Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / tests / Doctrine / Tests / ORM / Functional / SQLFilterTest.php
1 <?php
2
3 namespace Doctrine\Tests\ORM\Functional;
4
5 use Doctrine\DBAL\Types\Type as DBALType;
6 use Doctrine\ORM\Query\Filter\SQLFilter;
7 use Doctrine\ORM\Mapping\ClassMetaData;
8 use Doctrine\Common\Cache\ArrayCache;
9
10 use Doctrine\ORM\Mapping\ClassMetadataInfo;
11
12 use Doctrine\Tests\Models\CMS\CmsUser;
13 use Doctrine\Tests\Models\CMS\CmsPhonenumber;
14 use Doctrine\Tests\Models\CMS\CmsAddress;
15 use Doctrine\Tests\Models\CMS\CmsGroup;
16 use Doctrine\Tests\Models\CMS\CmsArticle;
17 use Doctrine\Tests\Models\CMS\CmsComment;
18
19 use Doctrine\Tests\Models\Company\CompanyPerson;
20 use Doctrine\Tests\Models\Company\CompanyManager;
21 use Doctrine\Tests\Models\Company\CompanyEmployee;
22 use Doctrine\Tests\Models\Company\CompanyOrganization;
23 use Doctrine\Tests\Models\Company\CompanyAuction;
24
25 use Doctrine\Tests\Models\Company\CompanyFlexContract;
26 use Doctrine\Tests\Models\Company\CompanyFlexUltraContract;
27
28 require_once __DIR__ . '/../../TestInit.php';
29
30 /**
31  * Tests SQLFilter functionality.
32  *
33  * @author Alexander <iam.asm89@gmail.com>
34  */
35 class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
36 {
37     private $userId, $userId2, $articleId, $articleId2;
38     private $groupId, $groupId2;
39     private $managerId, $managerId2, $contractId1, $contractId2;
40     private $organizationId, $eventId1, $eventId2;
41
42     public function setUp()
43     {
44         $this->useModelSet('cms');
45         $this->useModelSet('company');
46         parent::setUp();
47     }
48
49     public function tearDown()
50     {
51         parent::tearDown();
52
53         $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
54         $class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
55         $class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
56     }
57
58     public function testConfigureFilter()
59     {
60         $config = new \Doctrine\ORM\Configuration();
61
62         $config->addFilter("locale", "\Doctrine\Tests\ORM\Functional\MyLocaleFilter");
63
64         $this->assertEquals("\Doctrine\Tests\ORM\Functional\MyLocaleFilter", $config->getFilterClassName("locale"));
65         $this->assertNull($config->getFilterClassName("foo"));
66     }
67
68     public function testEntityManagerEnableFilter()
69     {
70         $em = $this->_getEntityManager();
71         $this->configureFilters($em);
72
73         // Enable an existing filter
74         $filter = $em->getFilters()->enable("locale");
75         $this->assertTrue($filter instanceof \Doctrine\Tests\ORM\Functional\MyLocaleFilter);
76
77         // Enable the filter again
78         $filter2 = $em->getFilters()->enable("locale");
79         $this->assertEquals($filter, $filter2);
80
81         // Enable a non-existing filter
82         $exceptionThrown = false;
83         try {
84             $filter = $em->getFilters()->enable("foo");
85         } catch (\InvalidArgumentException $e) {
86             $exceptionThrown = true;
87         }
88         $this->assertTrue($exceptionThrown);
89     }
90
91     public function testEntityManagerEnabledFilters()
92     {
93         $em = $this->_getEntityManager();
94
95         // No enabled filters
96         $this->assertEquals(array(), $em->getFilters()->getEnabledFilters());
97
98         $this->configureFilters($em);
99         $filter = $em->getFilters()->enable("locale");
100         $filter = $em->getFilters()->enable("soft_delete");
101
102         // Two enabled filters
103         $this->assertEquals(2, count($em->getFilters()->getEnabledFilters()));
104
105     }
106
107     public function testEntityManagerDisableFilter()
108     {
109         $em = $this->_getEntityManager();
110         $this->configureFilters($em);
111
112         // Enable the filter
113         $filter = $em->getFilters()->enable("locale");
114
115         // Disable it
116         $this->assertEquals($filter, $em->getFilters()->disable("locale"));
117         $this->assertEquals(0, count($em->getFilters()->getEnabledFilters()));
118
119         // Disable a non-existing filter
120         $exceptionThrown = false;
121         try {
122             $filter = $em->getFilters()->disable("foo");
123         } catch (\InvalidArgumentException $e) {
124             $exceptionThrown = true;
125         }
126         $this->assertTrue($exceptionThrown);
127
128         // Disable a non-enabled filter
129         $exceptionThrown = false;
130         try {
131             $filter = $em->getFilters()->disable("locale");
132         } catch (\InvalidArgumentException $e) {
133             $exceptionThrown = true;
134         }
135         $this->assertTrue($exceptionThrown);
136     }
137
138     public function testEntityManagerGetFilter()
139     {
140         $em = $this->_getEntityManager();
141         $this->configureFilters($em);
142
143         // Enable the filter
144         $filter = $em->getFilters()->enable("locale");
145
146         // Get the filter
147         $this->assertEquals($filter, $em->getFilters()->getFilter("locale"));
148
149         // Get a non-enabled filter
150         $exceptionThrown = false;
151         try {
152             $filter = $em->getFilters()->getFilter("soft_delete");
153         } catch (\InvalidArgumentException $e) {
154             $exceptionThrown = true;
155         }
156         $this->assertTrue($exceptionThrown);
157     }
158
159     protected function configureFilters($em)
160     {
161         // Add filters to the configuration of the EM
162         $config = $em->getConfiguration();
163         $config->addFilter("locale", "\Doctrine\Tests\ORM\Functional\MyLocaleFilter");
164         $config->addFilter("soft_delete", "\Doctrine\Tests\ORM\Functional\MySoftDeleteFilter");
165     }
166
167     protected function getMockConnection()
168     {
169         // Setup connection mock
170         $conn = $this->getMockBuilder('Doctrine\DBAL\Connection')
171             ->disableOriginalConstructor()
172             ->getMock();
173
174         return $conn;
175     }
176
177     protected function getMockEntityManager()
178     {
179         // Setup connection mock
180         $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
181             ->disableOriginalConstructor()
182             ->getMock();
183
184         return $em;
185     }
186
187     protected function addMockFilterCollection($em)
188     {
189         $filterCollection = $this->getMockBuilder('Doctrine\ORM\Query\FilterCollection')
190             ->disableOriginalConstructor()
191             ->getMock();
192
193         $em->expects($this->any())
194             ->method('getFilters')
195             ->will($this->returnValue($filterCollection));
196
197         return $filterCollection;
198     }
199
200     public function testSQLFilterGetSetParameter()
201     {
202         // Setup mock connection
203         $conn = $this->getMockConnection();
204         $conn->expects($this->once())
205             ->method('quote')
206             ->with($this->equalTo('en'))
207             ->will($this->returnValue("'en'"));
208
209         $em = $this->getMockEntityManager($conn);
210         $em->expects($this->once())
211             ->method('getConnection')
212             ->will($this->returnValue($conn));
213
214         $filterCollection = $this->addMockFilterCollection($em);
215         $filterCollection
216             ->expects($this->once())
217             ->method('setFiltersStateDirty');
218
219         $filter = new MyLocaleFilter($em);
220
221         $filter->setParameter('locale', 'en', DBALType::STRING);
222
223         $this->assertEquals("'en'", $filter->getParameter('locale'));
224     }
225
226     public function testSQLFilterSetParameterInfersType()
227     {
228         // Setup mock connection
229         $conn = $this->getMockConnection();
230         $conn->expects($this->once())
231             ->method('quote')
232             ->with($this->equalTo('en'))
233             ->will($this->returnValue("'en'"));
234
235         $em = $this->getMockEntityManager($conn);
236         $em->expects($this->once())
237             ->method('getConnection')
238             ->will($this->returnValue($conn));
239
240         $filterCollection = $this->addMockFilterCollection($em);
241         $filterCollection
242             ->expects($this->once())
243             ->method('setFiltersStateDirty');
244
245         $filter = new MyLocaleFilter($em);
246
247         $filter->setParameter('locale', 'en');
248
249         $this->assertEquals("'en'", $filter->getParameter('locale'));
250     }
251
252     public function testSQLFilterAddConstraint()
253     {
254         // Set up metadata mock
255         $targetEntity = $this->getMockBuilder('Doctrine\ORM\Mapping\ClassMetadata')
256             ->disableOriginalConstructor()
257             ->getMock();
258
259         $filter = new MySoftDeleteFilter($this->getMockEntityManager());
260
261         // Test for an entity that gets extra filter data
262         $targetEntity->name = 'MyEntity\SoftDeleteNewsItem';
263         $this->assertEquals('t1_.deleted = 0', $filter->addFilterConstraint($targetEntity, 't1_'));
264
265         // Test for an entity that doesn't get extra filter data
266         $targetEntity->name = 'MyEntity\NoSoftDeleteNewsItem';
267         $this->assertEquals('', $filter->addFilterConstraint($targetEntity, 't1_'));
268
269     }
270
271     public function testSQLFilterToString()
272     {
273         $em = $this->getMockEntityManager();
274         $filterCollection = $this->addMockFilterCollection($em);
275
276         $filter = new MyLocaleFilter($em);
277         $filter->setParameter('locale', 'en', DBALType::STRING);
278         $filter->setParameter('foo', 'bar', DBALType::STRING);
279
280         $filter2 = new MyLocaleFilter($em);
281         $filter2->setParameter('foo', 'bar', DBALType::STRING);
282         $filter2->setParameter('locale', 'en', DBALType::STRING);
283
284         $parameters = array(
285             'foo' => array('value' => 'bar', 'type' => DBALType::STRING),
286             'locale' => array('value' => 'en', 'type' => DBALType::STRING),
287         );
288
289         $this->assertEquals(serialize($parameters), ''.$filter);
290         $this->assertEquals(''.$filter, ''.$filter2);
291     }
292
293     public function testQueryCache_DependsOnFilters()
294     {
295         $cacheDataReflection = new \ReflectionProperty("Doctrine\Common\Cache\ArrayCache", "data");
296         $cacheDataReflection->setAccessible(true);
297
298         $query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
299
300         $cache = new ArrayCache();
301         $query->setQueryCacheDriver($cache);
302
303         $query->getResult();
304         $this->assertEquals(2, sizeof($cacheDataReflection->getValue($cache)));
305
306         $conf = $this->_em->getConfiguration();
307         $conf->addFilter("locale", "\Doctrine\Tests\ORM\Functional\MyLocaleFilter");
308         $this->_em->getFilters()->enable("locale");
309
310         $query->getResult();
311         $this->assertEquals(3, sizeof($cacheDataReflection->getValue($cache)));
312
313         // Another time doesn't add another cache entry
314         $query->getResult();
315         $this->assertEquals(3, sizeof($cacheDataReflection->getValue($cache)));
316     }
317
318     public function testQueryGeneration_DependsOnFilters()
319     {
320         $query = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsAddress a');
321         $firstSQLQuery = $query->getSQL();
322
323         $conf = $this->_em->getConfiguration();
324         $conf->addFilter("country", "\Doctrine\Tests\ORM\Functional\CMSCountryFilter");
325         $this->_em->getFilters()->enable("country")
326             ->setParameter("country", "en", DBALType::STRING);
327
328         $this->assertNotEquals($firstSQLQuery, $query->getSQL());
329     }
330
331     public function testRepositoryFind()
332     {
333         $this->loadFixtureData();
334
335         $this->assertNotNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->find($this->groupId));
336         $this->assertNotNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->find($this->groupId2));
337
338         $this->useCMSGroupPrefixFilter();
339         $this->_em->clear();
340
341         $this->assertNotNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->find($this->groupId));
342         $this->assertNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->find($this->groupId2));
343     }
344
345     public function testRepositoryFindAll()
346     {
347         $this->loadFixtureData();
348
349         $this->assertCount(2, $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findAll());
350
351         $this->useCMSGroupPrefixFilter();
352         $this->_em->clear();
353
354         $this->assertCount(1, $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findAll());
355     }
356
357     public function testRepositoryFindBy()
358     {
359         $this->loadFixtureData();
360
361         $this->assertCount(1, $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findBy(array('id' => $this->groupId2)));
362
363         $this->useCMSGroupPrefixFilter();
364         $this->_em->clear();
365
366         $this->assertCount(0, $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findBy(array('id' => $this->groupId2)));
367     }
368
369     public function testRepositoryFindByX()
370     {
371         $this->loadFixtureData();
372
373         $this->assertCount(1, $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findById($this->groupId2));
374
375         $this->useCMSGroupPrefixFilter();
376         $this->_em->clear();
377
378         $this->assertCount(0, $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findById($this->groupId2));
379     }
380
381     public function testRepositoryFindOneBy()
382     {
383         $this->loadFixtureData();
384
385         $this->assertNotNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findOneBy(array('id' => $this->groupId2)));
386
387         $this->useCMSGroupPrefixFilter();
388         $this->_em->clear();
389
390         $this->assertNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findOneBy(array('id' => $this->groupId2)));
391     }
392
393     public function testRepositoryFindOneByX()
394     {
395         $this->loadFixtureData();
396
397         $this->assertNotNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findOneById($this->groupId2));
398
399         $this->useCMSGroupPrefixFilter();
400         $this->_em->clear();
401
402         $this->assertNull($this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsGroup')->findOneById($this->groupId2));
403     }
404
405     public function testToOneFilter()
406     {
407         //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
408         $this->loadFixtureData();
409
410         $query = $this->_em->createQuery('select ux, ua from Doctrine\Tests\Models\CMS\CmsUser ux JOIN ux.address ua');
411
412         // We get two users before enabling the filter
413         $this->assertEquals(2, count($query->getResult()));
414
415         $conf = $this->_em->getConfiguration();
416         $conf->addFilter("country", "\Doctrine\Tests\ORM\Functional\CMSCountryFilter");
417         $this->_em->getFilters()->enable("country")->setParameter("country", "Germany", DBALType::STRING);
418
419         // We get one user after enabling the filter
420         $this->assertEquals(1, count($query->getResult()));
421     }
422
423     public function testManyToManyFilter()
424     {
425         $this->loadFixtureData();
426         $query = $this->_em->createQuery('select ux, ug from Doctrine\Tests\Models\CMS\CmsUser ux JOIN ux.groups ug');
427
428         // We get two users before enabling the filter
429         $this->assertEquals(2, count($query->getResult()));
430
431         $conf = $this->_em->getConfiguration();
432         $conf->addFilter("group_prefix", "\Doctrine\Tests\ORM\Functional\CMSGroupPrefixFilter");
433         $this->_em->getFilters()->enable("group_prefix")->setParameter("prefix", "bar_%", DBALType::STRING);
434
435         // We get one user after enabling the filter
436         $this->assertEquals(1, count($query->getResult()));
437
438     }
439
440     public function testWhereFilter()
441     {
442         $this->loadFixtureData();
443         $query = $this->_em->createQuery('select ug from Doctrine\Tests\Models\CMS\CmsGroup ug WHERE 1=1');
444
445         // We get two users before enabling the filter
446         $this->assertEquals(2, count($query->getResult()));
447
448         $conf = $this->_em->getConfiguration();
449         $conf->addFilter("group_prefix", "\Doctrine\Tests\ORM\Functional\CMSGroupPrefixFilter");
450         $this->_em->getFilters()->enable("group_prefix")->setParameter("prefix", "bar_%", DBALType::STRING);
451
452         // We get one user after enabling the filter
453         $this->assertEquals(1, count($query->getResult()));
454     }
455
456
457     private function loadLazyFixtureData()
458     {
459         $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
460         $class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
461         $class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
462         $this->loadFixtureData();
463     }
464
465     private function useCMSArticleTopicFilter()
466     {
467         $conf = $this->_em->getConfiguration();
468         $conf->addFilter("article_topic", "\Doctrine\Tests\ORM\Functional\CMSArticleTopicFilter");
469         $this->_em->getFilters()->enable("article_topic")->setParameter("topic", "Test1", DBALType::STRING);
470     }
471
472     public function testOneToMany_ExtraLazyCountWithFilter()
473     {
474         $this->loadLazyFixtureData();
475         $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
476
477         $this->assertFalse($user->articles->isInitialized());
478         $this->assertEquals(2, count($user->articles));
479
480         $this->useCMSArticleTopicFilter();
481
482         $this->assertEquals(1, count($user->articles));
483     }
484
485     public function testOneToMany_ExtraLazyContainsWithFilter()
486     {
487         $this->loadLazyFixtureData();
488         $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
489         $filteredArticle = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId2);
490
491         $this->assertFalse($user->articles->isInitialized());
492         $this->assertTrue($user->articles->contains($filteredArticle));
493
494         $this->useCMSArticleTopicFilter();
495
496         $this->assertFalse($user->articles->contains($filteredArticle));
497     }
498
499     public function testOneToMany_ExtraLazySliceWithFilter()
500     {
501         $this->loadLazyFixtureData();
502         $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
503
504         $this->assertFalse($user->articles->isInitialized());
505         $this->assertEquals(2, count($user->articles->slice(0,10)));
506
507         $this->useCMSArticleTopicFilter();
508
509         $this->assertEquals(1, count($user->articles->slice(0,10)));
510     }
511
512     private function useCMSGroupPrefixFilter()
513     {
514         $conf = $this->_em->getConfiguration();
515         $conf->addFilter("group_prefix", "\Doctrine\Tests\ORM\Functional\CMSGroupPrefixFilter");
516         $this->_em->getFilters()->enable("group_prefix")->setParameter("prefix", "foo%", DBALType::STRING);
517     }
518
519     public function testManyToMany_ExtraLazyCountWithFilter()
520     {
521         $this->loadLazyFixtureData();
522
523         $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId2);
524
525         $this->assertFalse($user->groups->isInitialized());
526         $this->assertEquals(2, count($user->groups));
527
528         $this->useCMSGroupPrefixFilter();
529
530         $this->assertEquals(1, count($user->groups));
531     }
532
533     public function testManyToMany_ExtraLazyContainsWithFilter()
534     {
535         $this->loadLazyFixtureData();
536         $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId2);
537         $filteredArticle = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId2);
538
539         $this->assertFalse($user->groups->isInitialized());
540         $this->assertTrue($user->groups->contains($filteredArticle));
541
542         $this->useCMSGroupPrefixFilter();
543
544         $this->assertFalse($user->groups->contains($filteredArticle));
545     }
546
547     public function testManyToMany_ExtraLazySliceWithFilter()
548     {
549         $this->loadLazyFixtureData();
550         $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId2);
551
552         $this->assertFalse($user->groups->isInitialized());
553         $this->assertEquals(2, count($user->groups->slice(0,10)));
554
555         $this->useCMSGroupPrefixFilter();
556
557         $this->assertEquals(1, count($user->groups->slice(0,10)));
558     }
559
560     private function loadFixtureData()
561     {
562         $user = new CmsUser;
563         $user->name = 'Roman';
564         $user->username = 'romanb';
565         $user->status = 'developer';
566
567         $address = new CmsAddress;
568         $address->country = 'Germany';
569         $address->city = 'Berlin';
570         $address->zip = '12345';
571
572         $user->address = $address; // inverse side
573         $address->user = $user; // owning side!
574
575         $group = new CmsGroup;
576         $group->name = 'foo_group';
577         $user->addGroup($group);
578
579         $article1 = new CmsArticle;
580         $article1->topic = "Test1";
581         $article1->text = "Test";
582         $article1->setAuthor($user);
583
584         $article2 = new CmsArticle;
585         $article2->topic = "Test2";
586         $article2->text = "Test";
587         $article2->setAuthor($user);
588
589         $this->_em->persist($article1);
590         $this->_em->persist($article2);
591
592         $this->_em->persist($user);
593
594         $user2 = new CmsUser;
595         $user2->name = 'Guilherme';
596         $user2->username = 'gblanco';
597         $user2->status = 'developer';
598
599         $address2 = new CmsAddress;
600         $address2->country = 'France';
601         $address2->city = 'Paris';
602         $address2->zip = '12345';
603
604         $user->address = $address2; // inverse side
605         $address2->user = $user2; // owning side!
606
607         $user2->addGroup($group);
608         $group2 = new CmsGroup;
609         $group2->name = 'bar_group';
610         $user2->addGroup($group2);
611
612         $this->_em->persist($user2);
613         $this->_em->flush();
614         $this->_em->clear();
615
616         $this->userId = $user->getId();
617         $this->userId2 = $user2->getId();
618         $this->articleId = $article1->id;
619         $this->articleId2 = $article2->id;
620         $this->groupId = $group->id;
621         $this->groupId2 = $group2->id;
622     }
623
624     public function testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingSubEntity()
625     {
626         $this->loadCompanyJoinedSubclassFixtureData();
627         // Persister
628         $this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll()));
629         // SQLWalker
630         $this->assertEquals(2, count($this->_em->createQuery("SELECT cm FROM Doctrine\Tests\Models\Company\CompanyManager cm")->getResult()));
631
632         // Enable the filter
633         $this->usePersonNameFilter('Guilh%');
634
635         $managers = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll();
636         $this->assertEquals(1, count($managers));
637         $this->assertEquals("Guilherme", $managers[0]->getName());
638
639         $this->assertEquals(1, count($this->_em->createQuery("SELECT cm FROM Doctrine\Tests\Models\Company\CompanyManager cm")->getResult()));
640     }
641
642     public function testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingRootEntity()
643     {
644         $this->loadCompanyJoinedSubclassFixtureData();
645         $this->assertEquals(3, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyPerson')->findAll()));
646         $this->assertEquals(3, count($this->_em->createQuery("SELECT cp FROM Doctrine\Tests\Models\Company\CompanyPerson cp")->getResult()));
647
648         // Enable the filter
649         $this->usePersonNameFilter('Guilh%');
650
651         $persons = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyPerson')->findAll();
652         $this->assertEquals(1, count($persons));
653         $this->assertEquals("Guilherme", $persons[0]->getName());
654
655         $this->assertEquals(1, count($this->_em->createQuery("SELECT cp FROM Doctrine\Tests\Models\Company\CompanyPerson cp")->getResult()));
656     }
657
658     private function loadCompanyJoinedSubclassFixtureData()
659     {
660         $manager = new CompanyManager;
661         $manager->setName('Roman');
662         $manager->setTitle('testlead');
663         $manager->setSalary(42);
664         $manager->setDepartment('persisters');
665
666         $manager2 = new CompanyManager;
667         $manager2->setName('Guilherme');
668         $manager2->setTitle('devlead');
669         $manager2->setSalary(42);
670         $manager2->setDepartment('parsers');
671
672         $person = new CompanyPerson;
673         $person->setName('Benjamin');
674
675         $this->_em->persist($manager);
676         $this->_em->persist($manager2);
677         $this->_em->persist($person);
678         $this->_em->flush();
679         $this->_em->clear();
680     }
681
682     public function testSingleTableInheritance_FilterOnlyOnRootTableWhenFetchingSubEntity()
683     {
684         $this->loadCompanySingleTableInheritanceFixtureData();
685         // Persister
686         $this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexUltraContract')->findAll()));
687         // SQLWalker
688         $this->assertEquals(2, count($this->_em->createQuery("SELECT cfc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract cfc")->getResult()));
689
690         // Enable the filter
691         $conf = $this->_em->getConfiguration();
692         $conf->addFilter("completed_contract", "\Doctrine\Tests\ORM\Functional\CompletedContractFilter");
693         $this->_em->getFilters()
694             ->enable("completed_contract")
695             ->setParameter("completed", true, DBALType::BOOLEAN);
696
697         $this->assertEquals(1, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexUltraContract')->findAll()));
698         $this->assertEquals(1, count($this->_em->createQuery("SELECT cfc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract cfc")->getResult()));
699     }
700
701     public function testSingleTableInheritance_FilterOnlyOnRootTableWhenFetchingRootEntity()
702     {
703         $this->loadCompanySingleTableInheritanceFixtureData();
704         $this->assertEquals(4, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexContract')->findAll()));
705         $this->assertEquals(4, count($this->_em->createQuery("SELECT cfc FROM Doctrine\Tests\Models\Company\CompanyFlexContract cfc")->getResult()));
706
707         // Enable the filter
708         $conf = $this->_em->getConfiguration();
709         $conf->addFilter("completed_contract", "\Doctrine\Tests\ORM\Functional\CompletedContractFilter");
710         $this->_em->getFilters()
711             ->enable("completed_contract")
712             ->setParameter("completed", true, DBALType::BOOLEAN);
713
714         $this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexContract')->findAll()));
715         $this->assertEquals(2, count($this->_em->createQuery("SELECT cfc FROM Doctrine\Tests\Models\Company\CompanyFlexContract cfc")->getResult()));
716     }
717
718     private function loadCompanySingleTableInheritanceFixtureData()
719     {
720         $contract1 = new CompanyFlexUltraContract;
721         $contract2 = new CompanyFlexUltraContract;
722         $contract2->markCompleted();
723
724         $contract3 = new CompanyFlexContract;
725         $contract4 = new CompanyFlexContract;
726         $contract4->markCompleted();
727
728         $manager = new CompanyManager;
729         $manager->setName('Alexander');
730         $manager->setSalary(42);
731         $manager->setDepartment('Doctrine');
732         $manager->setTitle('Filterer');
733
734         $manager2 = new CompanyManager;
735         $manager2->setName('Benjamin');
736         $manager2->setSalary(1337);
737         $manager2->setDepartment('Doctrine');
738         $manager2->setTitle('Maintainer');
739
740         $contract1->addManager($manager);
741         $contract2->addManager($manager);
742         $contract3->addManager($manager);
743         $contract4->addManager($manager);
744
745         $contract1->addManager($manager2);
746
747         $contract1->setSalesPerson($manager);
748         $contract2->setSalesPerson($manager);
749
750         $this->_em->persist($manager);
751         $this->_em->persist($manager2);
752         $this->_em->persist($contract1);
753         $this->_em->persist($contract2);
754         $this->_em->persist($contract3);
755         $this->_em->persist($contract4);
756         $this->_em->flush();
757         $this->_em->clear();
758
759         $this->managerId = $manager->getId();
760         $this->managerId2 = $manager2->getId();
761         $this->contractId1 = $contract1->getId();
762         $this->contractId2 = $contract2->getId();
763     }
764
765     private function useCompletedContractFilter()
766     {
767         $conf = $this->_em->getConfiguration();
768         $conf->addFilter("completed_contract", "\Doctrine\Tests\ORM\Functional\CompletedContractFilter");
769         $this->_em->getFilters()
770             ->enable("completed_contract")
771             ->setParameter("completed", true, DBALType::BOOLEAN);
772     }
773
774     public function testManyToMany_ExtraLazyCountWithFilterOnSTI()
775     {
776         $this->loadCompanySingleTableInheritanceFixtureData();
777
778         $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
779
780         $this->assertFalse($manager->managedContracts->isInitialized());
781         $this->assertEquals(4, count($manager->managedContracts));
782
783         // Enable the filter
784         $this->useCompletedContractFilter();
785
786         $this->assertFalse($manager->managedContracts->isInitialized());
787         $this->assertEquals(2, count($manager->managedContracts));
788     }
789
790     public function testManyToMany_ExtraLazyContainsWithFilterOnSTI()
791     {
792         $this->loadCompanySingleTableInheritanceFixtureData();
793
794         $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
795         $contract1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId1);
796         $contract2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId2);
797
798         $this->assertFalse($manager->managedContracts->isInitialized());
799         $this->assertTrue($manager->managedContracts->contains($contract1));
800         $this->assertTrue($manager->managedContracts->contains($contract2));
801
802         // Enable the filter
803         $this->useCompletedContractFilter();
804
805         $this->assertFalse($manager->managedContracts->isInitialized());
806         $this->assertFalse($manager->managedContracts->contains($contract1));
807         $this->assertTrue($manager->managedContracts->contains($contract2));
808     }
809
810     public function testManyToMany_ExtraLazySliceWithFilterOnSTI()
811     {
812         $this->loadCompanySingleTableInheritanceFixtureData();
813
814         $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
815
816         $this->assertFalse($manager->managedContracts->isInitialized());
817         $this->assertEquals(4, count($manager->managedContracts->slice(0, 10)));
818
819         // Enable the filter
820         $this->useCompletedContractFilter();
821
822         $this->assertFalse($manager->managedContracts->isInitialized());
823         $this->assertEquals(2, count($manager->managedContracts->slice(0, 10)));
824     }
825
826     private function usePersonNameFilter($name)
827     {
828         // Enable the filter
829         $conf = $this->_em->getConfiguration();
830         $conf->addFilter("person_name", "\Doctrine\Tests\ORM\Functional\CompanyPersonNameFilter");
831         $this->_em->getFilters()
832             ->enable("person_name")
833             ->setParameter("name", $name, DBALType::STRING);
834     }
835
836     public function testManyToMany_ExtraLazyCountWithFilterOnCTI()
837     {
838         $this->loadCompanySingleTableInheritanceFixtureData();
839
840         $contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $this->contractId1);
841
842         $this->assertFalse($contract->managers->isInitialized());
843         $this->assertEquals(2, count($contract->managers));
844
845         // Enable the filter
846         $this->usePersonNameFilter('Benjamin');
847
848         $this->assertFalse($contract->managers->isInitialized());
849         $this->assertEquals(1, count($contract->managers));
850     }
851
852     public function testManyToMany_ExtraLazyContainsWithFilterOnCTI()
853     {
854         $this->loadCompanySingleTableInheritanceFixtureData();
855
856         $contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $this->contractId1);
857         $manager1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
858         $manager2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId2);
859
860         $this->assertFalse($contract->managers->isInitialized());
861         $this->assertTrue($contract->managers->contains($manager1));
862         $this->assertTrue($contract->managers->contains($manager2));
863
864         // Enable the filter
865         $this->usePersonNameFilter('Benjamin');
866
867         $this->assertFalse($contract->managers->isInitialized());
868         $this->assertFalse($contract->managers->contains($manager1));
869         $this->assertTrue($contract->managers->contains($manager2));
870     }
871
872     public function testManyToMany_ExtraLazySliceWithFilterOnCTI()
873     {
874         $this->loadCompanySingleTableInheritanceFixtureData();
875
876         $contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexUltraContract', $this->contractId1);
877
878         $this->assertFalse($contract->managers->isInitialized());
879         $this->assertEquals(2, count($contract->managers->slice(0, 10)));
880
881         // Enable the filter
882         $this->usePersonNameFilter('Benjamin');
883
884         $this->assertFalse($contract->managers->isInitialized());
885         $this->assertEquals(1, count($contract->managers->slice(0, 10)));
886     }
887
888     public function testOneToMany_ExtraLazyCountWithFilterOnSTI()
889     {
890         $this->loadCompanySingleTableInheritanceFixtureData();
891
892         $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
893
894         $this->assertFalse($manager->soldContracts->isInitialized());
895         $this->assertEquals(2, count($manager->soldContracts));
896
897         // Enable the filter
898         $this->useCompletedContractFilter();
899
900         $this->assertFalse($manager->soldContracts->isInitialized());
901         $this->assertEquals(1, count($manager->soldContracts));
902     }
903
904     public function testOneToMany_ExtraLazyContainsWithFilterOnSTI()
905     {
906         $this->loadCompanySingleTableInheritanceFixtureData();
907
908         $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
909         $contract1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId1);
910         $contract2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyContract', $this->contractId2);
911
912         $this->assertFalse($manager->soldContracts->isInitialized());
913         $this->assertTrue($manager->soldContracts->contains($contract1));
914         $this->assertTrue($manager->soldContracts->contains($contract2));
915
916         // Enable the filter
917         $this->useCompletedContractFilter();
918
919         $this->assertFalse($manager->soldContracts->isInitialized());
920         $this->assertFalse($manager->soldContracts->contains($contract1));
921         $this->assertTrue($manager->soldContracts->contains($contract2));
922     }
923
924     public function testOneToMany_ExtraLazySliceWithFilterOnSTI()
925     {
926
927         $this->loadCompanySingleTableInheritanceFixtureData();
928
929         $manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $this->managerId);
930
931         $this->assertFalse($manager->soldContracts->isInitialized());
932         $this->assertEquals(2, count($manager->soldContracts->slice(0, 10)));
933
934         // Enable the filter
935         $this->useCompletedContractFilter();
936
937         $this->assertFalse($manager->soldContracts->isInitialized());
938         $this->assertEquals(1, count($manager->soldContracts->slice(0, 10)));
939     }
940     private function loadCompanyOrganizationEventJoinedSubclassFixtureData()
941     {
942         $organization = new CompanyOrganization;
943
944         $event1 = new CompanyAuction;
945         $event1->setData('foo');
946
947         $event2 = new CompanyAuction;
948         $event2->setData('bar');
949
950         $organization->addEvent($event1);
951         $organization->addEvent($event2);
952
953         $this->_em->persist($organization);
954         $this->_em->flush();
955         $this->_em->clear();
956
957         $this->organizationId = $organization->getId();
958         $this->eventId1 = $event1->getId();
959         $this->eventId2 = $event2->getId();
960     }
961
962     private function useCompanyEventIdFilter()
963     {
964         // Enable the filter
965         $conf = $this->_em->getConfiguration();
966         $conf->addFilter("event_id", "\Doctrine\Tests\ORM\Functional\CompanyEventFilter");
967         $this->_em->getFilters()
968             ->enable("event_id")
969             ->setParameter("id", $this->eventId2);
970     }
971
972
973     public function testOneToMany_ExtraLazyCountWithFilterOnCTI()
974     {
975         $this->loadCompanyOrganizationEventJoinedSubclassFixtureData();
976
977         $organization = $this->_em->find('Doctrine\Tests\Models\Company\CompanyOrganization', $this->organizationId);
978
979         $this->assertFalse($organization->events->isInitialized());
980         $this->assertEquals(2, count($organization->events));
981
982         // Enable the filter
983         $this->useCompanyEventIdFilter();
984
985         $this->assertFalse($organization->events->isInitialized());
986         $this->assertEquals(1, count($organization->events));
987     }
988
989     public function testOneToMany_ExtraLazyContainsWithFilterOnCTI()
990     {
991         $this->loadCompanyOrganizationEventJoinedSubclassFixtureData();
992
993         $organization = $this->_em->find('Doctrine\Tests\Models\Company\CompanyOrganization', $this->organizationId);
994
995         $event1 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyEvent', $this->eventId1);
996         $event2 = $this->_em->find('Doctrine\Tests\Models\Company\CompanyEvent', $this->eventId2);
997
998         $this->assertFalse($organization->events->isInitialized());
999         $this->assertTrue($organization->events->contains($event1));
1000         $this->assertTrue($organization->events->contains($event2));
1001
1002         // Enable the filter
1003         $this->useCompanyEventIdFilter();
1004
1005         $this->assertFalse($organization->events->isInitialized());
1006         $this->assertFalse($organization->events->contains($event1));
1007         $this->assertTrue($organization->events->contains($event2));
1008     }
1009
1010     public function testOneToMany_ExtraLazySliceWithFilterOnCTI()
1011     {
1012         $this->loadCompanyOrganizationEventJoinedSubclassFixtureData();
1013
1014         $organization = $this->_em->find('Doctrine\Tests\Models\Company\CompanyOrganization', $this->organizationId);
1015
1016         $this->assertFalse($organization->events->isInitialized());
1017         $this->assertEquals(2, count($organization->events->slice(0, 10)));
1018
1019         // Enable the filter
1020         $this->useCompanyEventIdFilter();
1021
1022         $this->assertFalse($organization->events->isInitialized());
1023         $this->assertEquals(1, count($organization->events->slice(0, 10)));
1024     }
1025 }
1026
1027 class MySoftDeleteFilter extends SQLFilter
1028 {
1029     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
1030     {
1031         if ($targetEntity->name != "MyEntity\SoftDeleteNewsItem") {
1032             return "";
1033         }
1034
1035         return $targetTableAlias.'.deleted = 0';
1036     }
1037 }
1038
1039 class MyLocaleFilter extends SQLFilter
1040 {
1041     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
1042     {
1043         if (!in_array("LocaleAware", $targetEntity->reflClass->getInterfaceNames())) {
1044             return "";
1045         }
1046
1047         return $targetTableAlias.'.locale = ' . $this->getParameter('locale'); // getParam uses connection to quote the value.
1048     }
1049 }
1050
1051 class CMSCountryFilter extends SQLFilter
1052 {
1053     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
1054     {
1055         if ($targetEntity->name != "Doctrine\Tests\Models\CMS\CmsAddress") {
1056             return "";
1057         }
1058
1059         return $targetTableAlias.'.country = ' . $this->getParameter('country'); // getParam uses connection to quote the value.
1060     }
1061 }
1062
1063 class CMSGroupPrefixFilter extends SQLFilter
1064 {
1065     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
1066     {
1067         if ($targetEntity->name != "Doctrine\Tests\Models\CMS\CmsGroup") {
1068             return "";
1069         }
1070
1071         return $targetTableAlias.'.name LIKE ' . $this->getParameter('prefix'); // getParam uses connection to quote the value.
1072     }
1073 }
1074
1075 class CMSArticleTopicFilter extends SQLFilter
1076 {
1077     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
1078     {
1079         if ($targetEntity->name != "Doctrine\Tests\Models\CMS\CmsArticle") {
1080             return "";
1081         }
1082
1083         return $targetTableAlias.'.topic = ' . $this->getParameter('topic'); // getParam uses connection to quote the value.
1084     }
1085 }
1086
1087 class CompanyPersonNameFilter extends SQLFilter
1088 {
1089     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
1090     {
1091         if ($targetEntity->name != "Doctrine\Tests\Models\Company\CompanyPerson") {
1092             return "";
1093         }
1094
1095         return $targetTableAlias.'.name LIKE ' . $this->getParameter('name');
1096     }
1097 }
1098
1099 class CompletedContractFilter extends SQLFilter
1100 {
1101     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
1102     {
1103         if ($targetEntity->name != "Doctrine\Tests\Models\Company\CompanyContract") {
1104             return "";
1105         }
1106
1107         return $targetTableAlias.'.completed = ' . $this->getParameter('completed');
1108     }
1109 }
1110
1111 class CompanyEventFilter extends SQLFilter
1112 {
1113     public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '')
1114     {
1115         if ($targetEntity->name != "Doctrine\Tests\Models\Company\CompanyEvent") {
1116             return "";
1117         }
1118
1119         return $targetTableAlias.'.id = ' . $this->getParameter('id');
1120     }
1121 }