View source
<?php
namespace Doctrine\Common\Collections\Expr;
class ClosureExpressionVisitor extends ExpressionVisitor {
public static function getObjectFieldValue($object, $field) {
if (is_array($object)) {
return $object[$field];
}
$accessors = array(
'get',
'is',
);
foreach ($accessors as $accessor) {
$accessor .= $field;
if (!method_exists($object, $accessor)) {
continue;
}
return $object
->{$accessor}();
}
$accessor = $accessors[0] . $field;
if (method_exists($object, '__call')) {
return $object
->{$accessor}();
}
if ($object instanceof \ArrayAccess) {
return $object[$field];
}
return $object->{$field};
}
public static function sortByField($name, $orientation = 1, \Closure $next = null) {
if (!$next) {
$next = function () {
return 0;
};
}
return function ($a, $b) use ($name, $next, $orientation) {
$aValue = ClosureExpressionVisitor::getObjectFieldValue($a, $name);
$bValue = ClosureExpressionVisitor::getObjectFieldValue($b, $name);
if ($aValue === $bValue) {
return $next($a, $b);
}
return ($aValue > $bValue ? 1 : -1) * $orientation;
};
}
public function walkComparison(Comparison $comparison) {
$field = $comparison
->getField();
$value = $comparison
->getValue()
->getValue();
switch ($comparison
->getOperator()) {
case Comparison::EQ:
return function ($object) use ($field, $value) {
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) === $value;
};
case Comparison::NEQ:
return function ($object) use ($field, $value) {
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) !== $value;
};
case Comparison::LT:
return function ($object) use ($field, $value) {
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) < $value;
};
case Comparison::LTE:
return function ($object) use ($field, $value) {
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) <= $value;
};
case Comparison::GT:
return function ($object) use ($field, $value) {
return ClosureExpressionVisitor::getObjectFieldValue($object, $field) > $value;
};
case Comparison::GTE:
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::NIN:
return function ($object) use ($field, $value) {
return !in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value);
};
case Comparison::CONTAINS:
return function ($object) use ($field, $value) {
return false !== strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value);
};
default:
throw new \RuntimeException("Unknown comparison operator: " . $comparison
->getOperator());
}
}
public function walkValue(Value $value) {
return $value
->getValue();
}
public function walkCompositeExpression(CompositeExpression $expr) {
$expressionList = array();
foreach ($expr
->getExpressionList() as $child) {
$expressionList[] = $this
->dispatch($child);
}
switch ($expr
->getType()) {
case CompositeExpression::TYPE_AND:
return $this
->andExpressions($expressionList);
case CompositeExpression::TYPE_OR:
return $this
->orExpressions($expressionList);
default:
throw new \RuntimeException("Unknown composite " . $expr
->getType());
}
}
private function andExpressions($expressions) {
return function ($object) use ($expressions) {
foreach ($expressions as $expression) {
if (!$expression($object)) {
return false;
}
}
return true;
};
}
private function orExpressions($expressions) {
return function ($object) use ($expressions) {
foreach ($expressions as $expression) {
if ($expression($object)) {
return true;
}
}
return false;
};
}
}