-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Made
ObjectCollection::matching()
criteria expressions to behave mo…
…re like in Twig
- Loading branch information
Showing
3 changed files
with
196 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
<?php | ||
/** | ||
* @package Grav\Framework\Object | ||
* | ||
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. | ||
* @license MIT License; see LICENSE file for details. | ||
*/ | ||
|
||
namespace Grav\Framework\Object\Collection; | ||
|
||
use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor; | ||
use Doctrine\Common\Collections\Expr\Comparison; | ||
|
||
class ObjectExpressionVisitor extends ClosureExpressionVisitor | ||
{ | ||
/** | ||
* Accesses the field of a given object. | ||
* | ||
* @param object $object | ||
* @param string $field | ||
* | ||
* @return mixed | ||
*/ | ||
public static function getObjectFieldValue($object, $field) | ||
{ | ||
if (isset($object[$field])) { | ||
return $object[$field]; | ||
} | ||
|
||
$accessors = array('', 'get', 'is'); | ||
|
||
foreach ($accessors as $accessor) { | ||
$accessor .= $field; | ||
|
||
if (!method_exists($object, $accessor)) { | ||
continue; | ||
} | ||
|
||
return $object->{$accessor}(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/** | ||
* Helper for sorting arrays of objects based on multiple fields + orientations. | ||
* | ||
* @param string $name | ||
* @param int $orientation | ||
* @param \Closure $next | ||
* | ||
* @return \Closure | ||
*/ | ||
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 = static::getObjectFieldValue($a, $name); | ||
$bValue = static::getObjectFieldValue($b, $name); | ||
|
||
if ($aValue === $bValue) { | ||
return $next($a, $b); | ||
} | ||
|
||
return (($aValue > $bValue) ? 1 : -1) * $orientation; | ||
}; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function walkComparison(Comparison $comparison) | ||
{ | ||
$field = $comparison->getField(); | ||
$value = $comparison->getValue()->getValue(); // shortcut for walkValue() | ||
|
||
switch ($comparison->getOperator()) { | ||
case Comparison::EQ: | ||
return function ($object) use ($field, $value) { | ||
return static::getObjectFieldValue($object, $field) === $value; | ||
}; | ||
|
||
case Comparison::NEQ: | ||
return function ($object) use ($field, $value) { | ||
return static::getObjectFieldValue($object, $field) !== $value; | ||
}; | ||
|
||
case Comparison::LT: | ||
return function ($object) use ($field, $value) { | ||
return static::getObjectFieldValue($object, $field) < $value; | ||
}; | ||
|
||
case Comparison::LTE: | ||
return function ($object) use ($field, $value) { | ||
return static::getObjectFieldValue($object, $field) <= $value; | ||
}; | ||
|
||
case Comparison::GT: | ||
return function ($object) use ($field, $value) { | ||
return static::getObjectFieldValue($object, $field) > $value; | ||
}; | ||
|
||
case Comparison::GTE: | ||
return function ($object) use ($field, $value) { | ||
return static::getObjectFieldValue($object, $field) >= $value; | ||
}; | ||
|
||
case Comparison::IN: | ||
return function ($object) use ($field, $value) { | ||
return \in_array(static::getObjectFieldValue($object, $field), $value, true); | ||
}; | ||
|
||
case Comparison::NIN: | ||
return function ($object) use ($field, $value) { | ||
return !\in_array(static::getObjectFieldValue($object, $field), $value, true); | ||
}; | ||
|
||
case Comparison::CONTAINS: | ||
return function ($object) use ($field, $value) { | ||
return false !== strpos(static::getObjectFieldValue($object, $field), $value); | ||
}; | ||
|
||
case Comparison::MEMBER_OF: | ||
return function ($object) use ($field, $value) { | ||
$fieldValues = static::getObjectFieldValue($object, $field); | ||
if (!is_array($fieldValues)) { | ||
$fieldValues = iterator_to_array($fieldValues); | ||
} | ||
return \in_array($value, $fieldValues, true); | ||
}; | ||
|
||
case Comparison::STARTS_WITH: | ||
return function ($object) use ($field, $value) { | ||
return 0 === strpos(static::getObjectFieldValue($object, $field), $value); | ||
}; | ||
|
||
case Comparison::ENDS_WITH: | ||
return function ($object) use ($field, $value) { | ||
return $value === substr(static::getObjectFieldValue($object, $field), -strlen($value)); | ||
}; | ||
|
||
|
||
default: | ||
throw new \RuntimeException("Unknown comparison operator: " . $comparison->getOperator()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters