maj
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Acl
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -14,7 +14,6 @@ use Countable;
|
||||
use Grav\Common\Utils;
|
||||
use IteratorAggregate;
|
||||
use JsonSerializable;
|
||||
use RuntimeException;
|
||||
use Traversable;
|
||||
use function count;
|
||||
use function is_array;
|
||||
@@ -25,6 +24,7 @@ use function strlen;
|
||||
/**
|
||||
* Class Access
|
||||
* @package Grav\Framework\Acl
|
||||
* @implements IteratorAggregate<string,bool|array|null>
|
||||
*/
|
||||
class Access implements JsonSerializable, IteratorAggregate, Countable
|
||||
{
|
||||
@@ -34,7 +34,7 @@ class Access implements JsonSerializable, IteratorAggregate, Countable
|
||||
private $rules;
|
||||
/** @var array */
|
||||
private $ops;
|
||||
/** @var array */
|
||||
/** @var array<string,bool|array|null> */
|
||||
private $acl = [];
|
||||
/** @var array */
|
||||
private $inherited = [];
|
||||
@@ -78,12 +78,7 @@ class Access implements JsonSerializable, IteratorAggregate, Countable
|
||||
$inherited = array_diff_key($parent->getAllActions(), $acl);
|
||||
|
||||
$this->inherited += $parent->inherited + array_fill_keys(array_keys($inherited), $name ?? $parent->getName());
|
||||
$acl = array_replace($acl, $inherited);
|
||||
if (null === $acl) {
|
||||
throw new RuntimeException('Internal error');
|
||||
}
|
||||
|
||||
$this->acl = $acl;
|
||||
$this->acl = array_replace($acl, $inherited);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Acl
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -16,11 +16,11 @@ use IteratorAggregate;
|
||||
use RuntimeException;
|
||||
use Traversable;
|
||||
use function count;
|
||||
use function strlen;
|
||||
|
||||
/**
|
||||
* Class Action
|
||||
* @package Grav\Framework\Acl
|
||||
* @implements IteratorAggregate<string,Action>
|
||||
*/
|
||||
class Action implements IteratorAggregate, Countable
|
||||
{
|
||||
@@ -37,7 +37,7 @@ class Action implements IteratorAggregate, Countable
|
||||
|
||||
/** @var Action|null */
|
||||
protected $parent;
|
||||
/** @var Action[] */
|
||||
/** @var array<string,Action> */
|
||||
protected $children = [];
|
||||
|
||||
/**
|
||||
@@ -48,8 +48,8 @@ class Action implements IteratorAggregate, Countable
|
||||
{
|
||||
$label = $action['label'] ?? null;
|
||||
if (!$label) {
|
||||
if ($pos = strrpos($name, '.')) {
|
||||
$label = substr($name, $pos + 1);
|
||||
if ($pos = mb_strrpos($name, '.')) {
|
||||
$label = mb_substr($name, $pos + 1);
|
||||
} else {
|
||||
$label = $name;
|
||||
}
|
||||
@@ -114,9 +114,9 @@ class Action implements IteratorAggregate, Countable
|
||||
*/
|
||||
public function getScope(): string
|
||||
{
|
||||
$pos = strpos($this->name, '.');
|
||||
$pos = mb_strpos($this->name, '.');
|
||||
if ($pos) {
|
||||
return substr($this->name, 0, $pos);
|
||||
return mb_substr($this->name, 0, $pos);
|
||||
}
|
||||
|
||||
return $this->name;
|
||||
@@ -127,7 +127,7 @@ class Action implements IteratorAggregate, Countable
|
||||
*/
|
||||
public function getLevels(): int
|
||||
{
|
||||
return substr_count($this->name, '.');
|
||||
return mb_substr_count($this->name, '.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,12 +161,12 @@ class Action implements IteratorAggregate, Countable
|
||||
*/
|
||||
public function addChild(Action $child): void
|
||||
{
|
||||
if (strpos($child->name, "{$this->name}.") !== 0) {
|
||||
if (mb_strpos($child->name, "{$this->name}.") !== 0) {
|
||||
throw new RuntimeException('Bad child');
|
||||
}
|
||||
|
||||
$child->setParent($this);
|
||||
$name = substr($child->name, strlen($this->name) + 1);
|
||||
$name = mb_substr($child->name, mb_strlen($this->name) + 1);
|
||||
|
||||
$this->children[$name] = $child;
|
||||
}
|
||||
@@ -190,6 +190,7 @@ class Action implements IteratorAggregate, Countable
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -3,26 +3,32 @@
|
||||
/**
|
||||
* @package Grav\Framework\Acl
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Acl;
|
||||
|
||||
use ArrayAccess;
|
||||
use ArrayIterator;
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
use RecursiveIteratorIterator;
|
||||
use RuntimeException;
|
||||
use Traversable;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* Class Permissions
|
||||
* @package Grav\Framework\Acl
|
||||
* @implements ArrayAccess<string,Action>
|
||||
* @implements IteratorAggregate<string,Action>
|
||||
*/
|
||||
class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
class Permissions implements ArrayAccess, Countable, IteratorAggregate
|
||||
{
|
||||
/** @var Action[] */
|
||||
/** @var array<string,Action> */
|
||||
protected $instances = [];
|
||||
/** @var Action[] */
|
||||
/** @var array<string,Action> */
|
||||
protected $actions = [];
|
||||
/** @var array */
|
||||
protected $nested = [];
|
||||
@@ -142,9 +148,6 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
public function addTypes(array $types): void
|
||||
{
|
||||
$types = array_replace($this->types, $types);
|
||||
if (null === $types) {
|
||||
throw new RuntimeException('Internal error');
|
||||
}
|
||||
|
||||
$this->types = $types;
|
||||
}
|
||||
@@ -206,6 +209,7 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
/**
|
||||
* @return ArrayIterator|Traversable
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->actions);
|
||||
@@ -214,6 +218,7 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Acl
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -62,12 +62,14 @@ class PermissionsReader
|
||||
{
|
||||
$list = [];
|
||||
foreach ($actions as $name => $action) {
|
||||
$prefixNname = $prefix . $name;
|
||||
$list[$prefixNname] = null;
|
||||
$prefixName = $prefix . $name;
|
||||
$list[$prefixName] = null;
|
||||
|
||||
// Support nested sets of actions.
|
||||
if (isset($action['actions']) && is_array($action['actions'])) {
|
||||
$list += static::read($action['actions'], "{$prefixNname}.");
|
||||
$innerList = static::read($action['actions'], "{$prefixName}.");
|
||||
|
||||
$list += $innerList;
|
||||
}
|
||||
|
||||
unset($action['actions']);
|
||||
@@ -76,7 +78,7 @@ class PermissionsReader
|
||||
$action = static::addDefaults($action);
|
||||
|
||||
// Build flat list of actions.
|
||||
$list[$prefixNname] = $action;
|
||||
$list[$prefixName] = $action;
|
||||
}
|
||||
|
||||
return $list;
|
||||
@@ -172,9 +174,6 @@ class PermissionsReader
|
||||
$scopes[] = $action;
|
||||
|
||||
$action = array_replace_recursive(...$scopes);
|
||||
if (null === $action) {
|
||||
throw new RuntimeException('Internal error');
|
||||
}
|
||||
|
||||
$newType = $defaults['type'] ?? null;
|
||||
if ($newType && $newType !== $type) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Acl
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ use RocketTheme\Toolbox\ArrayTraits\Iterator;
|
||||
/**
|
||||
* Class Action
|
||||
* @package Grav\Framework\Acl
|
||||
* @implements RecursiveIterator<string,Action>
|
||||
*/
|
||||
class RecursiveActionIterator implements RecursiveIterator, \Countable
|
||||
{
|
||||
@@ -26,6 +27,7 @@ class RecursiveActionIterator implements RecursiveIterator, \Countable
|
||||
* @see \Iterator::key()
|
||||
* @return string
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
/** @var Action $current */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -33,11 +33,15 @@ class ChainCache extends AbstractCache
|
||||
* Chain Cache constructor.
|
||||
* @param array $caches
|
||||
* @param null|int|DateInterval $defaultLifetime
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException|InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $caches, $defaultLifetime = null)
|
||||
{
|
||||
parent::__construct('', $defaultLifetime);
|
||||
try {
|
||||
parent::__construct('', $defaultLifetime);
|
||||
} catch (\Psr\SimpleCache\InvalidArgumentException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
if (!$caches) {
|
||||
throw new InvalidArgumentException('At least one cache must be specified');
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -29,12 +29,16 @@ class DoctrineCache extends AbstractCache
|
||||
* @param CacheProvider $doctrineCache
|
||||
* @param string $namespace
|
||||
* @param null|int|DateInterval $defaultLifetime
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException|InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(CacheProvider $doctrineCache, $namespace = '', $defaultLifetime = null)
|
||||
{
|
||||
// Do not use $namespace or $defaultLifetime directly, store them with constructor and fetch with methods.
|
||||
parent::__construct($namespace, $defaultLifetime);
|
||||
try {
|
||||
parent::__construct($namespace, $defaultLifetime);
|
||||
} catch (\Psr\SimpleCache\InvalidArgumentException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
// Set namespace to Doctrine Cache provider if it was given.
|
||||
$namespace = $this->getNamespace();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -42,9 +42,13 @@ class FileCache extends AbstractCache
|
||||
*/
|
||||
public function __construct($namespace = '', $defaultLifetime = null, $folder = null)
|
||||
{
|
||||
parent::__construct($namespace, $defaultLifetime ?: 31557600); // = 1 year
|
||||
try {
|
||||
parent::__construct($namespace, $defaultLifetime ?: 31557600); // = 1 year
|
||||
|
||||
$this->initFileCache($namespace, $folder ?? '');
|
||||
$this->initFileCache($namespace, $folder ?? '');
|
||||
} catch (\Psr\SimpleCache\InvalidArgumentException $e) {
|
||||
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +107,13 @@ class FileCache extends AbstractCache
|
||||
{
|
||||
$file = $this->getFile($key);
|
||||
|
||||
return (!file_exists($file) || @unlink($file) || !file_exists($file));
|
||||
$result = false;
|
||||
if (file_exists($file)) {
|
||||
$result = @unlink($file);
|
||||
$result &= !file_exists($file);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +166,7 @@ class FileCache extends AbstractCache
|
||||
*/
|
||||
protected function initFileCache($namespace, $directory)
|
||||
{
|
||||
if (!isset($directory[0])) {
|
||||
if ($directory === '') {
|
||||
$directory = sys_get_temp_dir() . '/grav-cache';
|
||||
} else {
|
||||
$directory = realpath($directory) ?: $directory;
|
||||
@@ -246,6 +256,7 @@ class FileCache extends AbstractCache
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->tmp !== null && file_exists($this->tmp)) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Cache
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Collection
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -68,6 +68,7 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle
|
||||
/**
|
||||
* @param Criteria $criteria
|
||||
* @return ArrayCollection
|
||||
* @phpstan-return ArrayCollection<TKey,T>
|
||||
* @todo Implement lazy matching
|
||||
*/
|
||||
public function matching(Criteria $criteria)
|
||||
@@ -93,6 +94,7 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle
|
||||
foreach (array_reverse($orderings) as $field => $ordering) {
|
||||
$next = ClosureExpressionVisitor::sortByField($field, $ordering === Criteria::DESC ? -1 : 1, $next);
|
||||
}
|
||||
/** @phpstan-ignore-next-line */
|
||||
if (null === $next) {
|
||||
throw new RuntimeException('Criteria is missing orderings');
|
||||
}
|
||||
@@ -162,6 +164,7 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle
|
||||
* @param SeekableIterator $iterator
|
||||
* @param int $nestingLimit
|
||||
* @return array
|
||||
* @phpstan-param SeekableIterator<int,T> $iterator
|
||||
*/
|
||||
protected function doInitializeByIterator(SeekableIterator $iterator, $nestingLimit)
|
||||
{
|
||||
@@ -211,7 +214,6 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle
|
||||
protected function doInitializeChildren(array $children, $nestingLimit)
|
||||
{
|
||||
$objects = [];
|
||||
|
||||
foreach ($children as $iterator) {
|
||||
$objects += $this->doInitializeByIterator($iterator, $nestingLimit);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Collection
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,7 @@ use Closure;
|
||||
use Grav\Framework\Compat\Serializable;
|
||||
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
|
||||
use InvalidArgumentException;
|
||||
use Iterator;
|
||||
use function array_key_exists;
|
||||
use function array_slice;
|
||||
use function count;
|
||||
@@ -79,17 +80,17 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
/** @phpstan-var TKey $key */
|
||||
$key = (string)key($this->entries);
|
||||
|
||||
return $key;
|
||||
/** @phpstan-var TKey */
|
||||
return (string)key($this->entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
$value = next($this->entries);
|
||||
@@ -101,6 +102,7 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
$value = current($this->entries);
|
||||
@@ -131,7 +133,7 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
{
|
||||
$key = $this->isAllowedElement($element) ? $this->getCurrentKey($element) : null;
|
||||
|
||||
if (!$key || !isset($this->entries[$key])) {
|
||||
if (null !== $key || !isset($this->entries[$key])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -143,49 +145,64 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
/**
|
||||
* Required by interface ArrayAccess.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
* @param string|int|null $offset
|
||||
* @return bool
|
||||
* @phpstan-param TKey|null $offset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return $this->containsKey($offset);
|
||||
/** @phpstan-ignore-next-line phpstan bug? */
|
||||
return $offset !== null ? $this->containsKey($offset) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required by interface ArrayAccess.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
* @param string|int|null $offset
|
||||
* @return mixed
|
||||
* @phpstan-param TKey|null $offset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->get($offset);
|
||||
/** @phpstan-ignore-next-line phpstan bug? */
|
||||
return $offset !== null ? $this->get($offset) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Required by interface ArrayAccess.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
* @param string|int|null $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @phpstan-param TKey|null $offset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (null === $offset) {
|
||||
$this->add($value);
|
||||
} else {
|
||||
/** @phpstan-ignore-next-line phpstan bug? */
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
|
||||
$this->set($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Required by interface ArrayAccess.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
* @param string|int|null $offset
|
||||
* @return void
|
||||
* @phpstan-param TKey|null $offset
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$this->remove($offset);
|
||||
if ($offset !== null) {
|
||||
/** @phpstan-ignore-next-line phpstan bug? */
|
||||
$this->remove($offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,6 +272,7 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->entries);
|
||||
@@ -298,7 +316,9 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
* Required by interface IteratorAggregate.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
* @phpstan-return Iterator<TKey,T>
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->loadElements());
|
||||
@@ -341,6 +361,7 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __toString()
|
||||
{
|
||||
return __CLASS__ . '@' . spl_object_hash($this);
|
||||
@@ -395,7 +416,7 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
$keys = $this->getKeys();
|
||||
shuffle($keys);
|
||||
|
||||
return $this->createFrom(array_replace(array_flip($keys), $this->entries) ?? []);
|
||||
return $this->createFrom(array_replace(array_flip($keys), $this->entries));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,9 +457,11 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
*
|
||||
* @param int $size Size of each chunk.
|
||||
* @return array
|
||||
* @phpstan-return array<array<TKey,T>>
|
||||
*/
|
||||
public function chunk($size)
|
||||
{
|
||||
/** @phpstan-var array<array<TKey,T>> */
|
||||
return $this->loadCollection($this->entries)->chunk($size);
|
||||
}
|
||||
|
||||
@@ -466,6 +489,7 @@ abstract class AbstractIndexCollection implements CollectionInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->loadCollection()->jsonSerialize();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Collection
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -22,11 +22,15 @@ use Doctrine\Common\Collections\AbstractLazyCollection as BaseAbstractLazyCollec
|
||||
*/
|
||||
abstract class AbstractLazyCollection extends BaseAbstractLazyCollection implements CollectionInterface
|
||||
{
|
||||
/** @var ArrayCollection The backed collection to use */
|
||||
/**
|
||||
* @par ArrayCollection
|
||||
* @phpstan-var ArrayCollection<TKey,T>
|
||||
*/
|
||||
protected $collection;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @phpstan-return ArrayCollection<TKey,T>
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
@@ -37,6 +41,7 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @phpstan-return ArrayCollection<TKey,T>
|
||||
*/
|
||||
public function shuffle()
|
||||
{
|
||||
@@ -57,6 +62,8 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @phpstan-param array<TKey,T> $keys
|
||||
* @phpstan-return ArrayCollection<TKey,T>
|
||||
*/
|
||||
public function select(array $keys)
|
||||
{
|
||||
@@ -67,6 +74,8 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @phpstan-param array<TKey,T> $keys
|
||||
* @phpstan-return ArrayCollection<TKey,T>
|
||||
*/
|
||||
public function unselect(array $keys)
|
||||
{
|
||||
@@ -78,6 +87,7 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Collection
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -30,7 +30,10 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
return $this->createFrom(array_reverse($this->toArray()));
|
||||
$keys = array_reverse($this->toArray());
|
||||
|
||||
/** @phpstan-var static<TKey,T> */
|
||||
return $this->createFrom($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,8 +46,10 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface
|
||||
{
|
||||
$keys = $this->getKeys();
|
||||
shuffle($keys);
|
||||
$keys = array_replace(array_flip($keys), $this->toArray());
|
||||
|
||||
return $this->createFrom(array_replace(array_flip($keys), $this->toArray()) ?? []);
|
||||
/** @phpstan-var static<TKey,T> */
|
||||
return $this->createFrom($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,9 +57,11 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface
|
||||
*
|
||||
* @param int $size Size of each chunk.
|
||||
* @return array
|
||||
* @phpstan-return array<array<TKey,T>>
|
||||
*/
|
||||
public function chunk($size)
|
||||
{
|
||||
/** @phpstan-var array<array<TKey,T>> */
|
||||
return array_chunk($this->toArray(), $size, true);
|
||||
}
|
||||
|
||||
@@ -63,9 +70,9 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface
|
||||
*
|
||||
* Collection is returned in the order of $keys given to the function.
|
||||
*
|
||||
* @param array<int|string> $keys
|
||||
* @param array<int,string> $keys
|
||||
* @return static
|
||||
* @phpstan-param array<TKey> $keys
|
||||
* @phpstan-param TKey[] $keys
|
||||
* @phpstan-return static<TKey,T>
|
||||
*/
|
||||
public function select(array $keys)
|
||||
@@ -77,6 +84,7 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface
|
||||
}
|
||||
}
|
||||
|
||||
/** @phpstan-var static<TKey,T> */
|
||||
return $this->createFrom($list);
|
||||
}
|
||||
|
||||
@@ -85,11 +93,15 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface
|
||||
*
|
||||
* @param array<int|string> $keys
|
||||
* @return static
|
||||
* @phpstan-param TKey[] $keys
|
||||
* @phpstan-return static<TKey,T>
|
||||
*/
|
||||
public function unselect(array $keys)
|
||||
{
|
||||
return $this->select(array_diff($this->getKeys(), $keys));
|
||||
$list = array_diff($this->getKeys(), $keys);
|
||||
|
||||
/** @phpstan-var static<TKey,T> */
|
||||
return $this->select($list);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,6 +109,7 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Collection
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,7 @@ interface CollectionInterface extends Collection, JsonSerializable
|
||||
*
|
||||
* @param int $size Size of each chunk.
|
||||
* @return array
|
||||
* @phpstan-return array<array<TKey,T>>
|
||||
*/
|
||||
public function chunk($size);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Collection
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Collection
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Compat
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\ContentBlock
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -161,6 +161,7 @@ class ContentBlock implements ContentBlockInterface
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\ContentBlock
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\ContentBlock
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -29,6 +29,8 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
/** @var array */
|
||||
protected $scripts = [];
|
||||
/** @var array */
|
||||
protected $links = [];
|
||||
/** @var array */
|
||||
protected $html = [];
|
||||
|
||||
/**
|
||||
@@ -40,6 +42,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
|
||||
$this->sortAssets($assets['styles']);
|
||||
$this->sortAssets($assets['scripts']);
|
||||
$this->sortAssets($assets['links']);
|
||||
$this->sortAssets($assets['html']);
|
||||
|
||||
return $assets;
|
||||
@@ -73,6 +76,15 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
return $this->getAssetsInLocation('scripts', $location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $location
|
||||
* @return array
|
||||
*/
|
||||
public function getLinks($location = 'head')
|
||||
{
|
||||
return $this->getAssetsInLocation('links', $location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $location
|
||||
* @return array
|
||||
@@ -98,6 +110,9 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
if ($this->scripts) {
|
||||
$array['scripts'] = $this->scripts;
|
||||
}
|
||||
if ($this->links) {
|
||||
$array['links'] = $this->links;
|
||||
}
|
||||
if ($this->html) {
|
||||
$array['html'] = $this->html;
|
||||
}
|
||||
@@ -117,6 +132,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
$this->frameworks = isset($serialized['frameworks']) ? (array) $serialized['frameworks'] : [];
|
||||
$this->styles = isset($serialized['styles']) ? (array) $serialized['styles'] : [];
|
||||
$this->scripts = isset($serialized['scripts']) ? (array) $serialized['scripts'] : [];
|
||||
$this->links = isset($serialized['links']) ? (array) $serialized['links'] : [];
|
||||
$this->html = isset($serialized['html']) ? (array) $serialized['html'] : [];
|
||||
}
|
||||
|
||||
@@ -199,11 +215,14 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
$content = (string) $element['content'];
|
||||
$type = !empty($element['type']) ? (string) $element['type'] : 'text/css';
|
||||
|
||||
unset($element['content'], $element['type']);
|
||||
|
||||
$this->styles[$location][md5($content) . sha1($content)] = [
|
||||
':type' => 'inline',
|
||||
':priority' => (int) $priority,
|
||||
'content' => $content,
|
||||
'type' => $type
|
||||
'type' => $type,
|
||||
'element' => $element
|
||||
];
|
||||
|
||||
return true;
|
||||
@@ -229,18 +248,23 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
|
||||
$src = $element['src'];
|
||||
$type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript';
|
||||
$defer = isset($element['defer']);
|
||||
$async = isset($element['async']);
|
||||
$loading = !empty($element['loading']) ? (string) $element['loading'] : null;
|
||||
$defer = !empty($element['defer']);
|
||||
$async = !empty($element['async']);
|
||||
$handle = !empty($element['handle']) ? (string) $element['handle'] : '';
|
||||
|
||||
unset($element['src'], $element['type'], $element['loading'], $element['defer'], $element['async'], $element['handle']);
|
||||
|
||||
$this->scripts[$location][md5($src) . sha1($src)] = [
|
||||
':type' => 'file',
|
||||
':priority' => (int) $priority,
|
||||
'src' => $src,
|
||||
'type' => $type,
|
||||
'loading' => $loading,
|
||||
'defer' => $defer,
|
||||
'async' => $async,
|
||||
'handle' => $handle
|
||||
'handle' => $handle,
|
||||
'element' => $element
|
||||
];
|
||||
|
||||
return true;
|
||||
@@ -266,12 +290,83 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
|
||||
$content = (string) $element['content'];
|
||||
$type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript';
|
||||
$loading = !empty($element['loading']) ? (string) $element['loading'] : null;
|
||||
|
||||
unset($element['content'], $element['type'], $element['loading']);
|
||||
|
||||
$this->scripts[$location][md5($content) . sha1($content)] = [
|
||||
':type' => 'inline',
|
||||
':priority' => (int) $priority,
|
||||
'content' => $content,
|
||||
'type' => $type
|
||||
'type' => $type,
|
||||
'loading' => $loading,
|
||||
'element' => $element
|
||||
];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $element
|
||||
* @param int $priority
|
||||
* @param string $location
|
||||
* @return bool
|
||||
*/
|
||||
public function addModule($element, $priority = 0, $location = 'head')
|
||||
{
|
||||
if (!is_array($element)) {
|
||||
$element = ['src' => (string) $element];
|
||||
}
|
||||
|
||||
$element['type'] = 'module';
|
||||
|
||||
return $this->addScript($element, $priority, $location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $element
|
||||
* @param int $priority
|
||||
* @param string $location
|
||||
* @return bool
|
||||
*/
|
||||
public function addInlineModule($element, $priority = 0, $location = 'head')
|
||||
{
|
||||
if (!is_array($element)) {
|
||||
$element = ['content' => (string) $element];
|
||||
}
|
||||
|
||||
$element['type'] = 'module';
|
||||
|
||||
return $this->addInlineScript($element, $priority, $location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $element
|
||||
* @param int $priority
|
||||
* @param string $location
|
||||
* @return bool
|
||||
*/
|
||||
public function addLink($element, $priority = 0, $location = 'head')
|
||||
{
|
||||
if (!is_array($element) || empty($element['rel']) || empty($element['href'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->links[$location])) {
|
||||
$this->links[$location] = [];
|
||||
}
|
||||
|
||||
$rel = (string) $element['rel'];
|
||||
$href = (string) $element['href'];
|
||||
|
||||
unset($element['rel'], $element['href']);
|
||||
|
||||
$this->links[$location][md5($href) . sha1($href)] = [
|
||||
':type' => 'file',
|
||||
':priority' => (int) $priority,
|
||||
'href' => $href,
|
||||
'rel' => $rel,
|
||||
'element' => $element,
|
||||
];
|
||||
|
||||
return true;
|
||||
@@ -309,6 +404,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
'frameworks' => $this->frameworks,
|
||||
'styles' => $this->styles,
|
||||
'scripts' => $this->scripts,
|
||||
'links' => $this->links,
|
||||
'html' => $this->html
|
||||
];
|
||||
|
||||
@@ -333,6 +429,14 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($blockAssets['links'] as $location => $links) {
|
||||
if (!isset($assets['links'][$location])) {
|
||||
$assets['links'][$location] = $links;
|
||||
} elseif ($links) {
|
||||
$assets['links'][$location] += $links;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($blockAssets['html'] as $location => $htmls) {
|
||||
if (!isset($assets['html'][$location])) {
|
||||
$assets['html'][$location] = $htmls;
|
||||
@@ -391,7 +495,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface
|
||||
*/
|
||||
protected function sortAssets(array &$array)
|
||||
{
|
||||
foreach ($array as $location => &$items) {
|
||||
foreach ($array as &$items) {
|
||||
$this->sortAssetsInLocation($items);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\ContentBlock
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,13 @@ interface HtmlBlockInterface extends ContentBlockInterface
|
||||
*/
|
||||
public function getScripts($location = 'head');
|
||||
|
||||
|
||||
/**
|
||||
* @param string $location
|
||||
* @return array
|
||||
*/
|
||||
public function getLinks($location = 'head');
|
||||
|
||||
/**
|
||||
* @param string $location
|
||||
* @return array
|
||||
@@ -76,7 +83,6 @@ interface HtmlBlockInterface extends ContentBlockInterface
|
||||
*/
|
||||
public function addScript($element, $priority = 0, $location = 'head');
|
||||
|
||||
|
||||
/**
|
||||
* @param string|array $element
|
||||
* @param int $priority
|
||||
@@ -85,6 +91,35 @@ interface HtmlBlockInterface extends ContentBlockInterface
|
||||
*/
|
||||
public function addInlineScript($element, $priority = 0, $location = 'head');
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for writing addScript(['type' => 'module', 'src' => ...]).
|
||||
*
|
||||
* @param string|array $element
|
||||
* @param int $priority
|
||||
* @param string $location
|
||||
* @return bool
|
||||
*/
|
||||
public function addModule($element, $priority = 0, $location = 'head');
|
||||
|
||||
/**
|
||||
* Shortcut for writing addInlineScript(['type' => 'module', 'content' => ...]).
|
||||
*
|
||||
* @param string|array $element
|
||||
* @param int $priority
|
||||
* @param string $location
|
||||
* @return bool
|
||||
*/
|
||||
public function addInlineModule($element, $priority = 0, $location = 'head');
|
||||
|
||||
/**
|
||||
* @param array $element
|
||||
* @param int $priority
|
||||
* @param string $location
|
||||
* @return bool
|
||||
*/
|
||||
public function addLink($element, $priority = 0, $location = 'head');
|
||||
|
||||
/**
|
||||
* @param string $html
|
||||
* @param int $priority
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Controller
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,7 @@ trait ControllerResponseTrait
|
||||
$headers = $headers ?? [];
|
||||
$options = $options ?? ['force_download' => true];
|
||||
|
||||
$file_parts = pathinfo($filename);
|
||||
$file_parts = Utils::pathinfo($filename);
|
||||
|
||||
if (!isset($headers['Content-Type'])) {
|
||||
$mimetype = Utils::getMimeByExtension($file_parts['extension']);
|
||||
@@ -140,9 +140,9 @@ trait ControllerResponseTrait
|
||||
$code = (int)$this->getConfig()->get('system.pages.redirect_default_code', 302);
|
||||
}
|
||||
|
||||
$ext = Utils::pathinfo($url, PATHINFO_EXTENSION);
|
||||
$accept = $this->getAccept(['application/json', 'text/html']);
|
||||
|
||||
if ($accept === 'application/json') {
|
||||
if ($ext === 'json' || $accept === 'application/json') {
|
||||
return $this->createJsonResponse(['code' => $code, 'status' => 'redirect', 'redirect' => $url]);
|
||||
}
|
||||
|
||||
@@ -217,6 +217,7 @@ trait ControllerResponseTrait
|
||||
'code' => $code,
|
||||
'status' => 'error',
|
||||
'message' => $message,
|
||||
'redirect' => null,
|
||||
'error' => [
|
||||
'code' => $code,
|
||||
'message' => $message
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\DI
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -55,6 +55,7 @@ class AbstractFile implements FileInterface
|
||||
/**
|
||||
* Unlock file when the object gets destroyed.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->isLocked()) {
|
||||
@@ -65,6 +66,7 @@ class AbstractFile implements FileInterface
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __clone()
|
||||
{
|
||||
$this->handle = null;
|
||||
@@ -191,15 +193,16 @@ class AbstractFile implements FileInterface
|
||||
$this->handle = @fopen($this->filepath, 'cb+') ?: null;
|
||||
if (!$this->handle) {
|
||||
$error = error_get_last();
|
||||
$message = $error['message'] ?? 'Unknown error';
|
||||
|
||||
throw new RuntimeException("Opening file for writing failed on error {$error['message']}");
|
||||
throw new RuntimeException("Opening file for writing failed on error {$message}");
|
||||
}
|
||||
}
|
||||
|
||||
$lock = $block ? LOCK_EX : LOCK_EX | LOCK_NB;
|
||||
|
||||
// Some filesystems do not support file locks, only fail if another process holds the lock.
|
||||
$this->locked = flock($this->handle, $lock, $wouldblock) || !$wouldblock;
|
||||
$this->locked = flock($this->handle, $lock, $wouldBlock) || !$wouldBlock;
|
||||
|
||||
return $this->locked;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -28,4 +28,13 @@ class CsvFile extends DataFile
|
||||
{
|
||||
parent::__construct($filepath, $formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function load(): array
|
||||
{
|
||||
/** @var array */
|
||||
return parent::load();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -20,15 +20,6 @@ use function is_string;
|
||||
*/
|
||||
class File extends AbstractFile
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FileInterface::load()
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
return parent::load();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FileInterface::save()
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File\Formatter
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File\Formatter
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,7 @@ use Grav\Framework\File\Interfaces\FileFormatterInterface;
|
||||
use JsonSerializable;
|
||||
use RuntimeException;
|
||||
use stdClass;
|
||||
use function count;
|
||||
use function is_array;
|
||||
use function is_object;
|
||||
use function is_scalar;
|
||||
|
||||
@@ -5,13 +5,14 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File\Formatter
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\File\Formatter;
|
||||
|
||||
use Grav\Framework\File\Interfaces\FileFormatterInterface;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class IniFormatter
|
||||
@@ -59,7 +60,7 @@ class IniFormatter extends AbstractFormatter
|
||||
$decoded = @parse_ini_string($data);
|
||||
|
||||
if ($decoded === false) {
|
||||
throw new \RuntimeException('Decoding INI failed');
|
||||
throw new RuntimeException('Decoding INI failed');
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File\Formatter
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -75,9 +75,11 @@ class JsonFormatter extends AbstractFormatter
|
||||
if (is_string($options)) {
|
||||
$list = preg_split('/[\s,|]+/', $options);
|
||||
$options = 0;
|
||||
foreach ($list as $option) {
|
||||
if (isset($this->encodeOptions[$option])) {
|
||||
$options += $this->encodeOptions[$option];
|
||||
if ($list) {
|
||||
foreach ($list as $option) {
|
||||
if (isset($this->encodeOptions[$option])) {
|
||||
$options += $this->encodeOptions[$option];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -100,9 +102,11 @@ class JsonFormatter extends AbstractFormatter
|
||||
if (is_string($options)) {
|
||||
$list = preg_split('/[\s,|]+/', $options);
|
||||
$options = 0;
|
||||
foreach ($list as $option) {
|
||||
if (isset($this->decodeOptions[$option])) {
|
||||
$options += $this->decodeOptions[$option];
|
||||
if ($list) {
|
||||
foreach ($list as $option) {
|
||||
if (isset($this->decodeOptions[$option])) {
|
||||
$options += $this->decodeOptions[$option];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -117,6 +121,7 @@ class JsonFormatter extends AbstractFormatter
|
||||
* Returns recursion depth used in decode() function.
|
||||
*
|
||||
* @return int
|
||||
* @phpstan-return positive-int
|
||||
*/
|
||||
public function getDecodeDepth(): int
|
||||
{
|
||||
|
||||
@@ -5,13 +5,14 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File\Formatter
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\File\Formatter;
|
||||
|
||||
use Grav\Framework\File\Interfaces\FileFormatterInterface;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class MarkdownFormatter
|
||||
@@ -99,7 +100,7 @@ class MarkdownFormatter extends AbstractFormatter
|
||||
// Normalize line endings to Unix style.
|
||||
$encoded = preg_replace("/(\r\n|\r)/u", "\n", $encoded);
|
||||
if (null === $encoded) {
|
||||
throw new \RuntimeException('Encoding markdown failed');
|
||||
throw new RuntimeException('Encoding markdown failed');
|
||||
}
|
||||
|
||||
return $encoded;
|
||||
@@ -126,7 +127,7 @@ class MarkdownFormatter extends AbstractFormatter
|
||||
// Normalize line endings to Unix style.
|
||||
$data = preg_replace("/(\r\n|\r)/u", "\n", $data);
|
||||
if (null === $data) {
|
||||
throw new \RuntimeException('Decoding markdown failed');
|
||||
throw new RuntimeException('Decoding markdown failed');
|
||||
}
|
||||
|
||||
// Parse header.
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File\Formatter
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File\Formatter
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -107,7 +107,9 @@ class YamlFormatter extends AbstractFormatter
|
||||
$saved = @ini_get('yaml.decode_php');
|
||||
@ini_set('yaml.decode_php', '0');
|
||||
$decoded = @yaml_parse($data);
|
||||
@ini_set('yaml.decode_php', $saved);
|
||||
if ($saved !== false) {
|
||||
@ini_set('yaml.decode_php', $saved);
|
||||
}
|
||||
|
||||
if ($decoded !== false) {
|
||||
return (array) $decoded;
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -28,4 +28,13 @@ class IniFile extends DataFile
|
||||
{
|
||||
parent::__construct($filepath, $formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function load(): array
|
||||
{
|
||||
/** @var array */
|
||||
return parent::load();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -28,4 +28,13 @@ class MarkdownFile extends DataFile
|
||||
{
|
||||
parent::__construct($filepath, $formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function load(): array
|
||||
{
|
||||
/** @var array */
|
||||
return parent::load();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\File
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -28,4 +28,13 @@ class YamlFile extends DataFile
|
||||
{
|
||||
parent::__construct($filepath, $formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function load(): array
|
||||
{
|
||||
/** @var array */
|
||||
return parent::load();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Filesystem
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,7 @@ use Grav\Framework\Filesystem\Interfaces\FilesystemInterface;
|
||||
use RuntimeException;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function is_array;
|
||||
use function pathinfo;
|
||||
|
||||
/**
|
||||
@@ -150,7 +151,10 @@ class Filesystem implements FilesystemInterface
|
||||
*/
|
||||
public function basename(string $path, ?string $suffix = null): string
|
||||
{
|
||||
return $suffix ? basename($path, $suffix) : basename($path);
|
||||
// Escape path.
|
||||
$path = str_replace(['%2F', '%5C'], '/', rawurlencode($path));
|
||||
|
||||
return rawurldecode($suffix ? basename($path, $suffix) : basename($path));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,6 +180,7 @@ class Filesystem implements FilesystemInterface
|
||||
* @param string $path
|
||||
* @param int $levels
|
||||
* @return string
|
||||
* @phpstan-param positive-int $levels
|
||||
*/
|
||||
public function pathname(string $path, int $levels = 1): string
|
||||
{
|
||||
@@ -204,6 +209,7 @@ class Filesystem implements FilesystemInterface
|
||||
* @param string $path
|
||||
* @param int $levels
|
||||
* @return array
|
||||
* @phpstan-param positive-int $levels
|
||||
*/
|
||||
protected function dirnameInternal(?string $scheme, string $path, int $levels = 1): array
|
||||
{
|
||||
@@ -229,20 +235,30 @@ class Filesystem implements FilesystemInterface
|
||||
*/
|
||||
protected function pathinfoInternal(?string $scheme, string $path, ?int $options = null)
|
||||
{
|
||||
if ($options) {
|
||||
return pathinfo($path, $options);
|
||||
$path = str_replace(['%2F', '%5C'], ['/', '\\'], rawurlencode($path));
|
||||
|
||||
if (null === $options) {
|
||||
$info = pathinfo($path);
|
||||
} else {
|
||||
$info = pathinfo($path, $options);
|
||||
}
|
||||
|
||||
$info = pathinfo($path);
|
||||
if (!is_array($info)) {
|
||||
return rawurldecode($info);
|
||||
}
|
||||
|
||||
$info = array_map('rawurldecode', $info);
|
||||
|
||||
if (null !== $scheme) {
|
||||
$info['scheme'] = $scheme;
|
||||
$dirname = isset($info['dirname']) && $info['dirname'] !== '.' ? $info['dirname'] : null;
|
||||
|
||||
if (null !== $dirname) {
|
||||
/** @phpstan-ignore-next-line because pathinfo('') doesn't have dirname */
|
||||
$dirname = $info['dirname'] ?? '.';
|
||||
|
||||
if ('' !== $dirname && '.' !== $dirname) {
|
||||
// In Windows dirname may be using backslashes, fix that.
|
||||
if (DIRECTORY_SEPARATOR !== '/') {
|
||||
$dirname = str_replace('\\', '/', $dirname);
|
||||
$dirname = str_replace(DIRECTORY_SEPARATOR, '/', $dirname);
|
||||
}
|
||||
|
||||
$info['dirname'] = $scheme . '://' . $dirname;
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Filesystem
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -31,6 +31,7 @@ interface FilesystemInterface
|
||||
* @param int $levels The number of parent directories to go up (>= 1).
|
||||
* @return string Returns parent path.
|
||||
* @throws RuntimeException
|
||||
* @phpstan-param positive-int $levels
|
||||
* @api
|
||||
*/
|
||||
public function parent(string $path, int $levels = 1): string;
|
||||
@@ -46,7 +47,7 @@ interface FilesystemInterface
|
||||
public function normalize(string $path): string;
|
||||
|
||||
/**
|
||||
* Returns filename component of path.
|
||||
* Unicode-safe and stream-safe `\basename()` replacement.
|
||||
*
|
||||
* @param string $path A filename or path, does not need to exist as a file.
|
||||
* @param string|null $suffix If the filename ends in suffix this will also be cut off.
|
||||
@@ -56,7 +57,7 @@ interface FilesystemInterface
|
||||
public function basename(string $path, ?string $suffix = null): string;
|
||||
|
||||
/**
|
||||
* Stream-safe `\dirname()` replacement.
|
||||
* Unicode-safe and stream-safe `\dirname()` replacement.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.dirname.php
|
||||
*
|
||||
@@ -64,12 +65,13 @@ interface FilesystemInterface
|
||||
* @param int $levels The number of parent directories to go up (>= 1).
|
||||
* @return string Returns path to the directory.
|
||||
* @throws RuntimeException
|
||||
* @phpstan-param positive-int $levels
|
||||
* @api
|
||||
*/
|
||||
public function dirname(string $path, int $levels = 1): string;
|
||||
|
||||
/**
|
||||
* Stream-safe `\pathinfo()` replacement.
|
||||
* Unicode-safe and stream-safe `\pathinfo()` replacement.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.pathinfo.php
|
||||
*
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -62,7 +62,7 @@ class Flex implements FlexInterface
|
||||
*/
|
||||
public function addDirectoryType(string $type, string $blueprint, array $config = [])
|
||||
{
|
||||
$config = array_replace_recursive(['enabled' => true], $this->config ?? [], $config);
|
||||
$config = array_replace_recursive(['enabled' => true], $this->config, $config);
|
||||
|
||||
$this->types[$type] = new FlexDirectory($type, $blueprint, $config);
|
||||
|
||||
@@ -123,6 +123,7 @@ class Flex implements FlexInterface
|
||||
* @param array|null $keys
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface|null
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>|null
|
||||
*/
|
||||
public function getCollection(string $type, array $keys = null, string $keyField = null): ?FlexCollectionInterface
|
||||
{
|
||||
@@ -137,11 +138,12 @@ class Flex implements FlexInterface
|
||||
* collection_class: Class to be used to create the collection. Defaults to ObjectCollection.
|
||||
* @return FlexCollectionInterface
|
||||
* @throws RuntimeException
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function getMixedCollection(array $keys, array $options = []): FlexCollectionInterface
|
||||
{
|
||||
$collectionClass = $options['collection_class'] ?? ObjectCollection::class;
|
||||
if (!class_exists($collectionClass)) {
|
||||
if (!is_a($collectionClass, FlexCollectionInterface::class, true)) {
|
||||
throw new RuntimeException(sprintf('Cannot create collection: Class %s does not exist', $collectionClass));
|
||||
}
|
||||
|
||||
@@ -231,7 +233,7 @@ class Flex implements FlexInterface
|
||||
|
||||
// Use the original key ordering.
|
||||
if (!$guessed) {
|
||||
$list = array_replace(array_fill_keys($keys, null), $list) ?? [];
|
||||
$list = array_replace(array_fill_keys($keys, null), $list);
|
||||
} else {
|
||||
// We have mixed keys, we need to map flex keys back to storage keys.
|
||||
$results = [];
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,7 @@ use Grav\Common\User\Interfaces\UserInterface;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Cache\CacheInterface;
|
||||
use Grav\Framework\ContentBlock\HtmlBlock;
|
||||
use Grav\Framework\Flex\Interfaces\FlexIndexInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
|
||||
use Grav\Framework\Object\ObjectCollection;
|
||||
use Grav\Framework\Flex\Interfaces\FlexCollectionInterface;
|
||||
@@ -47,7 +48,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
private $_flexDirectory;
|
||||
|
||||
/** @var string */
|
||||
private $_keyField;
|
||||
private $_keyField = 'storage_key';
|
||||
|
||||
/**
|
||||
* Get list of cached methods.
|
||||
@@ -124,6 +125,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
*/
|
||||
public function getFlexFeatures(): array
|
||||
{
|
||||
/** @var array $implements */
|
||||
$implements = class_implements($this);
|
||||
|
||||
$list = [];
|
||||
@@ -152,7 +154,11 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
arsort($matching, SORT_NUMERIC);
|
||||
}
|
||||
|
||||
return $this->select(array_keys($matching));
|
||||
/** @var string[] $array */
|
||||
$array = array_keys($matching);
|
||||
|
||||
/** @phpstan-var static<T> */
|
||||
return $this->select($array);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +169,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
{
|
||||
$criteria = Criteria::create()->orderBy($order);
|
||||
|
||||
/** @var FlexCollectionInterface $matching */
|
||||
/** @phpstan-var FlexCollectionInterface<T> $matching */
|
||||
$matching = $this->matching($criteria);
|
||||
|
||||
return $matching;
|
||||
@@ -171,7 +177,8 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
|
||||
/**
|
||||
* @param array $filters
|
||||
* @return FlexCollectionInterface|Collection
|
||||
* @return static
|
||||
* @phpstan-return static<T>
|
||||
*/
|
||||
public function filterBy(array $filters)
|
||||
{
|
||||
@@ -182,6 +189,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
$criteria->andWhere($expr->eq($key, $value));
|
||||
}
|
||||
|
||||
/** @phpstan-var static<T> */
|
||||
return $this->matching($criteria);
|
||||
}
|
||||
|
||||
@@ -336,6 +344,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
*/
|
||||
public function getIndex()
|
||||
{
|
||||
/** @phpstan-var FlexIndexInterface<T> */
|
||||
return $this->getFlexDirectory()->getIndex($this->getKeys(), $this->getKeyField());
|
||||
}
|
||||
|
||||
@@ -460,7 +469,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaData(string $key): array
|
||||
public function getMetaData($key): array
|
||||
{
|
||||
$object = $this->get($key);
|
||||
|
||||
@@ -481,7 +490,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
*/
|
||||
public function getKeyField(): string
|
||||
{
|
||||
return $this->_keyField ?? 'storage_key';
|
||||
return $this->_keyField;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -496,13 +505,18 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
$list = $this->call('isAuthorized', [$action, $scope, $user]);
|
||||
$list = array_filter($list);
|
||||
|
||||
return $this->select(array_keys($list));
|
||||
/** @var string[] $keys */
|
||||
$keys = array_keys($list);
|
||||
|
||||
/** @phpstan-var static<T> */
|
||||
return $this->select($keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param string $field
|
||||
* @return T|null
|
||||
* @return FlexObjectInterface|null
|
||||
* @phpstan-return T|null
|
||||
*/
|
||||
public function find($value, $field = 'id')
|
||||
{
|
||||
@@ -520,6 +534,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
$elements = [];
|
||||
@@ -538,6 +553,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,7 @@ use Grav\Common\Utils;
|
||||
use Grav\Framework\Cache\Adapter\DoctrineCache;
|
||||
use Grav\Framework\Cache\Adapter\MemoryCache;
|
||||
use Grav\Framework\Cache\CacheInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexAuthorizeInterface;
|
||||
use Grav\Framework\Filesystem\Filesystem;
|
||||
use Grav\Framework\Flex\Interfaces\FlexCollectionInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexDirectoryInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexFormInterface;
|
||||
@@ -45,7 +45,6 @@ use function is_callable;
|
||||
/**
|
||||
* Class FlexDirectory
|
||||
* @package Grav\Framework\Flex
|
||||
* @template T
|
||||
*/
|
||||
class FlexDirectory implements FlexDirectoryInterface
|
||||
{
|
||||
@@ -57,9 +56,15 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
protected $blueprint_file;
|
||||
/** @var Blueprint[] */
|
||||
protected $blueprints;
|
||||
/** @var FlexIndexInterface[] */
|
||||
/**
|
||||
* @var FlexIndexInterface[]
|
||||
* @phpstan-var FlexIndexInterface<FlexObjectInterface>[]
|
||||
*/
|
||||
protected $indexes = [];
|
||||
/** @var FlexCollectionInterface|null */
|
||||
/**
|
||||
* @var FlexCollectionInterface|null
|
||||
* @phpstan-var FlexCollectionInterface<FlexObjectInterface>|null
|
||||
*/
|
||||
protected $collection;
|
||||
/** @var bool */
|
||||
protected $enabled;
|
||||
@@ -213,8 +218,17 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
/** @var string $filename Filename is always string */
|
||||
$filename = $locator->findResource($this->getDirectoryConfigUri($name), true, true);
|
||||
|
||||
$filename = $this->getDirectoryConfigUri($name);
|
||||
if (file_exists($filename)) {
|
||||
$filename = $locator->findResource($filename, true);
|
||||
} else {
|
||||
$filesystem = Filesystem::getInstance();
|
||||
$dirname = $filesystem->dirname($filename);
|
||||
$basename = $filesystem->basename($filename);
|
||||
$dirname = $locator->findResource($dirname, true) ?: $locator->findResource($dirname, true, true);
|
||||
$filename = "{$dirname}/{$basename}";
|
||||
}
|
||||
|
||||
$file = YamlFile::instance($filename);
|
||||
if (!empty($data)) {
|
||||
@@ -318,7 +332,7 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
* @param array|null $keys Array of keys.
|
||||
* @param string|null $keyField Field to be used as the key.
|
||||
* @return FlexCollectionInterface
|
||||
* @phpstan-return FlexCollectionInterface<T>
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface
|
||||
{
|
||||
@@ -345,6 +359,7 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
* @param array|null $keys Array of keys.
|
||||
* @param string|null $keyField Field to be used as the key.
|
||||
* @return FlexIndexInterface
|
||||
* @phpstan-return FlexIndexInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function getIndex(array $keys = null, string $keyField = null): FlexIndexInterface
|
||||
{
|
||||
@@ -353,7 +368,7 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
$index = clone $index;
|
||||
|
||||
if (null !== $keys) {
|
||||
/** @var FlexIndexInterface $index */
|
||||
/** @var FlexIndexInterface<FlexObjectInterface> $index */
|
||||
$index = $index->select($keys);
|
||||
}
|
||||
|
||||
@@ -487,8 +502,11 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
*/
|
||||
public function createObject(array $data, string $key = '', bool $validate = false): FlexObjectInterface
|
||||
{
|
||||
/** @var string|FlexObjectInterface $className */
|
||||
/** @phpstan-var class-string $className */
|
||||
$className = $this->objectClassName ?: $this->getObjectClass();
|
||||
if (!is_a($className, FlexObjectInterface::class, true)) {
|
||||
throw new \RuntimeException('Bad object class: ' . $className);
|
||||
}
|
||||
|
||||
return new $className($data, $key, $this, $validate);
|
||||
}
|
||||
@@ -497,11 +515,15 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
* @param array $entries
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function createCollection(array $entries, string $keyField = null): FlexCollectionInterface
|
||||
{
|
||||
/** @var string|FlexCollectionInterface $className */
|
||||
/** phpstan-var class-string $className */
|
||||
$className = $this->collectionClassName ?: $this->getCollectionClass();
|
||||
if (!is_a($className, FlexCollectionInterface::class, true)) {
|
||||
throw new \RuntimeException('Bad collection class: ' . $className);
|
||||
}
|
||||
|
||||
return $className::createFromArray($entries, $this, $keyField);
|
||||
}
|
||||
@@ -510,11 +532,15 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
* @param array $entries
|
||||
* @param string|null $keyField
|
||||
* @return FlexIndexInterface
|
||||
* @phpstan-return FlexIndexInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function createIndex(array $entries, string $keyField = null): FlexIndexInterface
|
||||
{
|
||||
/** @var string|FlexIndexInterface $className */
|
||||
/** @phpstan-var class-string $className */
|
||||
$className = $this->indexClassName ?: $this->getIndexClass();
|
||||
if (!is_a($className, FlexIndexInterface::class, true)) {
|
||||
throw new \RuntimeException('Bad index class: ' . $className);
|
||||
}
|
||||
|
||||
return $className::createFromArray($entries, $this, $keyField);
|
||||
}
|
||||
@@ -560,6 +586,7 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
* @param array $entries
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function loadCollection(array $entries, string $keyField = null): FlexCollectionInterface
|
||||
{
|
||||
@@ -889,12 +916,17 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
$className = $storage['class'] ?? SimpleStorage::class;
|
||||
$options = $storage['options'] ?? [];
|
||||
|
||||
if (!is_a($className, FlexStorageInterface::class, true)) {
|
||||
throw new \RuntimeException('Bad storage class: ' . $className);
|
||||
}
|
||||
|
||||
return new $className($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyField
|
||||
* @return FlexIndexInterface
|
||||
* @phpstan-return FlexIndexInterface<FlexObjectInterface>
|
||||
*/
|
||||
protected function loadIndex(string $keyField): FlexIndexInterface
|
||||
{
|
||||
@@ -924,7 +956,7 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
}
|
||||
|
||||
if (!is_array($keys)) {
|
||||
/** @var string|FlexIndexInterface $className */
|
||||
/** @phpstan-var class-string $className */
|
||||
$className = $this->getIndexClass();
|
||||
$keys = $className::loadEntriesFromStorage($storage);
|
||||
if (!$cache instanceof MemoryCache) {
|
||||
@@ -946,7 +978,7 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
// We need to do this in two steps as orderBy() calls loadIndex() again and we do not want infinite loop.
|
||||
$this->indexes['storage_key'] = $index = $this->createIndex($keys, 'storage_key');
|
||||
if ($ordering) {
|
||||
/** @var FlexCollectionInterface $collection */
|
||||
/** @var FlexCollectionInterface<FlexObjectInterface> $collection */
|
||||
$collection = $this->indexes['storage_key']->orderBy($ordering);
|
||||
$this->indexes['storage_key'] = $index = $collection->getIndex();
|
||||
}
|
||||
@@ -1035,7 +1067,9 @@ class FlexDirectory implements FlexDirectoryInterface
|
||||
$newKey = $object->getStorageKey();
|
||||
|
||||
if ($oldKey !== $newKey) {
|
||||
$object->triggerEvent('move');
|
||||
if (method_exists($object, 'triggerEvent')) {
|
||||
$object->triggerEvent('move');
|
||||
}
|
||||
$storage->renameRow($oldKey, $newKey);
|
||||
// TODO: media support.
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -358,6 +358,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable
|
||||
* @param string $name
|
||||
* @return mixed|null
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __get($name)
|
||||
{
|
||||
$method = "get{$name}";
|
||||
@@ -375,6 +376,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$method = "set{$name}";
|
||||
@@ -387,6 +389,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __isset($name)
|
||||
{
|
||||
$method = "get{$name}";
|
||||
@@ -403,6 +406,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __unset($name)
|
||||
{
|
||||
}
|
||||
@@ -493,6 +497,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable
|
||||
* Filter validated data.
|
||||
*
|
||||
* @param ArrayAccess|Data|null $data
|
||||
* @phpstan-param ArrayAccess<string,mixed>|Data|null $data
|
||||
*/
|
||||
protected function filterData($data = null): void
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -444,6 +444,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable
|
||||
* @param string $name
|
||||
* @return mixed|null
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __get($name)
|
||||
{
|
||||
$method = "get{$name}";
|
||||
@@ -461,6 +462,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$method = "set{$name}";
|
||||
@@ -473,6 +475,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __isset($name)
|
||||
{
|
||||
$method = "get{$name}";
|
||||
@@ -489,6 +492,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __unset($name)
|
||||
{
|
||||
}
|
||||
@@ -594,6 +598,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable
|
||||
*
|
||||
* @param ArrayAccess|Data|null $data
|
||||
* @return void
|
||||
* @phpstan-param ArrayAccess<string,mixed>|Data|null $data
|
||||
*/
|
||||
protected function filterData($data = null): void
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Common\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Grav\Framework\Flex;
|
||||
|
||||
use Exception;
|
||||
use Grav\Common\Debugger;
|
||||
use Grav\Common\File\CompiledJsonFile;
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Inflector;
|
||||
@@ -39,14 +40,14 @@ use function in_array;
|
||||
* @implements FlexIndexInterface<T>
|
||||
* @mixin C
|
||||
*/
|
||||
class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexIndexInterface
|
||||
class FlexIndex extends ObjectIndex implements FlexIndexInterface
|
||||
{
|
||||
const VERSION = 1;
|
||||
|
||||
/** @var FlexDirectory|null */
|
||||
private $_flexDirectory;
|
||||
/** @var string */
|
||||
private $_keyField;
|
||||
private $_keyField = 'storage_key';
|
||||
/** @var array */
|
||||
private $_indexKeys;
|
||||
|
||||
@@ -117,6 +118,14 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
$this->setKeyField(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
return $this->_key ?: $this->getFlexType() . '@@' . spl_object_hash($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCommonInterface::hasFlexFeature()
|
||||
@@ -132,6 +141,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
*/
|
||||
public function getFlexFeatures(): array
|
||||
{
|
||||
/** @var array $implements */
|
||||
$implements = class_implements($this->getFlexDirectory()->getCollectionClass());
|
||||
|
||||
$list = [];
|
||||
@@ -164,7 +174,6 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
return $this->orderBy($orderings);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @see FlexCollectionInterface::filterBy()
|
||||
@@ -353,7 +362,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
*/
|
||||
public function getKeyField(): string
|
||||
{
|
||||
return $this->_keyField ?? 'storage_key';
|
||||
return $this->_keyField;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -416,7 +425,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
$previous = $search;
|
||||
}
|
||||
|
||||
return $this->createFrom(array_replace($previous ?? [], $this->getEntries()) ?? []);
|
||||
return $this->createFrom(array_replace($previous ?? [], $this->getEntries()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,12 +441,13 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = Grav::instance()['debugger'];
|
||||
|
||||
/** @var FlexCollection $className */
|
||||
/** @phpstan-var class-string $className */
|
||||
$className = $this->getFlexDirectory()->getCollectionClass();
|
||||
$cachedMethods = $className::getCachedMethods();
|
||||
|
||||
@@ -492,9 +502,13 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
}
|
||||
} else {
|
||||
$collection = $this->loadCollection();
|
||||
$result = $collection->{$name}(...$arguments);
|
||||
if (!isset($cachedMethods[$name])) {
|
||||
$debugger->addMessage("Call '{$flexType}:{$name}()' isn't cached", 'debug');
|
||||
if (\is_callable([$collection, $name])) {
|
||||
$result = $collection->{$name}(...$arguments);
|
||||
if (!isset($cachedMethods[$name])) {
|
||||
$debugger->addMessage("Call '{$flexType}:{$name}()' isn't cached", 'debug');
|
||||
}
|
||||
} else {
|
||||
$result = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,6 +536,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
@@ -607,9 +622,11 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return ObjectInterface|null
|
||||
* @phpstan-return T|null
|
||||
*/
|
||||
protected function loadElement($key, $value): ?ObjectInterface
|
||||
{
|
||||
/** @phpstan-var T[] $objects */
|
||||
$objects = $this->getFlexDirectory()->loadObjects([$key => $value]);
|
||||
|
||||
return $objects ? reset($objects): null;
|
||||
@@ -618,10 +635,14 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
/**
|
||||
* @param array|null $entries
|
||||
* @return ObjectInterface[]
|
||||
* @phpstan-return T[]
|
||||
*/
|
||||
protected function loadElements(array $entries = null): array
|
||||
{
|
||||
return $this->getFlexDirectory()->loadObjects($entries ?? $this->getEntries());
|
||||
/** @phpstan-var T[] $objects */
|
||||
$objects = $this->getFlexDirectory()->loadObjects($entries ?? $this->getEntries());
|
||||
|
||||
return $objects;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -824,7 +845,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
|
||||
|
||||
/**
|
||||
* @param FlexStorageInterface $storage
|
||||
* @return CompiledYamlFile|null
|
||||
* @return CompiledYamlFile|CompiledJsonFile|null
|
||||
*/
|
||||
protected static function getIndexFile(FlexStorageInterface $storage)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -69,13 +69,13 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
private $_forms = [];
|
||||
/** @var Blueprint[] */
|
||||
private $_blueprint = [];
|
||||
/** @var array */
|
||||
/** @var array|null */
|
||||
private $_meta;
|
||||
/** @var array */
|
||||
/** @var array|null */
|
||||
protected $_original;
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
protected $storage_key;
|
||||
/** @var int */
|
||||
/** @var int|null */
|
||||
protected $storage_timestamp;
|
||||
|
||||
/**
|
||||
@@ -163,6 +163,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
*/
|
||||
public function getFlexFeatures(): array
|
||||
{
|
||||
/** @var array $implements */
|
||||
$implements = class_implements($this);
|
||||
|
||||
$list = [];
|
||||
@@ -656,6 +657,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->getElements();
|
||||
@@ -775,7 +777,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
$value = reset($result);
|
||||
$meta = $value['__META'] ?? null;
|
||||
if ($meta) {
|
||||
/** @var FlexIndex $indexClass */
|
||||
/** @phpstan-var class-string $indexClass */
|
||||
$indexClass = $this->getFlexDirectory()->getIndexClass();
|
||||
$indexClass::updateObjectMeta($meta, $value, $storage);
|
||||
$this->_meta = $meta;
|
||||
@@ -887,8 +889,8 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
public function getDefaultValue(string $name, string $separator = null)
|
||||
{
|
||||
$separator = $separator ?: '.';
|
||||
$path = explode($separator, $name) ?: [];
|
||||
$offset = array_shift($path) ?? '';
|
||||
$path = explode($separator, $name);
|
||||
$offset = array_shift($path);
|
||||
|
||||
$current = $this->getDefaultValues();
|
||||
|
||||
@@ -950,6 +952,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getFlexKey();
|
||||
@@ -958,6 +961,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
@@ -973,6 +977,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
|
||||
/**
|
||||
* Clone object.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __clone()
|
||||
{
|
||||
// Allows future compatibility as parent::__clone() works.
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -140,5 +140,5 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
|
||||
* @param string $key Key.
|
||||
* @return array
|
||||
*/
|
||||
public function getMetaData(string $key): array;
|
||||
public function getMetaData($key): array;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -105,6 +105,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface
|
||||
* @param array|null $keys Array of keys.
|
||||
* @param string|null $keyField Field to be used as the key.
|
||||
* @return FlexCollectionInterface
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface;
|
||||
|
||||
@@ -116,6 +117,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface
|
||||
* @param array|null $keys Array of keys.
|
||||
* @param string|null $keyField Field to be used as the key.
|
||||
* @return FlexIndexInterface
|
||||
* @phpstan-return FlexIndexInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function getIndex(array $keys = null, string $keyField = null): FlexIndexInterface;
|
||||
|
||||
@@ -170,6 +172,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface
|
||||
* @param array $entries
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function createCollection(array $entries, string $keyField = null): FlexCollectionInterface;
|
||||
|
||||
@@ -177,6 +180,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface
|
||||
* @param array $entries
|
||||
* @param string|null $keyField
|
||||
* @return FlexIndexInterface
|
||||
* @phpstan-return FlexIndexInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function createIndex(array $entries, string $keyField = null): FlexIndexInterface;
|
||||
|
||||
@@ -199,6 +203,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface
|
||||
* @param array $entries
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function loadCollection(array $entries, string $keyField = null): FlexCollectionInterface;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -43,4 +43,9 @@ interface FlexFormInterface extends Serializable, FormInterface
|
||||
* @return Route|null Returns Route object or null if file uploads are not enabled.
|
||||
*/
|
||||
public function getFileDeleteAjaxRoute($field, $filename);
|
||||
|
||||
// /**
|
||||
// * @return FlexObjectInterface
|
||||
// */
|
||||
// public function getObject();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -59,6 +59,7 @@ interface FlexInterface extends Countable
|
||||
* @param array|null $keys
|
||||
* @param string|null $keyField
|
||||
* @return FlexCollectionInterface|null
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>|null
|
||||
*/
|
||||
public function getCollection(string $type, array $keys = null, string $keyField = null): ?FlexCollectionInterface;
|
||||
|
||||
@@ -68,6 +69,7 @@ interface FlexInterface extends Countable
|
||||
* collection_class: Class to be used to create the collection. Defaults to ObjectCollection.
|
||||
* @return FlexCollectionInterface
|
||||
* @throws RuntimeException
|
||||
* @phpstan-return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
public function getMixedCollection(array $keys, array $options = []): FlexCollectionInterface;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,7 @@ use RuntimeException;
|
||||
/**
|
||||
* Defines Flex Objects.
|
||||
*
|
||||
* @extends ArrayAccess<string,mixed>
|
||||
* @used-by \Grav\Framework\Flex\FlexObject
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Grav\Framework\Flex\Pages;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Framework\Flex\FlexCollection;
|
||||
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
|
||||
use function array_search;
|
||||
use function assert;
|
||||
use function is_int;
|
||||
@@ -20,7 +21,7 @@ use function is_int;
|
||||
/**
|
||||
* Class FlexPageCollection
|
||||
* @package Grav\Plugin\FlexObjects\Types\FlexPages
|
||||
* @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface
|
||||
* @template T of FlexObjectInterface
|
||||
* @extends FlexCollection<T>
|
||||
*/
|
||||
class FlexPageCollection extends FlexCollection
|
||||
@@ -56,8 +57,10 @@ class FlexPageCollection extends FlexCollection
|
||||
*/
|
||||
public function withPublished(bool $bool = true)
|
||||
{
|
||||
/** @var string[] $list */
|
||||
$list = array_keys(array_filter($this->call('isPublished', [$bool])));
|
||||
|
||||
/** @phpstan-var static<T> */
|
||||
return $this->select($list);
|
||||
}
|
||||
|
||||
@@ -68,8 +71,10 @@ class FlexPageCollection extends FlexCollection
|
||||
*/
|
||||
public function withVisible(bool $bool = true)
|
||||
{
|
||||
/** @var string[] $list */
|
||||
$list = array_keys(array_filter($this->call('isVisible', [$bool])));
|
||||
|
||||
/** @phpstan-var static<T> */
|
||||
return $this->select($list);
|
||||
}
|
||||
|
||||
@@ -80,8 +85,10 @@ class FlexPageCollection extends FlexCollection
|
||||
*/
|
||||
public function withRoutable(bool $bool = true)
|
||||
{
|
||||
/** @var string[] $list */
|
||||
$list = array_keys(array_filter($this->call('isRoutable', [$bool])));
|
||||
|
||||
/** @phpstan-var static<T> */
|
||||
return $this->select($list);
|
||||
}
|
||||
|
||||
@@ -148,9 +155,10 @@ class FlexPageCollection extends FlexCollection
|
||||
public function adjacentSibling($path, $direction = 1)
|
||||
{
|
||||
$keys = $this->getKeys();
|
||||
$direction = (int)$direction;
|
||||
$pos = array_search($path, $keys, true);
|
||||
|
||||
if ($pos !== false) {
|
||||
if (is_int($pos)) {
|
||||
$pos += $direction;
|
||||
if (isset($keys[$pos])) {
|
||||
return $this[$keys[$pos]];
|
||||
@@ -170,7 +178,7 @@ class FlexPageCollection extends FlexCollection
|
||||
{
|
||||
$pos = array_search($path, $this->getKeys(), true);
|
||||
|
||||
return $pos !== false ? $pos : null;
|
||||
return is_int($pos) ? $pos : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,7 +192,6 @@ class FlexPageCollection extends FlexCollection
|
||||
$keys = $collection->getStorageKeys();
|
||||
|
||||
// Assign next free order.
|
||||
/** @var FlexPageObject|null $last */
|
||||
$last = null;
|
||||
$order = 0;
|
||||
foreach ($keys as $folder => $key) {
|
||||
@@ -196,8 +203,9 @@ class FlexPageCollection extends FlexCollection
|
||||
}
|
||||
}
|
||||
|
||||
/** @var FlexPageObject|null $last */
|
||||
$last = $collection[$last];
|
||||
|
||||
return sprintf('%d.', $last ? $last->value('order') + 1 : 1);
|
||||
return sprintf('%d.', $last ? $last->getFormValue('order') + 1 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -55,6 +55,7 @@ class FlexPageObject extends FlexObject implements PageInterface, FlexTranslateI
|
||||
/**
|
||||
* Clone page.
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __clone()
|
||||
{
|
||||
parent::__clone();
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -75,13 +75,13 @@ trait PageContentTrait
|
||||
'template' => 'template',
|
||||
];
|
||||
|
||||
/** @var object */
|
||||
/** @var object|null */
|
||||
protected $header;
|
||||
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
protected $_summary;
|
||||
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
protected $_content;
|
||||
|
||||
/**
|
||||
@@ -100,6 +100,7 @@ trait PageContentTrait
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* @return Header
|
||||
*/
|
||||
public function header($var = null)
|
||||
{
|
||||
@@ -288,7 +289,7 @@ trait PageContentTrait
|
||||
'process',
|
||||
$var,
|
||||
function ($value) {
|
||||
$value = array_replace(Grav::instance()['config']->get('system.pages.process', []), is_array($value) ? $value : []) ?? [];
|
||||
$value = array_replace(Grav::instance()['config']->get('system.pages.process', []), is_array($value) ? $value : []);
|
||||
foreach ($value as $process => $status) {
|
||||
$value[$process] = (bool)$status;
|
||||
}
|
||||
@@ -664,6 +665,7 @@ trait PageContentTrait
|
||||
*/
|
||||
protected function processContent($content): string
|
||||
{
|
||||
$content = is_string($content) ? $content : '';
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Config $config */
|
||||
@@ -676,7 +678,6 @@ trait PageContentTrait
|
||||
$twig_first = $this->getNestedProperty('header.twig_first') ?? $config->get('system.pages.twig_first', false);
|
||||
$never_cache_twig = $this->getNestedProperty('header.never_cache_twig') ?? $config->get('system.pages.never_cache_twig', false);
|
||||
|
||||
$cached = null;
|
||||
if ($cache_enable) {
|
||||
$cache = $this->getCache('render');
|
||||
$key = md5($this->getCacheKey() . '-content');
|
||||
@@ -688,12 +689,10 @@ trait PageContentTrait
|
||||
if ($process_twig && $never_cache_twig) {
|
||||
$this->_content = $this->processTwig($this->_content);
|
||||
}
|
||||
} else {
|
||||
$cached = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$cached) {
|
||||
if (null === $this->_content) {
|
||||
$markdown_options = [];
|
||||
if ($process_markdown) {
|
||||
// Build markdown options.
|
||||
@@ -746,6 +745,7 @@ trait PageContentTrait
|
||||
}
|
||||
|
||||
if ($process_twig) {
|
||||
\assert(is_string($this->_content));
|
||||
$this->_content = $this->processTwig($this->_content);
|
||||
}
|
||||
}
|
||||
@@ -755,6 +755,8 @@ trait PageContentTrait
|
||||
}
|
||||
}
|
||||
|
||||
\assert(is_string($this->_content));
|
||||
|
||||
// Handle summary divider
|
||||
$delimiter = $config->get('site.summary.delimiter', '===');
|
||||
$divider_pos = mb_strpos($this->_content, "<p>{$delimiter}</p>");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -17,13 +17,12 @@ use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Yaml;
|
||||
use Grav\Framework\Cache\CacheInterface;
|
||||
use Grav\Framework\File\Formatter\MarkdownFormatter;
|
||||
use Grav\Framework\File\Formatter\YamlFormatter;
|
||||
use Grav\Framework\Filesystem\Filesystem;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
use Grav\Framework\Flex\Interfaces\FlexCollectionInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexIndexInterface;
|
||||
use Grav\Framework\Flex\Pages\FlexPageCollection;
|
||||
use Grav\Framework\Flex\Pages\FlexPageIndex;
|
||||
use Grav\Framework\Flex\Pages\FlexPageObject;
|
||||
use InvalidArgumentException;
|
||||
@@ -300,7 +299,7 @@ trait PageLegacyTrait
|
||||
|
||||
$parentStorageKey = ltrim($filesystem->dirname("/{$this->getMasterKey()}"), '/');
|
||||
|
||||
/** @var FlexPageIndex $index */
|
||||
/** @var FlexPageIndex<FlexPageObject,FlexPageCollection<FlexPageObject>> $index */
|
||||
$index = $this->getFlexDirectory()->getIndex();
|
||||
|
||||
if ($parent) {
|
||||
@@ -323,8 +322,9 @@ trait PageLegacyTrait
|
||||
if ($this instanceof FlexPageObject) {
|
||||
$key = trim($parentKey . '/' . $this->folder(), '/');
|
||||
$key = preg_replace(static::PAGE_ORDER_PREFIX_REGEX, '', $key);
|
||||
\assert(is_string($key));
|
||||
} else {
|
||||
$key = trim($parentKey . '/' . basename($this->getKey()), '/');
|
||||
$key = trim($parentKey . '/' . Utils::basename($this->getKey()), '/');
|
||||
}
|
||||
|
||||
if ($index->containsKey($key)) {
|
||||
@@ -336,7 +336,7 @@ trait PageLegacyTrait
|
||||
} while ($index->containsKey($test));
|
||||
$key = $test;
|
||||
}
|
||||
$folder = basename($key);
|
||||
$folder = Utils::basename($key);
|
||||
|
||||
// Get the folder name.
|
||||
$order = $this->getProperty('order');
|
||||
@@ -539,7 +539,7 @@ trait PageLegacyTrait
|
||||
if ($language) {
|
||||
$language = '.' . $language;
|
||||
}
|
||||
$format = '.' . ($this->getProperty('format') ?? pathinfo($this->name(), PATHINFO_EXTENSION));
|
||||
$format = '.' . ($this->getProperty('format') ?? Utils::pathinfo($this->name(), PATHINFO_EXTENSION));
|
||||
|
||||
return $language . $format;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -15,10 +15,10 @@ use Grav\Common\Page\Interfaces\PageCollectionInterface;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Filesystem\Filesystem;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use RuntimeException;
|
||||
use function dirname;
|
||||
use function is_string;
|
||||
|
||||
/**
|
||||
@@ -375,7 +375,7 @@ trait PageRoutableTrait
|
||||
$value = $this->getMasterKey() ?: $this->getKey();
|
||||
}
|
||||
|
||||
return basename($value) ?: null;
|
||||
return Utils::basename($value) ?: null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,14 @@ trait PageTranslateTrait
|
||||
/** @var PageInterface[] */
|
||||
private $_translations = [];
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function translated(): bool
|
||||
{
|
||||
return (bool)$this->translatedLanguages(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $languageCode
|
||||
* @param bool|null $fallback
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -127,6 +127,10 @@ abstract class AbstractFilesystemStorage implements FlexStorageInterface
|
||||
$formatterClassName = $formatter['class'] ?? JsonFormatter::class;
|
||||
$formatterOptions = $formatter['options'] ?? [];
|
||||
|
||||
if (!is_a($formatterClassName, FileFormatterInterface::class, true)) {
|
||||
throw new \InvalidArgumentException('Bad Data Formatter');
|
||||
}
|
||||
|
||||
$this->dataFormatter = new $formatterClassName($formatterOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,14 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Flex\Storage;
|
||||
|
||||
use FilesystemIterator;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
|
||||
use RuntimeException;
|
||||
use SplFileInfo;
|
||||
@@ -125,7 +126,7 @@ class FileStorage extends FolderStorage
|
||||
*/
|
||||
protected function getKeyFromPath(string $path): string
|
||||
{
|
||||
return basename($path, $this->dataFormatter->getDefaultFileExtension());
|
||||
return Utils::basename($path, $this->dataFormatter->getDefaultFileExtension());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -352,7 +352,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
*/
|
||||
protected function getKeyFromPath(string $path): string
|
||||
{
|
||||
return basename($path);
|
||||
return Utils::basename($path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -688,7 +688,7 @@ class FolderStorage extends AbstractFilesystemStorage
|
||||
$pattern .= '/{FILE}{EXT}';
|
||||
} else {
|
||||
$filesystem = Filesystem::getInstance(true);
|
||||
$this->dataFile = basename($pattern, $extension);
|
||||
$this->dataFile = Utils::basename($pattern, $extension);
|
||||
$pattern = $filesystem->dirname($pattern) . '/{FILE}{EXT}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Grav\Framework\Flex\Storage;
|
||||
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Filesystem\Filesystem;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
@@ -30,7 +31,7 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
protected $dataFolder;
|
||||
/** @var string */
|
||||
protected $dataPattern;
|
||||
/** @var string */
|
||||
/** @var string|null */
|
||||
protected $prefix;
|
||||
/** @var array|null */
|
||||
protected $data;
|
||||
@@ -53,9 +54,9 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
$filesystem = Filesystem::getInstance(true);
|
||||
|
||||
$extension = $this->dataFormatter->getDefaultFileExtension();
|
||||
$pattern = basename($options['folder']);
|
||||
$pattern = Utils::basename($options['folder']);
|
||||
|
||||
$this->dataPattern = basename($pattern, $extension) . $extension;
|
||||
$this->dataPattern = Utils::basename($pattern, $extension) . $extension;
|
||||
$this->dataFolder = $filesystem->dirname($options['folder']);
|
||||
$this->keyField = $options['key'] ?? 'storage_key';
|
||||
$this->keyLen = (int)($options['key_len'] ?? 32);
|
||||
@@ -432,7 +433,7 @@ class SimpleStorage extends AbstractFilesystemStorage
|
||||
*/
|
||||
protected function getKeyFromPath(string $path): string
|
||||
{
|
||||
return basename($path);
|
||||
return Utils::basename($path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Grav\Framework\Flex\Traits;
|
||||
/**
|
||||
* @package Grav\Framework\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -44,7 +44,7 @@ trait FlexMediaTrait
|
||||
}
|
||||
|
||||
/** @var array */
|
||||
protected $_uploads;
|
||||
protected $_uploads = [];
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
@@ -119,7 +119,7 @@ trait FlexMediaTrait
|
||||
|
||||
// Load settings for the field.
|
||||
$schema = $this->getBlueprint()->schema();
|
||||
$settings = $field && is_object($schema) ? (array)$schema->getProperty($field) : null;
|
||||
$settings = (array)$schema->getProperty($field);
|
||||
if (!is_array($settings)) {
|
||||
return null;
|
||||
}
|
||||
@@ -165,6 +165,9 @@ trait FlexMediaTrait
|
||||
return $settings + ['accept' => '*', 'limit' => 1000, 'self' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getMediaFields(): array
|
||||
{
|
||||
// Load settings for the field.
|
||||
@@ -286,6 +289,7 @@ trait FlexMediaTrait
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __debugInfo()
|
||||
{
|
||||
return parent::__debugInfo() + [
|
||||
@@ -342,7 +346,7 @@ trait FlexMediaTrait
|
||||
}
|
||||
|
||||
// Calculate path without the retina scaling factor.
|
||||
$realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', basename($filepath));
|
||||
$realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', Utils::basename($filepath));
|
||||
|
||||
$list[$filename] = [$file, $settings];
|
||||
|
||||
@@ -397,11 +401,11 @@ trait FlexMediaTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, UploadedFileInterface|array|null>
|
||||
* @return array<string,UploadedFileInterface|array|null>
|
||||
*/
|
||||
protected function getUpdatedMedia(): array
|
||||
{
|
||||
return $this->_uploads ?? [];
|
||||
return $this->_uploads;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -504,7 +508,7 @@ trait FlexMediaTrait
|
||||
user_error(__METHOD__ . '() is deprecated since Grav 1.7, use Media class that implements MediaUploadInterface instead', E_USER_DEPRECATED);
|
||||
|
||||
// Check the file extension.
|
||||
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
$extension = strtolower(Utils::pathinfo($filename, PATHINFO_EXTENSION));
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Common\Flex
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Flex\Traits;
|
||||
|
||||
use Grav\Framework\Flex\FlexCollection;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
use Grav\Framework\Flex\Interfaces\FlexCollectionInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
|
||||
use RuntimeException;
|
||||
use function in_array;
|
||||
|
||||
@@ -26,7 +26,7 @@ trait FlexRelatedDirectoryTrait
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $property
|
||||
* @return FlexCollectionInterface
|
||||
* @return FlexCollectionInterface<FlexObjectInterface>
|
||||
*/
|
||||
protected function getCollectionByProperty($type, $property)
|
||||
{
|
||||
@@ -34,9 +34,9 @@ trait FlexRelatedDirectoryTrait
|
||||
$collection = $directory->getCollection();
|
||||
$list = $this->getNestedProperty($property) ?: [];
|
||||
|
||||
/** @var FlexCollection $collection */
|
||||
/** @var FlexCollectionInterface<FlexObjectInterface> $collection */
|
||||
$collection = $collection->filter(static function ($object) use ($list) {
|
||||
return in_array($object->id, $list, true);
|
||||
return in_array($object->getKey(), $list, true);
|
||||
});
|
||||
|
||||
return $collection;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Form
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -343,7 +343,7 @@ class FormFlash implements FormFlashInterface
|
||||
|
||||
// Prepare upload data for later save
|
||||
$data = [
|
||||
'name' => basename($filename),
|
||||
'name' => Utils::basename($filename),
|
||||
'type' => Utils::getMimeByLocalFile($filename),
|
||||
'size' => filesize($filename),
|
||||
];
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
/**
|
||||
* @package Grav\Framework\Form
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Form;
|
||||
|
||||
use Grav\Common\Security;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Psr7\Stream;
|
||||
use InvalidArgumentException;
|
||||
use JsonSerializable;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use RuntimeException;
|
||||
@@ -23,7 +26,7 @@ use function sprintf;
|
||||
* Class FormFlashFile
|
||||
* @package Grav\Framework\Form
|
||||
*/
|
||||
class FormFlashFile implements UploadedFileInterface, \JsonSerializable
|
||||
class FormFlashFile implements UploadedFileInterface, JsonSerializable
|
||||
{
|
||||
/** @var string */
|
||||
private $field;
|
||||
@@ -175,11 +178,27 @@ class FormFlashFile implements UploadedFileInterface, \JsonSerializable
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->upload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function checkXss(): void
|
||||
{
|
||||
$tmpFile = $this->getTmpFile();
|
||||
$mime = $this->getClientMediaType();
|
||||
if (Utils::contains($mime, 'svg', false)) {
|
||||
$response = Security::detectXssFromSvgFile($tmpFile);
|
||||
if ($response) {
|
||||
throw new RuntimeException(sprintf('SVG file XSS check failed on %s', $response));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
@@ -199,6 +218,7 @@ class FormFlashFile implements UploadedFileInterface, \JsonSerializable
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function __debugInfo()
|
||||
{
|
||||
return [
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Form
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Form
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Form
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Form
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -23,6 +23,7 @@ use Grav\Common\User\Interfaces\UserInterface;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Compat\Serializable;
|
||||
use Grav\Framework\ContentBlock\HtmlBlock;
|
||||
use Grav\Framework\Form\FormFlashFile;
|
||||
use Grav\Framework\Form\Interfaces\FormFlashInterface;
|
||||
use Grav\Framework\Form\Interfaces\FormInterface;
|
||||
use Grav\Framework\Session\SessionInterface;
|
||||
@@ -65,10 +66,10 @@ trait FormTrait
|
||||
private $sessionid;
|
||||
/** @var bool */
|
||||
private $submitted;
|
||||
/** @var ArrayAccess|Data|null */
|
||||
/** @var ArrayAccess<string,mixed>|Data|null */
|
||||
private $data;
|
||||
/** @var array|UploadedFileInterface[] */
|
||||
private $files;
|
||||
/** @var UploadedFileInterface[] */
|
||||
private $files = [];
|
||||
/** @var FormFlashInterface|null */
|
||||
private $flash;
|
||||
/** @var string */
|
||||
@@ -203,7 +204,7 @@ trait FormTrait
|
||||
*/
|
||||
public function getFiles(): array
|
||||
{
|
||||
return $this->files ?? [];
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,8 +222,8 @@ trait FormTrait
|
||||
*/
|
||||
public function getDefaultValue(string $name)
|
||||
{
|
||||
$path = explode('.', $name) ?: [];
|
||||
$offset = array_shift($path) ?? '';
|
||||
$path = explode('.', $name);
|
||||
$offset = array_shift($path);
|
||||
|
||||
$current = $this->getDefaultValues();
|
||||
|
||||
@@ -692,7 +693,7 @@ trait FormTrait
|
||||
throw new RuntimeException(sprintf('FlexForm: Bad HTTP method %s', $method));
|
||||
}
|
||||
|
||||
$body = $request->getParsedBody();
|
||||
$body = (array)$request->getParsedBody();
|
||||
$data = isset($body['data']) ? $this->decodeData($body['data']) : null;
|
||||
|
||||
$flash = $this->getFlash();
|
||||
@@ -721,6 +722,7 @@ trait FormTrait
|
||||
* @param ArrayAccess|Data|null $data
|
||||
* @return void
|
||||
* @throws ValidationException
|
||||
* @phpstan-param ArrayAccess<string,mixed>|Data|null $data
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function validateData($data = null): void
|
||||
@@ -735,6 +737,7 @@ trait FormTrait
|
||||
*
|
||||
* @param ArrayAccess|Data|null $data
|
||||
* @return void
|
||||
* @phpstan-param ArrayAccess<string,mixed>|Data|null $data
|
||||
*/
|
||||
protected function filterData($data = null): void
|
||||
{
|
||||
@@ -773,13 +776,16 @@ trait FormTrait
|
||||
{
|
||||
// Handle bad filenames.
|
||||
$filename = $file->getClientFilename();
|
||||
|
||||
if ($filename && !Utils::checkFilename($filename)) {
|
||||
$grav = Grav::instance();
|
||||
throw new RuntimeException(
|
||||
sprintf($grav['language']->translate('PLUGIN_FORM.FILEUPLOAD_UNABLE_TO_UPLOAD', null, true), $filename, 'Bad filename')
|
||||
);
|
||||
}
|
||||
|
||||
if ($file instanceof FormFlashFile) {
|
||||
$file->checkXss();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -797,9 +803,7 @@ trait FormTrait
|
||||
// Decode JSON encoded fields and merge them to data.
|
||||
if (isset($data['_json'])) {
|
||||
$data = array_replace_recursive($data, $this->jsonDecode($data['_json']));
|
||||
if (null === $data) {
|
||||
throw new RuntimeException(__METHOD__ . '(): Unexpected error');
|
||||
}
|
||||
|
||||
unset($data['_json']);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Interfaces
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Logger
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,15 +3,21 @@
|
||||
/**
|
||||
* @package Grav\Framework\Media
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Media\Interfaces;
|
||||
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
|
||||
/**
|
||||
* Class implements media collection interface.
|
||||
* @extends ArrayAccess<string,MediaObjectInterface>
|
||||
* @extends Iterator<string,MediaObjectInterface>
|
||||
*/
|
||||
interface MediaCollectionInterface extends \ArrayAccess, \Countable, \Iterator
|
||||
interface MediaCollectionInterface extends ArrayAccess, Countable, Iterator
|
||||
{
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Media
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
/**
|
||||
* @package Grav\Framework\Media
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Media
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Mime
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @package Grav\Framework\Object
|
||||
*
|
||||
* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved.
|
||||
* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
@@ -42,8 +42,8 @@ trait NestedPropertyTrait
|
||||
public function getNestedProperty($property, $default = null, $separator = null)
|
||||
{
|
||||
$separator = $separator ?: '.';
|
||||
$path = explode($separator, $property) ?: [];
|
||||
$offset = array_shift($path) ?? '';
|
||||
$path = explode($separator, $property);
|
||||
$offset = array_shift($path);
|
||||
|
||||
if (!$this->hasProperty($offset)) {
|
||||
return $default;
|
||||
@@ -85,8 +85,8 @@ trait NestedPropertyTrait
|
||||
public function setNestedProperty($property, $value, $separator = null)
|
||||
{
|
||||
$separator = $separator ?: '.';
|
||||
$path = explode($separator, $property) ?: [];
|
||||
$offset = array_shift($path) ?? '';
|
||||
$path = explode($separator, $property);
|
||||
$offset = array_shift($path);
|
||||
|
||||
if (!$path) {
|
||||
$this->setProperty($offset, $value);
|
||||
@@ -127,8 +127,8 @@ trait NestedPropertyTrait
|
||||
public function unsetNestedProperty($property, $separator = null)
|
||||
{
|
||||
$separator = $separator ?: '.';
|
||||
$path = explode($separator, $property) ?: [];
|
||||
$offset = array_shift($path) ?? '';
|
||||
$path = explode($separator, $property);
|
||||
$offset = array_shift($path);
|
||||
|
||||
if (!$path) {
|
||||
$this->unsetProperty($offset);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user