diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php b/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php index bf080f7cb..759707404 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php +++ b/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php @@ -205,8 +205,8 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad 'doctrine/mongodb-odm', '2.2', 'The "indexes" parameter in the "%s" attribute for class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" attributes on the class.', - $className, $documentAttribute::class, + $className, ); foreach ($documentAttribute->indexes as $index) { @@ -241,6 +241,14 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad } if ($propertyAttribute instanceof ODM\Indexes) { + trigger_deprecation( + 'doctrine/mongodb-odm', + '2.2', + 'The "@Indexes" attribute used in property "%s" of class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" attributes on the class.', + $property->getName(), + $className, + ); + $value = $propertyAttribute->value; foreach (is_array($value) ? $value : [$value] as $index) { $indexes[] = $index; diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AnnotationDriverTest.php b/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AnnotationDriverTest.php index b21f2c10a..6f6cd0144 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AnnotationDriverTest.php +++ b/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AnnotationDriverTest.php @@ -5,9 +5,19 @@ namespace Doctrine\ODM\MongoDB\Tests\Mapping; use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; +use Doctrine\ODM\MongoDB\Mapping\Annotations\Document; +use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver; use Doctrine\Persistence\Mapping\Driver\MappingDriver; +use function call_user_func; +use function restore_error_handler; +use function set_error_handler; +use function sprintf; + +use const E_USER_DEPRECATED; + class AnnotationDriverTest extends AbstractAnnotationDriverTestCase { protected static function loadDriver(): MappingDriver @@ -16,4 +26,125 @@ protected static function loadDriver(): MappingDriver return new AnnotationDriver($reader); } + + public function testIndexesClassAnnotationEmitsDeprecationMessage(): void + { + $driver = static::loadDriver(); + $classMetadata = new ClassMetadata(DeprecatedIndexesClassAnnotation::class); + + $this->captureDeprecationMessages( + static fn () => $driver->loadMetadataForClass($classMetadata->name, $classMetadata), + $errors, + ); + + self::assertCount(1, $errors); + self::assertSame(sprintf('Since doctrine/mongodb-odm 2.2: The "@Indexes" attribute used in class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" attributes on the class.', DeprecatedIndexesClassAnnotation::class), $errors[0]); + + $indexes = $classMetadata->indexes; + + self::assertTrue(isset($indexes[0]['keys']['foo'])); + self::assertEquals(1, $indexes[0]['keys']['foo']); + } + + public function testIndexesOptionOfDocumentClassAnnotationEmitsDeprecationMessage(): void + { + $driver = static::loadDriver(); + $classMetadata = new ClassMetadata(DeprecatedDocumentClassAnnotationIndexesOption::class); + + $this->captureDeprecationMessages( + static fn () => $driver->loadMetadataForClass($classMetadata->name, $classMetadata), + $errors, + ); + + self::assertCount(1, $errors); + self::assertSame(sprintf('Since doctrine/mongodb-odm 2.2: The "indexes" parameter in the "%s" attribute for class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" attributes on the class.', Document::class, DeprecatedDocumentClassAnnotationIndexesOption::class), $errors[0]); + + $indexes = $classMetadata->indexes; + + self::assertTrue(isset($indexes[0]['keys']['foo'])); + self::assertEquals(1, $indexes[0]['keys']['foo']); + } + + public function testIndexesPropertyAnnotationEmitsDeprecationMessage(): void + { + $driver = static::loadDriver(); + $classMetadata = new ClassMetadata(DeprecatedIndexesPropertyAnnotation::class); + + $this->captureDeprecationMessages( + static fn () => $driver->loadMetadataForClass($classMetadata->name, $classMetadata), + $errors, + ); + + self::assertCount(1, $errors); + self::assertSame(sprintf('Since doctrine/mongodb-odm 2.2: The "@Indexes" attribute used in property "foo" of class "%s" is deprecated. Specify all "@Index" and "@UniqueIndex" attributes on the class.', DeprecatedIndexesPropertyAnnotation::class), $errors[0]); + + $indexes = $classMetadata->indexes; + + self::assertTrue(isset($indexes[0]['keys']['foo'])); + self::assertEquals(1, $indexes[0]['keys']['foo']); + } + + /** @param list|null $errors */ + private function captureDeprecationMessages(callable $callable, ?array &$errors): mixed + { + /* TODO: this method can be replaced with expectUserDeprecationMessage() in PHPUnit 11+. + * See: https://docs.phpunit.de/en/11.1/error-handling.html#expecting-deprecations-e-user-deprecated */ + $errors = []; + + set_error_handler(static function (int $errno, string $errstr) use (&$errors): bool { + $errors[] = $errstr; + + return false; + }, E_USER_DEPRECATED); + + try { + return call_user_func($callable); + } finally { + restore_error_handler(); + } + } +} + +/** + * @ODM\Document + * @ODM\Indexes({ + * @ODM\Index(keys={"foo"="asc"}) + * }) + */ +class DeprecatedIndexesClassAnnotation +{ + /** @ODM\Id */ + public ?string $id; + + /** @ODM\Field(type="string") */ + public string $foo; +} + +/** + * @ODM\Document(indexes={ + * @ODM\Index(keys={"foo"="asc"}) + * }) + */ +class DeprecatedDocumentClassAnnotationIndexesOption +{ + /** @ODM\Id */ + public ?string $id; + + /** @ODM\Field(type="string") */ + public string $foo; +} + +/** @ODM\Document */ +class DeprecatedIndexesPropertyAnnotation +{ + /** @ODM\Id */ + public ?string $id; + + /** + * @ODM\Field(type="string") + * @ODM\Indexes({ + * @ODM\Index + * }) + */ + public string $foo; }