1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Doctrine\Tests\ORM\Functional; |
||
6 | |||
7 | use Doctrine\DBAL\Logging\DebugStack; |
||
8 | use Doctrine\ORM\Mapping\FetchMode; |
||
9 | use Doctrine\ORM\ORMInvalidArgumentException; |
||
10 | use Doctrine\ORM\PersistentCollection; |
||
11 | use Doctrine\ORM\Query; |
||
12 | use Doctrine\ORM\UnitOfWork; |
||
13 | use Doctrine\Tests\Models\CMS\CmsAddress; |
||
14 | use Doctrine\Tests\Models\CMS\CmsArticle; |
||
15 | use Doctrine\Tests\Models\CMS\CmsComment; |
||
16 | use Doctrine\Tests\Models\CMS\CmsPhonenumber; |
||
17 | use Doctrine\Tests\Models\CMS\CmsUser; |
||
18 | use Doctrine\Tests\OrmFunctionalTestCase; |
||
19 | use ProxyManager\Proxy\GhostObjectInterface; |
||
20 | |||
21 | class BasicFunctionalTest extends OrmFunctionalTestCase |
||
22 | { |
||
23 | protected function setUp() |
||
24 | { |
||
25 | $this->useModelSet('cms'); |
||
26 | parent::setUp(); |
||
27 | } |
||
28 | |||
29 | public function testBasicUnitsOfWorkWithOneToManyAssociation() |
||
30 | { |
||
31 | // Create |
||
32 | $user = new CmsUser; |
||
33 | $user->name = 'Roman'; |
||
34 | $user->username = 'romanb'; |
||
35 | $user->status = 'developer'; |
||
36 | $this->em->persist($user); |
||
37 | |||
38 | $this->em->flush(); |
||
39 | |||
40 | self::assertInternalType('numeric', $user->id); |
||
41 | self::assertTrue($this->em->contains($user)); |
||
42 | |||
43 | // Read |
||
44 | $user2 = $this->em->find(CmsUser::class, $user->id); |
||
45 | self::assertSame($user, $user2); |
||
46 | |||
47 | // Add a phonenumber |
||
48 | $ph = new CmsPhonenumber; |
||
49 | $ph->phonenumber = "12345"; |
||
50 | $user->addPhonenumber($ph); |
||
51 | $this->em->flush(); |
||
52 | self::assertTrue($this->em->contains($ph)); |
||
53 | self::assertTrue($this->em->contains($user)); |
||
54 | |||
55 | // Update name |
||
56 | $user->name = 'guilherme'; |
||
57 | $this->em->flush(); |
||
58 | self::assertEquals('guilherme', $user->name); |
||
59 | |||
60 | // Add another phonenumber |
||
61 | $ph2 = new CmsPhonenumber; |
||
62 | $ph2->phonenumber = "6789"; |
||
63 | $user->addPhonenumber($ph2); |
||
64 | $this->em->flush(); |
||
65 | self::assertTrue($this->em->contains($ph2)); |
||
66 | |||
67 | // Delete |
||
68 | $this->em->remove($user); |
||
69 | self::assertTrue($this->em->getUnitOfWork()->isScheduledForDelete($user)); |
||
70 | self::assertTrue($this->em->getUnitOfWork()->isScheduledForDelete($ph)); |
||
71 | self::assertTrue($this->em->getUnitOfWork()->isScheduledForDelete($ph2)); |
||
72 | $this->em->flush(); |
||
73 | self::assertFalse($this->em->getUnitOfWork()->isScheduledForDelete($user)); |
||
74 | self::assertFalse($this->em->getUnitOfWork()->isScheduledForDelete($ph)); |
||
75 | self::assertFalse($this->em->getUnitOfWork()->isScheduledForDelete($ph2)); |
||
76 | self::assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->em->getUnitOfWork()->getEntityState($user)); |
||
77 | self::assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->em->getUnitOfWork()->getEntityState($ph)); |
||
78 | self::assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->em->getUnitOfWork()->getEntityState($ph2)); |
||
79 | } |
||
80 | |||
81 | public function testOneToManyAssociationModification() |
||
82 | { |
||
83 | $user = new CmsUser; |
||
84 | $user->name = 'Roman'; |
||
85 | $user->username = 'romanb'; |
||
86 | $user->status = 'developer'; |
||
87 | |||
88 | $ph1 = new CmsPhonenumber; |
||
89 | $ph1->phonenumber = "0301234"; |
||
90 | $ph2 = new CmsPhonenumber; |
||
91 | $ph2->phonenumber = "987654321"; |
||
92 | |||
93 | $user->addPhonenumber($ph1); |
||
94 | $user->addPhonenumber($ph2); |
||
95 | |||
96 | $this->em->persist($user); |
||
97 | $this->em->flush(); |
||
98 | |||
99 | // Remove the first element from the collection |
||
100 | unset($user->phonenumbers[0]); |
||
101 | $ph1->user = null; // owning side! |
||
102 | |||
103 | $this->em->flush(); |
||
104 | |||
105 | self::assertCount(1, $user->phonenumbers); |
||
106 | self::assertNull($ph1->user); |
||
107 | } |
||
108 | |||
109 | public function testBasicOneToOne() |
||
110 | { |
||
111 | //$this->em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); |
||
112 | $user = new CmsUser; |
||
113 | $user->name = 'Roman'; |
||
114 | $user->username = 'romanb'; |
||
115 | $user->status = 'developer'; |
||
116 | |||
117 | $address = new CmsAddress; |
||
118 | $address->country = 'Germany'; |
||
119 | $address->city = 'Berlin'; |
||
120 | $address->zip = '12345'; |
||
121 | |||
122 | $user->address = $address; // inverse side |
||
123 | $address->user = $user; // owning side! |
||
124 | |||
125 | $this->em->persist($user); |
||
126 | $this->em->flush(); |
||
127 | |||
128 | // Check that the foreign key has been set |
||
129 | $userId = $this->em->getConnection()->executeQuery( |
||
130 | "SELECT user_id FROM cms_addresses WHERE id=?", [$address->id] |
||
131 | )->fetchColumn(); |
||
132 | self::assertInternalType('numeric', $userId); |
||
133 | |||
134 | $this->em->clear(); |
||
135 | |||
136 | $user2 = $this->em->createQuery('select u from \Doctrine\Tests\Models\CMS\CmsUser u where u.id=?1') |
||
137 | ->setParameter(1, $userId) |
||
138 | ->getSingleResult(); |
||
139 | |||
140 | // Address has been eager-loaded because it cant be lazy |
||
141 | self::assertInstanceOf(CmsAddress::class, $user2->address); |
||
142 | self::assertNotInstanceOf(GhostObjectInterface::class, $user2->address); |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * @group DDC-1230 |
||
147 | */ |
||
148 | public function testRemove() |
||
149 | { |
||
150 | $user = new CmsUser; |
||
151 | $user->name = 'Guilherme'; |
||
152 | $user->username = 'gblanco'; |
||
153 | $user->status = 'developer'; |
||
154 | |||
155 | self::assertEquals(UnitOfWork::STATE_NEW, $this->em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW"); |
||
156 | |||
157 | $this->em->persist($user); |
||
158 | |||
159 | self::assertEquals(UnitOfWork::STATE_MANAGED, $this->em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_MANAGED"); |
||
160 | |||
161 | $this->em->remove($user); |
||
162 | |||
163 | self::assertEquals(UnitOfWork::STATE_NEW, $this->em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW"); |
||
164 | |||
165 | $this->em->persist($user); |
||
166 | $this->em->flush(); |
||
167 | $id = $user->getId(); |
||
168 | |||
169 | $this->em->remove($user); |
||
170 | |||
171 | self::assertEquals(UnitOfWork::STATE_REMOVED, $this->em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_REMOVED"); |
||
172 | $this->em->flush(); |
||
173 | |||
174 | self::assertEquals(UnitOfWork::STATE_NEW, $this->em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW"); |
||
175 | |||
176 | self::assertNull($this->em->find(CmsUser::class, $id)); |
||
177 | } |
||
178 | |||
179 | public function testOneToManyOrphanRemoval() |
||
180 | { |
||
181 | $user = new CmsUser; |
||
182 | $user->name = 'Guilherme'; |
||
183 | $user->username = 'gblanco'; |
||
184 | $user->status = 'developer'; |
||
185 | |||
186 | for ($i=0; $i<3; ++$i) { |
||
187 | $phone = new CmsPhonenumber; |
||
188 | $phone->phonenumber = 100 + $i; |
||
189 | $user->addPhonenumber($phone); |
||
190 | } |
||
191 | |||
192 | $this->em->persist($user); |
||
193 | |||
194 | $this->em->flush(); |
||
195 | |||
196 | $user->getPhonenumbers()->remove(0); |
||
197 | self::assertCount(2, $user->getPhonenumbers()); |
||
198 | |||
199 | $this->em->flush(); |
||
200 | |||
201 | // Check that there are just 2 phonenumbers left |
||
202 | $count = $this->em->getConnection()->fetchColumn("SELECT COUNT(*) FROM cms_phonenumbers"); |
||
203 | self::assertEquals(2, $count); // only 2 remaining |
||
204 | |||
205 | // check that clear() removes the others via orphan removal |
||
206 | $user->getPhonenumbers()->clear(); |
||
207 | $this->em->flush(); |
||
208 | self::assertEquals(0, $this->em->getConnection()->fetchColumn("select count(*) from cms_phonenumbers")); |
||
209 | } |
||
210 | |||
211 | public function testBasicQuery() |
||
212 | { |
||
213 | $user = new CmsUser; |
||
214 | $user->name = 'Guilherme'; |
||
215 | $user->username = 'gblanco'; |
||
216 | $user->status = 'developer'; |
||
217 | $this->em->persist($user); |
||
218 | $this->em->flush(); |
||
219 | |||
220 | $query = $this->em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u"); |
||
221 | |||
222 | $users = $query->getResult(); |
||
223 | |||
224 | self::assertCount(1, $users); |
||
225 | self::assertEquals('Guilherme', $users[0]->name); |
||
226 | self::assertEquals('gblanco', $users[0]->username); |
||
227 | self::assertEquals('developer', $users[0]->status); |
||
228 | //self::assertNull($users[0]->phonenumbers); |
||
229 | //self::assertNull($users[0]->articles); |
||
230 | |||
231 | $usersArray = $query->getArrayResult(); |
||
232 | |||
233 | self::assertInternalType('array', $usersArray); |
||
234 | self::assertCount(1, $usersArray); |
||
235 | self::assertEquals('Guilherme', $usersArray[0]['name']); |
||
236 | self::assertEquals('gblanco', $usersArray[0]['username']); |
||
237 | self::assertEquals('developer', $usersArray[0]['status']); |
||
238 | |||
239 | $usersScalar = $query->getScalarResult(); |
||
240 | |||
241 | self::assertInternalType('array', $usersScalar); |
||
242 | self::assertCount(1, $usersScalar); |
||
243 | self::assertEquals('Guilherme', $usersScalar[0]['u_name']); |
||
244 | self::assertEquals('gblanco', $usersScalar[0]['u_username']); |
||
245 | self::assertEquals('developer', $usersScalar[0]['u_status']); |
||
246 | } |
||
247 | |||
248 | public function testBasicOneToManyInnerJoin() |
||
249 | { |
||
250 | $user = new CmsUser; |
||
251 | $user->name = 'Guilherme'; |
||
252 | $user->username = 'gblanco'; |
||
253 | $user->status = 'developer'; |
||
254 | $this->em->persist($user); |
||
255 | $this->em->flush(); |
||
256 | |||
257 | $query = $this->em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p"); |
||
258 | |||
259 | $users = $query->getResult(); |
||
260 | |||
261 | self::assertCount(0, $users); |
||
262 | } |
||
263 | |||
264 | public function testBasicOneToManyLeftJoin() |
||
265 | { |
||
266 | $user = new CmsUser; |
||
267 | $user->name = 'Guilherme'; |
||
268 | $user->username = 'gblanco'; |
||
269 | $user->status = 'developer'; |
||
270 | $this->em->persist($user); |
||
271 | $this->em->flush(); |
||
272 | |||
273 | $query = $this->em->createQuery("select u,p from Doctrine\Tests\Models\CMS\CmsUser u left join u.phonenumbers p"); |
||
274 | |||
275 | $users = $query->getResult(); |
||
276 | |||
277 | self::assertCount(1, $users); |
||
278 | self::assertEquals('Guilherme', $users[0]->name); |
||
279 | self::assertEquals('gblanco', $users[0]->username); |
||
280 | self::assertEquals('developer', $users[0]->status); |
||
281 | self::assertInstanceOf(PersistentCollection::class, $users[0]->phonenumbers); |
||
282 | self::assertTrue($users[0]->phonenumbers->isInitialized()); |
||
283 | self::assertEquals(0, $users[0]->phonenumbers->count()); |
||
284 | } |
||
285 | |||
286 | public function testBasicRefresh() |
||
287 | { |
||
288 | $user = new CmsUser; |
||
289 | $user->name = 'Guilherme'; |
||
290 | $user->username = 'gblanco'; |
||
291 | $user->status = 'developer'; |
||
292 | |||
293 | $this->em->persist($user); |
||
294 | $this->em->flush(); |
||
295 | |||
296 | $user->status = 'mascot'; |
||
297 | |||
298 | self::assertEquals('mascot', $user->status); |
||
299 | $this->em->refresh($user); |
||
300 | self::assertEquals('developer', $user->status); |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * @group DDC-833 |
||
305 | */ |
||
306 | public function testRefreshResetsCollection() |
||
307 | { |
||
308 | $user = new CmsUser; |
||
309 | $user->name = 'Guilherme'; |
||
310 | $user->username = 'gblanco'; |
||
311 | $user->status = 'developer'; |
||
312 | |||
313 | // Add a phonenumber |
||
314 | $ph1 = new CmsPhonenumber; |
||
315 | $ph1->phonenumber = "12345"; |
||
316 | $user->addPhonenumber($ph1); |
||
317 | |||
318 | // Add a phonenumber |
||
319 | $ph2 = new CmsPhonenumber; |
||
320 | $ph2->phonenumber = "54321"; |
||
321 | |||
322 | $this->em->persist($user); |
||
323 | $this->em->persist($ph1); |
||
324 | $this->em->persist($ph2); |
||
325 | $this->em->flush(); |
||
326 | |||
327 | $user->addPhonenumber($ph2); |
||
328 | |||
329 | self::assertCount(2, $user->phonenumbers); |
||
330 | $this->em->refresh($user); |
||
331 | |||
332 | self::assertCount(1, $user->phonenumbers); |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * @group DDC-833 |
||
337 | */ |
||
338 | public function testDqlRefreshResetsCollection() |
||
339 | { |
||
340 | $user = new CmsUser; |
||
341 | $user->name = 'Guilherme'; |
||
342 | $user->username = 'gblanco'; |
||
343 | $user->status = 'developer'; |
||
344 | |||
345 | // Add a phonenumber |
||
346 | $ph1 = new CmsPhonenumber; |
||
347 | $ph1->phonenumber = "12345"; |
||
348 | $user->addPhonenumber($ph1); |
||
349 | |||
350 | // Add a phonenumber |
||
351 | $ph2 = new CmsPhonenumber; |
||
352 | $ph2->phonenumber = "54321"; |
||
353 | |||
354 | $this->em->persist($user); |
||
355 | $this->em->persist($ph1); |
||
356 | $this->em->persist($ph2); |
||
357 | $this->em->flush(); |
||
358 | |||
359 | $user->addPhonenumber($ph2); |
||
360 | |||
361 | self::assertCount(2, $user->phonenumbers); |
||
362 | $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1"; |
||
363 | $user = $this->em->createQuery($dql) |
||
364 | ->setParameter(1, $user->id) |
||
365 | ->setHint(Query::HINT_REFRESH, true) |
||
366 | ->getSingleResult(); |
||
367 | |||
368 | self::assertCount(1, $user->phonenumbers); |
||
369 | } |
||
370 | |||
371 | /** |
||
372 | * @group DDC-833 |
||
373 | */ |
||
374 | public function testCreateEntityOfProxy() |
||
375 | { |
||
376 | $user = new CmsUser; |
||
377 | $user->name = 'Guilherme'; |
||
378 | $user->username = 'gblanco'; |
||
379 | $user->status = 'developer'; |
||
380 | |||
381 | // Add a phonenumber |
||
382 | $ph1 = new CmsPhonenumber; |
||
383 | $ph1->phonenumber = "12345"; |
||
384 | $user->addPhonenumber($ph1); |
||
385 | |||
386 | // Add a phonenumber |
||
387 | $ph2 = new CmsPhonenumber; |
||
388 | $ph2->phonenumber = "54321"; |
||
389 | |||
390 | $this->em->persist($user); |
||
391 | $this->em->persist($ph1); |
||
392 | $this->em->persist($ph2); |
||
393 | $this->em->flush(); |
||
394 | $this->em->clear(); |
||
395 | |||
396 | $userId = $user->id; |
||
397 | $user = $this->em->getReference(CmsUser::class, $user->id); |
||
398 | |||
399 | $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1"; |
||
400 | $user = $this->em->createQuery($dql) |
||
401 | ->setParameter(1, $userId) |
||
402 | ->getSingleResult(); |
||
403 | |||
404 | self::assertCount(1, $user->phonenumbers); |
||
405 | } |
||
406 | |||
407 | public function testAddToCollectionDoesNotInitialize() |
||
408 | { |
||
409 | $user = new CmsUser; |
||
410 | $user->name = 'Guilherme'; |
||
411 | $user->username = 'gblanco'; |
||
412 | $user->status = 'developer'; |
||
413 | |||
414 | for ($i=0; $i<3; ++$i) { |
||
415 | $phone = new CmsPhonenumber; |
||
416 | $phone->phonenumber = 100 + $i; |
||
417 | $user->addPhonenumber($phone); |
||
418 | } |
||
419 | |||
420 | $this->em->persist($user); |
||
421 | $this->em->flush(); |
||
422 | $this->em->clear(); |
||
423 | |||
424 | self::assertEquals(3, $user->getPhonenumbers()->count()); |
||
425 | |||
426 | $query = $this->em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'"); |
||
427 | |||
428 | $gblanco = $query->getSingleResult(); |
||
429 | |||
430 | self::assertFalse($gblanco->getPhonenumbers()->isInitialized()); |
||
431 | |||
432 | $newPhone = new CmsPhonenumber; |
||
433 | $newPhone->phonenumber = 555; |
||
434 | $gblanco->addPhonenumber($newPhone); |
||
435 | |||
436 | self::assertFalse($gblanco->getPhonenumbers()->isInitialized()); |
||
437 | $this->em->persist($gblanco); |
||
438 | |||
439 | $this->em->flush(); |
||
440 | $this->em->clear(); |
||
441 | |||
442 | $query = $this->em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'"); |
||
443 | $gblanco2 = $query->getSingleResult(); |
||
444 | self::assertEquals(4, $gblanco2->getPhonenumbers()->count()); |
||
445 | } |
||
446 | |||
447 | public function testInitializeCollectionWithNewObjectsRetainsNewObjects() |
||
448 | { |
||
449 | $user = new CmsUser; |
||
450 | $user->name = 'Guilherme'; |
||
451 | $user->username = 'gblanco'; |
||
452 | $user->status = 'developer'; |
||
453 | |||
454 | for ($i=0; $i<3; ++$i) { |
||
455 | $phone = new CmsPhonenumber; |
||
456 | $phone->phonenumber = 100 + $i; |
||
457 | $user->addPhonenumber($phone); |
||
458 | } |
||
459 | |||
460 | $this->em->persist($user); |
||
461 | $this->em->flush(); |
||
462 | $this->em->clear(); |
||
463 | |||
464 | self::assertEquals(3, $user->getPhonenumbers()->count()); |
||
465 | |||
466 | $query = $this->em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'"); |
||
467 | |||
468 | $gblanco = $query->getSingleResult(); |
||
469 | |||
470 | self::assertFalse($gblanco->getPhonenumbers()->isInitialized()); |
||
471 | |||
472 | $newPhone = new CmsPhonenumber; |
||
473 | $newPhone->phonenumber = 555; |
||
474 | $gblanco->addPhonenumber($newPhone); |
||
475 | |||
476 | self::assertFalse($gblanco->getPhonenumbers()->isInitialized()); |
||
477 | self::assertEquals(4, $gblanco->getPhonenumbers()->count()); |
||
478 | self::assertTrue($gblanco->getPhonenumbers()->isInitialized()); |
||
479 | |||
480 | $this->em->flush(); |
||
481 | $this->em->clear(); |
||
482 | |||
483 | $query = $this->em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'"); |
||
484 | $gblanco2 = $query->getSingleResult(); |
||
485 | self::assertEquals(4, $gblanco2->getPhonenumbers()->count()); |
||
486 | } |
||
487 | |||
488 | public function testOneToManyCascadeRemove() |
||
489 | { |
||
490 | $user = new CmsUser; |
||
491 | $user->name = 'Guilherme'; |
||
492 | $user->username = 'gblanco'; |
||
493 | $user->status = 'developer'; |
||
494 | |||
495 | for ($i=0; $i<3; ++$i) { |
||
496 | $phone = new CmsPhonenumber; |
||
497 | $phone->phonenumber = 100 + $i; |
||
498 | $user->addPhonenumber($phone); |
||
499 | } |
||
500 | |||
501 | $this->em->persist($user); |
||
502 | $this->em->flush(); |
||
503 | $this->em->clear(); |
||
504 | |||
505 | $query = $this->em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'"); |
||
506 | $gblanco = $query->getSingleResult(); |
||
507 | |||
508 | $this->em->remove($gblanco); |
||
509 | $this->em->flush(); |
||
510 | |||
511 | $this->em->clear(); |
||
512 | |||
513 | self::assertEquals(0, $this->em->createQuery( |
||
514 | "select count(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p") |
||
515 | ->getSingleScalarResult()); |
||
516 | |||
517 | self::assertEquals(0, $this->em->createQuery( |
||
518 | "select count(u.id) from Doctrine\Tests\Models\CMS\CmsUser u") |
||
519 | ->getSingleScalarResult()); |
||
520 | } |
||
521 | |||
522 | public function testTextColumnSaveAndRetrieve() |
||
523 | { |
||
524 | $user = new CmsUser; |
||
525 | $user->name = 'Guilherme'; |
||
526 | $user->username = 'gblanco'; |
||
527 | $user->status = 'developer'; |
||
528 | |||
529 | $this->em->persist($user); |
||
530 | |||
531 | $article = new CmsArticle(); |
||
532 | $article->text = "Lorem ipsum dolor sunt."; |
||
533 | $article->topic = "A Test Article!"; |
||
534 | $article->setAuthor($user); |
||
535 | |||
536 | $this->em->persist($article); |
||
537 | $this->em->flush(); |
||
538 | $articleId = $article->id; |
||
539 | |||
540 | $this->em->clear(); |
||
541 | |||
542 | // test find() with leading backslash at the same time |
||
543 | $articleNew = $this->em->find('\Doctrine\Tests\Models\CMS\CmsArticle', $articleId); |
||
544 | self::assertTrue($this->em->contains($articleNew)); |
||
545 | self::assertEquals("Lorem ipsum dolor sunt.", $articleNew->text); |
||
546 | |||
547 | self::assertNotSame($article, $articleNew); |
||
548 | |||
549 | $articleNew->text = "Lorem ipsum dolor sunt. And stuff!"; |
||
550 | |||
551 | $this->em->flush(); |
||
552 | $this->em->clear(); |
||
553 | |||
554 | $articleNew = $this->em->find(CmsArticle::class, $articleId); |
||
555 | self::assertEquals("Lorem ipsum dolor sunt. And stuff!", $articleNew->text); |
||
556 | self::assertTrue($this->em->contains($articleNew)); |
||
557 | } |
||
558 | |||
559 | public function testFlushDoesNotIssueUnnecessaryUpdates() |
||
560 | { |
||
561 | $user = new CmsUser; |
||
562 | $user->name = 'Guilherme'; |
||
563 | $user->username = 'gblanco'; |
||
564 | $user->status = 'developer'; |
||
565 | |||
566 | $address = new CmsAddress; |
||
567 | $address->country = 'Germany'; |
||
568 | $address->city = 'Berlin'; |
||
569 | $address->zip = '12345'; |
||
570 | |||
571 | $address->user = $user; |
||
572 | $user->address = $address; |
||
573 | |||
574 | $article = new CmsArticle(); |
||
575 | $article->text = "Lorem ipsum dolor sunt."; |
||
576 | $article->topic = "A Test Article!"; |
||
577 | $article->setAuthor($user); |
||
578 | |||
579 | $this->em->persist($article); |
||
580 | $this->em->persist($user); |
||
581 | |||
582 | //$this->em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); |
||
0 ignored issues
–
show
|
|||
583 | |||
584 | $this->em->flush(); |
||
585 | $this->em->clear(); |
||
586 | |||
587 | $query = $this->em->createQuery('select u,a,ad from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a join u.address ad'); |
||
588 | $user2 = $query->getSingleResult(); |
||
589 | |||
590 | self::assertCount(1, $user2->articles); |
||
591 | self::assertInstanceOf(CmsAddress::class, $user2->address); |
||
592 | |||
593 | $oldLogger = $this->em->getConnection()->getConfiguration()->getSQLLogger(); |
||
594 | $debugStack = new DebugStack(); |
||
595 | $this->em->getConnection()->getConfiguration()->setSQLLogger($debugStack); |
||
596 | |||
597 | $this->em->flush(); |
||
598 | self::assertCount(0, $debugStack->queries); |
||
599 | |||
600 | $this->em->getConnection()->getConfiguration()->setSQLLogger($oldLogger); |
||
601 | } |
||
602 | |||
603 | public function testRemoveEntityByReference() |
||
604 | { |
||
605 | $user = new CmsUser; |
||
606 | $user->name = 'Guilherme'; |
||
607 | $user->username = 'gblanco'; |
||
608 | $user->status = 'developer'; |
||
609 | |||
610 | //$this->em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
69% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
611 | |||
612 | $this->em->persist($user); |
||
613 | $this->em->flush(); |
||
614 | $this->em->clear(); |
||
615 | |||
616 | $userRef = $this->em->getReference(CmsUser::class, $user->getId()); |
||
617 | $this->em->remove($userRef); |
||
618 | $this->em->flush(); |
||
619 | $this->em->clear(); |
||
620 | |||
621 | self::assertEquals(0, $this->em->getConnection()->fetchColumn("select count(*) from cms_users")); |
||
622 | |||
623 | //$this->em->getConnection()->getConfiguration()->setSQLLogger(null); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
77% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
624 | } |
||
625 | |||
626 | public function testQueryEntityByReference() |
||
627 | { |
||
628 | $user = new CmsUser; |
||
629 | $user->name = 'Guilherme'; |
||
630 | $user->username = 'gblanco'; |
||
631 | $user->status = 'developer'; |
||
632 | |||
633 | $address = new CmsAddress; |
||
634 | $address->country = 'Germany'; |
||
635 | $address->city = 'Berlin'; |
||
636 | $address->zip = '12345'; |
||
637 | |||
638 | $user->setAddress($address); |
||
639 | |||
640 | $this->em->transactional(function($em) use ($user) { |
||
641 | $em->persist($user); |
||
642 | }); |
||
643 | $this->em->clear(); |
||
644 | |||
645 | //$this->em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
69% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them.
Loading history...
|
|||
646 | |||
647 | $userRef = $this->em->getReference(CmsUser::class, $user->getId()); |
||
648 | $address2 = $this->em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsAddress a where a.user = :user') |
||
649 | ->setParameter('user', $userRef) |
||
650 | ->getSingleResult(); |
||
651 | |||
652 | /* @var $fetchedUser CmsUser|GhostObjectInterface */ |
||
653 | $fetchedUser = $address2->getUser(); |
||
654 | |||
655 | self::assertInstanceOf(GhostObjectInterface::class, $fetchedUser); |
||
656 | self::assertSame($userRef, $fetchedUser); |
||
657 | self::assertFalse($userRef->isProxyInitialized()); |
||
658 | self::assertEquals('Germany', $address2->country); |
||
659 | self::assertEquals('Berlin', $address2->city); |
||
660 | self::assertEquals('12345', $address2->zip); |
||
661 | } |
||
662 | |||
663 | public function testOneToOneNullUpdate() |
||
664 | { |
||
665 | $user = new CmsUser(); |
||
666 | $user->username = "beberlei"; |
||
667 | $user->name = "Benjamin E."; |
||
668 | $user->status = 'active'; |
||
669 | |||
670 | $address = new CmsAddress(); |
||
671 | $address->city = "Bonn"; |
||
672 | $address->zip = "12354"; |
||
673 | $address->country = "Germany"; |
||
674 | $address->street = "somestreet"; |
||
675 | $address->user = $user; |
||
676 | |||
677 | $this->em->persist($address); |
||
678 | $this->em->persist($user); |
||
679 | $this->em->flush(); |
||
680 | |||
681 | self::assertEquals(1, $this->em->getConnection()->fetchColumn("select 1 from cms_addresses where user_id = ".$user->id)); |
||
682 | |||
683 | $address->user = null; |
||
684 | $this->em->flush(); |
||
685 | |||
686 | self::assertNotEquals(1, $this->em->getConnection()->fetchColumn("select 1 from cms_addresses where user_id = ".$user->id)); |
||
687 | } |
||
688 | |||
689 | /** |
||
690 | * @group DDC-600 |
||
691 | * @group DDC-455 |
||
692 | */ |
||
693 | public function testNewAssociatedEntityDuringFlushThrowsException() |
||
694 | { |
||
695 | $this->expectException(\InvalidArgumentException::class); |
||
696 | |||
697 | $user = new CmsUser(); |
||
698 | $user->username = "beberlei"; |
||
699 | $user->name = "Benjamin E."; |
||
700 | $user->status = 'active'; |
||
701 | |||
702 | $address = new CmsAddress(); |
||
703 | $address->city = "Bonn"; |
||
704 | $address->zip = "12354"; |
||
705 | $address->country = "Germany"; |
||
706 | $address->street = "somestreet"; |
||
707 | $address->user = $user; |
||
708 | |||
709 | $this->em->persist($address); |
||
710 | |||
711 | // flushing without persisting $user should raise an exception |
||
712 | $this->em->flush(); |
||
713 | } |
||
714 | |||
715 | /** |
||
716 | * @group DDC-600 |
||
717 | * @group DDC-455 |
||
718 | */ |
||
719 | public function testNewAssociatedEntityDuringFlushThrowsException2() |
||
720 | { |
||
721 | $this->expectException(\InvalidArgumentException::class); |
||
722 | |||
723 | $user = new CmsUser(); |
||
724 | $user->username = "beberlei"; |
||
725 | $user->name = "Benjamin E."; |
||
726 | $user->status = 'active'; |
||
727 | |||
728 | $address = new CmsAddress(); |
||
729 | $address->city = "Bonn"; |
||
730 | $address->zip = "12354"; |
||
731 | $address->country = "Germany"; |
||
732 | $address->street = "somestreet"; |
||
733 | $address->user = $user; |
||
734 | |||
735 | $this->em->persist($address); |
||
736 | $this->em->persist($user); |
||
737 | $this->em->flush(); |
||
738 | |||
739 | $u2 = new CmsUser; |
||
740 | $u2->username = "beberlei"; |
||
741 | $u2->name = "Benjamin E."; |
||
742 | $u2->status = 'inactive'; |
||
743 | $address->user = $u2; |
||
744 | |||
745 | // flushing without persisting $u2 should raise an exception |
||
746 | $this->em->flush(); |
||
747 | } |
||
748 | |||
749 | /** |
||
750 | * @group DDC-600 |
||
751 | * @group DDC-455 |
||
752 | */ |
||
753 | public function testNewAssociatedEntityDuringFlushThrowsException3() |
||
754 | { |
||
755 | $this->expectException(\InvalidArgumentException::class); |
||
756 | |||
757 | $art = new CmsArticle(); |
||
758 | $art->topic = 'topic'; |
||
759 | $art->text = 'the text'; |
||
760 | |||
761 | $com = new CmsComment(); |
||
762 | $com->topic = 'Good'; |
||
763 | $com->text = 'Really good!'; |
||
764 | $art->addComment($com); |
||
765 | |||
766 | $this->em->persist($art); |
||
767 | |||
768 | // flushing without persisting $com should raise an exception |
||
769 | $this->em->flush(); |
||
770 | } |
||
771 | |||
772 | public function testOneToOneOrphanRemoval() |
||
773 | { |
||
774 | $user = new CmsUser(); |
||
775 | $user->username = "beberlei"; |
||
776 | $user->name = "Benjamin E."; |
||
777 | $user->status = 'active'; |
||
778 | |||
779 | $address = new CmsAddress(); |
||
780 | $address->city = "Bonn"; |
||
781 | $address->zip = "12354"; |
||
782 | $address->country = "Germany"; |
||
783 | $address->street = "somestreet"; |
||
784 | $address->user = $user; |
||
785 | $user->address = $address; |
||
786 | |||
787 | $this->em->persist($address); |
||
788 | $this->em->persist($user); |
||
789 | $this->em->flush(); |
||
790 | $addressId = $address->getId(); |
||
791 | |||
792 | $user->address = null; |
||
793 | |||
794 | $this->em->flush(); |
||
795 | |||
796 | self::assertEquals(0, $this->em->getConnection()->fetchColumn("select count(*) from cms_addresses")); |
||
797 | |||
798 | // check orphan removal through replacement |
||
799 | $user->address = $address; |
||
800 | $address->user = $user; |
||
801 | |||
802 | $this->em->flush(); |
||
803 | |||
804 | self::assertEquals(1, $this->em->getConnection()->fetchColumn("select count(*) from cms_addresses")); |
||
805 | |||
806 | // remove $address to free up unique key id |
||
807 | $this->em->remove($address); |
||
808 | $this->em->flush(); |
||
809 | |||
810 | $newAddress = new CmsAddress(); |
||
811 | $newAddress->city = "NewBonn"; |
||
812 | $newAddress->zip = "12354"; |
||
813 | $newAddress->country = "NewGermany"; |
||
814 | $newAddress->street = "somenewstreet"; |
||
815 | $newAddress->user = $user; |
||
816 | $user->address = $newAddress; |
||
817 | |||
818 | $this->em->flush(); |
||
819 | |||
820 | self::assertEquals(1, $this->em->getConnection()->fetchColumn("select count(*) from cms_addresses")); |
||
821 | } |
||
822 | |||
823 | public function testGetPartialReferenceToUpdateObjectWithoutLoadingIt() |
||
824 | { |
||
825 | $user = new CmsUser(); |
||
826 | $user->username = "beberlei"; |
||
827 | $user->name = "Benjamin E."; |
||
828 | $user->status = 'active'; |
||
829 | $this->em->persist($user); |
||
830 | $this->em->flush(); |
||
831 | $userId = $user->id; |
||
832 | $this->em->clear(); |
||
833 | |||
834 | $user = $this->em->getPartialReference(CmsUser::class, $userId); |
||
835 | self::assertTrue($this->em->contains($user)); |
||
836 | self::assertNull($user->getName()); |
||
837 | self::assertEquals($userId, $user->id); |
||
838 | |||
839 | $user->name = 'Stephan'; |
||
840 | $this->em->flush(); |
||
841 | $this->em->clear(); |
||
842 | |||
843 | self::assertEquals('Benjamin E.', $this->em->find(get_class($user), $userId)->name); |
||
844 | } |
||
845 | |||
846 | /** |
||
847 | * @group DDC-952 |
||
848 | */ |
||
849 | public function testManyToOneFetchModeQuery() |
||
850 | { |
||
851 | $user = new CmsUser(); |
||
852 | $user->username = "beberlei"; |
||
853 | $user->name = "Benjamin E."; |
||
854 | $user->status = 'active'; |
||
855 | |||
856 | $article = new CmsArticle(); |
||
857 | $article->topic = "foo"; |
||
858 | $article->text = "bar"; |
||
859 | $article->user = $user; |
||
860 | |||
861 | $this->em->persist($article); |
||
862 | $this->em->persist($user); |
||
863 | $this->em->flush(); |
||
864 | $this->em->clear(); |
||
865 | |||
866 | $qc = $this->getCurrentQueryCount(); |
||
867 | $dql = "SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.id = ?1"; |
||
868 | /* @var $article CmsArticle */ |
||
869 | $article = $this->em |
||
870 | ->createQuery($dql) |
||
871 | ->setParameter(1, $article->id) |
||
872 | ->setFetchMode(CmsArticle::class, 'user', FetchMode::EAGER) |
||
873 | ->getSingleResult(); |
||
874 | |||
875 | /* @var $fetchedUser CmsUser|GhostObjectInterface */ |
||
876 | $fetchedUser = $article->user; |
||
877 | |||
878 | self::assertInstanceOf(GhostObjectInterface::class, $fetchedUser, "It IS a proxy, ..."); |
||
879 | self::assertTrue($fetchedUser->isProxyInitialized(), "...but its initialized!"); |
||
880 | self::assertEquals($qc+2, $this->getCurrentQueryCount()); |
||
881 | } |
||
882 | |||
883 | /** |
||
884 | * @group DDC-1278 |
||
885 | */ |
||
886 | public function testClear() |
||
887 | { |
||
888 | $user = new CmsUser; |
||
889 | $user->name = 'Dominik'; |
||
890 | $user->username = 'domnikl'; |
||
891 | $user->status = 'developer'; |
||
892 | |||
893 | $address = new CmsAddress(); |
||
894 | $address->city = "Springfield"; |
||
895 | $address->zip = "12354"; |
||
896 | $address->country = "Germany"; |
||
897 | $address->street = "Foo Street"; |
||
898 | $address->user = $user; |
||
899 | $user->address = $address; |
||
900 | |||
901 | $article1 = new CmsArticle(); |
||
902 | $article1->topic = 'Foo'; |
||
903 | $article1->text = 'Foo Text'; |
||
904 | |||
905 | $article2 = new CmsArticle(); |
||
906 | $article2->topic = 'Bar'; |
||
907 | $article2->text = 'Bar Text'; |
||
908 | |||
909 | $user->addArticle($article1); |
||
910 | $user->addArticle($article2); |
||
911 | |||
912 | $this->em->persist($article1); |
||
913 | $this->em->persist($article2); |
||
914 | $this->em->persist($address); |
||
915 | $this->em->persist($user); |
||
916 | $this->em->flush(); |
||
917 | |||
918 | $unitOfWork = $this->em->getUnitOfWork(); |
||
919 | |||
920 | $this->em->clear(); |
||
921 | |||
922 | self::assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($user)); |
||
923 | self::assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($article1)); |
||
924 | self::assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($article2)); |
||
925 | self::assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($address)); |
||
926 | } |
||
927 | |||
928 | /** |
||
929 | * @group DDC-1585 |
||
930 | */ |
||
931 | public function testWrongAssociationInstance() |
||
932 | { |
||
933 | $user = new CmsUser; |
||
934 | $user->name = 'Dominik'; |
||
935 | $user->username = 'domnikl'; |
||
936 | $user->status = 'developer'; |
||
937 | $user->address = $user; |
||
938 | |||
939 | $this->expectException(ORMInvalidArgumentException::class); |
||
940 | $this->expectExceptionMessage( |
||
941 | 'Expected value of type "Doctrine\Tests\Models\CMS\CmsAddress" for association field ' . |
||
942 | '"Doctrine\Tests\Models\CMS\CmsUser#$address", got "Doctrine\Tests\Models\CMS\CmsUser" instead.' |
||
943 | ); |
||
944 | |||
945 | $this->em->persist($user); |
||
946 | $this->em->flush(); |
||
947 | } |
||
948 | } |
||
949 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.