mirror of
https://github.com/getgrav/grav.git
synced 2025-02-20 19:56:53 +01:00
Major update on Object classes (backwards incompatible)
This commit is contained in:
parent
62389975a2
commit
23592b8a76
64
system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php
Normal file
64
system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Access;
|
||||
|
||||
/**
|
||||
* ArrayAccess Object Trait
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
trait ArrayAccessTrait
|
||||
{
|
||||
/**
|
||||
* Whether or not an offset exists.
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->hasProperty($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->getProperty($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->setProperty($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets an offset.
|
||||
*
|
||||
* @param mixed $offset The offset to unset.
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->unsetProperty($offset);
|
||||
}
|
||||
|
||||
abstract public function hasProperty($property);
|
||||
abstract public function getProperty($property, $default = null);
|
||||
abstract public function setProperty($property, $value);
|
||||
abstract public function unsetProperty($property);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Access;
|
||||
|
||||
/**
|
||||
* Nested ArrayAccess Object Trait
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
trait NestedArrayAccessTrait
|
||||
{
|
||||
/**
|
||||
* Whether or not an offset exists.
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->hasNestedProperty($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->getNestedProperty($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->setNestedProperty($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets an offset.
|
||||
*
|
||||
* @param mixed $offset The offset to unset.
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->unsetNestedProperty($offset);
|
||||
}
|
||||
|
||||
abstract public function hasNestedProperty($property, $separator = null);
|
||||
abstract public function getNestedProperty($property, $default = null, $separator = null);
|
||||
abstract public function setNestedProperty($property, $value, $separator = null);
|
||||
abstract public function unsetNestedProperty($property, $separator = null);
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Access;
|
||||
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
|
||||
/**
|
||||
* Nested Properties Collection Trait
|
||||
* @package Grav\Framework\Object\Properties
|
||||
*/
|
||||
trait NestedPropertyCollectionTrait
|
||||
{
|
||||
/**
|
||||
* @param string $property Object property to be matched.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return array Key/Value pairs of the properties.
|
||||
*/
|
||||
public function hasNestedProperty($property, $separator = null)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
/** @var NestedObjectInterface $element */
|
||||
foreach ($this->getIterator() as $id => $element) {
|
||||
$list[$id] = $element->hasNestedProperty($property, $separator);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if not set.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return array Key/Value pairs of the properties.
|
||||
*/
|
||||
public function getNestedProperty($property, $default = null, $separator = null)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
/** @var NestedObjectInterface $element */
|
||||
foreach ($this->getIterator() as $id => $element) {
|
||||
$list[$id] = $element->getNestedProperty($property, $default, $separator);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function setNestedProperty($property, $value, $separator = null)
|
||||
{
|
||||
/** @var NestedObjectInterface $element */
|
||||
foreach ($this->getIterator() as $element) {
|
||||
$element->setNestedProperty($property, $value, $separator);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function unsetNestedProperty($property, $separator = null)
|
||||
{
|
||||
/** @var NestedObjectInterface $element */
|
||||
foreach ($this->getIterator() as $element) {
|
||||
$element->unsetNestedProperty($property, $separator);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $default Default value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function defNestedProperty($property, $default, $separator = null)
|
||||
{
|
||||
/** @var NestedObjectInterface $element */
|
||||
foreach ($this->getIterator() as $element) {
|
||||
$element->defNestedProperty($property, $default, $separator);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group items in the collection by a field.
|
||||
*
|
||||
* @param string $property Object property to be used to make groups.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return array
|
||||
*/
|
||||
public function group($property, $separator = null)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
/** @var NestedObjectInterface $element */
|
||||
foreach ($this->getIterator() as $element) {
|
||||
$list[(string) $element->getNestedProperty($property, null, $separator)][] = $element;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Traversable
|
||||
*/
|
||||
abstract public function getIterator();
|
||||
}
|
||||
179
system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php
Normal file
179
system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Access;
|
||||
|
||||
use Grav\Framework\Object\Interfaces\ObjectInterface;
|
||||
|
||||
/**
|
||||
* Nested Property Object Trait
|
||||
* @package Grav\Framework\Object\Traits
|
||||
*/
|
||||
trait NestedPropertyTrait
|
||||
{
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
public function hasNestedProperty($property, $separator = null)
|
||||
{
|
||||
$test = new \stdClass;
|
||||
|
||||
return $this->getNestedProperty($property, $test, $separator) !== $test;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
public function getNestedProperty($property, $default = null, $separator = null)
|
||||
{
|
||||
$path = explode($separator ?: '.', $property);
|
||||
$offset = array_shift($path);
|
||||
|
||||
if (!$this->hasProperty($offset)) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$current = $this->getProperty($offset);
|
||||
|
||||
while ($path) {
|
||||
// Get property of nested Object.
|
||||
if ($current instanceof ObjectInterface) {
|
||||
if (method_exists($current, 'getNestedProperty')) {
|
||||
return $current->getNestedProperty(implode($separator, $path), $default, $separator);
|
||||
}
|
||||
return $current->getProperty(implode($separator, $path), $default);
|
||||
}
|
||||
|
||||
$offset = array_shift($path);
|
||||
|
||||
if ((is_array($current) || is_a($current, 'ArrayAccess')) && isset($current[$offset])) {
|
||||
$current = $current[$offset];
|
||||
} elseif (is_object($current) && isset($current->{$offset})) {
|
||||
$current = $current->{$offset};
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
};
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function setNestedProperty($property, $value, $separator = null)
|
||||
{
|
||||
$path = explode($separator ?: '.', $property);
|
||||
$offset = array_shift($path);
|
||||
|
||||
if (!$path) {
|
||||
$this->setProperty($offset, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$current = &$this->doGetProperty($offset, null, true);
|
||||
|
||||
while ($path) {
|
||||
$offset = array_shift($path);
|
||||
|
||||
// Handle arrays and scalars.
|
||||
if ($current === null) {
|
||||
$current = [$offset => []];
|
||||
} elseif (is_array($current)) {
|
||||
if (!isset($current[$offset])) {
|
||||
$current[$offset] = [];
|
||||
}
|
||||
} else {
|
||||
throw new \RuntimeException('Cannot set nested property on non-array value');
|
||||
}
|
||||
|
||||
$current = &$current[$offset];
|
||||
};
|
||||
|
||||
$current = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function unsetNestedProperty($property, $separator = null)
|
||||
{
|
||||
$path = explode($separator ?: '.', $property);
|
||||
$offset = array_shift($path);
|
||||
|
||||
if (!$path) {
|
||||
$this->unsetProperty($offset);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$last = array_pop($path);
|
||||
$current = &$this->doGetProperty($offset, null, true);
|
||||
|
||||
while ($path) {
|
||||
$offset = array_shift($path);
|
||||
|
||||
// Handle arrays and scalars.
|
||||
if ($current === null) {
|
||||
return $this;
|
||||
}
|
||||
if (is_array($current)) {
|
||||
if (!isset($current[$offset])) {
|
||||
return $this;
|
||||
}
|
||||
} else {
|
||||
throw new \RuntimeException('Cannot set nested property on non-array value');
|
||||
}
|
||||
|
||||
$current = &$current[$offset];
|
||||
};
|
||||
|
||||
unset($current[$last]);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $default Default value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function defNestedProperty($property, $default, $separator = null)
|
||||
{
|
||||
if (!$this->hasNestedProperty($property, $separator)) {
|
||||
$this->setNestedProperty($property, $default, $separator);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
abstract public function hasProperty($property);
|
||||
abstract public function getProperty($property, $default = null);
|
||||
abstract public function setProperty($property, $value);
|
||||
abstract public function unsetProperty($property);
|
||||
abstract protected function &doGetProperty($property, $default = null, $doCreate = false);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Access;
|
||||
|
||||
/**
|
||||
* Overloaded Property Object Trait
|
||||
* @package Grav\Framework\Object\Access
|
||||
*/
|
||||
trait OverloadedPropertyTrait
|
||||
{
|
||||
/**
|
||||
* Checks whether or not an offset exists.
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function __isset($offset)
|
||||
{
|
||||
return $this->hasProperty($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function __get($offset)
|
||||
{
|
||||
return $this->getProperty($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*/
|
||||
public function __set($offset, $value)
|
||||
{
|
||||
$this->setProperty($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to unset the attribute
|
||||
*
|
||||
* @param mixed $offset The name value to unset
|
||||
*/
|
||||
public function __unset($offset)
|
||||
{
|
||||
$this->unsetProperty($offset);
|
||||
}
|
||||
|
||||
abstract public function hasProperty($property);
|
||||
abstract public function getProperty($property, $default = null);
|
||||
abstract public function setProperty($property, $value);
|
||||
abstract public function unsetProperty($property);
|
||||
}
|
||||
|
|
@ -8,62 +8,19 @@
|
|||
|
||||
namespace Grav\Framework\Object;
|
||||
|
||||
use Grav\Framework\Object\Access\NestedPropertyTrait;
|
||||
use Grav\Framework\Object\Access\OverloadedPropertyTrait;
|
||||
use Grav\Framework\Object\Base\ObjectTrait;
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
use Grav\Framework\Object\Property\ArrayPropertyTrait;
|
||||
use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccess;
|
||||
|
||||
/**
|
||||
* ArrayObject class.
|
||||
* Array Object class.
|
||||
*
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
class ArrayObject extends Object implements \ArrayAccess
|
||||
class ArrayObject implements NestedObjectInterface, \ArrayAccess
|
||||
{
|
||||
/**
|
||||
* Whether or not an offset exists.
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
if (strpos($offset, '.') !== false) {
|
||||
$test = new \stdClass();
|
||||
return $this->getProperty($offset, $test) !== $test;
|
||||
}
|
||||
|
||||
return $this->__isset($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->getProperty($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->setProperty($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets an offset.
|
||||
*
|
||||
* @param mixed $offset The offset to unset.
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
if (strpos($offset, '.') !== false) {
|
||||
$this->setProperty($offset, null);
|
||||
} else {
|
||||
$this->__unset($offset);
|
||||
}
|
||||
}
|
||||
use ObjectTrait, ArrayPropertyTrait, NestedPropertyTrait, OverloadedPropertyTrait, NestedArrayAccess;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
namespace Grav\Framework\Object\Base;
|
||||
|
||||
use Grav\Framework\Object\Interfaces\ObjectInterface;
|
||||
|
||||
/**
|
||||
* ObjectCollection Trait
|
||||
|
|
@ -14,7 +16,9 @@ namespace Grav\Framework\Object;
|
|||
*/
|
||||
trait ObjectCollectionTrait
|
||||
{
|
||||
use ObjectTrait;
|
||||
use ObjectTrait {
|
||||
setKey as public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy from this collection by cloning all objects in the collection.
|
||||
|
|
@ -44,12 +48,28 @@ trait ObjectCollectionTrait
|
|||
return $this->call('getKey');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be matched.
|
||||
* @return array Key/Value pairs of the properties.
|
||||
*/
|
||||
public function doHasProperty($property)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
/** @var ObjectInterface $element */
|
||||
foreach ($this->getIterator() as $id => $element) {
|
||||
$list[$id] = $element->hasProperty($property);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if not set.
|
||||
* @return array Key/Value pairs of the properties.
|
||||
*/
|
||||
public function getProperty($property, $default = null)
|
||||
public function doGetProperty($property, $default = null)
|
||||
{
|
||||
$list = [];
|
||||
|
||||
|
|
@ -66,7 +86,7 @@ trait ObjectCollectionTrait
|
|||
* @param string $value New value.
|
||||
* @return $this
|
||||
*/
|
||||
public function setProperty($property, $value)
|
||||
public function doSetProperty($property, $value)
|
||||
{
|
||||
/** @var ObjectInterface $element */
|
||||
foreach ($this->getIterator() as $element) {
|
||||
|
|
@ -78,14 +98,28 @@ trait ObjectCollectionTrait
|
|||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @return $this
|
||||
*/
|
||||
public function defProperty($property, $value)
|
||||
public function doUnsetProperty($property)
|
||||
{
|
||||
/** @var ObjectInterface $element */
|
||||
foreach ($this->getIterator() as $element) {
|
||||
$element->defProperty($property, $value);
|
||||
$element->unsetProperty($property);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $default Default value.
|
||||
* @return $this
|
||||
*/
|
||||
public function doDefProperty($property, $default)
|
||||
{
|
||||
/** @var ObjectInterface $element */
|
||||
foreach ($this->getIterator() as $element) {
|
||||
$element->defProperty($property, $default);
|
||||
}
|
||||
|
||||
return $this;
|
||||
167
system/src/Grav/Framework/Object/Base/ObjectTrait.php
Normal file
167
system/src/Grav/Framework/Object/Base/ObjectTrait.php
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Base;
|
||||
|
||||
/**
|
||||
* Object trait.
|
||||
*
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
trait ObjectTrait
|
||||
{
|
||||
static protected $prefix;
|
||||
static protected $type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $_key;
|
||||
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
*/
|
||||
public function getType($prefix = true)
|
||||
{
|
||||
if (static::$type) {
|
||||
return ($prefix ? static::$prefix : '') . static::$type;
|
||||
}
|
||||
|
||||
$class = get_class($this);
|
||||
return ($prefix ? static::$prefix : '') . strtolower(substr($class, strrpos($class, '\\') + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->_key ?: $this->getType() . '@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
public function hasProperty($property)
|
||||
{
|
||||
return $this->doHasProperty($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
public function getProperty($property, $default = null)
|
||||
{
|
||||
return $this->doGetProperty($property, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @return $this
|
||||
*/
|
||||
public function setProperty($property, $value)
|
||||
{
|
||||
$this->doSetProperty($property, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be unset.
|
||||
* @return $this
|
||||
*/
|
||||
public function unsetProperty($property)
|
||||
{
|
||||
$this->doUnsetProperty($property);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be defined.
|
||||
* @param mixed $default Default value.
|
||||
* @return $this
|
||||
*/
|
||||
public function defProperty($property, $default)
|
||||
{
|
||||
if (!$this->hasProperty($property)) {
|
||||
$this->setProperty($property, $default);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements Serializable interface.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize($this->jsonSerialize());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $serialized
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = unserialize($serialized);
|
||||
|
||||
$this->doUnserialize($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $serialized
|
||||
*/
|
||||
protected function doUnserialize(array $serialized)
|
||||
{
|
||||
$this->setKey($serialized['key']);
|
||||
$this->setElements($serialized['elements']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements JsonSerializable interface.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return ['key' => $this->getKey(), 'type' => $this->getType(), 'elements' => $this->getElements()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*/
|
||||
protected function setKey($key)
|
||||
{
|
||||
$this->_key = (string) $key;
|
||||
}
|
||||
|
||||
abstract protected function doHasProperty($property);
|
||||
abstract protected function &doGetProperty($property, $default = null, $doCreate = false);
|
||||
abstract protected function doSetProperty($property, $value);
|
||||
abstract protected function doUnsetProperty($property);
|
||||
abstract protected function getElements();
|
||||
abstract protected function setElements(array $elements);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Interfaces;
|
||||
|
||||
/**
|
||||
* Object Interface
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
interface NestedObjectInterface extends ObjectInterface
|
||||
{
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
public function hasNestedProperty($property, $separator = null);
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
public function getNestedProperty($property, $default = null, $separator = null);
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function setNestedProperty($property, $value, $separator = null);
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be defined.
|
||||
* @param string $default Default value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function defNestedProperty($property, $default, $separator = null);
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be unset.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function unsetNestedProperty($property, $separator = null);
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
namespace Grav\Framework\Object\Interfaces;
|
||||
|
||||
use Grav\Framework\Collection\CollectionInterface;
|
||||
|
||||
|
|
@ -6,13 +6,13 @@
|
|||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
namespace Grav\Framework\Object\Interfaces;
|
||||
|
||||
/**
|
||||
* Object Interface
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
interface ObjectInterface extends \JsonSerializable
|
||||
interface ObjectInterface extends \Serializable, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @param array $elements
|
||||
|
|
@ -30,9 +30,15 @@ interface ObjectInterface extends \JsonSerializable
|
|||
*/
|
||||
public function getKey();
|
||||
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
public function hasProperty($property);
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if not set.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
public function getProperty($property, $default = null);
|
||||
|
|
@ -46,8 +52,14 @@ interface ObjectInterface extends \JsonSerializable
|
|||
|
||||
/**
|
||||
* @param string $property Object property to be defined.
|
||||
* @param mixed $value Default value.
|
||||
* @param mixed $default Default value.
|
||||
* @return $this
|
||||
*/
|
||||
public function defProperty($property, $value);
|
||||
public function defProperty($property, $default);
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be unset.
|
||||
* @return $this
|
||||
*/
|
||||
public function unsetProperty($property);
|
||||
}
|
||||
26
system/src/Grav/Framework/Object/LazyObject.php
Normal file
26
system/src/Grav/Framework/Object/LazyObject.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
|
||||
use Grav\Framework\Object\Access\NestedPropertyTrait;
|
||||
use Grav\Framework\Object\Access\OverloadedPropertyTrait;
|
||||
use Grav\Framework\Object\Base\ObjectTrait;
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
use Grav\Framework\Object\Property\LazyPropertyTrait;
|
||||
use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccess;
|
||||
|
||||
/**
|
||||
* Lazy Object class.
|
||||
*
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
class LazyObject implements NestedObjectInterface, \ArrayAccess
|
||||
{
|
||||
use ObjectTrait, LazyPropertyTrait, NestedPropertyTrait, OverloadedPropertyTrait, NestedArrayAccess;
|
||||
}
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
|
||||
/**
|
||||
* Object class.
|
||||
*
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
class Object implements ObjectInterface
|
||||
{
|
||||
use ObjectTrait;
|
||||
|
||||
static protected $prefix = 'o.';
|
||||
static protected $type;
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $this->get('this.is.my.nested.variable');
|
||||
*
|
||||
* @param string $property Dot separated path to the requested value.
|
||||
* @param mixed $default Default value (or null).
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return mixed Value.
|
||||
*/
|
||||
public function getProperty($property, $default = null, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $property);
|
||||
$offset = array_shift($path);
|
||||
$current = $this->__get($offset);
|
||||
|
||||
do {
|
||||
// We are done: return current variable.
|
||||
if (empty($path)) {
|
||||
return $current;
|
||||
}
|
||||
|
||||
// Get property of nested Object.
|
||||
if ($current instanceof Object) {
|
||||
return $current->getProperty(implode($separator, $path), $default, $separator);
|
||||
}
|
||||
|
||||
$offset = array_shift($path);
|
||||
|
||||
if ((is_array($current) || is_a($current, 'ArrayAccess')) && isset($current[$offset])) {
|
||||
$current = $current[$offset];
|
||||
} elseif (is_object($current) && isset($current->{$offset})) {
|
||||
$current = $current->{$offset};
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
} while ($path);
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $data->set('this.is.my.nested.variable', $value);
|
||||
*
|
||||
* @param string $property Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function setProperty($property, $value, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $property);
|
||||
$offset = array_shift($path);
|
||||
|
||||
// Set simple variable.
|
||||
if (empty($path)) {
|
||||
$this->__set($offset, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$current = &$this->getRef($offset, true);
|
||||
|
||||
do {
|
||||
// Set property of nested Object.
|
||||
if ($current instanceof Object) {
|
||||
$current->setProperty(implode($separator, $path), $value, $separator);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$offset = array_shift($path);
|
||||
|
||||
if (is_object($current)) {
|
||||
// Handle objects.
|
||||
if (!isset($current->{$offset})) {
|
||||
$current->{$offset} = [];
|
||||
}
|
||||
$current = &$current->{$offset};
|
||||
} else {
|
||||
// Handle arrays and scalars.
|
||||
if (!is_array($current)) {
|
||||
$current = [$offset => []];
|
||||
} elseif (!isset($current[$offset])) {
|
||||
$current[$offset] = [];
|
||||
}
|
||||
$current = &$current[$offset];
|
||||
}
|
||||
} while ($path);
|
||||
|
||||
$current = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $data->defProperty('this.is.my.nested.variable', $value);
|
||||
*
|
||||
* @param string $property Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return $this
|
||||
*/
|
||||
public function defProperty($property, $value, $separator = '.')
|
||||
{
|
||||
$test = new \stdClass;
|
||||
if ($this->getProperty($property, $test, $separator) === $test) {
|
||||
$this->setProperty($property, $value, $separator);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not an offset exists with a possibility to load the field by $this->offsetLoad_{$offset}().
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function __isset($offset)
|
||||
{
|
||||
return array_key_exists($offset, $this->items) || $this->isPropertyDefined($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset with a possibility to load the field by $this->offsetLoad_{$offset}().
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function __get($offset)
|
||||
{
|
||||
return $this->getRef($offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a value to the specified offset with a possibility to check or alter the value by
|
||||
* $this->offsetPrepare_{$offset}().
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
*/
|
||||
public function __set($offset, $value)
|
||||
{
|
||||
if ($this->isPropertyDefined($offset)) {
|
||||
$methodName = "offsetPrepare_{$offset}";
|
||||
|
||||
if (method_exists($this, $methodName)) {
|
||||
$this->{$offset} = $this->{$methodName}($value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->items[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to unset the attribute
|
||||
*
|
||||
* @param mixed $offset The name value to unset
|
||||
*/
|
||||
public function __unset($offset)
|
||||
{
|
||||
if ($this->isPropertyDefined($offset)) {
|
||||
$this->{$offset} = null;
|
||||
} else {
|
||||
unset($this->items[$offset]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert object into an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function toArray()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
protected function &getRef($offset, $new = false)
|
||||
{
|
||||
if ($this->isPropertyDefined($offset)) {
|
||||
if ($this->{$offset} === null) {
|
||||
$methodName = "offsetLoad_{$offset}";
|
||||
|
||||
if (method_exists($this, $methodName)) {
|
||||
$this->{$offset} = $this->{$methodName}();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->{$offset};
|
||||
}
|
||||
|
||||
if (!isset($this->items[$offset])) {
|
||||
if (!$new) {
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
$this->items[$offset] = [];
|
||||
}
|
||||
|
||||
return $this->items[$offset];
|
||||
}
|
||||
|
||||
protected function isPropertyDefined($offset)
|
||||
{
|
||||
return array_key_exists($offset, get_object_vars($this));
|
||||
}
|
||||
}
|
||||
|
|
@ -9,16 +9,20 @@
|
|||
namespace Grav\Framework\Object;
|
||||
|
||||
use Grav\Framework\Collection\ArrayCollection;
|
||||
use Grav\Framework\Object\Access\NestedPropertyCollectionTrait;
|
||||
use Grav\Framework\Object\Base\ObjectCollectionTrait;
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
use Grav\Framework\Object\Interfaces\ObjectCollectionInterface;
|
||||
|
||||
/**
|
||||
* Object Collection
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
class ObjectCollection extends ArrayCollection implements ObjectCollectionInterface
|
||||
class ObjectCollection extends ArrayCollection implements ObjectCollectionInterface, NestedObjectInterface
|
||||
{
|
||||
use ObjectCollectionTrait;
|
||||
|
||||
static protected $prefix = 'c.';
|
||||
use ObjectCollectionTrait, NestedPropertyCollectionTrait {
|
||||
NestedPropertyCollectionTrait::group insteadof ObjectCollectionTrait;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
|
|
@ -27,23 +31,18 @@ class ObjectCollection extends ArrayCollection implements ObjectCollectionInterf
|
|||
*/
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
parent::__construct($elements);
|
||||
parent::__construct($this->setElements($elements));
|
||||
|
||||
$this->key = $key !== null ? $key : (string) $this;
|
||||
|
||||
if ($this->key === null) {
|
||||
throw new \InvalidArgumentException('Object cannot be created without assigning a key to it');
|
||||
}
|
||||
$this->setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return $this
|
||||
*/
|
||||
public function setKey($key)
|
||||
protected function getElements()
|
||||
{
|
||||
$this->key = $key;
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
return $this;
|
||||
protected function setElements(array $elements)
|
||||
{
|
||||
return $elements;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
|
||||
/**
|
||||
* Object trait.
|
||||
*
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
trait ObjectTrait
|
||||
{
|
||||
/**
|
||||
* Properties of the object.
|
||||
* @var array
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
|
||||
$this->items = $elements;
|
||||
$this->key = $key !== null ? $key : (string) $this;
|
||||
|
||||
if ($this->key === null) {
|
||||
throw new \InvalidArgumentException('Object cannot be created without assigning a key to it');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
*/
|
||||
public function getType($prefix = true)
|
||||
{
|
||||
if (static::$type) {
|
||||
return ($prefix ? static::$prefix : '') . static::$type;
|
||||
}
|
||||
|
||||
$class = get_class($this);
|
||||
return ($prefix ? static::$prefix : '') . strtolower(substr($class, strrpos($class, '\\') + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements JsonSerializable interface.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return ['key' => (string) $this, 'type' => $this->getType(), 'elements' => $this->toArray()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getKey() ?: $this->getType() . '@' . spl_object_hash($this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Property;
|
||||
|
||||
/**
|
||||
* Array Property Trait
|
||||
* @package Grav\Framework\Object\Property
|
||||
*/
|
||||
trait ArrayPropertyTrait
|
||||
{
|
||||
/**
|
||||
* Properties of the object.
|
||||
* @var array
|
||||
*/
|
||||
private $_elements;
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
$this->setElements($elements);
|
||||
$this->setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
protected function doHasProperty($property)
|
||||
{
|
||||
return array_key_exists($property, $this->_elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
protected function &doGetProperty($property, $default = null, $doCreate = false)
|
||||
{
|
||||
if (!$this->doHasProperty($property)) {
|
||||
if ($doCreate) {
|
||||
$this->_elements[$property] = null;
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_elements[$property];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
*/
|
||||
protected function doSetProperty($property, $value)
|
||||
{
|
||||
$this->_elements[$property] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be unset.
|
||||
*/
|
||||
protected function doUnsetProperty($property)
|
||||
{
|
||||
unset($this->_elements[$property]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getElements()
|
||||
{
|
||||
return $this->_elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
*/
|
||||
protected function setElements(array $elements)
|
||||
{
|
||||
$this->_elements = $elements;
|
||||
}
|
||||
|
||||
abstract protected function setKey($key);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Property;
|
||||
|
||||
/**
|
||||
* Lazy Mixed Property Trait
|
||||
* @package Grav\Framework\Object\Property
|
||||
*/
|
||||
trait LazyPropertyTrait
|
||||
{
|
||||
use ArrayPropertyTrait, ObjectPropertyTrait {
|
||||
ObjectPropertyTrait::__construct insteadof ArrayPropertyTrait;
|
||||
ArrayPropertyTrait::doHasProperty as hasArrayProperty;
|
||||
ArrayPropertyTrait::doGetProperty as getArrayProperty;
|
||||
ArrayPropertyTrait::doSetProperty as setArrayProperty;
|
||||
ArrayPropertyTrait::doUnsetProperty as unsetArrayProperty;
|
||||
ArrayPropertyTrait::getElements as getArrayElements;
|
||||
ArrayPropertyTrait::setElements insteadof ObjectPropertyTrait;
|
||||
ObjectPropertyTrait::doHasProperty as hasObjectProperty;
|
||||
ObjectPropertyTrait::doGetProperty as getObjectProperty;
|
||||
ObjectPropertyTrait::doSetProperty as setObjectProperty;
|
||||
ObjectPropertyTrait::doUnsetProperty as unsetObjectProperty;
|
||||
ObjectPropertyTrait::getElements as getObjectElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
protected function doHasProperty($property)
|
||||
{
|
||||
return $this->hasArrayProperty($property) || $this->hasObjectProperty($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
protected function &doGetProperty($property, $default = null, $doCreate = false)
|
||||
{
|
||||
if ($this->hasObjectProperty($property)) {
|
||||
return $this->getObjectProperty($property, $default, function ($default = null) use ($property) {
|
||||
return $this->getArrayProperty($property, $default);
|
||||
});
|
||||
}
|
||||
|
||||
return $this->getArrayProperty($property, $default, $doCreate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @return $this
|
||||
*/
|
||||
protected function doSetProperty($property, $value)
|
||||
{
|
||||
if ($this->hasObjectProperty($property)) {
|
||||
$this->setObjectProperty($property, $value);
|
||||
} else {
|
||||
$this->setArrayProperty($property, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be unset.
|
||||
* @return $this
|
||||
*/
|
||||
protected function doUnsetProperty($property)
|
||||
{
|
||||
$this->hasObjectProperty($property) ?
|
||||
$this->unsetObjectProperty($property) : $this->unsetArrayProperty($property);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getElements()
|
||||
{
|
||||
return $this->getObjectElements() + $this->getArrayElements();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Property;
|
||||
|
||||
/**
|
||||
* Mixed Property Trait
|
||||
* @package Grav\Framework\Object\Property
|
||||
*/
|
||||
trait MixedPropertyTrait
|
||||
{
|
||||
use ArrayPropertyTrait, ObjectPropertyTrait {
|
||||
ObjectPropertyTrait::__construct insteadof ArrayPropertyTrait;
|
||||
ArrayPropertyTrait::doHasProperty as hasArrayProperty;
|
||||
ArrayPropertyTrait::doGetProperty as getArrayProperty;
|
||||
ArrayPropertyTrait::doSetProperty as setArrayProperty;
|
||||
ArrayPropertyTrait::doUnsetProperty as unsetArrayProperty;
|
||||
ArrayPropertyTrait::getElements as getArrayElements;
|
||||
ArrayPropertyTrait::setElements as setArrayElements;
|
||||
ObjectPropertyTrait::doHasProperty as hasObjectProperty;
|
||||
ObjectPropertyTrait::doGetProperty as getObjectProperty;
|
||||
ObjectPropertyTrait::doSetProperty as setObjectProperty;
|
||||
ObjectPropertyTrait::doUnsetProperty as unsetObjectProperty;
|
||||
ObjectPropertyTrait::getElements as getObjectElements;
|
||||
ObjectPropertyTrait::setElements as setObjectElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
protected function doHasProperty($property)
|
||||
{
|
||||
return $this->hasArrayProperty($property) || $this->hasObjectProperty($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @param mixed $default Default value if property has not been set.
|
||||
* @return mixed Property value.
|
||||
*/
|
||||
protected function &doGetProperty($property, $default = null, $doCreate = false)
|
||||
{
|
||||
if ($this->hasObjectProperty($property)) {
|
||||
return $this->getObjectProperty($property);
|
||||
}
|
||||
|
||||
return $this->getArrayProperty($property, $default, $doCreate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @return $this
|
||||
*/
|
||||
protected function doSetProperty($property, $value)
|
||||
{
|
||||
$this->hasObjectProperty($property)
|
||||
? $this->setObjectProperty($property, $value) : $this->setArrayProperty($property, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be unset.
|
||||
* @return $this
|
||||
*/
|
||||
protected function doUnsetProperty($property)
|
||||
{
|
||||
$this->hasObjectProperty($property) ?
|
||||
$this->unsetObjectProperty($property) : $this->unsetArrayProperty($property);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getElements()
|
||||
{
|
||||
return $this->getObjectElements() + $this->getArrayElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
*/
|
||||
protected function setElements(array $elements)
|
||||
{
|
||||
$this->setObjectElements(array_intersect_key($elements, $this->_definedProperties));
|
||||
$this->setArrayElements(array_diff_key($elements, $this->_definedProperties));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Property;
|
||||
|
||||
/**
|
||||
* Object Property Trait
|
||||
* @package Grav\Framework\Object\Property
|
||||
*/
|
||||
trait ObjectPropertyTrait
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_definedProperties;
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
$this->initObjectProperties();
|
||||
$this->setElements($elements);
|
||||
$this->setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property name.
|
||||
* @return bool True if property has been defined (can be null).
|
||||
*/
|
||||
protected function doHasProperty($property)
|
||||
{
|
||||
return array_key_exists($property, $this->_definedProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
protected function &doGetProperty($property, $default = null, $doCreate = false)
|
||||
{
|
||||
if (!array_key_exists($property, $this->_definedProperties)) {
|
||||
throw new \InvalidArgumentException("Property '{$property}' does not exist in the object!");
|
||||
}
|
||||
|
||||
if (empty($this->_definedProperties[$property])) {
|
||||
if ($doCreate === true) {
|
||||
$this->_definedProperties[$property] = true;
|
||||
$this->{$property} = null;
|
||||
} elseif (is_callable($doCreate)) {
|
||||
$this->_definedProperties[$property] = true;
|
||||
$this->{$property} = $this->onPropertyLoad($property, $doCreate());
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->{$property};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be updated.
|
||||
* @param string $value New value.
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function doSetProperty($property, $value)
|
||||
{
|
||||
if (!array_key_exists($property, $this->_definedProperties)) {
|
||||
throw new \InvalidArgumentException("Property '{$property}' does not exist in the object!");
|
||||
}
|
||||
|
||||
$this->_definedProperties[$property] = true;
|
||||
$this->{$property} = $this->onPropertySet($property, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be unset.
|
||||
*/
|
||||
protected function doUnsetProperty($property)
|
||||
{
|
||||
if (!array_key_exists($property, $this->_definedProperties)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->_definedProperties[$property] = false;
|
||||
unset($this->{$property});
|
||||
}
|
||||
|
||||
|
||||
protected function onPropertyLoad($offset, $value)
|
||||
{
|
||||
$methodName = "offsetLoad_{$offset}";
|
||||
|
||||
if (method_exists($this, $methodName)) {
|
||||
return $this->{$methodName}($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function onPropertySet($offset, $value)
|
||||
{
|
||||
$methodName = "offsetPrepare_{$offset}";
|
||||
|
||||
if (method_exists($this, $methodName)) {
|
||||
return $this->{$methodName}($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function initObjectProperties()
|
||||
{
|
||||
$this->_definedProperties = [];
|
||||
foreach (get_object_vars($this) as $property => $value) {
|
||||
if ($property[0] !== '_') {
|
||||
$this->_definedProperties[$property] = ($value !== null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getElements()
|
||||
{
|
||||
return array_intersect_key(get_object_vars($this), array_filter($this->_definedProperties));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
*/
|
||||
protected function setElements(array $elements)
|
||||
{
|
||||
foreach ($elements as $property => $value) {
|
||||
$this->setProperty($property, $value);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function setProperty($property, $value);
|
||||
abstract protected function setKey($key);
|
||||
}
|
||||
26
system/src/Grav/Framework/Object/PropertyObject.php
Normal file
26
system/src/Grav/Framework/Object/PropertyObject.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object;
|
||||
|
||||
use Grav\Framework\Object\Access\NestedPropertyTrait;
|
||||
use Grav\Framework\Object\Access\OverloadedPropertyTrait;
|
||||
use Grav\Framework\Object\Base\ObjectTrait;
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
use Grav\Framework\Object\Property\ObjectPropertyTrait;
|
||||
use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccess;
|
||||
|
||||
/**
|
||||
* Property Object class.
|
||||
*
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
class PropertyObject implements NestedObjectInterface, \ArrayAccess
|
||||
{
|
||||
use ObjectTrait, ObjectPropertyTrait, NestedPropertyTrait, OverloadedPropertyTrait, NestedArrayAccess;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user