mirror of
https://github.com/getgrav/grav.git
synced 2026-05-07 18:06:57 +02:00
Greatly improved Flex interfaces and docblocks
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
* Twig `nicenumber`: do not use 0 + string casting hack
|
||||
* Converted Twig tags to use namespaced Twig classes
|
||||
* Site shows error on page rather than hard-crash when page has invalid frontmatter [#2343](https://github.com/getgrav/grav/issues/2343)
|
||||
* Grav 1.6: Greatly improved Flex interfaces
|
||||
1. [](#bugfix)
|
||||
* Grav 1.6: Fixed `FlexUser` loosing ACL information
|
||||
* Grav 1.6: Fixed `FlexUser::find()` breaking when nothing is found
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
namespace Grav\Common\User\FlexUser;
|
||||
|
||||
use Grav\Common\Data\ValidationException;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Media\Interfaces\MediaCollectionInterface;
|
||||
use Grav\Common\Page\Media;
|
||||
@@ -18,7 +17,6 @@ use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\User\Authentication;
|
||||
use Grav\Common\User\Interfaces\UserInterface;
|
||||
use Grav\Common\User\Traits\UserTrait;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\File\Formatter\JsonFormatter;
|
||||
use Grav\Framework\File\Formatter\YamlFormatter;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
@@ -65,7 +63,7 @@ class User extends FlexObject implements UserInterface, MediaManipulationInterfa
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getCachedMethods()
|
||||
public static function getCachedMethods(): array
|
||||
{
|
||||
return [
|
||||
'load' => false,
|
||||
@@ -78,12 +76,12 @@ class User extends FlexObject implements UserInterface, MediaManipulationInterfa
|
||||
] + parent::getCachedMethods();
|
||||
}
|
||||
|
||||
public function __construct(array $elements, $key, FlexDirectory $flexDirectory, bool $validate = false)
|
||||
public function __construct(array $elements, $key, FlexDirectory $directory, bool $validate = false)
|
||||
{
|
||||
// User can only be authenticated via login.
|
||||
unset($elements['authenticated'], $elements['authorized']);
|
||||
|
||||
parent::__construct($elements, $key, $flexDirectory, $validate);
|
||||
parent::__construct($elements, $key, $directory, $validate);
|
||||
|
||||
// Define username and state if they aren't set.
|
||||
$this->defProperty('username', $key);
|
||||
@@ -435,7 +433,7 @@ class User extends FlexObject implements UserInterface, MediaManipulationInterfa
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function prepareStorage()
|
||||
public function prepareStorage(): array
|
||||
{
|
||||
$elements = parent::prepareStorage();
|
||||
|
||||
@@ -628,7 +626,7 @@ class User extends FlexObject implements UserInterface, MediaManipulationInterfa
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function doSerialize()
|
||||
protected function doSerialize(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'accounts',
|
||||
@@ -641,7 +639,7 @@ class User extends FlexObject implements UserInterface, MediaManipulationInterfa
|
||||
/**
|
||||
* @param array $serialized
|
||||
*/
|
||||
protected function doUnserialize(array $serialized)
|
||||
protected function doUnserialize(array $serialized): void
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class Flex implements \Countable
|
||||
* @param array $config
|
||||
* @return $this
|
||||
*/
|
||||
public function addDirectoryType(string $type, string $blueprint, array $config = []): self
|
||||
public function addDirectoryType(string $type, string $blueprint, array $config = [])
|
||||
{
|
||||
$config = array_merge_recursive(['enabled' => true], $this->config['object'] ?? [], $config);
|
||||
|
||||
|
||||
@@ -40,9 +40,11 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
private $_keyField;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* Get list of cached methods.
|
||||
*
|
||||
* @return array Returns a list of methods with their caching information.
|
||||
*/
|
||||
public static function getCachedMethods()
|
||||
public static function getCachedMethods(): array
|
||||
{
|
||||
return [
|
||||
'getTypePrefix' => true,
|
||||
@@ -65,12 +67,10 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $entries
|
||||
* @param FlexDirectory $directory
|
||||
* @param string $keyField
|
||||
* @return static
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::createFromArray()
|
||||
*/
|
||||
public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null): FlexCollectionInterface
|
||||
public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null)
|
||||
{
|
||||
$instance = new static($entries, $directory);
|
||||
$instance->setKeyField($keyField);
|
||||
@@ -79,66 +79,23 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param FlexDirectory|null $flexDirectory
|
||||
* @throws \InvalidArgumentException
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::__construct()
|
||||
*/
|
||||
public function __construct(array $elements = [], FlexDirectory $flexDirectory = null)
|
||||
public function __construct(array $entries = [], FlexDirectory $directory = null)
|
||||
{
|
||||
parent::__construct($elements);
|
||||
parent::__construct($entries);
|
||||
|
||||
if ($flexDirectory) {
|
||||
$this->setFlexDirectory($flexDirectory)->setKey($flexDirectory->getType());
|
||||
if ($directory) {
|
||||
$this->setFlexDirectory($directory)->setKey($directory->getType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance from the specified elements.
|
||||
*
|
||||
* This method is provided for derived classes to specify how a new
|
||||
* instance should be created when constructor semantics have changed.
|
||||
*
|
||||
* @param array $elements Elements.
|
||||
* @param string|null $keyField
|
||||
*
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::search()
|
||||
*/
|
||||
protected function createFrom(array $elements, $keyField = null)
|
||||
{
|
||||
$collection = new static($elements, $this->_flexDirectory);
|
||||
$collection->setKeyField($keyField ?: $this->_keyField);
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTypePrefix()
|
||||
{
|
||||
return 'c.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
*/
|
||||
public function getType($prefix = false)
|
||||
{
|
||||
$type = $prefix ? $this->getTypePrefix() : '';
|
||||
|
||||
return $type . $this->_flexDirectory->getType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return FlexCollectionInterface
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null) // : FlexCollectionInterface
|
||||
public function search(string $search, $properties = null, array $options = null)
|
||||
{
|
||||
$matching = $this->call('search', [$search, $properties, $options]);
|
||||
$matching = array_filter($matching);
|
||||
@@ -152,35 +109,154 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
return $this->select(array_keys($matching));
|
||||
}
|
||||
|
||||
public function sort(array $order) // : FlexCollectionInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::sort()
|
||||
*/
|
||||
public function sort(array $order)
|
||||
{
|
||||
$criteria = Criteria::create()->orderBy($order);
|
||||
|
||||
return $this->matching($criteria);
|
||||
/** @var FlexCollectionInterface $matching */
|
||||
$matching = $this->matching($criteria);
|
||||
|
||||
return $matching;
|
||||
}
|
||||
|
||||
/**
|
||||
* Twig example: {% render collection layout 'edit' with {my_check: true} %}
|
||||
*
|
||||
* @param string $layout
|
||||
* @param array $context
|
||||
* @return ContentBlockInterface|HtmlBlock
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
* @throws LoaderError
|
||||
* @throws SyntaxError
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexType()
|
||||
*/
|
||||
public function getFlexType(): string
|
||||
{
|
||||
return $this->_flexDirectory->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getFlexDirectory(): FlexDirectory
|
||||
{
|
||||
return $this->_flexDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getTimestamp()
|
||||
*/
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
$timestamps = $this->getTimestamps();
|
||||
|
||||
return $timestamps ? max($timestamps) : time();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
return $this->getTypePrefix() . $this->getFlexType() . '.' . sha1(json_encode($this->call('getKey')));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getCacheChecksum(): string
|
||||
{
|
||||
return sha1(json_encode($this->getTimestamps()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getTimestamps(): array
|
||||
{
|
||||
/** @var int[] $timestamps */
|
||||
$timestamps = $this->call('getTimestamp');
|
||||
|
||||
return $timestamps;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getStorageKeys(): array
|
||||
{
|
||||
/** @var string[] $keys */
|
||||
$keys = $this->call('getStorageKey');
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getFlexKeys(): array
|
||||
{
|
||||
/** @var string[] $keys */
|
||||
$keys = $this->call('getFlexKey');
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::withKeyField()
|
||||
*/
|
||||
public function withKeyField(string $keyField = null)
|
||||
{
|
||||
$keyField = $keyField ?: 'key';
|
||||
if ($keyField === $this->getKeyField()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$entries = [];
|
||||
foreach ($this as $key => $object) {
|
||||
// TODO: remove hardcoded logic
|
||||
if ($keyField === 'storage_key') {
|
||||
$entries[$object->getStorageKey()] = $object;
|
||||
} elseif ($keyField === 'flex_key') {
|
||||
$entries[$object->getFlexKey()] = $object;
|
||||
} elseif ($keyField === 'key') {
|
||||
$entries[$object->getKey()] = $object;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->createFrom($entries, $keyField);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getIndex()
|
||||
*/
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->getFlexDirectory()->getIndex($this->getKeys(), $this->getKeyField());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::render()
|
||||
*/
|
||||
public function render($layout = null, array $context = [])
|
||||
{
|
||||
if (null === $layout) {
|
||||
$layout = 'default';
|
||||
}
|
||||
$type = $this->getFlexType();
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $grav['debugger'];
|
||||
$debugger->startTimer('flex-collection-' . ($debugKey = uniqid($this->getType(false), false)), 'Render Collection ' . $this->getType(false) . ' (' . $layout . ')');
|
||||
$debugger->startTimer('flex-collection-' . ($debugKey = uniqid($type, false)), 'Render Collection ' . $type . ' (' . $layout . ')');
|
||||
|
||||
$cache = $key = null;
|
||||
foreach ($context as $value) {
|
||||
@@ -229,8 +305,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
);
|
||||
|
||||
if ($debugger->enabled()) {
|
||||
$name = $this->getType(false);
|
||||
$output = "\n<!–– START {$name} collection ––>\n{$output}\n<!–– END {$name} collection ––>\n";
|
||||
$output = "\n<!–– START {$type} collection ––>\n{$output}\n<!–– END {$type} collection ––>\n";
|
||||
}
|
||||
|
||||
$block->setContent($output);
|
||||
@@ -247,6 +322,20 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
* @deprecated 1.6 Use `->getFlexType()` instead.
|
||||
*/
|
||||
public function getType($prefix = false)
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getFlexType() method instead', E_USER_DEPRECATED);
|
||||
|
||||
$type = $prefix ? $this->getTypePrefix() : '';
|
||||
|
||||
return $type . $this->getFlexType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlexDirectory $type
|
||||
* @return $this
|
||||
@@ -258,14 +347,6 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FlexDirectory
|
||||
*/
|
||||
public function getFlexDirectory() //: FlexDirectory
|
||||
{
|
||||
return $this->_flexDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -280,94 +361,11 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
* @param string|null $namespace
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public function getCache(string $namespace = null): CacheInterface
|
||||
public function getCache(string $namespace = null)
|
||||
{
|
||||
return $this->_flexDirectory->getCache($namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheKey()
|
||||
{
|
||||
return $this->getType(true) . '.' . sha1(json_encode($this->call('getKey')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheChecksum()
|
||||
{
|
||||
return sha1(json_encode($this->getTimestamps()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getTimestamps()
|
||||
{
|
||||
/** @var int[] $timestamps */
|
||||
$timestamps = $this->call('getTimestamp');
|
||||
|
||||
return $timestamps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getStorageKeys()
|
||||
{
|
||||
/** @var string[] $keys */
|
||||
$keys = $this->call('getStorageKey');
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getFlexKeys()
|
||||
{
|
||||
/** @var string[] $keys */
|
||||
$keys = $this->call('getFlexKey');
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FlexIndexInterface
|
||||
*/
|
||||
public function getIndex(): FlexIndexInterface
|
||||
{
|
||||
return $this->getFlexDirectory()->getIndex($this->getKeys(), $this->getKeyField());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface
|
||||
*/
|
||||
public function withKeyField(string $keyField = null): FlexCollectionInterface
|
||||
{
|
||||
$keyField = $keyField ?: 'key';
|
||||
if ($keyField === $this->getKeyField()) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$entries = [];
|
||||
foreach ($this as $key => $object) {
|
||||
// TODO: remove hardcoded logic
|
||||
if ($keyField === 'storage_key') {
|
||||
$entries[$object->getStorageKey()] = $object;
|
||||
} elseif ($keyField === 'flex_key') {
|
||||
$entries[$object->getFlexKey()] = $object;
|
||||
} elseif ($keyField === 'key') {
|
||||
$entries[$object->getKey()] = $object;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->createFrom($entries, $keyField);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@@ -427,20 +425,48 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
'type:private' => $this->getType(false),
|
||||
'type:private' => $this->getFlexType(),
|
||||
'key:private' => $this->getKey(),
|
||||
'objects_key:private' => $this->getKeyField(),
|
||||
'objects:private' => $this->getElements()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance from the specified elements.
|
||||
*
|
||||
* This method is provided for derived classes to specify how a new
|
||||
* instance should be created when constructor semantics have changed.
|
||||
*
|
||||
* @param array $elements Elements.
|
||||
* @param string|null $keyField
|
||||
*
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
protected function createFrom(array $elements, $keyField = null)
|
||||
{
|
||||
$collection = new static($elements, $this->_flexDirectory);
|
||||
$collection->setKeyField($keyField ?: $this->_keyField);
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTypePrefix(): string
|
||||
{
|
||||
return 'c.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $layout
|
||||
* @return TemplateWrapper
|
||||
* @throws LoaderError
|
||||
* @throws SyntaxError
|
||||
*/
|
||||
protected function getTemplate($layout) //: \Twig_Template
|
||||
protected function getTemplate($layout)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
@@ -448,7 +474,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
$twig = $grav['twig'];
|
||||
|
||||
try {
|
||||
return $twig->twig()->resolveTemplate(["flex-objects/layouts/{$this->getType(false)}/collection/{$layout}.html.twig"]);
|
||||
return $twig->twig()->resolveTemplate(["flex-objects/layouts/{$this->getFlexType()}/collection/{$layout}.html.twig"]);
|
||||
} catch (LoaderError $e) {
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = Grav::instance()['debugger'];
|
||||
@@ -470,7 +496,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
return $flex->getDirectory($type);
|
||||
}
|
||||
|
||||
protected function setKeyField($keyField = null)
|
||||
protected function setKeyField($keyField = null): void
|
||||
{
|
||||
$this->_keyField = $keyField ?? 'storage_key';
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ class FlexDirectory implements FlexAuthorizeInterface
|
||||
* @param string $context
|
||||
* @return Blueprint
|
||||
*/
|
||||
public function getBlueprint(string $type = '', string $context = ''): Blueprint
|
||||
public function getBlueprint(string $type = '', string $context = '')
|
||||
{
|
||||
$blueprint = $this->getBlueprintInternal($type, $context);
|
||||
|
||||
@@ -291,7 +291,7 @@ class FlexDirectory implements FlexAuthorizeInterface
|
||||
* @param string|null $namespace
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public function getCache(string $namespace = null): CacheInterface
|
||||
public function getCache(string $namespace = null)
|
||||
{
|
||||
$namespace = $namespace ?: 'index';
|
||||
$cache = $this->cache[$namespace] ?? null;
|
||||
@@ -332,7 +332,7 @@ class FlexDirectory implements FlexAuthorizeInterface
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function clearCache(): self
|
||||
public function clearCache()
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
@@ -553,7 +553,7 @@ class FlexDirectory implements FlexAuthorizeInterface
|
||||
* @param string $context
|
||||
* @return Blueprint
|
||||
*/
|
||||
protected function getBlueprintInternal(string $type_view = '', string $context = ''): Blueprint
|
||||
protected function getBlueprintInternal(string $type_view = '', string $context = '')
|
||||
{
|
||||
if (!isset($this->blueprints[$type_view])) {
|
||||
if (!file_exists($this->blueprint_file)) {
|
||||
|
||||
@@ -79,7 +79,7 @@ class FlexForm implements FlexFormInterface
|
||||
/**
|
||||
* @return Data|FlexObjectInterface
|
||||
*/
|
||||
public function getData(): \ArrayAccess
|
||||
public function getData()
|
||||
{
|
||||
return $this->data ?? $this->getObject();
|
||||
}
|
||||
@@ -189,11 +189,6 @@ class FlexForm implements FlexFormInterface
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getMediaRoute(): string
|
||||
{
|
||||
return '/' . $this->getObject()->getKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Serializable::unserialize().
|
||||
*
|
||||
|
||||
@@ -40,18 +40,16 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
* @param FlexDirectory $directory
|
||||
* @return static
|
||||
*/
|
||||
public static function createFromStorage(FlexDirectory $directory) : FlexCollectionInterface
|
||||
public static function createFromStorage(FlexDirectory $directory)
|
||||
{
|
||||
return static::createFromArray(static::loadEntriesFromStorage($directory->getStorage()), $directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array[] $entries
|
||||
* @param FlexDirectory $directory
|
||||
* @param string $keyField
|
||||
* @return static
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::createFromArray()
|
||||
*/
|
||||
public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null) : FlexCollectionInterface
|
||||
public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null)
|
||||
{
|
||||
$instance = new static($entries, $directory);
|
||||
$instance->setKeyField($keyField);
|
||||
@@ -63,7 +61,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
* @param FlexStorageInterface $storage
|
||||
* @return array
|
||||
*/
|
||||
public static function loadEntriesFromStorage(FlexStorageInterface $storage) : array
|
||||
public static function loadEntriesFromStorage(FlexStorageInterface $storage): array
|
||||
{
|
||||
return $storage->getExistingKeys();
|
||||
}
|
||||
@@ -72,58 +70,104 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
* Initializes a new FlexIndex.
|
||||
*
|
||||
* @param array $entries
|
||||
* @param FlexDirectory $flexDirectory
|
||||
* @param FlexDirectory|null $directory
|
||||
*/
|
||||
public function __construct(array $entries, FlexDirectory $flexDirectory)
|
||||
public function __construct(array $entries = [], FlexDirectory $directory = null)
|
||||
{
|
||||
parent::__construct($entries);
|
||||
|
||||
$this->_flexDirectory = $flexDirectory;
|
||||
$this->_flexDirectory = $directory;
|
||||
$this->setKeyField(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return FlexCollectionInterface
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::search()
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null) // : FlexCollectionInterface
|
||||
public function search(string $search, $properties = null, array $options = null)
|
||||
{
|
||||
return $this->__call('search', [$search, $properties, $options]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FlexDirectory
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::sort()
|
||||
*/
|
||||
public function getFlexDirectory() : FlexDirectory
|
||||
public function sort(array $orderings)
|
||||
{
|
||||
return $this->orderBy($orderings);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexType()
|
||||
*/
|
||||
public function getFlexType(): string
|
||||
{
|
||||
return $this->_flexDirectory->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getFlexDirectory(): FlexDirectory
|
||||
{
|
||||
return $this->_flexDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getTimestamp()
|
||||
*/
|
||||
public function getType($prefix = false)
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
$type = $prefix ? $this->getTypePrefix() : '';
|
||||
$timestamps = $this->getTimestamps();
|
||||
|
||||
return $type . $this->_flexDirectory->getType();
|
||||
return $timestamps ? max($timestamps) : time();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getCacheKey()
|
||||
*/
|
||||
public function getStorageKeys()
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
return $this->getTypePrefix() . $this->getFlexType() . '.' . sha1(json_encode($this->getKeys()) . $this->_keyField);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getCacheChecksum()
|
||||
*/
|
||||
public function getCacheChecksum(): string
|
||||
{
|
||||
return sha1($this->getCacheKey() . json_encode($this->getTimestamps()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getTimestamps()
|
||||
*/
|
||||
public function getTimestamps(): array
|
||||
{
|
||||
return $this->getIndexMap('storage_timestamp');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getStorageKeys()
|
||||
*/
|
||||
public function getStorageKeys(): array
|
||||
{
|
||||
return $this->getIndexMap('storage_key');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getFlexKeys()
|
||||
*/
|
||||
public function getFlexKeys()
|
||||
public function getFlexKeys(): array
|
||||
{
|
||||
// Get storage keys for the objects.
|
||||
$keys = [];
|
||||
@@ -137,53 +181,10 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
* {@inheritdoc}
|
||||
* @see FlexIndexInterface::withKeyField()
|
||||
*/
|
||||
public function getTimestamps()
|
||||
{
|
||||
return $this->getIndexMap('storage_timestamp');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function getIndex(): FlexIndexInterface
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $indexKey
|
||||
* @return array
|
||||
*/
|
||||
public function getIndexMap(string $indexKey = null)
|
||||
{
|
||||
if (null === $indexKey) {
|
||||
return $this->getEntries();
|
||||
}
|
||||
|
||||
// Get storage keys for the objects.
|
||||
$index = [];
|
||||
foreach ($this->getEntries() as $key => $value) {
|
||||
$index[$key] = $value[$indexKey] ?? null;
|
||||
}
|
||||
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaData(string $key) : array
|
||||
{
|
||||
return $this->getEntries()[$key] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyField
|
||||
* @return FlexCollectionInterface
|
||||
*/
|
||||
public function withKeyField(string $keyField = null): FlexCollectionInterface
|
||||
public function withKeyField(string $keyField = null)
|
||||
{
|
||||
$keyField = $keyField ?: 'key';
|
||||
if ($keyField === $this->getKeyField()) {
|
||||
@@ -207,6 +208,65 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
return $this->createFrom($entries, $keyField);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::getIndex()
|
||||
*/
|
||||
public function getIndex()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::render()
|
||||
*/
|
||||
public function render($layout = null, array $context = [])
|
||||
{
|
||||
return $this->__call('render', [$layout, $context]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
* @deprecated 1.6 Use `->getFlexType()` instead.
|
||||
*/
|
||||
public function getType($prefix = false)
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getFlexType() method instead', E_USER_DEPRECATED);
|
||||
|
||||
$type = $prefix ? $this->getTypePrefix() : '';
|
||||
|
||||
return $type . $this->getFlexType();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexIndexInterface::getFlexKeys()
|
||||
*/
|
||||
public function getIndexMap(string $indexKey = null)
|
||||
{
|
||||
if (null === $indexKey) {
|
||||
return $this->getEntries();
|
||||
}
|
||||
|
||||
// Get storage keys for the objects.
|
||||
$index = [];
|
||||
foreach ($this->getEntries() as $key => $value) {
|
||||
$index[$key] = $value[$indexKey] ?? null;
|
||||
}
|
||||
|
||||
return $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaData(string $key): array
|
||||
{
|
||||
return $this->getEntries()[$key] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@@ -219,27 +279,11 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
* @param string|null $namespace
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public function getCache(string $namespace = null): CacheInterface
|
||||
public function getCache(string $namespace = null)
|
||||
{
|
||||
return $this->_flexDirectory->getCache($namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheKey()
|
||||
{
|
||||
return $this->getType(true) . '.' . sha1(json_encode($this->getKeys()) . $this->_keyField);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheChecksum()
|
||||
{
|
||||
return sha1($this->getCacheKey() . json_encode($this->getTimestamps()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $orderings
|
||||
* @return FlexIndex|FlexCollection
|
||||
@@ -302,6 +346,8 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
$className = $this->_flexDirectory->getCollectionClass();
|
||||
$cachedMethods = $className::getCachedMethods();
|
||||
|
||||
$flexType = $this->getFlexType();
|
||||
|
||||
if (!empty($cachedMethods[$name])) {
|
||||
$type = $cachedMethods[$name];
|
||||
if ($type === 'session') {
|
||||
@@ -311,7 +357,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
} else {
|
||||
$cacheKey = '';
|
||||
}
|
||||
$key = $this->getType(true) . '.' . sha1($name . '.' . $cacheKey . json_encode($arguments) . $this->getCacheKey());
|
||||
$key = "{$flexType}.idx." . sha1($name . '.' . $cacheKey . json_encode($arguments) . $this->getCacheKey());
|
||||
|
||||
$cache = $this->getCache('object');
|
||||
|
||||
@@ -319,7 +365,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
$result = $cache->get($key);
|
||||
|
||||
// Make sure the keys aren't changed if the returned type is the same index type.
|
||||
if ($result instanceof self && $this->getType(true) === $result->getType(true)) {
|
||||
if ($result instanceof self && $flexType === $result->getFlexType()) {
|
||||
$result = $result->withKeyField($this->getKeyField());
|
||||
}
|
||||
} catch (InvalidArgumentException $e) {
|
||||
@@ -368,7 +414,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(['type' => $this->getType(false), 'entries' => $this->getEntries()]);
|
||||
return serialize(['type' => $this->getFlexType(), 'entries' => $this->getEntries()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,7 +422,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = unserialize($serialized);
|
||||
$data = unserialize($serialized, ['allowed_classes' => false]);
|
||||
|
||||
$this->_flexDirectory = Grav::instance()['flex_objects']->getDirectory($data['type']);
|
||||
$this->setEntries($data['entries']);
|
||||
@@ -637,7 +683,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
'type:private' => $this->getType(false),
|
||||
'type:private' => $this->getFlexType(),
|
||||
'key:private' => $this->getKey(),
|
||||
'entries_key:private' => $this->getKeyField(),
|
||||
'entries:private' => $this->getEntries()
|
||||
|
||||
@@ -10,15 +10,14 @@
|
||||
namespace Grav\Framework\Flex;
|
||||
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\ValidationException;
|
||||
use Grav\Common\Debugger;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Twig\Twig;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Cache\CacheInterface;
|
||||
use Grav\Framework\ContentBlock\ContentBlockInterface;
|
||||
use Grav\Framework\ContentBlock\HtmlBlock;
|
||||
use Grav\Framework\Flex\Interfaces\FlexAuthorizeInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexCollectionInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexFormInterface;
|
||||
use Grav\Framework\Flex\Traits\FlexAuthorizeTrait;
|
||||
use Grav\Framework\Object\Access\NestedArrayAccessTrait;
|
||||
@@ -26,6 +25,7 @@ use Grav\Framework\Object\Access\NestedPropertyTrait;
|
||||
use Grav\Framework\Object\Access\OverloadedPropertyTrait;
|
||||
use Grav\Framework\Object\Base\ObjectTrait;
|
||||
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
|
||||
use Grav\Framework\Object\Interfaces\ObjectInterface;
|
||||
use Grav\Framework\Object\Property\LazyPropertyTrait;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
@@ -60,11 +60,12 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getCachedMethods()
|
||||
public static function getCachedMethods(): array
|
||||
{
|
||||
return [
|
||||
'getTypePrefix' => true,
|
||||
'getType' => true,
|
||||
'getFlexType' => true,
|
||||
'getFlexDirectory' => true,
|
||||
'getCacheKey' => true,
|
||||
'getCacheChecksum' => true,
|
||||
@@ -79,25 +80,21 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
];
|
||||
}
|
||||
|
||||
public static function createFromStorage(array $elements, array $storage, FlexDirectory $flexDirectory, $validate = false)
|
||||
public static function createFromStorage(array $elements, array $storage, FlexDirectory $directory, bool $validate = false)
|
||||
{
|
||||
$instance = new static($elements, $storage['key'], $flexDirectory, $validate);
|
||||
$instance = new static($elements, $storage['key'], $directory, $validate);
|
||||
$instance->setStorage($storage);
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
* @param FlexDirectory $flexDirectory
|
||||
* @param bool $validate
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws ValidationException
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::__construct()
|
||||
*/
|
||||
public function __construct(array $elements, $key, FlexDirectory $flexDirectory, $validate = false)
|
||||
public function __construct(array $elements, $key, FlexDirectory $directory, bool $validate = false)
|
||||
{
|
||||
$this->_flexDirectory = $flexDirectory;
|
||||
$this->_flexDirectory = $directory;
|
||||
|
||||
if ($validate) {
|
||||
$blueprint = $this->getFlexDirectory()->getBlueprint();
|
||||
@@ -113,10 +110,53 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return float
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getFlexType()
|
||||
*/
|
||||
public function getFlexType(): string
|
||||
{
|
||||
return $this->_flexDirectory->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getFlexDirectory()
|
||||
*/
|
||||
public function getFlexDirectory(): FlexDirectory
|
||||
{
|
||||
return $this->_flexDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getTimestamp()
|
||||
*/
|
||||
public function getTimestamp(): int
|
||||
{
|
||||
return $this->_storage['storage_timestamp'] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getCacheKey()
|
||||
*/
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
return $this->getTypePrefix() . $this->getFlexType() . '.' . $this->getStorageKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getCacheChecksum()
|
||||
*/
|
||||
public function getCacheChecksum(): string
|
||||
{
|
||||
return (string)$this->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::search()
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null): float
|
||||
{
|
||||
@@ -131,6 +171,53 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
return $weight > 0 ? min($weight, 1) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see ObjectInterface::getFlexKey()
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->_key ?: $this->getFlexType() . '@@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getFlexKey()
|
||||
*/
|
||||
public function getFlexKey(): string
|
||||
{
|
||||
return $this->_storage['flex_key'] ?? $this->_flexDirectory->getType() . '.obj:' . $this->getStorageKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getStorageKey()
|
||||
*/
|
||||
public function getStorageKey(): string
|
||||
{
|
||||
return $this->_storage['storage_key'] ?? $this->getTypePrefix() . $this->getFlexType() . '@@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getMetaData()
|
||||
*/
|
||||
public function getMetaData(): array
|
||||
{
|
||||
return $this->getStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::exists()
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
$key = $this->getStorageKey();
|
||||
|
||||
return $key && $this->getFlexDirectory()->getStorage()->hasKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param string $search
|
||||
@@ -192,56 +279,12 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $files
|
||||
* @return $this
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function update(array $data, array $files = [])
|
||||
{
|
||||
if ($data) {
|
||||
$blueprint = $this->getBlueprint();
|
||||
|
||||
// Process updated data through the object filters.
|
||||
$this->filterElements($data);
|
||||
|
||||
// Get currently stored data.
|
||||
$elements = $this->getElements();
|
||||
|
||||
// Merge existing object to the test data to be validated.
|
||||
$test = $blueprint->mergeData($elements, $data);
|
||||
|
||||
// Validate and filter elements and throw an error if any issues were found.
|
||||
$blueprint->validate($test + ['storage_key' => $this->getStorageKey(), 'timestamp' => $this->getTimestamp()]);
|
||||
$data = $blueprint->filter($data, false, true);
|
||||
|
||||
// Finally update the object.
|
||||
foreach ($blueprint->flattenData($data) as $key => $value) {
|
||||
if ($value === null) {
|
||||
$this->unsetNestedProperty($key);
|
||||
} else {
|
||||
$this->setNestedProperty($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the changes
|
||||
$this->_changes = Utils::arrayDiffMultidimensional($this->getElements(), $elements);
|
||||
}
|
||||
|
||||
if ($files && method_exists($this, 'setUpdatedMedia')) {
|
||||
$this->setUpdatedMedia($files);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any changes based on data sent to update
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChanges()
|
||||
public function getChanges(): array
|
||||
{
|
||||
return $this->_changes ?? [];
|
||||
}
|
||||
@@ -249,7 +292,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTypePrefix()
|
||||
protected function getTypePrefix(): string
|
||||
{
|
||||
return 'o.';
|
||||
}
|
||||
@@ -257,43 +300,15 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @param bool $prefix
|
||||
* @return string
|
||||
* @deprecated 1.6 Use `->getFlexType()` instead.
|
||||
*/
|
||||
public function getType($prefix = false)
|
||||
{
|
||||
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use ->getFlexType() method instead', E_USER_DEPRECATED);
|
||||
|
||||
$type = $prefix ? $this->getTypePrefix() : '';
|
||||
|
||||
return $type . $this->_flexDirectory->getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FlexDirectory
|
||||
*/
|
||||
public function getFlexDirectory() : FlexDirectory
|
||||
{
|
||||
return $this->_flexDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array|null $form
|
||||
* @return FlexFormInterface
|
||||
*/
|
||||
public function getForm(string $name = '', array $form = null): FlexFormInterface
|
||||
{
|
||||
if (!isset($this->_forms[$name])) {
|
||||
$this->_forms[$name] = $this->createFormObject($name, $form);
|
||||
}
|
||||
|
||||
return $this->_forms[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return Blueprint
|
||||
*/
|
||||
public function getBlueprint(string $name = '')
|
||||
{
|
||||
return $this->_flexDirectory->getBlueprint($name ? '.' . $name : $name);
|
||||
return $type . $this->getFlexType();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,57 +322,15 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
return $this->getBlueprint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFlexKey()
|
||||
{
|
||||
return $this->_storage['flex_key'] ?? $this->_flexDirectory->getType() . '.obj:' . $this->getStorageKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $namespace
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public function getCache(string $namespace = null): CacheInterface
|
||||
public function getCache(string $namespace = null)
|
||||
{
|
||||
return $this->_flexDirectory->getCache($namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheKey()
|
||||
{
|
||||
return $this->getType(true) . '.' . $this->getStorageKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheChecksum()
|
||||
{
|
||||
return (string)$this->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaData()
|
||||
{
|
||||
return $this->getStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStorageKey()
|
||||
{
|
||||
return $this->_storage['storage_key'] ?? $this->getType(true) . '@@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $key
|
||||
* @return $this
|
||||
@@ -369,14 +342,6 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestamp() : int
|
||||
{
|
||||
return $this->_storage['storage_timestamp'] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $timestamp
|
||||
* @return $this
|
||||
@@ -389,15 +354,8 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Twig example: {% render object layout 'edit' with {my_check: true} %}
|
||||
*
|
||||
* @param string $layout
|
||||
* @param array $context
|
||||
* @return ContentBlockInterface|HtmlBlock
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
* @throws LoaderError
|
||||
* @throws SyntaxError
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::render()
|
||||
*/
|
||||
public function render($layout = null, array $context = [])
|
||||
{
|
||||
@@ -405,11 +363,13 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
$layout = 'default';
|
||||
}
|
||||
|
||||
$type = $this->getFlexType();
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $grav['debugger'];
|
||||
$debugger->startTimer('flex-object-' . ($debugKey = uniqid($this->getType(false), false)), 'Render Object ' . $this->getType(false) . ' (' . $layout . ')');
|
||||
$debugger->startTimer('flex-object-' . ($debugKey = uniqid($type, false)), 'Render Object ' . $type . ' (' . $layout . ')');
|
||||
|
||||
$cache = $key = null;
|
||||
foreach ($context as $value) {
|
||||
@@ -460,7 +420,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
);
|
||||
|
||||
if ($debugger->enabled()) {
|
||||
$name = $this->getKey() . ' (' . $this->getType(false) . ')';
|
||||
$name = $this->getKey() . ' (' . $type . ')';
|
||||
$output = "\n<!–– START {$name} object ––>\n{$output}\n<!–– END {$name} object ––>\n";
|
||||
}
|
||||
|
||||
@@ -478,36 +438,6 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form field compatibility.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @param string $separator
|
||||
* @return mixed
|
||||
*/
|
||||
public function value($name, $default = null, $separator = null)
|
||||
{
|
||||
if ($name === 'storage_key') {
|
||||
return $this->getStorageKey();
|
||||
}
|
||||
if ($name === 'storage_timestamp') {
|
||||
return $this->getTimestamp();
|
||||
}
|
||||
|
||||
return $this->getNestedProperty($name, $default, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function exists()
|
||||
{
|
||||
$key = $this->getStorageKey();
|
||||
|
||||
return $key && $this->getFlexDirectory()->getStorage()->hasKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -517,9 +447,10 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::prepareStorage()
|
||||
*/
|
||||
public function prepareStorage()
|
||||
public function prepareStorage(): array
|
||||
{
|
||||
return $this->getElements();
|
||||
}
|
||||
@@ -534,10 +465,50 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new object into storage.
|
||||
*
|
||||
* @param string|null $key Optional new key.
|
||||
* @return $this
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::update()
|
||||
*/
|
||||
public function update(array $data, array $files = [])
|
||||
{
|
||||
if ($data) {
|
||||
$blueprint = $this->getBlueprint();
|
||||
|
||||
// Process updated data through the object filters.
|
||||
$this->filterElements($data);
|
||||
|
||||
// Get currently stored data.
|
||||
$elements = $this->getElements();
|
||||
|
||||
// Merge existing object to the test data to be validated.
|
||||
$test = $blueprint->mergeData($elements, $data);
|
||||
|
||||
// Validate and filter elements and throw an error if any issues were found.
|
||||
$blueprint->validate($test + ['storage_key' => $this->getStorageKey(), 'timestamp' => $this->getTimestamp()]);
|
||||
$data = $blueprint->filter($data, false, true);
|
||||
|
||||
// Finally update the object.
|
||||
foreach ($blueprint->flattenData($data) as $key => $value) {
|
||||
if ($value === null) {
|
||||
$this->unsetNestedProperty($key);
|
||||
} else {
|
||||
$this->setNestedProperty($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the changes
|
||||
$this->_changes = Utils::arrayDiffMultidimensional($this->getElements(), $elements);
|
||||
}
|
||||
|
||||
if ($files && method_exists($this, 'setUpdatedMedia')) {
|
||||
$this->setUpdatedMedia($files);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::create()
|
||||
*/
|
||||
public function create($key = null)
|
||||
{
|
||||
@@ -553,7 +524,8 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::save()
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
@@ -593,7 +565,8 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::delete()
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
@@ -619,6 +592,44 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getBlueprint()
|
||||
*/
|
||||
public function getBlueprint(string $name = '')
|
||||
{
|
||||
return $this->_flexDirectory->getBlueprint($name ? '.' . $name : $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::getForm()
|
||||
*/
|
||||
public function getForm(string $name = '', array $form = null)
|
||||
{
|
||||
if (!isset($this->_forms[$name])) {
|
||||
$this->_forms[$name] = $this->createFormObject($name, $form);
|
||||
}
|
||||
|
||||
return $this->_forms[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexObjectInterface::value()
|
||||
*/
|
||||
public function value($name, $default = null, $separator = null)
|
||||
{
|
||||
if ($name === 'storage_key') {
|
||||
return $this->getStorageKey();
|
||||
}
|
||||
if ($name === 'storage_timestamp') {
|
||||
return $this->getTimestamp();
|
||||
}
|
||||
|
||||
return $this->getNestedProperty($name, $default, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
@@ -632,7 +643,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
'type:private' => $this->getType(false),
|
||||
'type:private' => $this->getFlexType(),
|
||||
'key:private' => $this->getKey(),
|
||||
'elements:private' => $this->getElements(),
|
||||
'storage:private' => $this->getStorage()
|
||||
@@ -642,10 +653,10 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function doSerialize()
|
||||
protected function doSerialize(): array
|
||||
{
|
||||
return [
|
||||
'type' => $this->getType(false),
|
||||
'type' => $this->getFlexType(),
|
||||
'key' => $this->getKey(),
|
||||
'elements' => $this->getElements(),
|
||||
'storage' => $this->getStorage()
|
||||
@@ -655,7 +666,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @param array $serialized
|
||||
*/
|
||||
protected function doUnserialize(array $serialized)
|
||||
protected function doUnserialize(array $serialized): void
|
||||
{
|
||||
$type = $serialized['type'] ?? 'unknown';
|
||||
|
||||
@@ -679,7 +690,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @param FlexDirectory $directory
|
||||
*/
|
||||
public function setFlexDirectory(FlexDirectory $directory)
|
||||
public function setFlexDirectory(FlexDirectory $directory): void
|
||||
{
|
||||
$this->_flexDirectory = $directory;
|
||||
}
|
||||
@@ -702,7 +713,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $property
|
||||
* @return FlexCollection
|
||||
* @return FlexCollectionInterface
|
||||
*/
|
||||
protected function getCollectionByProperty($type, $property)
|
||||
{
|
||||
@@ -721,7 +732,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
* @return FlexDirectory
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function getRelatedDirectory($type)
|
||||
protected function getRelatedDirectory($type): FlexDirectory
|
||||
{
|
||||
/** @var Flex $flex */
|
||||
$flex = Grav::instance()['flex_objects'];
|
||||
@@ -747,7 +758,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
$twig = $grav['twig'];
|
||||
|
||||
try {
|
||||
return $twig->twig()->resolveTemplate(["flex-objects/layouts/{$this->getType(false)}/object/{$layout}.html.twig"]);
|
||||
return $twig->twig()->resolveTemplate(["flex-objects/layouts/{$this->getFlexType()}/object/{$layout}.html.twig"]);
|
||||
} catch (LoaderError $e) {
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = Grav::instance()['debugger'];
|
||||
@@ -764,7 +775,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
*
|
||||
* @param array $elements
|
||||
*/
|
||||
protected function filterElements(array &$elements)
|
||||
protected function filterElements(array &$elements): void
|
||||
{
|
||||
if (!empty($elements['storage_key'])) {
|
||||
$this->_storage['storage_key'] = trim($elements['storage_key']);
|
||||
@@ -783,7 +794,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
* @param array|null $form Form fields
|
||||
* @return FlexFormInterface
|
||||
*/
|
||||
protected function createFormObject(string $name, array $form = null): FlexFormInterface
|
||||
protected function createFormObject(string $name, array $form = null)
|
||||
{
|
||||
return new FlexForm($name, $this, $form);
|
||||
}
|
||||
|
||||
@@ -14,16 +14,19 @@ namespace Grav\Framework\Flex\Interfaces;
|
||||
use Grav\Common\User\Interfaces\UserInterface;
|
||||
|
||||
/**
|
||||
* Interface FlexAuthorizeInterface
|
||||
* @package Grav\Framework\User\Interfaces
|
||||
* Defines authorization checks for Flex Objects.
|
||||
*/
|
||||
interface FlexAuthorizeInterface
|
||||
{
|
||||
/**
|
||||
* @param string $action One of: create, read, update, delete, save, list
|
||||
* @param string|null $scope One of: admin, site
|
||||
* @param UserInterface|null $user
|
||||
* @return bool
|
||||
* Check if user is authorized to perform an action for the object.
|
||||
*
|
||||
* @param string $action One of: `create`, `read`, `update`, `delete`, `save`, `list`
|
||||
* @param string|null $scope One of: `admin`, `site`
|
||||
* @param UserInterface|null $user Optional user. Defaults to the current user.
|
||||
*
|
||||
* @return bool Returns `true` if user is authorized to perform action, `false` otherwise.
|
||||
* @api
|
||||
*/
|
||||
public function isAuthorized(string $action, string $scope = null, UserInterface $user = null) : bool;
|
||||
public function isAuthorized(string $action, string $scope = null, UserInterface $user = null): bool;
|
||||
}
|
||||
|
||||
@@ -11,53 +11,106 @@ declare(strict_types=1);
|
||||
|
||||
namespace Grav\Framework\Flex\Interfaces;
|
||||
|
||||
use Grav\Framework\Flex\Flex;
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
use Grav\Framework\Object\Interfaces\ObjectCollectionInterface;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
|
||||
/**
|
||||
* Interface FlexCollectionInterface
|
||||
* @package Grav\Framework\Flex\Interfaces
|
||||
* Defines a collection of Flex Objects.
|
||||
*
|
||||
* @used-by \Grav\Framework\Flex\FlexCollection
|
||||
* @since 1.6
|
||||
*/
|
||||
interface FlexCollectionInterface extends ObjectCollectionInterface, NestedObjectInterface
|
||||
interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionInterface, NestedObjectInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $entries
|
||||
* @param FlexDirectory $directory
|
||||
* @param string $keyField
|
||||
* @return static
|
||||
* Creates a Flex Collection from an array.
|
||||
*
|
||||
* @used-by FlexDirectory::createCollection() Official method to create a Flex Collection.
|
||||
*
|
||||
* @param FlexObjectInterface[] $entries Associated array of Flex Objects to be included in the collection.
|
||||
* @param FlexDirectory $directory Flex Directory where all the objects belong into.
|
||||
* @param string $keyField Key field used to index the collection.
|
||||
*
|
||||
* @return static Returns a new Flex Collection.
|
||||
*/
|
||||
public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null) : FlexCollectionInterface;
|
||||
public static function createFromArray(array $entries, FlexDirectory $directory, string $keyField = null);
|
||||
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param FlexDirectory $type
|
||||
* Creates a new Flex Collection.
|
||||
*
|
||||
* @used-by FlexDirectory::createCollection() Official method to create Flex Collection.
|
||||
*
|
||||
* @param FlexObjectInterface[] $entries Associated array of Flex Objects to be included in the collection.
|
||||
* @param FlexDirectory $directory Flex Directory where all the objects belong into.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $elements, FlexDirectory $type);
|
||||
public function __construct(array $entries = [], FlexDirectory $directory = null);
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return FlexCollectionInterface
|
||||
* Search a string from the collection.
|
||||
*
|
||||
* @param string $search Search string.
|
||||
* @param string|string[]|null $properties Properties to search for, defaults to configured properties.
|
||||
* @param array|null $options Search options, defaults to configured options.
|
||||
*
|
||||
* @return FlexCollectionInterface Returns a Flex Collection with only matching objects.
|
||||
* @api
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null); // : FlexCollection
|
||||
public function search(string $search, $properties = null, array $options = null);
|
||||
|
||||
/**
|
||||
* @return FlexDirectory
|
||||
* Sort the collection.
|
||||
*
|
||||
* @param array $orderings Pair of [property => 'ASC'|'DESC', ...].
|
||||
*
|
||||
* @return FlexCollectionInterface Returns a sorted version from the collection.
|
||||
*/
|
||||
public function getFlexDirectory(); //: FlexDirectory;
|
||||
public function sort(array $orderings);
|
||||
|
||||
/**
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface
|
||||
* Get timestamps from all the objects in the collection.
|
||||
*
|
||||
* This method can be used for example in caching.
|
||||
*
|
||||
* @return int[] Returns [key => timestamp, ...] pairs.
|
||||
*/
|
||||
public function withKeyField(string $keyField = null): FlexCollectionInterface;
|
||||
public function getTimestamps(): array;
|
||||
|
||||
/**
|
||||
* @return FlexIndexInterface
|
||||
* Get storage keys from all the objects in the collection.
|
||||
*
|
||||
* @see FlexDirectory::getObject() If you want to get Flex Object from the Flex Directory.
|
||||
*
|
||||
* @return string[] Returns [key => storage_key, ...] pairs.
|
||||
*/
|
||||
public function getIndex(): FlexIndexInterface;
|
||||
public function getStorageKeys(): array;
|
||||
|
||||
/**
|
||||
* Get Flex keys from all the objects in the collection.
|
||||
*
|
||||
* @see Flex::getObjects() If you want to get list of Flex Objects from any Flex Directory.
|
||||
*
|
||||
* @return string[] Returns[key => flex_key, ...] pairs.
|
||||
*/
|
||||
public function getFlexKeys(): array;
|
||||
|
||||
/**
|
||||
* Return new collection with a different key.
|
||||
*
|
||||
* @param string|null $keyField Switch key field of the collection.
|
||||
*
|
||||
* @return FlexCollectionInterface Returns a new Flex Collection with new key field.
|
||||
* @api
|
||||
*/
|
||||
public function withKeyField(string $keyField = null);
|
||||
|
||||
/**
|
||||
* Get Flex Index from the Flex Collection.
|
||||
*
|
||||
* @return FlexIndexInterface Returns a Flex Index from the current collection.
|
||||
*/
|
||||
public function getIndex();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Flex\Interfaces;
|
||||
|
||||
use Grav\Framework\ContentBlock\ContentBlockInterface;
|
||||
use Grav\Framework\ContentBlock\HtmlBlock;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
use Twig\Error\LoaderError;
|
||||
use Twig\Error\SyntaxError;
|
||||
|
||||
/**
|
||||
* Defines common interface shared with both Flex Objects and Collections.
|
||||
*
|
||||
* @used-by \Grav\Framework\Flex\FlexObject
|
||||
* @since 1.6
|
||||
*/
|
||||
interface FlexCommonInterface
|
||||
{
|
||||
/**
|
||||
* Get Flex Type of the object / collection.
|
||||
*
|
||||
* @return string Returns Flex Type of the collection.
|
||||
* @api
|
||||
*/
|
||||
public function getFlexType(): string;
|
||||
|
||||
/**
|
||||
* Get Flex Directory for the object / collection.
|
||||
*
|
||||
* @return FlexDirectory Returns associated Flex Directory.
|
||||
* @api
|
||||
*/
|
||||
public function getFlexDirectory(): FlexDirectory;
|
||||
|
||||
/**
|
||||
* Get last updated timestamp for the object / collection.
|
||||
*
|
||||
* @return int Returns Unix timestamp.
|
||||
* @api
|
||||
*/
|
||||
public function getTimestamp(): int;
|
||||
|
||||
/**
|
||||
* Get a cache key which is used for caching the object / collection.
|
||||
*
|
||||
* @return string Returns cache key.
|
||||
*/
|
||||
public function getCacheKey(): string;
|
||||
|
||||
/**
|
||||
* Get cache checksum for the object / collection.
|
||||
*
|
||||
* If checksum changes, cache gets invalided.
|
||||
*
|
||||
* @return string Returns cache checksum.
|
||||
*/
|
||||
public function getCacheChecksum(): string;
|
||||
|
||||
/**
|
||||
* Renders the object / collection.
|
||||
*
|
||||
* @example {% render object layout 'edit' with { limited: true } %}
|
||||
* @example {% render collection layout 'list' %}
|
||||
*
|
||||
* @param string $layout Layout name.
|
||||
* @param array $context Context given to the renderer.
|
||||
*
|
||||
* @return ContentBlockInterface|HtmlBlock Returns `HtmlBlock` containing the rendered output.
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
* @throws LoaderError
|
||||
* @throws SyntaxError
|
||||
* @api
|
||||
*/
|
||||
public function render($layout = null, array $context = []);
|
||||
}
|
||||
@@ -13,35 +13,42 @@ use Grav\Framework\Form\Interfaces\FormInterface;
|
||||
use Grav\Framework\Route\Route;
|
||||
|
||||
/**
|
||||
* Class FlexForm
|
||||
* @package Grav\Framework\Flex
|
||||
* Defines Forms for Flex Objects.
|
||||
*
|
||||
* @used-by \Grav\Framework\Flex\FlexForm
|
||||
* @since 1.6
|
||||
*/
|
||||
interface FlexFormInterface extends \Serializable, FormInterface
|
||||
{
|
||||
/**
|
||||
* @return FlexObjectInterface
|
||||
* Get object associated to the form.
|
||||
*
|
||||
* @return FlexObjectInterface Returns Flex Object associated to the form.
|
||||
* @api
|
||||
*/
|
||||
public function getObject(): FlexObjectInterface;
|
||||
public function getObject();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* Get media task route.
|
||||
*
|
||||
* @return string Returns admin route for media tasks.
|
||||
*/
|
||||
public function getMediaTaskRoute(): string;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* Get route for uploading files by AJAX.
|
||||
*
|
||||
* @return Route|null Returns Route object or null if file uploads are not enabled.
|
||||
*/
|
||||
public function getMediaRoute(): string;
|
||||
public function getFileUploadAjaxRoute();
|
||||
|
||||
/**
|
||||
* @return Route|null
|
||||
* Get route for deleting files by AJAX.
|
||||
*
|
||||
* @param string $field Field where the file is associated into.
|
||||
* @param string $filename Filename for the file.
|
||||
*
|
||||
* @return Route|null Returns Route object or null if file uploads are not enabled.
|
||||
*/
|
||||
public function getFileUploadAjaxRoute(): ?Route;
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @param string $filename
|
||||
* @return Route|null
|
||||
*/
|
||||
public function getFileDeleteAjaxRoute($field, $filename): ?Route;
|
||||
public function getFileDeleteAjaxRoute($field, $filename);
|
||||
}
|
||||
|
||||
@@ -14,20 +14,51 @@ namespace Grav\Framework\Flex\Interfaces;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
|
||||
/**
|
||||
* Interface FlexCollectionInterface
|
||||
* @package Grav\Framework\Flex\Interfaces
|
||||
* Defines Indexes for Flex Objects.
|
||||
*
|
||||
* Flex indexes are similar to database indexes, they contain indexed fields which can be used to quickly look up or
|
||||
* find the objects without loading them.
|
||||
*
|
||||
* @used-by \Grav\Framework\Flex\FlexIndex
|
||||
* @since 1.6
|
||||
*/
|
||||
interface FlexIndexInterface extends FlexCollectionInterface
|
||||
{
|
||||
/**
|
||||
* @param FlexDirectory $directory
|
||||
* @return static
|
||||
* Helper method to create Flex Index.
|
||||
*
|
||||
* @used-by FlexDirectory::getIndex() Official method to get Index from a Flex Directory.
|
||||
*
|
||||
* @param FlexDirectory $directory Flex directory.
|
||||
*
|
||||
* @return static Returns a new Flex Index.
|
||||
*/
|
||||
public static function createFromStorage(FlexDirectory $directory) : FlexCollectionInterface;
|
||||
public static function createFromStorage(FlexDirectory $directory);
|
||||
|
||||
/**
|
||||
* @param FlexStorageInterface $storage
|
||||
* Method to load index from the object storage, usually filesystem.
|
||||
*
|
||||
* @used-by FlexDirectory::getIndex() Official method to get Index from a Flex Directory.
|
||||
*
|
||||
* @param FlexStorageInterface $storage Flex Storage associated to the directory.
|
||||
*
|
||||
* @return array Returns a list of existing objects [storage_key => [storage_key => xxx, storage_timestamp => 123456, ...]]
|
||||
*/
|
||||
public static function loadEntriesFromStorage(FlexStorageInterface $storage): array;
|
||||
|
||||
/**
|
||||
* Return new collection with a different key.
|
||||
*
|
||||
* @param string|null $keyField Switch key field of the collection.
|
||||
*
|
||||
* @return FlexIndexInterface Returns a new Flex Collection with new key field.
|
||||
* @api
|
||||
*/
|
||||
public function withKeyField(string $keyField = null);
|
||||
|
||||
/**
|
||||
* @param string $indexKey
|
||||
* @return array
|
||||
*/
|
||||
public static function loadEntriesFromStorage(FlexStorageInterface $storage) : array;
|
||||
public function getIndexMap(string $indexKey = null);
|
||||
}
|
||||
|
||||
@@ -12,141 +12,173 @@ declare(strict_types=1);
|
||||
namespace Grav\Framework\Flex\Interfaces;
|
||||
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Framework\ContentBlock\HtmlBlock;
|
||||
use Grav\Framework\Flex\FlexForm;
|
||||
use Grav\Framework\Flex\Flex;
|
||||
use Grav\Framework\Object\Interfaces\NestedObjectInterface;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
||||
/**
|
||||
* Interface FlexObjectInterface
|
||||
* @package Grav\Framework\Flex\Interfaces
|
||||
* Defines Flex Objects.
|
||||
*
|
||||
* @used-by \Grav\Framework\Flex\FlexObject
|
||||
* @since 1.6
|
||||
*/
|
||||
interface FlexObjectInterface extends NestedObjectInterface, \ArrayAccess
|
||||
interface FlexObjectInterface extends FlexCommonInterface, NestedObjectInterface, \ArrayAccess
|
||||
{
|
||||
/**
|
||||
* @param array $elements
|
||||
* @param string $key
|
||||
* @param FlexDirectory $type
|
||||
* Construct a new Flex Object instance.
|
||||
*
|
||||
* @used-by FlexDirectory::createObject() Method to create Flex Object.
|
||||
*
|
||||
* @param array $elements Array of object properties.
|
||||
* @param string $key Identifier key for the new object.
|
||||
* @param FlexDirectory $directory Flex Directory the object belongs into.
|
||||
* @param bool $validate True if the object should be validated against blueprint.
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $elements, $key, FlexDirectory $type);
|
||||
public function __construct(array $elements, $key, FlexDirectory $directory, bool $validate = false);
|
||||
|
||||
/**
|
||||
* Search object, returns weight between 0 and 1.
|
||||
* Search a string from the object, returns weight between 0 and 1.
|
||||
*
|
||||
* Note: If you override this function, make sure you return value in range 0...1!
|
||||
*
|
||||
* @param string $search
|
||||
* @param string|string[]|null $properties
|
||||
* @param array|null $options
|
||||
* @return float Weight between 0...1
|
||||
* @used-by FlexCollectionInterface::search() If you want to search a string from a Flex Collection.
|
||||
*
|
||||
* @param string $search Search string.
|
||||
* @param string|string[]|null $properties Properties to search for, defaults to configured properties.
|
||||
* @param array|null $options Search options, defaults to configured options.
|
||||
*
|
||||
* @return float Returns a weight between 0 and 1.
|
||||
* @api
|
||||
*/
|
||||
public function search(string $search, $properties = null, array $options = null): float;
|
||||
|
||||
/**
|
||||
* Returns the directory where the object belongs into.
|
||||
* Get a unique key for the object.
|
||||
*
|
||||
* @return FlexDirectory
|
||||
*/
|
||||
public function getFlexDirectory() : FlexDirectory;
|
||||
|
||||
/**
|
||||
* Returns a unique key for this object.
|
||||
* Flex Keys can be used without knowing the Directory the Object belongs into.
|
||||
*
|
||||
* @see Flex::getObject() If you want to get Flex Object from any Flex Directory.
|
||||
* @see Flex::getObjects() If you want to get list of Flex Objects from any Flex Directory.
|
||||
*
|
||||
* NOTE: Please do not override the method!
|
||||
*
|
||||
* @return string
|
||||
* @return string Returns Flex Key of the object.
|
||||
* @api
|
||||
*/
|
||||
public function getFlexKey();
|
||||
public function getFlexKey(): string;
|
||||
|
||||
/**
|
||||
* Returns a storage key which is used for figuring out the filename or database id.
|
||||
* Get an unique storage key (within the directory) which is used for figuring out the filename or database id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStorageKey();
|
||||
|
||||
/**
|
||||
* Returns a cache key which is used for caching the object.
|
||||
* @see FlexDirectory::getObject() If you want to get Flex Object from the Flex Directory.
|
||||
* @see FlexDirectory::getCollection() If you want to get Flex Collection with selected keys from the Flex Directory.
|
||||
*
|
||||
* @return string
|
||||
* @return string Returns storage key of the Object.
|
||||
* @api
|
||||
*/
|
||||
public function getCacheKey();
|
||||
public function getStorageKey(): string;
|
||||
|
||||
/**
|
||||
* Returns cache checksum for the object. If checksum changes, cache gets invalided.
|
||||
* Get index data associated to the object.
|
||||
*
|
||||
* @return string
|
||||
* @return array Returns metadata of the object.
|
||||
*/
|
||||
public function getCacheChecksum();
|
||||
|
||||
/**
|
||||
* Returns a last updated timestamp for the object.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTimestamp() : int;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaData();
|
||||
public function getMetaData(): array;
|
||||
|
||||
/**
|
||||
* Returns true if the object exists in the storage.
|
||||
*
|
||||
* @return bool
|
||||
* @return bool Returns `true` if the object exists, `false` otherwise.
|
||||
* @api
|
||||
*/
|
||||
public function exists();
|
||||
public function exists(): bool;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* Prepare object for saving into the storage.
|
||||
*
|
||||
* @return array Returns an array of object properties containing only scalars and arrays.
|
||||
*/
|
||||
public function prepareStorage();
|
||||
public function prepareStorage(): array;
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $files
|
||||
* @return $this
|
||||
* Updates object in the memory.
|
||||
*
|
||||
* @see FlexObjectInterface::save() You need to save the object after calling this method.
|
||||
*
|
||||
* @param array $data Data containing updated properties with their values. To unset a value, use `null`.
|
||||
* @param array|UploadedFileInterface[] $files List of uploaded files to be saved within the object.
|
||||
*
|
||||
* @return FlexObjectInterface
|
||||
* @throws \RuntimeException
|
||||
* @api
|
||||
*/
|
||||
public function update(array $data, array $files = []);
|
||||
|
||||
/**
|
||||
* Returns the blueprint for the object.
|
||||
* Create new object into the storage.
|
||||
*
|
||||
* @param string $name
|
||||
* @return Blueprint
|
||||
* @see FlexDirectory::createObject() If you want to create a new object instance.
|
||||
* @see FlexObjectInterface::update() If you want to update properties of the object.
|
||||
*
|
||||
* @param string|null $key Optional new key. If key isn't given, random key will be associated to the object.
|
||||
*
|
||||
* @return FlexObjectInterface
|
||||
* @throws \RuntimeException if object already exists.
|
||||
* @api
|
||||
*/
|
||||
public function create($key = null);
|
||||
|
||||
/**
|
||||
* Save object into the storage.
|
||||
*
|
||||
* @see FlexObjectInterface::update() If you want to update properties of the object.
|
||||
*
|
||||
* @return FlexObjectInterface
|
||||
* @api
|
||||
*/
|
||||
public function save();
|
||||
|
||||
/**
|
||||
* Delete object from the storage.
|
||||
*
|
||||
* @return FlexObjectInterface
|
||||
* @api
|
||||
*/
|
||||
public function delete();
|
||||
|
||||
/**
|
||||
* Returns the blueprint of the object.
|
||||
*
|
||||
* @see FlexObjectInterface::getForm()
|
||||
* @used-by FlexForm::getBlueprint()
|
||||
*
|
||||
* @param string $name Name of the Blueprint form. Used to create customized forms for different use cases.
|
||||
*
|
||||
* @return Blueprint Returns a Blueprint.
|
||||
*/
|
||||
public function getBlueprint(string $name = '');
|
||||
|
||||
/**
|
||||
* Returns a form instance for the object.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array|null $form
|
||||
* @return FlexForm
|
||||
* @param string $name Name of the form. Can be used to create customized forms for different use cases.
|
||||
* @param array|null $form Can be used to further customize the form.
|
||||
*
|
||||
* @return FlexFormInterface Returns a Form.
|
||||
* @api
|
||||
*/
|
||||
public function getForm(string $name = '', array $form = null);
|
||||
|
||||
/**
|
||||
* @param string $layout
|
||||
* @param array $context
|
||||
* @return HtmlBlock
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
* @throws \Twig_Error_Loader
|
||||
* @throws \Twig_Error_Syntax
|
||||
*/
|
||||
public function render($layout = null, array $context = []);
|
||||
|
||||
/**
|
||||
* Form field compatibility.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default
|
||||
* @param string $separator
|
||||
* @return mixed
|
||||
* @param string $name Property name.
|
||||
* @param mixed $default Default value.
|
||||
* @param string $separator Optional nested property separator.
|
||||
* @return mixed Returns value of the field.
|
||||
*/
|
||||
public function value($name, $default = null, $separator = null);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,9 @@ declare(strict_types=1);
|
||||
namespace Grav\Framework\Flex\Interfaces;
|
||||
|
||||
/**
|
||||
* Interface FlexStorageInterface
|
||||
* @package Grav\Framework\Flex\Interfaces
|
||||
* Defines Flex Storage layer.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
interface FlexStorageInterface
|
||||
{
|
||||
@@ -24,83 +25,96 @@ interface FlexStorageInterface
|
||||
public function __construct(array $options);
|
||||
|
||||
/**
|
||||
* Returns list of all stored keys in [key => timestamp] pairs.
|
||||
* Returns associated array of all existing storage keys with a timestamp.
|
||||
*
|
||||
* @return array
|
||||
* @return array Returns all existing keys as `[key => [storage_key => key, storage_timestamp => timestamp], ...]`.
|
||||
*/
|
||||
public function getExistingKeys() : array;
|
||||
public function getExistingKeys(): array;
|
||||
|
||||
/**
|
||||
* Check if storage has a row for the key.
|
||||
* Check if the key exists in the storage.
|
||||
*
|
||||
* @param string $key
|
||||
* @return bool
|
||||
* @param string $key Storage key of an object.
|
||||
*
|
||||
* @return bool Returns `true` if the key exists in the storage, `false` otherwise.
|
||||
*/
|
||||
public function hasKey(string $key) : bool;
|
||||
public function hasKey(string $key): bool;
|
||||
|
||||
/**
|
||||
* Create new rows. New keys will be assigned when the objects are created.
|
||||
* Create new rows into the storage.
|
||||
*
|
||||
* @param array $rows Array of rows.
|
||||
* @return array Returns created rows. Note that existing rows will fail to save and have null value.
|
||||
* New keys will be assigned when the objects are created.
|
||||
*
|
||||
* @param array $rows List of rows as `[row, ...]`.
|
||||
*
|
||||
* @return array Returns created rows as `[key => row, ...] pairs.
|
||||
*/
|
||||
public function createRows(array $rows) : array;
|
||||
public function createRows(array $rows): array;
|
||||
|
||||
/**
|
||||
* Read rows. If you pass object or array as value, that value will be used to save I/O.
|
||||
* Read rows from the storage.
|
||||
*
|
||||
* @param array $rows Array of [key => row] pairs.
|
||||
* @param array $fetched Optional variable for storing only fetched items.
|
||||
* @return array Returns rows. Note that non-existing rows have null value.
|
||||
* If you pass object or array as value, that value will be used to save I/O.
|
||||
*
|
||||
* @param array $rows Array of `[key => row, ...]` pairs.
|
||||
* @param array $fetched Optional reference to store only fetched items.
|
||||
*
|
||||
* @return array Returns rows. Note that non-existing rows will have `null` as their value.
|
||||
*/
|
||||
public function readRows(array $rows, array &$fetched = null) : array;
|
||||
public function readRows(array $rows, array &$fetched = null): array;
|
||||
|
||||
/**
|
||||
* Update existing rows.
|
||||
* Update existing rows in the storage.
|
||||
*
|
||||
* @param array $rows Array of [key => row] pairs.
|
||||
* @return array Returns updated rows. Note that non-existing rows will fail to save and have null value.
|
||||
* @param array $rows Array of `[key => row, ...]` pairs.
|
||||
*
|
||||
* @return array Returns updated rows. Note that non-existing rows will not be saved and have `null` as their value.
|
||||
*/
|
||||
public function updateRows(array $rows) : array;
|
||||
public function updateRows(array $rows): array;
|
||||
|
||||
/**
|
||||
* Delete rows.
|
||||
* Delete rows from the storage.
|
||||
*
|
||||
* @param array $rows Array of [key => row] pairs.
|
||||
* @return array Returns deleted rows. Note that non-existing rows have null value.
|
||||
* @param array $rows Array of `[key => row, ...]` pairs.
|
||||
*
|
||||
* @return array Returns deleted rows. Note that non-existing rows have `null` as their value.
|
||||
*/
|
||||
public function deleteRows(array $rows) : array;
|
||||
public function deleteRows(array $rows): array;
|
||||
|
||||
/**
|
||||
* Replace rows regardless if they exist or not.
|
||||
*
|
||||
* All rows should have a specified key for this to work.
|
||||
* All rows should have a specified key for replace to work properly.
|
||||
*
|
||||
* @param array $rows Array of `[key => row, ...]` pairs.
|
||||
*
|
||||
* @param array $rows Array of [key => row] pairs.
|
||||
* @return array Returns both created and updated rows.
|
||||
*/
|
||||
public function replaceRows(array $rows) : array;
|
||||
public function replaceRows(array $rows): array;
|
||||
|
||||
/**
|
||||
* @param string $src
|
||||
* @param string $dst
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function renameRow(string $src, string $dst) : bool;
|
||||
public function renameRow(string $src, string $dst): bool;
|
||||
|
||||
/**
|
||||
* Get filesystem path for the collection or object storage.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string
|
||||
* @param string|null $key Optional storage key.
|
||||
*
|
||||
* @return string Path in the filesystem. Can be URI.
|
||||
*/
|
||||
public function getStoragePath(string $key = null) : string;
|
||||
public function getStoragePath(string $key = null): string;
|
||||
|
||||
/**
|
||||
* Get filesystem path for the collection or object media.
|
||||
*
|
||||
* @param string|null $key
|
||||
* @return string
|
||||
* @param string|null $key Optional storage key.
|
||||
*
|
||||
* @return string Path in the filesystem. Can be URI.
|
||||
*/
|
||||
public function getMediaPath(string $key = null) : string;
|
||||
public function getMediaPath(string $key = null): string;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ abstract class AbstractFilesystemStorage implements FlexStorageInterface
|
||||
* @param string $filename
|
||||
* @return File
|
||||
*/
|
||||
protected function getFile(string $filename): File
|
||||
protected function getFile(string $filename)
|
||||
{
|
||||
$filename = $this->resolvePath($filename);
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Grav\Framework\Flex\Storage;
|
||||
|
||||
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
|
||||
|
||||
/**
|
||||
* Class FileStorage
|
||||
* @package Grav\Framework\Flex\Storage
|
||||
@@ -19,6 +21,7 @@ class FileStorage extends FolderStorage
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::__construct()
|
||||
*/
|
||||
public function __construct(array $options)
|
||||
{
|
||||
@@ -33,8 +36,9 @@ class FileStorage extends FolderStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::getMediaPath()
|
||||
*/
|
||||
public function getMediaPath(string $key = null) : string
|
||||
public function getMediaPath(string $key = null): string
|
||||
{
|
||||
return $key ? \dirname($this->getStoragePath($key)) . '/' . $key : $this->getStoragePath();
|
||||
}
|
||||
@@ -42,7 +46,7 @@ class FileStorage extends FolderStorage
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getKeyFromPath(string $path) : string
|
||||
protected function getKeyFromPath(string $path): string
|
||||
{
|
||||
return basename($path, $this->dataFormatter->getDefaultFileExtension());
|
||||
}
|
||||
@@ -50,7 +54,7 @@ class FileStorage extends FolderStorage
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function buildIndex() : array
|
||||
protected function buildIndex(): array
|
||||
{
|
||||
if (!file_exists($this->getStoragePath())) {
|
||||
return [];
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Grav\Framework\Flex\Storage;
|
||||
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
|
||||
use RocketTheme\Toolbox\File\File;
|
||||
use InvalidArgumentException;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
@@ -57,24 +58,27 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::getExistingKeys()
|
||||
*/
|
||||
public function getExistingKeys() : array
|
||||
public function getExistingKeys(): array
|
||||
{
|
||||
return $this->buildIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::hasKey()
|
||||
*/
|
||||
public function hasKey(string $key) : bool
|
||||
public function hasKey(string $key): bool
|
||||
{
|
||||
return $key && !strpos($key, '@@') && file_exists($this->getPathFromKey($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::createRows()
|
||||
*/
|
||||
public function createRows(array $rows) : array
|
||||
public function createRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -90,8 +94,9 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::readRows()
|
||||
*/
|
||||
public function readRows(array $rows, array &$fetched = null) : array
|
||||
public function readRows(array $rows, array &$fetched = null): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -118,8 +123,9 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::updateRows()
|
||||
*/
|
||||
public function updateRows(array $rows) : array
|
||||
public function updateRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -137,8 +143,9 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::deleteRows()
|
||||
*/
|
||||
public function deleteRows(array $rows) : array
|
||||
public function deleteRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -162,8 +169,9 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::replaceRows()
|
||||
*/
|
||||
public function replaceRows(array $rows) : array
|
||||
public function replaceRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -180,8 +188,9 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::renameRow()
|
||||
*/
|
||||
public function renameRow(string $src, string $dst) : bool
|
||||
public function renameRow(string $src, string $dst): bool
|
||||
{
|
||||
if ($this->hasKey($dst)) {
|
||||
throw new \RuntimeException("Cannot rename object: key '{$dst}' is already taken");
|
||||
@@ -196,8 +205,9 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::getStoragePath()
|
||||
*/
|
||||
public function getStoragePath(string $key = null) : string
|
||||
public function getStoragePath(string $key = null): string
|
||||
{
|
||||
if (null === $key) {
|
||||
$path = $this->dataFolder;
|
||||
@@ -210,8 +220,9 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::getMediaPath()
|
||||
*/
|
||||
public function getMediaPath(string $key = null) : string
|
||||
public function getMediaPath(string $key = null): string
|
||||
{
|
||||
return null !== $key ? \dirname($this->getStoragePath($key)) : $this->getStoragePath();
|
||||
}
|
||||
@@ -222,7 +233,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
* @param string $key
|
||||
* @return string
|
||||
*/
|
||||
public function getPathFromKey(string $key) : string
|
||||
public function getPathFromKey(string $key): string
|
||||
{
|
||||
return sprintf($this->dataPattern, $this->dataFolder, $key, substr($key, 0, 2));
|
||||
}
|
||||
@@ -231,7 +242,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
* @param File $file
|
||||
* @return array|null
|
||||
*/
|
||||
protected function loadFile(File $file) : ?array
|
||||
protected function loadFile(File $file): ?array
|
||||
{
|
||||
if (!$file->exists()) {
|
||||
return null;
|
||||
@@ -254,7 +265,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function saveFile(File $file, array $data) : array
|
||||
protected function saveFile(File $file, array $data): array
|
||||
{
|
||||
try {
|
||||
$file->save($data);
|
||||
@@ -298,7 +309,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
* @param string $dst
|
||||
* @return bool
|
||||
*/
|
||||
protected function moveFolder(string $src, string $dst) : bool
|
||||
protected function moveFolder(string $src, string $dst): bool
|
||||
{
|
||||
try {
|
||||
Folder::move($this->resolvePath($src), $this->resolvePath($dst));
|
||||
@@ -320,7 +331,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
* @param bool $include_target
|
||||
* @return bool
|
||||
*/
|
||||
protected function deleteFolder(string $path, bool $include_target = false) : bool
|
||||
protected function deleteFolder(string $path, bool $include_target = false): bool
|
||||
{
|
||||
try {
|
||||
$success = Folder::delete($this->resolvePath($path), $include_target);
|
||||
@@ -343,7 +354,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function getKeyFromPath(string $path) : string
|
||||
protected function getKeyFromPath(string $path): string
|
||||
{
|
||||
return basename($path);
|
||||
}
|
||||
@@ -353,7 +364,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildIndex() : array
|
||||
protected function buildIndex(): array
|
||||
{
|
||||
$path = $this->getStoragePath();
|
||||
if (!file_exists($path)) {
|
||||
@@ -424,7 +435,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getNewKey() : string
|
||||
protected function getNewKey(): string
|
||||
{
|
||||
// Make sure that the file doesn't exist.
|
||||
do {
|
||||
@@ -437,7 +448,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
/**
|
||||
* @param array $options
|
||||
*/
|
||||
protected function initOptions(array $options) : void
|
||||
protected function initOptions(array $options): void
|
||||
{
|
||||
$extension = $this->dataFormatter->getDefaultFileExtension();
|
||||
$pattern = !empty($options['pattern']) ? $options['pattern'] : $this->dataPattern;
|
||||
|
||||
@@ -29,6 +29,7 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::__construct()
|
||||
*/
|
||||
public function __construct(array $options)
|
||||
{
|
||||
@@ -57,24 +58,27 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::getExistingKeys()
|
||||
*/
|
||||
public function getExistingKeys() : array
|
||||
public function getExistingKeys(): array
|
||||
{
|
||||
return $this->buildIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::hasKey()
|
||||
*/
|
||||
public function hasKey(string $key) : bool
|
||||
public function hasKey(string $key): bool
|
||||
{
|
||||
return $key && !strpos($key, '@@') && isset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::createRows()
|
||||
*/
|
||||
public function createRows(array $rows) : array
|
||||
public function createRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -91,8 +95,9 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::readRows()
|
||||
*/
|
||||
public function readRows(array $rows, array &$fetched = null) : array
|
||||
public function readRows(array $rows, array &$fetched = null): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -113,8 +118,9 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::updateRows()
|
||||
*/
|
||||
public function updateRows(array $rows) : array
|
||||
public function updateRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -132,8 +138,9 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::deleteRows()
|
||||
*/
|
||||
public function deleteRows(array $rows) : array
|
||||
public function deleteRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -152,8 +159,9 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::replaceRows()
|
||||
*/
|
||||
public function replaceRows(array $rows) : array
|
||||
public function replaceRows(array $rows): array
|
||||
{
|
||||
$list = [];
|
||||
foreach ($rows as $key => $row) {
|
||||
@@ -169,8 +177,9 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::renameRow()
|
||||
*/
|
||||
public function renameRow(string $src, string $dst) : bool
|
||||
public function renameRow(string $src, string $dst): bool
|
||||
{
|
||||
if ($this->hasKey($dst)) {
|
||||
throw new \RuntimeException("Cannot rename object: key '{$dst}' is already taken");
|
||||
@@ -191,16 +200,18 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::getStoragePath()
|
||||
*/
|
||||
public function getStoragePath(string $key = null) : string
|
||||
public function getStoragePath(string $key = null): string
|
||||
{
|
||||
return $this->dataFolder . '/' . $this->dataPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexStorageInterface::getMediaPath()
|
||||
*/
|
||||
public function getMediaPath(string $key = null) : string
|
||||
public function getMediaPath(string $key = null): string
|
||||
{
|
||||
return sprintf('%s/%s/%s', $this->dataFolder, basename($this->dataPattern, $this->dataFormatter->getDefaultFileExtension()), $key);
|
||||
}
|
||||
@@ -222,7 +233,7 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
protected function getKeyFromPath(string $path) : string
|
||||
protected function getKeyFromPath(string $path): string
|
||||
{
|
||||
return basename($path);
|
||||
}
|
||||
@@ -232,7 +243,7 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function buildIndex() : array
|
||||
protected function buildIndex(): array
|
||||
{
|
||||
$file = $this->getFile($this->getStoragePath());
|
||||
$modified = $file->modified();
|
||||
@@ -253,7 +264,7 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getNewKey() : string
|
||||
protected function getNewKey(): string
|
||||
{
|
||||
if (null === $this->data) {
|
||||
$this->buildIndex();
|
||||
|
||||
@@ -31,7 +31,7 @@ use RuntimeException;
|
||||
trait FlexMediaTrait
|
||||
{
|
||||
use MediaTrait {
|
||||
MediaTrait::getMedia as private getTraitMedia;
|
||||
MediaTrait::getMedia as protected getExistingMedia;
|
||||
}
|
||||
|
||||
protected $_uploads;
|
||||
@@ -66,7 +66,7 @@ trait FlexMediaTrait
|
||||
{
|
||||
if ($this->media === null) {
|
||||
/** @var AbstractMedia $media */
|
||||
$media = $this->getTraitMedia();
|
||||
$media = $this->getExistingMedia();
|
||||
|
||||
// Include uploaded media to the object media.
|
||||
/** @var FormFlashFile $upload */
|
||||
@@ -136,7 +136,7 @@ trait FlexMediaTrait
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadMediaFile(UploadedFileInterface $uploadedFile, string $filename = null) : void
|
||||
public function uploadMediaFile(UploadedFileInterface $uploadedFile, string $filename = null): void
|
||||
{
|
||||
$this->checkUploadedMediaFile($uploadedFile);
|
||||
|
||||
@@ -187,7 +187,7 @@ trait FlexMediaTrait
|
||||
$this->clearMediaCache();
|
||||
}
|
||||
|
||||
public function deleteMediaFile(string $filename) : void
|
||||
public function deleteMediaFile(string $filename): void
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$language = $grav['language'];
|
||||
|
||||
@@ -36,7 +36,7 @@ trait FormTrait
|
||||
private $submitted;
|
||||
/** @var string[] */
|
||||
private $errors;
|
||||
/** @var \ArrayAccess|null */
|
||||
/** @var Data|object|null */
|
||||
private $data;
|
||||
/** @var array|UploadedFileInterface[] */
|
||||
private $files;
|
||||
@@ -115,7 +115,7 @@ trait FormTrait
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return $this
|
||||
* @return FormInterface|$this
|
||||
*/
|
||||
public function handleRequest(ServerRequestInterface $request): FormInterface
|
||||
{
|
||||
@@ -132,7 +132,7 @@ trait FormTrait
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return $this
|
||||
* @return FormInterface|$this
|
||||
*/
|
||||
public function setRequest(ServerRequestInterface $request): FormInterface
|
||||
{
|
||||
@@ -187,7 +187,7 @@ trait FormTrait
|
||||
/**
|
||||
* @param array $data
|
||||
* @param UploadedFileInterface[] $files
|
||||
* @return $this
|
||||
* @return FormInterface|$this
|
||||
*/
|
||||
public function submit(array $data, array $files = null): FormInterface
|
||||
{
|
||||
|
||||
@@ -12,6 +12,6 @@ namespace Grav\Framework\Media\Interfaces;
|
||||
/**
|
||||
* Class implements media collection interface.
|
||||
*/
|
||||
interface MediaCollectionInterface
|
||||
interface MediaCollectionInterface extends \ArrayAccess, \Countable, \Iterator
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user