/** * Recursive iterates through filters and builds an expression to be applied to the given data source * * @param array $filters * @param GroupingOrmFilterDatasourceAdapter $ds */ protected function buildRestrictions(array &$filters, GroupingOrmFilterDatasourceAdapter $ds) { $operatorStack = [FilterUtility::CONDITION_AND]; foreach ($filters as $item) { if (is_string($item)) { array_push($operatorStack, $item); } elseif (!isset($item['filter'])) { $ds->beginRestrictionGroup(array_pop($operatorStack)); $this->buildRestrictions($item, $ds); $ds->endRestrictionGroup(); } else { $operator = array_pop($operatorStack); /** @var FilterInterface $filter */ $filter = $this->getFilterObject($item['filter'], $item['column']); $form = $filter->getForm(); if (!$form->isSubmitted()) { $form->submit($item['filterData']); } if ($form->isValid()) { $ds->beginRestrictionGroup($operator); $filter->apply($ds, $form->getData()); $ds->endRestrictionGroup(); } } } }
/** * @expectedException LogicException * @expectedExceptionMessage Computed conditions cannot be mixed with uncomputed. */ public function testComputedWithUnComputedRestrictionsTogetherShouldReturnExceptionWhenRestrictionsAreMixed() { $qb = new QueryBuilder($this->getTestEntityManager()); $qb->select(['u.status, COUNT(u.id)'])->from('Oro\\Bundle\\QueryDesignerBundle\\Tests\\Unit\\Fixtures\\Models\\CMS\\CmsUser', 'u')->groupBy('u.status'); $ds = new GroupingOrmFilterDatasourceAdapter($qb); $ds->addRestriction($qb->expr()->eq('u.id', '1'), FilterUtility::CONDITION_AND); $ds->addRestriction($qb->expr()->eq('COUNT(u.id)', '2'), FilterUtility::CONDITION_AND, true); $ds->addRestriction($qb->expr()->eq('COUNT(u.id)', '3'), FilterUtility::CONDITION_OR); $ds->applyRestrictions(); $this->assertEquals('SELECT u.status, COUNT(u.id) FROM Oro\\Bundle\\QueryDesignerBundle\\Tests\\Unit\\Fixtures\\Models\\CMS\\CmsUser u ' . 'WHERE u.id = 1 AND u.id = 2 ' . 'GROUP BY u.status ' . 'HAVING COUNT(u.id) = 3 OR COUNT(u.id) = 4', $qb->getDQL()); }
public function testComplexExpr() { $qb = new QueryBuilder($this->getTestEntityManager()); $qb->select(['u.id'])->from('Oro\\Bundle\\QueryDesignerBundle\\Tests\\Unit\\Fixtures\\Models\\CMS\\CmsUser', 'u')->where('u.id = 0'); $ds = new GroupingOrmFilterDatasourceAdapter($qb); // src: (1 AND ((2 AND (3 OR 4)) OR (5) OR (6 AND 7)) AND 8) // dest: (1 AND ((2 AND (3 OR 4)) OR 5 OR (6 AND 7)) AND 8) $ds->addRestriction($qb->expr()->eq('u.name', '1'), FilterUtility::CONDITION_AND); $ds->beginRestrictionGroup(FilterUtility::CONDITION_AND); $ds->beginRestrictionGroup(FilterUtility::CONDITION_AND); $ds->addRestriction($qb->expr()->eq('u.name', '2'), FilterUtility::CONDITION_AND); $ds->beginRestrictionGroup(FilterUtility::CONDITION_AND); $ds->addRestriction($qb->expr()->eq('u.name', '3'), FilterUtility::CONDITION_AND); $ds->addRestriction($qb->expr()->eq('u.name', '4'), FilterUtility::CONDITION_OR); $ds->endRestrictionGroup(); $ds->endRestrictionGroup(); $ds->beginRestrictionGroup(FilterUtility::CONDITION_OR); $ds->addRestriction($qb->expr()->eq('u.name', '5'), FilterUtility::CONDITION_AND); $ds->endRestrictionGroup(); $ds->beginRestrictionGroup(FilterUtility::CONDITION_OR); $ds->addRestriction($qb->expr()->eq('u.name', '6'), FilterUtility::CONDITION_AND); $ds->addRestriction($qb->expr()->eq('u.name', '7'), FilterUtility::CONDITION_AND); $ds->endRestrictionGroup(); $ds->endRestrictionGroup(); $ds->addRestriction($qb->expr()->eq('u.name', '8'), FilterUtility::CONDITION_AND); $ds->applyRestrictions(); $this->assertEquals('SELECT u.id FROM Oro\\Bundle\\QueryDesignerBundle\\Tests\\Unit\\Fixtures\\Models\\CMS\\CmsUser u ' . 'WHERE u.id = 0 AND ' . '(u.name = 1 AND ' . '((u.name = 2 AND (u.name = 3 OR u.name = 4)) OR u.name = 5 OR (u.name = 6 AND u.name = 7)) AND ' . 'u.name = 8)', $qb->getDQL()); }