maj+ header
This commit is contained in:
@@ -32,11 +32,6 @@ trait ObjectCollectionTrait
|
||||
$list[$key] = is_object($value) ? clone $value : $value;
|
||||
}
|
||||
|
||||
// TODO: remove when PHP 5.6 is minimum (with doctrine/collections v1.4).
|
||||
if (!method_exists($this, 'createFrom')) {
|
||||
return new static($list);
|
||||
}
|
||||
|
||||
return $this->createFrom($list);
|
||||
}
|
||||
|
||||
@@ -170,12 +165,7 @@ trait ObjectCollectionTrait
|
||||
{
|
||||
$collections = [];
|
||||
foreach ($this->group($property) as $id => $elements) {
|
||||
// TODO: remove when PHP 5.6 is minimum (with doctrine/collections v1.4).
|
||||
if (!method_exists($this, 'createFrom')) {
|
||||
$collection = new static($elements);
|
||||
} else {
|
||||
$collection = $this->createFrom($elements);
|
||||
}
|
||||
$collection = $this->createFrom($elements);
|
||||
|
||||
$collections[$id] = $collection;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Grav\Framework\Object\Base;
|
||||
*/
|
||||
trait ObjectTrait
|
||||
{
|
||||
static protected $prefix;
|
||||
/** @var string */
|
||||
static protected $type;
|
||||
|
||||
/**
|
||||
@@ -23,18 +23,28 @@ trait ObjectTrait
|
||||
*/
|
||||
private $_key;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTypePrefix()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
*/
|
||||
public function getType($prefix = true)
|
||||
{
|
||||
$type = $prefix ? $this->getTypePrefix() : '';
|
||||
|
||||
if (static::$type) {
|
||||
return ($prefix ? static::$prefix : '') . static::$type;
|
||||
return $type . static::$type;
|
||||
}
|
||||
|
||||
$class = get_class($this);
|
||||
return ($prefix ? static::$prefix : '') . strtolower(substr($class, strrpos($class, '\\') + 1));
|
||||
return $type . strtolower(substr($class, strrpos($class, '\\') + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +118,7 @@ trait ObjectTrait
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize($this->jsonSerialize());
|
||||
return serialize($this->doSerialize());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,6 +134,14 @@ trait ObjectTrait
|
||||
$this->doUnserialize($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function doSerialize()
|
||||
{
|
||||
return $this->jsonSerialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $serialized
|
||||
*/
|
||||
@@ -159,10 +177,13 @@ trait ObjectTrait
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return $this
|
||||
*/
|
||||
protected function setKey($key)
|
||||
{
|
||||
$this->_key = (string) $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract protected function doHasProperty($property);
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
<?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)
|
||||
{
|
||||
$op = $value = null;
|
||||
|
||||
$pos = strpos($field, '(');
|
||||
if (false !== $pos) {
|
||||
list ($op, $field) = explode('(', $field, 2);
|
||||
$field = rtrim($field, ')');
|
||||
}
|
||||
|
||||
if (isset($object[$field])) {
|
||||
$value = $object[$field];
|
||||
} else {
|
||||
$accessors = array('', 'get', 'is');
|
||||
|
||||
foreach ($accessors as $accessor) {
|
||||
$accessor .= $field;
|
||||
|
||||
if (!method_exists($object, $accessor)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $object->{$accessor}();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($op) {
|
||||
$function = 'filter' . ucfirst(strtolower($op));
|
||||
if (method_exists(static::class, $function)) {
|
||||
$value = static::$function($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function filterLower($str)
|
||||
{
|
||||
return mb_strtolower($str);
|
||||
}
|
||||
|
||||
public static function filterUpper($str)
|
||||
{
|
||||
return mb_strtoupper($str);
|
||||
}
|
||||
|
||||
public static function filterLength($str)
|
||||
{
|
||||
return mb_strlen($str);
|
||||
}
|
||||
|
||||
public static function filterLtrim($str)
|
||||
{
|
||||
return ltrim($str);
|
||||
}
|
||||
|
||||
public static function filterRtrim($str)
|
||||
{
|
||||
return rtrim($str);
|
||||
}
|
||||
|
||||
public static function filterTrim($str)
|
||||
{
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,13 +8,14 @@
|
||||
|
||||
namespace Grav\Framework\Object\Interfaces;
|
||||
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Grav\Framework\Collection\CollectionInterface;
|
||||
|
||||
/**
|
||||
* ObjectCollection Interface
|
||||
* @package Grav\Framework\Collection
|
||||
*/
|
||||
interface ObjectCollectionInterface extends CollectionInterface, ObjectInterface
|
||||
interface ObjectCollectionInterface extends CollectionInterface, Selectable, ObjectInterface
|
||||
{
|
||||
/**
|
||||
* Create a copy from this collection by cloning all objects in the collection.
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Grav\Framework\Collection\ArrayCollection;
|
||||
use Grav\Framework\Object\Access\NestedPropertyCollectionTrait;
|
||||
use Grav\Framework\Object\Base\ObjectCollectionTrait;
|
||||
use Grav\Framework\Object\Collection\ObjectExpressionVisitor;
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
use Grav\Framework\Object\Interfaces\ObjectCollectionInterface;
|
||||
|
||||
@@ -36,6 +38,39 @@ class ObjectCollection extends ArrayCollection implements ObjectCollectionInterf
|
||||
$this->setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function matching(Criteria $criteria)
|
||||
{
|
||||
$expr = $criteria->getWhereExpression();
|
||||
$filtered = $this->getElements();
|
||||
|
||||
if ($expr) {
|
||||
$visitor = new ObjectExpressionVisitor();
|
||||
$filter = $visitor->dispatch($expr);
|
||||
$filtered = array_filter($filtered, $filter);
|
||||
}
|
||||
|
||||
if ($orderings = $criteria->getOrderings()) {
|
||||
$next = null;
|
||||
foreach (array_reverse($orderings) as $field => $ordering) {
|
||||
$next = ObjectExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $next);
|
||||
}
|
||||
|
||||
uasort($filtered, $next);
|
||||
}
|
||||
|
||||
$offset = $criteria->getFirstResult();
|
||||
$length = $criteria->getMaxResults();
|
||||
|
||||
if ($offset || $length) {
|
||||
$filtered = array_slice($filtered, (int)$offset, $length);
|
||||
}
|
||||
|
||||
return $this->createFrom($filtered);
|
||||
}
|
||||
|
||||
protected function getElements()
|
||||
{
|
||||
return $this->toArray();
|
||||
|
||||
@@ -95,10 +95,10 @@ trait ObjectPropertyTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @param bool $doCreate Set true to create variable.
|
||||
* @return mixed Property value.
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @param callable|bool $doCreate Set true to create variable.
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
protected function &doGetProperty($property, $default = null, $doCreate = false)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user