From 65f2ed08394dda5921ce48c5f5015c3beac29bad Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 19 Dec 2023 09:34:58 +0100 Subject: [PATCH 1/2] Resolve deprecations --- phpstan-baseline.neon | 7 +- src/AbstractFixture.php | 29 +--- src/ProxyReferenceRepository.php | 34 ----- src/ReferenceRepository.php | 139 ++---------------- .../Executor/ORMExecutorSharedFixtureTest.php | 6 +- .../ProxyReferenceRepositoryTest.php | 24 +-- .../DataFixtures/ReferenceRepositoryTest.php | 63 +++++--- .../DataFixtures/TestFixtures/UserFixture.php | 3 +- 8 files changed, 78 insertions(+), 227 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 16029250..8ecbfb27 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -27,11 +27,6 @@ parameters: - message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getReference\\(\\)\\.$#" - count: 2 - path: src/ProxyReferenceRepository.php - - - - message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getUnitOfWork\\(\\)\\.$#" count: 1 path: src/ProxyReferenceRepository.php @@ -71,7 +66,7 @@ parameters: path: src/Purger/PHPCRPurger.php - - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\\\:\\:\\$name\\.$#" + message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\\\:\\:\\$name\\.$#" count: 1 path: src/ReferenceRepository.php diff --git a/src/AbstractFixture.php b/src/AbstractFixture.php index d090bcc5..81274e1d 100644 --- a/src/AbstractFixture.php +++ b/src/AbstractFixture.php @@ -5,7 +5,6 @@ namespace Doctrine\Common\DataFixtures; use BadMethodCallException; -use Doctrine\Deprecations\Deprecation; use function assert; @@ -79,24 +78,15 @@ public function addReference(string $name, object $object) * * @see ReferenceRepository::getReference() * - * @psalm-param class-string|null $class + * @psalm-param class-string $class * * @return object - * @psalm-return ($class is null ? object : T) + * @psalm-return T * * @template T of object */ - public function getReference(string $name, string|null $class = null) + public function getReference(string $name, string $class) { - if ($class === null) { - Deprecation::trigger( - 'doctrine/data-fixtures', - 'https://github.com/doctrine/data-fixtures/pull/409', - 'Argument $class of %s() will be mandatory in 2.0.', - __METHOD__, - ); - } - return $this->getReferenceRepository()->getReference($name, $class); } @@ -106,21 +96,12 @@ public function getReference(string $name, string|null $class = null) * * @see ReferenceRepository::hasReference() * - * @psalm-param class-string|null $class + * @psalm-param class-string $class * * @return bool */ - public function hasReference(string $name, string|null $class = null) + public function hasReference(string $name, string $class) { - if ($class === null) { - Deprecation::trigger( - 'doctrine/data-fixtures', - 'https://github.com/doctrine/data-fixtures/pull/409', - 'Argument $class of %s() will be mandatory in 2.0.', - __METHOD__, - ); - } - return $this->getReferenceRepository()->hasReference($name, $class); } } diff --git a/src/ProxyReferenceRepository.php b/src/ProxyReferenceRepository.php index 876773e3..0e9cfc2a 100644 --- a/src/ProxyReferenceRepository.php +++ b/src/ProxyReferenceRepository.php @@ -25,18 +25,7 @@ class ProxyReferenceRepository extends ReferenceRepository */ public function serialize() { - $unitOfWork = $this->getManager()->getUnitOfWork(); - $simpleReferences = []; - - foreach ($this->getReferences() as $name => $reference) { - $className = $this->getRealClass($reference::class); - - $simpleReferences[$name] = [$className, $this->getIdentifier($reference, $unitOfWork)]; - } - return serialize([ - 'references' => $simpleReferences, // For BC, remove in next major. - 'identities' => $this->getIdentities(), // For BC, remove in next major. 'identitiesByClass' => $this->getIdentitiesByClass(), ]); } @@ -52,29 +41,6 @@ public function unserialize(string $serializedData) { $repositoryData = unserialize($serializedData); - // For BC, remove in next major. - if (! isset($repositoryData['identitiesByClass'])) { - $references = $repositoryData['references']; - - foreach ($references as $name => $proxyReference) { - $this->setReference( - $name, - $this->getManager()->getReference( - $proxyReference[0], // entity class name - $proxyReference[1], // identifiers - ), - ); - } - - $identities = $repositoryData['identities']; - - foreach ($identities as $name => $identity) { - $this->setReferenceIdentity($name, $identity); - } - - return; - } - foreach ($repositoryData['identitiesByClass'] as $className => $identities) { foreach ($identities as $name => $identity) { $this->setReference( diff --git a/src/ReferenceRepository.php b/src/ReferenceRepository.php index f3c52c20..37a29ef3 100644 --- a/src/ReferenceRepository.php +++ b/src/ReferenceRepository.php @@ -5,7 +5,6 @@ namespace Doctrine\Common\DataFixtures; use BadMethodCallException; -use Doctrine\Deprecations\Deprecation; use Doctrine\ODM\PHPCR\DocumentManager as PhpcrDocumentManager; use Doctrine\ORM\UnitOfWork as OrmUnitOfWork; use Doctrine\Persistence\ObjectManager; @@ -22,14 +21,6 @@ */ class ReferenceRepository { - /** - * List of named references to the fixture objects - * gathered during fixure loading - * - * @psalm-var array - */ - private array $references = []; - /** * List of named references to the fixture objects * gathered during fixure loading @@ -38,15 +29,6 @@ class ReferenceRepository */ private array $referencesByClass = []; - /** - * List of identifiers stored for references - * in case a reference gets no longer managed, it will - * use a proxy referenced by this identity - * - * @psalm-var array - */ - private array $identities = []; - /** * List of identifiers stored for references * in case a reference gets no longer managed, it will @@ -110,9 +92,6 @@ public function setReference(string $name, object $reference) $this->referencesByClass[$class][$name] = $reference; - // For BC, to be removed in next major. - $this->references[$name] = $reference; - if (! $this->hasIdentifier($reference)) { return; } @@ -122,34 +101,19 @@ public function setReference(string $name, object $reference) $identifier = $this->getIdentifier($reference, $uow); $this->identitiesByClass[$class][$name] = $identifier; - - // For BC, to be removed in next major. - $this->identities[$name] = $identifier; } /** * Store the identifier of a reference * - * @param mixed $identity - * @param class-string|null $class + * @param mixed $identity + * @param class-string $class * * @return void */ - public function setReferenceIdentity(string $name, $identity, string|null $class = null) + public function setReferenceIdentity(string $name, $identity, string $class) { - if ($class === null) { - Deprecation::trigger( - 'doctrine/data-fixtures', - 'https://github.com/doctrine/data-fixtures/pull/409', - 'Argument $class of %s() will be mandatory in 2.0.', - __METHOD__, - ); - } - $this->identitiesByClass[$class][$name] = $identity; - - // For BC, to be removed in next major. - $this->identities[$name] = $identity; } /** @@ -169,14 +133,6 @@ public function setReferenceIdentity(string $name, $identity, string|null $class */ public function addReference(string $name, object $object) { - // For BC, to be removed in next major. - if (isset($this->references[$name])) { - throw new BadMethodCallException(sprintf( - 'Reference to "%s" already exists, use method setReference() in order to override it', - $name, - )); - } - $class = $this->getRealClass($object::class); if (isset($this->referencesByClass[$class][$name])) { throw new BadMethodCallException(sprintf( @@ -193,52 +149,29 @@ public function addReference(string $name, object $object) * Loads an object using stored reference * named by $name * - * @psalm-param class-string|null $class + * @psalm-param class-string $class * * @return object - * @psalm-return ($class is null ? object : T) + * @psalm-return T * * @throws OutOfBoundsException - if repository does not exist. * * @template T of object */ - public function getReference(string $name, string|null $class = null) + public function getReference(string $name, string $class) { - if ($class === null) { - Deprecation::trigger( - 'doctrine/data-fixtures', - 'https://github.com/doctrine/data-fixtures/pull/409', - 'Argument $class of %s() will be mandatory in 2.0.', - __METHOD__, - ); - } - if (! $this->hasReference($name, $class)) { - // For BC, to be removed in next major. - if ($class === null) { - throw new OutOfBoundsException(sprintf('Reference to "%s" does not exist', $name)); - } - throw new OutOfBoundsException(sprintf('Reference to "%s" for class "%s" does not exist', $name, $class)); } - $reference = $class === null - ? $this->references[$name] // For BC, to be removed in next major. - : $this->referencesByClass[$class][$name]; - - $identity = $class === null - ? ($this->identities[$name] ?? null) // For BC, to be removed in next major. - : ($this->identitiesByClass[$class][$name] ?? null); + $reference = $this->referencesByClass[$class][$name]; - if ($class === null) { // For BC, to be removed in next major. - $class = $this->getRealClass($reference::class); - } + $identity = ($this->identitiesByClass[$class][$name] ?? null); $meta = $this->manager->getClassMetadata($class); if (! $this->manager->contains($reference) && $identity !== null) { $reference = $this->manager->getReference($meta->name, $identity); - $this->references[$name] = $reference; // already in identity map $this->referencesByClass[$class][$name] = $reference; // already in identity map } @@ -253,20 +186,9 @@ public function getReference(string $name, string|null $class = null) * * @return bool */ - public function hasReference(string $name, string|null $class = null) + public function hasReference(string $name, string $class) { - if ($class === null) { - Deprecation::trigger( - 'doctrine/data-fixtures', - 'https://github.com/doctrine/data-fixtures/pull/409', - 'Argument $class of %s() will be mandatory in 2.0.', - __METHOD__, - ); - } - - return $class === null - ? isset($this->references[$name]) // For BC, to be removed in next major. - : isset($this->referencesByClass[$class][$name]); + return isset($this->referencesByClass[$class][$name]); } /** @@ -288,36 +210,13 @@ public function getReferenceNames(object $reference) /** * Checks if reference has identity stored * - * @param class-string|null $class + * @param class-string $class * * @return bool */ - public function hasIdentity(string $name, string|null $class = null) - { - if ($class === null) { - Deprecation::trigger( - 'doctrine/data-fixtures', - 'https://github.com/doctrine/data-fixtures/pull/409', - 'Argument $class of %s() will be mandatory in 2.0.', - __METHOD__, - ); - } - - return $class === null - ? array_key_exists($name, $this->identities) // For BC, to be removed in next major. - : array_key_exists($class, $this->identitiesByClass) && array_key_exists($name, $this->identitiesByClass[$class]); - } - - /** - * @deprecated in favor of getIdentitiesByClass - * - * Get all stored identities - * - * @psalm-return array - */ - public function getIdentities() + public function hasIdentity(string $name, string $class) { - return $this->identities; + return array_key_exists($class, $this->identitiesByClass) && array_key_exists($name, $this->identitiesByClass[$class]); } /** @@ -330,18 +229,6 @@ public function getIdentitiesByClass(): array return $this->identitiesByClass; } - /** - * @deprecated in favor of getReferencesByClass - * - * Get all stored references - * - * @psalm-return array - */ - public function getReferences() - { - return $this->references; - } - /** * Get all stored references * diff --git a/tests/Common/DataFixtures/Executor/ORMExecutorSharedFixtureTest.php b/tests/Common/DataFixtures/Executor/ORMExecutorSharedFixtureTest.php index f4275f3e..75cbd3b6 100644 --- a/tests/Common/DataFixtures/Executor/ORMExecutorSharedFixtureTest.php +++ b/tests/Common/DataFixtures/Executor/ORMExecutorSharedFixtureTest.php @@ -57,14 +57,14 @@ public function testSharedFixtures(): void $executor->execute([$roleFixture, $userFixture], true); $referenceRepository = $executor->getReferenceRepository(); - $references = $referenceRepository->getReferences(); + $references = $referenceRepository->getReferencesByClass(); $this->assertCount(2, $references); - $roleReference = $referenceRepository->getReference('admin-role'); + $roleReference = $referenceRepository->getReference('admin-role', Role::class); $this->assertInstanceOf(Role::class, $roleReference); $this->assertEquals('admin', $roleReference->getName()); - $userReference = $referenceRepository->getReference('admin'); + $userReference = $referenceRepository->getReference('admin', User::class); $this->assertInstanceOf(User::class, $userReference); $this->assertEquals('admin@example.com', $userReference->getEmail()); } diff --git a/tests/Common/DataFixtures/ProxyReferenceRepositoryTest.php b/tests/Common/DataFixtures/ProxyReferenceRepositoryTest.php index 75bf6f07..dd5a8f9c 100644 --- a/tests/Common/DataFixtures/ProxyReferenceRepositoryTest.php +++ b/tests/Common/DataFixtures/ProxyReferenceRepositoryTest.php @@ -44,11 +44,13 @@ public function testReferenceEntry(): void $referenceRepo = new ProxyReferenceRepository($em); $referenceRepo->addReference('test', $role); - $references = $referenceRepo->getReferences(); + $referencesByClass = $referenceRepo->getReferencesByClass(); - $this->assertCount(1, $references); - $this->assertArrayHasKey('test', $references); - $this->assertInstanceOf(self::TEST_ENTITY_ROLE, $references['test']); + $this->assertCount(1, $referencesByClass); + $this->assertArrayHasKey(Role::class, $referencesByClass); + $this->assertCount(1, $referencesByClass[Role::class]); + $this->assertArrayHasKey('test', $referencesByClass[Role::class]); + $this->assertInstanceOf(self::TEST_ENTITY_ROLE, $referencesByClass[Role::class]['test']); } public function testReferenceIdentityPopulation(): void @@ -96,7 +98,7 @@ public function testReferenceReconstruction(): void $roleFixture->load($em); // first test against managed state - $ref = $referenceRepository->getReference('admin-role'); + $ref = $referenceRepository->getReference('admin-role', Role::class); $this->assertNotInstanceOf(Proxy::class, $ref); @@ -106,7 +108,7 @@ public function testReferenceReconstruction(): void $proxyReferenceRepository = new ProxyReferenceRepository($em); $proxyReferenceRepository->unserialize($serializedData); - $ref = $proxyReferenceRepository->getReference('admin-role'); + $ref = $proxyReferenceRepository->getReference('admin-role', Role::class); // before clearing, the reference is not yet a proxy $this->assertNotInstanceOf(Proxy::class, $ref); @@ -114,7 +116,7 @@ public function testReferenceReconstruction(): void // now test reference reconstruction from identity $em->clear(); - $ref = $referenceRepository->getReference('admin-role'); + $ref = $referenceRepository->getReference('admin-role', Role::class); $this->assertInstanceOf(Proxy::class, $ref); @@ -124,7 +126,7 @@ public function testReferenceReconstruction(): void $proxyReferenceRepository = new ProxyReferenceRepository($em); $proxyReferenceRepository->unserialize($serializedData); - $ref = $proxyReferenceRepository->getReference('admin-role'); + $ref = $proxyReferenceRepository->getReference('admin-role', Role::class); $this->assertInstanceOf(Proxy::class, $ref); } @@ -154,7 +156,7 @@ public function testReconstructionOfCustomTypedId(): void $this->assertInstanceOf( 'Doctrine\Tests\Common\DataFixtures\TestValueObjects\Uuid', - $proxyReferenceRepository->getReference('home-link')->getId(), + $proxyReferenceRepository->getReference('home-link', Link::class)->getId(), ); } @@ -175,7 +177,7 @@ public function testReferenceMultipleEntries(): void $em->flush(); $em->clear(); - $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin')); - $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate')); + $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin', Role::class)); + $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate', Role::class)); } } diff --git a/tests/Common/DataFixtures/ReferenceRepositoryTest.php b/tests/Common/DataFixtures/ReferenceRepositoryTest.php index 95b66de5..586f6108 100644 --- a/tests/Common/DataFixtures/ReferenceRepositoryTest.php +++ b/tests/Common/DataFixtures/ReferenceRepositoryTest.php @@ -12,9 +12,12 @@ use Doctrine\ORM\UnitOfWork; use Doctrine\Persistence\Proxy; use Doctrine\Tests\Common\DataFixtures\TestEntity\Role; +use Doctrine\Tests\Common\DataFixtures\TestEntity\User; use Doctrine\Tests\Mock\ForwardCompatibleEntityManager; use OutOfBoundsException; +use function sprintf; + class ReferenceRepositoryTest extends BaseTestCase { public function testReferenceEntry(): void @@ -32,10 +35,12 @@ public function testReferenceEntry(): void $referenceRepo->addReference('test', $role); - $references = $referenceRepo->getReferences(); - $this->assertCount(1, $references); - $this->assertArrayHasKey('test', $references); - $this->assertInstanceOf(Role::class, $references['test']); + $referencesByClass = $referenceRepo->getReferencesByClass(); + $this->assertCount(1, $referencesByClass); + $this->assertArrayHasKey(Role::class, $referencesByClass); + $this->assertCount(1, $referencesByClass[Role::class]); + $this->assertArrayHasKey('test', $referencesByClass[Role::class]); + $this->assertInstanceOf(Role::class, $referencesByClass[Role::class]['test']); } public function testReferenceIdentityPopulation(): void @@ -84,13 +89,13 @@ public function testReferenceReconstruction(): void $roleFixture->load($em); // first test against managed state - $ref = $referenceRepository->getReference('admin-role'); + $ref = $referenceRepository->getReference('admin-role', Role::class); $this->assertNotInstanceOf(Proxy::class, $ref); // now test reference reconstruction from identity $em->clear(); - $ref = $referenceRepository->getReference('admin-role'); + $ref = $referenceRepository->getReference('admin-role', Role::class); $this->assertInstanceOf(Proxy::class, $ref); } @@ -112,8 +117,8 @@ public function testReferenceMultipleEntries(): void $em->flush(); $em->clear(); - $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin')); - $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate')); + $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin', Role::class)); + $this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate', Role::class)); } public function testUndefinedReference(): void @@ -121,9 +126,9 @@ public function testUndefinedReference(): void $referenceRepository = new ReferenceRepository($this->getMockSqliteEntityManager()); $this->expectException(OutOfBoundsException::class); - $this->expectExceptionMessage('Reference to "foo" does not exist'); + $this->expectExceptionMessage(sprintf('Reference to "foo" for class "%s" does not exist', Role::class)); - $referenceRepository->getReference('foo'); + $referenceRepository->getReference('foo', Role::class); } public function testThrowsExceptionAddingDuplicatedReference(): void @@ -134,32 +139,43 @@ public function testThrowsExceptionAddingDuplicatedReference(): void $referenceRepository->addReference('duplicated_reference', new Role()); $this->expectException(BadMethodCallException::class); - $this->expectExceptionMessage( - 'Reference to "duplicated_reference" already exists, use method setReference() in order to override it', - ); + $this->expectExceptionMessage(sprintf( + 'Reference to "duplicated_reference" for class "%s" already exists, use method setReference() in order to override it', + Role::class, + )); $referenceRepository->addReference('duplicated_reference', new Role()); } + public function testThereIsNoDuplicateWithDifferentClasses(): void + { + $em = $this->getMockSqliteEntityManager(); + $referenceRepository = new ReferenceRepository($em); + + $referenceRepository->addReference('not_duplicated_reference', new Role()); + $referenceRepository->addReference('not_duplicated_reference', new User()); + + static::assertCount(2, $referenceRepository->getReferencesByClass()); + } + public function testThrowsExceptionTryingToGetWrongReference(): void { $referenceRepository = new ReferenceRepository($this->getMockSqliteEntityManager()); $this->expectException(OutOfBoundsException::class); - $this->expectExceptionMessage('Reference to "missing_reference" does not exist'); + $this->expectExceptionMessage(sprintf('Reference to "missing_reference" for class "%s" does not exist', Role::class)); - $referenceRepository->getReference('missing_reference'); + $referenceRepository->getReference('missing_reference', Role::class); } public function testHasIdentityCheck(): void { - $role = new Role(); $referenceRepository = new ReferenceRepository($this->getMockSqliteEntityManager()); - $referenceRepository->setReferenceIdentity('entity', $role); + $referenceRepository->setReferenceIdentity('entity', 1, Role::class); - $this->assertTrue($referenceRepository->hasIdentity('entity')); - $this->assertFalse($referenceRepository->hasIdentity('invalid_entity')); - $this->assertEquals(['entity' => $role], $referenceRepository->getIdentities()); + $this->assertTrue($referenceRepository->hasIdentity('entity', Role::class)); + $this->assertFalse($referenceRepository->hasIdentity('invalid_entity', Role::class)); + $this->assertEquals(['entity' => 1], $referenceRepository->getIdentitiesByClass()[Role::class] ?? []); } public function testSetReferenceHavingIdentifier(): void @@ -177,7 +193,7 @@ public function testSetReferenceHavingIdentifier(): void $em->flush(); $referenceRepository->setReference('entity', $role); - $identities = $referenceRepository->getIdentities(); + $identities = $referenceRepository->getIdentitiesByClass()[Role::class] ?? []; $this->assertCount(1, $identities); $this->assertArrayHasKey('entity', $identities); } @@ -198,6 +214,9 @@ public function testGetIdentifierWhenHasNotBeenManagedYetByUnitOfWork(): void ->method('getIdentifierValues') ->with($role) ->willReturn($identitiesExpected); + $classMetadata->expects($this->once()) + ->method('getName') + ->willReturn(Role::class); $em = $this->createMock(ForwardCompatibleEntityManager::class); $em->method('getUnitOfWork') @@ -208,7 +227,7 @@ public function testGetIdentifierWhenHasNotBeenManagedYetByUnitOfWork(): void $referenceRepository = new ReferenceRepository($em); $referenceRepository->setReference('entity', $role); - $identities = $referenceRepository->getIdentities(); + $identities = $referenceRepository->getIdentitiesByClass()[Role::class] ?? []; $this->assertEquals($identitiesExpected, $identities['entity']); } diff --git a/tests/Common/DataFixtures/TestFixtures/UserFixture.php b/tests/Common/DataFixtures/TestFixtures/UserFixture.php index 383150ff..972b9a01 100644 --- a/tests/Common/DataFixtures/TestFixtures/UserFixture.php +++ b/tests/Common/DataFixtures/TestFixtures/UserFixture.php @@ -6,6 +6,7 @@ use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Persistence\ObjectManager; +use Doctrine\Tests\Common\DataFixtures\TestEntity\Role; use Doctrine\Tests\Common\DataFixtures\TestEntity\User; class UserFixture extends AbstractFixture @@ -17,7 +18,7 @@ public function load(ObjectManager $manager): void $admin->setCode('007'); $admin->setEmail('admin@example.com'); $admin->setPassword('secret'); - $role = $this->getReference('admin-role'); + $role = $this->getReference('admin-role', Role::class); $admin->setRole($role); $manager->persist($admin); From 6985e4c5c680ff6a7fe9cc495a7c2c00b97cf608 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 19 Dec 2023 13:36:18 +0100 Subject: [PATCH 2/2] Add upgrade note --- UPGRADE.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/UPGRADE.md b/UPGRADE.md index 77e9fff0..ee59099b 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -10,6 +10,17 @@ awareness about deprecated code. You need PHP 8.1 or newer to use this library. +For the following method, the `class` param is now mandatory: +- `AbstractFixture::getReference` +- `AbstractFixture::hasReference` +- `ReferenceRepository::setReferenceIdentity` +- `ReferenceRepository::hasIdentity` +- `ReferenceRepository::getReference` +- `ReferenceRepository::setReference` + +The following method was removed: +- `ReferenceRepository::getReferences` + # Upgrade to 1.8 Executor and Purger classes are final, they cannot be extended.