From 382756f79b88e93d6dfbcc85d44ef633df4886fd Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 8 Feb 2022 08:40:59 +0200 Subject: [PATCH 01/32] Fixed pimple link #3527 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 562726dfdc..f16f62b4e4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![PHPStan](https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat)](https://github.com/phpstan/phpstan) [![Discord](https://img.shields.io/discord/501836936584101899.svg?logo=discord&colorB=728ADA&label=Discord%20Chat)](https://chat.getgrav.org) - [![PHP Tests](https://github.com/getgrav/grav/workflows/PHP%20Tests/badge.svg?branch=develop)](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [![OpenCollective](https://opencollective.com/grav/tiers/backers/badge.svg?label=Backers&color=brightgreen)](#backers) [![OpenCollective](https://opencollective.com/grav/tiers/supporters/badge.svg?label=Supporters&color=brightgreen)](#supporters) [![OpenCollective](https://opencollective.com/grav/tiers/sponsors/badge.svg?label=Sponsors&color=brightgreen)](#sponsors) + [![PHP Tests](https://github.com/getgrav/grav/workflows/PHP%20Tests/badge.svg?branch=develop)](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [![OpenCollective](https://opencollective.com/grav/tiers/backers/badge.svg?label=Backers&color=brightgreen)](#backers) [![OpenCollective](https://opencollective.com/grav/tiers/supporters/badge.svg?label=Supporters&color=brightgreen)](#supporters) [![OpenCollective](https://opencollective.com/grav/tiers/sponsors/badge.svg?label=Sponsors&color=brightgreen)](#sponsors) Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself. @@ -13,7 +13,7 @@ The underlying architecture of Grav is designed to use well-established and _bes * [YAML](https://yaml.org): for simple configuration * [Parsedown](https://parsedown.org/): for fast Markdown and Markdown Extra support * [Doctrine Cache](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance -* [Pimple Dependency Injection Container](https://pimple.sensiolabs.org/): for extensibility and maintainability +* [Pimple Dependency Injection Container](https://github.com/silexphp/Pimple): for extensibility and maintainability * [Symfony Event Dispatcher](https://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling * [Symfony Console](https://symfony.com/doc/current/components/console/introduction.html): for CLI interface * [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation From 2c252c43b4162fda7dd258927250a603f95fa589 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 8 Feb 2022 12:15:17 +0200 Subject: [PATCH 02/32] Composer update --- composer.lock | 55 ++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/composer.lock b/composer.lock index 2153094194..1f73769f43 100644 --- a/composer.lock +++ b/composer.lock @@ -2075,44 +2075,37 @@ }, { "name": "rockettheme/toolbox", - "version": "1.6.0", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "a0eb328b9c416e526c8264b48ccbc1a7519e8618" + "reference": "fdf0195ced25b83525d3b084c3e81f05de96ac8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/a0eb328b9c416e526c8264b48ccbc1a7519e8618", - "reference": "a0eb328b9c416e526c8264b48ccbc1a7519e8618", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/fdf0195ced25b83525d3b084c3e81f05de96ac8c", + "reference": "fdf0195ced25b83525d3b084c3e81f05de96ac8c", "shasum": "" }, "require": { "ext-json": "*", "php": ">=5.6.0", - "pimple/pimple": "~3.0", - "symfony/event-dispatcher": "^3.4|^4.0", - "symfony/polyfill-php80": "^1.23", - "symfony/polyfill-php81": "^1.23", - "symfony/yaml": "^3.4|^4.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.2", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpunit/phpunit": "^8.0" + "pimple/pimple": "^3.0", + "symfony/event-dispatcher": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "type": "library", "autoload": { "psr-4": { - "RocketTheme\\Toolbox\\ArrayTraits\\": "ArrayTraits/src", - "RocketTheme\\Toolbox\\Blueprints\\": "Blueprints/src", - "RocketTheme\\Toolbox\\Compat\\": "Compat/src", "RocketTheme\\Toolbox\\DI\\": "DI/src", - "RocketTheme\\Toolbox\\Event\\": "Event/src", "RocketTheme\\Toolbox\\File\\": "File/src", - "RocketTheme\\Toolbox\\ResourceLocator\\": "ResourceLocator/src", + "RocketTheme\\Toolbox\\Event\\": "Event/src", + "RocketTheme\\Toolbox\\Compat\\": "Compat/src", "RocketTheme\\Toolbox\\Session\\": "Session/src", - "RocketTheme\\Toolbox\\StreamWrapper\\": "StreamWrapper/src" + "RocketTheme\\Toolbox\\Blueprints\\": "Blueprints/src", + "RocketTheme\\Toolbox\\ArrayTraits\\": "ArrayTraits/src", + "RocketTheme\\Toolbox\\StreamWrapper\\": "StreamWrapper/src", + "RocketTheme\\Toolbox\\ResourceLocator\\": "ResourceLocator/src" }, "exclude-from-classmap": [ "**/tests/" @@ -2130,9 +2123,9 @@ ], "support": { "issues": "https://github.com/rockettheme/toolbox/issues", - "source": "https://github.com/rockettheme/toolbox/tree/1.6.0" + "source": "https://github.com/rockettheme/toolbox/tree/1.6.1" }, - "time": "2021-12-15T19:20:00+00:00" + "time": "2022-02-08T08:36:03+00:00" }, { "name": "seld/cli-prompt", @@ -4363,16 +4356,16 @@ }, { "name": "phar-io/version", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "reference": "15a90844ad40f127afd244c0cad228de2a80052a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a", + "reference": "15a90844ad40f127afd244c0cad228de2a80052a", "shasum": "" }, "require": { @@ -4408,9 +4401,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "source": "https://github.com/phar-io/version/tree/3.1.1" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2022-02-07T21:56:48+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -5133,11 +5126,11 @@ } }, "autoload": { - "classmap": [ - "src/" - ], "files": [ "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", From c4e10cf59f643806daea8b2009c3fcfe42e8d9e1 Mon Sep 17 00:00:00 2001 From: Xaver Maierhofer Date: Fri, 11 Feb 2022 10:26:11 +0100 Subject: [PATCH 03/32] Add Vector image auto_sizes support --- .../Grav/Common/Page/Medium/MediumFactory.php | 3 +- .../Common/Page/Medium/VectorImageMedium.php | 63 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 system/src/Grav/Common/Page/Medium/VectorImageMedium.php diff --git a/system/src/Grav/Common/Page/Medium/MediumFactory.php b/system/src/Grav/Common/Page/Medium/MediumFactory.php index 620446b70c..913f198f17 100644 --- a/system/src/Grav/Common/Page/Medium/MediumFactory.php +++ b/system/src/Grav/Common/Page/Medium/MediumFactory.php @@ -159,8 +159,9 @@ public static function fromArray(array $items = [], Blueprint $blueprint = null) return new ImageMedium($items, $blueprint); case 'thumbnail': return new ThumbnailImageMedium($items, $blueprint); - case 'animated': case 'vector': + return new VectorImageMedium($items, $blueprint); + case 'animated': return new StaticImageMedium($items, $blueprint); case 'video': return new VideoMedium($items, $blueprint); diff --git a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php new file mode 100644 index 0000000000..b43c38214e --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php @@ -0,0 +1,63 @@ +get('filepath'); + if (!$path || !file_exists($path) || !filesize($path)) { + return; + } + + $xml = simplexml_load_string(file_get_contents($path)); + $attr = $xml->attributes(); + + if (!$attr instanceof \SimpleXMLElement) { + return; + } + + if ($attr->width > 0 && $attr->height > 0) { + $width = (int)$attr->width; + $height = (int)$attr->height; + } elseif ($attr->viewBox && count($size = explode(' ', $attr->viewBox)) === 4) { + $width = (int)$size[2]; + $height = (int)$size[3]; + } + + if ($width && $height) { + $this->def('width', $width); + $this->def('height', $height); + } + } +} From 3a45748ce68070819f1d05fdef20c494911e3353 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 12 Feb 2022 10:41:34 +0200 Subject: [PATCH 04/32] Added auto_sizes support for SVG vector images [#3533] --- CHANGELOG.md | 6 ++++++ .../Common/Page/Medium/VectorImageMedium.php | 18 +++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c394dadf0d..fa2f0ef605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.7.31 +## mm/dd/2022 + +1. [](#new) + * Added auto_sizes support for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) + # v1.7.30 ## 02/07/2022 diff --git a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php index b43c38214e..b2cfc07f9a 100644 --- a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php @@ -28,10 +28,7 @@ public function __construct($items = [], Blueprint $blueprint = null) { parent::__construct($items, $blueprint); - $height = false; - $width = false; - - if (!extension_loaded('simplexml')) { + if ($this->mime !== 'image/svg+xml' || !\extension_loaded('simplexml')) { return; } @@ -41,7 +38,7 @@ public function __construct($items = [], Blueprint $blueprint = null) } $xml = simplexml_load_string(file_get_contents($path)); - $attr = $xml->attributes(); + $attr = $xml ? $xml->attributes() : null; if (!$attr instanceof \SimpleXMLElement) { return; @@ -50,14 +47,13 @@ public function __construct($items = [], Blueprint $blueprint = null) if ($attr->width > 0 && $attr->height > 0) { $width = (int)$attr->width; $height = (int)$attr->height; - } elseif ($attr->viewBox && count($size = explode(' ', $attr->viewBox)) === 4) { - $width = (int)$size[2]; - $height = (int)$size[3]; + } elseif ($attr->viewBox && \count($size = explode(' ', $attr->viewBox)) === 4) { + [,$width,$height,] = $size; } - if ($width && $height) { - $this->def('width', $width); - $this->def('height', $height); + if (isset($width, $height)) { + $this->def('width', (int)$width); + $this->def('height', (int)$height); } } } From ec884997eff805e1c92374745a81620fe414e10b Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 12 Feb 2022 10:49:52 +0200 Subject: [PATCH 05/32] Improve vector image code [#3533] --- CHANGELOG.md | 2 +- .../Common/Page/Medium/VectorImageMedium.php | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa2f0ef605..dd1fd9d5f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## mm/dd/2022 1. [](#new) - * Added auto_sizes support for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) + * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) # v1.7.30 ## 02/07/2022 diff --git a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php index b2cfc07f9a..8468701311 100644 --- a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php @@ -28,10 +28,19 @@ public function __construct($items = [], Blueprint $blueprint = null) { parent::__construct($items, $blueprint); + // If we already have the image size, we do not need to do anything else. + $width = $this->get('width'); + $height = $this->get('height'); + if ($width && $height) { + return; + } + + // Make sure that getting image size is supported. if ($this->mime !== 'image/svg+xml' || !\extension_loaded('simplexml')) { return; } + // Make sure that the image exists. $path = $this->get('filepath'); if (!$path || !file_exists($path) || !filesize($path)) { return; @@ -39,19 +48,19 @@ public function __construct($items = [], Blueprint $blueprint = null) $xml = simplexml_load_string(file_get_contents($path)); $attr = $xml ? $xml->attributes() : null; - if (!$attr instanceof \SimpleXMLElement) { return; } + // Get the size from svg image. if ($attr->width > 0 && $attr->height > 0) { - $width = (int)$attr->width; - $height = (int)$attr->height; + $width = $attr->width; + $height = $attr->height; } elseif ($attr->viewBox && \count($size = explode(' ', $attr->viewBox)) === 4) { [,$width,$height,] = $size; } - if (isset($width, $height)) { + if ($width && $height) { $this->def('width', (int)$width); $this->def('height', (int)$height); } From b3b5fca16cee7339cd11c8aa6dd86d9490b43222 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 14 Feb 2022 09:38:22 +0200 Subject: [PATCH 06/32] Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504] --- CHANGELOG.md | 2 ++ bin/gpm | 8 ++------ bin/grav | 8 ++------ bin/plugin | 8 ++------ index.php | 23 ++++++++--------------- 5 files changed, 16 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd1fd9d5f1..08737d2bc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 1. [](#new) * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) +2. [](#bugfix) + * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) # v1.7.30 ## 02/07/2022 diff --git a/bin/gpm b/bin/gpm index 9e58706f69..12d0c3d365 100755 --- a/bin/gpm +++ b/bin/gpm @@ -25,14 +25,10 @@ if (!file_exists(__DIR__ . '/../vendor/autoload.php')){ $autoload = require __DIR__ . '/../vendor/autoload.php'; -if (!ini_get('date.timezone')) { - date_default_timezone_set('UTC'); -} +// Set timezone to default, falls back to system if php.ini not set +date_default_timezone_set(@date_default_timezone_get()); // Set internal encoding. -if (!\extension_loaded('mbstring')) { - die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); -} @ini_set('default_charset', 'UTF-8'); mb_internal_encoding('UTF-8'); diff --git a/bin/grav b/bin/grav index cc925c3944..1bcba715a3 100755 --- a/bin/grav +++ b/bin/grav @@ -25,14 +25,10 @@ if (!file_exists(__DIR__ . '/../vendor/autoload.php')){ $autoload = require __DIR__ . '/../vendor/autoload.php'; -if (!ini_get('date.timezone')) { - date_default_timezone_set('UTC'); -} +// Set timezone to default, falls back to system if php.ini not set +date_default_timezone_set(@date_default_timezone_get()); // Set internal encoding. -if (!\extension_loaded('mbstring')) { - die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); -} @ini_set('default_charset', 'UTF-8'); mb_internal_encoding('UTF-8'); diff --git a/bin/plugin b/bin/plugin index 3a784af571..4a36838580 100755 --- a/bin/plugin +++ b/bin/plugin @@ -25,14 +25,10 @@ if (!file_exists(__DIR__ . '/../vendor/autoload.php')){ $autoload = require __DIR__ . '/../vendor/autoload.php'; -if (!ini_get('date.timezone')) { - date_default_timezone_set('UTC'); -} +// Set timezone to default, falls back to system if php.ini not set +date_default_timezone_set(@date_default_timezone_get()); // Set internal encoding. -if (!\extension_loaded('mbstring')) { - die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); -} @ini_set('default_charset', 'UTF-8'); mb_internal_encoding('UTF-8'); diff --git a/index.php b/index.php index 3e308312f5..5393b8cffc 100644 --- a/index.php +++ b/index.php @@ -20,16 +20,6 @@ } } -// Set timezone to default, falls back to system if php.ini not set -date_default_timezone_set(@date_default_timezone_get()); - -// Set internal encoding. -if (!\extension_loaded('mbstring')) { - die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); -} -@ini_set('default_charset', 'UTF-8'); -mb_internal_encoding('UTF-8'); - // Ensure vendor libraries exist $autoload = __DIR__ . '/vendor/autoload.php'; if (!is_file($autoload)) { @@ -39,15 +29,18 @@ // Register the auto-loader. $loader = require $autoload; +// Set timezone to default, falls back to system if php.ini not set +date_default_timezone_set(@date_default_timezone_get()); + +// Set internal encoding. +@ini_set('default_charset', 'UTF-8'); +mb_internal_encoding('UTF-8'); + use Grav\Common\Grav; use RocketTheme\Toolbox\Event\Event; // Get the Grav instance -$grav = Grav::instance( - array( - 'loader' => $loader - ) -); +$grav = Grav::instance(array('loader' => $loader)); // Process the page try { From 7cafeb2870bfbfdaa63c6e4fd109ce77e40d561a Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 16 Feb 2022 09:53:11 +0200 Subject: [PATCH 07/32] Composer update --- composer.lock | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/composer.lock b/composer.lock index 1f73769f43..a90114272e 100644 --- a/composer.lock +++ b/composer.lock @@ -840,22 +840,21 @@ }, { "name": "itsgoingd/clockwork", - "version": "v5.1.4", + "version": "v5.1.5", "source": { "type": "git", "url": "https://github.com/itsgoingd/clockwork.git", - "reference": "7252aa771b77ac8678b44290fd7ec7577435cce6" + "reference": "6a7b3942224fa53cf3704d9adba636e1f3dfeb9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/7252aa771b77ac8678b44290fd7ec7577435cce6", - "reference": "7252aa771b77ac8678b44290fd7ec7577435cce6", + "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/6a7b3942224fa53cf3704d9adba636e1f3dfeb9a", + "reference": "6a7b3942224fa53cf3704d9adba636e1f3dfeb9a", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=5.6", - "psr/log": "1.* || ^2.0" + "php": ">=5.6" }, "type": "library", "extra": { @@ -897,7 +896,7 @@ ], "support": { "issues": "https://github.com/itsgoingd/clockwork/issues", - "source": "https://github.com/itsgoingd/clockwork/tree/v5.1.4" + "source": "https://github.com/itsgoingd/clockwork/tree/v5.1.5" }, "funding": [ { @@ -905,7 +904,7 @@ "type": "github" } ], - "time": "2022-01-30T12:36:18+00:00" + "time": "2022-02-13T22:57:42+00:00" }, { "name": "league/climate", @@ -1105,25 +1104,26 @@ }, { "name": "maximebf/debugbar", - "version": "v1.17.3", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c" + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/e8ac3499af0ea5b440908e06cc0abe5898008b3c", - "reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", "shasum": "" }, "require": { "php": "^7.1|^8", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^2.6|^3|^4|^5" + "symfony/var-dumper": "^2.6|^3|^4|^5|^6" }, "require-dev": { - "phpunit/phpunit": "^7.5.20 || ^9.4.2" + "phpunit/phpunit": "^7.5.20 || ^9.4.2", + "twig/twig": "^1.38|^2.7|^3.0" }, "suggest": { "kriswallsmith/assetic": "The best way to manage assets", @@ -1164,9 +1164,9 @@ ], "support": { "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.17.3" + "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.0" }, - "time": "2021-10-19T12:33:27+00:00" + "time": "2021-12-27T18:49:48+00:00" }, { "name": "miljar/php-exif", @@ -2730,12 +2730,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4019,12 +4019,12 @@ } }, "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5725,16 +5725,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.3", + "version": "5.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", "shasum": "" }, "require": { @@ -5777,7 +5777,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" }, "funding": [ { @@ -5785,7 +5785,7 @@ "type": "github" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2022-02-14T08:28:10+00:00" }, { "name": "sebastian/lines-of-code", From cad8510daef8083161b4506ca8d130cded2ede87 Mon Sep 17 00:00:00 2001 From: Xaver Maierhofer Date: Tue, 15 Feb 2022 05:33:21 +0100 Subject: [PATCH 08/32] Merge index exceptions with same handling --- index.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/index.php b/index.php index 5393b8cffc..b6b86e1c08 100644 --- a/index.php +++ b/index.php @@ -45,10 +45,7 @@ // Process the page try { $grav->process(); -} catch (\Error $e) { - $grav->fireEvent('onFatalException', new Event(array('exception' => $e))); - throw $e; -} catch (\Exception $e) { +} catch (\Error|\Exception $e) { $grav->fireEvent('onFatalException', new Event(array('exception' => $e))); throw $e; } From a900b89795fe30f74d8741c4b26c8aa12ed0a45c Mon Sep 17 00:00:00 2001 From: xaver Date: Fri, 18 Feb 2022 16:39:20 +0100 Subject: [PATCH 09/32] Remove variable duplicate (#3539) --- system/src/Grav/Common/Backup/Backups.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Backup/Backups.php b/system/src/Grav/Common/Backup/Backups.php index 9c23908c42..ff4789d86b 100644 --- a/system/src/Grav/Common/Backup/Backups.php +++ b/system/src/Grav/Common/Backup/Backups.php @@ -104,7 +104,7 @@ public function onSchedulerInitialized(Event $event) */ public function getBackupDownloadUrl($backup, $base_url) { - $param_sep = $param_sep = Grav::instance()['config']->get('system.param_sep', ':'); + $param_sep = Grav::instance()['config']->get('system.param_sep', ':'); $download = urlencode(base64_encode(Utils::basename($backup))); $url = rtrim(Grav::instance()['uri']->rootUrl(true), '/') . '/' . trim( $base_url, From 7e52112b212d205bdaa994781210216f57c9149d Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 19 Feb 2022 12:01:50 +0200 Subject: [PATCH 10/32] Fixed phpstan issues (All level 2, Framework level 5) --- CHANGELOG.md | 1 + composer.json | 4 ++-- composer.lock | 24 +++++++++---------- system/src/Grav/Common/Assets.php | 17 +++++++++++-- system/src/Grav/Common/Assets/BlockAssets.php | 2 +- .../Common/Flex/Types/Pages/PageIndex.php | 6 ++++- .../Common/Flex/Types/Pages/PageObject.php | 9 ++++++- .../Media/Interfaces/MediaObjectInterface.php | 2 ++ .../Common/Page/Medium/VectorImageMedium.php | 8 +++---- system/src/Grav/Common/Page/Pages.php | 19 +++++++++++---- .../src/Grav/Common/Twig/TwigEnvironment.php | 10 ++++++-- 11 files changed, 73 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08737d2bc4..3b3d199017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#new) * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) + * Fixed phpstan issues (All level 2, Framework level 5) 2. [](#bugfix) * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) diff --git a/composer.json b/composer.json index 5116901043..db54497381 100644 --- a/composer.json +++ b/composer.json @@ -115,8 +115,8 @@ "scripts": { "api-17": "vendor/bin/phpdoc-md generate system/src > user/pages/14.api/default.17.md", "post-create-project-cmd": "bin/grav install", - "phpstan": "vendor/bin/phpstan analyse -l 1 -c ./tests/phpstan/phpstan.neon --memory-limit=720M system/src", - "phpstan-framework": "vendor/bin/phpstan analyse -l 4 -c ./tests/phpstan/phpstan.neon --memory-limit=480M system/src/Grav/Framework system/src/Grav/Events system/src/Grav/Installer", + "phpstan": "vendor/bin/phpstan analyse -l 2 -c ./tests/phpstan/phpstan.neon --memory-limit=720M system/src", + "phpstan-framework": "vendor/bin/phpstan analyse -l 5 -c ./tests/phpstan/phpstan.neon --memory-limit=480M system/src/Grav/Framework system/src/Grav/Events system/src/Grav/Installer", "phpstan-plugins": "vendor/bin/phpstan analyse -l 1 -c ./tests/phpstan/plugins.neon --memory-limit=400M user/plugins", "test": "vendor/bin/codecept run unit", "test-windows": "vendor\\bin\\codecept run unit" diff --git a/composer.lock b/composer.lock index a90114272e..06c0bbf38d 100644 --- a/composer.lock +++ b/composer.lock @@ -4748,16 +4748,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.10", + "version": "9.2.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" + "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f", + "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f", "shasum": "" }, "require": { @@ -4813,7 +4813,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11" }, "funding": [ { @@ -4821,7 +4821,7 @@ "type": "github" } ], - "time": "2021-12-05T09:12:13+00:00" + "time": "2022-02-18T12:46:09+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5066,16 +5066,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.13", + "version": "9.5.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "597cb647654ede35e43b137926dfdfef0fb11743" + "reference": "1883687169c017d6ae37c58883ca3994cfc34189" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743", - "reference": "597cb647654ede35e43b137926dfdfef0fb11743", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189", + "reference": "1883687169c017d6ae37c58883ca3994cfc34189", "shasum": "" }, "require": { @@ -5153,7 +5153,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.14" }, "funding": [ { @@ -5165,7 +5165,7 @@ "type": "github" } ], - "time": "2022-01-24T07:33:35+00:00" + "time": "2022-02-18T12:54:07+00:00" }, { "name": "psr/http-client", diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 134c62fbaf..23878a390a 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -525,8 +525,8 @@ public function js($group = 'head', $attributes = [], $include_js_module = true) /** * Build the Javascript Modules tags * - * @param $group - * @param $attributes + * @param string $group + * @param array $attributes * @return string */ public function jsModule($group = 'head', $attributes = []) @@ -534,6 +534,11 @@ public function jsModule($group = 'head', $attributes = []) return $this->render(self::JS_MODULE, $group, $attributes); } + /** + * @param string $group + * @param array $attributes + * @return string + */ public function all($group = 'head', $attributes = []) { $output = $this->css($group, $attributes, false); @@ -543,11 +548,19 @@ public function all($group = 'head', $attributes = []) return $output; } + /** + * @param class-string $type + * @return bool + */ protected function isValidType($type) { return in_array($type, [self::CSS_TYPE, self::JS_TYPE, self::JS_MODULE_TYPE]); } + /** + * @param class-string $type + * @return string + */ protected function getBaseType($type) { switch ($type) { diff --git a/system/src/Grav/Common/Assets/BlockAssets.php b/system/src/Grav/Common/Assets/BlockAssets.php index 798bdd3040..7d97960908 100644 --- a/system/src/Grav/Common/Assets/BlockAssets.php +++ b/system/src/Grav/Common/Assets/BlockAssets.php @@ -55,7 +55,7 @@ public static function registerAssets(HtmlBlock $block): void /** * @param Assets $assets - * @param array $groups + * @param array $list * @return void */ protected static function registerFrameworks(Assets $assets, array $list): void diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php b/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php index c0ca5c4053..f3978bc1d7 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php +++ b/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php @@ -606,8 +606,10 @@ protected function getLevelListingRecurse(array $options): array } } + /** @var PageCollection|PageIndex $children */ + $children = $page->children(); /** @var PageIndex $children */ - $children = $page->children()->getIndex(); + $children = $children->getIndex(); $selectedChildren = $children->filterBy($filters, true); /** @var Header $header */ @@ -686,6 +688,8 @@ protected function getLevelListingRecurse(array $options): array $extras = array_filter($extras, static function ($v) { return $v !== null; }); + + /** @var PageIndex $tmp */ $tmp = $child->children()->getIndex(); $child_count = $tmp->count(); $count = $filters ? $tmp->filterBy($filters, true)->count() : null; diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageObject.php b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php index fed11b437b..a05f0eb42c 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/PageObject.php +++ b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php @@ -625,7 +625,14 @@ public function filterBy(array $filters, bool $recursive = false): bool // If current filter does not match, we still may have match as a parent. if ($matches === false) { - return $recursive && $this->children()->getIndex()->filterBy($filters, true)->count() > 0; + if (!$recursive) { + return false; + } + + /** @var PageIndex $index */ + $index = $this->children()->getIndex(); + + return $index->filterBy($filters, true)->count() > 0; } } diff --git a/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php index 4af3052b02..9334759626 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php @@ -16,6 +16,8 @@ * Class implements media object interface. * * @property string $type + * @property string $filename + * @property string $filepath */ interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObjectInterface, ArrayAccess { diff --git a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php index 8468701311..c44f35a77b 100644 --- a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php @@ -53,10 +53,10 @@ public function __construct($items = [], Blueprint $blueprint = null) } // Get the size from svg image. - if ($attr->width > 0 && $attr->height > 0) { - $width = $attr->width; - $height = $attr->height; - } elseif ($attr->viewBox && \count($size = explode(' ', $attr->viewBox)) === 4) { + if ($attr->width && $attr->height) { + $width = (string)$attr->width; + $height = (string)$attr->height; + } elseif ($attr->viewBox && \count($size = explode(' ', (string)$attr->viewBox)) === 4) { [,$width,$height,] = $size; } diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 8ad2ccd8f0..ec48b51730 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -736,7 +736,13 @@ protected function evaluate($value, PageInterface $self = null) break; case 'siblings': $parent = $page->parent(); - $collection = $parent ? $parent->children()->remove($page->path()) : new Collection(); + if ($parent) { + /** @var Collection $collection */ + $collection = $parent->children(); + $collection = $collection->remove($page->path()); + } else { + $collection = new Collection(); + } break; case 'descendants': $collection = $this->all($page)->remove($page->path())->pages(); @@ -1041,9 +1047,14 @@ public function dispatch($route, $all = false, $redirect = true) $this->grav->redirectLangSafe($page->redirect()); } - if (!$routable && ($child = $page->children()->visible()->routable()->published()->first()) !== null) { - // Redirect to the first visible child as current page isn't routable. - $this->grav->redirectLangSafe($child->route()); + if (!$routable) { + /** @var Collection $children */ + $children = $page->children()->visible()->routable()->published(); + $child = $children->first(); + if ($child !== null) { + // Redirect to the first visible child as current page isn't routable. + $this->grav->redirectLangSafe($child->route()); + } } } diff --git a/system/src/Grav/Common/Twig/TwigEnvironment.php b/system/src/Grav/Common/Twig/TwigEnvironment.php index 6b2a86befa..dba8846931 100644 --- a/system/src/Grav/Common/Twig/TwigEnvironment.php +++ b/system/src/Grav/Common/Twig/TwigEnvironment.php @@ -11,6 +11,8 @@ use Twig\Environment; use Twig\Error\LoaderError; +use Twig\Loader\ExistsLoaderInterface; +use Twig\Loader\LoaderInterface; use Twig\Template; use Twig\TemplateWrapper; @@ -41,8 +43,12 @@ public function resolveTemplate($names) } // Optimization: Avoid throwing an exception when it would be ignored anyway. - if (1 !== $count && !$this->getLoader()->exists($name)) { - continue; + if (1 !== $count) { + /** @var LoaderInterface|ExistsLoaderInterface $loader */ + $loader = $this->getLoader(); + if (!$loader->exists($name)) { + continue; + } } // Throws LoaderError: Unable to find template "%s". From 6d0d6c22d395fe0b7baf3479d43729e0e2b2dae2 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 22 Feb 2022 09:46:29 +0200 Subject: [PATCH 11/32] Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542] --- CHANGELOG.md | 1 + system/src/Grav/Common/Assets.php | 9 +++++++-- system/src/Grav/Common/Grav.php | 8 ++++++-- system/src/Grav/Common/Utils.php | 4 ++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b3d199017..3d04d38212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Fixed phpstan issues (All level 2, Framework level 5) 2. [](#bugfix) * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) + * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) # v1.7.30 ## 02/07/2022 diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 23878a390a..621a140410 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -16,8 +16,8 @@ use Grav\Common\Config\Config; use Grav\Framework\Object\PropertyObject; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; +use function array_slice; use function call_user_func_array; -use function count; use function func_get_args; use function is_array; @@ -174,6 +174,10 @@ public function config(array $config) */ public function add($asset) { + if (!$asset) { + return $this; + } + $args = func_get_args(); // More than one asset @@ -198,7 +202,8 @@ public function add($asset) call_user_func_array([$this, 'add'], $args); } else { // Get extension - $extension = Utils::pathinfo(parse_url($asset, PHP_URL_PATH), PATHINFO_EXTENSION); + $path = parse_url($asset, PHP_URL_PATH); + $extension = $path ? Utils::pathinfo($path, PATHINFO_EXTENSION) : ''; // JavaScript or CSS if ($extension !== '') { diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 18d490295a..b9b44a4df9 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -62,6 +62,7 @@ use function function_exists; use function get_class; use function in_array; +use function is_array; use function is_callable; use function is_int; use function is_string; @@ -729,14 +730,17 @@ protected function registerServices(): void */ public function fallbackUrl($path) { + $path_parts = Utils::pathinfo($path); + if (!is_array($path_parts)) { + return false; + } + /** @var Uri $uri */ $uri = $this['uri']; /** @var Config $config */ $config = $this['config']; - $path_parts = Utils::pathinfo($path); - /** @var Pages $pages */ $pages = $this['pages']; $page = $pages->find($path_parts['dirname'], true); diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 64c81a927f..9ac24c217e 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -994,7 +994,7 @@ public static function checkFilename($filename) * @param int|null $flags * @return array|string */ - public static function pathinfo(string $path, int $flags = null) + public static function pathinfo($path, int $flags = null) { $path = str_replace(['%2F', '%5C'], ['/', '\\'], rawurlencode($path)); @@ -1020,7 +1020,7 @@ public static function pathinfo(string $path, int $flags = null) * @param string $suffix * @return string */ - public static function basename(string $path, string $suffix = ''): string + public static function basename($path, string $suffix = ''): string { return rawurldecode(basename(str_replace(['%2F', '%5C'], '/', rawurlencode($path)), $suffix)); } From a7e82f279a41fbb287044b19c0531bafa1adc6ce Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 22 Feb 2022 11:28:57 +0200 Subject: [PATCH 12/32] Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540] --- CHANGELOG.md | 1 + .../src/Grav/Common/Media/Traits/MediaPlayerTrait.php | 10 +++++----- .../src/Grav/Common/Media/Traits/VideoMediaTrait.php | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d04d38212..be63eea0e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ 2. [](#bugfix) * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) + * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) # v1.7.30 ## 02/07/2022 diff --git a/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php b/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php index 06cb99ad98..7e59d64b06 100644 --- a/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php +++ b/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php @@ -25,7 +25,7 @@ trait MediaPlayerTrait public function controls($status = true) { if ($status) { - $this->attributes['controls'] = true; + $this->attributes['controls'] = 'controls'; } else { unset($this->attributes['controls']); } @@ -42,7 +42,7 @@ public function controls($status = true) public function loop($status = false) { if ($status) { - $this->attributes['loop'] = true; + $this->attributes['loop'] = 'loop'; } else { unset($this->attributes['loop']); } @@ -59,7 +59,7 @@ public function loop($status = false) public function autoplay($status = false) { if ($status) { - $this->attributes['autoplay'] = true; + $this->attributes['autoplay'] = 'autoplay'; } else { unset($this->attributes['autoplay']); } @@ -76,7 +76,7 @@ public function autoplay($status = false) public function muted($status = false) { if ($status) { - $this->attributes['muted'] = true; + $this->attributes['muted'] = 'muted'; } else { unset($this->attributes['muted']); } @@ -108,6 +108,6 @@ public function preload($preload = null) */ public function resetPlayer() { - $this->attributes['controls'] = true; + $this->attributes['controls'] = 'controls'; } } diff --git a/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php b/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php index b16bb53c70..07f0c3f12a 100644 --- a/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php +++ b/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php @@ -40,7 +40,7 @@ public function poster($urlImage) public function playsinline($status = false) { if ($status) { - $this->attributes['playsinline'] = true; + $this->attributes['playsinline'] = 'playsinline'; } else { unset($this->attributes['playsinline']); } From b992d7f18548c31670d2cf1322e01f8eb7681872 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 22 Feb 2022 11:33:27 +0200 Subject: [PATCH 13/32] Composer update --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 06c0bbf38d..965a63c1f4 100644 --- a/composer.lock +++ b/composer.lock @@ -4356,16 +4356,16 @@ }, { "name": "phar-io/version", - "version": "3.1.1", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "15a90844ad40f127afd244c0cad228de2a80052a" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a", - "reference": "15a90844ad40f127afd244c0cad228de2a80052a", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { @@ -4401,9 +4401,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.1" + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2022-02-07T21:56:48+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpdocumentor/reflection-common", From 3dd0cabeac9835fe64dcb4b68c658b39f1f6be2f Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Wed, 23 Feb 2022 14:57:36 -0800 Subject: [PATCH 14/32] Fixed entity sanitization for XSS detection --- CHANGELOG.md | 1 + system/src/Grav/Common/Security.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be63eea0e2..bb0adfc476 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) + * Fixed entity sanitization for XSS detection # v1.7.30 ## 02/07/2022 diff --git a/system/src/Grav/Common/Security.php b/system/src/Grav/Common/Security.php index 017720ca89..01ea0f13c8 100644 --- a/system/src/Grav/Common/Security.php +++ b/system/src/Grav/Common/Security.php @@ -200,7 +200,7 @@ public static function detectXss($string, array $options = null): ?string }, $string); // Clean up entities - $string = preg_replace('!(�+[0-9]+)!u', '$1;', $string); + $string = preg_replace('!(&#[0-9]+)!u', '$1;', $string); // Decode entities $string = html_entity_decode($string, ENT_NOQUOTES | ENT_HTML5, 'UTF-8'); From 78b8051627a2404d42641bd63d6a46a6b2fe5f08 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 26 Feb 2022 19:20:13 +0200 Subject: [PATCH 15/32] Fixed avatar save location when `account://` stream points to custom directory --- CHANGELOG.md | 1 + system/blueprints/user/account.yaml | 2 +- system/src/Grav/Common/Flex/Types/Users/UserObject.php | 2 +- system/src/Grav/Common/User/DataUser/User.php | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb0adfc476..7b4711cfc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) * Fixed entity sanitization for XSS detection + * Fixed avatar save location when `account://` stream points to custom directory # v1.7.30 ## 02/07/2022 diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index cfe5376205..391c7370a3 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -11,7 +11,7 @@ form: avatar: type: file size: large - destination: 'user://accounts/avatars' + destination: 'account://avatars' multiple: false random_name: true diff --git a/system/src/Grav/Common/Flex/Types/Users/UserObject.php b/system/src/Grav/Common/Flex/Types/Users/UserObject.php index d9217917d7..9dec9729fb 100644 --- a/system/src/Grav/Common/Flex/Types/Users/UserObject.php +++ b/system/src/Grav/Common/Flex/Types/Users/UserObject.php @@ -666,7 +666,7 @@ public function getMediaFolder(): ?string // Check for shared media if (!$folder && !$this->getFlexDirectory()->getMediaFolder()) { $this->_loadMedia = false; - $folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'user://accounts/avatars'; + $folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'account://avatars'; } return $folder; diff --git a/system/src/Grav/Common/User/DataUser/User.php b/system/src/Grav/Common/User/DataUser/User.php index 71e7f9b354..9cd3904f03 100644 --- a/system/src/Grav/Common/User/DataUser/User.php +++ b/system/src/Grav/Common/User/DataUser/User.php @@ -193,7 +193,7 @@ public function getMedia() */ public function getMediaFolder() { - return $this->blueprints()->fields()['avatar']['destination'] ?? 'user://accounts/avatars'; + return $this->blueprints()->fields()['avatar']['destination'] ?? 'account://avatars'; } /** From f19297d5f70476e7bedae9f2acef6b43615538b8 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 2 Mar 2022 13:37:51 +0200 Subject: [PATCH 16/32] Added XSS check for uploaded SVG files before they get stored --- CHANGELOG.md | 1 + .../Common/Media/Traits/MediaUploadTrait.php | 4 ++++ system/src/Grav/Common/Security.php | 18 +++++++++++++++++- .../src/Grav/Framework/Form/FormFlashFile.php | 17 +++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b4711cfc6..28c2db4557 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 1. [](#new) * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) + * Added XSS check for uploaded SVG files before they get stored * Fixed phpstan issues (All level 2, Framework level 5) 2. [](#bugfix) * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) diff --git a/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php b/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php index 36a4503f1b..88591f6aeb 100644 --- a/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php +++ b/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php @@ -100,6 +100,10 @@ public function checkUploadedFile(UploadedFileInterface $uploadedFile, string $f 'size' => $uploadedFile->getSize(), ]; + if ($uploadedFile instanceof FormFlashFile) { + $uploadedFile->checkXss(); + } + return $this->checkFileMetadata($metadata, $filename, $settings); } diff --git a/system/src/Grav/Common/Security.php b/system/src/Grav/Common/Security.php index 01ea0f13c8..779e61918a 100644 --- a/system/src/Grav/Common/Security.php +++ b/system/src/Grav/Common/Security.php @@ -25,6 +25,22 @@ */ class Security { + /** + * @param string $filepath + * @param array|null $options + * @return string|null + */ + public static function detectXssFromSvgFile(string $filepath, array $options = null): ?string + { + if (file_exists($filepath) && Grav::instance()['config']->get('security.sanitize_svg')) { + $content = file_get_contents($filepath); + + return static::detectXss($content, $options); + } + + return null; + } + /** * Sanitize SVG string for XSS code * @@ -200,7 +216,7 @@ public static function detectXss($string, array $options = null): ?string }, $string); // Clean up entities - $string = preg_replace('!(&#[0-9]+)!u', '$1;', $string); + $string = preg_replace('!(&#[0-9]+);?!u', '$1;', $string); // Decode entities $string = html_entity_decode($string, ENT_NOQUOTES | ENT_HTML5, 'UTF-8'); diff --git a/system/src/Grav/Framework/Form/FormFlashFile.php b/system/src/Grav/Framework/Form/FormFlashFile.php index 6c995993eb..65af544d1b 100644 --- a/system/src/Grav/Framework/Form/FormFlashFile.php +++ b/system/src/Grav/Framework/Form/FormFlashFile.php @@ -9,6 +9,8 @@ namespace Grav\Framework\Form; +use Grav\Common\Security; +use Grav\Common\Utils; use Grav\Framework\Psr7\Stream; use InvalidArgumentException; use JsonSerializable; @@ -182,6 +184,21 @@ 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 */ From 34ab8408fa25ec18a5c65067b314c513d6ef7c9b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 3 Mar 2022 11:21:03 -0700 Subject: [PATCH 17/32] fix for url() function breaking when path contains root --- system/src/Grav/Common/Utils.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 64c81a927f..d0e0fab15c 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -134,10 +134,10 @@ public static function url($input, $domain = false, $fail_gracefully = false) $resource = $locator->findResource($input, false); } } else { - $root = $uri->rootUrl(); + $root = $uri->rootUrl() . '/'; if (static::startsWith($input, $root)) { - $input = static::replaceFirstOccurrence($root, '', $input); + $input = static::replaceFirstOccurrence($root, '/', $input); } $input = ltrim($input, '/'); From 879eb275409966a632a65c5c8936d184ecb8fad3 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 3 Mar 2022 11:21:36 -0700 Subject: [PATCH 18/32] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28c2db4557..79c680ef71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) * Fixed entity sanitization for XSS detection * Fixed avatar save location when `account://` stream points to custom directory + * Fixed bug in `Utils::url()` when path contains root # v1.7.30 ## 02/07/2022 From b80fcca0cf5adbf61d444a9ce35b7f63fde105e0 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 3 Mar 2022 12:35:17 -0700 Subject: [PATCH 19/32] fixes for Utils::url() --- system/src/Grav/Common/Utils.php | 10 +++++----- tests/unit/Grav/Common/UtilsTest.php | 26 +++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index a1ba549e8c..5ae8193610 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -134,11 +134,11 @@ public static function url($input, $domain = false, $fail_gracefully = false) $resource = $locator->findResource($input, false); } } else { - $root = $uri->rootUrl() . '/'; - - if (static::startsWith($input, $root)) { - $input = static::replaceFirstOccurrence($root, '/', $input); - } +// $root = $uri->rootUrl(); +// $pattern = '/(' . '\\' . $root . '[\s\/])/'; +// if (preg_match($pattern, $input, $matches)) { +// $input = static::replaceFirstOccurrence($matches[0], '', $input); +// } $input = ltrim($input, '/'); diff --git a/tests/unit/Grav/Common/UtilsTest.php b/tests/unit/Grav/Common/UtilsTest.php index 32fd84ce1a..5cf554adc4 100644 --- a/tests/unit/Grav/Common/UtilsTest.php +++ b/tests/unit/Grav/Common/UtilsTest.php @@ -502,19 +502,19 @@ public function testUrlWithRoot(): void self::assertSame('http://testing.dev/subdir/path1/path2/foobar.jpg', Utils::url('/path1/path2/foobar.jpg', true)); self::assertSame('http://testing.dev/subdir/random/path1/path2/foobar.jpg', Utils::url('/random/path1/path2/foobar.jpg', true)); - // Paths including the grav base. - self::assertSame('/subdir/', Utils::url('/subdir')); - self::assertSame('/subdir/path1', Utils::url('/subdir/path1')); - self::assertSame('/subdir/path1/path2', Utils::url('/subdir/path1/path2')); - self::assertSame('/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg')); - self::assertSame('/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg')); - - // Relative paths from Grav root with domain. - self::assertSame('http://testing.dev/subdir/', Utils::url('/subdir', true)); - self::assertSame('http://testing.dev/subdir/path1', Utils::url('/subdir/path1', true)); - self::assertSame('http://testing.dev/subdir/path1/path2', Utils::url('/subdir/path1/path2', true)); - self::assertSame('http://testing.dev/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg', true)); - self::assertSame('http://testing.dev/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true)); + // Absolute Paths including the grav base. + self::assertSame('/subdir/subdir', Utils::url('/subdir')); + self::assertSame('/subdir/subdir/path1', Utils::url('/subdir/path1')); + self::assertSame('/subdir/subdir/path1/path2', Utils::url('/subdir/path1/path2')); + self::assertSame('/subdir/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg')); + self::assertSame('/subdir/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg')); + + // Absolute paths from Grav root with domain. + self::assertSame('http://testing.dev/subdir/subdir', Utils::url('/subdir', true)); + self::assertSame('http://testing.dev/subdir/subdir/path1', Utils::url('/subdir/path1', true)); + self::assertSame('http://testing.dev/subdir/subdir/path1/path2', Utils::url('/subdir/path1/path2', true)); + self::assertSame('http://testing.dev/subdir/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg', true)); + self::assertSame('http://testing.dev/subdir/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true)); // Relative paths from Grav root. self::assertSame('/subdir/subdir', Utils::url('subdir')); From 4f9256817132280ec3940e4397302b399942320c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 3 Mar 2022 13:16:48 -0700 Subject: [PATCH 20/32] Added system config option `legacy_url_root_behavior` --- CHANGELOG.md | 1 + system/config/system.yaml | 1 + system/src/Grav/Common/Utils.php | 13 +++++++------ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79c680ef71..5f5ccf218c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) * Added XSS check for uploaded SVG files before they get stored * Fixed phpstan issues (All level 2, Framework level 5) + * Added a `system.legacy_url_root_behavior` config option to enable legacy/broken `Utils::url()` behavior 2. [](#bugfix) * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) diff --git a/system/config/system.yaml b/system/config/system.yaml index 2de075b263..9fba968a98 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -15,6 +15,7 @@ http_x_forwarded: # Configuration options for the host: false port: true ip: true +legacy_url_root_behavior: false # Enable legacy root URL behavior that breaks URls with paths that match root languages: supported: [] # List of languages supported. eg: [en, fr, de] diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 5ae8193610..017c49822a 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -134,14 +134,15 @@ public static function url($input, $domain = false, $fail_gracefully = false) $resource = $locator->findResource($input, false); } } else { -// $root = $uri->rootUrl(); -// $pattern = '/(' . '\\' . $root . '[\s\/])/'; -// if (preg_match($pattern, $input, $matches)) { -// $input = static::replaceFirstOccurrence($matches[0], '', $input); -// } + // You can manually restore the old legacy behavior that does not produce expected results + if ($grav['config']->get('system.legacy_url_root_behavior', false)) { + $root = $uri->rootUrl(); + if (static::startsWith($input, $root)) { + $input = static::replaceFirstOccurrence($root, '', $input); + } + } $input = ltrim($input, '/'); - $resource = $input; } From 03f71fa49d981de6cd5be3a83f485a3744f69c3b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 4 Mar 2022 15:37:03 -0700 Subject: [PATCH 21/32] rolled back but fixed the Utils::url() functionality --- CHANGELOG.md | 3 +-- system/config/system.yaml | 1 - system/src/Grav/Common/Utils.php | 10 ++++------ tests/unit/Grav/Common/UtilsTest.php | 22 ++++++++++++---------- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f5ccf218c..2e7c277d57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,13 @@ * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) * Added XSS check for uploaded SVG files before they get stored * Fixed phpstan issues (All level 2, Framework level 5) - * Added a `system.legacy_url_root_behavior` config option to enable legacy/broken `Utils::url()` behavior 2. [](#bugfix) * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) * Fixed entity sanitization for XSS detection * Fixed avatar save location when `account://` stream points to custom directory - * Fixed bug in `Utils::url()` when path contains root + * Fixed bug in `Utils::url()` when path contains part of root # v1.7.30 ## 02/07/2022 diff --git a/system/config/system.yaml b/system/config/system.yaml index 9fba968a98..2de075b263 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -15,7 +15,6 @@ http_x_forwarded: # Configuration options for the host: false port: true ip: true -legacy_url_root_behavior: false # Enable legacy root URL behavior that breaks URls with paths that match root languages: supported: [] # List of languages supported. eg: [en, fr, de] diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 017c49822a..d8db12c350 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -134,12 +134,10 @@ public static function url($input, $domain = false, $fail_gracefully = false) $resource = $locator->findResource($input, false); } } else { - // You can manually restore the old legacy behavior that does not produce expected results - if ($grav['config']->get('system.legacy_url_root_behavior', false)) { - $root = $uri->rootUrl(); - if (static::startsWith($input, $root)) { - $input = static::replaceFirstOccurrence($root, '', $input); - } + $root = $uri->rootUrl(); + $pattern = '/(' . '\\' . $root . '[\s\/]?)/'; + if (preg_match($pattern, $input, $matches)) { + $input = static::replaceFirstOccurrence($matches[0], '', $input); } $input = ltrim($input, '/'); diff --git a/tests/unit/Grav/Common/UtilsTest.php b/tests/unit/Grav/Common/UtilsTest.php index 5cf554adc4..c010ec4326 100644 --- a/tests/unit/Grav/Common/UtilsTest.php +++ b/tests/unit/Grav/Common/UtilsTest.php @@ -503,18 +503,20 @@ public function testUrlWithRoot(): void self::assertSame('http://testing.dev/subdir/random/path1/path2/foobar.jpg', Utils::url('/random/path1/path2/foobar.jpg', true)); // Absolute Paths including the grav base. - self::assertSame('/subdir/subdir', Utils::url('/subdir')); - self::assertSame('/subdir/subdir/path1', Utils::url('/subdir/path1')); - self::assertSame('/subdir/subdir/path1/path2', Utils::url('/subdir/path1/path2')); - self::assertSame('/subdir/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg')); - self::assertSame('/subdir/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg')); + self::assertSame('/subdir/', Utils::url('/subdir')); + self::assertSame('/subdir/', Utils::url('/subdir/')); + self::assertSame('/subdir/path1', Utils::url('/subdir/path1')); + self::assertSame('/subdir/path1/path2', Utils::url('/subdir/path1/path2')); + self::assertSame('/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg')); + self::assertSame('/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg')); // Absolute paths from Grav root with domain. - self::assertSame('http://testing.dev/subdir/subdir', Utils::url('/subdir', true)); - self::assertSame('http://testing.dev/subdir/subdir/path1', Utils::url('/subdir/path1', true)); - self::assertSame('http://testing.dev/subdir/subdir/path1/path2', Utils::url('/subdir/path1/path2', true)); - self::assertSame('http://testing.dev/subdir/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg', true)); - self::assertSame('http://testing.dev/subdir/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true)); + self::assertSame('http://testing.dev/subdir/', Utils::url('/subdir', true)); + self::assertSame('http://testing.dev/subdir/', Utils::url('/subdir/', true)); + self::assertSame('http://testing.dev/subdir/path1', Utils::url('/subdir/path1', true)); + self::assertSame('http://testing.dev/subdir/path1/path2', Utils::url('/subdir/path1/path2', true)); + self::assertSame('http://testing.dev/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg', true)); + self::assertSame('http://testing.dev/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true)); // Relative paths from Grav root. self::assertSame('/subdir/subdir', Utils::url('subdir')); From 0abde01442f34a1e14adb25b3ee8f8f39edd8ba9 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 5 Mar 2022 09:22:12 -0700 Subject: [PATCH 22/32] better fix --- system/src/Grav/Common/Utils.php | 2 +- tests/unit/Grav/Common/UtilsTest.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index d8db12c350..f444fe2172 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -135,7 +135,7 @@ public static function url($input, $domain = false, $fail_gracefully = false) } } else { $root = $uri->rootUrl(); - $pattern = '/(' . '\\' . $root . '[\s\/]?)/'; + $pattern = '/(\\' . $root . '$|\\' . $root . '\/)/'; if (preg_match($pattern, $input, $matches)) { $input = static::replaceFirstOccurrence($matches[0], '', $input); } diff --git a/tests/unit/Grav/Common/UtilsTest.php b/tests/unit/Grav/Common/UtilsTest.php index c010ec4326..37e8637146 100644 --- a/tests/unit/Grav/Common/UtilsTest.php +++ b/tests/unit/Grav/Common/UtilsTest.php @@ -519,7 +519,9 @@ public function testUrlWithRoot(): void self::assertSame('http://testing.dev/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true)); // Relative paths from Grav root. + self::assertSame('/subdir/sub', Utils::url('/sub')); self::assertSame('/subdir/subdir', Utils::url('subdir')); + self::assertSame('/subdir/subdir2/sub', Utils::url('/subdir2/sub')); self::assertSame('/subdir/subdir/path1', Utils::url('subdir/path1')); self::assertSame('/subdir/subdir/path1/path2', Utils::url('subdir/path1/path2')); self::assertSame('/subdir/path1', Utils::url('path1')); From e09bae918cee3109b86887c05fa52a5c6b482216 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 5 Mar 2022 11:20:54 -0700 Subject: [PATCH 23/32] fix for empty $root --- system/src/Grav/Common/Utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index f444fe2172..ea4d971f30 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -136,7 +136,7 @@ public static function url($input, $domain = false, $fail_gracefully = false) } else { $root = $uri->rootUrl(); $pattern = '/(\\' . $root . '$|\\' . $root . '\/)/'; - if (preg_match($pattern, $input, $matches)) { + if (!empty($root) && preg_match($pattern, $input, $matches)) { $input = static::replaceFirstOccurrence($matches[0], '', $input); } From 9fd580c49bca326dcc78aa7a97599b0f826d7297 Mon Sep 17 00:00:00 2001 From: Andy Miller <1084697+rhukster@users.noreply.github.com> Date: Tue, 8 Mar 2022 09:45:41 -0700 Subject: [PATCH 24/32] Alternative Multiavatar Approach (#3551) * Support multiavatar by default * Support custom hash string --- composer.json | 3 +- composer.lock | 49 ++++++++++++++++++- system/blueprints/config/system.yaml | 10 ++++ system/blueprints/user/account.yaml | 7 +++ system/config/system.yaml | 1 + .../src/Grav/Common/User/Traits/UserTrait.php | 39 ++++++++++++++- 6 files changed, 105 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index db54497381..5855970e53 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,8 @@ "itsgoingd/clockwork": "^5.0", "symfony/http-client": "^4.4", "composer/semver": "^1.4", - "rhukster/dom-sanitizer": "^1.0" + "rhukster/dom-sanitizer": "^1.0", + "multiavatar/multiavatar-php": "^1.0" }, "require-dev": { "codeception/codeception": "^4.1", diff --git a/composer.lock b/composer.lock index 965a63c1f4..ff1d930a41 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1067938388862c52927c6450e8a36df0", + "content-hash": "f0530b0fd3e574fef0852376653da5a0", "packages": [ { "name": "composer/ca-bundle", @@ -1314,6 +1314,53 @@ ], "time": "2021-05-28T08:32:12+00:00" }, + { + "name": "multiavatar/multiavatar-php", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/multiavatar/multiavatar-php.git", + "reference": "13a62a656b1c2ca1c62dee57b4c1d8a3b04e6574" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/multiavatar/multiavatar-php/zipball/13a62a656b1c2ca1c62dee57b4c1d8a3b04e6574", + "reference": "13a62a656b1c2ca1c62dee57b4c1d8a3b04e6574", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "Multiavatar.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Gie Katon", + "homepage": "https://giekaton.com" + } + ], + "description": "Multicultural Avatar Generator", + "homepage": "https://multiavatar.com", + "keywords": [ + "avatar", + "creator", + "generator", + "image", + "maker", + "picture", + "profile" + ], + "support": { + "issues": "https://github.com/multiavatar/multiavatar-php/issues", + "source": "https://github.com/multiavatar/multiavatar-php/tree/v1.0.5" + }, + "time": "2021-03-02T07:33:46+00:00" + }, { "name": "nyholm/psr7", "version": "1.5.0", diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index b6beb41b94..1be73e243f 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -1833,3 +1833,13 @@ form: options: file: PLUGIN_ADMIN.FILE folder: PLUGIN_ADMIN.FOLDER + + accounts.avatar: + type: select + label: PLUGIN_ADMIN.AVATAR + default: multiavatar + help: PLUGIN_ADMIN.AVATAR_HELP + options: + multiavatar: Multiavatar [local] + gravatar: Gravatar [external] + diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index 391c7370a3..d8a2930c4c 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -15,6 +15,13 @@ form: multiple: false random_name: true + avatar_hash: + type: text + label: '' + placeholder: 'e.g. dceaadcfda491f4e45' + description: PLUGIN_ADMIN.AVATAR_HASH + size: large + content: type: section title: PLUGIN_ADMIN.ACCOUNT diff --git a/system/config/system.yaml b/system/config/system.yaml index 2de075b263..33222860b9 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -208,6 +208,7 @@ http: accounts: type: regular # EXPERIMENTAL: Account type: regular or flex storage: file # EXPERIMENTAL: Flex storage type: file or folder + avatar: muiltiavatar # Avatar generator [multiavatar|gravatar] flex: cache: diff --git a/system/src/Grav/Common/User/Traits/UserTrait.php b/system/src/Grav/Common/User/Traits/UserTrait.php index 0608caf5ec..8f97b5032d 100644 --- a/system/src/Grav/Common/User/Traits/UserTrait.php +++ b/system/src/Grav/Common/User/Traits/UserTrait.php @@ -9,12 +9,14 @@ namespace Grav\Common\User\Traits; +use Grav\Common\Filesystem\Folder; use Grav\Common\Grav; use Grav\Common\Page\Medium\ImageMedium; use Grav\Common\Page\Medium\Medium; use Grav\Common\Page\Medium\StaticImageMedium; use Grav\Common\User\Authentication; use Grav\Common\Utils; +use Gregwar\Image\Image; use function is_array; use function is_string; @@ -174,10 +176,43 @@ public function getAvatarUrl(): string } } + $avatar_url = ''; $email = $this->get('email'); + $hashcode = $this->get('avatar_hash'); + $avatar_generator = Grav::instance()['config']->get('system.accounts.avatar', 'multiavatar'); + + if ($hashcode || $email) { + $hash = $hashcode ?: md5(strtolower(trim($email))); + switch ($avatar_generator) { + case 'gravatar': + $avatar_url = 'https://www.gravatar.com/avatar/' . $hash; + break; + default: + return $this->generateMultiavatar($hash); + } + } + + return $avatar_url; + } + + protected function generateMultiavatar($hash) { + + $storage = Grav::instance()['locator']->findResource('image://multiavatar', true, true); + $avatar_file = "$storage/$hash.svg"; + $avatar_url = "/user/images/multiavatar/$hash.svg"; + + if (!file_exists($storage)) { + Folder::create($storage); + } + + if (!file_exists($avatar_file)) { + $mavatar = new \Multiavatar(); + file_put_contents($avatar_file, $mavatar->generate($hash, null, null)); + } + + + return Utils::url($avatar_url); - // By default fall back to gravatar image. - return $email ? 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($email))) : ''; } abstract public function get($name, $default = null, $separator = null); From 499b25aad8d1ff5caf98cee9a333808de35a238c Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 8 Mar 2022 19:07:55 +0200 Subject: [PATCH 25/32] Composer update --- composer.lock | 191 ++++++++++++++++++++++++++------------------------ 1 file changed, 98 insertions(+), 93 deletions(-) diff --git a/composer.lock b/composer.lock index ff1d930a41..d0dc8dfd37 100644 --- a/composer.lock +++ b/composer.lock @@ -2231,16 +2231,16 @@ }, { "name": "symfony/console", - "version": "v4.4.37", + "version": "v4.4.38", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6" + "reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0259f01dbf9d77badddbbf4c2abb681f24c9cac6", - "reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6", + "url": "https://api.github.com/repos/symfony/console/zipball/5a50085bf5460f0c0d60a50b58388c1249826b8a", + "reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a", "shasum": "" }, "require": { @@ -2301,7 +2301,7 @@ "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/v4.4.37" + "source": "https://github.com/symfony/console/tree/v4.4.38" }, "funding": [ { @@ -2317,7 +2317,7 @@ "type": "tidelift" } ], - "time": "2022-01-26T16:15:26+00:00" + "time": "2022-01-30T21:23:57+00:00" }, { "name": "symfony/contracts", @@ -2499,16 +2499,16 @@ }, { "name": "symfony/http-client", - "version": "v4.4.37", + "version": "v4.4.39", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "8129ccd6233338e1d495b7734c003053766cb262" + "reference": "40342406a975385c5b21e929df46e3fc0278853d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/8129ccd6233338e1d495b7734c003053766cb262", - "reference": "8129ccd6233338e1d495b7734c003053766cb262", + "url": "https://api.github.com/repos/symfony/http-client/zipball/40342406a975385c5b21e929df46e3fc0278853d", + "reference": "40342406a975385c5b21e929df46e3fc0278853d", "shasum": "" }, "require": { @@ -2560,7 +2560,7 @@ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-client/tree/v4.4.37" + "source": "https://github.com/symfony/http-client/tree/v4.4.39" }, "funding": [ { @@ -2576,11 +2576,11 @@ "type": "tidelift" } ], - "time": "2022-01-19T13:29:07+00:00" + "time": "2022-02-28T13:17:32+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -2612,12 +2612,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2642,7 +2642,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" }, "funding": [ { @@ -2662,7 +2662,7 @@ }, { "name": "symfony/polyfill-iconv", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", @@ -2725,7 +2725,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.25.0" }, "funding": [ { @@ -2745,7 +2745,7 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", @@ -2808,7 +2808,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" }, "funding": [ { @@ -2828,7 +2828,7 @@ }, { "name": "symfony/polyfill-php74", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php74.git", @@ -2888,7 +2888,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php74/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php74/tree/v1.25.0" }, "funding": [ { @@ -2908,16 +2908,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", "shasum": "" }, "require": { @@ -2971,7 +2971,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" }, "funding": [ { @@ -2987,11 +2987,11 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:33+00:00" + "time": "2022-03-04T08:16:47+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.24.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", @@ -3050,7 +3050,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.24.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" }, "funding": [ { @@ -3132,16 +3132,16 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.37", + "version": "v4.4.39", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "e74eee4ec02de71db3d60151aa5b203c990556df" + "reference": "35237c5e5dcb6593a46a860ba5b29c1d4683d80e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e74eee4ec02de71db3d60151aa5b203c990556df", - "reference": "e74eee4ec02de71db3d60151aa5b203c990556df", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/35237c5e5dcb6593a46a860ba5b29c1d4683d80e", + "reference": "35237c5e5dcb6593a46a860ba5b29c1d4683d80e", "shasum": "" }, "require": { @@ -3201,7 +3201,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.37" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.39" }, "funding": [ { @@ -3217,7 +3217,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:41:36+00:00" + "time": "2022-02-25T10:38:15+00:00" }, { "name": "symfony/yaml", @@ -3491,16 +3491,16 @@ }, { "name": "codeception/codeception", - "version": "4.1.29", + "version": "4.1.30", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "f8dec8f2bf5347cc596aaf141753f4fb2504c17c" + "reference": "a035d77d070fa57fad438e07a65447aeca248c45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/f8dec8f2bf5347cc596aaf141753f4fb2504c17c", - "reference": "f8dec8f2bf5347cc596aaf141753f4fb2504c17c", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/a035d77d070fa57fad438e07a65447aeca248c45", + "reference": "a035d77d070fa57fad438e07a65447aeca248c45", "shasum": "" }, "require": { @@ -3577,7 +3577,7 @@ ], "support": { "issues": "https://github.com/Codeception/Codeception/issues", - "source": "https://github.com/Codeception/Codeception/tree/4.1.29" + "source": "https://github.com/Codeception/Codeception/tree/4.1.30" }, "funding": [ { @@ -3585,7 +3585,7 @@ "type": "open_collective" } ], - "time": "2022-01-29T16:56:03+00:00" + "time": "2022-03-05T18:12:30+00:00" }, { "name": "codeception/lib-asserts", @@ -3903,29 +3903,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -3952,7 +3953,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" }, "funding": [ { @@ -3968,7 +3969,7 @@ "type": "tidelift" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-03-03T08:28:38+00:00" }, { "name": "getgrav/markdowndocs", @@ -4173,12 +4174,12 @@ } }, "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4232,25 +4233,29 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { @@ -4275,7 +4280,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" }, "funding": [ { @@ -4283,7 +4288,7 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2022-03-03T13:19:32+00:00" }, { "name": "nikic/php-parser", @@ -4681,16 +4686,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.4.6", + "version": "1.4.8", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "8a7761f1c520e0dad6e04d862fdc697445457cfe" + "reference": "2a6d6704b17c4db6190cc3104056c0aad740cb15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8a7761f1c520e0dad6e04d862fdc697445457cfe", - "reference": "8a7761f1c520e0dad6e04d862fdc697445457cfe", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/2a6d6704b17c4db6190cc3104056c0aad740cb15", + "reference": "2a6d6704b17c4db6190cc3104056c0aad740cb15", "shasum": "" }, "require": { @@ -4721,7 +4726,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.4.6" + "source": "https://github.com/phpstan/phpstan/tree/1.4.8" }, "funding": [ { @@ -4741,7 +4746,7 @@ "type": "tidelift" } ], - "time": "2022-02-06T12:56:13+00:00" + "time": "2022-03-04T13:03:56+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -4795,16 +4800,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.11", + "version": "9.2.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f" + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f", - "reference": "665a1ac0a763c51afc30d6d130dac0813092b17f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", "shasum": "" }, "require": { @@ -4860,7 +4865,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" }, "funding": [ { @@ -4868,7 +4873,7 @@ "type": "github" } ], - "time": "2022-02-18T12:46:09+00:00" + "time": "2022-03-07T09:28:20+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5113,16 +5118,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.14", + "version": "9.5.18", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189" + "reference": "1b5856028273bfd855e60a887278857d872ec67a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1883687169c017d6ae37c58883ca3994cfc34189", - "reference": "1883687169c017d6ae37c58883ca3994cfc34189", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1b5856028273bfd855e60a887278857d872ec67a", + "reference": "1b5856028273bfd855e60a887278857d872ec67a", "shasum": "" }, "require": { @@ -5138,7 +5143,7 @@ "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -5200,7 +5205,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.14" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.18" }, "funding": [ { @@ -5212,7 +5217,7 @@ "type": "github" } ], - "time": "2022-02-18T12:54:07+00:00" + "time": "2022-03-08T06:52:28+00:00" }, { "name": "psr/http-client", @@ -6437,16 +6442,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v5.4.3", + "version": "v5.4.6", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "2634381fdf27a2a0a8ac8eb404025eb656c65d0c" + "reference": "c0bda97480d96337bd3866026159a8b358665457" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2634381fdf27a2a0a8ac8eb404025eb656c65d0c", - "reference": "2634381fdf27a2a0a8ac8eb404025eb656c65d0c", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/c0bda97480d96337bd3866026159a8b358665457", + "reference": "c0bda97480d96337bd3866026159a8b358665457", "shasum": "" }, "require": { @@ -6492,7 +6497,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v5.4.3" + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.6" }, "funding": [ { @@ -6508,7 +6513,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-03-02T12:42:23+00:00" }, { "name": "symfony/finder", From e0deeeb551b99fa2b5f75c2f77c11672806d8944 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 8 Mar 2022 19:15:46 +0200 Subject: [PATCH 26/32] Make new avatar logic more robust --- .../src/Grav/Common/User/Traits/UserTrait.php | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/system/src/Grav/Common/User/Traits/UserTrait.php b/system/src/Grav/Common/User/Traits/UserTrait.php index 8f97b5032d..91c41aa110 100644 --- a/system/src/Grav/Common/User/Traits/UserTrait.php +++ b/system/src/Grav/Common/User/Traits/UserTrait.php @@ -16,7 +16,8 @@ use Grav\Common\Page\Medium\StaticImageMedium; use Grav\Common\User\Authentication; use Grav\Common\Utils; -use Gregwar\Image\Image; +use Multiavatar; +use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use function is_array; use function is_string; @@ -176,40 +177,50 @@ public function getAvatarUrl(): string } } - $avatar_url = ''; $email = $this->get('email'); - $hashcode = $this->get('avatar_hash'); $avatar_generator = Grav::instance()['config']->get('system.accounts.avatar', 'multiavatar'); - - if ($hashcode || $email) { - $hash = $hashcode ?: md5(strtolower(trim($email))); - switch ($avatar_generator) { - case 'gravatar': - $avatar_url = 'https://www.gravatar.com/avatar/' . $hash; - break; - default: - return $this->generateMultiavatar($hash); + if ($avatar_generator === 'gravatar') { + if (!$email) { + return ''; } + + $hash = md5(strtolower(trim($email))); + + return 'https://www.gravatar.com/avatar/' . $hash; + } + + $hash = $this->get('avatar_hash'); + if (!$hash) { + $username = $this->get('username'); + $hash = md5(strtolower(trim($email ?? $username))); } - return $avatar_url; + return $this->generateMultiavatar($hash); } - protected function generateMultiavatar($hash) { + /** + * @param string $hash + * @return string + */ + protected function generateMultiavatar(string $hash): string + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; - $storage = Grav::instance()['locator']->findResource('image://multiavatar', true, true); - $avatar_file = "$storage/$hash.svg"; - $avatar_url = "/user/images/multiavatar/$hash.svg"; + $storage = $locator->findResource('image://multiavatar', true, true); + $avatar_file = "{$storage}/{$hash}.svg"; if (!file_exists($storage)) { Folder::create($storage); } if (!file_exists($avatar_file)) { - $mavatar = new \Multiavatar(); + $mavatar = new Multiavatar(); + file_put_contents($avatar_file, $mavatar->generate($hash, null, null)); } + $avatar_url = $locator->findResource("image://multiavatar/{$hash}.svg", false, true); return Utils::url($avatar_url); From e60ba13d75ab194354e6cffa3f06219b1d7836cc Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Tue, 8 Mar 2022 09:32:28 -0800 Subject: [PATCH 27/32] Fixed issue with URL method not escaping subpaths slashes --- system/src/Grav/Common/Utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index ea4d971f30..a0e1a5ef75 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -135,7 +135,7 @@ public static function url($input, $domain = false, $fail_gracefully = false) } } else { $root = $uri->rootUrl(); - $pattern = '/(\\' . $root . '$|\\' . $root . '\/)/'; + $pattern = '#(' . $root . '$|' . $root . '/)#'; if (!empty($root) && preg_match($pattern, $input, $matches)) { $input = static::replaceFirstOccurrence($matches[0], '', $input); } From 41b8fbb0e09e0c2406bd43b55e03f4bba7ee4e8c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 8 Mar 2022 10:45:44 -0700 Subject: [PATCH 28/32] Update changelog + Accounts in sidebar --- CHANGELOG.md | 23 ++++++----- system/blueprints/config/system.yaml | 58 ++++++++++++++++------------ system/config/system.yaml | 2 +- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e7c277d57..8cffdfcc23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,16 +2,19 @@ ## mm/dd/2022 1. [](#new) - * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) - * Added XSS check for uploaded SVG files before they get stored - * Fixed phpstan issues (All level 2, Framework level 5) -2. [](#bugfix) - * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) - * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) - * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) - * Fixed entity sanitization for XSS detection - * Fixed avatar save location when `account://` stream points to custom directory - * Fixed bug in `Utils::url()` when path contains part of root + * Added new local Multiavatar (local generation). **This will be default in Grav 1.8** + * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) + * Added XSS check for uploaded SVG files before they get stored + * Fixed phpstan issues (All level 2, Framework level 5) +2. [](#improved) + * Moved Accounts out of Experimental section of System configuration +3. [](#bugfix) + * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) + * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) + * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) + * Fixed entity sanitization for XSS detection + * Fixed avatar save location when `account://` stream points to custom directory + * Fixed bug in `Utils::url()` when path contains part of root # v1.7.30 ## 02/07/2022 diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 1be73e243f..787fcd5775 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -1786,35 +1786,15 @@ form: validate: type: bool - experimental: + + accounts: type: tab - title: PLUGIN_ADMIN.EXPERIMENTAL + title: PLUGIN_ADMIN.ACCOUNTS fields: - experimental_section: - type: section - title: PLUGIN_ADMIN.EXPERIMENTAL - underline: true - -# flex_pages: -# type: section -# title: Flex Pages -# -# pages.type: -# type: select -# label: PLUGIN_ADMIN.PAGES_TYPE -# highlight: regular -# help: PLUGIN_ADMIN.PAGES_TYPE_HELP -# options: -# regular: PLUGIN_ADMIN.REGULAR -# flex: PLUGIN_ADMIN.FLEX - - pages.type: - type: hidden - flex_accounts: type: section - title: Flex Accounts + title: User Accounts accounts.type: type: select @@ -1837,9 +1817,37 @@ form: accounts.avatar: type: select label: PLUGIN_ADMIN.AVATAR - default: multiavatar + default: gravatar help: PLUGIN_ADMIN.AVATAR_HELP options: multiavatar: Multiavatar [local] gravatar: Gravatar [external] +# experimental: +# type: tab +# title: PLUGIN_ADMIN.EXPERIMENTAL +# +# fields: +# experimental_section: +# type: section +# title: PLUGIN_ADMIN.EXPERIMENTAL +# underline: true +# +# flex_pages: +# type: section +# title: Flex Pages +# +# pages.type: +# type: select +# label: PLUGIN_ADMIN.PAGES_TYPE +# highlight: regular +# help: PLUGIN_ADMIN.PAGES_TYPE_HELP +# options: +# regular: PLUGIN_ADMIN.REGULAR +# flex: PLUGIN_ADMIN.FLEX +# +# pages.type: +# type: hidden + + + diff --git a/system/config/system.yaml b/system/config/system.yaml index 33222860b9..380d650ebc 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -208,7 +208,7 @@ http: accounts: type: regular # EXPERIMENTAL: Account type: regular or flex storage: file # EXPERIMENTAL: Flex storage type: file or folder - avatar: muiltiavatar # Avatar generator [multiavatar|gravatar] + avatar: gravatar # Avatar generator [multiavatar|gravatar] flex: cache: From c7bc5f5b59b1f8a3d1967ea00d7c677338440aa3 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 8 Mar 2022 14:00:06 -0700 Subject: [PATCH 29/32] hash for multiavatar only --- system/blueprints/user/account.yaml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index d8a2930c4c..ef5f25b045 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -15,12 +15,16 @@ form: multiple: false random_name: true - avatar_hash: - type: text - label: '' - placeholder: 'e.g. dceaadcfda491f4e45' - description: PLUGIN_ADMIN.AVATAR_HASH - size: large + multiavatar_only: + type: conditional + condition: config.system.accounts.avatar == 'multiavatar' + fields: + avatar_hash: + type: text + label: '' + placeholder: 'e.g. dceaadcfda491f4e45' + description: PLUGIN_ADMIN.AVATAR_HASH + size: large content: type: section From 4d4efb31e3b3a857118783e840ef82699e809ffe Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Wed, 9 Mar 2022 12:25:46 +0200 Subject: [PATCH 30/32] Escape root url pattern in Utils::url() --- system/src/Grav/Common/Utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index a0e1a5ef75..145a893569 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -134,7 +134,7 @@ public static function url($input, $domain = false, $fail_gracefully = false) $resource = $locator->findResource($input, false); } } else { - $root = $uri->rootUrl(); + $root = preg_quote($uri->rootUrl(), '#'); $pattern = '#(' . $root . '$|' . $root . '/)#'; if (!empty($root) && preg_match($pattern, $input, $matches)) { $input = static::replaceFirstOccurrence($matches[0], '', $input); From 492cc1d2f11eda6d139e27d23ff3d0fcc8ea7d06 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Mon, 14 Mar 2022 18:55:56 +0200 Subject: [PATCH 31/32] Added XSS check for uploaded SVG files before they get stored (in Form plugin) --- system/src/Grav/Framework/Form/Traits/FormTrait.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Framework/Form/Traits/FormTrait.php b/system/src/Grav/Framework/Form/Traits/FormTrait.php index f4be9e7aaf..710d8b0cc8 100644 --- a/system/src/Grav/Framework/Form/Traits/FormTrait.php +++ b/system/src/Grav/Framework/Form/Traits/FormTrait.php @@ -23,6 +23,7 @@ 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; @@ -775,13 +776,16 @@ protected function validateUpload(UploadedFileInterface $file): void { // 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(); + } } /** From 0d19bc6e970221716a489c43614cb99c51649fa3 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 14 Mar 2022 11:34:33 -0600 Subject: [PATCH 32/32] prepare for release --- CHANGELOG.md | 4 ++-- system/defines.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cffdfcc23..5b396bd183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v1.7.31 -## mm/dd/2022 +## 03/14/2022 1. [](#new) * Added new local Multiavatar (local generation). **This will be default in Grav 1.8** @@ -7,7 +7,7 @@ * Added XSS check for uploaded SVG files before they get stored * Fixed phpstan issues (All level 2, Framework level 5) 2. [](#improved) - * Moved Accounts out of Experimental section of System configuration + * Moved Accounts out of Experimental section of System configuration to new "Accounts" tab 3. [](#bugfix) * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) diff --git a/system/defines.php b/system/defines.php index 39dd692640..5f743db3f1 100644 --- a/system/defines.php +++ b/system/defines.php @@ -9,7 +9,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.7.30'); +define('GRAV_VERSION', '1.7.31'); define('GRAV_SCHEMA', '1.7.0_2020-11-20_1'); define('GRAV_TESTING', false);