updated core to 1.7.16

This commit is contained in:
Bachir Soussi Chiadmi 2021-06-10 16:04:05 +02:00
parent 7a4bfa16c8
commit 6dfae7006b
15 changed files with 140 additions and 51 deletions

View File

@ -1,3 +1,21 @@
# v1.7.16
## 06/02/2021
1. [](#new)
* Added 'addFrame()' method to ImageMedium [#3323](https://github.com/getgrav/grav/pull/3323)
1. [](#improved)
* Set `cache.clear_images_by_default` to `false` by default
* Improve error on bad nested form data [#3364](https://github.com/getgrav/grav/issues/3364)
1. [](#bugfix)
* Improve Plugin and Theme initialization to fix PHP8 bug [#3368](https://github.com/getgrav/grav/issues/3368)
* Fixed `pathinfo()` twig filter in PHP7
* Fixed the first visible child page getting ordering number `999999.` [#3365](https://github.com/getgrav/grav/issues/3365)
* Fixed flex pages search using only folder name [#3316](https://github.com/getgrav/grav/issues/3316)
* Fixed flex pages using wrong type in `onBlueprintCreated` event [#3157](https://github.com/getgrav/grav/issues/3157)
* Fixed wrong SRI paths invoked when Grav instance as a sub folder [#3358](https://github.com/getgrav/grav/issues/3358)
* Fixed SRI trying to calculate remote assets, only ever set integrity for local files. Use the SRI provided by the remote source and manually add it in the `addJs/addCss` call for remote support. [#3358](https://github.com/getgrav/grav/issues/3358)
* Fix for weird regex issue with latest PHP versions on Intel Macs causing params to not parse properly in URI object
# v1.7.15 # v1.7.15
## 05/19/2021 ## 05/19/2021

View File

@ -646,7 +646,7 @@ form:
type: toggle type: toggle
label: PLUGIN_ADMIN.CLEAR_IMAGES_BY_DEFAULT label: PLUGIN_ADMIN.CLEAR_IMAGES_BY_DEFAULT
help: PLUGIN_ADMIN.CLEAR_IMAGES_BY_DEFAULT_HELP help: PLUGIN_ADMIN.CLEAR_IMAGES_BY_DEFAULT_HELP
highlight: 1 highlight: 0
options: options:
1: PLUGIN_ADMIN.YES 1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO 0: PLUGIN_ADMIN.NO

View File

@ -96,7 +96,7 @@ cache:
purge_at: '0 4 * * *' # How often to purge old file cache (using new scheduler) purge_at: '0 4 * * *' # How often to purge old file cache (using new scheduler)
clear_at: '0 3 * * *' # How often to clear cache (using new scheduler) clear_at: '0 3 * * *' # How often to clear cache (using new scheduler)
clear_job_type: 'standard' # Type to clear when processing the scheduled clear job `standard`|`all` clear_job_type: 'standard' # Type to clear when processing the scheduled clear job `standard`|`all`
clear_images_by_default: true # By default grav will include processed images in cache clear, this can be disabled clear_images_by_default: false # By default grav will include processed images in cache clear, this can be disabled
cli_compatibility: false # Ensures only non-volatile drivers are used (file, redis, memcache, etc.) cli_compatibility: false # Ensures only non-volatile drivers are used (file, redis, memcache, etc.)
lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite) lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite)
gzip: false # GZip compress the page output gzip: false # GZip compress the page output

View File

@ -9,7 +9,7 @@
// Some standard defines // Some standard defines
define('GRAV', true); define('GRAV', true);
define('GRAV_VERSION', '1.7.15'); define('GRAV_VERSION', '1.7.16');
define('GRAV_SCHEMA', '1.7.0_2020-11-20_1'); define('GRAV_SCHEMA', '1.7.0_2020-11-20_1');
define('GRAV_TESTING', false); define('GRAV_TESTING', false);

View File

@ -15,6 +15,7 @@ use Grav\Common\Grav;
use Grav\Common\Uri; use Grav\Common\Uri;
use Grav\Common\Utils; use Grav\Common\Utils;
use Grav\Framework\Object\PropertyObject; use Grav\Framework\Object\PropertyObject;
use RocketTheme\Toolbox\File\File;
use SplFileInfo; use SplFileInfo;
/** /**
@ -182,16 +183,21 @@ abstract class BaseAsset extends PropertyObject
public static function integrityHash($input) public static function integrityHash($input)
{ {
$grav = Grav::instance(); $grav = Grav::instance();
$uri = $grav['uri'];
$assetsConfig = $grav['config']->get('system.assets'); $assetsConfig = $grav['config']->get('system.assets');
if ( !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri'] ) if (!self::isRemoteLink($input) && !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri']) {
{ $input = preg_replace('#^' . $uri->rootUrl() . '#', '', $input);
$dataToHash = file_get_contents( GRAV_WEBROOT . $input); $asset = File::instance(GRAV_WEBROOT . $input);
$hash = hash('sha256', $dataToHash, true); if ($asset->exists()) {
$hash_base64 = base64_encode($hash); $dataToHash = $asset->content();
return ' integrity="sha256-' . $hash_base64 . '"'; $hash = hash('sha256', $dataToHash, true);
$hash_base64 = base64_encode($hash);
return ' integrity="sha256-' . $hash_base64 . '"';
}
} }
return ''; return '';

View File

@ -317,6 +317,10 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
$toggle = []; $toggle = [];
} }
// Recursively fetch the items. // 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); $data[$key] = $this->processFormRecursive($data[$key] ?? null, $toggle, $value);
} else { } else {
$field = $this->get($value); $field = $this->get($value);

View File

@ -367,7 +367,7 @@ class PageObject extends FlexPageObject
$filesystem = Filesystem::getInstance(false); $filesystem = Filesystem::getInstance(false);
$oldParentKey = ltrim($filesystem->dirname("/{$storageKey}"), '/'); $oldParentKey = ltrim($filesystem->dirname("/{$storageKey}"), '/');
$newParentKey = $this->getProperty('parent_key'); $newParentKey = $this->getProperty('parent_key');
$isMoved = $oldParentKey !== $newParentKey; $isMoved = $this->exists() && $oldParentKey !== $newParentKey;
$order = !$isMoved ? $this->order() : false; $order = !$isMoved ? $this->order() : false;
if ($order !== false) { if ($order !== false) {
$order = (int)$order; $order = (int)$order;
@ -385,10 +385,12 @@ class PageObject extends FlexPageObject
// Handle special case where ordering isn't given. // Handle special case where ordering isn't given.
if ($ordering === []) { if ($ordering === []) {
if ($order >= 999999) { 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; $order = 0;
foreach ($siblings as $sibling) { 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); $this->order($order + 1);
} }
@ -500,6 +502,8 @@ class PageObject extends FlexPageObject
if ($isNew === true && $name === '') { if ($isNew === true && $name === '') {
// Support onBlueprintCreated event just like in Pages::blueprints($template) // Support onBlueprintCreated event just like in Pages::blueprints($template)
$blueprint->set('initialized', true); $blueprint->set('initialized', true);
$blueprint->setFilename($template);
Grav::instance()->fireEvent('onBlueprintCreated', new Event(['blueprint' => $blueprint, 'type' => $template])); Grav::instance()->fireEvent('onBlueprintCreated', new Event(['blueprint' => $blueprint, 'type' => $template]));
} }

View File

@ -56,7 +56,7 @@ trait ImageMediaTrait
'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop', 'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop',
'negate', 'brightness', 'contrast', 'grayscale', 'emboss', 'negate', 'brightness', 'contrast', 'grayscale', 'emboss',
'smooth', 'sharp', 'edge', 'colorize', 'sepia', 'enableProgressive', 'smooth', 'sharp', 'edge', 'colorize', 'sepia', 'enableProgressive',
'rotate', 'flip', 'fixOrientation', 'gaussianBlur', 'format' 'rotate', 'flip', 'fixOrientation', 'gaussianBlur', 'format', 'create', 'fill', 'merge'
]; ];
/** @var array */ /** @var array */

View File

@ -337,6 +337,37 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
return $this; return $this;
} }
/**
* Add a frame to image
*
* @return $this
*/
public function addFrame(int $border = 10, string $color = '0x000000')
{
if(is_int(intval($border)) && $border>0 && preg_match('/^0x[a-f0-9]{6}$/i', $color)) { // $border must be an integer and bigger than 0; $color must be formatted as an HEX value (0x??????).
$image = ImageFile::open($this->path());
}
else {
return $this;
}
$dst_width = $image->width()+2*$border;
$dst_height = $image->height()+2*$border;
$frame = ImageFile::create($dst_width, $dst_height);
$frame->__call('fill', [$color]);
$this->image = $frame;
$this->__call('merge', [$image, $border, $border]);
$this->saveImage();
return $this;
}
/** /**
* Forward the call to the image processing method. * Forward the call to the image processing method.
* *
@ -344,6 +375,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
* @param mixed $args * @param mixed $args
* @return $this|mixed * @return $this|mixed
*/ */
public function __call($method, $args) public function __call($method, $args)
{ {
if (!in_array($method, static::$magic_actions, true)) { if (!in_array($method, static::$magic_actions, true)) {

View File

@ -287,33 +287,42 @@ class Plugins extends Iterator
{ {
// NOTE: ALL THE LOCAL VARIABLES ARE USED INSIDE INCLUDED FILE, DO NOT REMOVE THEM! // NOTE: ALL THE LOCAL VARIABLES ARE USED INSIDE INCLUDED FILE, DO NOT REMOVE THEM!
$grav = Grav::instance(); $grav = Grav::instance();
/** @var UniformResourceLocator $locator */
$locator = $grav['locator']; $locator = $grav['locator'];
$file = $locator->findResource('plugins://' . $name . DS . $name . PLUGIN_EXT); $class = null;
// Start by attempting to load the plugin_name.php file.
$file = $locator->findResource('plugins://' . $name . DS . $name . PLUGIN_EXT);
if (is_file($file)) { if (is_file($file)) {
// Local variables available in the file: $grav, $name, $file // Local variables available in the file: $grav, $name, $file
$class = include_once $file; $class = include_once $file;
if (!is_object($class) || !is_subclass_of($class, Plugin::class, true)) {
$class = null;
}
}
if (!$class || !is_subclass_of($class, Plugin::class, true)) { // If the class hasn't been initialized yet, guess the class name and create a new instance.
$className = Inflector::camelize($name); if (null === $class) {
$pluginClassFormat = [ $className = Inflector::camelize($name);
'Grav\\Plugin\\' . ucfirst($name). 'Plugin', $pluginClassFormat = [
'Grav\\Plugin\\' . $className . 'Plugin', 'Grav\\Plugin\\' . ucfirst($name). 'Plugin',
'Grav\\Plugin\\' . $className 'Grav\\Plugin\\' . $className . 'Plugin',
]; 'Grav\\Plugin\\' . $className
];
foreach ($pluginClassFormat as $pluginClass) { foreach ($pluginClassFormat as $pluginClass) {
if (is_subclass_of($pluginClass, Plugin::class, true)) { if (is_subclass_of($pluginClass, Plugin::class, true)) {
$class = new $pluginClass($name, $grav); $class = new $pluginClass($name, $grav);
break; break;
}
} }
} }
} else { }
// Log a warning if plugin cannot be found.
if (null === $class) {
$grav['log']->addWarning( $grav['log']->addWarning(
sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clearcache`", $name) sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clearcache`", $name)
); );
return null;
} }
return $class; return $class;

View File

@ -224,28 +224,18 @@ class Themes extends Iterator
$grav = $this->grav; $grav = $this->grav;
$config = $this->config; $config = $this->config;
$name = $this->current(); $name = $this->current();
$class = null;
/** @var UniformResourceLocator $locator */ /** @var UniformResourceLocator $locator */
$locator = $grav['locator']; $locator = $grav['locator'];
$file = $locator('theme://theme.php') ?: $locator("theme://{$name}.php");
// Start by attempting to load the theme.php file.
$file = $locator('theme://theme.php') ?: $locator("theme://{$name}.php");
if ($file) { if ($file) {
// Local variables available in the file: $grav, $config, $name, $file // Local variables available in the file: $grav, $config, $name, $file
$class = include $file; $class = include $file;
if (!\is_object($class) || !is_subclass_of($class, Theme::class, true)) {
if (!$class || !is_subclass_of($class, Plugin::class, true)) { $class = null;
$className = Inflector::camelize($name);
$themeClassFormat = [
'Grav\\Theme\\' . $className,
'Grav\\Theme\\' . ucfirst($name)
];
foreach ($themeClassFormat as $themeClass) {
if (is_subclass_of($themeClass, Theme::class, true)) {
$class = new $themeClass($grav, $config, $name);
break;
}
}
} }
} elseif (!$locator('theme://') && !defined('GRAV_CLI')) { } elseif (!$locator('theme://') && !defined('GRAV_CLI')) {
$response = new Response(500, [], "Theme '$name' does not exist, unable to display page."); $response = new Response(500, [], "Theme '$name' does not exist, unable to display page.");
@ -253,12 +243,28 @@ class Themes extends Iterator
$grav->close($response); $grav->close($response);
} }
$this->config->set('theme', $config->get('themes.' . $name)); // If the class hasn't been initialized yet, guess the class name and create a new instance.
if (null === $class) {
$themeClassFormat = [
'Grav\\Theme\\' . Inflector::camelize($name),
'Grav\\Theme\\' . ucfirst($name)
];
if (empty($class)) { foreach ($themeClassFormat as $themeClass) {
if (is_subclass_of($themeClass, Theme::class, true)) {
$class = new $themeClass($grav, $config, $name);
break;
}
}
}
// Finally if everything else fails, just create a new instance from the default Theme class.
if (null === $class) {
$class = new Theme($grav, $config, $name); $class = new Theme($grav, $config, $name);
} }
$this->config->set('theme', $config->get('themes.' . $name));
return $class; return $class;
} }

View File

@ -368,11 +368,15 @@ class FilesystemExtension extends AbstractExtension
/** /**
* @param string $path * @param string $path
* @param int $flags * @param int|null $flags
* @return string|string[] * @return string|string[]
*/ */
public function pathinfo($path, $flags = PATHINFO_ALL) public function pathinfo($path, $flags = null)
{ {
if (null !== $flags) {
return pathinfo($path, (int)$flags);
}
return pathinfo($path); return pathinfo($path);
} }

View File

@ -665,7 +665,7 @@ class Uri
*/ */
public static function paramsRegex() public static function paramsRegex()
{ {
return '/\/([^\:\#\/\?]*' . Grav::instance()['config']->get('system.param_sep') . '[^\:\#\/\?]*)/'; return '/\/{1,}([^\:\#\/\?]*' . Grav::instance()['config']->get('system.param_sep') . '[^\:\#\/\?]*)/';
} }
/** /**
@ -1498,7 +1498,7 @@ class Uri
* @param string $delimiter * @param string $delimiter
* @return string * @return string
*/ */
private function processParams($uri, $delimiter = ':') private function processParams(string $uri, string $delimiter = ':'): string
{ {
if (strpos($uri, $delimiter) !== false) { if (strpos($uri, $delimiter) !== false) {
preg_match_all(static::paramsRegex(), $uri, $matches, PREG_SET_ORDER); preg_match_all(static::paramsRegex(), $uri, $matches, PREG_SET_ORDER);

View File

@ -298,7 +298,11 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface
$weight = 0; $weight = 0;
foreach ($properties as $property) { foreach ($properties as $property) {
$weight += $this->searchNestedProperty($property, $search, $options); if (strpos($property, '.')) {
$weight += $this->searchNestedProperty($property, $search, $options);
} else {
$weight += $this->searchProperty($property, $search, $options);
}
} }
return $weight > 0 ? min($weight, 1) : 0; return $weight > 0 ? min($weight, 1) : 0;

View File

@ -1,4 +1,6 @@
core: core:
grav: grav:
version: 1.7.15 version: 1.7.16
schema: 1.7.0_2020-11-20_1 schema: 1.7.0_2020-11-20_1
history:
- { version: 1.7.16, date: '2021-06-10 14:03:35' }