From 982087f210e9a31ba4c49e378941aa033a09dc18 Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Fri, 9 Mar 2012 13:28:33 +0900 Subject: [PATCH] Issue #1471368 by amateescu: Convert uuid.inc to PSR-0. --- core/includes/uuid.inc | 154 ------------------ core/lib/Drupal/Component/Uuid/Com.php | 20 +++ core/lib/Drupal/Component/Uuid/Pecl.php | 21 +++ core/lib/Drupal/Component/Uuid/Php.php | 47 ++++++ core/lib/Drupal/Component/Uuid/Uuid.php | 87 ++++++++++ .../Drupal/Component/Uuid/UuidInterface.php | 22 +++ core/modules/simpletest/simpletest.info | 1 + core/modules/simpletest/tests/uuid.test | 69 ++++++++ core/modules/system/system.test | 65 -------- 9 files changed, 267 insertions(+), 219 deletions(-) delete mode 100644 core/includes/uuid.inc create mode 100644 core/lib/Drupal/Component/Uuid/Com.php create mode 100644 core/lib/Drupal/Component/Uuid/Pecl.php create mode 100644 core/lib/Drupal/Component/Uuid/Php.php create mode 100644 core/lib/Drupal/Component/Uuid/Uuid.php create mode 100644 core/lib/Drupal/Component/Uuid/UuidInterface.php create mode 100644 core/modules/simpletest/tests/uuid.test diff --git a/core/includes/uuid.inc b/core/includes/uuid.inc deleted file mode 100644 index 57f2199d7b8f..000000000000 --- a/core/includes/uuid.inc +++ /dev/null @@ -1,154 +0,0 @@ -<?php - -/** - * @file - * Handling of universally unique identifiers. - */ - -/** - * Interface that defines a UUID backend. - */ -interface UuidInterface { - - /** - * Generates a Universally Unique IDentifier (UUID). - * - * @return - * A 32 byte integer represented as a hex string formatted with 4 hypens. - */ - public function generate(); - -} - -/** - * Factory class for UUIDs. - * - * Determines which UUID implementation to use, and uses that to generate - * and validate UUIDs. - */ -class Uuid { - - /** - * Holds the UUID implementation. - */ - protected $plugin; - - /** - * This constructor instantiates the correct UUID object. - */ - public function __construct() { - $class = $this->determinePlugin(); - $this->plugin = new $class(); - } - - /** - * Generates an universally unique identifier. - * - * @see UuidInterface::generate() - */ - public function generate() { - return $this->plugin->generate(); - } - - /** - * Check that a string appears to be in the format of a UUID. - * - * Plugins should not implement validation, since UUIDs should be in a - * consistent format across all plugins. - * - * @param $uuid - * The string to test. - * - * @return - * TRUE if the string is well formed. - */ - public function isValid($uuid) { - return preg_match("/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/", $uuid); - } - - /** - * Determines the optimal implementation to use for generating UUIDs. - * - * The selection is made based on the enabled PHP extensions with the - * most performant available option chosen. - * - * @return - * The class name for the optimal UUID generator. - */ - protected function determinePlugin() { - static $plugin; - if (!empty($plugin)) { - return $plugin; - } - - $plugin = 'UuidPhp'; - - // Debian/Ubuntu uses the (broken) OSSP extension as their UUID - // implementation. The OSSP implementation is not compatible with the - // PECL functions. - if (function_exists('uuid_create') && !function_exists('uuid_make')) { - $plugin = 'UuidPecl'; - } - // Try to use the COM implementation for Windows users. - elseif (function_exists('com_create_guid')) { - $plugin = 'UuidCom'; - } - return $plugin; - } -} - -/** - * UUID implementation using the PECL extension. - */ -class UuidPecl implements UuidInterface { - public function generate() { - return uuid_create(UUID_TYPE_DEFAULT); - } -} - -/** - * UUID implementation using the Windows internal GUID extension. - * - * @see http://php.net/com_create_guid - */ -class UuidCom implements UuidInterface { - public function generate() { - // Remove {} wrapper and make lower case to keep result consistent. - return drupal_strtolower(trim(com_create_guid(), '{}')); - } -} - -/** - * Generates an UUID v4 using PHP code. - * - * Loosely based on Ruby's UUIDTools generate_random logic. - * - * @see http://uuidtools.rubyforge.org/api/classes/UUIDTools/UUID.html - */ -class UuidPhp implements UuidInterface { - public function generate() { - $hex = substr(hash('sha256', drupal_random_bytes(16)), 0, 32); - - // The field names refer to RFC 4122 section 4.1.2. - $time_low = substr($hex, 0, 8); - $time_mid = substr($hex, 8, 4); - - $time_hi_and_version = base_convert(substr($hex, 12, 4), 16, 10); - $time_hi_and_version &= 0x0FFF; - $time_hi_and_version |= (4 << 12); - - $clock_seq_hi_and_reserved = base_convert(substr($hex, 16, 4), 16, 10); - $clock_seq_hi_and_reserved &= 0x3F; - $clock_seq_hi_and_reserved |= 0x80; - - $clock_seq_low = substr($hex, 20, 2); - $nodes = substr($hex, 20); - - $uuid = sprintf('%s-%s-%04x-%02x%02x-%s', - $time_low, $time_mid, - $time_hi_and_version, $clock_seq_hi_and_reserved, - $clock_seq_low, $nodes); - - return $uuid; - } -} diff --git a/core/lib/Drupal/Component/Uuid/Com.php b/core/lib/Drupal/Component/Uuid/Com.php new file mode 100644 index 000000000000..41cfba42ffec --- /dev/null +++ b/core/lib/Drupal/Component/Uuid/Com.php @@ -0,0 +1,20 @@ +<?php + +/** + * @file + * Definition of Drupal\Component\Uuid\Com. + */ + +namespace Drupal\Component\Uuid; + +/** + * UUID implementation using the Windows internal GUID extension. + * + * @see http://php.net/com_create_guid + */ +class Com implements UuidInterface { + public function generate() { + // Remove {} wrapper and make lower case to keep result consistent. + return drupal_strtolower(trim(com_create_guid(), '{}')); + } +} diff --git a/core/lib/Drupal/Component/Uuid/Pecl.php b/core/lib/Drupal/Component/Uuid/Pecl.php new file mode 100644 index 000000000000..3d4cb2723375 --- /dev/null +++ b/core/lib/Drupal/Component/Uuid/Pecl.php @@ -0,0 +1,21 @@ +<?php + +/** + * @file + * Definition of Drupal\Component\Uuid\Pecl. + */ + +namespace Drupal\Component\Uuid; + +/** + * UUID implementation using the PECL extension. + */ +class Pecl implements UuidInterface { + + /** + * Implements Drupal\Component\Uuid\UuidInterface::generate(). + */ + public function generate() { + return uuid_create(UUID_TYPE_DEFAULT); + } +} diff --git a/core/lib/Drupal/Component/Uuid/Php.php b/core/lib/Drupal/Component/Uuid/Php.php new file mode 100644 index 000000000000..49c7df65738c --- /dev/null +++ b/core/lib/Drupal/Component/Uuid/Php.php @@ -0,0 +1,47 @@ +<?php + +/** + * @file + * Definition of Drupal\Component\Uuid\Php. + */ + +namespace Drupal\Component\Uuid; + +/** + * Generates an UUID v4 using PHP code. + * + * Loosely based on Ruby's UUIDTools generate_random logic. + * + * @see http://uuidtools.rubyforge.org/api/classes/UUIDTools/UUID.html + */ +class Php implements UuidInterface { + + /** + * Implements Drupal\Component\Uuid\UuidInterface::generate(). + */ + public function generate() { + $hex = substr(hash('sha256', drupal_random_bytes(16)), 0, 32); + + // The field names refer to RFC 4122 section 4.1.2. + $time_low = substr($hex, 0, 8); + $time_mid = substr($hex, 8, 4); + + $time_hi_and_version = base_convert(substr($hex, 12, 4), 16, 10); + $time_hi_and_version &= 0x0FFF; + $time_hi_and_version |= (4 << 12); + + $clock_seq_hi_and_reserved = base_convert(substr($hex, 16, 4), 16, 10); + $clock_seq_hi_and_reserved &= 0x3F; + $clock_seq_hi_and_reserved |= 0x80; + + $clock_seq_low = substr($hex, 20, 2); + $nodes = substr($hex, 20); + + $uuid = sprintf('%s-%s-%04x-%02x%02x-%s', + $time_low, $time_mid, + $time_hi_and_version, $clock_seq_hi_and_reserved, + $clock_seq_low, $nodes); + + return $uuid; + } +} diff --git a/core/lib/Drupal/Component/Uuid/Uuid.php b/core/lib/Drupal/Component/Uuid/Uuid.php new file mode 100644 index 000000000000..68a73d1f72b2 --- /dev/null +++ b/core/lib/Drupal/Component/Uuid/Uuid.php @@ -0,0 +1,87 @@ +<?php + +/** + * @file + * Definition of Drupal\Component\Uuid\Uuid. + */ + +namespace Drupal\Component\Uuid; + +/** + * Factory class for UUIDs. + * + * Determines which UUID implementation to use, and uses that to generate + * and validate UUIDs. + */ +class Uuid { + + /** + * Holds the UUID implementation. + * + * @var Drupal\Component\Uuid\UuidInterface + */ + protected $plugin; + + /** + * Instantiates the correct UUID object. + */ + public function __construct() { + $class = $this->determinePlugin(); + $this->plugin = new $class(); + } + + /** + * Generates an universally unique identifier. + * + * @see Drupal\Component\Uuid\UuidInterface::generate() + */ + public function generate() { + return $this->plugin->generate(); + } + + /** + * Checks that a string appears to be in the format of a UUID. + * + * Plugins should not implement validation, since UUIDs should be in a + * consistent format across all plugins. + * + * @param string $uuid + * The string to test. + * + * @return bool + * TRUE if the string is well formed, FALSE otherwise. + */ + public function isValid($uuid) { + return preg_match("/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/", $uuid); + } + + /** + * Determines the optimal implementation to use for generating UUIDs. + * + * The selection is made based on the enabled PHP extensions with the + * most performant available option chosen. + * + * @return string + * The class name for the optimal UUID generator. + */ + protected function determinePlugin() { + static $plugin; + if (!empty($plugin)) { + return $plugin; + } + + $plugin = 'Drupal\Component\Uuid\Php'; + + // Debian/Ubuntu uses the (broken) OSSP extension as their UUID + // implementation. The OSSP implementation is not compatible with the + // PECL functions. + if (function_exists('uuid_create') && !function_exists('uuid_make')) { + $plugin = 'Drupal\Component\Uuid\Pecl'; + } + // Try to use the COM implementation for Windows users. + elseif (function_exists('com_create_guid')) { + $plugin = 'Drupal\Component\Uuid\Com'; + } + return $plugin; + } +} diff --git a/core/lib/Drupal/Component/Uuid/UuidInterface.php b/core/lib/Drupal/Component/Uuid/UuidInterface.php new file mode 100644 index 000000000000..d1225ba4be62 --- /dev/null +++ b/core/lib/Drupal/Component/Uuid/UuidInterface.php @@ -0,0 +1,22 @@ +<?php + +/** + * @file + * Definition of Drupal\Component\Uuid\UuidInterface. + */ + +namespace Drupal\Component\Uuid; + +/** + * Interface that defines a UUID backend. + */ +interface UuidInterface { + + /** + * Generates a Universally Unique IDentifier (UUID). + * + * @return + * A 32 byte integer represented as a hex string formatted with 4 hypens. + */ + public function generate(); +} diff --git a/core/modules/simpletest/simpletest.info b/core/modules/simpletest/simpletest.info index d518a76e33eb..d18fe6e53746 100644 --- a/core/modules/simpletest/simpletest.info +++ b/core/modules/simpletest/simpletest.info @@ -37,6 +37,7 @@ files[] = tests/tablesort.test files[] = tests/theme.test files[] = tests/unicode.test files[] = tests/update.test +files[] = tests/uuid.test files[] = tests/xmlrpc.test files[] = tests/upgrade/upgrade.test files[] = tests/upgrade/upgrade_bare.test diff --git a/core/modules/simpletest/tests/uuid.test b/core/modules/simpletest/tests/uuid.test new file mode 100644 index 000000000000..0e1d67915020 --- /dev/null +++ b/core/modules/simpletest/tests/uuid.test @@ -0,0 +1,69 @@ +<?php + +use Drupal\Component\Uuid\Uuid; + +/** + * Tests the Drupal\Component\Uuid\Uuid class. + */ +class UuidUnitTestCase extends DrupalUnitTestCase { + + /** + * The UUID object to be used for generating UUIDs. + * + * @var Drupal\Component\Uuid\UuidInterface + */ + protected $uuid; + + public static function getInfo() { + return array( + 'name' => 'UUID handling', + 'description' => "Test the handling of Universally Unique IDentifiers (UUIDs).", + 'group' => 'UUID', + ); + } + + public function setUp() { + // Initiate the generator. This will lazy-load uuid.inc. + $this->uuid = new Uuid(); + parent::setUp(); + } + + /** + * Test generating a UUID. + */ + public function testGenerateUuid() { + $uuid = $this->uuid->generate(); + $this->assertTrue($this->uuid->isValid($uuid), 'UUID generation works.'); + } + + /** + * Test that generated UUIDs are unique. + */ + public function testUuidIsUnique() { + $uuid1 = $this->uuid->generate(); + $uuid2 = $this->uuid->generate(); + $this->assertNotEqual($uuid1, $uuid2, 'Same UUID was not generated twice.'); + } + + /** + * Test UUID validation. + */ + function testUuidValidation() { + // These valid UUIDs. + $uuid_fqdn = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; + $uuid_min = '00000000-0000-0000-0000-000000000000'; + $uuid_max = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; + + $this->assertTrue($this->uuid->isValid($uuid_fqdn), t('FQDN namespace UUID (@uuid) is valid', array('@uuid' => $uuid_fqdn))); + $this->assertTrue($this->uuid->isValid($uuid_min), t('Minimum UUID value (@uuid) is valid', array('@uuid' => $uuid_min))); + $this->assertTrue($this->uuid->isValid($uuid_max), t('Maximum UUID value (@uuid) is valid', array('@uuid' => $uuid_max))); + + // These are invalid UUIDs. + $invalid_format = '0ab26e6b-f074-4e44-9da-601205fa0e976'; + $invalid_length = '0ab26e6b-f074-4e44-9daf-1205fa0e9761f'; + + $this->assertFalse($this->uuid->isValid($invalid_format), t('@uuid is not a valid UUID', array('@uuid' => $invalid_format))); + $this->assertFalse($this->uuid->isValid($invalid_length), t('@uuid is not a valid UUID', array('@uuid' => $invalid_length))); + + } +} diff --git a/core/modules/system/system.test b/core/modules/system/system.test index 1431bf75d027..ecde8de7b088 100644 --- a/core/modules/system/system.test +++ b/core/modules/system/system.test @@ -2686,68 +2686,3 @@ class SystemIndexPhpTest extends DrupalWebTestCase { $this->assertResponse(404, t("Make sure index.php/user returns a 'page not found'.")); } } -/** - * Tests uuid.inc and related functions. - */ -class UuidUnitTestCase extends DrupalUnitTestCase { - - /** - * The UUID object to be used for generating UUIDs. - * - * @var Uuid - */ - protected $uuid; - - public static function getInfo() { - return array( - 'name' => 'UUID handling', - 'description' => "Test the handling of Universally Unique IDentifiers (UUIDs).", - 'group' => 'System', - ); - } - - public function setUp() { - // Initiate the generator. This will lazy-load uuid.inc. - $this->uuid = new Uuid(); - parent::setUp(); - } - - /** - * Test generating a UUID. - */ - public function testGenerateUuid() { - $uuid = $this->uuid->generate(); - $this->assertTrue($this->uuid->isValid($uuid), 'UUID generation works.'); - } - - /** - * Test that generated UUIDs are unique. - */ - public function testUuidIsUnique() { - $uuid1 = $this->uuid->generate(); - $uuid2 = $this->uuid->generate(); - $this->assertNotEqual($uuid1, $uuid2, 'Same UUID was not generated twice.'); - } - - /** - * Test UUID validation. - */ - function testUuidValidation() { - // These valid UUIDs. - $uuid_fqdn = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; - $uuid_min = '00000000-0000-0000-0000-000000000000'; - $uuid_max = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; - - $this->assertTrue($this->uuid->isValid($uuid_fqdn), t('FQDN namespace UUID (@uuid) is valid', array('@uuid' => $uuid_fqdn))); - $this->assertTrue($this->uuid->isValid($uuid_min), t('Minimum UUID value (@uuid) is valid', array('@uuid' => $uuid_min))); - $this->assertTrue($this->uuid->isValid($uuid_max), t('Maximum UUID value (@uuid) is valid', array('@uuid' => $uuid_max))); - - // These are invalid UUIDs. - $invalid_format = '0ab26e6b-f074-4e44-9da-601205fa0e976'; - $invalid_length = '0ab26e6b-f074-4e44-9daf-1205fa0e9761f'; - - $this->assertFalse($this->uuid->isValid($invalid_format), t('@uuid is not a valid UUID', array('@uuid' => $invalid_format))); - $this->assertFalse($this->uuid->isValid($invalid_length), t('@uuid is not a valid UUID', array('@uuid' => $invalid_length))); - - } -} -- GitLab