Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Functional / SingleTableInheritanceTest.php
1 <?php
2
3 namespace Doctrine\Tests\ORM\Functional;
4
5 use Doctrine\ORM\Mapping\ClassMetadata;
6 use Doctrine\Common\Collections\Criteria;
7
8 class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
9 {
10     private $salesPerson;
11     private $engineers = array();
12     private $fix;
13     private $flex;
14     private $ultra;
15
16     public function setUp()
17     {
18         $this->useModelSet('company');
19         parent::setUp();
20     }
21
22     public function persistRelatedEmployees()
23     {
24         $this->salesPerson = new \Doctrine\Tests\Models\Company\CompanyEmployee();
25         $this->salesPerson->setName('Poor Sales Guy');
26         $this->salesPerson->setDepartment('Sales');
27         $this->salesPerson->setSalary(100);
28
29         $engineer1 = new \Doctrine\Tests\Models\Company\CompanyEmployee();
30         $engineer1->setName('Roman B.');
31         $engineer1->setDepartment('IT');
32         $engineer1->setSalary(100);
33         $this->engineers[] = $engineer1;
34
35         $engineer2 = new \Doctrine\Tests\Models\Company\CompanyEmployee();
36         $engineer2->setName('Jonathan W.');
37         $engineer2->setDepartment('IT');
38         $engineer2->setSalary(100);
39         $this->engineers[] = $engineer2;
40
41         $engineer3 = new \Doctrine\Tests\Models\Company\CompanyEmployee();
42         $engineer3->setName('Benjamin E.');
43         $engineer3->setDepartment('IT');
44         $engineer3->setSalary(100);
45         $this->engineers[] = $engineer3;
46
47         $engineer4 = new \Doctrine\Tests\Models\Company\CompanyEmployee();
48         $engineer4->setName('Guilherme B.');
49         $engineer4->setDepartment('IT');
50         $engineer4->setSalary(100);
51         $this->engineers[] = $engineer4;
52
53         $this->_em->persist($this->salesPerson);
54         $this->_em->persist($engineer1);
55         $this->_em->persist($engineer2);
56         $this->_em->persist($engineer3);
57         $this->_em->persist($engineer4);
58     }
59
60     public function loadFullFixture()
61     {
62         $this->persistRelatedEmployees();
63
64         $this->fix = new \Doctrine\Tests\Models\Company\CompanyFixContract();
65         $this->fix->setFixPrice(1000);
66         $this->fix->setSalesPerson($this->salesPerson);
67         $this->fix->addEngineer($this->engineers[0]);
68         $this->fix->addEngineer($this->engineers[1]);
69         $this->fix->markCompleted();
70
71         $this->flex = new \Doctrine\Tests\Models\Company\CompanyFlexContract();
72         $this->flex->setSalesPerson($this->salesPerson);
73         $this->flex->setHoursWorked(100);
74         $this->flex->setPricePerHour(100);
75         $this->flex->addEngineer($this->engineers[2]);
76         $this->flex->addEngineer($this->engineers[1]);
77         $this->flex->addEngineer($this->engineers[3]);
78         $this->flex->markCompleted();
79
80         $this->ultra = new \Doctrine\Tests\Models\Company\CompanyFlexUltraContract();
81         $this->ultra->setSalesPerson($this->salesPerson);
82         $this->ultra->setHoursWorked(150);
83         $this->ultra->setPricePerHour(150);
84         $this->ultra->setMaxPrice(7000);
85         $this->ultra->addEngineer($this->engineers[3]);
86         $this->ultra->addEngineer($this->engineers[0]);
87
88         $this->_em->persist($this->fix);
89         $this->_em->persist($this->flex);
90         $this->_em->persist($this->ultra);
91         $this->_em->flush();
92         $this->_em->clear();
93     }
94
95     public function testPersistChildOfBaseClass()
96     {
97         $this->persistRelatedEmployees();
98
99         $fixContract = new \Doctrine\Tests\Models\Company\CompanyFixContract();
100         $fixContract->setFixPrice(1000);
101         $fixContract->setSalesPerson($this->salesPerson);
102
103         $this->_em->persist($fixContract);
104         $this->_em->flush();
105         $this->_em->clear();
106
107         $contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFixContract', $fixContract->getId());
108
109         $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyFixContract', $contract);
110         $this->assertEquals(1000, $contract->getFixPrice());
111         $this->assertEquals($this->salesPerson->getId(), $contract->getSalesPerson()->getId());
112     }
113
114     public function testPersistDeepChildOfBaseClass()
115     {
116         $this->persistRelatedEmployees();
117
118         $ultraContract = new \Doctrine\Tests\Models\Company\CompanyFlexUltraContract();
119         $ultraContract->setSalesPerson($this->salesPerson);
120         $ultraContract->setHoursWorked(100);
121         $ultraContract->setPricePerHour(50);
122         $ultraContract->setMaxPrice(7000);
123
124         $this->_em->persist($ultraContract);
125         $this->_em->flush();
126         $this->_em->clear();
127
128         $contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $ultraContract->getId());
129
130         $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $contract);
131         $this->assertEquals(7000, $contract->getMaxPrice());
132         $this->assertEquals(100, $contract->getHoursWorked());
133         $this->assertEquals(50, $contract->getPricePerHour());
134     }
135
136     public function testChildClassLifecycleUpdate()
137     {
138         $this->loadFullFixture();
139
140         $fix = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->fix->getId());
141         $fix->setFixPrice(2500);
142
143         $this->_em->flush();
144         $this->_em->clear();
145
146         $newFix = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->fix->getId());
147         $this->assertEquals(2500, $newFix->getFixPrice());
148     }
149
150     public function testChildClassLifecycleRemove()
151     {
152         $this->loadFullFixture();
153
154         $fix = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->fix->getId());
155         $this->_em->remove($fix);
156         $this->_em->flush();
157
158         $this->assertNull($this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->fix->getId()));
159     }
160
161     public function testFindAllForAbstractBaseClass()
162     {
163         $this->loadFullFixture();
164         $contracts = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyContract')->findAll();
165
166         $this->assertEquals(3, count($contracts));
167         $this->assertContainsOnly('Doctrine\Tests\Models\Company\CompanyContract', $contracts);
168     }
169
170     public function testFindAllForChildClass()
171     {
172         $this->loadFullFixture();
173
174         $this->assertEquals(1, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFixContract')->findAll()));
175         $this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexContract')->findAll()));
176         $this->assertEquals(1, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexUltraContract')->findAll()));
177     }
178
179     public function testFindForAbstractBaseClass()
180     {
181         $this->loadFullFixture();
182
183         $contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->fix->getId());
184
185         $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyFixContract', $contract);
186         $this->assertEquals(1000, $contract->getFixPrice());
187     }
188
189     public function testQueryForAbstractBaseClass()
190     {
191         $this->loadFullFixture();
192
193         $contracts = $this->_em->createQuery('SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c')->getResult();
194
195         $this->assertEquals(3, count($contracts));
196         $this->assertContainsOnly('Doctrine\Tests\Models\Company\CompanyContract', $contracts);
197     }
198
199     public function testQueryForChildClass()
200     {
201         $this->loadFullFixture();
202
203         $this->assertEquals(1, count($this->_em->createQuery('SELECT c FROM Doctrine\Tests\Models\Company\CompanyFixContract c')->getResult()));
204         $this->assertEquals(2, count($this->_em->createQuery('SELECT c FROM Doctrine\Tests\Models\Company\CompanyFlexContract c')->getResult()));
205         $this->assertEquals(1, count($this->_em->createQuery('SELECT c FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract c')->getResult()));
206     }
207
208     public function testQueryBaseClassWithJoin()
209     {
210         $this->loadFullFixture();
211
212         $contracts = $this->_em->createQuery('SELECT c, p FROM Doctrine\Tests\Models\Company\CompanyContract c JOIN c.salesPerson p')->getResult();
213         $this->assertEquals(3, count($contracts));
214         $this->assertContainsOnly('Doctrine\Tests\Models\Company\CompanyContract', $contracts);
215     }
216
217     public function testQueryScalarWithDiscrimnatorValue()
218     {
219         $this->loadFullFixture();
220
221         $contracts = $this->_em->createQuery('SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c ORDER BY c.id')->getScalarResult();
222
223         $discrValues = \array_map(function($a) {
224             return $a['c_discr'];
225         }, $contracts);
226
227         sort($discrValues);
228
229         $this->assertEquals(array('fix', 'flexible', 'flexultra'), $discrValues);
230     }
231
232     public function testQueryChildClassWithCondition()
233     {
234         $this->loadFullFixture();
235
236         $dql = 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyFixContract c WHERE c.fixPrice = ?1';
237         $contract = $this->_em->createQuery($dql)->setParameter(1, 1000)->getSingleResult();
238
239         $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyFixContract', $contract);
240         $this->assertEquals(1000, $contract->getFixPrice());
241     }
242
243     public function testUpdateChildClassWithCondition()
244     {
245         $this->loadFullFixture();
246
247         $dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyFlexContract c SET c.hoursWorked = c.hoursWorked * 2 WHERE c.hoursWorked = 150';
248         $affected = $this->_em->createQuery($dql)->execute();
249
250         $this->assertEquals(1, $affected);
251
252         $flexContract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->flex->getId());
253         $ultraContract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->ultra->getId());
254
255         $this->assertEquals(300, $ultraContract->getHoursWorked());
256         $this->assertEquals(100, $flexContract->getHoursWorked());
257     }
258
259     public function testUpdateBaseClassWithCondition()
260     {
261         $this->loadFullFixture();
262
263         $dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyContract c SET c.completed = true WHERE c.completed = false';
264         $affected = $this->_em->createQuery($dql)->execute();
265
266         $this->assertEquals(1, $affected);
267
268         $dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyContract c SET c.completed = false';
269         $affected = $this->_em->createQuery($dql)->execute();
270
271         $this->assertEquals(3, $affected);
272     }
273
274     public function testDeleteByChildClassCondition()
275     {
276         $this->loadFullFixture();
277
278         $dql = 'DELETE Doctrine\Tests\Models\Company\CompanyFlexContract c';
279         $affected = $this->_em->createQuery($dql)->execute();
280
281         $this->assertEquals(2, $affected);
282     }
283
284     public function testDeleteByBaseClassCondition()
285     {
286         $this->loadFullFixture();
287
288         $dql = "DELETE Doctrine\Tests\Models\Company\CompanyContract c WHERE c.completed = true";
289         $affected = $this->_em->createQuery($dql)->execute();
290
291         $this->assertEquals(2, $affected);
292
293         $contracts = $this->_em->createQuery('SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c')->getResult();
294         $this->assertEquals(1, count($contracts));
295
296         $this->assertFalse($contracts[0]->isCompleted(), "Only non completed contracts should be left.");
297     }
298
299     /**
300      * @group DDC-130
301      */
302     public function testDeleteJoinTableRecords()
303     {
304         $this->loadFullFixture();
305
306         // remove managed copy of the fix contract
307         $this->_em->remove($this->_em->find(get_class($this->fix), $this->fix->getId()));
308         $this->_em->flush();
309
310         $this->assertNull($this->_em->find(get_class($this->fix), $this->fix->getId()), "Contract should not be present in the database anymore.");
311     }
312
313     /**
314      * @group DDC-817
315      */
316     public function testFindByAssociation()
317     {
318         $this->loadFullFixture();
319
320         $repos = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyContract");
321         $contracts = $repos->findBy(array('salesPerson' => $this->salesPerson->getId()));
322         $this->assertEquals(3, count($contracts), "There should be 3 entities related to " . $this->salesPerson->getId() . " for 'Doctrine\Tests\Models\Company\CompanyContract'");
323
324         $repos = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyFixContract");
325         $contracts = $repos->findBy(array('salesPerson' => $this->salesPerson->getId()));
326         $this->assertEquals(1, count($contracts), "There should be 1 entities related to " . $this->salesPerson->getId() . " for 'Doctrine\Tests\Models\Company\CompanyFixContract'");
327
328         $repos = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyFlexContract");
329         $contracts = $repos->findBy(array('salesPerson' => $this->salesPerson->getId()));
330         $this->assertEquals(2, count($contracts), "There should be 2 entities related to " . $this->salesPerson->getId() . " for 'Doctrine\Tests\Models\Company\CompanyFlexContract'");
331
332         $repos = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyFlexUltraContract");
333         $contracts = $repos->findBy(array('salesPerson' => $this->salesPerson->getId()));
334         $this->assertEquals(1, count($contracts), "There should be 1 entities related to " . $this->salesPerson->getId() . " for 'Doctrine\Tests\Models\Company\CompanyFlexUltraContract'");
335     }
336
337     /**
338      * @group DDC-1637
339      */
340     public function testInheritanceMatching()
341     {
342         $this->loadFullFixture();
343
344         $repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyContract");
345         $contracts = $repository->matching(new Criteria(
346             Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
347         ));
348         $this->assertEquals(3, count($contracts));
349
350         $repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyFixContract");
351         $contracts = $repository->matching(new Criteria(
352             Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
353         ));
354         $this->assertEquals(1, count($contracts));
355     }
356
357     /**
358      * @group DDC-834
359      */
360     public function testGetReferenceEntityWithSubclasses()
361     {
362         $this->loadFullFixture();
363
364         $ref = $this->_em->getReference('Doctrine\Tests\Models\Company\CompanyContract', $this->fix->getId());
365         $this->assertNotInstanceOf('Doctrine\ORM\Proxy\Proxy', $ref, "Cannot Request a proxy from a class that has subclasses.");
366         $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyContract', $ref);
367         $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyFixContract', $ref, "Direct fetch of the reference has to load the child class Emplyoee directly.");
368         $this->_em->clear();
369
370         $ref = $this->_em->getReference('Doctrine\Tests\Models\Company\CompanyFixContract', $this->fix->getId());
371         $this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $ref, "A proxy can be generated only if no subclasses exists for the requested reference.");
372     }
373
374     /**
375      * @group DDC-952
376      */
377     public function testEagerLoadInheritanceHierachy()
378     {
379         $this->loadFullFixture();
380
381         $dql = 'SELECT f FROM Doctrine\Tests\Models\Company\CompanyFixContract f WHERE f.id = ?1';
382         $contract = $this->_em->createQuery($dql)
383                               ->setFetchMode('Doctrine\Tests\Models\Company\CompanyFixContract', 'salesPerson', ClassMetadata::FETCH_EAGER)
384                               ->setParameter(1, $this->fix->getId())
385                               ->getSingleResult();
386
387         $this->assertNotInstanceOf('Doctrine\ORM\Proxy\Proxy', $contract->getSalesPerson());
388     }
389 }