mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 15:29:57 +01:00
Merge branch 'feature/objects' of https://github.com/getgrav/grav into feature/objects
This commit is contained in:
@@ -256,20 +256,31 @@ abstract class AbstractObject implements ObjectInterface
|
||||
*
|
||||
* @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 boolean True on success, false if the object doesn't exist.
|
||||
*/
|
||||
public function load($keys = null)
|
||||
public function load($keys = null, $getKey = true)
|
||||
{
|
||||
if (is_scalar($keys)) {
|
||||
$keys = ['id' => (string) $keys];
|
||||
if ($getKey) {
|
||||
if (is_scalar($keys)) {
|
||||
$keys = ['id' => (string) $keys];
|
||||
}
|
||||
|
||||
// Fetch internal key.
|
||||
$key = $this->getStorageKey($keys);
|
||||
|
||||
} else {
|
||||
// Internal key was passed.
|
||||
$key = $keys;
|
||||
$keys = [];
|
||||
}
|
||||
|
||||
// Get storage.
|
||||
$storage = $this->getStorage();
|
||||
|
||||
// Load the object based on the keys.
|
||||
$this->items = $storage->load($keys);
|
||||
$this->items = $storage->load($key);
|
||||
$this->exists = !empty($this->items);
|
||||
|
||||
// Append the keys and defaults if they were not set by load().
|
||||
@@ -293,25 +304,38 @@ abstract class AbstractObject implements ObjectInterface
|
||||
*
|
||||
* @return boolean True on success.
|
||||
*/
|
||||
public function save()
|
||||
public function save($includeChildren = false)
|
||||
{
|
||||
// Check the object.
|
||||
if ($this->readonly || !$this->check() || !$this->onBeforeSave()) {
|
||||
if ($this->readonly || !$this->check($includeChildren) || !$this->onBeforeSave()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get storage.
|
||||
$storage = $this->getStorage();
|
||||
try {
|
||||
// Get storage.
|
||||
$storage = $this->getStorage();
|
||||
$key = $this->getStorageKey();
|
||||
|
||||
// Get data to be saved.
|
||||
$data = $this->prepareSave($this->toArray());
|
||||
|
||||
// Save the object.
|
||||
$id = $storage->save($key, $data);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save the object.
|
||||
$id = $storage->save($this);
|
||||
if (!$id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If item was created, load the object.
|
||||
if (!$this->exists) {
|
||||
$this->load($id);
|
||||
$this->load($id, false);
|
||||
}
|
||||
|
||||
if ($includeChildren) {
|
||||
$this->saveChildren();
|
||||
}
|
||||
|
||||
$this->onAfterSave();
|
||||
@@ -322,18 +346,23 @@ abstract class AbstractObject implements ObjectInterface
|
||||
/**
|
||||
* Method to delete the object from the database.
|
||||
*
|
||||
* @param bool $includeChildren
|
||||
* @return boolean True on success.
|
||||
*/
|
||||
public function delete()
|
||||
public function delete($includeChildren = false)
|
||||
{
|
||||
if ($this->readonly || !$this->exists || !$this->onBeforeDelete()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($includeChildren) {
|
||||
$this->deleteChildren();
|
||||
}
|
||||
|
||||
// Get storage.
|
||||
$storage = $this->getStorage();
|
||||
|
||||
if (!$storage->delete($this)) {
|
||||
if (!$storage->delete($this->getStorageKey())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -352,9 +381,29 @@ abstract class AbstractObject implements ObjectInterface
|
||||
*
|
||||
* @return boolean True if the instance is sane and able to be stored in the storage.
|
||||
*/
|
||||
public function check()
|
||||
public function check($includeChildren = false)
|
||||
{
|
||||
return !empty($this->id);
|
||||
$result = true;
|
||||
|
||||
if ($includeChildren) {
|
||||
foreach ($this->items as $field => $value) {
|
||||
if (is_object($value) && method_exists($value, 'check')) {
|
||||
$result = $result && $value->check();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result && !empty($this->items['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementes JsonSerializable interface.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
// Internal functions
|
||||
@@ -371,7 +420,7 @@ abstract class AbstractObject implements ObjectInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
protected function onBeforeSave()
|
||||
{
|
||||
@@ -383,7 +432,7 @@ abstract class AbstractObject implements ObjectInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
protected function onBeforeDelete()
|
||||
{
|
||||
@@ -394,6 +443,43 @@ abstract class AbstractObject implements ObjectInterface
|
||||
{
|
||||
}
|
||||
|
||||
protected function saveChildren()
|
||||
{
|
||||
foreach ($this->items as $field => $value) {
|
||||
if (is_object($value) && method_exists($value, 'save')) {
|
||||
$value->save(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function deleteChildren()
|
||||
{
|
||||
foreach ($this->items as $field => $value) {
|
||||
if (is_object($value) && method_exists($value, 'delete')) {
|
||||
$value->delete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareSave(array $data)
|
||||
{
|
||||
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 protected function getStorageKey(array $keys = null);
|
||||
|
||||
/**
|
||||
* @return StorageInterface
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Grav\Common\Object;
|
||||
|
||||
interface ObjectInterface extends \ArrayAccess
|
||||
interface ObjectInterface extends \ArrayAccess, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Returns the global instance to the object.
|
||||
|
||||
@@ -1,48 +1,95 @@
|
||||
<?php
|
||||
namespace Grav\Common\Object\Storage;
|
||||
|
||||
use Grav\Common\Object\AbstractObject;
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\File\FileInterface;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
class FilesystemStorage implements StorageInterface
|
||||
{
|
||||
/**
|
||||
* @param array $keys
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $extension;
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $extension
|
||||
* @param string $type
|
||||
*/
|
||||
public function __construct($path, $type = 'Grav\\Common\\File\\CompiledJsonFile', $extension = '.json')
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->type = $type;
|
||||
$this->extension = $extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function load(array $keys)
|
||||
public function load($key)
|
||||
{
|
||||
// TODO
|
||||
return [];
|
||||
if ($key === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$file = $this->getFile($key);
|
||||
$content = (array)$file->content();
|
||||
$file->free();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractObject $object
|
||||
* @return string|int Id
|
||||
* @param string $key
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function save(AbstractObject $object)
|
||||
public function save($key, array $data)
|
||||
{
|
||||
// TODO
|
||||
return 'xxx';
|
||||
$file = $this->getFile($key);
|
||||
$file->save($data);
|
||||
$file->free();
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AbstractObject $object
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(AbstractObject $object)
|
||||
public function delete($key)
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
$file = $this->getFile($key);
|
||||
$result = $file->delete();
|
||||
$file->free();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|int[]|string[] $list
|
||||
* @param string[] $list
|
||||
* @return array
|
||||
*/
|
||||
public function loadList(array $list)
|
||||
{
|
||||
// TODO
|
||||
return [];
|
||||
$results = [];
|
||||
foreach ($list as $id) {
|
||||
$results[$id] = $this->load(['id' => $id]);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,11 +104,32 @@ class FilesystemStorage implements StorageInterface
|
||||
|
||||
/**
|
||||
* @param array $query
|
||||
* @return array|int[]|string[]
|
||||
* @return string[]
|
||||
*/
|
||||
public function find(array $query)
|
||||
public function find(array $query, $start = 0, $limit = 0)
|
||||
{
|
||||
// TODO
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @return FileInterface
|
||||
*/
|
||||
protected function getFile($key)
|
||||
{
|
||||
if ($key === null) {
|
||||
throw new \RuntimeException('Id 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,30 +1,29 @@
|
||||
<?php
|
||||
namespace Grav\Common\Object\Storage;
|
||||
|
||||
use Grav\Common\Object\AbstractObject;
|
||||
|
||||
interface StorageInterface
|
||||
{
|
||||
/**
|
||||
* @param array $keys
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function load(array $keys);
|
||||
public function load($key);
|
||||
|
||||
/**
|
||||
* @param AbstractObject $object
|
||||
* @return string Id
|
||||
* @param string $key
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function save(AbstractObject $object);
|
||||
public function save($key, array $data);
|
||||
|
||||
/**
|
||||
* @param AbstractObject $object
|
||||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(AbstractObject $object);
|
||||
public function delete($key);
|
||||
|
||||
/**
|
||||
* @param array|string[] $list
|
||||
* @param string[] $list
|
||||
* @return array
|
||||
*/
|
||||
public function loadList(array $list);
|
||||
@@ -39,7 +38,7 @@ interface StorageInterface
|
||||
* @param array $query
|
||||
* @param int $start
|
||||
* @param int $limit
|
||||
* @return array|string[]
|
||||
* @return string[]
|
||||
*/
|
||||
public function find(array $query, $start, $limit);
|
||||
public function find(array $query, $start = 0, $limit = 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user