diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 1f4550d8c..af7cf302c 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -1584,7 +1584,15 @@ class BasicEntityPersister ); } - private function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) + /** + * Generates the filter SQL for a given entity and table alias. + * + * @param ClassMetadata $targetEntity Metadata of the target entity. + * @param string $targetTableAlias The table alias of the joined/selected table. + * + * @return string The SQL query part to add to a query. + */ + protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) { $filterSql = ''; diff --git a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php index 9e9477f0a..73e65797c 100644 --- a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php +++ b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php @@ -491,18 +491,4 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister $this->_class->setFieldValue($entity, $this->_class->versionField, $value); } - private function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) - { - $filterSql = ''; - - $first = true; - foreach($this->_em->getFilters()->getEnabledFilters() as $filter) { - if("" !== $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias)) { - if ( ! $first) $filterSql .= ' AND '; else $first = false; - $filterSql .= '(' . $filterExpr . ')'; - } - } - - return $filterSql; - } } diff --git a/lib/Doctrine/ORM/Persisters/SingleTablePersister.php b/lib/Doctrine/ORM/Persisters/SingleTablePersister.php index 0f1b9e3de..d11486e93 100644 --- a/lib/Doctrine/ORM/Persisters/SingleTablePersister.php +++ b/lib/Doctrine/ORM/Persisters/SingleTablePersister.php @@ -131,4 +131,16 @@ class SingleTablePersister extends AbstractEntityInheritancePersister return $conditionSql; } + + /** {@inheritdoc} */ + protected function generateFilterConditionSQL(ClassMetadata $targetEntity, $targetTableAlias) + { + // Ensure that the filters are applied to the root entity of the inheritance tree + $realTargetEntity = $targetEntity; + if($targetEntity->name !== $targetEntity->rootEntityName) { + $realTargetEntity = $this->_em->getClassMetadata($targetEntity->rootEntityName); + } + + return parent::generateFilterConditionSQL($realTargetEntity, $targetTableAlias); + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php b/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php index 5d9803277..2353814b0 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php @@ -19,6 +19,9 @@ use Doctrine\Tests\Models\Company\CompanyPerson; use Doctrine\Tests\Models\Company\CompanyManager; use Doctrine\Tests\Models\Company\CompanyEmployee; +use Doctrine\Tests\Models\Company\CompanyFlexContract; +use Doctrine\Tests\Models\Company\CompanyFlexUltraContract; + require_once __DIR__ . '/../../TestInit.php'; /** @@ -515,7 +518,7 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase public function testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingSubEntity() { - $this->loadCompanyFixtureData(); + $this->loadCompanyJoinedSubclassFixtureData(); $this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyManager')->findAll())); // Enable the filter @@ -532,7 +535,7 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase public function testJoinSubclassPersister_FilterOnlyOnRootTableWhenFetchingRootEntity() { - $this->loadCompanyFixtureData(); + $this->loadCompanyJoinedSubclassFixtureData(); $this->assertEquals(3, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyPerson')->findAll())); // Enable the filter @@ -542,12 +545,12 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase ->enable("person_name") ->setParameter("name", "Guilh%", \Doctrine\DBAL\Types\Type::getType(\Doctrine\DBAL\Types\Type::STRING)->getBindingType()); - $managers = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyPerson')->findAll(); - $this->assertEquals(1, count($managers)); - $this->assertEquals("Guilherme", $managers[0]->getName()); + $persons = $this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyPerson')->findAll(); + $this->assertEquals(1, count($persons)); + $this->assertEquals("Guilherme", $persons[0]->getName()); } - private function loadCompanyFixtureData() + private function loadCompanyJoinedSubclassFixtureData() { $manager = new CompanyManager; $manager->setName('Roman'); @@ -570,6 +573,52 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->flush(); $this->_em->clear(); } + + public function testSingleTableInheritance_FilterOnlyOnRootTableWhenFetchingSubEntity() + { + $this->loadCompanySingleTableInheritanceFixtureData(); + $this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexUltraContract')->findAll())); + + // Enable the filter + $conf = $this->_em->getConfiguration(); + $conf->addFilter("completed_contract", "\Doctrine\Tests\ORM\Functional\CompletedContractFilter"); + $this->_em->getFilters() + ->enable("completed_contract"); + + $this->assertEquals(1, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexUltraContract')->findAll())); + } + + public function testSingleTableInheritance_FilterOnlyOnRootTableWhenFetchingRootEntity() + { + $this->loadCompanySingleTableInheritanceFixtureData(); + $this->assertEquals(4, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexContract')->findAll())); + + // Enable the filter + $conf = $this->_em->getConfiguration(); + $conf->addFilter("completed_contract", "\Doctrine\Tests\ORM\Functional\CompletedContractFilter"); + $this->_em->getFilters() + ->enable("completed_contract"); + + $this->assertEquals(2, count($this->_em->getRepository('Doctrine\Tests\Models\Company\CompanyFlexContract')->findAll())); + } + + private function loadCompanySingleTableInheritanceFixtureData() + { + $contract1 = new CompanyFlexUltraContract; + $contract2 = new CompanyFlexUltraContract; + $contract2->markCompleted(); + + $contract3 = new CompanyFlexContract; + $contract4 = new CompanyFlexContract; + $contract4->markCompleted(); + + $this->_em->persist($contract1); + $this->_em->persist($contract2); + $this->_em->persist($contract3); + $this->_em->persist($contract4); + $this->_em->flush(); + $this->_em->clear(); + } } class MySoftDeleteFilter extends SQLFilter @@ -642,3 +691,15 @@ class CompanyPersonNameFilter extends SQLFilter return $targetTableAlias.'.name LIKE ' . $this->getParameter('name'); } } + +class CompletedContractFilter extends SQLFilter +{ + public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias, $targetTable = '') + { + if ($targetEntity->name != "Doctrine\Tests\Models\Company\CompanyContract") { + return ""; + } + + return $targetTableAlias.'.completed = 1'; + } +}