diff --git a/CHANGELOG.md b/CHANGELOG.md index ee182b8..f7fc0d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,115 @@ +# v1.7.42.3 +## 07/18/2023 + +2. [](#improved) + * Fixed a typo in `Utils::isDangerousFunction` + +# v1.7.42.2 +## 07/18/2023 + +2. [](#improved) + * In `Utils::isDangerousFunction`, handle double `\\` in `|map` twig filter to mitigate SSTI attack + * Better handle empty email in `Validatoin::typeEmail()` + +# v1.7.42.1 +## 06/15/2023 + +2. [](#improved) + * Quick fix for `isDangerousFunction` when `$name` was a closure [#3727](https://github.com/getgrav/grav/issues/3727) + +# v1.7.42 +## 06/14/2023 + +1. [](#new) + * Added a new `system.languages.debug` option that adds a `` around strings translated with `|t`. This can be styled by the theme as needed. +1. [](#improved) + * More robust SSTI handling in `filter`, `map`, and `reduce` Twig filters and functions + * Various SSTI improvements `Utils::isDangerousFunction()` +1. [](#bugfix) + * Fixed Twig `|map()` allowing code execution + * Fixed Twig `|reduce()` allowing code execution + +# v1.7.41.2 +## 06/01/2023 + +1. [](#improved) + * Added the ability to set a configurable 'key' for the Twig Cache Tag: `{% cache 'my-key' 600 %}` +1. [](#bugfix) + * Fixed an issue with special characters in slug's would cause redirect loops + +# v1.7.41.1 +## 05/10/2023 + +1. [](#bugfix) + * Fixed certain UTF-8 characters breaking `Truncator` class [#3716](https://github.com/getgrav/grav/issues/3716) + +# v1.7.41 +## 05/09/2023 + +1. [](#improved) + * Removed `FILTER_SANITIZE_STRING` input filter in favor of `htmlspecialchars(strip_tags())` for PHP 8.2+ + * Added `GRAV_SANITIZE_STRING` constant to replace `FILTER_SANITIZE_STRING` for PHP 8.2+ + * Support non-deprecated style dynamic properties in `Parsedown` class via `ParseDownGravTrait` for PHP 8.2+ + * Modified `Truncator` to not use deprecated `mb_convert_encoding()` for PHP 8.2+ + * Fixed passing null into `mb_strpos()` deprecated for PHP 8.2+ + * Updated internal `TwigDeferredExtension` to be PHP 8.2+ compatible + * Upgraded `getgrav/image` fork to take advantage of various PHP 8.2+ fixes + * Use `UserGroupObject::groupNames` method in blueprints for PHP 8.2+ + * Comment out `files-upload` deprecated message as this is not going to be removed + * Added various public `Twig` class variables used by admin to address deprecated messages for PHP 8.2+ + * Added `parse_url` to list of PHP functions supported in Twig Extension + * Added support for dynamic functions in `Parsedown` to stop deprecation messages in PHP 8.2+ + +# v1.7.40 +## 03/22/2023 + +1. [](#new) + * Added a new `timestamp: true|false` option for individual assets +1. [](#improved) + * Removed outdated `xcache` setting [#3615](https://github.com/getgrav/grav/pull/3615) + * Updated `robots.txt` [#3625](https://github.com/getgrav/grav/pull/3625) +1. [](#bugfix) + * Fixed `force_ssl` redirect in case of undefined hostname [#3702](https://github.com/getgrav/grav/pull/3702) + * Fixed an issue with duplicate identical page paths + * Fixed `BlueprintSchema:flattenData` to properly handle ignored fields + * Fixed LogViewer regex greediness [#3684](https://github.com/getgrav/grav/pull/3684) + * Fixed `whoami` command [#3695](https://github.com/getgrav/grav/pull/3695) + +# v1.7.39.4 +## 02/22/2023 + +1. [](#bugfix) + * Reverted a reorganization of `account.yaml` that caused username to be disabled [admin#2344](https://github.com/getgrav/grav-plugin-admin/issues/2344) + +# v1.7.39.3 +## 02/21/2023 + +1. [](#bugfix) + * Fix for overzealous modular page template rendering fix in 1.7.39 causing Feed plugin to break [#3689](https://github.com/getgrav/grav/issues/3689) + +# v1.7.39.2 +## 02/20/2023 + +1. [](#bugfix) + * Fix for invalid session breaking Flex Accounts (when switching from Regular to Flex) + +# v1.7.39.1 +## 02/20/2023 + +1. [](#bugfix) + * Fix for broken image CSS with the latest version of DebugBar + +# v1.7.39 +## 02/19/2023 + +1. [](#improved) + * Vendor library updates to latest versions +1. [](#bugfix) + * Various PHP 8.2 fixes + * Fixed an issue with modular pages rendering thew wrong template when dynamically changing the page + * Fixed an issue with `email` validation that was failing on UTF-8 characters. Following best practices and now only check for `@` and length. + * Fixed PHPUnit tests to remove deprecation warnings + # v1.7.38 ## 01/02/2023 @@ -7,7 +119,6 @@ * Vendor library updates to latest versions * Updated `bin/composer.phar` to latest `2.4.4` version [#3627](https://github.com/getgrav/grav/issues/3627) 1. [](#bugfix) - * Don't fail hard if pages recurse with same path * Github workflows security hardening [#3624](https://github.com/getgrav/grav/pull/3624) diff --git a/composer.lock b/composer.lock index 9dcec10..92cde48 100644 --- a/composer.lock +++ b/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "composer/ca-bundle", - "version": "1.3.4", + "version": "1.3.6", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5" + "reference": "90d087e988ff194065333d16bc5cf649872d9cdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/69098eca243998b53eed7a48d82dedd28b447cd5", - "reference": "69098eca243998b53eed7a48d82dedd28b447cd5", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/90d087e988ff194065333d16bc5cf649872d9cdb", + "reference": "90d087e988ff194065333d16bc5cf649872d9cdb", "shasum": "" }, "require": { @@ -64,7 +64,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.4" + "source": "https://github.com/composer/ca-bundle/tree/1.3.6" }, "funding": [ { @@ -80,7 +80,7 @@ "type": "tidelift" } ], - "time": "2022-10-12T12:08:29+00:00" + "time": "2023-06-06T12:02:59+00:00" }, { "name": "composer/semver", @@ -333,25 +333,29 @@ }, { "name": "doctrine/deprecations", - "version": "v1.0.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -370,9 +374,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" }, - "time": "2022-05-02T15:47:09+00:00" + "time": "2023-06-03T09:27:29+00:00" }, { "name": "donatj/phpuseragentparser", @@ -593,16 +597,16 @@ }, { "name": "filp/whoops", - "version": "2.14.6", + "version": "2.15.2", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "f7948baaa0330277c729714910336383286305da" + "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/f7948baaa0330277c729714910336383286305da", - "reference": "f7948baaa0330277c729714910336383286305da", + "url": "https://api.github.com/repos/filp/whoops/zipball/aac9304c5ed61bf7b1b7a6064bf9806ab842ce73", + "reference": "aac9304c5ed61bf7b1b7a6064bf9806ab842ce73", "shasum": "" }, "require": { @@ -652,7 +656,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.6" + "source": "https://github.com/filp/whoops/tree/2.15.2" }, "funding": [ { @@ -660,7 +664,7 @@ "type": "github" } ], - "time": "2022-11-02T16:23:29+00:00" + "time": "2023-04-12T12:00:00+00:00" }, { "name": "getgrav/cache", @@ -715,17 +719,17 @@ }, { "name": "getgrav/image", - "version": "v3.0.0", + "version": "v3.0.1", "target-dir": "Gregwar/Image", "source": { "type": "git", "url": "https://github.com/getgrav/Image.git", - "reference": "02c1bb2c179dd894c4f6610c9c49da364ee7d264" + "reference": "a6a36c24db4b0fd7a7bfd50b86412eaecd5c6370" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getgrav/Image/zipball/02c1bb2c179dd894c4f6610c9c49da364ee7d264", - "reference": "02c1bb2c179dd894c4f6610c9c49da364ee7d264", + "url": "https://api.github.com/repos/getgrav/Image/zipball/a6a36c24db4b0fd7a7bfd50b86412eaecd5c6370", + "reference": "a6a36c24db4b0fd7a7bfd50b86412eaecd5c6370", "shasum": "" }, "require": { @@ -769,22 +773,22 @@ "image" ], "support": { - "source": "https://github.com/getgrav/Image/tree/v3.0.0" + "source": "https://github.com/getgrav/Image/tree/v3.0.1" }, - "time": "2021-04-20T05:50:18+00:00" + "time": "2023-05-08T21:44:38+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.9.0", + "version": "1.9.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318" + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/e98e3e6d4f86621a9b75f623996e6bbdeb4b9318", - "reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b", "shasum": "" }, "require": { @@ -803,11 +807,6 @@ "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9-dev" - } - }, "autoload": { "files": [ "src/functions_include.php" @@ -865,7 +864,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.9.0" + "source": "https://github.com/guzzle/psr7/tree/1.9.1" }, "funding": [ { @@ -881,7 +880,7 @@ "type": "tidelift" } ], - "time": "2022-06-20T21:43:03+00:00" + "time": "2023-04-17T16:00:37+00:00" }, { "name": "itsgoingd/clockwork", @@ -1018,16 +1017,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.70", + "version": "1.3.71", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b" + "reference": "ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/2807d9f9bece6877577ad44acb5c801bb3ae536b", - "reference": "2807d9f9bece6877577ad44acb5c801bb3ae536b", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1", + "reference": "ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1", "shasum": "" }, "require": { @@ -1077,7 +1076,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.70" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.71" }, "funding": [ { @@ -1085,7 +1084,7 @@ "type": "github" } ], - "time": "2022-12-09T12:56:44+00:00" + "time": "2023-04-25T20:33:03+00:00" }, { "name": "matthiasmullie/path-converter", @@ -1142,25 +1141,25 @@ }, { "name": "maximebf/debugbar", - "version": "v1.18.1", + "version": "v1.18.2", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "ba0af68dd4316834701ecb30a00ce9604ced3ee9" + "reference": "17dcf3f6ed112bb85a37cf13538fd8de49f5c274" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/ba0af68dd4316834701ecb30a00ce9604ced3ee9", - "reference": "ba0af68dd4316834701ecb30a00ce9604ced3ee9", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/17dcf3f6ed112bb85a37cf13538fd8de49f5c274", + "reference": "17dcf3f6ed112bb85a37cf13538fd8de49f5c274", "shasum": "" }, "require": { "php": "^7.1|^8", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^2.6|^3|^4|^5|^6" + "symfony/var-dumper": "^4|^5|^6" }, "require-dev": { - "phpunit/phpunit": "^7.5.20 || ^9.4.2", + "phpunit/phpunit": ">=7.5.20 <10.0", "twig/twig": "^1.38|^2.7|^3.0" }, "suggest": { @@ -1202,9 +1201,9 @@ ], "support": { "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.1" + "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.2" }, - "time": "2022-03-31T14:55:54+00:00" + "time": "2023-02-04T15:27:00+00:00" }, { "name": "miljar/php-exif", @@ -1401,38 +1400,39 @@ }, { "name": "nyholm/psr7", - "version": "1.5.1", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "f734364e38a876a23be4d906a2a089e1315be18a" + "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/f734364e38a876a23be4d906a2a089e1315be18a", - "reference": "f734364e38a876a23be4d906a2a089e1315be18a", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/3cb4d163b58589e47b35103e8e5e6a6a475b47be", + "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be", "shasum": "" }, "require": { - "php": ">=7.1", - "php-http/message-factory": "^1.0", + "php": ">=7.2", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.1 || ^2.0" }, "provide": { + "php-http/message-factory-implementation": "1.0", "psr/http-factory-implementation": "1.0", "psr/http-message-implementation": "1.0" }, "require-dev": { "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", "php-http/psr7-integration-tests": "^1.0", - "phpunit/phpunit": "^7.5 || 8.5 || 9.4", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", "symfony/error-handler": "^4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "1.8-dev" } }, "autoload": { @@ -1462,7 +1462,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.5.1" + "source": "https://github.com/Nyholm/psr7/tree/1.8.0" }, "funding": [ { @@ -1474,7 +1474,7 @@ "type": "github" } ], - "time": "2022-06-22T07:13:36+00:00" + "time": "2023-05-02T11:26:24+00:00" }, { "name": "nyholm/psr7-server", @@ -1542,60 +1542,6 @@ ], "time": "2021-05-12T11:11:27+00:00" }, - { - "name": "php-http/message-factory", - "version": "v1.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-http/message-factory.git", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", - "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "psr/http-message": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com" - } - ], - "description": "Factory interfaces for PSR-7 HTTP Message", - "homepage": "http://php-http.org", - "keywords": [ - "factory", - "http", - "message", - "stream", - "uri" - ], - "support": { - "issues": "https://github.com/php-http/message-factory/issues", - "source": "https://github.com/php-http/message-factory/tree/master" - }, - "time": "2015-12-19T14:08:53+00:00" - }, { "name": "pimple/pimple", "version": "v3.5.0", @@ -1748,21 +1694,21 @@ }, { "name": "psr/http-factory", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", - "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", "shasum": "" }, "require": { "php": ">=7.0.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -1782,7 +1728,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for PSR-7 HTTP message factories", @@ -1797,31 +1743,31 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" }, - "time": "2019-04-30T12:38:16+00:00" + "time": "2023-04-10T20:10:41+00:00" }, { "name": "psr/http-message", - "version": "1.0.1", + "version": "1.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -1850,27 +1796,27 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/master" + "source": "https://github.com/php-fig/http-message/tree/1.1" }, - "time": "2016-08-06T14:39:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { "name": "psr/http-server-handler", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-server-handler.git", - "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7" + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7", - "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", "shasum": "" }, "require": { "php": ">=7.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -1890,7 +1836,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP server-side request handler", @@ -1906,28 +1852,27 @@ "server" ], "support": { - "issues": "https://github.com/php-fig/http-server-handler/issues", - "source": "https://github.com/php-fig/http-server-handler/tree/master" + "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" }, - "time": "2018-10-30T16:46:14+00:00" + "time": "2023-04-10T20:06:20+00:00" }, { "name": "psr/http-server-middleware", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-server-middleware.git", - "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5" + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5", - "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", "shasum": "" }, "require": { "php": ">=7.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0 || ^2.0", "psr/http-server-handler": "^1.0" }, "type": "library", @@ -1948,7 +1893,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP server-side middleware", @@ -1964,9 +1909,9 @@ ], "support": { "issues": "https://github.com/php-fig/http-server-middleware/issues", - "source": "https://github.com/php-fig/http-server-middleware/tree/master" + "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" }, - "time": "2018-10-30T17:12:04+00:00" + "time": "2023-04-11T06:14:47+00:00" }, { "name": "psr/log", @@ -2160,16 +2105,16 @@ }, { "name": "rockettheme/toolbox", - "version": "1.6.2", + "version": "1.6.5", "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "99448a20a2f78d6480035d72821ecb9e4dc17032" + "reference": "c5e84deac813da7fcb78cd8a663c8966da9b27bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/99448a20a2f78d6480035d72821ecb9e4dc17032", - "reference": "99448a20a2f78d6480035d72821ecb9e4dc17032", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/c5e84deac813da7fcb78cd8a663c8966da9b27bd", + "reference": "c5e84deac813da7fcb78cd8a663c8966da9b27bd", "shasum": "" }, "require": { @@ -2208,9 +2153,9 @@ ], "support": { "issues": "https://github.com/rockettheme/toolbox/issues", - "source": "https://github.com/rockettheme/toolbox/tree/1.6.2" + "source": "https://github.com/rockettheme/toolbox/tree/1.6.5" }, - "time": "2022-06-14T16:24:33+00:00" + "time": "2023-05-09T18:11:17+00:00" }, { "name": "seld/cli-prompt", @@ -4063,22 +4008,22 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.5.0", + "version": "7.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" + "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", - "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/fb7566caccf22d74d1ab270de3551f72a58399f5", + "reference": "fb7566caccf22d74d1ab270de3551f72a58399f5", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.9 || ^2.4", + "guzzlehttp/promises": "^1.5.3 || ^2.0", + "guzzlehttp/psr7": "^1.9.1 || ^2.4.5", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -4089,7 +4034,8 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.1", "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.29 || ^9.5.23", "psr/log": "^1.1 || ^2.0 || ^3.0" }, @@ -4103,9 +4049,6 @@ "bamarni-bin": { "bin-links": true, "forward-command": false - }, - "branch-alias": { - "dev-master": "7.5-dev" } }, "autoload": { @@ -4171,7 +4114,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.5.0" + "source": "https://github.com/guzzle/guzzle/tree/7.7.0" }, "funding": [ { @@ -4187,38 +4130,37 @@ "type": "tidelift" } ], - "time": "2022-08-28T15:39:27+00:00" + "time": "2023-05-21T14:04:53+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "b94b2807d85443f9719887892882d0329d1e2598" + "reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", - "reference": "b94b2807d85443f9719887892882d0329d1e2598", + "url": "https://api.github.com/repos/guzzle/promises/zipball/3a494dc7dc1d7d12e511890177ae2d0e6c107da6", + "reference": "3a494dc7dc1d7d12e511890177ae2d0e6c107da6", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.1", + "phpunit/phpunit": "^8.5.29 || ^9.5.23" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.5-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Promise\\": "src/" } @@ -4255,7 +4197,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.2" + "source": "https://github.com/guzzle/promises/tree/2.0.0" }, "funding": [ { @@ -4271,20 +4213,20 @@ "type": "tidelift" } ], - "time": "2022-08-28T14:55:35+00:00" + "time": "2023-05-21T13:50:22+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -4322,7 +4264,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -4330,20 +4272,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.2", + "version": "v4.15.5", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e", + "reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e", "shasum": "" }, "require": { @@ -4384,9 +4326,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5" }, - "time": "2022-11-12T15:38:23+00:00" + "time": "2023-05-19T20:20:00+00:00" }, { "name": "phar-io/manifest", @@ -4501,16 +4443,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.9.4", + "version": "1.10.19", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2" + "reference": "af5a296ff02610c1bfb4ddfac9fd4a08657b9046" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d03bccee595e2146b7c9d174486b84f4dc61b0f2", - "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/af5a296ff02610c1bfb4ddfac9fd4a08657b9046", + "reference": "af5a296ff02610c1bfb4ddfac9fd4a08657b9046", "shasum": "" }, "require": { @@ -4539,8 +4481,11 @@ "static analysis" ], "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.9.4" + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { @@ -4556,25 +4501,25 @@ "type": "tidelift" } ], - "time": "2022-12-17T13:33:52+00:00" + "time": "2023-06-14T15:26:58+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", - "version": "1.1.1", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", - "reference": "2c6792eda026d9c474c14aa018aed312686714db" + "reference": "a22b36b955a2e9a3d39fe533b6c1bb5359f9c319" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/2c6792eda026d9c474c14aa018aed312686714db", - "reference": "2c6792eda026d9c474c14aa018aed312686714db", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/a22b36b955a2e9a3d39fe533b6c1bb5359f9c319", + "reference": "a22b36b955a2e9a3d39fe533b6c1bb5359f9c319", "shasum": "" }, "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.9.3" + "phpstan/phpstan": "^1.10" }, "require-dev": { "php-parallel-lint/php-parallel-lint": "^1.2", @@ -4602,29 +4547,29 @@ "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", "support": { "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", - "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.1.1" + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.1.3" }, - "time": "2022-12-13T14:26:20+00:00" + "time": "2023-03-17T07:50:08+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.23", + "version": "9.2.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4639,8 +4584,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { @@ -4673,7 +4618,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" }, "funding": [ { @@ -4681,7 +4626,7 @@ "type": "github" } ], - "time": "2022-12-28T12:41:10+00:00" + "time": "2023-03-06T12:58:08+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4926,20 +4871,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.27", + "version": "9.6.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" + "reference": "a9aceaf20a682aeacf28d582654a1670d8826778" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a9aceaf20a682aeacf28d582654a1670d8826778", + "reference": "a9aceaf20a682aeacf28d582654a1670d8826778", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -4968,8 +4913,8 @@ "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -4977,7 +4922,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -5008,7 +4953,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.9" }, "funding": [ { @@ -5024,25 +4970,25 @@ "type": "tidelift" } ], - "time": "2022-12-09T07:31:23+00:00" + "time": "2023-06-11T06:13:56+00:00" }, { "name": "psr/http-client", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31", + "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31", "shasum": "" }, "require": { "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -5062,7 +5008,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP clients", @@ -5074,9 +5020,9 @@ "psr-18" ], "support": { - "source": "https://github.com/php-fig/http-client/tree/master" + "source": "https://github.com/php-fig/http-client/tree/1.0.2" }, - "time": "2020-06-29T06:28:15+00:00" + "time": "2023-04-10T20:12:12+00:00" }, { "name": "sebastian/cli-parser", @@ -5378,16 +5324,16 @@ }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", "shasum": "" }, "require": { @@ -5432,7 +5378,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" }, "funding": [ { @@ -5440,20 +5386,20 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-07T05:35:17+00:00" }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -5495,7 +5441,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -5503,7 +5449,7 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -5817,16 +5763,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -5865,10 +5811,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -5876,7 +5822,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -5935,16 +5881,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -5979,7 +5925,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -5987,7 +5933,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -6044,16 +5990,16 @@ }, { "name": "symfony/browser-kit", - "version": "v5.4.11", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "081fe28a26b6bd671dea85ef3a4b5003f3c88027" + "reference": "a866ca7e396f15d7efb6d74a8a7d364d4e05b704" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/081fe28a26b6bd671dea85ef3a4b5003f3c88027", - "reference": "081fe28a26b6bd671dea85ef3a4b5003f3c88027", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/a866ca7e396f15d7efb6d74a8a7d364d4e05b704", + "reference": "a866ca7e396f15d7efb6d74a8a7d364d4e05b704", "shasum": "" }, "require": { @@ -6096,7 +6042,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v5.4.11" + "source": "https://github.com/symfony/browser-kit/tree/v5.4.21" }, "funding": [ { @@ -6112,20 +6058,20 @@ "type": "tidelift" } ], - "time": "2022-07-27T15:50:05+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/css-selector", - "version": "v5.4.17", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "052ef49b660f9ad2a3adb311c555c9bc11ba61f4" + "reference": "95f3c7468db1da8cc360b24fa2a26e7cefcb355d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/052ef49b660f9ad2a3adb311c555c9bc11ba61f4", - "reference": "052ef49b660f9ad2a3adb311c555c9bc11ba61f4", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/95f3c7468db1da8cc360b24fa2a26e7cefcb355d", + "reference": "95f3c7468db1da8cc360b24fa2a26e7cefcb355d", "shasum": "" }, "require": { @@ -6162,7 +6108,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.17" + "source": "https://github.com/symfony/css-selector/tree/v5.4.21" }, "funding": [ { @@ -6178,7 +6124,7 @@ "type": "tidelift" } ], - "time": "2022-12-23T11:40:44+00:00" + "time": "2023-02-14T08:03:56+00:00" }, { "name": "symfony/deprecation-contracts", @@ -6249,16 +6195,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v5.4.17", + "version": "v5.4.23", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "32a07d910edc138a1dd5508c17c6b9bc1eb27a1b" + "reference": "4a286c916b74ecfb6e2caf1aa31d3fe2a34b7e08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/32a07d910edc138a1dd5508c17c6b9bc1eb27a1b", - "reference": "32a07d910edc138a1dd5508c17c6b9bc1eb27a1b", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4a286c916b74ecfb6e2caf1aa31d3fe2a34b7e08", + "reference": "4a286c916b74ecfb6e2caf1aa31d3fe2a34b7e08", "shasum": "" }, "require": { @@ -6304,7 +6250,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.17" + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.23" }, "funding": [ { @@ -6320,20 +6266,20 @@ "type": "tidelift" } ], - "time": "2022-12-22T10:31:03+00:00" + "time": "2023-04-08T21:20:19+00:00" }, { "name": "symfony/finder", - "version": "v5.4.17", + "version": "v5.4.21", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "40c08632019838dfb3350f18cf5563b8080055fc" + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/40c08632019838dfb3350f18cf5563b8080055fc", - "reference": "40c08632019838dfb3350f18cf5563b8080055fc", + "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", + "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", "shasum": "" }, "require": { @@ -6367,7 +6313,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.17" + "source": "https://github.com/symfony/finder/tree/v5.4.21" }, "funding": [ { @@ -6383,7 +6329,7 @@ "type": "tidelift" } ], - "time": "2022-12-22T10:31:03+00:00" + "time": "2023-02-16T09:33:00+00:00" }, { "name": "theseer/tokenizer", diff --git a/system/assets/debugger/phpdebugbar.css b/system/assets/debugger/phpdebugbar.css index 93e2d2c..0912ff0 100644 --- a/system/assets/debugger/phpdebugbar.css +++ b/system/assets/debugger/phpdebugbar.css @@ -14,11 +14,8 @@ div.phpdebugbar { padding: 5px 8px; } -.phpdebugbar div.phpdebugbar-header, .phpdebugbar a.phpdebugbar-restore-btn { - background-image: url(data:image/png;base64,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); -} - .phpdebugbar a.phpdebugbar-restore-btn { + background-image: url(data:image/png;base64,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); width: 13px; } diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 09e8083..182457c 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -448,6 +448,17 @@ form: validate: type: bool + languages.debug: + type: toggle + label: PLUGIN_ADMIN.LANGUAGE_DEBUG + help: PLUGIN_ADMIN.LANGUAGE_DEBUG_HELP + highlight: 0 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + http_headers: type: tab title: PLUGIN_ADMIN.HTTP_HEADERS @@ -608,7 +619,6 @@ form: file: File apc: APC apcu: APCu - xcache: Xcache memcache: Memcache memcached: Memcached wincache: WinCache diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index ef5f25b..3b589a0 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -140,7 +140,7 @@ form: multiple: true size: large label: PLUGIN_ADMIN.GROUPS - data-options@: '\Grav\Common\User\Group::groupNames' + data-options@: 'Grav\Common\Flex\Types\UserGroups\UserGroupObject::groupNames' classes: fancy help: PLUGIN_ADMIN.GROUPS_HELP validate: diff --git a/system/config/system.yaml b/system/config/system.yaml index 2ffd02a..8bcc280 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -28,6 +28,7 @@ languages: override_locale: false # Override the default or system locale with language specific one content_fallback: {} # Custom language fallbacks. eg: {fr: ['fr', 'en']} pages_fallback_only: false # DEPRECATED: Use `content_fallback` instead + debug: false # Debug language detection home: alias: '/home' # Default path for home, ie / diff --git a/system/defines.php b/system/defines.php index 803ab45..12e38b6 100644 --- a/system/defines.php +++ b/system/defines.php @@ -9,7 +9,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.7.38'); +define('GRAV_VERSION', '1.7.42.3'); define('GRAV_SCHEMA', '1.7.0_2020-11-20_1'); define('GRAV_TESTING', false); @@ -99,3 +99,6 @@ define('RAW_CONTENT', 1); define('TWIG_CONTENT', 2); define('TWIG_CONTENT_LIST', 3); define('TWIG_TEMPLATES', 4); + +// Filters +define('GRAV_SANITIZE_STRING', 5001); diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 125a518..9c270d9 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -268,7 +268,13 @@ class Assets extends PropertyObject } // Add timestamp - $options['timestamp'] = $this->timestamp; + $timestamp_override = $options['timestamp'] ?? true; + + if (filter_var($timestamp_override, FILTER_VALIDATE_BOOLEAN)) { + $options['timestamp'] = $this->timestamp; + } else { + $options['timestamp'] = null; + } // Set order $group = $options['group'] ?? 'head'; diff --git a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php index e2d8981..d4a223b 100644 --- a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php +++ b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php @@ -192,6 +192,7 @@ trait AssetUtilsTrait $querystring = ''; $asset = $asset ?? $this->asset; + $attributes = $this->attributes; if (!empty($this->query)) { if (Utils::contains($asset, '?')) { diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php index 137e042..b476706 100644 --- a/system/src/Grav/Common/Data/BlueprintSchema.php +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -129,7 +129,8 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface $items = $name !== '' ? $this->getProperty($name)['fields'] ?? [] : $this->items; foreach ($items as $key => $rules) { $type = $rules['type'] ?? ''; - if (!str_starts_with($type, '_') && !str_contains($key, '*')) { + $ignore = (bool) array_filter((array)($rules['validate']['ignore'] ?? [])) ?? false; + if (!str_starts_with($type, '_') && !str_contains($key, '*') && $ignore !== true) { $list[$prefix . $key] = null; } } diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php index a551fb5..daca735 100644 --- a/system/src/Grav/Common/Data/Validation.php +++ b/system/src/Grav/Common/Data/Validation.php @@ -631,6 +631,10 @@ class Validation */ public static function typeEmail($value, array $params, array $field) { + if (empty($value)) { + return false; + } + if (!isset($params['max'])) { $params['max'] = 320; } @@ -638,7 +642,7 @@ class Validation $values = !is_array($value) ? explode(',', preg_replace('/\s+/', '', $value)) : $value; foreach ($values as $val) { - if (!(self::typeText($val, $params, $field) && filter_var($val, FILTER_VALIDATE_EMAIL))) { + if (!(self::typeText($val, $params, $field) && strpos($val, '@', 1))) { return false; } } diff --git a/system/src/Grav/Common/Errors/SimplePageHandler.php b/system/src/Grav/Common/Errors/SimplePageHandler.php index 4b0db05..df28847 100644 --- a/system/src/Grav/Common/Errors/SimplePageHandler.php +++ b/system/src/Grav/Common/Errors/SimplePageHandler.php @@ -57,7 +57,7 @@ class SimplePageHandler extends Handler $vars = array( 'stylesheet' => file_get_contents($cssFile), 'code' => $code, - 'message' => filter_var(rawurldecode($message), FILTER_SANITIZE_STRING), + 'message' => htmlspecialchars(strip_tags(rawurldecode($message)), ENT_QUOTES, 'UTF-8'), ); $helper->setVariables($vars); diff --git a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php index d1e4c40..b3d7b23 100644 --- a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php +++ b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Grav\Common\Flex\Types\UserGroups; use Grav\Common\Flex\FlexObject; +use Grav\Common\Grav; use Grav\Common\User\Access; use Grav\Common\User\Interfaces\UserGroupInterface; use function is_bool; @@ -74,6 +75,18 @@ class UserGroupObject extends FlexObject implements UserGroupInterface return $access->authorize('admin.super') ? true : null; } + public static function groupNames(): array + { + $groups = []; + $user_groups = Grav::instance()['user_groups']; + + foreach ($user_groups as $key => $group) { + $groups[$key] = $group->readableName; + } + + return $groups; + } + /** * @return Access */ diff --git a/system/src/Grav/Common/Helpers/LogViewer.php b/system/src/Grav/Common/Helpers/LogViewer.php index 060e561..a862fdd 100644 --- a/system/src/Grav/Common/Helpers/LogViewer.php +++ b/system/src/Grav/Common/Helpers/LogViewer.php @@ -21,7 +21,7 @@ use function is_string; class LogViewer { /** @var string */ - protected $pattern = '/\[(?P.*)\] (?P\w+).(?P\w+): (?P.*[^ ]+) (?P[^ ]+) (?P[^ ]+)/'; + protected $pattern = '/\[(?P.*?)\] (?P\w+)\.(?P\w+): (?P.*[^ ]+) (?P[^ ]+) (?P[^ ]+)/'; /** * Get the objects of a tailed file diff --git a/system/src/Grav/Common/Helpers/Truncator.php b/system/src/Grav/Common/Helpers/Truncator.php index 318079c..8d1cce6 100644 --- a/system/src/Grav/Common/Helpers/Truncator.php +++ b/system/src/Grav/Common/Helpers/Truncator.php @@ -144,7 +144,7 @@ class Truncator } // Transform multibyte entities which otherwise display incorrectly. - $html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'); + $html = mb_encode_numericentity($html, [0x80, 0x10FFFF, 0, ~0], 'UTF-8'); // Internal errors enabled as HTML5 not fully supported. libxml_use_internal_errors(true); diff --git a/system/src/Grav/Common/Markdown/Parsedown.php b/system/src/Grav/Common/Markdown/Parsedown.php index 634a174..c36bf70 100644 --- a/system/src/Grav/Common/Markdown/Parsedown.php +++ b/system/src/Grav/Common/Markdown/Parsedown.php @@ -18,6 +18,7 @@ use Grav\Common\Page\Markdown\Excerpts; */ class Parsedown extends \Parsedown { + use ParsedownGravTrait; /** diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index b97b129..9b8bb9a 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -25,6 +25,7 @@ trait ParsedownGravTrait public $completable_blocks = []; /** @var array */ public $continuable_blocks = []; + public $plugins = []; /** @var Excerpts */ protected $excerpts; @@ -292,7 +293,12 @@ trait ParsedownGravTrait #[\ReturnTypeWillChange] public function __call($method, $args) { - if (isset($this->{$method}) === true) { + + if (isset($this->plugins[$method]) === true) { + $func = $this->plugins[$method]; + + return call_user_func_array($func, $args); + } elseif (isset($this->{$method}) === true) { $func = $this->{$method}; return call_user_func_array($func, $args); @@ -300,4 +306,14 @@ trait ParsedownGravTrait return null; } + + public function __set($name, $value) + { + if (is_callable($value)) { + $this->plugins[$name] = $value; + } + + } + + } diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php index d215465..95e6a78 100644 --- a/system/src/Grav/Common/Page/Medium/ImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php @@ -62,8 +62,8 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate if (!($this->offsetExists('width') && $this->offsetExists('height') && $this->offsetExists('mime'))) { $image_info = getimagesize($path); if ($image_info) { - $this->def('width', $image_info[0]); - $this->def('height', $image_info[1]); + $this->def('width', (int) $image_info[0]); + $this->def('height', (int) $image_info[1]); $this->def('mime', $image_info['mime']); } } @@ -299,7 +299,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate } if ($width && $height) { - $this->__call('cropResize', [$width, $height]); + $this->__call('cropResize', [(int) $width, (int) $height]); } return parent::lightbox($width, $height, $reset); @@ -361,8 +361,8 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate // Scaling operations $scale = ($scale ?? $config->get('system.images.watermark.scale', 100)) / 100; - $wwidth = (int)$this->get('width') * $scale; - $wheight = (int)$this->get('height') * $scale; + $wwidth = (int) ($this->get('width') * $scale); + $wheight = (int) ($this->get('height') * $scale); $watermark->resize($wwidth, $wheight); // Position operations @@ -392,11 +392,11 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate break; case 'right': - $positionX = (int)$this->get('width')-$wwidth; + $positionX = (int) ($this->get('width')-$wwidth); break; case 'center': - $positionX = ((int)$this->get('width')/2) - ($wwidth/2); + $positionX = (int) (($this->get('width')/2) - ($wwidth/2)); break; } @@ -431,8 +431,8 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate return $this; } - $dst_width = $image->width()+2*$border; - $dst_height = $image->height()+2*$border; + $dst_width = (int) ($image->width()+2*$border); + $dst_height = (int) ($image->height()+2*$border); $frame = ImageFile::create($dst_width, $dst_height); diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 14e7a12..3fc5acb 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -1270,9 +1270,14 @@ class Page implements PageInterface */ public function blueprintName() { - $blueprint_name = filter_input(INPUT_POST, 'blueprint', FILTER_SANITIZE_STRING) ?: $this->template(); + if (!isset($_POST['blueprint'])) { + return $this->template(); + } - return $blueprint_name; + $post_value = $_POST['blueprint']; + $sanitized_value = htmlspecialchars(strip_tags($post_value), ENT_QUOTES, 'UTF-8'); + + return $sanitized_value ?: $this->template(); } /** @@ -1802,7 +1807,7 @@ class Page implements PageInterface } if (empty($this->slug)) { - $this->slug = $this->adjustRouteCase(preg_replace(PAGE_ORDER_PREFIX_REGEX, '', $this->folder)) ?: null; + $this->slug = $this->adjustRouteCase(preg_replace(PAGE_ORDER_PREFIX_REGEX, '', (string) $this->folder)) ?: null; } return $this->slug; diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 9282a8f..e39e3ab 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -26,6 +26,7 @@ use Grav\Common\Page\Interfaces\PageInterface; use Grav\Common\Taxonomy; use Grav\Common\Uri; use Grav\Common\Utils; +use Grav\Events\TypesEvent; use Grav\Framework\Flex\Flex; use Grav\Framework\Flex\FlexDirectory; use Grav\Framework\Flex\Interfaces\FlexTranslateInterface; @@ -1289,7 +1290,7 @@ class Pages $scanBlueprintsAndTemplates = static function (Types $types) use ($grav) { // Scan blueprints - $event = new Event(); + $event = new TypesEvent(); $event->types = $types; $grav->fireEvent('onGetPageBlueprints', $event); @@ -1303,7 +1304,7 @@ class Pages $types->scanBlueprints($lookup); // Scan templates - $event = new Event(); + $event = new TypesEvent(); $event->types = $types; $grav->fireEvent('onGetPageTemplates', $event); @@ -1773,7 +1774,7 @@ class Pages $dirs = (array) $grav['config']->get('system.pages.dirs', ['page://']); foreach ($dirs as $dir) { $path = $locator->findResource($dir); - if (file_exists($path)) { + if (file_exists($path) && !in_array($path, $paths, true)) { $paths[] = $path; } } diff --git a/system/src/Grav/Common/Processors/PagesProcessor.php b/system/src/Grav/Common/Processors/PagesProcessor.php index 14a09bb..2d29a35 100644 --- a/system/src/Grav/Common/Processors/PagesProcessor.php +++ b/system/src/Grav/Common/Processors/PagesProcessor.php @@ -10,6 +10,7 @@ namespace Grav\Common\Processors; use Grav\Common\Page\Interfaces\PageInterface; +use Grav\Events\PageEvent; use Grav\Framework\RequestHandler\Exception\RequestException; use Grav\Plugin\Form\Forms; use RocketTheme\Toolbox\Event\Event; @@ -66,7 +67,7 @@ class PagesProcessor extends ProcessorBase if (!$page->routable()) { $exception = new RequestException($request, 'Page Not Found', 404); // If no page found, fire event - $event = new Event([ + $event = new PageEvent([ 'page' => $page, 'code' => $exception->getCode(), 'message' => $exception->getMessage(), diff --git a/system/src/Grav/Common/Scheduler/Scheduler.php b/system/src/Grav/Common/Scheduler/Scheduler.php index 1a1750b..f4cf454 100644 --- a/system/src/Grav/Common/Scheduler/Scheduler.php +++ b/system/src/Grav/Common/Scheduler/Scheduler.php @@ -357,7 +357,7 @@ class Scheduler */ public function whoami() { - $process = new Process('whoami'); + $process = new Process(['whoami']); $process->run(); if ($process->isSuccessful()) { diff --git a/system/src/Grav/Common/Service/PagesServiceProvider.php b/system/src/Grav/Common/Service/PagesServiceProvider.php index 52ef5ea..a6fc59e 100644 --- a/system/src/Grav/Common/Service/PagesServiceProvider.php +++ b/system/src/Grav/Common/Service/PagesServiceProvider.php @@ -59,7 +59,7 @@ class PagesServiceProvider implements ServiceProviderInterface /** @var Uri $uri */ $uri = $grav['uri']; - $path = $uri->path() ?: '/'; // Don't trim to support trailing slash default routes + $path = $uri->path() ? urldecode($uri->path()) : '/'; // Don't trim to support trailing slash default routes $page = $pages->dispatch($path); // Redirection tests @@ -72,7 +72,7 @@ class PagesServiceProvider implements ServiceProviderInterface if ($config->get('system.force_ssl')) { $scheme = $uri->scheme(true); if ($scheme !== 'https') { - $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $url = 'https://' . $uri->host() . $uri->uri(); $grav->redirect($url); } } diff --git a/system/src/Grav/Common/Service/TaskServiceProvider.php b/system/src/Grav/Common/Service/TaskServiceProvider.php index ce5ec64..9dac67a 100644 --- a/system/src/Grav/Common/Service/TaskServiceProvider.php +++ b/system/src/Grav/Common/Service/TaskServiceProvider.php @@ -33,7 +33,7 @@ class TaskServiceProvider implements ServiceProviderInterface $task = $body['task'] ?? $c['uri']->param('task'); if (null !== $task) { - $task = filter_var($task, FILTER_SANITIZE_STRING); + $task = htmlspecialchars(strip_tags($task), ENT_QUOTES, 'UTF-8'); } return $task ?: null; @@ -46,7 +46,7 @@ class TaskServiceProvider implements ServiceProviderInterface $action = $body['action'] ?? $c['uri']->param('action'); if (null !== $action) { - $action = filter_var($action, FILTER_SANITIZE_STRING); + $action = htmlspecialchars(strip_tags($action), ENT_QUOTES, 'UTF-8'); } return $action ?: null; diff --git a/system/src/Grav/Common/Session.php b/system/src/Grav/Common/Session.php index 14d09a2..84b53e1 100644 --- a/system/src/Grav/Common/Session.php +++ b/system/src/Grav/Common/Session.php @@ -122,10 +122,10 @@ class Session extends \Grav\Framework\Session\Session // Make sure that Forms 3.0+ has been installed. if (null === $object && isset($grav['forms'])) { - user_error( - __CLASS__ . '::' . __FUNCTION__ . '(\'files-upload\') is deprecated since Grav 1.6, use $form->getFlash()->getLegacyFiles() instead', - E_USER_DEPRECATED - ); +// user_error( +// __CLASS__ . '::' . __FUNCTION__ . '(\'files-upload\') is deprecated since Grav 1.6, use $form->getFlash()->getLegacyFiles() instead', +// E_USER_DEPRECATED +// ); /** @var Uri $uri */ $uri = $grav['uri']; diff --git a/system/src/Grav/Common/Twig/Extension/GravExtension.php b/system/src/Grav/Common/Twig/Extension/GravExtension.php index f3a122e..2ef5364 100644 --- a/system/src/Grav/Common/Twig/Extension/GravExtension.php +++ b/system/src/Grav/Common/Twig/Extension/GravExtension.php @@ -46,6 +46,7 @@ use Twig\Error\RuntimeError; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; use Twig\Loader\FilesystemLoader; +use Twig\Markup; use Twig\TwigFilter; use Twig\TwigFunction; use function array_slice; @@ -170,8 +171,10 @@ class GravExtension extends AbstractExtension implements GlobalsInterface new TwigFilter('count', 'count'), new TwigFilter('array_diff', 'array_diff'), - // Security fix - new TwigFilter('filter', [$this, 'filterFilter'], ['needs_environment' => true]), + // Security fixes + new TwigFilter('filter', [$this, 'filterFunc'], ['needs_environment' => true]), + new TwigFilter('map', [$this, 'mapFunc'], ['needs_environment' => true]), + new TwigFilter('reduce', [$this, 'reduceFunc'], ['needs_environment' => true]), ]; } @@ -247,6 +250,12 @@ class GravExtension extends AbstractExtension implements GlobalsInterface new TwigFunction('is_object', 'is_object'), new TwigFunction('count', 'count'), new TwigFunction('array_diff', 'array_diff'), + new TwigFunction('parse_url', 'parse_url'), + + // Security fixes + new TwigFunction('filter', [$this, 'filterFunc'], ['needs_environment' => true]), + new TwigFunction('map', [$this, 'mapFunc'], ['needs_environment' => true]), + new TwigFunction('reduce', [$this, 'reduceFunc'], ['needs_environment' => true]), ]; } @@ -468,7 +477,7 @@ class GravExtension extends AbstractExtension implements GlobalsInterface */ public function base64EncodeFilter($str) { - return base64_encode($str); + return base64_encode((string) $str); } /** @@ -904,8 +913,13 @@ class GravExtension extends AbstractExtension implements GlobalsInterface return $this->grav['admin']->translate($args, $lang); } - // else use the default grav translate functionality - return $this->grav['language']->translate($args); + $translation = $this->grav['language']->translate($args); + + if ($this->config->get('system.languages.debug', false)) { + return new Markup("$translation", 'UTF-8'); + } else { + return $translation; + } } /** @@ -949,7 +963,7 @@ class GravExtension extends AbstractExtension implements GlobalsInterface */ public function repeatFunc($input, $multiplier) { - return str_repeat($input, $multiplier); + return str_repeat($input, (int) $multiplier); } /** @@ -1203,6 +1217,9 @@ class GravExtension extends AbstractExtension implements GlobalsInterface */ public function jsonDecodeFilter($str, $assoc = false, $depth = 512, $options = 0) { + if ($str === null) { + $str = ''; + } return json_decode(html_entity_decode($str, ENT_COMPAT | ENT_HTML401, 'UTF-8'), $assoc, $depth, $options); } @@ -1214,7 +1231,13 @@ class GravExtension extends AbstractExtension implements GlobalsInterface */ public function getCookie($key) { - return filter_input(INPUT_COOKIE, $key, FILTER_SANITIZE_STRING); + $cookie_value = filter_input(INPUT_COOKIE, $key); + + if ($cookie_value === null) { + return null; + } + + return htmlspecialchars(strip_tags($cookie_value), ENT_QUOTES, 'UTF-8'); } /** @@ -1689,12 +1712,44 @@ class GravExtension extends AbstractExtension implements GlobalsInterface * @return array|CallbackFilterIterator * @throws RuntimeError */ - function filterFilter(Environment $env, $array, $arrow) + function filterFunc(Environment $env, $array, $arrow) { - if (is_string($arrow) && Utils::isDangerousFunction($arrow)) { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { throw new RuntimeError('Twig |filter("' . $arrow . '") is not allowed.'); } return twig_array_filter($env, $array, $arrow); } + + /** + * @param Environment $env + * @param array $array + * @param callable|string $arrow + * @return array|CallbackFilterIterator + * @throws RuntimeError + */ + function mapFunc(Environment $env, $array, $arrow) + { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { + throw new RuntimeError('Twig |map("' . $arrow . '") is not allowed.'); + } + + return twig_array_map($env, $array, $arrow); + } + + /** + * @param Environment $env + * @param array $array + * @param callable|string $arrow + * @return array|CallbackFilterIterator + * @throws RuntimeError + */ + function reduceFunc(Environment $env, $array, $arrow) + { + if (!$arrow instanceof \Closure && !is_string($arrow) || Utils::isDangerousFunction($arrow)) { + throw new RuntimeError('Twig |reduce("' . $arrow . '") is not allowed.'); + } + + return twig_array_map($env, $array, $arrow); + } } diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeCache.php b/system/src/Grav/Common/Twig/Node/TwigNodeCache.php index 64a13a6..c7d4eea 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeCache.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeCache.php @@ -10,13 +10,15 @@ namespace Grav\Common\Twig\Node; use Twig\Compiler; +use Twig\Node\Expression\AbstractExpression; use Twig\Node\Node; +use Twig\Node\NodeOutputInterface; /** * Class TwigNodeCache * @package Grav\Common\Twig\Node */ -class TwigNodeCache extends Node +class TwigNodeCache extends Node implements NodeOutputInterface { /** * @param string $key unique name for key @@ -25,25 +27,58 @@ class TwigNodeCache extends Node * @param integer $lineno * @param string|null $tag */ - public function __construct(string $key, int $lifetime, Node $body, $lineno, $tag = null) + public function __construct(Node $body, ?AbstractExpression $key, ?AbstractExpression $lifetime, array $defaults, int $lineno, string $tag) { - parent::__construct(array('body' => $body), array( 'key' => $key, 'lifetime' => $lifetime), $lineno, $tag); + $nodes = ['body' => $body]; + + if ($key !== null) { + $nodes['key'] = $key; + } + + if ($lifetime !== null) { + $nodes['lifetime'] = $lifetime; + } + + parent::__construct($nodes, $defaults, $lineno, $tag); } - /** - * {@inheritDoc} - */ public function compile(Compiler $compiler): void { - $boo = $this->getAttribute('key'); + $compiler->addDebugInfo($this); + + + // Generate the cache key + if ($this->hasNode('key')) { + $compiler + ->write('$key = "twigcache-" . ') + ->subcompile($this->getNode('key')) + ->raw(";\n"); + } else { + $compiler + ->write('$key = ') + ->string($this->getAttribute('key')) + ->raw(";\n"); + } + + // Set the cache timeout + if ($this->hasNode('lifetime')) { + $compiler + ->write('$lifetime = ') + ->subcompile($this->getNode('lifetime')) + ->raw(";\n"); + } else { + $compiler + ->write('$lifetime = ') + ->write($this->getAttribute('lifetime')) + ->raw(";\n"); + } + $compiler - ->addDebugInfo($this) ->write("\$cache = \\Grav\\Common\\Grav::instance()['cache'];\n") - ->write("\$key = \"twigcache-\" . \"" . $this->getAttribute('key') . "\";\n") - ->write("\$lifetime = " . $this->getAttribute('lifetime') . ";\n") ->write("\$cache_body = \$cache->fetch(\$key);\n") ->write("if (\$cache_body === false) {\n") ->indent() + ->write("\\Grav\\Common\\Grav::instance()['debugger']->addMessage(\"Cache Key: \$key, Lifetime: \$lifetime\");\n") ->write("ob_start();\n") ->indent() ->subcompile($this->getNode('body')) @@ -53,6 +88,6 @@ class TwigNodeCache extends Node ->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n") ->outdent() ->write("}\n") - ->write("echo \$cache_body;\n"); + ->write("echo '' === \$cache_body ? '' : new Markup(\$cache_body, \$this->env->getCharset());\n"); } -} +} \ No newline at end of file diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php index d3658b2..3b030a4 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php @@ -11,7 +11,6 @@ namespace Grav\Common\Twig\TokenParser; use Grav\Common\Grav; use Grav\Common\Twig\Node\TwigNodeCache; -use Twig\Error\SyntaxError; use Twig\Token; use Twig\TokenParser\AbstractTokenParser; @@ -22,50 +21,54 @@ use Twig\TokenParser\AbstractTokenParser; * {{ some_complex_work() }} * {% endcache %} * - * Where the `600` is an optional lifetime in seconds + * Also can provide a unique key for the cache: + * + * {% cache "prefix-"~lang 600 %} + * + * Where the "prefix-"~lang will use a unique key based on the current language. "prefix-en" for example */ class TwigTokenParserCache extends AbstractTokenParser { - /** - * @param Token $token - * @return TwigNodeCache - * @throws SyntaxError - */ public function parse(Token $token) { - $lineno = $token->getLine(); $stream = $this->parser->getStream(); - $key = $this->parser->getVarName() . $lineno; - $lifetime = Grav::instance()['cache']->getLifetime(); + $lineno = $token->getLine(); - // Check for optional lifetime override - if (!$stream->test(Token::BLOCK_END_TYPE)) { - $lifetime_expr = $this->parser->getExpressionParser()->parseExpression(); - $lifetime = $lifetime_expr->getAttribute('value'); + // Parse the optional key and timeout parameters + $defaults = [ + 'key' => $this->parser->getVarName() . $lineno, + 'lifetime' => Grav::instance()['cache']->getLifetime() + ]; + + $key = null; + $lifetime = null; + while (!$stream->test(Token::BLOCK_END_TYPE)) { + if ($stream->test(Token::STRING_TYPE)) { + $key = $this->parser->getExpressionParser()->parseExpression(); + } elseif ($stream->test(Token::NUMBER_TYPE)) { + $lifetime = $this->parser->getExpressionParser()->parseExpression(); + } else { + throw new \Twig\Error\SyntaxError("Unexpected token type in cache tag.", $token->getLine(), $stream->getSourceContext()); + } } $stream->expect(Token::BLOCK_END_TYPE); - $body = $this->parser->subparse(array($this, 'decideCacheEnd'), true); + + // Parse the content inside the cache block + $body = $this->parser->subparse([$this, 'decideCacheEnd'], true); + $stream->expect(Token::BLOCK_END_TYPE); - return new TwigNodeCache($key, $lifetime, $body, $lineno, $this->getTag()); + return new TwigNodeCache($body, $key, $lifetime, $defaults, $lineno, $this->getTag()); } - /** - * Decide if current token marks end of cache block. - * - * @param Token $token - * @return bool - */ public function decideCacheEnd(Token $token): bool { return $token->test('endcache'); } - /** - * {@inheritDoc} - */ + public function getTag(): string { return 'cache'; } -} +} \ No newline at end of file diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php index 66a9d78..b510ed7 100644 --- a/system/src/Grav/Common/Twig/Twig.php +++ b/system/src/Grav/Common/Twig/Twig.php @@ -57,6 +57,15 @@ class Twig /** @var string */ public $template; + /** @var array */ + public $plugins_hooked_nav = []; + /** @var array */ + public $plugins_quick_tray = []; + /** @var array */ + public $plugins_hooked_dashboard_widgets_top = []; + /** @var array */ + public $plugins_hooked_dashboard_widgets_main = []; + /** @var Grav */ protected $grav; /** @var FilesystemLoader */ @@ -493,13 +502,19 @@ class Twig /** * Simple helper method to get the twig template if it has already been set, else return * the one being passed in + * NOTE: Modular pages that are injected should not use this pre-set template as it's usually set at the page level * * @param string $template the template name * @return string the template name */ - public function template($template) + public function template(string $template): string { - return $this->template ?? $template; + if (isset($this->template)) { + $template = $this->template; + unset($this->template); + } + + return $template; } /** @@ -513,7 +528,7 @@ class Twig $default = $page->isModule() ? 'modular/default' : 'default'; $extension = $format ?: $page->templateFormat(); $twig_extension = $extension ? '.'. $extension .TWIG_EXT : TEMPLATE_EXT; - $template_file = $this->template($page->template() . $twig_extension); + $template_file = $this->template($template . $twig_extension); // TODO: no longer needed in Twig 3. /** @var ExistsLoaderInterface $loader */ diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index c192438..8eefd50 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -1005,7 +1005,7 @@ class Uri foreach ($matches as $match) { $param = explode($delimiter, $match[1]); if (count($param) === 2) { - $plain_var = filter_var(rawurldecode($param[1]), FILTER_SANITIZE_STRING); + $plain_var = htmlspecialchars(strip_tags(rawurldecode($param[1])), ENT_QUOTES, 'UTF-8'); $params[$param[0]] = $plain_var; $uri = str_replace($match[0], '', $uri); } @@ -1388,7 +1388,11 @@ class Uri if ($this->post && null !== $element) { $item = Utils::getDotNotation($this->post, $element); if ($filter_type) { - $item = filter_var($item, $filter_type); + if ($filter_type === FILTER_SANITIZE_STRING || $filter_type === GRAV_SANITIZE_STRING) { + $item = htmlspecialchars(strip_tags($item), ENT_QUOTES, 'UTF-8'); + } else { + $item = filter_var($item, $filter_type); + } } return $item; } @@ -1514,7 +1518,7 @@ class Uri foreach ($matches as $match) { $param = explode($delimiter, $match[1]); if (count($param) === 2) { - $plain_var = filter_var($param[1], FILTER_SANITIZE_STRING); + $plain_var = htmlspecialchars(strip_tags($param[1]), ENT_QUOTES, 'UTF-8'); $this->params[$param[0]] = $plain_var; $uri = str_replace($match[0], '', $uri); } diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 078a49a..378bffa 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -201,7 +201,7 @@ abstract class Utils $compare_func = $case_sensitive ? 'mb_strpos' : 'mb_stripos'; foreach ((array)$needle as $each_needle) { - $status = $each_needle === '' || $compare_func($haystack, $each_needle) === 0; + $status = $each_needle === '' || $compare_func((string) $haystack, $each_needle) === 0; if ($status) { break; } @@ -225,8 +225,8 @@ abstract class Utils $compare_func = $case_sensitive ? 'mb_strrpos' : 'mb_strripos'; foreach ((array)$needle as $each_needle) { - $expectedPosition = mb_strlen($haystack) - mb_strlen($each_needle); - $status = $each_needle === '' || $compare_func($haystack, $each_needle, 0) === $expectedPosition; + $expectedPosition = mb_strlen((string) $haystack) - mb_strlen($each_needle); + $status = $each_needle === '' || $compare_func((string) $haystack, $each_needle, 0) === $expectedPosition; if ($status) { break; } @@ -250,7 +250,7 @@ abstract class Utils $compare_func = $case_sensitive ? 'mb_strpos' : 'mb_stripos'; foreach ((array)$needle as $each_needle) { - $status = $each_needle === '' || $compare_func($haystack, $each_needle) !== false; + $status = $each_needle === '' || $compare_func((string) $haystack, $each_needle) !== false; if ($status) { break; } @@ -1145,9 +1145,9 @@ abstract class Utils $offset_prefix = $offset < 0 ? '-' : '+'; $offset_formatted = gmdate('H:i', abs($offset)); - $pretty_offset = "UTC${offset_prefix}${offset_formatted}"; + $pretty_offset = "UTC{$offset_prefix}{$offset_formatted}"; - $timezone_list[$timezone] = "(${pretty_offset}) " . str_replace('_', ' ', $timezone); + $timezone_list[$timezone] = "({$pretty_offset}) " . str_replace('_', ' ', $timezone); } return $timezone_list; @@ -1874,9 +1874,9 @@ abstract class Utils } if ($block) { - $string = $parsedown->text($string); + $string = $parsedown->text((string) $string); } else { - $string = $parsedown->line($string); + $string = $parsedown->line((string) $string); } return $string; @@ -1950,10 +1950,10 @@ abstract class Utils } /** - * @param string $name + * @param string|array|Closure $name * @return bool */ - public static function isDangerousFunction(string $name): bool + public static function isDangerousFunction($name): bool { static $commandExecutionFunctions = [ 'exec', @@ -2048,8 +2048,30 @@ abstract class Utils 'posix_setpgid', 'posix_setsid', 'posix_setuid', + 'unserialize', + 'ini_alter', + 'simplexml_load_file', + 'simplexml_load_string', + 'forward_static_call', + 'forward_static_call_array', ]; + if (is_string($name)) { + $name = strtolower($name); + } + + if ($name instanceof \Closure) { + return false; + } + + if (is_array($name) || strpos($name, ":") !== false) { + return true; + } + + if (strpos($name, "\\") !== false) { + return true; + } + if (in_array($name, $commandExecutionFunctions)) { return true; } diff --git a/system/src/Grav/Console/Cli/LogViewerCommand.php b/system/src/Grav/Console/Cli/LogViewerCommand.php index 8c26af2..107ebf7 100644 --- a/system/src/Grav/Console/Cli/LogViewerCommand.php +++ b/system/src/Grav/Console/Cli/LogViewerCommand.php @@ -82,7 +82,7 @@ class LogViewerCommand extends GravCommand if ($log['trace'] && $verbose) { $output .= " {$log['message']}\n"; foreach ((array) $log['trace'] as $index => $tracerow) { - $output .= "{$index}${tracerow}\n"; + $output .= "{$index}{$tracerow}\n"; } } else { $output .= " {$log['message']}"; diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index f16b5be..a45c290 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -317,7 +317,7 @@ class InstallCommand extends GpmCommand $questionNoun = 'packages'; } - $question = new ConfirmationQuestion("${questionAction} {$questionArticle} {$questionNoun}? [Y|n] ", true); + $question = new ConfirmationQuestion("{$questionAction} {$questionArticle} {$questionNoun}? [Y|n] ", true); $answer = $this->all_yes ? true : $io->askQuestion($question); if ($answer) { diff --git a/system/src/Grav/Events/PageEvent.php b/system/src/Grav/Events/PageEvent.php new file mode 100644 index 0000000..4429eb8 --- /dev/null +++ b/system/src/Grav/Events/PageEvent.php @@ -0,0 +1,18 @@ +template(); + if (!isset($_POST['blueprint'])) { + return $this->template(); + } - return $blueprint_name; + $post_value = $_POST['blueprint']; + $sanitized_value = htmlspecialchars(strip_tags($post_value), ENT_QUOTES, 'UTF-8'); + + return $sanitized_value ?: $this->template(); } /** diff --git a/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php b/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php index 87737dc..757452c 100644 --- a/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php @@ -42,7 +42,7 @@ trait NestedPropertyTrait public function getNestedProperty($property, $default = null, $separator = null) { $separator = $separator ?: '.'; - $path = explode($separator, $property); + $path = explode($separator, (string) $property); $offset = array_shift($path); if (!$this->hasProperty($offset)) { diff --git a/system/src/Grav/Framework/Session/Session.php b/system/src/Grav/Framework/Session/Session.php index 0dd9aed..5524d44 100644 --- a/system/src/Grav/Framework/Session/Session.php +++ b/system/src/Grav/Framework/Session/Session.php @@ -11,6 +11,7 @@ namespace Grav\Framework\Session; use ArrayIterator; use Exception; +use Throwable; use Grav\Common\Debugger; use Grav\Common\Grav; use Grav\Common\User\Interfaces\UserInterface; @@ -254,13 +255,17 @@ class Session implements SessionInterface $this->started = true; $this->onSessionStart(); - $user = $this->__get('user'); - if ($user && (!$user instanceof UserInterface || (method_exists($user, 'isValid') && !$user->isValid()))) { + try { + $user = $this->__get('user'); + if ($user && (!$user instanceof UserInterface || (method_exists($user, 'isValid') && !$user->isValid()))) { + throw new RuntimeException('Bad user'); + } + } catch (Throwable $e) { $this->invalidate(); - throw new SessionException('Invalid User object, session destroyed.', 500); } + // Extend the lifetime of the session. if ($sessionExists) { $this->setCookie(); diff --git a/system/src/Grav/Framework/Uri/UriFactory.php b/system/src/Grav/Framework/Uri/UriFactory.php index f70194e..c8ba345 100644 --- a/system/src/Grav/Framework/Uri/UriFactory.php +++ b/system/src/Grav/Framework/Uri/UriFactory.php @@ -93,7 +93,7 @@ class UriFactory } // Support ngnix routes. - if (strpos($query, '_url=') === 0) { + if (strpos((string) $query, '_url=') === 0) { parse_str($query, $q); unset($q['_url']); $query = http_build_query($q); diff --git a/system/src/Twig/DeferredExtension/DeferredDeclareNode.php b/system/src/Twig/DeferredExtension/DeferredDeclareNode.php new file mode 100644 index 0000000..ba05121 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredDeclareNode.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Compiler; +use Twig\Node\Node; + +final class DeferredDeclareNode extends Node +{ + public function compile(Compiler $compiler) : void + { + $compiler + ->write("private \$deferred;\n") + ; + } +} \ No newline at end of file diff --git a/system/src/Twig/DeferredExtension/DeferredExtensionNode.php b/system/src/Twig/DeferredExtension/DeferredInitializeNode.php similarity index 92% rename from system/src/Twig/DeferredExtension/DeferredExtensionNode.php rename to system/src/Twig/DeferredExtension/DeferredInitializeNode.php index 1b851b4..0653f5c 100644 --- a/system/src/Twig/DeferredExtension/DeferredExtensionNode.php +++ b/system/src/Twig/DeferredExtension/DeferredInitializeNode.php @@ -16,7 +16,7 @@ namespace Twig\DeferredExtension; use Twig\Compiler; use Twig\Node\Node; -final class DeferredExtensionNode extends Node +final class DeferredInitializeNode extends Node { public function compile(Compiler $compiler) : void { diff --git a/system/src/Twig/DeferredExtension/DeferredNodeVisitor.php b/system/src/Twig/DeferredExtension/DeferredNodeVisitor.php index aef7399..6f61487 100644 --- a/system/src/Twig/DeferredExtension/DeferredNodeVisitor.php +++ b/system/src/Twig/DeferredExtension/DeferredNodeVisitor.php @@ -34,8 +34,9 @@ final class DeferredNodeVisitor implements NodeVisitorInterface public function leaveNode(Node $node, Environment $env) : ?Node { if ($this->hasDeferred && $node instanceof ModuleNode) { - $node->setNode('constructor_end', new Node([new DeferredExtensionNode(), $node->getNode('constructor_end')])); - $node->setNode('display_end', new Node([new DeferredNode(), $node->getNode('display_end')])); + $node->getNode('constructor_end')->setNode('deferred_initialize', new DeferredInitializeNode()); + $node->getNode('display_end')->setNode('deferred_resolve', new DeferredResolveNode()); + $node->getNode('class_end')->setNode('deferred_declare', new DeferredDeclareNode()); $this->hasDeferred = false; } diff --git a/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php b/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php index 1ff7fd4..aa61b72 100644 --- a/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php +++ b/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php @@ -46,8 +46,9 @@ final class DeferredNodeVisitorCompat implements NodeVisitorInterface public function leaveNode(\Twig_NodeInterface $node, Environment $env): ?Node { if ($this->hasDeferred && $node instanceof ModuleNode) { - $node->setNode('constructor_end', new Node([new DeferredExtensionNode(), $node->getNode('constructor_end')])); - $node->setNode('display_end', new Node([new DeferredNode(), $node->getNode('display_end')])); + $node->getNode('constructor_end')->setNode('deferred_initialize', new DeferredInitializeNode()); + $node->getNode('display_end')->setNode('deferred_resolve', new DeferredResolveNode()); + $node->getNode('class_end')->setNode('deferred_declare', new DeferredDeclareNode()); $this->hasDeferred = false; } diff --git a/system/src/Twig/DeferredExtension/DeferredResolveNode.php b/system/src/Twig/DeferredExtension/DeferredResolveNode.php new file mode 100644 index 0000000..72e0e29 --- /dev/null +++ b/system/src/Twig/DeferredExtension/DeferredResolveNode.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Twig\DeferredExtension; + +use Twig\Compiler; +use Twig\Node\Node; + +final class DeferredResolveNode extends Node +{ + public function compile(Compiler $compiler) : void + { + $compiler + ->write("\$this->deferred->resolve(\$this, \$context, \$blocks);\n") + ; + } +} diff --git a/user/config/versions.yaml b/user/config/versions.yaml index 21f36c8..5d01416 100644 --- a/user/config/versions.yaml +++ b/user/config/versions.yaml @@ -1,6 +1,6 @@ core: grav: - version: 1.7.38 + version: 1.7.42.3 schema: 1.7.0_2020-11-20_1 history: - { version: 1.7.16, date: '2021-06-10 14:03:35' } @@ -8,3 +8,4 @@ core: - { version: 1.7.25, date: '2021-12-06 12:22:00' } - { version: 1.7.31, date: '2022-03-15 08:48:47' } - { version: 1.7.38, date: '2023-01-03 15:06:08' } + - { version: 1.7.42.3, date: '2023-09-19 10:47:33' } diff --git a/webserver-configs/nginx.conf b/webserver-configs/nginx.conf index fc7d06b..ed109b1 100644 --- a/webserver-configs/nginx.conf +++ b/webserver-configs/nginx.conf @@ -30,7 +30,7 @@ server { ## Begin - PHP location ~ \.php$ { # Choose either a socket or TCP/IP address - fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; + fastcgi_pass unix:/var/run/php/php-fpm.sock; # fastcgi_pass unix:/var/run/php5-fpm.sock; #legacy # fastcgi_pass 127.0.0.1:9000;