page evenement

This commit is contained in:
2021-10-01 15:05:41 +02:00
parent a5073396ea
commit 9494467cc2
1307 changed files with 5140 additions and 962 deletions
+21 -7
View File
@@ -110,7 +110,7 @@ class Assets extends PropertyObject
/** @var UniformResourceLocator $locator */
$locator = $grav['locator'];
$this->assets_dir = $locator->findResource('asset://') . DS;
$this->assets_dir = $locator->findResource('asset://');
$this->assets_url = $locator->findResource('asset://', false);
$this->config($asset_config);
@@ -164,10 +164,19 @@ class Assets extends PropertyObject
// More than one asset
if (is_array($asset)) {
foreach ($asset as $a) {
array_shift($args);
$args = array_merge([$a], $args);
call_user_func_array([$this, 'add'], $args);
foreach ($asset as $index => $location) {
$params = array_slice($args, 1);
if (is_array($location)) {
$params = array_shift($params);
if (is_numeric($params)) {
$params = [ 'priority' => $params ];
}
$params = [array_replace_recursive([], $location, $params)];
$location = $index;
}
$params = array_merge([$location], $params);
call_user_func_array([$this, 'add'], $params);
}
} elseif (isset($this->collections[$asset])) {
array_shift($args);
@@ -201,8 +210,13 @@ class Assets extends PropertyObject
protected function addType($collection, $type, $asset, $options)
{
if (is_array($asset)) {
foreach ($asset as $a) {
$this->addType($collection, $type, $a, $options);
foreach ($asset as $index => $location) {
$assetOptions = $options;
if (is_array($location)) {
$assetOptions = array_replace_recursive([], $options, $location);
$location = $index;
}
$this->addType($collection, $type, $location, $assetOptions);
}
return $this;
+17 -7
View File
@@ -15,6 +15,7 @@ use Grav\Common\Grav;
use Grav\Common\Uri;
use Grav\Common\Utils;
use Grav\Framework\Object\PropertyObject;
use RocketTheme\Toolbox\File\File;
use SplFileInfo;
/**
@@ -91,6 +92,10 @@ abstract class BaseAsset extends PropertyObject
*/
public function init($asset, $options)
{
if (!$asset) {
return false;
}
$config = Grav::instance()['config'];
$uri = Grav::instance()['uri'];
@@ -182,16 +187,21 @@ abstract class BaseAsset extends PropertyObject
public static function integrityHash($input)
{
$grav = Grav::instance();
$uri = $grav['uri'];
$assetsConfig = $grav['config']->get('system.assets');
if ( !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri'] )
{
$dataToHash = file_get_contents( GRAV_WEBROOT . $input);
if (!self::isRemoteLink($input) && !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri']) {
$input = preg_replace('#^' . $uri->rootUrl() . '#', '', $input);
$asset = File::instance(GRAV_WEBROOT . $input);
$hash = hash('sha256', $dataToHash, true);
$hash_base64 = base64_encode($hash);
return ' integrity="sha256-' . $hash_base64 . '"';
if ($asset->exists()) {
$dataToHash = $asset->content();
$hash = hash('sha256', $dataToHash, true);
$hash_base64 = base64_encode($hash);
return ' integrity="sha256-' . $hash_base64 . '"';
}
}
return '';
@@ -253,6 +263,6 @@ abstract class BaseAsset extends PropertyObject
*/
protected function cssRewrite($file, $dir, $local)
{
return;
return '';
}
}
View File
View File
View File
View File
+18 -13
View File
@@ -9,9 +9,9 @@
namespace Grav\Common\Assets;
use Grav\Common\Assets\BaseAsset;
use Grav\Common\Assets\Traits\AssetUtilsTrait;
use Grav\Common\Config\Config;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use Grav\Common\Uri;
use Grav\Common\Utils;
@@ -88,7 +88,14 @@ class Pipeline extends PropertyObject
$uri = Grav::instance()['uri'];
$this->base_url = rtrim($uri->rootUrl($config->get('system.absolute_urls')), '/') . '/';
$this->assets_dir = $locator->findResource('asset://') . DS;
$this->assets_dir = $locator->findResource('asset://');
if (!$this->assets_dir) {
// Attempt to create assets folder if it doesn't exist yet.
$this->assets_dir = $locator->findResource('asset://', true, true);
Folder::mkdir($this->assets_dir);
$locator->clearCache();
}
$this->assets_url = $locator->findResource('asset://', false);
}
@@ -119,10 +126,9 @@ class Pipeline extends PropertyObject
$file = $uid . '.css';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
$buffer = null;
if (file_exists($this->assets_dir . $file)) {
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
$filepath = "{$this->assets_dir}/{$file}";
if (file_exists($filepath)) {
$buffer = file_get_contents($filepath) . "\n";
} else {
//if nothing found get out of here!
if (empty($assets)) {
@@ -141,7 +147,7 @@ class Pipeline extends PropertyObject
// Write file
if (trim($buffer) !== '') {
file_put_contents($this->assets_dir . $file, $buffer);
file_put_contents($filepath, $buffer);
}
}
@@ -182,10 +188,9 @@ class Pipeline extends PropertyObject
$file = $uid . '.js';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
$buffer = null;
if (file_exists($this->assets_dir . $file)) {
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
$filepath = "{$this->assets_dir}/{$file}";
if (file_exists($filepath)) {
$buffer = file_get_contents($filepath) . "\n";
} else {
//if nothing found get out of here!
if (empty($assets)) {
@@ -204,7 +209,7 @@ class Pipeline extends PropertyObject
// Write file
if (trim($buffer) !== '') {
file_put_contents($this->assets_dir . $file, $buffer);
file_put_contents($filepath, $buffer);
}
}
@@ -249,7 +254,7 @@ class Pipeline extends PropertyObject
$old_url = ltrim($old_url, '/');
}
$new_url = ($local ? $this->base_url: '') . $old_url;
$new_url = ($local ? $this->base_url : '') . $old_url;
return str_replace($matches[2], $new_url, $matches[0]);
}, $file);
+6 -4
View File
@@ -68,8 +68,6 @@ trait AssetUtilsTrait
protected function gatherLinks(array $assets, $css = true)
{
$buffer = '';
foreach ($assets as $id => $asset) {
$local = true;
@@ -135,7 +133,7 @@ trait AssetUtilsTrait
$imports = [];
$file = (string)preg_replace_callback($regex, function ($matches) use (&$imports) {
$file = (string)preg_replace_callback($regex, static function ($matches) use (&$imports) {
$imports[] = $matches[0];
return '';
@@ -156,6 +154,10 @@ trait AssetUtilsTrait
$no_key = ['loading'];
foreach ($this->attributes as $key => $value) {
if ($value === null) {
continue;
}
if (is_numeric($key)) {
$key = $value;
}
@@ -196,7 +198,7 @@ trait AssetUtilsTrait
}
if ($this->timestamp) {
if (Utils::contains($asset, '?') || $querystring) {
if ($querystring || Utils::contains($asset, '?')) {
$querystring .= '&' . $this->timestamp;
} else {
$querystring .= '?' . $this->timestamp;
View File
View File
+1 -1
View File
@@ -222,7 +222,7 @@ class Backups
$backup_root = rtrim(GRAV_ROOT . $backup_root, '/');
}
if (!file_exists($backup_root)) {
if (!$backup_root || !file_exists($backup_root)) {
throw new RuntimeException("Backup location: {$backup_root} does not exist...");
}
View File
Regular → Executable
+2 -6
View File
@@ -141,7 +141,7 @@ class Cache extends Getters
$uniqueness = substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
// Cache key allows us to invalidate all cache on configuration changes.
$this->key = ($prefix ? $prefix : 'g') . '-' . $uniqueness;
$this->key = ($prefix ?: 'g') . '-' . $uniqueness;
$this->cache_dir = $grav['locator']->findResource('cache://doctrine/' . $uniqueness, true, true);
$this->driver_setting = $this->config->get('system.cache.driver');
$this->driver = $this->getCacheDriver();
@@ -618,11 +618,7 @@ class Cache extends Getters
*/
public function isVolatileDriver($setting)
{
if (in_array($setting, ['apc', 'apcu', 'xcache', 'wincache'])) {
return true;
}
return false;
return in_array($setting, ['apc', 'apcu', 'xcache', 'wincache'], true);
}
/**
View File
View File
View File
View File
View File
View File
View File
View File
+13 -3
View File
@@ -41,6 +41,9 @@ class Setup extends Data
*/
public static $environment;
/** @var string */
public static $securityFile = 'config://security.yaml';
/** @var array */
protected $streams = [
'user' => [
@@ -390,12 +393,19 @@ class Setup extends Data
if (!$locator->findResource('environment://config', true)) {
// If environment does not have its own directory, remove it from the lookup.
$this->set('streams.schemes.environment.prefixes', ['config' => []]);
$prefixes = $this->get('streams.schemes.environment.prefixes');
$prefixes['config'] = [];
$this->set('streams.schemes.environment.prefixes', $prefixes);
$this->initializeLocator($locator);
}
// Create security.yaml if it doesn't exist.
$filename = $locator->findResource('config://security.yaml', true, true);
// Create security.yaml salt if it doesn't exist into existing configuration environment if possible.
$securityFile = basename(static::$securityFile);
$securityFolder = substr(static::$securityFile, 0, -\strlen($securityFile));
$securityFolder = $locator->findResource($securityFolder, true) ?: $locator->findResource($securityFolder, true, true);
$filename = "{$securityFolder}/{$securityFile}";
$security_file = CompiledYamlFile::instance($filename);
$security_content = (array)$security_file->content();
+2 -2
View File
@@ -37,7 +37,7 @@ class Blueprint extends BlueprintForm
/** @var string|null */
protected $scope;
/** @var BlueprintSchema */
/** @var BlueprintSchema|null */
protected $blueprintSchema;
/** @var object|null */
@@ -54,7 +54,7 @@ class Blueprint extends BlueprintForm
*/
public function __clone()
{
if ($this->blueprintSchema) {
if (null !== $this->blueprintSchema) {
$this->blueprintSchema = clone $this->blueprintSchema;
}
}
+13
View File
@@ -56,6 +56,15 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
return $this->types[$name] ?? [];
}
/**
* @param string $name
* @return array|null
*/
public function getNestedRules(string $name)
{
return $this->getNested($name);
}
/**
* Validate data against blueprints.
*
@@ -317,6 +326,10 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
$toggle = [];
}
// Recursively fetch the items.
$childData = $data[$key] ?? null;
if (null !== $childData && !is_array($childData)) {
throw new \RuntimeException(sprintf("Bad form data for field collection '%s': %s used instead of an array", $key, gettype($childData)));
}
$data[$key] = $this->processFormRecursive($data[$key] ?? null, $toggle, $value);
} else {
$field = $this->get($value);
View File
+1 -1
View File
@@ -264,7 +264,7 @@ class Data implements DataInterface, ArrayAccess, \Countable, JsonSerializable,
*/
public function blueprints()
{
if (!$this->blueprints) {
if (null === $this->blueprints) {
$this->blueprints = new Blueprint();
} elseif (is_callable($this->blueprints)) {
// Lazy load blueprints.
View File
+23 -8
View File
@@ -519,17 +519,32 @@ class Validation
return false;
}
if (isset($params['min']) && $value < $params['min']) {
return false;
$value = (float)$value;
$min = 0;
if (isset($params['min'])) {
$min = (float)$params['min'];
if ($value < $min) {
return false;
}
}
if (isset($params['max']) && $value > $params['max']) {
return false;
if (isset($params['max'])) {
$max = (float)$params['max'];
if ($value > $max) {
return false;
}
}
$min = $params['min'] ?? 0;
if (isset($params['step'])) {
$step = (float)$params['step'];
// Count of how many steps we are above/below the minimum value.
$pos = ($value - $min) / $step;
return !(isset($params['step']) && fmod($value - $min, $params['step']) === 0);
return is_int(static::filterNumber($pos, $params, $field));
}
return true;
}
/**
@@ -593,7 +608,7 @@ class Validation
*/
public static function typeColor($value, array $params, array $field)
{
return preg_match('/^\#[0-9a-fA-F]{3}[0-9a-fA-F]{3}?$/u', $value);
return (bool)preg_match('/^\#[0-9a-fA-F]{3}[0-9a-fA-F]{3}?$/u', $value);
}
/**
@@ -1174,7 +1189,7 @@ class Validation
*/
public static function filterItem_List($value, $params)
{
return array_values(array_filter($value, function ($v) {
return array_values(array_filter($value, static function ($v) {
return !empty($v);
}));
}
View File
+1 -1
View File
@@ -332,7 +332,7 @@ class Debugger
return new Response(404, $headers, json_encode($response));
}
$data = is_array($data) ? array_map(function ($item) {
$data = is_array($data) ? array_map(static function ($item) {
return $item->toArray();
}, $data) : $data->toArray();
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
+4 -3
View File
@@ -197,7 +197,7 @@ abstract class Folder
* Shift first directory out of the path.
*
* @param string $path
* @return string
* @return string|null
*/
public static function shift(&$path)
{
@@ -371,7 +371,7 @@ abstract class Folder
return;
}
if (strpos($target, $source) === 0) {
if (strpos($target, $source . '/') === 0) {
throw new RuntimeException('Cannot move folder to itself');
}
@@ -417,7 +417,8 @@ abstract class Folder
if (!$success) {
$error = error_get_last();
throw new RuntimeException($error['message']);
throw new RuntimeException($error['message'] ?? 'Unknown error');
}
// Make sure that the change will be detected when caching.
View File
View File
+3 -4
View File
@@ -57,7 +57,9 @@ class ZipArchiver extends Archiver
throw new InvalidArgumentException('ZipArchiver: Zip PHP module not installed...');
}
if (!file_exists($source)) {
// Get real path for our folder
$rootPath = realpath($source);
if (!$rootPath) {
throw new InvalidArgumentException('ZipArchiver: ' . $source . ' cannot be found...');
}
@@ -66,9 +68,6 @@ class ZipArchiver extends Archiver
throw new InvalidArgumentException('ZipArchiver:' . $this->archive_file . ' cannot be created...');
}
// Get real path for our folder
$rootPath = realpath($source);
$files = $this->getArchiveFiles($rootPath);
$status && $status([
View File
View File
+3 -2
View File
@@ -13,6 +13,7 @@ namespace Grav\Common\Flex;
use Grav\Common\Flex\Traits\FlexGravTrait;
use Grav\Common\Flex\Traits\FlexObjectTrait;
use Grav\Common\Media\Interfaces\MediaInterface;
use Grav\Framework\Flex\Traits\FlexMediaTrait;
use function is_array;
@@ -21,7 +22,7 @@ use function is_array;
*
* @package Grav\Common\Flex
*/
abstract class FlexObject extends \Grav\Framework\Flex\FlexObject
abstract class FlexObject extends \Grav\Framework\Flex\FlexObject implements MediaInterface
{
use FlexGravTrait;
use FlexObjectTrait;
@@ -42,7 +43,7 @@ abstract class FlexObject extends \Grav\Framework\Flex\FlexObject
// Handle media fields.
$settings = $this->getFieldSettings($name);
if ($settings['media_field'] ?? false === true) {
if (($settings['media_field'] ?? false) === true) {
return $this->parseFileProperty($value, $settings);
}
View File
View File
View File
View File
View File
View File
View File
View File
+19 -12
View File
@@ -19,7 +19,6 @@ use Grav\Common\Page\Header;
use Grav\Common\Page\Interfaces\PageCollectionInterface;
use Grav\Common\Page\Interfaces\PageInterface;
use Grav\Common\Utils;
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
use Grav\Framework\Flex\Pages\FlexPageCollection;
use Collator;
use InvalidArgumentException;
@@ -159,7 +158,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa
*/
public function addPage(PageInterface $page)
{
if (!$page instanceof FlexObjectInterface) {
if (!$page instanceof PageObject) {
throw new InvalidArgumentException('$page is not a flex page.');
}
@@ -192,6 +191,14 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa
throw new RuntimeException(__METHOD__ . '(): Not Implemented');
}
/**
* Set current page.
*/
public function setCurrent(string $path): void
{
throw new RuntimeException(__METHOD__ . '(): Not Implemented');
}
/**
* Return previous item.
*
@@ -392,8 +399,8 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa
$i = count($manual);
$new_list = [];
foreach ($list as $key => $dummy) {
$child = $this[$key];
$order = array_search($child->slug, $manual, true);
$child = $this[$key] ?? null;
$order = $child ? array_search($child->slug, $manual, true) : false;
if ($order === false) {
$order = $i++;
}
@@ -426,20 +433,20 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa
/**
* Returns the items between a set of date ranges of either the page date field (default) or
* an arbitrary datetime page field where end date is optional
* Dates can be passed in as text that strtotime() can process
* an arbitrary datetime page field where start date and end date are optional
* Dates must be passed in as text that strtotime() can process
* http://php.net/manual/en/function.strtotime.php
*
* @param string $startDate
* @param string|false $endDate
* @param string|null $startDate
* @param string|null $endDate
* @param string|null $field
* @return static
* @throws Exception
*/
public function dateRange($startDate, $endDate = false, $field = null)
public function dateRange($startDate = null, $endDate = null, $field = null)
{
$start = Utils::date2timestamp($startDate);
$end = $endDate ? Utils::date2timestamp($endDate) : false;
$start = $startDate ? Utils::date2timestamp($startDate) : null;
$end = $endDate ? Utils::date2timestamp($endDate) : null;
$entries = [];
foreach ($this as $key => $object) {
@@ -449,7 +456,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa
$date = $field ? strtotime($object->getNestedProperty($field)) : $object->date();
if ($date >= $start && (!$end || $date <= $end)) {
if ((!$start || $date >= $start) && (!$end || $date <= $end)) {
$entries[$key] = $object;
}
}
+20 -13
View File
@@ -109,6 +109,10 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
}
$element = parent::get($key);
if (null === $element) {
return null;
}
if (isset($params)) {
$element = $element->getTranslation(ltrim($params, '.'));
}
@@ -331,7 +335,10 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
*/
protected function filterByParent(array $filters)
{
return parent::filterBy($filters);
/** @var static $index */
$index = parent::filterBy($filters);
return $index;
}
/**
@@ -673,13 +680,14 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
$child_count = $tmp->count();
$count = $filters ? $tmp->filterBy($filters, true)->count() : null;
$route = $child->getRoute();
$route = $route ? ($route->toString(false) ?: '/') : '';
$payload = [
'item-key' => basename($child->rawRoute() ?? $child->getKey()),
'item-key' => htmlspecialchars(basename($child->rawRoute() ?? $child->getKey())),
'icon' => $icon,
'title' => htmlspecialchars($child->menu()),
'route' => [
'display' => ($route ? ($route->toString(false) ?: '/') : null) ?? '',
'raw' => $child->rawRoute(),
'display' => htmlspecialchars($route) ?: null,
'raw' => htmlspecialchars($child->rawRoute()),
],
'modified' => $this->jsDate($child->modified()),
'child_count' => $child_count ?: null,
@@ -834,12 +842,11 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
/**
* Remove item from the list.
*
* @param PageInterface|string|null $key
*
* @return $this
* @param string $key
* @return PageObject|null
* @throws InvalidArgumentException
*/
public function remove($key = null)
public function remove($key)
{
return $this->getCollection()->remove($key);
}
@@ -949,17 +956,17 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
/**
* Returns the items between a set of date ranges of either the page date field (default) or
* an arbitrary datetime page field where end date is optional
* Dates can be passed in as text that strtotime() can process
* an arbitrary datetime page field where start date and end date are optional
* Dates must be passed in as text that strtotime() can process
* http://php.net/manual/en/function.strtotime.php
*
* @param string $startDate
* @param bool $endDate
* @param string|null $startDate
* @param string|null $endDate
* @param string|null $field
* @return static
* @throws Exception
*/
public function dateRange($startDate, $endDate = false, $field = null)
public function dateRange($startDate = null, $endDate = null, $field = null)
{
$collection = $this->__call('dateRange', [$startDate, $endDate, $field]);
+46 -12
View File
@@ -104,12 +104,12 @@ class PageObject extends FlexPageObject
*/
public function getRoute($query = []): ?Route
{
$route = $this->route();
if (null === $route) {
$path = $this->route();
if (null === $path) {
return null;
}
$route = RouteFactory::createFromString($route);
$route = RouteFactory::createFromString($path);
if ($lang = $route->getLanguage()) {
$grav = Grav::instance();
if (!$grav['config']->get('system.languages.include_default_lang')) {
@@ -262,6 +262,24 @@ class PageObject extends FlexPageObject
$this->getFlexDirectory()->reloadIndex();
}
/**
* @param UserInterface|null $user
*/
public function check(UserInterface $user = null): void
{
parent::check($user);
if ($user && $this->isMoved()) {
$parentKey = $this->getProperty('parent_key');
/** @var PageObject|null $parent */
$parent = $this->getFlexDirectory()->getObject($parentKey, 'storage_key');
if (!$parent || !$parent->isAuthorized('create', null, $user)) {
throw new \RuntimeException('Forbidden', 403);
}
}
}
/**
* @param array|bool $reorder
* @return FlexObject|FlexObjectInterface
@@ -293,7 +311,7 @@ class PageObject extends FlexPageObject
}
// Reset original after save events have all been called.
$this->_original = null;
$this->_originalObject = null;
return $instance;
}
@@ -357,6 +375,19 @@ class PageObject extends FlexPageObject
return parent::isAuthorizedOverride($user, $action, $scope, $isMe);
}
/**
* @return bool
*/
protected function isMoved(): bool
{
$storageKey = $this->getMasterKey();
$filesystem = Filesystem::getInstance(false);
$oldParentKey = ltrim($filesystem->dirname("/{$storageKey}"), '/');
$newParentKey = $this->getProperty('parent_key');
return $this->exists() && $oldParentKey !== $newParentKey;
}
/**
* @param array $ordering
* @return PageCollection|null
@@ -364,10 +395,7 @@ class PageObject extends FlexPageObject
protected function reorderSiblings(array $ordering)
{
$storageKey = $this->getMasterKey();
$filesystem = Filesystem::getInstance(false);
$oldParentKey = ltrim($filesystem->dirname("/{$storageKey}"), '/');
$newParentKey = $this->getProperty('parent_key');
$isMoved = $oldParentKey !== $newParentKey;
$isMoved = $this->isMoved();
$order = !$isMoved ? $this->order() : false;
if ($order !== false) {
$order = (int)$order;
@@ -385,10 +413,12 @@ class PageObject extends FlexPageObject
// Handle special case where ordering isn't given.
if ($ordering === []) {
if ($order >= 999999) {
// Set ordering to point to be the last item.
// Set ordering to point to be the last item, ignoring the object itself.
$order = 0;
foreach ($siblings as $sibling) {
$order = max($order, (int)$sibling->order());
if ($sibling->getKey() !== $this->getKey()) {
$order = max($order, (int)$sibling->order());
}
}
$this->order($order + 1);
}
@@ -411,7 +441,8 @@ class PageObject extends FlexPageObject
// Add missing siblings into the end of the list, keeping the previous ordering between them.
foreach ($siblings as $sibling) {
$basename = preg_replace('|^\d+\.|', '', $sibling->getProperty('folder'));
$folder = (string)$sibling->getProperty('folder');
$basename = preg_replace('|^\d+\.|', '', $folder);
if (!in_array($basename, $ordering, true)) {
$ordering[] = $basename;
}
@@ -421,7 +452,8 @@ class PageObject extends FlexPageObject
$ordering = array_flip(array_values($ordering));
$count = count($ordering);
foreach ($siblings as $sibling) {
$basename = preg_replace('|^\d+\.|', '', $sibling->getProperty('folder'));
$folder = (string)$sibling->getProperty('folder');
$basename = preg_replace('|^\d+\.|', '', $folder);
$newOrder = $ordering[$basename] ?? null;
$newOrder = null !== $newOrder ? $newOrder + 1 : (int)$sibling->order() + $count;
$sibling->order($newOrder);
@@ -500,6 +532,8 @@ class PageObject extends FlexPageObject
if ($isNew === true && $name === '') {
// Support onBlueprintCreated event just like in Pages::blueprints($template)
$blueprint->set('initialized', true);
$blueprint->setFilename($template);
Grav::instance()->fireEvent('onBlueprintCreated', new Event(['blueprint' => $blueprint, 'type' => $template]));
}
View File
View File
+4 -1
View File
@@ -103,7 +103,10 @@ trait PageLegacyTrait
$parent = $this->parent();
$collection = $parent ? $parent->collection('content', false) : null;
if (null !== $path && $collection instanceof PageCollectionInterface) {
return $collection->adjacentSibling($path, $direction);
$child = $collection->adjacentSibling($path, $direction);
if ($child instanceof PageInterface) {
return $child;
}
}
return false;
View File
View File
View File
View File
+8
View File
@@ -41,6 +41,14 @@ class UserGroupObject extends FlexObject implements UserGroupInterface
] + parent::getCachedMethods();
}
/**
* @return string
*/
public function getTitle(): string
{
return $this->getProperty('readableName');
}
/**
* Checks user authorization to the action.
*
View File
View File
+2 -2
View File
@@ -92,7 +92,7 @@ class UserCollection extends FlexCollection implements UserCollectionInterface
} else {
$user = parent::find($query, $field);
}
if ($user) {
if ($user instanceof UserObject) {
return $user;
}
}
@@ -123,7 +123,7 @@ class UserCollection extends FlexCollection implements UserCollectionInterface
* @param string $key
* @return string
*/
protected function filterUsername(string $key)
protected function filterUsername(string $key): string
{
$storage = $this->getFlexDirectory()->getStorage();
if (method_exists($storage, 'normalizeKey')) {
+2 -2
View File
@@ -62,7 +62,7 @@ class UserIndex extends FlexIndex implements UserCollectionInterface
* @param FlexStorageInterface $storage
* @return void
*/
public static function updateObjectMeta(array &$meta, array $data, FlexStorageInterface $storage)
public static function updateObjectMeta(array &$meta, array $data, FlexStorageInterface $storage): void
{
// Username can also be number and stored as such.
$key = (string)($data['username'] ?? $meta['key'] ?? $meta['storage_key']);
@@ -187,7 +187,7 @@ class UserIndex extends FlexIndex implements UserCollectionInterface
* @param array $updated
* @param array $removed
*/
protected static function onChanges(array $entries, array $added, array $updated, array $removed)
protected static function onChanges(array $entries, array $added, array $updated, array $removed): void
{
$message = sprintf('Flex: User index updated, %d objects (%d added, %d updated, %d removed).', count($entries), count($added), count($updated), count($removed));
+39 -5
View File
@@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Grav\Common\Flex\Types\Users;
use Closure;
use Countable;
use Grav\Common\Config\Config;
use Grav\Common\Data\Blueprint;
@@ -31,6 +32,7 @@ use Grav\Common\User\Interfaces\UserInterface;
use Grav\Common\User\Traits\UserTrait;
use Grav\Framework\File\Formatter\JsonFormatter;
use Grav\Framework\File\Formatter\YamlFormatter;
use Grav\Framework\Filesystem\Filesystem;
use Grav\Framework\Flex\Flex;
use Grav\Framework\Flex\FlexDirectory;
use Grav\Framework\Flex\Storage\FileStorage;
@@ -75,6 +77,9 @@ class UserObject extends FlexObject implements UserInterface, Countable
use UserTrait;
use UserObjectLegacyTrait;
/** @var Closure|null */
static public $authorizeCallable;
/** @var array|null */
protected $_uploads_original;
/** @var FileInterface|null */
@@ -259,6 +264,15 @@ class UserObject extends FlexObject implements UserInterface, Countable
}
}
$authorizeCallable = static::$authorizeCallable;
if ($authorizeCallable instanceof Closure) {
$authorizeCallable->bindTo($this);
$authorized = $authorizeCallable($action, $scope);
if (is_bool($authorized)) {
return $authorized;
}
}
// Check user access.
$access = $this->getAccess();
$authorized = $access->authorize($action, $scope);
@@ -292,6 +306,14 @@ class UserObject extends FlexObject implements UserInterface, Countable
return $value;
}
/**
* @return UserGroupIndex
*/
public function getRoles(): UserGroupIndex
{
return $this->getGroups();
}
/**
* Convert object into an array.
*
@@ -689,6 +711,7 @@ class UserObject extends FlexObject implements UserInterface, Countable
/**
* @param array $files
* @return void
*/
protected function setUpdatedMedia(array $files): void
{
@@ -696,10 +719,16 @@ class UserObject extends FlexObject implements UserInterface, Countable
$locator = Grav::instance()['locator'];
$media = $this->getMedia();
if (!$media instanceof MediaUploadInterface) {
return;
}
$filesystem = Filesystem::getInstance(false);
$list = [];
$list_original = [];
foreach ($files as $field => $group) {
// Ignore files without a field.
if ($field === '') {
continue;
}
@@ -707,7 +736,6 @@ class UserObject extends FlexObject implements UserInterface, Countable
// Load settings for the field.
$settings = $this->getMediaFieldSettings($field);
foreach ($group as $filename => $file) {
if ($file) {
// File upload.
@@ -722,8 +750,8 @@ class UserObject extends FlexObject implements UserInterface, Countable
}
if ($file) {
// Check file upload against media limits.
$filename = $media->checkUploadedFile($file, $filename, $settings);
// Check file upload against media limits (except for max size).
$filename = $media->checkUploadedFile($file, $filename, ['filesize' => 0] + $settings);
}
$self = $settings['self'];
@@ -746,19 +774,25 @@ class UserObject extends FlexObject implements UserInterface, Countable
continue;
}
// Calculate path without the retina scaling factor.
$realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', basename($filepath));
$list[$filename] = [$file, $settings];
$path = str_replace('.', "\n", $field);
if (null !== $data) {
$data['name'] = $filename;
$data['path'] = $filepath;
$this->setNestedProperty("{$field}\n{$filepath}", $data, "\n");
$this->setNestedProperty("{$path}\n{$realpath}", $data, "\n");
} else {
$this->unsetNestedProperty("{$field}\n{$filepath}", "\n");
$this->unsetNestedProperty("{$path}\n{$realpath}", "\n");
}
}
}
$this->clearMediaCache();
$this->_uploads = $list;
$this->_uploads_original = $list_original;
}
View File
View File
View File
View File
View File
+99 -37
View File
@@ -35,7 +35,11 @@ class GPM extends Iterator
/** @var Remote\Packages|null Remote available Packages */
private $repository;
/** @var Remote\GravCore|null Remove Grav Packages */
public $grav;
private $grav;
/** @var bool */
private $refresh;
/** @var callable|null */
private $callback;
/** @var array Internal cache */
protected $cache;
@@ -55,13 +59,45 @@ class GPM extends Iterator
public function __construct($refresh = false, $callback = null)
{
parent::__construct();
Folder::create(CACHE_DIR . '/gpm');
$this->cache = [];
$this->installed = new Local\Packages();
try {
$this->repository = new Remote\Packages($refresh, $callback);
$this->grav = new Remote\GravCore($refresh, $callback);
} catch (Exception $e) {
$this->refresh = $refresh;
$this->callback = $callback;
}
/**
* Magic getter method
*
* @param string $offset Asset name value
* @return mixed Asset value
*/
public function __get($offset)
{
switch ($offset) {
case 'grav':
return $this->getGrav();
}
return parent::__get($offset);
}
/**
* Magic method to determine if the attribute is set
*
* @param string $offset Asset name value
* @return bool True if the value is set
*/
public function __isset($offset)
{
switch ($offset) {
case 'grav':
return $this->getGrav() !== null;
}
return parent::__isset($offset);
}
/**
@@ -266,11 +302,12 @@ class GPM extends Iterator
{
$items = [];
if (null === $this->repository) {
$repository = $this->getRepository();
if (null === $repository) {
return $items;
}
$repository = $this->repository['plugins'];
$plugins = $repository['plugins'];
// local cache to speed things up
if (isset($this->cache[__METHOD__])) {
@@ -278,18 +315,18 @@ class GPM extends Iterator
}
foreach ($this->installed['plugins'] as $slug => $plugin) {
if (!isset($repository[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) {
if (!isset($plugins[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) {
continue;
}
$local_version = $plugin->version ?? 'Unknown';
$remote_version = $repository[$slug]->version;
$remote_version = $plugins[$slug]->version;
if (version_compare($local_version, $remote_version) < 0) {
$repository[$slug]->available = $remote_version;
$repository[$slug]->version = $local_version;
$repository[$slug]->type = $repository[$slug]->release_type;
$items[$slug] = $repository[$slug];
$plugins[$slug]->available = $remote_version;
$plugins[$slug]->version = $local_version;
$plugins[$slug]->type = $plugins[$slug]->release_type;
$items[$slug] = $plugins[$slug];
}
}
@@ -306,19 +343,20 @@ class GPM extends Iterator
*/
public function getLatestVersionOfPackage($package_name)
{
if (null === $this->repository) {
$repository = $this->getRepository();
if (null === $repository) {
return null;
}
$repository = $this->repository['plugins'];
if (isset($repository[$package_name])) {
return $repository[$package_name]->available ?: $repository[$package_name]->version;
$plugins = $repository['plugins'];
if (isset($plugins[$package_name])) {
return $plugins[$package_name]->available ?: $plugins[$package_name]->version;
}
//Not a plugin, it's a theme?
$repository = $this->repository['themes'];
if (isset($repository[$package_name])) {
return $repository[$package_name]->available ?: $repository[$package_name]->version;
$themes = $repository['themes'];
if (isset($themes[$package_name])) {
return $themes[$package_name]->available ?: $themes[$package_name]->version;
}
return null;
@@ -356,11 +394,12 @@ class GPM extends Iterator
{
$items = [];
if (null === $this->repository) {
$repository = $this->getRepository();
if (null === $repository) {
return $items;
}
$repository = $this->repository['themes'];
$themes = $repository['themes'];
// local cache to speed things up
if (isset($this->cache[__METHOD__])) {
@@ -368,18 +407,18 @@ class GPM extends Iterator
}
foreach ($this->installed['themes'] as $slug => $plugin) {
if (!isset($repository[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) {
if (!isset($themes[$slug]) || $plugin->symlink || !$plugin->version || $plugin->gpm === false) {
continue;
}
$local_version = $plugin->version ?? 'Unknown';
$remote_version = $repository[$slug]->version;
$remote_version = $themes[$slug]->version;
if (version_compare($local_version, $remote_version) < 0) {
$repository[$slug]->available = $remote_version;
$repository[$slug]->version = $local_version;
$repository[$slug]->type = $repository[$slug]->release_type;
$items[$slug] = $repository[$slug];
$themes[$slug]->available = $remote_version;
$themes[$slug]->version = $local_version;
$themes[$slug]->type = $themes[$slug]->release_type;
$items[$slug] = $themes[$slug];
}
}
@@ -407,19 +446,20 @@ class GPM extends Iterator
*/
public function getReleaseType($package_name)
{
if (null === $this->repository) {
$repository = $this->getRepository();
if (null === $repository) {
return null;
}
$repository = $this->repository['plugins'];
if (isset($repository[$package_name])) {
return $repository[$package_name]->release_type;
$plugins = $repository['plugins'];
if (isset($plugins[$package_name])) {
return $plugins[$package_name]->release_type;
}
//Not a plugin, it's a theme?
$repository = $this->repository['themes'];
if (isset($repository[$package_name])) {
return $repository[$package_name]->release_type;
$themes = $repository['themes'];
if (isset($themes[$package_name])) {
return $themes[$package_name]->release_type;
}
return null;
@@ -470,7 +510,7 @@ class GPM extends Iterator
*/
public function getRepositoryPlugins()
{
return $this->repository['plugins'] ?? null;
return $this->getRepository()['plugins'] ?? null;
}
/**
@@ -493,7 +533,7 @@ class GPM extends Iterator
*/
public function getRepositoryThemes()
{
return $this->repository['themes'] ?? null;
return $this->getRepository()['themes'] ?? null;
}
/**
@@ -504,9 +544,31 @@ class GPM extends Iterator
*/
public function getRepository()
{
if (null === $this->repository) {
try {
$this->repository = new Remote\Packages($this->refresh, $this->callback);
} catch (Exception $e) {}
}
return $this->repository;
}
/**
* Returns Grav version available in the repository
*
* @return Remote\GravCore|null
*/
public function getGrav()
{
if (null === $this->grav) {
try {
$this->grav = new Remote\GravCore($this->refresh, $this->callback);
} catch (Exception $e) {}
}
return $this->grav;
}
/**
* Searches for a Package in the repository
*
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
Regular → Executable
+19 -13
View File
@@ -9,6 +9,7 @@
namespace Grav\Common;
use Composer\Autoload\ClassLoader;
use Grav\Common\Config\Config;
use Grav\Common\Config\Setup;
use Grav\Common\Helpers\Exif;
@@ -134,7 +135,7 @@ class Grav extends Container
*
* @return void
*/
public static function resetInstance()
public static function resetInstance(): void
{
if (self::$instance) {
// @phpstan-ignore-next-line
@@ -152,6 +153,13 @@ class Grav extends Container
{
if (null === self::$instance) {
self::$instance = static::load($values);
/** @var ClassLoader|null $loader */
$loader = self::$instance['loader'] ?? null;
if ($loader) {
// Load fix for Deferred Twig Extension
$loader->addPsr4('Phive\\Twig\\Extensions\\Deferred\\', LIB_DIR . 'Phive/Twig/Extensions/Deferred/', true);
}
} elseif ($values) {
$instance = self::$instance;
foreach ($values as $key => $value) {
@@ -234,7 +242,7 @@ class Grav extends Container
*
* @return void
*/
public function process()
public function process(): void
{
if (isset($this->initialized['process'])) {
return;
@@ -466,7 +474,7 @@ class Grav extends Container
* @param int $code Redirection code (30x)
* @return void
*/
public function redirectLangSafe($route, $code = null)
public function redirectLangSafe($route, $code = null): void
{
if (!$this['uri']->isExternal($route)) {
$this->redirect($this['pages']->route($route), $code);
@@ -481,7 +489,7 @@ class Grav extends Container
* @param ResponseInterface|null $response
* @return void
*/
public function header(ResponseInterface $response = null)
public function header(ResponseInterface $response = null): void
{
if (null === $response) {
/** @var PageInterface $page */
@@ -506,7 +514,7 @@ class Grav extends Container
*
* @return void
*/
public function setLocale()
public function setLocale(): void
{
// Initialize Locale if set and configured.
if ($this['language']->enabled() && $this['config']->get('system.languages.override_locale')) {
@@ -567,7 +575,7 @@ class Grav extends Container
*
* @return void
*/
public function shutdown()
public function shutdown(): void
{
// Prevent user abort allowing onShutdown event to run without interruptions.
if (function_exists('ignore_user_abort')) {
@@ -686,7 +694,7 @@ class Grav extends Container
*
* @return void
*/
protected function registerServices()
protected function registerServices(): void
{
foreach (self::$diMap as $serviceKey => $serviceClass) {
if (is_int($serviceKey)) {
@@ -753,12 +761,10 @@ class Grav extends Container
// unsupported media type, try to download it...
if ($uri_extension) {
$extension = $uri_extension;
} elseif (isset($path_parts['extension'])) {
$extension = $path_parts['extension'];
} else {
if (isset($path_parts['extension'])) {
$extension = $path_parts['extension'];
} else {
$extension = null;
}
$extension = null;
}
if ($extension) {
@@ -773,6 +779,6 @@ class Grav extends Container
return false;
}
return $page;
return $page ?? false;
}
}
View File
View File
+6 -1
View File
@@ -33,6 +33,9 @@ class Excerpts
public static function processImageHtml($html, PageInterface $page = null)
{
$excerpt = static::getExcerptFromHtml($html, 'img');
if (null === $excerpt) {
return '';
}
$original_src = $excerpt['element']['attributes']['src'];
$excerpt['element']['attributes']['href'] = $original_src;
@@ -61,6 +64,9 @@ class Excerpts
public static function processLinkHtml($html, PageInterface $page = null)
{
$excerpt = static::getExcerptFromHtml($html, 'a');
if (null === $excerpt) {
return '';
}
$original_href = $excerpt['element']['attributes']['href'];
$excerpt = static::processLinkExcerpt($excerpt, $page, 'link');
@@ -89,7 +95,6 @@ class Excerpts
$excerpt = null;
$inner = [];
/** @var DOMElement $element */
foreach ($elements as $element) {
$attributes = [];
foreach ($element->attributes as $name => $value) {
View File

Some files were not shown because too many files have changed in this diff Show More