mirror of
https://github.com/getgrav/grav.git
synced 2026-07-19 22:21:56 +02:00
Greatly simplify Object classes
This commit is contained in:
@@ -1,185 +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;
|
||||
|
||||
use RocketTheme\Toolbox\ArrayTraits\ArrayAccessWithGetters;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Export;
|
||||
|
||||
/**
|
||||
* Abstract base class for stored objects.
|
||||
*
|
||||
* @property string $id
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
abstract class AbstractObject implements ObjectInterface, StoredObjectInterface
|
||||
{
|
||||
use ObjectStorageTrait {
|
||||
check as traitcheck;
|
||||
}
|
||||
use ArrayAccessWithGetters, Export;
|
||||
|
||||
/**
|
||||
* Primary key for the object.
|
||||
* @var array
|
||||
*/
|
||||
static protected $primaryKey = [
|
||||
'id' => null
|
||||
];
|
||||
|
||||
/**
|
||||
* Default properties for the object.
|
||||
* @var array
|
||||
*/
|
||||
static protected $defaults = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
static protected $collectionClass = 'Grav\\Framework\\Object\\AbstractObjectCollection';
|
||||
|
||||
/**
|
||||
* Properties of the object.
|
||||
* @var array
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @param array $ids List of primary Ids or null to return everything that has been loaded.
|
||||
* @param bool $readonly
|
||||
* @return AbstractObjectCollection
|
||||
*/
|
||||
static public function instances(array $ids = null, $readonly = true)
|
||||
{
|
||||
$collectionClass = static::$collectionClass;
|
||||
|
||||
if (is_null($ids)) {
|
||||
return new $collectionClass(static::$instances);
|
||||
}
|
||||
|
||||
if (empty($ids)) {
|
||||
return new $collectionClass([]);
|
||||
}
|
||||
|
||||
$results = [];
|
||||
$list = [];
|
||||
|
||||
foreach ($ids as $id) {
|
||||
if (!isset(static::$instances[$id])) {
|
||||
$list[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($list) {
|
||||
$c = get_called_class();
|
||||
$storage = static::getStorage();
|
||||
$list = $storage->loadList($list);
|
||||
foreach ($list as $keys) {
|
||||
/** @var static $instance */
|
||||
$instance = new $c();
|
||||
$instance->doLoad($keys);
|
||||
$id = $instance->getId();
|
||||
if ($id && !isset(static::$instances[$id])) {
|
||||
$instance->initialize();
|
||||
static::$instances[$id] = $instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($ids as $id) {
|
||||
if (isset(static::$instances[$id])) {
|
||||
$results[$id] = $readonly ? clone static::$instances[$id] : static::$instances[$id];
|
||||
}
|
||||
}
|
||||
|
||||
return new $collectionClass($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to perform sanity checks on the instance properties to ensure they are safe to store in the storage.
|
||||
*
|
||||
* Child classes should override this method to make sure the data they are storing in the storage is safe and as
|
||||
* expected before saving the object.
|
||||
*
|
||||
* @return bool True if the instance is sane and able to be stored in the storage.
|
||||
*/
|
||||
public function check($includeChildren = false)
|
||||
{
|
||||
return $this->checkKeys() && $this->traitCheck($includeChildren);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
* @return array
|
||||
*/
|
||||
public function getKeys(array $keys = [])
|
||||
{
|
||||
foreach (static::$primaryKey as $key => $value) {
|
||||
if (!isset($keys[$key])) {
|
||||
if (isset($this->items[$key])) {
|
||||
$keys[$key] = $this->items[$key];
|
||||
} else {
|
||||
$keys[$key] = $value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
* @return bool
|
||||
*/
|
||||
public function checkKeys(array $keys = [])
|
||||
{
|
||||
if (!$keys) {
|
||||
$keys = $this->getKeys();
|
||||
}
|
||||
|
||||
foreach ($keys as $key => $value) {
|
||||
if ($value === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementes JsonSerializable interface.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__ . '@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
// Internal functions
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
* @param array $keys
|
||||
*/
|
||||
protected function doLoad(array $items, array $keys = [])
|
||||
{
|
||||
$this->items = array_replace(static::$defaults, $this->items, $this->getKeys($keys), $items);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +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;
|
||||
|
||||
use Grav\Framework\Collection\ArrayCollection;
|
||||
|
||||
/**
|
||||
* Abstract Object Collection
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
abstract class AbstractObjectCollection extends ArrayCollection implements ObjectCollectionInterface, StoredObjectInterface
|
||||
{
|
||||
use ObjectStorageTrait {
|
||||
getId as getParentId;
|
||||
}
|
||||
use ObjectCollectionTrait;
|
||||
|
||||
protected $id;
|
||||
|
||||
public function setId($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id ?: $this->getParentId();
|
||||
}
|
||||
}
|
||||
58
system/src/Grav/Framework/Object/Object.php
Normal file
58
system/src/Grav/Framework/Object/Object.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?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 RocketTheme\Toolbox\ArrayTraits\ArrayAccessWithGetters;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Export;
|
||||
|
||||
/**
|
||||
* Object class.
|
||||
*
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
class Object implements ObjectInterface
|
||||
{
|
||||
use ObjectTrait, ArrayAccessWithGetters, Export;
|
||||
|
||||
/**
|
||||
* Properties of the object.
|
||||
* @var array
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
*/
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
|
||||
$this->items = $elements;
|
||||
$this->key = $key !== null ? $key : $this->getKey();
|
||||
|
||||
if ($this->key === null) {
|
||||
throw new \InvalidArgumentException('Object cannot be created without assigning a key');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements JsonSerializable interface.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return ['key' => $this->getKey(), 'object' => $this->toArray()];
|
||||
}
|
||||
}
|
||||
50
system/src/Grav/Framework/Object/ObjectCollection.php
Normal file
50
system/src/Grav/Framework/Object/ObjectCollection.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?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\Collection\ArrayCollection;
|
||||
|
||||
/**
|
||||
* Object Collection
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
class ObjectCollection extends ArrayCollection implements ObjectCollectionInterface
|
||||
{
|
||||
use ObjectCollectionTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
*/
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
parent::__construct($elements);
|
||||
|
||||
$this->key = $key !== null ? $key : $this->getKey();
|
||||
|
||||
if ($this->key === null) {
|
||||
throw new \InvalidArgumentException('Object cannot be created without assigning a key');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements JsonSerializable interface.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return ['key' => $this->getKey(), 'objects' => $this->toArray()];
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ use Grav\Framework\Collection\CollectionInterface;
|
||||
* ObjectCollection Interface
|
||||
* @package Grav\Framework\Collection
|
||||
*/
|
||||
interface ObjectCollectionInterface extends CollectionInterface
|
||||
interface ObjectCollectionInterface extends CollectionInterface, ObjectInterface
|
||||
{
|
||||
/**
|
||||
* Create a copy from this collection by cloning all objects in the collection.
|
||||
@@ -23,6 +23,11 @@ interface ObjectCollectionInterface extends CollectionInterface
|
||||
*/
|
||||
public function copy();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getObjectKeys();
|
||||
|
||||
/**
|
||||
* @param string $property Object property to be fetched.
|
||||
* @return array Values of the property.
|
||||
@@ -42,4 +47,12 @@ interface ObjectCollectionInterface extends CollectionInterface
|
||||
* @return array Return values.
|
||||
*/
|
||||
public function call($name, array $arguments);
|
||||
|
||||
/**
|
||||
* Group items in the collection by a field.
|
||||
*
|
||||
* @param string $property
|
||||
* @return array
|
||||
*/
|
||||
public function group($property);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace Grav\Framework\Object;
|
||||
*/
|
||||
trait ObjectCollectionTrait
|
||||
{
|
||||
use ObjectTrait;
|
||||
|
||||
/**
|
||||
* Create a copy from this collection by cloning all objects in the collection.
|
||||
*
|
||||
@@ -26,12 +28,20 @@ trait ObjectCollectionTrait
|
||||
$list[$key] = is_object($value) ? clone $value : $value;
|
||||
}
|
||||
|
||||
if (method_exists($this, 'createFrom')) {
|
||||
return $this->createFrom($list);
|
||||
} else {
|
||||
// TODO: remove when PHP 5.6 is minimum (with doctrine/collections v1.4).
|
||||
// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getObjectKeys()
|
||||
{
|
||||
return $this->call('getKey');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +75,7 @@ trait ObjectCollectionTrait
|
||||
* @param array $arguments List of arguments passed to the function.
|
||||
* @return array Return values.
|
||||
*/
|
||||
public function call($method, array $arguments)
|
||||
public function call($method, array $arguments = [])
|
||||
{
|
||||
$list = [];
|
||||
|
||||
|
||||
@@ -15,48 +15,13 @@ namespace Grav\Framework\Object;
|
||||
interface ObjectInterface extends \ArrayAccess, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Returns the global instance to the object.
|
||||
*
|
||||
* Note that using array of fields will always make a query, but it's very useful feature if you want to search one
|
||||
* item by using arbitrary set of matching fields. If there are more than one matching object, first one gets returned.
|
||||
*
|
||||
* @param null|int|string|array $keys An optional primary key value to load the object by, or an array of fields to match.
|
||||
* @param boolean $reload Force object to reload.
|
||||
*
|
||||
* @return Object
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
*/
|
||||
static public function instance($keys = null, $reload = false);
|
||||
public function __construct(array $elements = [], $key = null);
|
||||
|
||||
/**
|
||||
* @param array $ids List of primary Ids or null to return everything that has been loaded.
|
||||
* @param bool $readonly
|
||||
* @return AbstractObjectCollection
|
||||
* @return string
|
||||
*/
|
||||
static public function instances(array $ids = null, $readonly = true);
|
||||
|
||||
/**
|
||||
* Removes all or selected instances from the object cache.
|
||||
*
|
||||
* @param null|int|string|array $ids An optional primary key or list of keys.
|
||||
*/
|
||||
static public function freeInstances($ids = null);
|
||||
|
||||
/**
|
||||
* Override this function if you need to initialize object right after creating it.
|
||||
*
|
||||
* Can be used for example if the fields need to be converted from json strings to array.
|
||||
*
|
||||
* @return bool True if initialization was done, false if object was already initialized.
|
||||
*/
|
||||
public function initialize();
|
||||
|
||||
/**
|
||||
* Method to perform sanity checks on the instance properties to ensure they are safe to store in the storage.
|
||||
*
|
||||
* Child classes should override this method to make sure the data they are storing in the storage is safe and as
|
||||
* expected before saving the object.
|
||||
*
|
||||
* @return boolean True if the instance is sane and able to be stored in the storage.
|
||||
*/
|
||||
public function check();
|
||||
public function getKey();
|
||||
}
|
||||
|
||||
@@ -1,385 +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;
|
||||
|
||||
use Grav\Framework\Object\Storage\StorageInterface;
|
||||
|
||||
/**
|
||||
* Trait for implementing stored objects.
|
||||
*
|
||||
* @property string $id
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
trait ObjectStorageTrait
|
||||
{
|
||||
/**
|
||||
* If you don't have global instance ids, override this in extending class.
|
||||
* @var array
|
||||
*/
|
||||
static protected $instances = [];
|
||||
|
||||
/**
|
||||
* If you don't have global storage, override this in extending class.
|
||||
* @var StorageInterface
|
||||
*/
|
||||
static protected $storage;
|
||||
|
||||
/**
|
||||
* Readonly object.
|
||||
* @var bool
|
||||
*/
|
||||
protected $readonly = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $initialized = false;
|
||||
|
||||
|
||||
/**
|
||||
* @param StorageInterface $storage
|
||||
*/
|
||||
static public function setStorage(StorageInterface $storage)
|
||||
{
|
||||
static::$storage = $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global instance to the object.
|
||||
*
|
||||
* Note that using array of fields will always make a query, but it's very useful feature if you want to search one
|
||||
* item by using arbitrary set of matching fields. If there are more than one matching object, first one gets returned.
|
||||
*
|
||||
* @param string|array $keys An optional primary key value to load the object by, or an array of fields to match.
|
||||
* @param boolean $reload Force object to reload.
|
||||
*
|
||||
* @return ObjectInterface
|
||||
*/
|
||||
static public function instance($keys = null, $reload = false)
|
||||
{
|
||||
if (is_scalar($keys)) {
|
||||
$keys = ['id' => (string) $keys];
|
||||
}
|
||||
$id = $keys ? static::getInstanceId($keys) : null;
|
||||
|
||||
// If we are creating or loading a new item or we load instance by alternative keys, we need to create a new object.
|
||||
if (!$id || !isset(static::$instances[$id])) {
|
||||
$c = get_called_class();
|
||||
|
||||
/** @var ObjectStorageTrait|ObjectInterface $instance */
|
||||
$instance = new $c();
|
||||
if (!$instance->load($keys)) {
|
||||
return $instance;
|
||||
}
|
||||
|
||||
// Instance exists in storage: make sure that we return the global instance.
|
||||
$id = $instance->getId();
|
||||
$reload = false;
|
||||
}
|
||||
|
||||
// Return global instance from the identifier.
|
||||
$instance = static::$instances[$id];
|
||||
|
||||
if ($reload) {
|
||||
$instance->load();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all or selected instances from the object cache.
|
||||
*
|
||||
* @param null|string|array $ids An optional primary key or list of keys.
|
||||
*/
|
||||
static public function freeInstances($ids = null)
|
||||
{
|
||||
if ($ids === null) {
|
||||
$ids = array_keys(static::$instances);
|
||||
}
|
||||
$ids = (array) $ids;
|
||||
|
||||
foreach ($ids as $id) {
|
||||
unset(static::$instances[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this function if you need to initialize object right after creating it.
|
||||
*
|
||||
* Can be used for example if the fields need to be converted from json strings to array.
|
||||
*
|
||||
* @return bool True if initialization was done, false if object was already initialized.
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
$initialized = $this->initialized;
|
||||
$this->initialized = true;
|
||||
|
||||
return !$initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert instance to a read only object.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function readonly()
|
||||
{
|
||||
$this->readonly = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the object has been stored.
|
||||
*
|
||||
* @return boolean True if object exists in storage.
|
||||
*/
|
||||
public function isSaved()
|
||||
{
|
||||
return $this->getStorage()->exists($this->getStorageKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to load object from the storage.
|
||||
*
|
||||
* @param mixed $keys An optional primary key value to load the object by, or an array of fields to match. If not
|
||||
* set the instance key value is used.
|
||||
* @param bool $getKey Internal parameter, please do not use.
|
||||
*
|
||||
* @return bool True on success, false if the object doesn't exist.
|
||||
*/
|
||||
public function load($keys = null, $getKey = true)
|
||||
{
|
||||
if ($getKey) {
|
||||
if (is_scalar($keys)) {
|
||||
$keys = ['id' => (string) $keys];
|
||||
}
|
||||
|
||||
// Fetch internal key.
|
||||
$key = $keys ? $this->getStorageKey($keys) : null;
|
||||
|
||||
} else {
|
||||
// Internal key was passed.
|
||||
$key = $keys;
|
||||
$keys = [];
|
||||
}
|
||||
|
||||
$this->doLoad($this->getStorage()->load($key), $keys);
|
||||
$this->initialize();
|
||||
|
||||
$id = $this->getId();
|
||||
if ($id) {
|
||||
if (!isset(static::$instances[$id])) {
|
||||
static::$instances[$id] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->isSaved();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to save the object to the storage.
|
||||
*
|
||||
* Before saving the object, this method checks if object can be safely saved.
|
||||
*
|
||||
* @param bool $includeChildren
|
||||
* @return bool True on success.
|
||||
*/
|
||||
public function save($includeChildren = false)
|
||||
{
|
||||
// Check the object.
|
||||
if ($this->readonly || !$this->check($includeChildren) || !$this->onBeforeSave()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get storage.
|
||||
$storage = $this->getStorage();
|
||||
$key = $this->getStorageKey();
|
||||
|
||||
// Get data to be saved.
|
||||
$data = $this->prepareSave();
|
||||
|
||||
// Save the object.
|
||||
$exists = $storage->exists($key);
|
||||
$id = $storage->save($key, $data);
|
||||
|
||||
if (!$id) {
|
||||
throw new \LogicException('No id specified');
|
||||
}
|
||||
|
||||
// If item was created, load the object (making sure it has been properly initialized).
|
||||
if (!$exists) {
|
||||
$this->load($id, false);
|
||||
}
|
||||
|
||||
if ($includeChildren) {
|
||||
$this->saveChildren();
|
||||
}
|
||||
|
||||
$this->onAfterSave();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to delete the object from the database.
|
||||
*
|
||||
* @param bool $includeChildren
|
||||
* @return bool True on success.
|
||||
*/
|
||||
public function delete($includeChildren = false)
|
||||
{
|
||||
if ($this->readonly || !$this->isSaved() || !$this->onBeforeDelete()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($includeChildren) {
|
||||
$this->deleteChildren();
|
||||
}
|
||||
|
||||
// Get storage.
|
||||
$storage = $this->getStorage();
|
||||
|
||||
if (!$storage->delete($this->getStorageKey())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->onAfterDelete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to perform sanity checks on the instance properties to ensure they are safe to store in the storage.
|
||||
*
|
||||
* Child classes should override this method to make sure the data they are storing in the storage is safe and as
|
||||
* expected before saving the object.
|
||||
*
|
||||
* @return bool True if the instance is sane and able to be stored in the storage.
|
||||
*/
|
||||
public function check($includeChildren = false)
|
||||
{
|
||||
$result = true;
|
||||
|
||||
if ($includeChildren) {
|
||||
foreach ($this->toArray() as $field => $value) {
|
||||
if (is_object($value) && method_exists($value, 'check')) {
|
||||
$result = $result && $value->check();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Internal functions
|
||||
|
||||
abstract protected function doLoad(array $items, array $keys = []);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function onBeforeSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function onAfterSave()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function onBeforeDelete()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function onAfterDelete()
|
||||
{
|
||||
}
|
||||
|
||||
protected function saveChildren()
|
||||
{
|
||||
foreach ($this->toArray() as $field => $value) {
|
||||
if (is_object($value) && method_exists($value, 'save')) {
|
||||
$value->save(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function deleteChildren()
|
||||
{
|
||||
foreach ($this->toArray() as $field => $value) {
|
||||
if (is_object($value) && method_exists($value, 'delete')) {
|
||||
$value->delete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareSave(array $data = null)
|
||||
{
|
||||
if ($data === null) {
|
||||
$data = $this->toArray();
|
||||
}
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
if (is_object($value) && method_exists($value, 'save')) {
|
||||
unset($data[$field]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the storage key for the object.
|
||||
*
|
||||
* @param array
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getStorageKey(array $keys = []);
|
||||
|
||||
/**
|
||||
* @param array $keys
|
||||
* @return string
|
||||
*/
|
||||
public function getInstanceId(array $keys)
|
||||
{
|
||||
return $this->getStorageKey($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->getStorageKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return StorageInterface
|
||||
*/
|
||||
protected static function getStorage()
|
||||
{
|
||||
if (!static::$storage) {
|
||||
static::loadStorage();
|
||||
}
|
||||
|
||||
return static::$storage;
|
||||
}
|
||||
|
||||
protected static function loadStorage()
|
||||
{
|
||||
throw new \RuntimeException('Storage has not been set.');
|
||||
}
|
||||
}
|
||||
64
system/src/Grav/Framework/Object/ObjectTrait.php
Normal file
64
system/src/Grav/Framework/Object/ObjectTrait.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;
|
||||
|
||||
use RocketTheme\Toolbox\ArrayTraits\ArrayAccessWithGetters;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Export;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function __construct(array $elements = [], $key = null)
|
||||
{
|
||||
|
||||
$this->items = $elements;
|
||||
$this->key = $key !== null ? $key : $this->getKey();
|
||||
|
||||
if ($this->key === null) {
|
||||
throw new \InvalidArgumentException('Object cannot be created without assigning a key');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__ . '@' . spl_object_hash($this);
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object\Storage
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Storage;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\File\FileInterface;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
/**
|
||||
* FilesystemStorage
|
||||
* @package Grav\Framework\Object\Storage
|
||||
*/
|
||||
class FilesystemStorage implements StorageInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'Grav\\Common\\File\\CompiledJsonFile';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension = '.json';
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $extension
|
||||
* @param string $type
|
||||
*/
|
||||
public function __construct($path, $type = null, $extension = null)
|
||||
{
|
||||
$this->path = $path;
|
||||
if ($type) {
|
||||
$this->type = $type;
|
||||
}
|
||||
if ($extension) {
|
||||
$this->extension = $extension;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($key)
|
||||
{
|
||||
if ($key === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->getFile($key);
|
||||
|
||||
return $file->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function load($key)
|
||||
{
|
||||
if ($key === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$file = $this->getFile($key);
|
||||
$content = (array)$file->content();
|
||||
$file->free();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function save($key, array $data)
|
||||
{
|
||||
$file = $this->getFile($key);
|
||||
$file->save($data);
|
||||
$file->free();
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$file = $this->getFile($key);
|
||||
$result = $file->delete();
|
||||
$file->free();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $list
|
||||
* @return array
|
||||
*/
|
||||
public function loadList(array $list)
|
||||
{
|
||||
$results = [];
|
||||
foreach ($list as $id) {
|
||||
$results[$id] = $this->load($id);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return FileInterface
|
||||
*/
|
||||
protected function getFile($key)
|
||||
{
|
||||
if ($key === null) {
|
||||
throw new \RuntimeException('Storage key not defined');
|
||||
}
|
||||
|
||||
$filename = "{$this->path}/{$key}{$this->extension}";
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
/** @var FileInterface $type */
|
||||
$type = $this->type;
|
||||
|
||||
return $type::instance($locator->findResource($filename, true) ?: $locator->findResource($filename, true, true));
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Grav\Framework\Object\Storage
|
||||
*
|
||||
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Object\Storage;
|
||||
|
||||
/**
|
||||
* Interface StorageInterface
|
||||
* @package Grav\Framework\Object\Storage
|
||||
*/
|
||||
interface StorageInterface
|
||||
{
|
||||
/**
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($key);
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function load($key);
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function save($key, array $data);
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function delete($key);
|
||||
|
||||
/**
|
||||
* @param string[] $list
|
||||
* @return array
|
||||
*/
|
||||
public function loadList(array $list);
|
||||
}
|
||||
@@ -1,58 +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;
|
||||
|
||||
/**
|
||||
* Stored Object Interface
|
||||
* @package Grav\Framework\Object
|
||||
*/
|
||||
interface StoredObjectInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Convert instance to a read only object.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function readonly();
|
||||
|
||||
/**
|
||||
* Returns true if the object exists in the storage.
|
||||
*
|
||||
* @return boolean True if object exists.
|
||||
*/
|
||||
public function isSaved();
|
||||
|
||||
/**
|
||||
* Method to load object from the storage.
|
||||
*
|
||||
* @param null|int|string|array $keys An optional primary key value to load the object by, or an array of fields
|
||||
* to match. If not set the instance key value is used.
|
||||
*
|
||||
* @return boolean True on success, false if the object doesn't exist.
|
||||
*/
|
||||
public function load($keys = null);
|
||||
|
||||
/**
|
||||
* Method to save the object to the storage.
|
||||
*
|
||||
* Before saving the object, this method checks if object can be safely saved.
|
||||
*
|
||||
* @param bool $includeChildren
|
||||
* @return boolean True on success.
|
||||
*/
|
||||
public function save($includeChildren = false);
|
||||
|
||||
/**
|
||||
* Method to delete the object from the database.
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*/
|
||||
public function delete();
|
||||
}
|
||||
Reference in New Issue
Block a user