diff --git a/src/Filter/Filter.php b/src/Filter/Filter.php index c04ee347d..c9a10fd9b 100644 --- a/src/Filter/Filter.php +++ b/src/Filter/Filter.php @@ -13,6 +13,7 @@ namespace Sonata\DoctrineORMAdminBundle\Filter; +use Doctrine\ORM\Query\Expr\Orx; use Sonata\AdminBundle\Datagrid\ProxyQueryInterface as BaseProxyQueryInterface; use Sonata\AdminBundle\Filter\Filter as BaseFilter; use Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQueryInterface; @@ -94,48 +95,30 @@ protected function applyWhere(BaseProxyQueryInterface $query, $parameter) } $qb = $query->getQueryBuilder(); + $cond = $this->getRootFilterCondition($query); + + if (null !== $cond) { + // Use for search purposes. + if (self::CONDITION_OR === $this->getCondition() || 'SEARCH_LEAD'/*self::CONDITION_SEARCH_LEAD*/ === $this->getCondition()) { + $subCond = $qb->expr()->orX($parameter); + } else { + $subCond = $qb->expr()->andX($parameter); + } - if (self::CONDITION_OR === $this->getCondition()) { - $subCond = $qb->expr()->orX($parameter); + $cond->add($subCond); } else { - $subCond = $qb->expr()->andX($parameter); + // Use for filtering purposes. + if (self::CONDITION_OR === $this->getCondition()) { + $qb->orWhere($parameter); + } else { + $qb->andWhere($parameter); + } } - $cond = $this->getFilterCondition($query); - $cond->add($subCond); - // filter is active since it's added to the queryBuilder $this->active = true; } - private function getFilterCondition(BaseProxyQueryInterface $query): Orx - { - $qb = $query->getQueryBuilder(); - $where = $qb->getDQLPart('where'); - - foreach ($where->getParts() as $part) { - if (!$part instanceof Orx) { - continue; - } - - $conditionParts = $part->getParts(); - - if (isset($conditionParts[0]) && is_string($conditionParts[0]) && - 0 === strpos($conditionParts[0], ':sonata_admin_datagrid_filter_query_marker') - ) { - return $part; - } - } - - // NEXT_MAJOR: remove the following `return` statement and uncomment the `\InvalidArgumentException` exception. - return $qb->expr()->orX(); - -// throw new \InvalidArgumentException( -// 'Query must define the "sonata_admin_datagrid_filter_query_marker"' -// .' marker in order to be used as part of the filter based search.' -// ); - } - /** * @param mixed $parameter */ @@ -171,4 +154,42 @@ protected function getNewParameterName(BaseProxyQueryInterface $query) // by underscores. return str_replace('.', '_', $this->getName()).'_'.$query->getUniqueParameterId(); } + + /** + * Returns the reference to the `Orx` expression used for search purposes inside + * the root `Andx` expression. If it doesn't exist and the filter condition equals + * "SEARCH_LEAD", it creates the mentioned expressions. Otherwise, it returns null. + */ + private function getRootFilterCondition(BaseProxyQueryInterface $query): ?Orx + { + $qb = $query->getQueryBuilder(); + $where = $qb->getDQLPart('where'); + + if ($where) { + foreach ($where->getParts() as $part) { + if (!$part instanceof Orx) { + continue; + } + + $conditionParts = $part->getParts(); + + if (isset($conditionParts[0]) && \is_string($conditionParts[0]) && + 0 === strpos($conditionParts[0], ':sonata_admin_datagrid_filter_query_marker') + ) { + return $part; + } + } + } + + if ('SEARCH_LEAD'/*self::CONDITION_SEARCH_LEAD*/ === $this->getCondition()) { + $cond = $qb->expr()->orX(); + $cond->add($qb->expr()->isNull(':sonata_admin_datagrid_filter_query_marker')); + $qb->setParameter('sonata_admin_datagrid_filter_query_marker', 'sonata_admin.datagrid.filter_query.marker'); + $qb->andWhere($cond); + + return $cond; + } + + return null; + } }