Skip to content

Commit

Permalink
Fix deprecation notices Indexes annotation (#2622)
Browse files Browse the repository at this point in the history
* Fix argument order for Indexes deprecation notice

The argument order has been incorrect since the deprecation message was changed in 3bdfe97.

* Deprecation notice when using Indexes annotation on a property

This was missed when Indexes was originally deprecated in 7435e66.

* Test deprecation messages for Indexes annotation

The attribute is intentionally untested. The Indexes attribute cannot target a property (it omits Attribute::TARGET_PROPERTY). When Indexes targets a class, Index attributes cannot be nested within its definition. Testing the "indexes" option for class-level Document attributes is technically possible but not worth the effort.
  • Loading branch information
jmikola authored Apr 23, 2024
1 parent 7972411 commit e032256
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
131 changes: 131 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/Mapping/AnnotationDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<string>|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;
}

0 comments on commit e032256

Please sign in to comment.