1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace Doctrine\Tests\ORM\Functional; |
||||
6 | |||||
7 | use Doctrine\Tests\Models\CMS\CmsAddress; |
||||
8 | use Doctrine\Tests\Models\CMS\CmsArticle; |
||||
9 | use Doctrine\Tests\Models\CMS\CmsEmail; |
||||
10 | use Doctrine\Tests\Models\CMS\CmsGroup; |
||||
11 | use Doctrine\Tests\Models\CMS\CmsPhonenumber; |
||||
12 | use Doctrine\Tests\Models\CMS\CmsTag; |
||||
13 | use Doctrine\Tests\Models\CMS\CmsUser; |
||||
14 | use Doctrine\Tests\OrmFunctionalTestCase; |
||||
15 | use Exception; |
||||
16 | use ProxyManager\Configuration; |
||||
17 | use ProxyManager\Proxy\GhostObjectInterface; |
||||
18 | use function sprintf; |
||||
19 | |||||
20 | /** |
||||
21 | * Test that Doctrine ORM correctly works with proxy instances exactly like with ordinary Entities |
||||
22 | * |
||||
23 | * The test considers two possible cases: |
||||
24 | * a) __initialized__ = true and no identifier set in proxy |
||||
25 | * b) __initialized__ = false and identifier set in proxy and in property |
||||
26 | * |
||||
27 | * @todo All other cases would cause lazy loading |
||||
28 | */ |
||||
29 | class ProxiesLikeEntitiesTest extends OrmFunctionalTestCase |
||||
30 | { |
||||
31 | /** @var CmsUser */ |
||||
32 | protected $user; |
||||
33 | |||||
34 | /** @var string */ |
||||
35 | private $proxyClassName; |
||||
36 | |||||
37 | protected function setUp() : void |
||||
38 | { |
||||
39 | parent::setUp(); |
||||
40 | try { |
||||
41 | $this->schemaTool->createSchema( |
||||
42 | [ |
||||
43 | $this->em->getClassMetadata(CmsUser::class), |
||||
44 | $this->em->getClassMetadata(CmsTag::class), |
||||
45 | $this->em->getClassMetadata(CmsPhonenumber::class), |
||||
46 | $this->em->getClassMetadata(CmsArticle::class), |
||||
47 | $this->em->getClassMetadata(CmsAddress::class), |
||||
48 | $this->em->getClassMetadata(CmsEmail::class), |
||||
49 | $this->em->getClassMetadata(CmsGroup::class), |
||||
50 | ] |
||||
51 | ); |
||||
52 | } catch (Exception $e) { |
||||
53 | } |
||||
54 | $this->user = new CmsUser(); |
||||
55 | $this->user->username = 'ocramius'; |
||||
56 | $this->user->name = 'Marco'; |
||||
57 | $this->em->persist($this->user); |
||||
58 | $this->em->flush(); |
||||
59 | $this->em->clear(); |
||||
60 | |||||
61 | $this->proxyClassName = (new Configuration())->getClassNameInflector()->getProxyClassName(CmsUser::class); |
||||
62 | } |
||||
63 | |||||
64 | /** |
||||
65 | * Verifies that a proxy can be successfully persisted and updated |
||||
66 | */ |
||||
67 | public function testPersistUpdate() : void |
||||
68 | { |
||||
69 | // Considering case (a) |
||||
70 | $metadata = $this->em->getClassMetadata(CmsUser::class); |
||||
71 | $proxy = $this->em->getProxyFactory()->getProxy($metadata, ['id' => 123]); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
72 | |||||
73 | $proxy->setProxyInitializer(null); |
||||
74 | $proxy->id = null; |
||||
75 | $proxy->username = 'ocra'; |
||||
76 | $proxy->name = 'Marco'; |
||||
77 | |||||
78 | $this->em->persist($proxy); |
||||
79 | $this->em->flush(); |
||||
80 | |||||
81 | self::assertNotNull($proxy->getId()); |
||||
82 | |||||
83 | $proxy->name = 'Marco Pivetta'; |
||||
84 | |||||
85 | $this->em->getUnitOfWork()->computeChangeSet($metadata, $proxy); |
||||
0 ignored issues
–
show
$metadata of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $class of Doctrine\ORM\UnitOfWork::computeChangeSet() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
86 | self::assertNotEmpty($this->em->getUnitOfWork()->getEntityChangeSet($proxy)); |
||||
87 | self::assertEquals('Marco Pivetta', $this->em->find(CmsUser::class, $proxy->getId())->name); |
||||
88 | |||||
89 | $this->em->remove($proxy); |
||||
90 | $this->em->flush(); |
||||
91 | } |
||||
92 | |||||
93 | public function testEntityWithIdentifier() : void |
||||
94 | { |
||||
95 | $userId = $this->user->getId(); |
||||
96 | /** @var CmsUser|GhostObjectInterface $uninitializedProxy */ |
||||
97 | $uninitializedProxy = $this->em->getReference(CmsUser::class, $userId); |
||||
98 | self::assertInstanceOf(GhostObjectInterface::class, $uninitializedProxy); |
||||
99 | self::assertInstanceOf(CmsUser::class, $uninitializedProxy); |
||||
100 | self::assertFalse($uninitializedProxy->isProxyInitialized()); |
||||
101 | |||||
102 | $this->em->persist($uninitializedProxy); |
||||
103 | $this->em->flush(); |
||||
104 | self::assertFalse($uninitializedProxy->isProxyInitialized(), 'Proxy didn\'t get initialized during flush operations'); |
||||
105 | self::assertEquals($userId, $uninitializedProxy->getId()); |
||||
106 | $this->em->remove($uninitializedProxy); |
||||
107 | $this->em->flush(); |
||||
108 | } |
||||
109 | |||||
110 | /** |
||||
111 | * Verifying that proxies can be used without problems as query parameters |
||||
112 | */ |
||||
113 | public function testProxyAsDqlParameterPersist() : void |
||||
114 | { |
||||
115 | $proxy = $this->em->getProxyFactory()->getProxy( |
||||
116 | $this->em->getClassMetadata(CmsUser::class), |
||||
0 ignored issues
–
show
$this->em->getClassMetad...els\CMS\CmsUser::class) of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $metadata of Doctrine\ORM\Proxy\Facto...roxyFactory::getProxy() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
117 | ['id' => $this->user->getId()] |
||||
118 | ); |
||||
119 | |||||
120 | $proxy->id = $this->user->getId(); |
||||
121 | |||||
122 | $result = $this |
||||
123 | ->em |
||||
124 | ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u = ?1') |
||||
125 | ->setParameter(1, $proxy) |
||||
126 | ->getSingleResult(); |
||||
127 | |||||
128 | self::assertSame($this->user->getId(), $result->getId()); |
||||
129 | |||||
130 | $this->em->remove($proxy); |
||||
131 | $this->em->flush(); |
||||
132 | } |
||||
133 | |||||
134 | /** |
||||
135 | * Verifying that proxies can be used without problems as query parameters |
||||
136 | */ |
||||
137 | public function testFindWithProxyName() : void |
||||
138 | { |
||||
139 | self::assertNotEquals(CmsUser::class, $this->proxyClassName); |
||||
140 | |||||
141 | $result = $this->em->find($this->proxyClassName, $this->user->getId()); |
||||
142 | |||||
143 | self::assertSame($this->user->getId(), $result->getId()); |
||||
144 | |||||
145 | $this->em->clear(); |
||||
146 | |||||
147 | $result = $this->em->getReference($this->proxyClassName, $this->user->getId()); |
||||
148 | |||||
149 | self::assertSame($this->user->getId(), $result->getId()); |
||||
150 | |||||
151 | $this->em->clear(); |
||||
152 | |||||
153 | $result = $this->em->getRepository($this->proxyClassName)->findOneBy([ |
||||
154 | 'username' => $this->user->username, |
||||
155 | ]); |
||||
156 | |||||
157 | self::assertSame($this->user->getId(), $result->getId()); |
||||
158 | |||||
159 | $this->em->clear(); |
||||
160 | |||||
161 | $result = $this->em |
||||
162 | ->createQuery(sprintf('SELECT u FROM %s u WHERE u.id = ?1', $this->proxyClassName)) |
||||
163 | ->setParameter(1, $this->user->getId()) |
||||
164 | ->getSingleResult(); |
||||
165 | |||||
166 | self::assertSame($this->user->getId(), $result->getId()); |
||||
167 | |||||
168 | $this->em->clear(); |
||||
169 | } |
||||
170 | |||||
171 | protected function tearDown() : void |
||||
172 | { |
||||
173 | $this->em->createQuery('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u')->execute(); |
||||
174 | } |
||||
175 | } |
||||
176 |