Skip to content

Commit

Permalink
Use a DQL marker in order to have a reference to the corresponding `O…
Browse files Browse the repository at this point in the history
…rx` expression
  • Loading branch information
phansys committed Mar 20, 2021
1 parent 59988a2 commit 38fbdcc
Showing 1 changed file with 55 additions and 34 deletions.
89 changes: 55 additions & 34 deletions src/Filter/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
}
}

0 comments on commit 38fbdcc

Please sign in to comment.