예제 #1
0
 /**
  * Parses `CriteriaExpression` to a set of expressions.
  *
  * @param QueryBuilder       $queryBuilder Query builder to be configured.
  * @param CriteriaExpression $criteria     Criteria to be parsed.
  *
  * @return CompositeExpression
  */
 private function parseCriteria(QueryBuilder $queryBuilder, CriteriaExpression $criteria)
 {
     $expressions = [];
     foreach ($criteria->getCriteria() as $criterium) {
         if ($criterium instanceof CriteriaExpression) {
             $expressions[] = $this->parseCriteria($queryBuilder, $criterium);
             continue;
         }
         $expressions[] = $this->createExpression($queryBuilder, $criterium);
     }
     // now join all the expressions by the predefined logic
     $logic = $criteria->getLogic() === Knit::LOGIC_OR ? 'orX' : 'andX';
     return call_user_func_array([$queryBuilder->expr(), $logic], $expressions);
 }
예제 #2
0
 /**
  * Checks if the given object matches the given criteria.
  *
  * @param array              $object   Object to check.
  * @param CriteriaExpression $criteria Criteria expression to check against. Optional.
  *
  * @return bool
  */
 public function matches(array $object, CriteriaExpression $criteria = null)
 {
     if (!$criteria || count($criteria->getCriteria()) === 0) {
         return true;
     }
     $matches = [];
     foreach ($criteria->getCriteria() as $criterium) {
         if ($criterium instanceof CriteriaExpression) {
             $matches[] = $this->matches($object, $criterium);
             continue;
         }
         $matches[] = $this->matchesProperty($object, $criterium);
     }
     // map bool's to ints so they can be summed
     $matches = array_map('intval', $matches);
     $sum = array_sum($matches);
     return $criteria->getLogic() === Knit::LOGIC_AND ? $sum === count($matches) : $sum > 0;
     // at least 1 must match for OR
 }
예제 #3
0
 /**
  * Does the actual work of parsing criteria.
  *
  * @param CriteriaExpression $criteria     Knit's criteria expression to be parsed.
  * @param boolean            $asCollection [optional] Should this criteria be parsed as a collection?
  *                                          Required for OR logic. For internal use. Default: `false`.
  *
  * @return array
  */
 private function parseCriteria(CriteriaExpression $criteria, $asCollection = false)
 {
     $result = [];
     foreach ($criteria->getCriteria() as $criterium) {
         if ($criterium instanceof CriteriaExpression) {
             $logic = $criterium->getLogic() === Knit::LOGIC_OR ? '$or' : '$and';
             $parsedCriterium = $this->parseCriteria($criterium, true);
             // if parent is OR then add this as a collection
             if ($criteria->getLogic() === Knit::LOGIC_OR) {
                 $result[][$logic] = $parsedCriterium;
             } else {
                 $result[$logic] = $parsedCriterium;
             }
             continue;
         }
         $result = $this->parseCriterium($criterium, $result, $asCollection);
     }
     return $result;
 }
예제 #4
0
 /**
  * Tests generating the criteria object.
  *
  * @param array $criteria Criteria array.
  * @param array $expected Expected result.
  *
  * @dataProvider provideCriteria
  */
 public function testCriteria(array $criteria, array $expected)
 {
     $expression = new CriteriaExpression($criteria);
     $validator = function (CriteriaExpression $expression, $expected, $validator) {
         $this->assertEquals($expected['logic'], $expression->getLogic());
         $criteria = $expression->getCriteria();
         foreach ($criteria as $i => $criterium) {
             $expectedItem = $expected['properties'][$i];
             if ($expectedItem[0] === 'criteria') {
                 $validator($criterium, $expectedItem[1], $validator);
             } elseif ($expectedItem[0] === 'property') {
                 $this->assertInstanceOf(PropertyValue::class, $criterium);
                 $this->assertEquals($expectedItem[1], $criterium->getProperty());
                 $this->assertEquals($expectedItem[2], $criterium->getOperator());
                 $this->assertEquals($expectedItem[3], $criterium->getValue());
             }
         }
     };
     $validator($expression, $expected, $validator);
 }