Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ReflectionClass::newLazyGhost of PHP 8.4 #11652

Draft
wants to merge 2 commits into
base: 3.3.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@ parameters:
count: 1
path: src/Proxy/ProxyFactory.php

-
message: "#^Call to an undefined method ReflectionClass\\<object\\>\\:\\:newLazyGhost\\(\\)\\.$#"
count: 1
path: src/Proxy/ProxyFactory.php

-
message: "#^Call to an undefined method ReflectionProperty\\:\\:setRawValueWithoutLazyInitialization\\(\\)\\.$#"
count: 1
path: src/Proxy/ProxyFactory.php

-
message: "#^Call to an undefined static method Doctrine\\\\ORM\\\\Proxy\\\\ProxyFactory\\:\\:createLazyGhost\\(\\)\\.$#"
count: 1
Expand Down
16 changes: 16 additions & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
use function is_a;
use function strtolower;

use const PHP_VERSION_ID;

/**
* Configuration container for all configuration options of Doctrine.
* It combines all configuration options from DBAL & ORM.
Expand Down Expand Up @@ -595,6 +597,20 @@ public function setSchemaIgnoreClasses(array $schemaIgnoreClasses): void
$this->attributes['schemaIgnoreClasses'] = $schemaIgnoreClasses;
}

public function isLazyProxyEnabled(): bool
{
return $this->attributes['lazyProxy'] ?? false;
}

public function setLazyProxyEnabled(bool $lazyProxy): void
{
if (PHP_VERSION_ID < 80400) {
throw new LogicException('Lazy loading proxies require PHP 8.4 or higher.');
}

$this->attributes['lazyProxy'] = $lazyProxy;
}

/**
* To be deprecated in 3.1.0
*
Expand Down
41 changes: 40 additions & 1 deletion src/Proxy/ProxyFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,43 @@
* @param class-string $className
* @param array<mixed> $identifier
*/
public function getProxy(string $className, array $identifier): InternalProxy
public function getProxy(string $className, array $identifier): object
{
if ($this->em->getConfiguration()->isLazyProxyEnabled()) {
$classMetadata = $this->em->getClassMetadata($className);
$entityPersister = $this->uow->getEntityPersister($className);

$proxy = $classMetadata->reflClass->newLazyGhost(static function ($object) use ($identifier, $entityPersister): void {

Check failure on line 172 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

PossiblyNullReference

src/Proxy/ProxyFactory.php:172:49: PossiblyNullReference: Cannot call method newLazyGhost on possibly null value (see https://psalm.dev/083)

Check failure on line 172 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedMethod

src/Proxy/ProxyFactory.php:172:49: UndefinedMethod: Method ReflectionClass::newLazyGhost does not exist (see https://psalm.dev/022)

Check failure on line 172 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

MissingClosureParamType

src/Proxy/ProxyFactory.php:172:79: MissingClosureParamType: Parameter $object has no provided type (see https://psalm.dev/153)

Check failure on line 172 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

PossiblyNullReference

src/Proxy/ProxyFactory.php:172:49: PossiblyNullReference: Cannot call method newLazyGhost on possibly null value (see https://psalm.dev/083)

Check failure on line 172 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedMethod

src/Proxy/ProxyFactory.php:172:49: UndefinedMethod: Method ReflectionClass::newLazyGhost does not exist (see https://psalm.dev/022)

Check failure on line 172 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

MissingClosureParamType

src/Proxy/ProxyFactory.php:172:79: MissingClosureParamType: Parameter $object has no provided type (see https://psalm.dev/153)
$entityPersister->loadById($identifier, $object);
});

foreach ($identifier as $idField => $value) {
$classMetadata->reflFields[$idField]->setRawValueWithoutLazyInitialization($proxy, $value);

Check failure on line 177 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

PossiblyNullReference

src/Proxy/ProxyFactory.php:177:55: PossiblyNullReference: Cannot call method setRawValueWithoutLazyInitialization on possibly null value (see https://psalm.dev/083)

Check failure on line 177 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedMethod

src/Proxy/ProxyFactory.php:177:55: UndefinedMethod: Method ReflectionProperty::setRawValueWithoutLazyInitialization does not exist (see https://psalm.dev/022)

Check failure on line 177 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

PossiblyNullReference

src/Proxy/ProxyFactory.php:177:55: PossiblyNullReference: Cannot call method setRawValueWithoutLazyInitialization on possibly null value (see https://psalm.dev/083)

Check failure on line 177 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedMethod

src/Proxy/ProxyFactory.php:177:55: UndefinedMethod: Method ReflectionProperty::setRawValueWithoutLazyInitialization does not exist (see https://psalm.dev/022)
}

// todo: this skipLazyInitialization for properites calculation must be moved into ClassMetadata partially
$identifiers = array_flip($classMetadata->getIdentifierFieldNames());
$filter = ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE;
$reflector = $classMetadata->getReflectionClass();

while ($reflector) {
foreach ($reflector->getProperties($filter) as $property) {
$name = $property->name;

if ($property->isStatic() || (($classMetadata->hasField($name) || $classMetadata->hasAssociation($name)) && ! isset($identifiers[$name]))) {
continue;
}

$property->skipLazyInitialization($proxy);

Check failure on line 193 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedMethod

src/Proxy/ProxyFactory.php:193:32: UndefinedMethod: Method ReflectionProperty::skipLazyInitialization does not exist (see https://psalm.dev/022)

Check failure on line 193 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedMethod

src/Proxy/ProxyFactory.php:193:32: UndefinedMethod: Method ReflectionProperty::skipLazyInitialization does not exist (see https://psalm.dev/022)

Check failure on line 193 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to an undefined method ReflectionProperty::skipLazyInitialization().

Check failure on line 193 in src/Proxy/ProxyFactory.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to an undefined method ReflectionProperty::skipLazyInitialization().
}

$filter = ReflectionProperty::IS_PRIVATE;
$reflector = $reflector->getParentClass();
}

return $proxy;
}

$proxyFactory = $this->proxyFactories[$className] ?? $this->getProxyFactory($className);

return $proxyFactory($identifier);
Expand All @@ -182,6 +217,10 @@
*/
public function generateProxyClasses(array $classes, string|null $proxyDir = null): int
{
if ($this->em->getConfiguration()->isLazyProxyEnabled()) {
return 0;
}

$generated = 0;

foreach ($classes as $class) {
Expand Down
17 changes: 16 additions & 1 deletion src/UnitOfWork.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
use Doctrine\Persistence\PropertyChangedListener;
use Exception;
use InvalidArgumentException;
use ReflectionObject;
use RuntimeException;
use Stringable;
use Throwable;
Expand All @@ -64,6 +65,7 @@
use function array_values;
use function assert;
use function current;
use function get_class;
use function get_debug_type;
use function implode;
use function in_array;
Expand Down Expand Up @@ -2382,8 +2384,12 @@
}
}

if ($this->isUninitializedObject($entity)) {

Check failure on line 2387 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

PossiblyNullReference

src/UnitOfWork.php:2387:40: PossiblyNullReference: Cannot call method markLazyObjectAsInitialized on possibly null value (see https://psalm.dev/083)

Check failure on line 2387 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedMethod

src/UnitOfWork.php:2387:40: UndefinedMethod: Method ReflectionClass::markLazyObjectAsInitialized does not exist (see https://psalm.dev/022)

Check failure on line 2387 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

PossiblyNullReference

src/UnitOfWork.php:2387:40: PossiblyNullReference: Cannot call method markLazyObjectAsInitialized on possibly null value (see https://psalm.dev/083)

Check failure on line 2387 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedMethod

src/UnitOfWork.php:2387:40: UndefinedMethod: Method ReflectionClass::markLazyObjectAsInitialized does not exist (see https://psalm.dev/022)

Check failure on line 2387 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to an undefined method ReflectionClass<object>::markLazyObjectAsInitialized().

Check failure on line 2387 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to an undefined method ReflectionClass<object>::markLazyObjectAsInitialized().
$entity->__setInitialized(true);
if ($this->em->getConfiguration()->isLazyProxyEnabled()) {
$class->reflClass->markLazyObjectAsInitialized($entity);
} else {
$entity->__setInitialized(true);
}
} else {
if (
! isset($hints[Query::HINT_REFRESH])
Expand Down Expand Up @@ -3040,6 +3046,11 @@
if ($obj instanceof PersistentCollection) {
$obj->initialize();
}

Check failure on line 3049 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

UndefinedMethod

src/UnitOfWork.php:3049:26: UndefinedMethod: Method ReflectionObject::initializeLazyObject does not exist (see https://psalm.dev/022)

Check failure on line 3049 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

UndefinedMethod

src/UnitOfWork.php:3049:26: UndefinedMethod: Method ReflectionObject::initializeLazyObject does not exist (see https://psalm.dev/022)

Check failure on line 3049 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to an undefined method ReflectionObject::initializeLazyObject().

Check failure on line 3049 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to an undefined method ReflectionObject::initializeLazyObject().
if ($this->em->getConfiguration()->isLazyProxyEnabled()) {
$reflection = new ReflectionObject($obj);
$reflection->initializeLazyObject($obj);
}
}

/**
Expand All @@ -3047,8 +3058,12 @@
*
* @psalm-assert-if-true InternalProxy $obj
*/
public function isUninitializedObject(mixed $obj): bool

Check failure on line 3061 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (default)

PossiblyNullReference

src/UnitOfWork.php:3061:77: PossiblyNullReference: Cannot call method isUninitializedLazyObject on possibly null value (see https://psalm.dev/083)

Check failure on line 3061 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with Psalm (3.8.2)

PossiblyNullReference

src/UnitOfWork.php:3061:77: PossiblyNullReference: Cannot call method isUninitializedLazyObject on possibly null value (see https://psalm.dev/083)

Check failure on line 3061 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to an undefined method ReflectionClass<object>::isUninitializedLazyObject().

Check failure on line 3061 in src/UnitOfWork.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to an undefined method ReflectionClass<object>::isUninitializedLazyObject().
{
if ($this->em->getConfiguration()->isLazyProxyEnabled() && ! ($obj instanceof Collection)) {
return $this->em->getClassMetadata(get_class($obj))->reflClass->isUninitializedLazyObject($obj);
}

return $obj instanceof InternalProxy && ! $obj->__isInitialized();
}

Expand Down
7 changes: 3 additions & 4 deletions tests/Tests/ORM/Functional/BasicFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\ORMInvalidArgumentException;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Proxy\InternalProxy;

Check failure on line 12 in tests/Tests/ORM/Functional/BasicFunctionalTest.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Type Doctrine\ORM\Proxy\InternalProxy is not used in this file.
use Doctrine\ORM\Query;
use Doctrine\ORM\UnitOfWork;
use Doctrine\Tests\IterableTester;
Expand Down Expand Up @@ -557,7 +557,7 @@
$this->_em->persist($article);
$this->_em->flush();

self::assertFalse($userRef->__isInitialized());
self::assertTrue($this->isUninitializedObject($userRef));

$this->_em->clear();

Expand Down Expand Up @@ -592,7 +592,7 @@
$this->_em->persist($user);
$this->_em->flush();

self::assertFalse($groupRef->__isInitialized());
self::assertTrue($this->isUninitializedObject($groupRef));

$this->_em->clear();

Expand Down Expand Up @@ -940,8 +940,7 @@
->setParameter(1, $article->id)
->setFetchMode(CmsArticle::class, 'user', ClassMetadata::FETCH_EAGER)
->getSingleResult();
self::assertInstanceOf(InternalProxy::class, $article->user, 'It IS a proxy, ...');
self::assertFalse($this->isUninitializedObject($article->user), '...but its initialized!');
self::assertFalse($this->isUninitializedObject($article->user));
$this->assertQueryCount(2);
}

Expand Down
4 changes: 4 additions & 0 deletions tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ protected function setUp(): void
{
parent::setUp();

if ($this->_em->getConfiguration()->isLazyProxyEnabled()) {
self::markTestSkipped('This test is not applicable when lazy proxy is enabled.');
}

$this->createSchemaForModels(
CmsUser::class,
CmsTag::class,
Expand Down
3 changes: 1 addition & 2 deletions tests/Tests/ORM/Functional/ReferenceProxyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Doctrine\Common\Proxy\Proxy as CommonProxy;
use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
use Doctrine\ORM\Proxy\InternalProxy;

Check failure on line 9 in tests/Tests/ORM/Functional/ReferenceProxyTest.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Type Doctrine\ORM\Proxy\InternalProxy is not used in this file.
use Doctrine\Tests\Models\Company\CompanyAuction;
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
use Doctrine\Tests\Models\ECommerce\ECommerceProduct2;
Expand Down Expand Up @@ -248,7 +248,6 @@
assert($entity instanceof ECommerceProduct);
$className = DefaultProxyClassNameResolver::getClass($entity);

self::assertInstanceOf(InternalProxy::class, $entity);
self::assertTrue($this->isUninitializedObject($entity));
self::assertEquals(ECommerceProduct::class, $className);

Expand All @@ -257,7 +256,7 @@
$proxyFileName = $this->_em->getConfiguration()->getProxyDir() . DIRECTORY_SEPARATOR . str_replace('\\', '', $restName) . '.php';
self::assertTrue(file_exists($proxyFileName), 'Proxy file name cannot be found generically.');

$entity->__load();
$this->initializeObject($entity);
self::assertFalse($this->isUninitializedObject($entity));
}
}
5 changes: 0 additions & 5 deletions tests/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use Doctrine\ORM\Cache\Exception\CacheException;
use Doctrine\ORM\Cache\QueryCacheEntry;
use Doctrine\ORM\Cache\QueryCacheKey;
use Doctrine\ORM\Proxy\InternalProxy;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Tests\Models\Cache\Attraction;
Expand Down Expand Up @@ -939,7 +938,6 @@ public function testResolveAssociationCacheEntry(): void
self::assertNotNull($state1->getCountry());
$this->assertQueryCount(1);
self::assertInstanceOf(State::class, $state1);
self::assertInstanceOf(InternalProxy::class, $state1->getCountry());
self::assertEquals($countryName, $state1->getCountry()->getName());
self::assertEquals($stateId, $state1->getId());

Expand All @@ -957,7 +955,6 @@ public function testResolveAssociationCacheEntry(): void
self::assertNotNull($state2->getCountry());
$this->assertQueryCount(0);
self::assertInstanceOf(State::class, $state2);
self::assertInstanceOf(InternalProxy::class, $state2->getCountry());
self::assertEquals($countryName, $state2->getCountry()->getName());
self::assertEquals($stateId, $state2->getId());
}
Expand Down Expand Up @@ -1031,7 +1028,6 @@ public function testResolveToManyAssociationCacheEntry(): void

$this->assertQueryCount(1);
self::assertInstanceOf(State::class, $state1);
self::assertInstanceOf(InternalProxy::class, $state1->getCountry());
self::assertInstanceOf(City::class, $state1->getCities()->get(0));
self::assertInstanceOf(State::class, $state1->getCities()->get(0)->getState());
self::assertSame($state1, $state1->getCities()->get(0)->getState());
Expand All @@ -1048,7 +1044,6 @@ public function testResolveToManyAssociationCacheEntry(): void

$this->assertQueryCount(0);
self::assertInstanceOf(State::class, $state2);
self::assertInstanceOf(InternalProxy::class, $state2->getCountry());
self::assertInstanceOf(City::class, $state2->getCities()->get(0));
self::assertInstanceOf(State::class, $state2->getCities()->get(0)->getState());
self::assertSame($state2, $state2->getCities()->get(0)->getState());
Expand Down
8 changes: 0 additions & 8 deletions tests/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Doctrine\Tests\ORM\Functional;

use Doctrine\ORM\Proxy\InternalProxy;

Check failure on line 7 in tests/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Type Doctrine\ORM\Proxy\InternalProxy is not used in this file.
use Doctrine\Tests\Models\Cache\Country;
use Doctrine\Tests\Models\Cache\State;
use PHPUnit\Framework\Attributes\Group;
Expand Down Expand Up @@ -198,8 +198,6 @@
self::assertInstanceOf(State::class, $entities[1]);
self::assertInstanceOf(Country::class, $entities[0]->getCountry());
self::assertInstanceOf(Country::class, $entities[0]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[0]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[1]->getCountry());

// load from cache
$this->getQueryLog()->reset()->enable();
Expand All @@ -212,8 +210,6 @@
self::assertInstanceOf(State::class, $entities[1]);
self::assertInstanceOf(Country::class, $entities[0]->getCountry());
self::assertInstanceOf(Country::class, $entities[1]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[0]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[1]->getCountry());

// invalidate cache
$this->_em->persist(new State('foo', $this->_em->find(Country::class, $this->countries[0]->getId())));
Expand All @@ -231,8 +227,6 @@
self::assertInstanceOf(State::class, $entities[1]);
self::assertInstanceOf(Country::class, $entities[0]->getCountry());
self::assertInstanceOf(Country::class, $entities[1]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[0]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[1]->getCountry());

// load from cache
$this->getQueryLog()->reset()->enable();
Expand All @@ -245,7 +239,5 @@
self::assertInstanceOf(State::class, $entities[1]);
self::assertInstanceOf(Country::class, $entities[0]->getCountry());
self::assertInstanceOf(Country::class, $entities[1]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[0]->getCountry());
self::assertInstanceOf(InternalProxy::class, $entities[1]->getCountry());
}
}
4 changes: 2 additions & 2 deletions tests/Tests/ORM/Functional/Ticket/DDC1238Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ public function testIssueProxyClear(): void

$user2 = $this->_em->getReference(DDC1238User::class, $userId);

//$user->__load();
//$this->initializeObject($user);

self::assertIsInt($user->getId(), 'Even if a proxy is detached, it should still have an identifier');

$user2->__load();
$this->initializeObject($user2);

self::assertIsInt($user2->getId(), 'The managed instance still has an identifier');
}
Expand Down
13 changes: 3 additions & 10 deletions tests/Tests/ORM/Functional/Ticket/GH10808Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Doctrine\Tests\OrmFunctionalTestCase;
use PHPUnit\Framework\Attributes\Group;

use function get_class;

Check failure on line 18 in tests/Tests/ORM/Functional/Ticket/GH10808Test.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Type get_class is not used in this file.

#[Group('GH10808')]
class GH10808Test extends OrmFunctionalTestCase
Expand Down Expand Up @@ -49,18 +49,11 @@
// Clear the EM to prevent the recovery of the loaded instance, which would otherwise result in a proxy.
$this->_em->clear();

self::assertTrue($this->_em->getUnitOfWork()->isUninitializedObject($deferredLoadResult->child));

$eagerLoadResult = $query->setHint(UnitOfWork::HINT_DEFEREAGERLOAD, false)->getSingleResult();

self::assertNotEquals(
GH10808AppointmentChild::class,
get_class($deferredLoadResult->child),
'$deferredLoadResult->child should be a proxy',
);
self::assertEquals(
GH10808AppointmentChild::class,
get_class($eagerLoadResult->child),
'$eagerLoadResult->child should not be a proxy',
);
self::assertFalse($this->_em->getUnitOfWork()->isUninitializedObject($eagerLoadResult->child));
}
}

Expand Down
13 changes: 13 additions & 0 deletions tests/Tests/OrmFunctionalTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\ORM\Proxy\InternalProxy;

Check failure on line 25 in tests/Tests/OrmFunctionalTestCase.php

View workflow job for this annotation

GitHub Actions / coding-standards / Coding Standards (8.3)

Type Doctrine\ORM\Proxy\InternalProxy is not used in this file.
use Doctrine\ORM\Tools\DebugUnitOfWorkListener;
use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\ORM\Tools\ToolsException;
Expand Down Expand Up @@ -193,6 +194,7 @@
use function var_export;

use const PHP_EOL;
use const PHP_VERSION_ID;

/**
* Base testcase class for all functional ORM testcases.
Expand Down Expand Up @@ -941,6 +943,12 @@
$this->isSecondLevelCacheEnabled = true;
}

$enableLazyProxy = getenv('ENABLE_LAZY_PROXY');

if (PHP_VERSION_ID >= 80400 && $enableLazyProxy) {
$config->setLazyProxyEnabled(true);
}

$config->setMetadataDriverImpl(
$mappingDriver ?? new AttributeDriver([
realpath(__DIR__ . '/Models/Cache'),
Expand Down Expand Up @@ -1118,4 +1126,9 @@
{
return $this->_em->getUnitOfWork()->isUninitializedObject($entity);
}

final protected function initializeObject(object $entity): void
{
$this->_em->getUnitOfWork()->initializeObject($entity);
}
}
Loading