diff --git a/CHANGELOG.md b/CHANGELOG.md index 36f134b0c..9f5662547 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ * Made `modular` blueprint more flexible 1. [](#bugfix) * Date ordering should always be numeric [#1810](https://github.com/getgrav/grav/issues/1810) +1. [](#improved) + * Objects: Add protected function `getElement()` to get serialized value for a single property + * `ObjectPropertyTrait`: Added protected functions `isPropertyLoaded()`, `offsetLoad()`, `offsetPrepare()` and `offsetSerialize()` # v1.4.0-beta.3 ## 12/29/2017 diff --git a/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php b/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php index 6ae1400eb..400b163c8 100644 --- a/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php @@ -10,6 +10,9 @@ namespace Grav\Framework\Object\Property; /** * Array Property Trait + * + * Stores all object properties into an array. + * * @package Grav\Framework\Object\Property */ trait ArrayPropertyTrait @@ -48,7 +51,7 @@ trait ArrayPropertyTrait */ protected function &doGetProperty($property, $default = null, $doCreate = false) { - if (!$this->doHasProperty($property)) { + if (!array_key_exists($property, $this->_elements)) { if ($doCreate) { $this->_elements[$property] = null; } else { @@ -61,7 +64,7 @@ trait ArrayPropertyTrait /** * @param string $property Object property to be updated. - * @param string $value New value. + * @param mixed $value New value. */ protected function doSetProperty($property, $value) { @@ -76,6 +79,16 @@ trait ArrayPropertyTrait unset($this->_elements[$property]); } + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + return array_key_exists($property, $this->_elements) ? $this->_elements[$property] : $default; + } + /** * @return array */ diff --git a/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php b/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php index 735bbb2ae..28b9432cd 100644 --- a/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php @@ -10,6 +10,15 @@ namespace Grav\Framework\Object\Property; /** * Lazy Mixed Property Trait + * + * Stores defined object properties as class member variables and the rest into an array. Object properties are lazy + * loaded from the array. + * + * You may define following methods for the member variables: + * - `$this->offsetLoad($offset, $value)` called first time object property gets accessed + * - `$this->offsetPrepare($offset, $value)` called on every object property set + * - `$this->offsetSerialize($offset, $value)` called when the raw or serialized object property value is needed + * * @package Grav\Framework\Object\Property */ trait LazyPropertyTrait @@ -20,12 +29,14 @@ trait LazyPropertyTrait ArrayPropertyTrait::doGetProperty as getArrayProperty; ArrayPropertyTrait::doSetProperty as setArrayProperty; ArrayPropertyTrait::doUnsetProperty as unsetArrayProperty; + ArrayPropertyTrait::getElement as getArrayElement; 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::getElement as getObjectElement; ObjectPropertyTrait::getElements as getObjectElements; } @@ -56,7 +67,7 @@ trait LazyPropertyTrait /** * @param string $property Object property to be updated. - * @param string $value New value. + * @param mixed $value New value. * @return $this */ protected function doSetProperty($property, $value) @@ -82,6 +93,20 @@ trait LazyPropertyTrait return $this; } + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + if ($this->isPropertyLoaded($property)) { + return $this->getObjectElement($property, $default); + } + + return $this->getArrayElement($property, $default); + } + /** * @return array */ diff --git a/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php b/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php index 5c2e4a0f7..2c86376bf 100644 --- a/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php @@ -10,6 +10,15 @@ namespace Grav\Framework\Object\Property; /** * Mixed Property Trait + * + * Stores defined object properties as class member variables and the rest into an array. + * + * You may define following methods for member variables: + * - `$this->offsetLoad($offset, $value)` called first time object property gets accessed + * - `$this->offsetPrepare($offset, $value)` called on every object property set + * - `$this->offsetSerialize($offset, $value)` called when the raw or serialized object property value is needed + + * * @package Grav\Framework\Object\Property */ trait MixedPropertyTrait @@ -20,12 +29,14 @@ trait MixedPropertyTrait ArrayPropertyTrait::doGetProperty as getArrayProperty; ArrayPropertyTrait::doSetProperty as setArrayProperty; ArrayPropertyTrait::doUnsetProperty as unsetArrayProperty; + ArrayPropertyTrait::getElement as getArrayElement; 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::getElement as getObjectElement; ObjectPropertyTrait::getElements as getObjectElements; ObjectPropertyTrait::setElements as setObjectElements; } @@ -55,7 +66,7 @@ trait MixedPropertyTrait /** * @param string $property Object property to be updated. - * @param string $value New value. + * @param mixed $value New value. * @return $this */ protected function doSetProperty($property, $value) @@ -78,6 +89,20 @@ trait MixedPropertyTrait return $this; } + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + if ($this->hasObjectProperty($property)) { + return $this->getObjectElement($property, $default); + } + + return $this->getArrayElement($property, $default); + } + /** * @return array */ diff --git a/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php b/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php index b9e575cf6..c26903f21 100644 --- a/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php @@ -10,6 +10,15 @@ namespace Grav\Framework\Object\Property; /** * Object Property Trait + * + * Stores all properties as class member variables or object properties. All properties need to be defined as protected + * properties. Undefined properties will throw an error. + * + * Additionally you may define following methods: + * - `$this->offsetLoad($offset, $value)` called first time object property gets accessed + * - `$this->offsetPrepare($offset, $value)` called on every object property set + * - `$this->offsetSerialize($offset, $value)` called when the raw or serialized object property value is needed + * * @package Grav\Framework\Object\Property */ trait ObjectPropertyTrait @@ -31,6 +40,51 @@ trait ObjectPropertyTrait $this->setKey($key); } + /** + * @param string $property Object property name. + * @return bool True if property has been loaded. + */ + protected function isPropertyLoaded($property) + { + return !empty($this->_definedProperties[$property]); + } + + /** + * @param string $offset + * @param mixed $value + * @return mixed + */ + protected function offsetLoad($offset, $value) + { + $methodName = "offsetLoad_{$offset}"; + + return method_exists($this, $methodName)? $this->{$methodName}($value) : $value; + } + + /** + * @param string $offset + * @param mixed $value + * @return mixed + */ + protected function offsetPrepare($offset, $value) + { + $methodName = "offsetPrepare_{$offset}"; + + return method_exists($this, $methodName) ? $this->{$methodName}($value) : $value; + } + + /** + * @param string $offset + * @param mixed $value + * @return mixed + */ + protected function offsetSerialize($offset, $value) + { + $methodName = "offsetSerialize_{$offset}"; + + return method_exists($this, $methodName) ? $this->{$methodName}($value) : $value; + } + /** * @param string $property Object property name. * @return bool True if property has been defined (can be null). @@ -58,7 +112,7 @@ trait ObjectPropertyTrait $this->{$property} = null; } elseif (is_callable($doCreate)) { $this->_definedProperties[$property] = true; - $this->{$property} = $this->onPropertyLoad($property, $doCreate()); + $this->{$property} = $this->offsetLoad($property, $doCreate()); } else { return $default; } @@ -69,7 +123,7 @@ trait ObjectPropertyTrait /** * @param string $property Object property to be updated. - * @param string $value New value. + * @param mixed $value New value. * @throws \InvalidArgumentException */ protected function doSetProperty($property, $value) @@ -79,7 +133,7 @@ trait ObjectPropertyTrait } $this->_definedProperties[$property] = true; - $this->{$property} = $this->onPropertySet($property, $value); + $this->{$property} = $this->offsetPrepare($property, $value); } /** @@ -95,29 +149,6 @@ trait ObjectPropertyTrait 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 = []; @@ -128,6 +159,20 @@ trait ObjectPropertyTrait } } + /** + * @param string $property + * @param mixed|null $default + * @return mixed|null + */ + protected function getElement($property, $default = null) + { + if (empty($this->_definedProperties[$property])) { + return $default; + } + + return $this->offsetSerialize($property, $this->{$property}); + } + /** * @return array */ @@ -137,12 +182,7 @@ trait ObjectPropertyTrait $elements = []; foreach ($properties as $offset => $value) { - $methodName = "offsetSerialize_{$offset}"; - if (method_exists($this, $methodName)) { - $elements[$offset] = $this->{$methodName}($value); - } else { - $elements[$offset] = $value; - } + $elements[$offset] = $this->offsetSerialize($offset, $value); } return $elements;