* @git Joomla Component Builder * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace VDM\Joomla\Data; /** * Globally Unique Identifier * * @since 5.0.2 */ trait Guid { /** * Returns a GUIDv4 string. * * This function uses the best cryptographically secure method * available on the platform with a fallback to an older, less secure version. * * @param string $key The key to check and modify values. * * @return string A GUIDv4 string. * * @since 5.0.2 */ public function getGuid(string $key): string { // Windows: Use com_create_guid if available if (function_exists('com_create_guid')) { $guid = trim(\com_create_guid(), '{}'); return $this->checkGuid($guid, $key); } // Unix-based systems: Use openssl_random_pseudo_bytes if available if (function_exists('random_bytes')) { try { $data = random_bytes(16); } catch (Exception $e) { // Handle the error appropriately (logging, throwing, etc.) return $this->fallbackGuid($key); } // Set the version to 0100 and the bits 6-7 to 10 as per RFC 4122 $data[6] = chr(ord($data[6]) & 0x0f | 0x40); $data[8] = chr(ord($data[8]) & 0x3f | 0x80); $guid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); return $this->checkGuid($guid, $key); } // Fallback to older methods if secure methods are not available return $this->fallbackGuid($key); } /** * Generates a fallback GUIDv4 using less secure methods. * * @param string $key The key to check and modify values. * * @return string A GUIDv4 string. * * @since 5.0.2 */ private function fallbackGuid(string $key): string { $charid = strtolower(md5(uniqid(random_int(0, PHP_INT_MAX), true))); $guidv4 = sprintf( '%s-%s-%s-%s-%s', substr($charid, 0, 8), substr($charid, 8, 4), substr($charid, 12, 4), substr($charid, 16, 4), substr($charid, 20, 12) ); return $this->checkGuid($guidv4, $key); } /** * Checks if the GUID value is unique and does not already exist. * * @param string $guid The GUID value to check. * @param string $key The key to check and modify values. * * @return string The unique GUID value. * * @since 5.0.2 */ private function checkGuid(string $guid, string $key): string { // Check that the GUID does not already exist if ($this->items->table($this->getTable())->values([$guid], $key)) { return $this->getGuid($key); } return $guid; } }