Skip to content

Commit 8c42712

Browse files
Don't rely on LazyProxyTrait in LazyServiceEntityRepository (#1727)
1 parent ca64ca7 commit 8c42712

File tree

3 files changed

+67
-107
lines changed

3 files changed

+67
-107
lines changed

Repository/LazyServiceEntityRepository.php

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
use Doctrine\ORM\EntityRepository;
66
use Doctrine\Persistence\ManagerRegistry;
77
use LogicException;
8-
use Symfony\Component\VarExporter\LazyGhostTrait;
98
use Symfony\Component\VarExporter\LazyObjectInterface;
109

10+
use function debug_backtrace;
1111
use function sprintf;
1212

13+
use const DEBUG_BACKTRACE_IGNORE_ARGS;
14+
1315
/**
1416
* @internal Extend {@see ServiceEntityRepository} instead.
1517
*
@@ -18,41 +20,63 @@
1820
*/
1921
class LazyServiceEntityRepository extends EntityRepository implements ServiceEntityRepositoryInterface
2022
{
21-
use LazyGhostTrait {
22-
createLazyGhost as private;
23-
}
23+
private ManagerRegistry $registry;
24+
private string $entityClass;
2425

2526
/**
2627
* @param string $entityClass The class name of the entity this repository manages
2728
* @psalm-param class-string<T> $entityClass
2829
*/
2930
public function __construct(ManagerRegistry $registry, string $entityClass)
3031
{
31-
$initializer = function ($instance, $property) use ($registry, $entityClass) {
32-
$manager = $registry->getManagerForClass($entityClass);
32+
$this->registry = $registry;
33+
$this->entityClass = $entityClass;
3334

34-
if ($manager === null) {
35-
throw new LogicException(sprintf(
36-
'Could not find the entity manager for class "%s". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.',
37-
$entityClass,
38-
));
39-
}
35+
if ($this instanceof LazyObjectInterface) {
36+
$this->initialize();
37+
38+
return;
39+
}
4040

41-
parent::__construct($manager, $manager->getClassMetadata($entityClass));
41+
unset($this->_em);
42+
unset($this->_class);
43+
unset($this->_entityName);
44+
}
4245

43-
return $this->$property;
44-
};
46+
/** @return mixed */
47+
public function __get(string $name)
48+
{
49+
$this->initialize();
4550

46-
if ($this instanceof LazyObjectInterface) {
47-
$initializer($this, '_entityName');
51+
$scope = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] ?? null;
4852

49-
return;
53+
return (function () use ($name) {
54+
return $this->$name;
55+
})->bindTo($this, $scope)();
56+
}
57+
58+
public function __isset(string $name): bool
59+
{
60+
$this->initialize();
61+
62+
$scope = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] ?? null;
63+
64+
return (function () use ($name) {
65+
return isset($this->$name);
66+
})->bindTo($this, $scope)();
67+
}
68+
69+
private function initialize(): void
70+
{
71+
$manager = $this->registry->getManagerForClass($this->entityClass);
72+
73+
if ($manager === null) {
74+
throw new LogicException(sprintf(
75+
'Could not find the entity manager for class "%s". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.',
76+
$this->entityClass,
77+
));
5078
}
5179

52-
self::createLazyGhost([
53-
"\0*\0_em" => $initializer,
54-
"\0*\0_class" => $initializer,
55-
"\0*\0_entityName" => $initializer,
56-
], null, $this);
80+
parent::__construct($manager, $manager->getClassMetadata($this->entityClass));
5781
}
5882
}

Repository/LegacyServiceEntityRepository.php

Lines changed: 0 additions & 38 deletions
This file was deleted.

Repository/ServiceEntityRepository.php

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,30 @@
33
namespace Doctrine\Bundle\DoctrineBundle\Repository;
44

55
use Doctrine\ORM\EntityRepository;
6-
use Symfony\Component\VarExporter\LazyGhostTrait;
76

87
use function property_exists;
9-
use function trait_exists;
108

119
if (property_exists(EntityRepository::class, '_entityName')) {
12-
if (trait_exists(LazyGhostTrait::class)) {
13-
// ORM 2 with VarExporter
14-
/**
15-
* Optional EntityRepository base class with a simplified constructor (for autowiring).
16-
*
17-
* To use in your class, inject the "registry" service and call
18-
* the parent constructor. For example:
19-
*
20-
* class YourEntityRepository extends ServiceEntityRepository
21-
* {
22-
* public function __construct(ManagerRegistry $registry)
23-
* {
24-
* parent::__construct($registry, YourEntity::class);
25-
* }
26-
* }
27-
*
28-
* @template T of object
29-
* @template-extends LazyServiceEntityRepository<T>
30-
*/
31-
class ServiceEntityRepository extends LazyServiceEntityRepository
32-
{
33-
}
34-
} else {
35-
// ORM 2 without VarExporter
36-
/**
37-
* Optional EntityRepository base class with a simplified constructor (for autowiring).
38-
*
39-
* To use in your class, inject the "registry" service and call
40-
* the parent constructor. For example:
41-
*
42-
* class YourEntityRepository extends ServiceEntityRepository
43-
* {
44-
* public function __construct(ManagerRegistry $registry)
45-
* {
46-
* parent::__construct($registry, YourEntity::class);
47-
* }
48-
* }
49-
*
50-
* @template T of object
51-
* @template-extends LegacyServiceEntityRepository<T>
52-
*/
53-
class ServiceEntityRepository extends LegacyServiceEntityRepository
54-
{
55-
}
10+
// ORM 2
11+
/**
12+
* Optional EntityRepository base class with a simplified constructor (for autowiring).
13+
*
14+
* To use in your class, inject the "registry" service and call
15+
* the parent constructor. For example:
16+
*
17+
* class YourEntityRepository extends ServiceEntityRepository
18+
* {
19+
* public function __construct(ManagerRegistry $registry)
20+
* {
21+
* parent::__construct($registry, YourEntity::class);
22+
* }
23+
* }
24+
*
25+
* @template T of object
26+
* @template-extends LazyServiceEntityRepository<T>
27+
*/
28+
class ServiceEntityRepository extends LazyServiceEntityRepository
29+
{
5630
}
5731
} else {
5832
// ORM 3

0 commit comments

Comments
 (0)