diff --git a/docs/en/reference/basic-mapping.rst b/docs/en/reference/basic-mapping.rst index 90ba5a8d60..3f52e40754 100644 --- a/docs/en/reference/basic-mapping.rst +++ b/docs/en/reference/basic-mapping.rst @@ -286,19 +286,12 @@ object ID. The available strategies are: - ``ALNUM`` - Generates an alpha-numeric string (based on an incrementing value). - ``CUSTOM`` - Defers generation to an implementation of ``IdGenerator`` specified in the ``class`` option. - ``INCREMENT`` - Uses another collection to auto increment an integer identifier. -- ``UUID`` - Generates a UUID identifier (deprecated). - ``NONE`` - Do not generate any identifier. ID must be manually set. When using the ``AUTO`` strategy in combination with a UUID identifier, the generator can create UUIDs of type 1, type 4, and type 7 automatically. For all other UUID types, assign the identifier manually in combination with the ``NONE`` strategy. -.. note:: - - The ``UUID`` generator is deprecated, as it stores UUIDs as strings. It is recommended to use the ``AUTO`` strategy - with a ``uuid`` type identifier field instead. If you need to keep generating string UUIDs, you can use the - ``CUSTOM`` strategy with your own generator. - Here is an example how to manually set a string identifier for your documents: .. configuration-block:: @@ -315,7 +308,7 @@ Here is an example how to manually set a string identifier for your documents: #[Document] class MyPersistentClass { - #[Id(strategy: 'NONE', type: 'string')] + #[Id(strategy: 'NONE')] public string $id; //... diff --git a/src/Id/AbstractIdGenerator.php b/src/Id/AbstractIdGenerator.php deleted file mode 100644 index 966116d843..0000000000 --- a/src/Id/AbstractIdGenerator.php +++ /dev/null @@ -1,10 +0,0 @@ - UuidV1::class, diff --git a/src/Id/UuidGenerator.php b/src/Id/UuidGenerator.php deleted file mode 100644 index ac2a188290..0000000000 --- a/src/Id/UuidGenerator.php +++ /dev/null @@ -1,141 +0,0 @@ -salt = $salt; - } - - /** - * Returns the current salt value - * - * @return string|null The current salt - */ - public function getSalt(): ?string - { - return $this->salt; - } - - /** - * Checks that a given string is a valid uuid. - */ - public function isValid(string $uuid): bool - { - return preg_match('/^\{?[0-9a-f]{8}\-?[0-9a-f]{4}\-?[0-9a-f]{4}\-?[0-9a-f]{4}\-?[0-9a-f]{12}\}?$/i', $uuid) - === 1; - } - - /** - * Generates a new UUID - * - * @param DocumentManager $dm Not used. - * @param object $document Not used. - * - * @return string UUID - * - * @throws Exception - */ - public function generate(DocumentManager $dm, object $document) - { - $uuid = $this->generateV4(); - - return $this->generateV5($uuid, $this->salt ?: php_uname('n')); - } - - /** - * Generates a v4 UUID - */ - public function generateV4(): string - { - return sprintf( - '%04x%04x%04x%04x%04x%04x%04x%04x', - // 32 bits for "time_low" - random_int(0, 0xffff), - random_int(0, 0xffff), - // 16 bits for "time_mid" - random_int(0, 0xffff), - // 16 bits for "time_hi_and_version", - // four most significant bits holds version number 4 - random_int(0, 0x0fff) | 0x4000, - // 16 bits, 8 bits for "clk_seq_hi_res", - // 8 bits for "clk_seq_low", - // two most significant bits holds zero and one for variant DCE1.1 - random_int(0, 0x3fff) | 0x8000, - // 48 bits for "node" - random_int(0, 0xffff), - random_int(0, 0xffff), - random_int(0, 0xffff), - ); - } - - /** - * Generates a v5 UUID - * - * @throws Exception When the provided namespace is invalid. - */ - public function generateV5(string $namespace, string $salt): string - { - if (! $this->isValid($namespace)) { - throw new Exception('Provided $namespace is invalid: ' . $namespace); - } - - // Get hexadecimal components of namespace - $nhex = str_replace(['-', '{', '}'], '', $namespace); - - // Binary Value - $nstr = ''; - - // Convert Namespace UUID to bits - for ($i = 0; $i < strlen($nhex); $i += 2) { - $nstr .= chr((int) hexdec($nhex[$i] . $nhex[$i + 1])); - } - - // Calculate hash value - $hash = sha1($nstr . $salt); - - return sprintf( - '%08s%04s%04x%04x%12s', - // 32 bits for "time_low" - substr($hash, 0, 8), - // 16 bits for "time_mid" - substr($hash, 8, 4), - // 16 bits for "time_hi_and_version", - // four most significant bits holds version number 3 - (hexdec(substr($hash, 12, 4)) & 0x0fff) | 0x3000, - // 16 bits, 8 bits for "clk_seq_hi_res", - // 8 bits for "clk_seq_low", - // two most significant bits holds zero and one for variant DCE1.1 - (hexdec(substr($hash, 16, 4)) & 0x3fff) | 0x8000, - // 48 bits for "node" - substr($hash, 20, 12), - ); - } -} diff --git a/src/Mapping/ClassMetadata.php b/src/Mapping/ClassMetadata.php index 763d70cfa9..67ef325cc5 100644 --- a/src/Mapping/ClassMetadata.php +++ b/src/Mapping/ClassMetadata.php @@ -306,13 +306,6 @@ */ public const GENERATOR_TYPE_INCREMENT = 2; - /** - * UUID means Doctrine will generate a uuid for us. - * - * @deprecated without replacement. Use a custom generator or switch to binary UUIDs. - */ - public const GENERATOR_TYPE_UUID = 3; - /** * ALNUM means Doctrine will generate Alpha-numeric string identifiers, using the INCREMENT * generator to ensure identifier uniqueness @@ -2168,14 +2161,6 @@ public function isIdGeneratorIncrement(): bool return $this->generatorType === self::GENERATOR_TYPE_INCREMENT; } - /** - * Checks whether the class will generate a uuid id. - */ - public function isIdGeneratorUuid(): bool - { - return $this->generatorType === self::GENERATOR_TYPE_UUID; - } - /** * Checks whether the class uses no id generator. */ diff --git a/src/Mapping/ClassMetadataFactory.php b/src/Mapping/ClassMetadataFactory.php index 6f02bde635..2fbf9e4e77 100644 --- a/src/Mapping/ClassMetadataFactory.php +++ b/src/Mapping/ClassMetadataFactory.php @@ -16,7 +16,6 @@ use Doctrine\ODM\MongoDB\Id\IncrementGenerator; use Doctrine\ODM\MongoDB\Id\ObjectIdGenerator; use Doctrine\ODM\MongoDB\Id\SymfonyUuidGenerator; -use Doctrine\ODM\MongoDB\Id\UuidGenerator; use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory; use Doctrine\Persistence\Mapping\ClassMetadata as ClassMetadataInterface; use Doctrine\Persistence\Mapping\Driver\MappingDriver; @@ -292,14 +291,6 @@ private function completeIdGeneratorMapping(ClassMetadata $class): void $class->setIdGenerator($incrementGenerator); break; - case ClassMetadata::GENERATOR_TYPE_UUID: - $uuidGenerator = new UuidGenerator(); - if (isset($idGenOptions['salt'])) { - $uuidGenerator->setSalt((string) $idGenOptions['salt']); - } - - $class->setIdGenerator($uuidGenerator); - break; case ClassMetadata::GENERATOR_TYPE_ALNUM: $alnumGenerator = new AlnumGenerator(); if (isset($idGenOptions['pad'])) { diff --git a/tests/Tests/Functional/IdTest.php b/tests/Tests/Functional/IdTest.php index 099e380650..3f33acab59 100644 --- a/tests/Tests/Functional/IdTest.php +++ b/tests/Tests/Functional/IdTest.php @@ -6,9 +6,7 @@ use DateTime; use Doctrine\Common\Collections\Collection; -use Doctrine\ODM\MongoDB\Id\UuidGenerator; use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; -use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; use InvalidArgumentException; use MongoDB\BSON\Binary; @@ -22,35 +20,11 @@ use function gettype; use function is_object; use function md5; -use function serialize; use function sprintf; use function ucfirst; -use function unserialize; class IdTest extends BaseTestCase { - public function testUuidId(): void - { - $user = new UuidUser('Jonathan H. Wage'); - $this->dm->persist($user); - $this->dm->flush(); - $id = $user->id; - - $this->dm->clear(); - $check1 = $this->dm->getRepository(UuidUser::class)->findOneBy(['id' => $id]); - self::assertNotNull($check1); - - $check2 = $this->dm->createQueryBuilder(UuidUser::class) - ->field('id')->equals($id)->getQuery()->getSingleResult(); - self::assertNotNull($check2); - self::assertSame($check1, $check2); - - $check3 = $this->dm->createQueryBuilder(UuidUser::class) - ->field('name')->equals('Jonathan H. Wage')->getQuery()->getSingleResult(); - self::assertNotNull($check3); - self::assertSame($check2, $check3); - } - public function testAlnumIdChars(): void { $user = new AlnumCharsUser('Jonathan H. Wage'); @@ -146,23 +120,6 @@ public function testEmbeddedDocumentWithId(): void self::assertEquals(4, $user2->embedded[1]->id); } - public function testIdGeneratorInstance(): void - { - $class = $this->dm->getClassMetadata(UuidUser::class); - self::assertEquals(ClassMetadata::GENERATOR_TYPE_UUID, $class->generatorType); - self::assertEquals(['salt' => 'test'], $class->generatorOptions); - self::assertInstanceOf(UuidGenerator::class, $class->idGenerator); - self::assertEquals('test', $class->idGenerator->getSalt()); - - $serialized = serialize($class); - $class = unserialize($serialized); - - self::assertEquals(ClassMetadata::GENERATOR_TYPE_UUID, $class->generatorType); - self::assertEquals(['salt' => 'test'], $class->generatorOptions); - self::assertInstanceOf(UuidGenerator::class, $class->idGenerator); - self::assertEquals('test', $class->idGenerator->getSalt()); - } - /** @param int|float $user2Id */ #[DataProvider('provideEqualButNotIdenticalIds')] public function testEqualButNotIdenticalIds(string $user1Id, $user2Id): void @@ -293,7 +250,6 @@ public static function getTestIdTypesAndStrategiesData(): array // bin ['bin', 'none', 'test-data', 'test-data', Binary::class], - ['bin', 'uuid', null, null, Binary::class], ['bin_func', 'none', 'test-data', 'test-data', Binary::class], ['bin_bytearray', 'none', 'test-data', 'test-data', Binary::class], ['bin_uuid', 'none', 'TestTestTestTest', 'TestTestTestTest', Binary::class], @@ -392,23 +348,6 @@ class %s } } -#[ODM\Document] -class UuidUser -{ - /** @var string|null */ - #[ODM\Id(strategy: 'uuid', options: ['salt' => 'test'])] - public $id; - - /** @var string */ - #[ODM\Field(name: 't', type: 'string')] - public $name; - - public function __construct(string $name) - { - $this->name = $name; - } -} - #[ODM\Document] class CollectionIdUser { diff --git a/tests/Tests/Functional/Ticket/GH1294Test.php b/tests/Tests/Functional/Ticket/GH1294Test.php deleted file mode 100644 index 2082c10cbb..0000000000 --- a/tests/Tests/Functional/Ticket/GH1294Test.php +++ /dev/null @@ -1,55 +0,0 @@ -id = 'aaa111aaa'; - $user1->name = 'Steven'; - - $user2 = new GH1294User(); - $user2->id = 'bbb111bbb'; - $user2->name = 'Jeff'; - - $this->dm->persist($user1); - $this->dm->persist($user2); - $this->dm->flush(); - $this->dm->clear(); - - $qb = $this->dm->createQueryBuilder(GH1294User::class); - - $res = $qb->field('id') - ->equals(new Regex('^bbb.*$', 'i')) - ->getQueryArray(); - - self::assertInstanceOf(Regex::class, $res['_id']); - self::assertEquals('^bbb.*$', $res['_id']->getPattern()); - self::assertEquals('i', $res['_id']->getFlags()); - } -} - -#[ODM\Document] -class GH1294User -{ - /** @var string|null */ - #[ODM\Id(strategy: 'UUID', type: 'string')] - public $id; - - /** @var string|null */ - #[ODM\Field(type: 'string')] - public $name = ''; - - public function getId(): ?string - { - return $this->id; - } -} diff --git a/tests/Tests/Functional/Ticket/GH1525Test.php b/tests/Tests/Functional/Ticket/GH1525Test.php index d5770bc3d4..206eef3a7e 100644 --- a/tests/Tests/Functional/Ticket/GH1525Test.php +++ b/tests/Tests/Functional/Ticket/GH1525Test.php @@ -6,10 +6,12 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; -use Doctrine\ODM\MongoDB\Id\UuidGenerator; use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; +use function bin2hex; +use function random_bytes; + class GH1525Test extends BaseTestCase { public function testEmbedCloneTwoFlushesPerDocument(): void @@ -46,12 +48,11 @@ public function testEmbedCloneTwoFlushesPerDocument(): void public function testEmbedCloneWithIdStrategyNoneOnParentAndEarlyPersist(): void { - $uuidGen = new UuidGenerator(); $embedded = new GH1525Embedded('embedded'); $count = 2; for ($i = 0; $i < $count; ++$i) { - $parent = new GH1525DocumentIdStrategyNone($uuidGen->generateV4(), 'test' . $i); + $parent = new GH1525DocumentIdStrategyNone(bin2hex(random_bytes(6)), 'test' . $i); $this->dm->persist($parent); $parent->embedded = $embedded; $this->dm->flush(); @@ -71,12 +72,11 @@ public function testEmbedCloneWithIdStrategyNoneOnParentAndEarlyPersist(): void public function testEmbedCloneWithIdStrategyNoneOnParentAndLatePersist(): void { - $uuidGen = new UuidGenerator(); $embedded = new GH1525Embedded('embedded'); $count = 2; for ($i = 0; $i < $count; ++$i) { - $parent = new GH1525DocumentIdStrategyNone($uuidGen->generateV4(), 'test' . $i); + $parent = new GH1525DocumentIdStrategyNone(bin2hex(random_bytes(6)), 'test' . $i); $parent->embedded = $embedded; $this->dm->persist($parent); $this->dm->flush();