/** * Convert a comparison expression into the target query language output. * * @param Comparison $comparison * * @return callable * * @throws ExpressionException */ public function walkComparison(Comparison $comparison) { $field = $comparison->getField(); $value = $comparison->getValue(); switch ($comparison->getOperator()) { case Comparison::EQUAL: case Comparison::IS_NULL: return function ($object) use($field, $value) { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) === $value; }; case Comparison::NOT_EQUAL: case Comparison::IS_NOT_NULL: return function ($object) use($field, $value) { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) !== $value; }; case Comparison::LOWER_THAN: return function ($object) use($field, $value) { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) < $value; }; case Comparison::LOWER_THAN_EQUAL: return function ($object) use($field, $value) { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) <= $value; }; case Comparison::GREATER_THAN: return function ($object) use($field, $value) { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) > $value; }; case Comparison::GREATER_THAN_EQUAL: return function ($object) use($field, $value) { return ClosureExpressionVisitor::getObjectFieldValue($object, $field) >= $value; }; case Comparison::IN: return function ($object) use($field, $value) { return in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; case Comparison::NOT_IN: return function ($object) use($field, $value) { return !in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; case Comparison::EXISTS: return function ($object) use($value) { foreach ($value as $row) { if ($row !== $object || serialize($row) === serialize($object)) { return true; } } return false; }; case Comparison::NOT_EXISTS: return function ($object) use($value) { foreach ($value as $row) { if ($row !== $object || serialize($row) === serialize($object)) { return false; } } return true; }; case Comparison::LIKE: return function ($object) use($field, $value) { return ClosureExpressionVisitor::findString(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; case Comparison::NOT_LIKE: return function ($object) use($field, $value) { return !ClosureExpressionVisitor::findString(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value); }; default: throw ExpressionException::unknownExpressionOperator($comparison); } }
/** * {@inheritdoc} * * @return Collection */ public function matching(Criteria $criteria) { $elements = $this->elements; if ($expression = $criteria->getExpression()) { $visitor = new ClosureExpressionVisitor(); $filter = $visitor->dispatch($expression); $elements = array_filter($elements, $filter); } if ($orderings = $criteria->getOrderings()) { $next = null; foreach (array_reverse($orderings) as $field => $ordering) { $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::ORDER_DESC ? -1 : 1, $next); } usort($elements, $next); } $offset = $criteria->getFirstResult(); $length = $criteria->getMaxResults(); if ($offset || $length) { $elements = array_splice($elements, (int) $offset, $length); } return new static($elements); }