diff --git a/public/composer.json b/public/composer.json
index def6aa4..dc68ea8 100644
--- a/public/composer.json
+++ b/public/composer.json
@@ -23,7 +23,7 @@
},
"require": {
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
- "getkirby/cms": "^4.0",
+ "getkirby/cms": "^4.5",
"getkirby/kql": "^1.2"
},
"config": {
diff --git a/public/composer.lock b/public/composer.lock
index a947d3f..9f08a10 100644
--- a/public/composer.lock
+++ b/public/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": "45a7afdac49ac63b55055018fb1e8d5a",
+ "content-hash": "8f2fa8b1557df883bef5b3425ee05c4c",
"packages": [
{
"name": "christian-riesen/base32",
@@ -120,24 +120,24 @@
},
{
"name": "composer/semver",
- "version": "3.4.0",
+ "version": "3.4.3",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
- "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
+ "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
- "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
+ "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
+ "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
- "phpstan/phpstan": "^1.4",
- "symfony/phpunit-bridge": "^4.2 || ^5"
+ "phpstan/phpstan": "^1.11",
+ "symfony/phpunit-bridge": "^3 || ^7"
},
"type": "library",
"extra": {
@@ -181,7 +181,7 @@
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
- "source": "https://github.com/composer/semver/tree/3.4.0"
+ "source": "https://github.com/composer/semver/tree/3.4.3"
},
"funding": [
{
@@ -197,30 +197,30 @@
"type": "tidelift"
}
],
- "time": "2023-08-31T09:50:34+00:00"
+ "time": "2024-09-19T14:15:21+00:00"
},
{
"name": "filp/whoops",
- "version": "2.15.4",
+ "version": "2.16.0",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
- "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546"
+ "reference": "befcdc0e5dce67252aa6322d82424be928214fa2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546",
- "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546",
+ "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2",
+ "reference": "befcdc0e5dce67252aa6322d82424be928214fa2",
"shasum": ""
},
"require": {
- "php": "^5.5.9 || ^7.0 || ^8.0",
+ "php": "^7.1 || ^8.0",
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
},
"require-dev": {
- "mockery/mockery": "^0.9 || ^1.0",
- "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3",
- "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0"
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3",
+ "symfony/var-dumper": "^4.0 || ^5.0"
},
"suggest": {
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
@@ -260,7 +260,7 @@
],
"support": {
"issues": "https://github.com/filp/whoops/issues",
- "source": "https://github.com/filp/whoops/tree/2.15.4"
+ "source": "https://github.com/filp/whoops/tree/2.16.0"
},
"funding": [
{
@@ -268,26 +268,26 @@
"type": "github"
}
],
- "time": "2023-11-03T12:00:00+00:00"
+ "time": "2024-09-25T12:00:00+00:00"
},
{
"name": "getkirby/cms",
- "version": "4.3.0",
+ "version": "4.5.0",
"source": {
"type": "git",
"url": "https://github.com/getkirby/kirby.git",
- "reference": "f9f00b16a22fe9dbbbddc2bfd4719ca3437cbee9"
+ "reference": "94cc37ee7c3004ebb4950a53f14e1329ed4d28d3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/getkirby/kirby/zipball/f9f00b16a22fe9dbbbddc2bfd4719ca3437cbee9",
- "reference": "f9f00b16a22fe9dbbbddc2bfd4719ca3437cbee9",
+ "url": "https://api.github.com/repos/getkirby/kirby/zipball/94cc37ee7c3004ebb4950a53f14e1329ed4d28d3",
+ "reference": "94cc37ee7c3004ebb4950a53f14e1329ed4d28d3",
"shasum": ""
},
"require": {
"christian-riesen/base32": "1.6.0",
"claviska/simpleimage": "4.2.0",
- "composer/semver": "3.4.0",
+ "composer/semver": "3.4.3",
"ext-ctype": "*",
"ext-curl": "*",
"ext-dom": "*",
@@ -299,15 +299,15 @@
"ext-mbstring": "*",
"ext-openssl": "*",
"ext-simplexml": "*",
- "filp/whoops": "2.15.4",
+ "filp/whoops": "2.16.0",
"getkirby/composer-installer": "^1.2.1",
- "laminas/laminas-escaper": "2.13.0",
+ "laminas/laminas-escaper": "2.14.0",
"michelf/php-smartypants": "1.8.1",
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
- "phpmailer/phpmailer": "6.9.1",
- "symfony/polyfill-intl-idn": "1.29.0",
- "symfony/polyfill-mbstring": "1.29.0",
- "symfony/yaml": "6.4.8"
+ "phpmailer/phpmailer": "6.9.2",
+ "symfony/polyfill-intl-idn": "1.31.0",
+ "symfony/polyfill-mbstring": "1.31.0",
+ "symfony/yaml": "6.4.13"
},
"replace": {
"symfony/polyfill-php72": "*"
@@ -371,7 +371,7 @@
"type": "custom"
}
],
- "time": "2024-06-13T09:58:27+00:00"
+ "time": "2024-11-28T10:10:23+00:00"
},
{
"name": "getkirby/composer-installer",
@@ -477,33 +477,33 @@
},
{
"name": "laminas/laminas-escaper",
- "version": "2.13.0",
+ "version": "2.14.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-escaper.git",
- "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba"
+ "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/af459883f4018d0f8a0c69c7a209daef3bf973ba",
- "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba",
+ "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/0f7cb975f4443cf22f33408925c231225cfba8cb",
+ "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-mbstring": "*",
- "php": "~8.1.0 || ~8.2.0 || ~8.3.0"
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
},
"conflict": {
"zendframework/zend-escaper": "*"
},
"require-dev": {
- "infection/infection": "^0.27.0",
- "laminas/laminas-coding-standard": "~2.5.0",
+ "infection/infection": "^0.27.9",
+ "laminas/laminas-coding-standard": "~3.0.0",
"maglnet/composer-require-checker": "^3.8.0",
- "phpunit/phpunit": "^9.6.7",
- "psalm/plugin-phpunit": "^0.18.4",
- "vimeo/psalm": "^5.9"
+ "phpunit/phpunit": "^9.6.16",
+ "psalm/plugin-phpunit": "^0.19.0",
+ "vimeo/psalm": "^5.21.1"
},
"type": "library",
"autoload": {
@@ -535,7 +535,7 @@
"type": "community_bridge"
}
],
- "time": "2023-10-10T08:35:13+00:00"
+ "time": "2024-10-24T10:12:53+00:00"
},
{
"name": "league/color-extractor",
@@ -654,16 +654,16 @@
},
{
"name": "phpmailer/phpmailer",
- "version": "v6.9.1",
+ "version": "v6.9.2",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
- "reference": "039de174cd9c17a8389754d3b877a2ed22743e18"
+ "reference": "a7b17b42fa4887c92146243f3d2f4ccb962af17c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18",
- "reference": "039de174cd9c17a8389754d3b877a2ed22743e18",
+ "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a7b17b42fa4887c92146243f3d2f4ccb962af17c",
+ "reference": "a7b17b42fa4887c92146243f3d2f4ccb962af17c",
"shasum": ""
},
"require": {
@@ -723,7 +723,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
- "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1"
+ "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.2"
},
"funding": [
{
@@ -731,20 +731,20 @@
"type": "github"
}
],
- "time": "2023-11-25T22:23:28+00:00"
+ "time": "2024-10-09T10:07:50+00:00"
},
{
"name": "psr/log",
- "version": "3.0.0",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
- "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
- "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
+ "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"shasum": ""
},
"require": {
@@ -779,22 +779,22 @@
"psr-3"
],
"support": {
- "source": "https://github.com/php-fig/log/tree/3.0.0"
+ "source": "https://github.com/php-fig/log/tree/3.0.2"
},
- "time": "2021-07-14T16:46:02+00:00"
+ "time": "2024-09-11T13:17:53+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.5.0",
+ "version": "v3.5.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
- "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
+ "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
- "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
+ "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
"shasum": ""
},
"require": {
@@ -802,12 +802,12 @@
},
"type": "library",
"extra": {
+ "thanks": {
+ "url": "https://github.com/symfony/contracts",
+ "name": "symfony/contracts"
+ },
"branch-alias": {
"dev-main": "3.5-dev"
- },
- "thanks": {
- "name": "symfony/contracts",
- "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
@@ -832,7 +832,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1"
},
"funding": [
{
@@ -848,24 +848,24 @@
"type": "tidelift"
}
],
- "time": "2024-04-18T09:32:20+00:00"
+ "time": "2024-09-25T14:20:29+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.30.0",
+ "version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "0424dff1c58f028c451efff2045f5d92410bd540"
+ "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
- "reference": "0424dff1c58f028c451efff2045f5d92410bd540",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
+ "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"provide": {
"ext-ctype": "*"
@@ -876,8 +876,8 @@
"type": "library",
"extra": {
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -911,7 +911,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
},
"funding": [
{
@@ -927,26 +927,25 @@
"type": "tidelift"
}
],
- "time": "2024-05-31T15:07:36+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
- "version": "v1.29.0",
+ "version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
- "reference": "a287ed7475f85bf6f61890146edbc932c0fff919"
+ "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919",
- "reference": "a287ed7475f85bf6f61890146edbc932c0fff919",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773",
+ "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773",
"shasum": ""
},
"require": {
- "php": ">=7.1",
- "symfony/polyfill-intl-normalizer": "^1.10",
- "symfony/polyfill-php72": "^1.10"
+ "php": ">=7.2",
+ "symfony/polyfill-intl-normalizer": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
@@ -954,8 +953,8 @@
"type": "library",
"extra": {
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -995,7 +994,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0"
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0"
},
"funding": [
{
@@ -1011,24 +1010,24 @@
"type": "tidelift"
}
],
- "time": "2024-01-29T20:11:03+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.30.0",
+ "version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb"
+ "reference": "3833d7255cc303546435cb650316bff708a1c75c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb",
- "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
+ "reference": "3833d7255cc303546435cb650316bff708a1c75c",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"suggest": {
"ext-intl": "For best performance"
@@ -1036,8 +1035,8 @@
"type": "library",
"extra": {
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -1076,7 +1075,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0"
},
"funding": [
{
@@ -1092,24 +1091,24 @@
"type": "tidelift"
}
],
- "time": "2024-05-31T15:07:36+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.29.0",
+ "version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
+ "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
- "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
+ "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
@@ -1120,8 +1119,8 @@
"type": "library",
"extra": {
"thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
+ "url": "https://github.com/symfony/polyfill",
+ "name": "symfony/polyfill"
}
},
"autoload": {
@@ -1156,7 +1155,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
},
"funding": [
{
@@ -1172,20 +1171,20 @@
"type": "tidelift"
}
],
- "time": "2024-01-29T20:11:03+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/yaml",
- "version": "v6.4.8",
+ "version": "v6.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "52903de178d542850f6f341ba92995d3d63e60c9"
+ "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/52903de178d542850f6f341ba92995d3d63e60c9",
- "reference": "52903de178d542850f6f341ba92995d3d63e60c9",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/e99b4e94d124b29ee4cf3140e1b537d2dad8cec9",
+ "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9",
"shasum": ""
},
"require": {
@@ -1228,7 +1227,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/yaml/tree/v6.4.8"
+ "source": "https://github.com/symfony/yaml/tree/v6.4.13"
},
"funding": [
{
@@ -1244,7 +1243,7 @@
"type": "tidelift"
}
],
- "time": "2024-05-31T14:49:08+00:00"
+ "time": "2024-09-25T14:18:03+00:00"
}
],
"packages-dev": [],
diff --git a/public/kirby/cacert.pem b/public/kirby/cacert.pem
index 86d6cd8..eb11b2f 100644
--- a/public/kirby/cacert.pem
+++ b/public/kirby/cacert.pem
@@ -1,7 +1,9 @@
##
## Bundle of CA Root Certificates
##
-## Certificate data from Mozilla as of: Tue Jul 2 03:12:04 2024 GMT
+## Certificate data from Mozilla as of: Tue Nov 26 13:58:25 2024 GMT
+##
+## Find updated versions here: https://curl.se/docs/caextract.html
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,7 +16,7 @@
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.29.
-## SHA256: 456ff095dde6dd73354c5c28c73d9c06f53b61a803963414cb91a1d92945cdd3
+## SHA256: 36105b01631f9fc03b1eca779b44a30a1a5890b9bf8dc07ccb001a07301e01cf
##
@@ -2600,6 +2602,36 @@ vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+
CAezNIm8BZ/3Hobui3A=
-----END CERTIFICATE-----
+GLOBALTRUST 2020
+================
+-----BEGIN CERTIFICATE-----
+MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx
+IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT
+VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh
+BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy
+MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi
+D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO
+VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM
+CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm
+fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA
+A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR
+JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG
+DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU
+clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ
+mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud
+IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
+VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw
+4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9
+iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS
+8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2
+HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS
+vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918
+oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF
+YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl
+gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
+-----END CERTIFICATE-----
+
ANF Secure Server Root CA
=========================
-----BEGIN CERTIFICATE-----
@@ -3566,3 +3598,99 @@ Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB
cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ
pYXFuXqUPoeovQA=
-----END CERTIFICATE-----
+
+TWCA CYBER Root CA
+==================
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYDVQQG
+EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB
+IENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQG
+EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB
+IENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1s
+Ts6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxFavcokPFh
+V8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/34bKS1PE2Y2yHer43CdT
+o0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684iJkXXYJndzk834H/nY62wuFm40AZoNWDT
+Nq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK
+/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkH
+IuNZW0CP2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TM
+fAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF
+2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzR
+wyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83
+QOGt4A1WNzAdBgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB
+AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olN
+c79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x
+X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDR
+IG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq
+/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0R
+FxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz8ppy6rBe
+Pm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4NxKfKjLji7gh7MMrZQzv
+It6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrruoBa3lwtcHb4yOWHh8qgnaHl
+IhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X
+-----END CERTIFICATE-----
+
+SecureSign Root CA12
+====================
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTELMAkG
+A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT
+ZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJ
+BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU
+U2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3
+emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mtp7JIKwcc
+J/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zdJ1M3s6oYwlkm7Fsf0uZl
+fO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gurFzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBF
+EaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1Uef
+NzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOC
+AQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQi
+LUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpce
+mik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPS
+vWKErI4cqc1avTc7bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhga
+aaI5gdka9at/yOPiZwud9AzqVN/Ssq+xIvEg37xEHA==
+-----END CERTIFICATE-----
+
+SecureSign Root CA14
+====================
+-----BEGIN CERTIFICATE-----
+MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTELMAkG
+A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT
+ZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJ
+BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU
+U2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh
+1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOgvlIfX8xn
+bacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy6pJxaeQp8E+BgQQ8sqVb
+1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa
+/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOE
+kJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSx
+jVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18iz
+ju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0
+dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsY
+AFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQAB
+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeq
+YR3r6/wtbyPk86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E
+rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoA
+ymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds
+Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPG
+FrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6q
+nsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/
+OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6dB7h7sxa
+OgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtlLor6CZpO2oYofaphNdgO
+pygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6UeTo3cKXhZ+PmhIIynJkBugnLN
+eLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S
+-----END CERTIFICATE-----
+
+SecureSign Root CA15
+====================
+-----BEGIN CERTIFICATE-----
+MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkGA1UE
+BhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRTZWN1
+cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNV
+BAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2Vj
+dXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5G
+dCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSRZHX+AezB
+2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT9DAKBggqhkjOPQQDAwNoADBlAjEA2S6J
+fl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJ
+SwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr62Nuk22rGwlgMU4=
+-----END CERTIFICATE-----
diff --git a/public/kirby/composer.json b/public/kirby/composer.json
index 1ccb407..0cf0d0a 100644
--- a/public/kirby/composer.json
+++ b/public/kirby/composer.json
@@ -3,7 +3,7 @@
"description": "The Kirby core",
"license": "proprietary",
"type": "kirby-cms",
- "version": "4.4.0",
+ "version": "4.5.0",
"keywords": [
"kirby",
"cms",
@@ -38,15 +38,15 @@
"ext-openssl": "*",
"christian-riesen/base32": "1.6.0",
"claviska/simpleimage": "4.2.0",
- "composer/semver": "3.4.2",
- "filp/whoops": "2.15.4",
+ "composer/semver": "3.4.3",
+ "filp/whoops": "2.16.0",
"getkirby/composer-installer": "^1.2.1",
- "laminas/laminas-escaper": "2.13.0",
+ "laminas/laminas-escaper": "2.14.0",
"michelf/php-smartypants": "1.8.1",
- "phpmailer/phpmailer": "6.9.1",
- "symfony/polyfill-intl-idn": "1.30.0",
- "symfony/polyfill-mbstring": "1.30.0",
- "symfony/yaml": "6.4.11"
+ "phpmailer/phpmailer": "6.9.2",
+ "symfony/polyfill-intl-idn": "1.31.0",
+ "symfony/polyfill-mbstring": "1.31.0",
+ "symfony/yaml": "6.4.13"
},
"replace": {
"symfony/polyfill-php72": "*"
diff --git a/public/kirby/composer.lock b/public/kirby/composer.lock
index ea8097d..778013c 100644
--- a/public/kirby/composer.lock
+++ b/public/kirby/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": "a49870b845c1d596a44c5af23c4dd685",
+ "content-hash": "f12b026f0a6ca67dc1bd0072f607d1eb",
"packages": [
{
"name": "christian-riesen/base32",
@@ -120,24 +120,24 @@
},
{
"name": "composer/semver",
- "version": "3.4.2",
+ "version": "3.4.3",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
- "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6"
+ "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6",
- "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6",
+ "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
+ "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
- "phpstan/phpstan": "^1.4",
- "symfony/phpunit-bridge": "^4.2 || ^5"
+ "phpstan/phpstan": "^1.11",
+ "symfony/phpunit-bridge": "^3 || ^7"
},
"type": "library",
"extra": {
@@ -181,7 +181,7 @@
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
- "source": "https://github.com/composer/semver/tree/3.4.2"
+ "source": "https://github.com/composer/semver/tree/3.4.3"
},
"funding": [
{
@@ -197,30 +197,30 @@
"type": "tidelift"
}
],
- "time": "2024-07-12T11:35:52+00:00"
+ "time": "2024-09-19T14:15:21+00:00"
},
{
"name": "filp/whoops",
- "version": "2.15.4",
+ "version": "2.16.0",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
- "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546"
+ "reference": "befcdc0e5dce67252aa6322d82424be928214fa2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546",
- "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546",
+ "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2",
+ "reference": "befcdc0e5dce67252aa6322d82424be928214fa2",
"shasum": ""
},
"require": {
- "php": "^5.5.9 || ^7.0 || ^8.0",
+ "php": "^7.1 || ^8.0",
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
},
"require-dev": {
- "mockery/mockery": "^0.9 || ^1.0",
- "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3",
- "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0"
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3",
+ "symfony/var-dumper": "^4.0 || ^5.0"
},
"suggest": {
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
@@ -260,7 +260,7 @@
],
"support": {
"issues": "https://github.com/filp/whoops/issues",
- "source": "https://github.com/filp/whoops/tree/2.15.4"
+ "source": "https://github.com/filp/whoops/tree/2.16.0"
},
"funding": [
{
@@ -268,7 +268,7 @@
"type": "github"
}
],
- "time": "2023-11-03T12:00:00+00:00"
+ "time": "2024-09-25T12:00:00+00:00"
},
{
"name": "getkirby/composer-installer",
@@ -319,33 +319,33 @@
},
{
"name": "laminas/laminas-escaper",
- "version": "2.13.0",
+ "version": "2.14.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-escaper.git",
- "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba"
+ "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/af459883f4018d0f8a0c69c7a209daef3bf973ba",
- "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba",
+ "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/0f7cb975f4443cf22f33408925c231225cfba8cb",
+ "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-mbstring": "*",
- "php": "~8.1.0 || ~8.2.0 || ~8.3.0"
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
},
"conflict": {
"zendframework/zend-escaper": "*"
},
"require-dev": {
- "infection/infection": "^0.27.0",
- "laminas/laminas-coding-standard": "~2.5.0",
+ "infection/infection": "^0.27.9",
+ "laminas/laminas-coding-standard": "~3.0.0",
"maglnet/composer-require-checker": "^3.8.0",
- "phpunit/phpunit": "^9.6.7",
- "psalm/plugin-phpunit": "^0.18.4",
- "vimeo/psalm": "^5.9"
+ "phpunit/phpunit": "^9.6.16",
+ "psalm/plugin-phpunit": "^0.19.0",
+ "vimeo/psalm": "^5.21.1"
},
"type": "library",
"autoload": {
@@ -377,7 +377,7 @@
"type": "community_bridge"
}
],
- "time": "2023-10-10T08:35:13+00:00"
+ "time": "2024-10-24T10:12:53+00:00"
},
{
"name": "league/color-extractor",
@@ -496,16 +496,16 @@
},
{
"name": "phpmailer/phpmailer",
- "version": "v6.9.1",
+ "version": "v6.9.2",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
- "reference": "039de174cd9c17a8389754d3b877a2ed22743e18"
+ "reference": "a7b17b42fa4887c92146243f3d2f4ccb962af17c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18",
- "reference": "039de174cd9c17a8389754d3b877a2ed22743e18",
+ "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a7b17b42fa4887c92146243f3d2f4ccb962af17c",
+ "reference": "a7b17b42fa4887c92146243f3d2f4ccb962af17c",
"shasum": ""
},
"require": {
@@ -565,7 +565,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
- "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1"
+ "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.2"
},
"funding": [
{
@@ -573,7 +573,7 @@
"type": "github"
}
],
- "time": "2023-11-25T22:23:28+00:00"
+ "time": "2024-10-09T10:07:50+00:00"
},
{
"name": "psr/log",
@@ -773,22 +773,21 @@
},
{
"name": "symfony/polyfill-intl-idn",
- "version": "v1.30.0",
+ "version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
- "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c"
+ "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
- "reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773",
+ "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773",
"shasum": ""
},
"require": {
- "php": ">=7.1",
- "symfony/polyfill-intl-normalizer": "^1.10",
- "symfony/polyfill-php72": "^1.10"
+ "php": ">=7.2",
+ "symfony/polyfill-intl-normalizer": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
@@ -837,7 +836,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.30.0"
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0"
},
"funding": [
{
@@ -853,7 +852,7 @@
"type": "tidelift"
}
],
- "time": "2024-05-31T15:07:36+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
@@ -938,20 +937,20 @@
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.30.0",
+ "version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
+ "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
- "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
+ "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
@@ -998,7 +997,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
},
"funding": [
{
@@ -1014,20 +1013,20 @@
"type": "tidelift"
}
],
- "time": "2024-06-19T12:30:46+00:00"
+ "time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/yaml",
- "version": "v6.4.11",
+ "version": "v6.4.13",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "be37e7f13195e05ab84ca5269365591edd240335"
+ "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/be37e7f13195e05ab84ca5269365591edd240335",
- "reference": "be37e7f13195e05ab84ca5269365591edd240335",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/e99b4e94d124b29ee4cf3140e1b537d2dad8cec9",
+ "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9",
"shasum": ""
},
"require": {
@@ -1070,7 +1069,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/yaml/tree/v6.4.11"
+ "source": "https://github.com/symfony/yaml/tree/v6.4.13"
},
"funding": [
{
@@ -1086,7 +1085,7 @@
"type": "tidelift"
}
],
- "time": "2024-08-12T09:55:28+00:00"
+ "time": "2024-09-25T14:18:03+00:00"
}
],
"packages-dev": [],
diff --git a/public/kirby/config/api/routes/system.php b/public/kirby/config/api/routes/system.php
index 103e826..e7e49b4 100644
--- a/public/kirby/config/api/routes/system.php
+++ b/public/kirby/config/api/routes/system.php
@@ -31,6 +31,18 @@ return [
];
}
],
+ [
+ 'pattern' => 'system/method-test',
+ 'method' => 'PATCH',
+ 'action' => function () {
+ return [
+ 'status' => match ($this->kirby()->request()->method()) {
+ 'PATCH' => 'ok',
+ default => 'fail'
+ }
+ ];
+ }
+ ],
[
'pattern' => 'system/register',
'method' => 'POST',
diff --git a/public/kirby/config/api/routes/users.php b/public/kirby/config/api/routes/users.php
index 88658d8..203e2d2 100644
--- a/public/kirby/config/api/routes/users.php
+++ b/public/kirby/config/api/routes/users.php
@@ -203,7 +203,9 @@ return [
'users/(:any)/roles',
],
'action' => function (string $id) {
- return $this->user($id)->roles();
+ $kirby = $this->kirby();
+ $purpose = $kirby->request()->get('purpose');
+ return $this->user($id)->roles($purpose);
}
],
[
diff --git a/public/kirby/config/areas/languages/dialogs.php b/public/kirby/config/areas/languages/dialogs.php
index fe88ff3..e208ac9 100644
--- a/public/kirby/config/areas/languages/dialogs.php
+++ b/public/kirby/config/areas/languages/dialogs.php
@@ -256,7 +256,7 @@ return [
},
'submit' => function (string $languageCode, string $translationKey) {
Find::language($languageCode)->variable($translationKey, true)->update(
- App::instance()->request()->get('value')
+ App::instance()->request()->get('value', '')
);
return true;
diff --git a/public/kirby/config/areas/site/dialogs.php b/public/kirby/config/areas/site/dialogs.php
index 834b8ca..1a2cc1d 100644
--- a/public/kirby/config/areas/site/dialogs.php
+++ b/public/kirby/config/areas/site/dialogs.php
@@ -3,6 +3,7 @@
use Kirby\Cms\App;
use Kirby\Cms\Find;
use Kirby\Cms\PageRules;
+use Kirby\Cms\Url;
use Kirby\Exception\Exception;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\PermissionException;
@@ -431,7 +432,7 @@ return [
];
}
- $slugAppendix = Str::slug(I18n::translate('page.duplicate.appendix'));
+ $slugAppendix = Url::slug(I18n::translate('page.duplicate.appendix'));
$titleAppendix = I18n::translate('page.duplicate.appendix');
// if the item to be duplicated already exists
diff --git a/public/kirby/config/areas/site/requests.php b/public/kirby/config/areas/site/requests.php
index 972b43d..74a0228 100644
--- a/public/kirby/config/areas/site/requests.php
+++ b/public/kirby/config/areas/site/requests.php
@@ -70,12 +70,19 @@ return [
'action' => function () {
$kirby = App::instance();
$request = $kirby->request();
+ $root = $request->get('root');
$page = $kirby->page($request->get('page'));
+ $parents = $page?->parents()->flip()->values(
+ fn ($parent) => $parent->uuid()?->toString() ?? $parent->id()
+ ) ?? [];
+
+ // if root is included, add the site as top-level parent
+ if ($root === 'true') {
+ array_unshift($parents, $kirby->site()->uuid()?->toString() ?? '/');
+ }
return [
- 'data' => $page->parents()->flip()->values(
- fn ($parent) => $parent->uuid()?->toString() ?? $parent->id()
- )
+ 'data' => $parents
];
}
]
diff --git a/public/kirby/config/areas/users/dialogs.php b/public/kirby/config/areas/users/dialogs.php
index 1f1da96..1f60ecf 100644
--- a/public/kirby/config/areas/users/dialogs.php
+++ b/public/kirby/config/areas/users/dialogs.php
@@ -20,12 +20,19 @@ return [
'pattern' => 'users/create',
'load' => function () {
$kirby = App::instance();
+ $roles = $kirby->roles()->canBeCreated();
// get default value for role
if ($role = $kirby->request()->get('role')) {
- $role = $kirby->roles()->find($role)?->id();
+ $role = $roles->find($role)?->id();
}
+ // get role field definition, incl. available role options
+ $roles = Field::role(
+ roles: $roles,
+ props: ['required' => true]
+ );
+
return [
'component' => 'k-form-dialog',
'props' => [
@@ -39,9 +46,7 @@ return [
'translation' => Field::translation([
'required' => true
]),
- 'role' => Field::role([
- 'required' => true
- ])
+ 'role' => $roles
],
'submitButton' => I18n::translate('create'),
'value' => [
@@ -49,7 +54,7 @@ return [
'email' => '',
'password' => '',
'translation' => $kirby->panelLanguage(),
- 'role' => $role ?? $kirby->user()->role()->name()
+ 'role' => $role ?? $roles['options'][0]['value'] ?? null
]
]
];
@@ -228,10 +233,13 @@ return [
'component' => 'k-form-dialog',
'props' => [
'fields' => [
- 'role' => Field::role([
- 'label' => I18n::translate('user.changeRole.select'),
- 'required' => true,
- ])
+ 'role' => Field::role(
+ roles: $user->roles(),
+ props: [
+ 'label' => I18n::translate('user.changeRole.select'),
+ 'required' => true,
+ ]
+ )
],
'submitButton' => I18n::translate('user.changeRole'),
'value' => [
diff --git a/public/kirby/config/areas/users/views.php b/public/kirby/config/areas/users/views.php
index 5f0ce9d..60d9536 100644
--- a/public/kirby/config/areas/users/views.php
+++ b/public/kirby/config/areas/users/views.php
@@ -18,7 +18,8 @@ return [
return [
'component' => 'k-users-view',
'props' => [
- 'role' => function () use ($kirby, $roles, $role) {
+ 'canCreate' => $kirby->roles()->canBeCreated()->count() > 0,
+ 'role' => function () use ($roles, $role) {
if ($role) {
return $roles[$role] ?? null;
}
diff --git a/public/kirby/config/blocks/video/video.php b/public/kirby/config/blocks/video/video.php
index a1b1a31..3e7ed65 100644
--- a/public/kirby/config/blocks/video/video.php
+++ b/public/kirby/config/blocks/video/video.php
@@ -10,12 +10,13 @@ if (
) {
$url = $video->url();
$attrs = array_filter([
- 'autoplay' => $block->autoplay()->toBool(),
- 'controls' => $block->controls()->toBool(),
- 'loop' => $block->loop()->toBool(),
- 'muted' => $block->muted()->toBool(),
- 'poster' => $block->poster()->toFile()?->url(),
- 'preload' => $block->preload()->value(),
+ 'autoplay' => $block->autoplay()->toBool(),
+ 'controls' => $block->controls()->toBool(),
+ 'loop' => $block->loop()->toBool(),
+ 'muted' => $block->muted()->toBool() || $block->autoplay()->toBool(),
+ 'playsinline' => $block->autoplay()->toBool(),
+ 'poster' => $block->poster()->toFile()?->url(),
+ 'preload' => $block->preload()->value(),
]);
} else {
$url = $block->url();
diff --git a/public/kirby/i18n/translations/cs.json b/public/kirby/i18n/translations/cs.json
index 326b675..e2154f9 100644
--- a/public/kirby/i18n/translations/cs.json
+++ b/public/kirby/i18n/translations/cs.json
@@ -126,12 +126,12 @@
"error.form.notSaved": "Formulář nemohl být uložen",
"error.language.code": "Zadejte prosím platný kód jazyka",
- "error.language.create.permission": "You are not allowed to create a language",
- "error.language.delete.permission": "You are not allowed to delete the language",
+ "error.language.create.permission": "Nemáte dovoleno vytvořit jazyk",
+ "error.language.delete.permission": "Nemáte dovoleno jazyk vymazat",
"error.language.duplicate": "Jazyk již existuje",
"error.language.name": "Zadejte prosím platné jméno jazyka",
"error.language.notFound": "Jazyk nebyl nalezen",
- "error.language.update.permission": "You are not allowed to update the language",
+ "error.language.update.permission": "Nemáte dovoleno aktualizovat jazyk",
"error.layout.validation.block": "V rozvržení {layoutIndex} je v poli \"{field}\" v bloku {blockIndex} při použití \"{fieldset}\" typu chyba",
"error.layout.validation.settings": "Chyba v nastavení rozvržení {index}",
@@ -620,8 +620,8 @@
"stats.empty": "Žádná hlášení",
"status": "Stav",
- "system.info.copy": "Copy info",
- "system.info.copied": "System info copied",
+ "system.info.copy": "Kopírovat informace",
+ "system.info.copied": "Systémové informace zkopírovány",
"system.issues.content": "Složka content je zřejmě přístupná zvenčí",
"system.issues.eol.kirby": "Instalovaná verze Kirby dosáhla konce životnosti a nebude již dále dostávat bezpečnostní aktualizace",
"system.issues.eol.plugin": "Instalovaná verze doplňku { plugin } dosáhla konce životnosti a nebude již dále dostávat bezpečnostní aktualizace",
diff --git a/public/kirby/i18n/translations/en.json b/public/kirby/i18n/translations/en.json
index 6212ecf..f88d787 100644
--- a/public/kirby/i18n/translations/en.json
+++ b/public/kirby/i18n/translations/en.json
@@ -168,6 +168,7 @@
"error.page.move.ancestor": "The page cannot be moved into itself",
"error.page.move.directory": "The page directory cannot be moved",
"error.page.move.duplicate": "A sub page with the URL appendix \"{slug}\" already exists",
+ "error.page.move.noSections": "The page \"{parent}\" cannot be a parent of any page because it lacks any pages sections in its blueprint",
"error.page.move.notFound": "The moved page could not be found",
"error.page.move.permission": "You are not allowed to move \"{slug}\"",
"error.page.move.template": "The \"{template}\" template is not accepted as a subpage of \"{parent}\"",
@@ -629,6 +630,7 @@
"system.info.copy": "Copy info",
"system.info.copied": "System info copied",
+ "system.issues.api.methods": "Your server does not support PATCH requests",
"system.issues.content": "The content folder seems to be exposed",
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
diff --git a/public/kirby/i18n/translations/ko.json b/public/kirby/i18n/translations/ko.json
index d203767..4dae542 100644
--- a/public/kirby/i18n/translations/ko.json
+++ b/public/kirby/i18n/translations/ko.json
@@ -126,12 +126,12 @@
"error.form.notSaved": "항목을 저장할 수 없습니다.",
"error.language.code": "올바른 언어 코드를 입력하세요.",
- "error.language.create.permission": "You are not allowed to create a language",
- "error.language.delete.permission": "You are not allowed to delete the language",
+ "error.language.create.permission": "언어를 등록할 권한이 없습니다.",
+ "error.language.delete.permission": "언어를 삭제할 권한이 없습니다.",
"error.language.duplicate": "이미 등록한 언어입니다.",
"error.language.name": "올바른 언어명을 입력하세요.",
"error.language.notFound": "언어를 찾을 수 없습니다.",
- "error.language.update.permission": "You are not allowed to update the language",
+ "error.language.update.permission": "언어를 변경할 권한이 없습니다.",
"error.layout.validation.block": "레이아웃({layoutIndex})의 특정 블록 유형({fieldset})을 사용하는 블록({blockIndex})의 특정 필드({field})에 오류가 있습니다.",
"error.layout.validation.settings": "레이아웃({index}) 옵션을 확인하세요.",
@@ -620,8 +620,8 @@
"stats.empty": "관련 기록이 없습니다.",
"status": "상태",
- "system.info.copy": "Copy info",
- "system.info.copied": "System info copied",
+ "system.info.copy": "정보 복사",
+ "system.info.copied": "시스템 정보가 복사되었습니다.",
"system.issues.content": "/content 폴더의 권한을 확인하세요.",
"system.issues.eol.kirby": "설치된 Kirby 버전이 만료되었습니다. 더 이상 보안 업데이트를 받을 수 없습니다.",
"system.issues.eol.plugin": "설치된 플러그인({plugin}의 지원이 종료되었습니다. 더 이상 보안 업데이트를 받을 수 없습니다.",
diff --git a/public/kirby/i18n/translations/nl.json b/public/kirby/i18n/translations/nl.json
index 997697a..37fde74 100644
--- a/public/kirby/i18n/translations/nl.json
+++ b/public/kirby/i18n/translations/nl.json
@@ -126,12 +126,12 @@
"error.form.notSaved": "Het formulier kon niet worden opgeslagen",
"error.language.code": "Vul een geldige code voor deze taal in",
- "error.language.create.permission": "You are not allowed to create a language",
- "error.language.delete.permission": "You are not allowed to delete the language",
+ "error.language.create.permission": "Je hebt geen rechten om een taal toe te voegen",
+ "error.language.delete.permission": "Je hebt geen rechten om een taal te verwijderen",
"error.language.duplicate": "De taal bestaat al",
"error.language.name": "Vul een geldige naam voor deze taal in",
"error.language.notFound": "De taal kan niet worden gevonden",
- "error.language.update.permission": "You are not allowed to update the language",
+ "error.language.update.permission": "Je hebt geen rechten om deze taal te updaten",
"error.layout.validation.block": "Er is een fout opgetreden bij het \"{field}\" veld in blok {blockIndex} in het \"{fieldset}\" bloktype in layout {layoutIndex}",
"error.layout.validation.settings": "Er is een fout gevonden in de instellingen van ontwerp {index} ",
diff --git a/public/kirby/i18n/translations/pt_PT.json b/public/kirby/i18n/translations/pt_PT.json
index 574c257..3da7c47 100644
--- a/public/kirby/i18n/translations/pt_PT.json
+++ b/public/kirby/i18n/translations/pt_PT.json
@@ -104,16 +104,16 @@
"error.file.extension.forbidden": "A extensão \"{extension}\" não é permitida",
"error.file.extension.invalid": "Extensão inválida: {extension}",
"error.file.extension.missing": "As extensões de \"{filename}\" estão em falta",
- "error.file.maxheight": "A altura da imagem não deve exceder {height} pixels",
+ "error.file.maxheight": "A altura da imagem não deve exceder {height} píxeis",
"error.file.maxsize": "O ficheiro é demasiado grande",
- "error.file.maxwidth": "A largura da imagem não deve exceder {width} pixels",
+ "error.file.maxwidth": "A largura da imagem não deve exceder {width} píxeis",
"error.file.mime.differs": "O ficheiro enviado precisa de ser do tipo \"{mime}\"",
"error.file.mime.forbidden": "O tipo de mídia \"{mime}\" não é permitido",
"error.file.mime.invalid": "Tipo de mídia inválido: {mime}",
"error.file.mime.missing": "Não foi possível detectar o tipo de mídia de \"{filename}\"",
- "error.file.minheight": "A altura da imagem deve ter pelo menos {height} pixels",
+ "error.file.minheight": "A altura da imagem deve ter pelo menos {height} píxeis",
"error.file.minsize": "O ficheiro é demasiado pequeno",
- "error.file.minwidth": "A largura da imagem deve ter pelo menos {width} pixels",
+ "error.file.minwidth": "A largura da imagem deve ter pelo menos {width} píxeis",
"error.file.name.unique": "O nome do ficheiro deve ser único",
"error.file.name.missing": "O nome do ficheiro não pode ficar em branco",
"error.file.notFound": "Não foi possível encontrar o ficheiro \"{filename}\"",
@@ -490,7 +490,7 @@
"login.totp.disable.option": "Desativar códigos de segurança",
"login.totp.disable.label": "Insira a sua palavra-passe para desativar códigos de segurança",
"login.totp.disable.help": "No futuro, um segundo fator diferente, como um código de início de sessão enviado por e-mail, será solicitado quando iniciar a sessão. Poderá configurar códigos de segurança novamente mais tarde.",
- "login.totp.disable.admin": "
Isto irá desactivar os códigos de segurança para {user}.
No futuro, um segundo fator diferente, como um código de início de sessão enviado por e-mail, será solicitado quando eles iniciarem a sessão. {user} poderá configurar códigos de segurança novamente após o próximo início de sessão.
", + "login.totp.disable.admin": "Isto irá desativar os códigos de segurança para {user}.
No futuro, um segundo fator diferente, como um código de início de sessão enviado por e-mail, será solicitado quando eles iniciarem a sessão. {user} poderá configurar códigos de segurança novamente após o próximo início de sessão.
", "login.totp.disable.success": "Códigos de segurança desativados", "logout": "Sair", @@ -573,7 +573,7 @@ "paste": "Colar", "paste.after": "Colar após", "paste.success": "{count} colados!", - "pixel": "Pixel", + "pixel": "Píxel", "plugin": "Plugin", "plugins": "Plugins", "prev": "Anterior", diff --git a/public/kirby/i18n/translations/sv_SE.json b/public/kirby/i18n/translations/sv_SE.json index feb5caf..75e2e20 100644 --- a/public/kirby/i18n/translations/sv_SE.json +++ b/public/kirby/i18n/translations/sv_SE.json @@ -126,12 +126,12 @@ "error.form.notSaved": "Formuläret kunde inte sparas", "error.language.code": "Ange en giltig kod för språket", - "error.language.create.permission": "You are not allowed to create a language", - "error.language.delete.permission": "You are not allowed to delete the language", + "error.language.create.permission": "Du saknar behörighet att skapa ett nytt språk", + "error.language.delete.permission": "Du saknar behörighet att radera språket", "error.language.duplicate": "Språket finns redan", "error.language.name": "Ange ett giltigt namn för språket", "error.language.notFound": "Språket hittades inte", - "error.language.update.permission": "You are not allowed to update the language", + "error.language.update.permission": "Du saknar behörighet att redigera språket", "error.layout.validation.block": "Det finns ett fel i fältet \"{field}\" i blocket {blockIndex} med blocktypen \"{fieldset}\" i layouten {layoutIndex}", "error.layout.validation.settings": "Det finns ett fel i inställningarna för layout {index}", @@ -620,8 +620,8 @@ "stats.empty": "Inga rapporter", "status": "Status", - "system.info.copy": "Copy info", - "system.info.copied": "System info copied", + "system.info.copy": "Kopiera info", + "system.info.copied": "Systeminformation kopierad", "system.issues.content": "Mappen content verkar vara exponerad", "system.issues.eol.kirby": "Din installerade Kirby-version har nått slutet av sin livscykel och kommer inte att få fler säkerhetsuppdateringar", "system.issues.eol.plugin": "Den installerade versionen av tillägget { plugin } har nått slutet på sin livscykel och kommer inte att få fler säkerhetsuppdateringar.", diff --git a/public/kirby/src/Cms/File.php b/public/kirby/src/Cms/File.php index 4fac82c..9937bdc 100644 --- a/public/kirby/src/Cms/File.php +++ b/public/kirby/src/Cms/File.php @@ -338,13 +338,12 @@ class File extends ModelWithContent return false; } - static $accessible = []; + static $accessible = []; + $role = $this->kirby()->user()?->role()->id() ?? '__none__'; + $template = $this->template() ?? '__none__'; + $accessible[$role] ??= []; - if ($template = $this->template()) { - return $accessible[$template] ??= $this->permissions()->can('access'); - } - - return $accessible['__none__'] ??= $this->permissions()->can('access'); + return $accessible[$role][$template] ??= $this->permissions()->can('access'); } /** @@ -363,13 +362,12 @@ class File extends ModelWithContent return false; } - static $listable = []; + static $listable = []; + $role = $this->kirby()->user()?->role()->id() ?? '__none__'; + $template = $this->template() ?? '__none__'; + $listable[$role] ??= []; - if ($template = $this->template()) { - return $listable[$template] ??= $this->permissions()->can('list'); - } - - return $listable['__none__'] ??= $this->permissions()->can('list'); + return $listable[$role][$template] ??= $this->permissions()->can('list'); } /** @@ -379,13 +377,12 @@ class File extends ModelWithContent */ public function isReadable(): bool { - static $readable = []; + static $readable = []; + $role = $this->kirby()->user()?->role()->id() ?? '__none__'; + $template = $this->template() ?? '__none__'; + $readable[$role] ??= []; - if ($template = $this->template()) { - return $readable[$template] ??= $this->permissions()->can('read'); - } - - return $readable['__none__'] ??= $this->permissions()->can('read'); + return $readable[$role][$template] ??= $this->permissions()->can('read'); } /** @@ -633,12 +630,6 @@ class File extends ModelWithContent case 'page': $preview = $parent->blueprint()->preview(); - // user has no permission to preview page, - // also return null for file preview - if ($preview === false) { - return null; - } - // the page has a custom preview setting, // thus the file is only accessible through // the direct media URL diff --git a/public/kirby/src/Cms/FileActions.php b/public/kirby/src/Cms/FileActions.php index f6d57fb..712291a 100644 --- a/public/kirby/src/Cms/FileActions.php +++ b/public/kirby/src/Cms/FileActions.php @@ -139,10 +139,9 @@ trait FileActions $file = $file->update(['template' => $template]); - // rename and/or resize the file if configured by new blueprint + // resize the file if configured by new blueprint $create = $file->blueprint()->create(); - $file = $file->manipulate($create); - $file = $file->changeExtension($file, $create['format'] ?? null); + $file = $file->manipulate($create); return $file; }); @@ -185,6 +184,7 @@ trait FileActions /** * Copy the file to the given page + * @internal */ public function copy(Page $page): static { @@ -285,7 +285,6 @@ trait FileActions // resize the file on upload if configured $file = $file->manipulate($create); - $file = $file->changeExtension($file, $create['format'] ?? null); // store the content if necessary // (always create files in the default language) @@ -338,7 +337,14 @@ trait FileActions // generate image file and overwrite it in place $this->kirby()->thumb($this->root(), $this->root(), $options); - return $this->clone([]); + $file = $this->clone(); + + // change the file extension if format option configured + if ($format = $options['format'] ?? null) { + $file = $file->changeExtension($file, $format); + } + + return $file; } /** @@ -387,7 +393,6 @@ trait FileActions // apply the resizing/crop options from the blueprint $create = $file->blueprint()->create(); $file = $file->manipulate($create); - $file = $file->changeExtension($file, $create['format'] ?? null); // return a fresh clone return $file->clone(); diff --git a/public/kirby/src/Cms/LanguageRoutes.php b/public/kirby/src/Cms/LanguageRoutes.php index 201fbd4..68bdf42 100644 --- a/public/kirby/src/Cms/LanguageRoutes.php +++ b/public/kirby/src/Cms/LanguageRoutes.php @@ -3,7 +3,6 @@ namespace Kirby\Cms; use Kirby\Filesystem\F; -use Kirby\Toolkit\Str; class LanguageRoutes { @@ -30,26 +29,9 @@ class LanguageRoutes 'pattern' => $language->pattern(), 'method' => 'ALL', 'env' => 'site', - 'action' => function ($path = null) use ($kirby, $language) { + 'action' => function ($path = null) use ($language) { $result = $language->router()->call($path); - // redirect secondary-language pages that have - // been accessed with non-translated slugs in their path - // to their fully translated URL - if ($path !== null && $result instanceof Page) { - if (Str::endsWith($result->url(), $path) === false) { - $url = $result->url(); - $query = $kirby->request()->query()->toString(); - - // preserve query across redirect - if (empty($query) === false) { - $url .= '?' . $query; - } - - return $kirby->response()->redirect($url); - } - } - // explicitly test for null as $result can // contain falsy values that should still be returned if ($result !== null) { diff --git a/public/kirby/src/Cms/LanguageVariable.php b/public/kirby/src/Cms/LanguageVariable.php index b26336e..7ca846b 100644 --- a/public/kirby/src/Cms/LanguageVariable.php +++ b/public/kirby/src/Cms/LanguageVariable.php @@ -56,7 +56,7 @@ class LanguageVariable throw new DuplicateException('The variable is part of the core translation and cannot be overwritten'); } - $translations[$key] = trim($value ?? ''); + $translations[$key] = $value ?? ''; $language->update(['translations' => $translations]); @@ -102,10 +102,10 @@ class LanguageVariable /** * Sets a new value for the language variable */ - public function update(string $value): static + public function update(string|null $value = null): static { - $translations = $this->language->translations(); - $translations[$this->key] = $value; + $translations = $this->language->translations(); + $translations[$this->key] = $value ?? ''; $language = $this->language->update(['translations' => $translations]); diff --git a/public/kirby/src/Cms/License.php b/public/kirby/src/Cms/License.php index 4aa09af..6179cbb 100644 --- a/public/kirby/src/Cms/License.php +++ b/public/kirby/src/Cms/License.php @@ -42,8 +42,9 @@ class License protected string|null $date = null, protected string|null $signature = null, ) { - // normalize the email address - $this->email = $this->email === null ? null : $this->normalizeEmail($this->email); + // normalize arguments + $this->code = $this->code !== null ? trim($this->code) : null; + $this->email = $this->email !== null ? $this->normalizeEmail($this->email) : null; } /** diff --git a/public/kirby/src/Cms/Page.php b/public/kirby/src/Cms/Page.php index 3fab7b3..413a267 100644 --- a/public/kirby/src/Cms/Page.php +++ b/public/kirby/src/Cms/Page.php @@ -523,11 +523,12 @@ class Page extends ModelWithContent return false; } - static $accessible = []; + static $accessible = []; + $role = $this->kirby()->user()?->role()->id() ?? '__none__'; + $template = $this->intendedTemplate()->name(); + $accessible[$role] ??= []; - $template = $this->intendedTemplate()->name(); - - return $accessible[$template] ??= $this->permissions()->can('access'); + return $accessible[$role][$template] ??= $this->permissions()->can('access'); } /** @@ -689,11 +690,12 @@ class Page extends ModelWithContent return false; } - static $listable = []; + static $listable = []; + $role = $this->kirby()->user()?->role()->id() ?? '__none__'; + $template = $this->intendedTemplate()->name(); + $listable[$role] ??= []; - $template = $this->intendedTemplate()->name(); - - return $listable[$template] ??= $this->permissions()->can('list'); + return $listable[$role][$template] ??= $this->permissions()->can('list'); } /** @@ -745,11 +747,12 @@ class Page extends ModelWithContent */ public function isReadable(): bool { - static $readable = []; + static $readable = []; + $role = $this->kirby()->user()?->role()->id() ?? '__none__'; + $template = $this->intendedTemplate()->name(); + $readable[$role] ??= []; - $template = $this->intendedTemplate()->name(); - - return $readable[$template] ??= $this->permissions()->can('read'); + return $readable[$role][$template] ??= $this->permissions()->can('read'); } /** diff --git a/public/kirby/src/Cms/PageActions.php b/public/kirby/src/Cms/PageActions.php index ac5a9ef..4145692 100644 --- a/public/kirby/src/Cms/PageActions.php +++ b/public/kirby/src/Cms/PageActions.php @@ -153,7 +153,7 @@ trait PageActions string|null $languageCode = null ): static { // always sanitize the slug - $slug = Str::slug($slug); + $slug = Url::slug($slug); // in multi-language installations the slug for the non-default // languages is stored in the text file. The changeSlugForLanguage @@ -431,6 +431,8 @@ trait PageActions * Copies the page to a new parent * * @throws \Kirby\Exception\DuplicateException If the page already exists + * + * @internal */ public function copy(array $options = []): static { @@ -443,7 +445,7 @@ trait PageActions $files = $options['files'] ?? false; // clean up the slug - $slug = Str::slug($slug); + $slug = Url::slug($slug); if ($parentModel->findPageOrDraft($slug)) { throw new DuplicateException([ @@ -495,7 +497,7 @@ trait PageActions public static function create(array $props): Page { // clean up the slug - $props['slug'] = Str::slug($props['slug'] ?? $props['content']['title'] ?? null); + $props['slug'] = Url::slug($props['slug'] ?? $props['content']['title'] ?? null); $props['template'] = $props['model'] = strtolower($props['template'] ?? 'default'); $props['isDraft'] ??= $props['draft'] ?? true; @@ -685,7 +687,7 @@ trait PageActions public function duplicate(string|null $slug = null, array $options = []): static { // create the slug for the duplicate - $slug = Str::slug($slug ?? $this->slug() . '-' . Str::slug(I18n::translate('page.duplicate.appendix'))); + $slug = Url::slug($slug ?? $this->slug() . '-' . Url::slug(I18n::translate('page.duplicate.appendix'))); $arguments = [ 'originalPage' => $this, @@ -762,6 +764,7 @@ trait PageActions /** * @return $this|static * @throws \Kirby\Exception\LogicException If the folder cannot be moved + * @internal */ public function publish(): static { @@ -913,6 +916,7 @@ trait PageActions /** * Convert a page from listed or * unlisted to draft. + * @internal * * @return $this|static * @throws \Kirby\Exception\LogicException If the folder cannot be moved diff --git a/public/kirby/src/Cms/PageRules.php b/public/kirby/src/Cms/PageRules.php index b981058..8bc6736 100644 --- a/public/kirby/src/Cms/PageRules.php +++ b/public/kirby/src/Cms/PageRules.php @@ -365,27 +365,40 @@ class PageRules $allowed = []; // collect all allowed subpage templates - foreach ($parent->blueprint()->sections() as $section) { - // only take pages sections into consideration - if ($section->type() !== 'pages') { - continue; - } + // from all pages sections in the blueprint + // (only consider page sections that list pages + // of the targeted new parent page) + $sections = array_filter( + $parent->blueprint()->sections(), + fn ($section) => + $section->type() === 'pages' && + $section->parent()->is($parent) + ); - // only consider page sections that list pages - // of the targeted new parent page - if ($section->parent() !== $parent) { - continue; - } + // check if the parent has at least one pages section + if ($sections === []) { + throw new LogicException([ + 'key' => 'page.move.noSections', + 'data' => [ + 'parent' => $parent->id() ?? '/', + ] + ]); + } - // go through all allowed blueprints and - // add the name to the allow list - foreach ($section->blueprints() as $blueprint) { - $allowed[] = $blueprint['name']; + // go through all allowed templates and + // add the name to the allowlist + foreach ($sections as $section) { + foreach ($section->templates() as $template) { + $allowed[] = $template; } } // check if the template of this page is allowed as subpage type - if (in_array($page->intendedTemplate()->name(), $allowed) === false) { + // for the potential new parent + if ( + $allowed !== [] && + in_array($page->intendedTemplate()->name(), $allowed) === false + ) { throw new PermissionException([ 'key' => 'page.move.template', 'data' => [ diff --git a/public/kirby/src/Cms/Roles.php b/public/kirby/src/Cms/Roles.php index 11be6c9..b2a4dec 100644 --- a/public/kirby/src/Cms/Roles.php +++ b/public/kirby/src/Cms/Roles.php @@ -25,15 +25,19 @@ class Roles extends Collection /** * Returns a filtered list of all - * roles that can be created by the + * roles that can be changed by the * current user * + * Use with `$kirby->roles()`. For retrieving + * which roles are available for a specific user, + * use `$user->roles()` without additional filters. + * * @return $this|static * @throws \Exception */ public function canBeChanged(): static { - if (App::instance()->user()) { + if (App::instance()->user()?->isAdmin() !== true) { return $this->filter(function ($role) { $newUser = new User([ 'email' => 'test@getkirby.com', @@ -50,14 +54,16 @@ class Roles extends Collection /** * Returns a filtered list of all * roles that can be created by the - * current user + * current user. + * + * Use with `$kirby->roles()`. * * @return $this|static * @throws \Exception */ public function canBeCreated(): static { - if (App::instance()->user()) { + if (App::instance()->user()?->isAdmin() !== true) { return $this->filter(function ($role) { $newUser = new User([ 'email' => 'test@getkirby.com', diff --git a/public/kirby/src/Cms/System/UpdateStatus.php b/public/kirby/src/Cms/System/UpdateStatus.php index 8adf65d..0579f68 100644 --- a/public/kirby/src/Cms/System/UpdateStatus.php +++ b/public/kirby/src/Cms/System/UpdateStatus.php @@ -26,7 +26,7 @@ class UpdateStatus /** * Host to request the update data from */ - public static string $host = 'https://assets.getkirby.com'; + public static string $host = 'https://getkirby.com'; /** * Marker that stores whether a previous remote diff --git a/public/kirby/src/Cms/Url.php b/public/kirby/src/Cms/Url.php index bb44139..2ec0fd7 100644 --- a/public/kirby/src/Cms/Url.php +++ b/public/kirby/src/Cms/Url.php @@ -3,6 +3,7 @@ namespace Kirby\Cms; use Kirby\Http\Url as BaseUrl; +use Kirby\Toolkit\Str; /** * The `Url` class extends the @@ -31,6 +32,26 @@ class Url extends BaseUrl return App::instance()->url(); } + /** + * Convert a string to a safe version to be used in a URL, + * obeying the `slugs.maxlength` option + * + * @param string $string The unsafe string + * @param string $separator To be used instead of space and + * other non-word characters. + * @param string $allowed List of all allowed characters (regex) + * @param int $maxlength The maximum length of the slug + * @return string The safe string + */ + public static function slug( + string $string = null, + string $separator = null, + string $allowed = null, + ): string { + $maxlength = App::instance()->option('slugs.maxlength', 255); + return Str::slug($string, $separator, $allowed, $maxlength); + } + /** * Creates an absolute Url to a template asset if it exists. * This is used in the `css()` and `js()` helpers diff --git a/public/kirby/src/Cms/User.php b/public/kirby/src/Cms/User.php index ce5fbb0..d72df94 100644 --- a/public/kirby/src/Cms/User.php +++ b/public/kirby/src/Cms/User.php @@ -574,33 +574,24 @@ class User extends ModelWithContent } /** - * Returns all available roles - * for this user, that can be selected - * by the authenticated user + * Returns all available roles for this user, + * that the authenticated user can change to. + * + * For all roles the current user can create + * use `$kirby->roles()->canBeCreated()`. */ public function roles(): Roles { $kirby = $this->kirby(); $roles = $kirby->roles(); - // a collection with just the one role of the user - $myRole = $roles->filter('id', $this->role()->id()); - - // if there's an authenticated user … - // admin users can select pretty much any role - if ($kirby->user()?->isAdmin() === true) { - // except if the user is the last admin - if ($this->isLastAdmin() === true) { - // in which case they have to stay admin - return $myRole; - } - - // return all roles for mighty admins - return $roles; + // if the authenticated user doesn't have the permission to change + // the role of this user, only the current role is available + if ($this->permissions()->can('changeRole') === false) { + return $roles->filter('id', $this->role()->id()); } - // any other user can only keep their role - return $myRole; + return $roles->canBeCreated(); } /** @@ -666,7 +657,7 @@ class User extends ModelWithContent */ protected function siblingsCollection(): Users { - return $this->kirby()->users(); + return $this->kirby()->users()->sortBy('username', 'asc'); } /** diff --git a/public/kirby/src/Cms/UserPermissions.php b/public/kirby/src/Cms/UserPermissions.php index 62cd662..cab3776 100644 --- a/public/kirby/src/Cms/UserPermissions.php +++ b/public/kirby/src/Cms/UserPermissions.php @@ -26,7 +26,20 @@ class UserPermissions extends ModelPermissions protected function canChangeRole(): bool { - return $this->model->roles()->count() > 1; + // protect admin from role changes by non-admin + if ( + $this->model->isAdmin() === true && + $this->user->isAdmin() !== true + ) { + return false; + } + + // prevent demoting the last admin + if ($this->model->isLastAdmin() === true) { + return false; + } + + return true; } protected function canCreate(): bool diff --git a/public/kirby/src/Cms/UserRules.php b/public/kirby/src/Cms/UserRules.php index cf32665..df5918e 100644 --- a/public/kirby/src/Cms/UserRules.php +++ b/public/kirby/src/Cms/UserRules.php @@ -101,17 +101,6 @@ class UserRules */ public static function changeRole(User $user, string $role): bool { - // protect admin from role changes by non-admin - if ( - $user->kirby()->user()->isAdmin() === false && - $user->isAdmin() === true - ) { - throw new PermissionException([ - 'key' => 'user.changeRole.permission', - 'data' => ['name' => $user->username()] - ]); - } - // prevent non-admins making a user to admin if ( $user->kirby()->user()->isAdmin() === false && @@ -122,8 +111,7 @@ class UserRules ]); } - static::validRole($user, $role); - + // prevent demoting the last admin if ($role !== 'admin' && $user->isLastAdmin() === true) { throw new LogicException([ 'key' => 'user.changeRole.lastAdmin', @@ -131,6 +119,7 @@ class UserRules ]); } + // check permissions if ($user->permissions()->changeRole() !== true) { throw new PermissionException([ 'key' => 'user.changeRole.permission', @@ -138,6 +127,13 @@ class UserRules ]); } + // prevent changing to role that is not available for user + if ($user->roles()->find($role) instanceof Role === false) { + throw new InvalidArgumentException([ + 'key' => 'user.role.invalid', + ]); + } + return true; } @@ -199,22 +195,27 @@ class UserRules return true; } - // only admins are allowed to add admins - $role = $props['role'] ?? null; + // allow to create the first user + if ($user->kirby()->users()->count() === 0) { + return true; + } - if ($role === 'admin' && $currentUser?->isAdmin() === false) { + // check user permissions + if ($user->permissions()->create() !== true) { throw new PermissionException([ 'key' => 'user.create.permission' ]); } - // check user permissions (if not on install) + $role = $props['role'] ?? null; + + // prevent creating a role that is not available for user if ( - $user->kirby()->users()->count() > 0 && - $user->permissions()->create() !== true + in_array($role, [null, 'default', 'nobody'], true) === false && + $user->kirby()->roles()->canBeCreated()->find($role) instanceof Role === false ) { - throw new PermissionException([ - 'key' => 'user.create.permission' + throw new InvalidArgumentException([ + 'key' => 'user.role.invalid', ]); } @@ -370,6 +371,7 @@ class UserRules * Validates a user role * * @throws \Kirby\Exception\InvalidArgumentException If the user role does not exist + * @deprecated 4.5.0 */ public static function validRole(User $user, string $role): bool { diff --git a/public/kirby/src/Content/Field.php b/public/kirby/src/Content/Field.php index 0082063..82ae4b6 100644 --- a/public/kirby/src/Content/Field.php +++ b/public/kirby/src/Content/Field.php @@ -124,9 +124,17 @@ class Field */ public function isEmpty(): bool { + $value = $this->value; + + if (is_string($value) === true) { + $value = trim($value); + } + return - empty($this->value) === true && - in_array($this->value, [0, '0', false], true) === false; + $value === null || + $value === '' || + $value === [] || + $value === '[]'; } /** diff --git a/public/kirby/src/Filesystem/Filename.php b/public/kirby/src/Filesystem/Filename.php index eaef058..247f06a 100644 --- a/public/kirby/src/Filesystem/Filename.php +++ b/public/kirby/src/Filesystem/Filename.php @@ -2,7 +2,6 @@ namespace Kirby\Filesystem; -use Kirby\Cms\App; use Kirby\Cms\Language; use Kirby\Toolkit\Str; @@ -49,7 +48,8 @@ class Filename public function __construct( protected string $filename, protected string $template, - protected array $attributes = [] + protected array $attributes = [], + protected string|null $language = null ) { $this->name = $this->sanitizeName($filename); $this->extension = $this->sanitizeExtension( @@ -234,13 +234,12 @@ class Filename { // temporarily store language rules $rules = Str::$language; - $kirby = App::instance(null, true); - // if current user, add rules for their language to `Str` class - if ($user = $kirby?->user()) { + // add rules for a particular language to `Str` class + if ($this->language !== null) { Str::$language = [ ...Str::$language, - ...Language::loadRules($user->language())]; + ...Language::loadRules($this->language)]; } // sanitize name diff --git a/public/kirby/src/Image/Image.php b/public/kirby/src/Image/Image.php index 6a5ad25..4e7b0de 100644 --- a/public/kirby/src/Image/Image.php +++ b/public/kirby/src/Image/Image.php @@ -28,6 +28,7 @@ class Image extends File protected Dimensions|null $dimensions = null; public static array $resizableTypes = [ + 'avif', 'jpg', 'jpeg', 'gif', diff --git a/public/kirby/src/Option/OptionsApi.php b/public/kirby/src/Option/OptionsApi.php index a3b7ae8..3c83538 100644 --- a/public/kirby/src/Option/OptionsApi.php +++ b/public/kirby/src/Option/OptionsApi.php @@ -28,7 +28,9 @@ class OptionsApi extends OptionsProvider public string $url, public string|null $query = null, public string|null $text = null, - public string|null $value = null + public string|null $value = null, + public string|null $icon = null, + public string|null $info = null ) { } @@ -46,10 +48,12 @@ class OptionsApi extends OptionsProvider } return new static( - url: $props['url'], + url : $props['url'], query: $props['query'] ?? $props['fetch'] ?? null, - text: $props['text'] ?? null, - value: $props['value'] ?? null + text : $props['text'] ?? null, + value: $props['value'] ?? null, + icon : $props['icon'] ?? null, + info : $props['info'] ?? null ); } @@ -138,7 +142,10 @@ class OptionsApi extends OptionsProvider 'value' => $model->toString($this->value, ['item' => $item]), // text is only a raw string when using {< >} // or when the safe mode is explicitly disabled (select field) - 'text' => $model->$safeMethod($this->text, ['item' => $item]) + 'text' => $model->$safeMethod($this->text, ['item' => $item]), + // additional data + 'icon' => $this->icon !== null ? $model->toString($this->icon, ['item' => $item]) : null, + 'info' => $this->info !== null ? $model->$safeMethod($this->info, ['item' => $item]) : null ]; } diff --git a/public/kirby/src/Option/OptionsQuery.php b/public/kirby/src/Option/OptionsQuery.php index 77312c4..9ffdbaa 100644 --- a/public/kirby/src/Option/OptionsQuery.php +++ b/public/kirby/src/Option/OptionsQuery.php @@ -30,7 +30,9 @@ class OptionsQuery extends OptionsProvider public function __construct( public string $query, public string|null $text = null, - public string|null $value = null + public string|null $value = null, + public string|null $icon = null, + public string|null $info = null ) { } @@ -56,8 +58,10 @@ class OptionsQuery extends OptionsProvider return new static( query: $props['query'] ?? $props['fetch'], - text: $props['text'] ?? null, - value: $props['value'] ?? null + text : $props['text'] ?? null, + value: $props['value'] ?? null, + icon : $props['icon'] ?? null, + info : $props['info'] ?? null ); } @@ -178,7 +182,11 @@ class OptionsQuery extends OptionsProvider $safeMethod = $safeMode === true ? 'toSafeString' : 'toString'; $text = $model->$safeMethod($this->text ?? $text, $data); - return compact('text', 'value'); + // additional data + $icon = $this->icon !== null ? $model->toString($this->icon, $data) : null; + $info = $this->info !== null ? $model->$safeMethod($this->info, $data) : null; + + return compact('text', 'value', 'icon', 'info'); }); return $this->options = Options::factory($options); diff --git a/public/kirby/src/Panel/Field.php b/public/kirby/src/Panel/Field.php index e895712..d792fc0 100644 --- a/public/kirby/src/Panel/Field.php +++ b/public/kirby/src/Panel/Field.php @@ -6,6 +6,7 @@ use Kirby\Cms\App; use Kirby\Cms\File; use Kirby\Cms\ModelWithContent; use Kirby\Cms\Page; +use Kirby\Cms\Roles; use Kirby\Form\Form; use Kirby\Http\Router; use Kirby\Toolkit\I18n; @@ -191,29 +192,33 @@ class Field /** * User role radio buttons */ - public static function role(array $props = []): array - { - $kirby = App::instance(); - $isAdmin = $kirby->user()?->isAdmin() ?? false; - $roles = []; + public static function role( + array $props = [], + Roles|null $roles = null + ): array { + $kirby = App::instance(); - foreach ($kirby->roles() as $role) { - // exclude the admin role, if the user - // is not allowed to change role to admin - if ($role->name() === 'admin' && $isAdmin === false) { - continue; - } + // if no $roles where provided, fall back to all roles + $roles ??= $kirby->roles(); - $roles[] = [ - 'text' => $role->title(), - 'info' => $role->description() ?? I18n::translate('role.description.placeholder'), - 'value' => $role->name() - ]; - } + // exclude the admin role, if the user + // is not allowed to change role to admin + $roles = $roles->filter( + fn ($role) => + $role->name() !== 'admin' || + $kirby->user()?->isAdmin() === true + ); + + // turn roles into radio field options + $roles = $roles->values(fn ($role) => [ + 'text' => $role->title(), + 'info' => $role->description() ?? I18n::translate('role.description.placeholder'), + 'value' => $role->name() + ]); return array_merge([ 'label' => I18n::translate('role'), - 'type' => count($roles) <= 1 ? 'hidden' : 'radio', + 'type' => count($roles) < 1 ? 'hidden' : 'radio', 'options' => $roles ], $props); } diff --git a/public/kirby/src/Panel/PageCreateDialog.php b/public/kirby/src/Panel/PageCreateDialog.php index 2ab9c58..a2aa712 100644 --- a/public/kirby/src/Panel/PageCreateDialog.php +++ b/public/kirby/src/Panel/PageCreateDialog.php @@ -54,6 +54,7 @@ class PageCreateDialog 'tags', 'tel', 'text', + 'toggle', 'toggles', 'time', 'url' @@ -247,8 +248,9 @@ class PageCreateDialog */ public function model(): Page { + // TODO: use actual in-memory page in v5 return $this->model ??= Page::factory([ - 'slug' => 'new', + 'slug' => '__new__', 'template' => $this->template, 'model' => $this->template, 'parent' => $this->parent instanceof Page ? $this->parent : null @@ -266,12 +268,7 @@ class PageCreateDialog // create temporary page object // to resolve the template strings - $page = new Page([ - 'slug' => 'tmp', - 'template' => $this->template, - 'parent' => $this->model(), - 'content' => $input - ]); + $page = $this->model()->clone(['content' => $input]); if (is_string($title)) { $input['title'] = $page->toSafeString($title); diff --git a/public/kirby/src/Panel/User.php b/public/kirby/src/Panel/User.php index 1aa8cf5..17f641e 100644 --- a/public/kirby/src/Panel/User.php +++ b/public/kirby/src/Panel/User.php @@ -70,7 +70,7 @@ class User extends Model 'dialog' => $url . '/changeRole', 'icon' => 'bolt', 'text' => I18n::translate('user.changeRole'), - 'disabled' => $this->isDisabledDropdownOption('changeRole', $options, $permissions) + 'disabled' => $this->isDisabledDropdownOption('changeRole', $options, $permissions) || $this->model->roles()->count() < 2 ]; $result[] = [ @@ -218,14 +218,19 @@ class User extends Model */ public function props(): array { - $user = $this->model; - $account = $user->isLoggedIn(); + $user = $this->model; + $account = $user->isLoggedIn(); + $permissions = $this->options(); return array_merge( parent::props(), - $account ? [] : $this->prevNext(), + $this->prevNext(), [ - 'blueprint' => $this->model->role()->name(), + 'blueprint' => $this->model->role()->name(), + 'canChangeEmail' => $permissions['changeEmail'], + 'canChangeLanguage' => $permissions['changeLanguage'], + 'canChangeName' => $permissions['changeName'], + 'canChangeRole' => $this->model->roles()->count() > 1, 'model' => [ 'account' => $account, 'avatar' => $user->avatar()?->url(), diff --git a/public/kirby/src/Panel/View.php b/public/kirby/src/Panel/View.php index a2fcebc..9058e5e 100644 --- a/public/kirby/src/Panel/View.php +++ b/public/kirby/src/Panel/View.php @@ -275,6 +275,9 @@ class View return [ '$config' => fn () => [ + 'api' => [ + 'methodOverwrite' => $kirby->option('api.methodOverwrite', true) + ], 'debug' => $kirby->option('debug', false), 'kirbytext' => $kirby->option('panel.kirbytext', true), 'translation' => $kirby->option('panel.language', 'en'), diff --git a/public/kirby/src/Toolkit/Collection.php b/public/kirby/src/Toolkit/Collection.php index a57b981..7c9fa16 100644 --- a/public/kirby/src/Toolkit/Collection.php +++ b/public/kirby/src/Toolkit/Collection.php @@ -96,8 +96,6 @@ class Collection extends Iterator implements Countable * Low-level setter for elements * * @param string $key string or array - * @param mixed $value - * @return void */ public function __set(string $key, $value): void { diff --git a/public/kirby/src/Toolkit/Obj.php b/public/kirby/src/Toolkit/Obj.php index f8e312a..5aee969 100644 --- a/public/kirby/src/Toolkit/Obj.php +++ b/public/kirby/src/Toolkit/Obj.php @@ -102,4 +102,12 @@ class Obj extends stdClass { return json_encode($this->toArray(), ...$arguments); } + + /** + * Returns the property names as keys + */ + public function toKeys(): array + { + return array_keys((array)$this); + } } diff --git a/public/kirby/src/Toolkit/Str.php b/public/kirby/src/Toolkit/Str.php index a8f450f..73fdbf6 100644 --- a/public/kirby/src/Toolkit/Str.php +++ b/public/kirby/src/Toolkit/Str.php @@ -1132,7 +1132,7 @@ class Str string $string = null, string $separator = null, string $allowed = null, - int $maxlength = 128 + int|false $maxlength = 128 ): string { $separator ??= static::$defaults['slug']['separator']; $allowed ??= static::$defaults['slug']['allowed']; @@ -1165,7 +1165,11 @@ class Str $string = preg_replace('![^a-z0-9]+$!', '', $string); // cut the string after the given maxlength - return static::short($string, $maxlength, ''); + if ($maxlength !== false) { + $string = static::short($string, $maxlength, ''); + } + + return $string; } /** diff --git a/public/kirby/src/Uuid/FileUuid.php b/public/kirby/src/Uuid/FileUuid.php index 68dfe89..2bd2075 100644 --- a/public/kirby/src/Uuid/FileUuid.php +++ b/public/kirby/src/Uuid/FileUuid.php @@ -3,6 +3,7 @@ namespace Kirby\Uuid; use Generator; +use Kirby\Cms\App; use Kirby\Cms\File; /** @@ -83,4 +84,18 @@ class FileUuid extends ModelUuid 'filename' => $model->filename() ]; } + + /** + * Returns permalink url + */ + public function url(): string + { + // make sure UUID is cached because the permalink + // route only looks up UUIDs from cache + if ($this->isCached() === false) { + $this->populate(); + } + + return App::instance()->url() . '/@/' . static::TYPE . '/' . $this->id(); + } } diff --git a/public/kirby/src/Uuid/ModelUuid.php b/public/kirby/src/Uuid/ModelUuid.php index 43eb5f3..1bc3cca 100644 --- a/public/kirby/src/Uuid/ModelUuid.php +++ b/public/kirby/src/Uuid/ModelUuid.php @@ -2,8 +2,6 @@ namespace Kirby\Uuid; -use Kirby\Cms\App; - /** * Base for UUIDs for models where id string * is stored in the content, such as pages and files @@ -107,18 +105,4 @@ abstract class ModelUuid extends Uuid // use the most basic write method to avoid object cloning $this->model->writeContent($data, 'default'); } - - /** - * Returns permalink url - */ - public function url(): string - { - // make sure UUID is cached because the permalink - // route only looks up UUIDs from cache - if ($this->isCached() === false) { - $this->populate(); - } - - return App::instance()->url() . '/@/' . static::TYPE . '/' . $this->id(); - } } diff --git a/public/kirby/src/Uuid/PageUuid.php b/public/kirby/src/Uuid/PageUuid.php index 2ab8c29..c492338 100644 --- a/public/kirby/src/Uuid/PageUuid.php +++ b/public/kirby/src/Uuid/PageUuid.php @@ -54,4 +54,25 @@ class PageUuid extends ModelUuid yield from static::index($page); } } + + /** + * Returns permalink url + */ + public function url(): string + { + // make sure UUID is cached because the permalink + // route only looks up UUIDs from cache + if ($this->isCached() === false) { + $this->populate(); + } + + $kirby = App::instance(); + $url = $kirby->url(); + + if ($language = $kirby->language('current')) { + $url .= '/' . $language->code(); + } + + return $url . '/@/' . static::TYPE . '/' . $this->id(); + } } diff --git a/public/kirby/vendor/autoload.php b/public/kirby/vendor/autoload.php deleted file mode 100644 index 26273e0..0000000 --- a/public/kirby/vendor/autoload.php +++ /dev/null @@ -1,25 +0,0 @@ -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if ( - (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) - || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) - ) { - return include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint'); - } -} - -return include __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint'; diff --git a/public/kirby/vendor/christian-riesen/base32/LICENSE b/public/kirby/vendor/christian-riesen/base32/LICENSE deleted file mode 100644 index 624fceb..0000000 --- a/public/kirby/vendor/christian-riesen/base32/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2013-2014 Christian Riesen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/public/kirby/vendor/christian-riesen/base32/src/Base32.php b/public/kirby/vendor/christian-riesen/base32/src/Base32.php deleted file mode 100644 index d71f135..0000000 --- a/public/kirby/vendor/christian-riesen/base32/src/Base32.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @author Sam Williams[>=M, !=N,
getEnd()->getOperator() === '<' && $i+1 < $count) {
- $nextInterval = $intervals['numeric'][$i+1];
- if ($interval->getEnd()->getVersion() === $nextInterval->getStart()->getVersion() && $nextInterval->getStart()->getOperator() === '>') {
- // only add a start if we didn't already do so, can be skipped if we're looking at second
- // interval in [>=M, P, =M, !=N] already and we only want to add !=P right now
- if (\count($unEqualConstraints) === 0 && (string) $interval->getStart() !== (string) Interval::fromZero()) {
- $unEqualConstraints[] = $interval->getStart();
- }
- $unEqualConstraints[] = new Constraint('!=', $interval->getEnd()->getVersion());
- continue;
- }
- }
-
- if (\count($unEqualConstraints) > 0) {
- // this is where the end of the following interval of a != constraint is added as explained above
- if ((string) $interval->getEnd() !== (string) Interval::untilPositiveInfinity()) {
- $unEqualConstraints[] = $interval->getEnd();
- }
-
- // count is 1 if entire constraint is just one != expression
- if (\count($unEqualConstraints) > 1) {
- $constraints[] = new MultiConstraint($unEqualConstraints, true);
- } else {
- $constraints[] = $unEqualConstraints[0];
- }
-
- $unEqualConstraints = array();
- continue;
- }
-
- // convert back >= x - <= x intervals to == x
- if ($interval->getStart()->getVersion() === $interval->getEnd()->getVersion() && $interval->getStart()->getOperator() === '>=' && $interval->getEnd()->getOperator() === '<=') {
- $constraints[] = new Constraint('==', $interval->getStart()->getVersion());
- continue;
- }
-
- if ((string) $interval->getStart() === (string) Interval::fromZero()) {
- $constraints[] = $interval->getEnd();
- } elseif ((string) $interval->getEnd() === (string) Interval::untilPositiveInfinity()) {
- $constraints[] = $interval->getStart();
- } else {
- $constraints[] = new MultiConstraint(array($interval->getStart(), $interval->getEnd()), true);
- }
- }
- }
-
- $devConstraints = array();
-
- if (0 === \count($intervals['branches']['names'])) {
- if ($intervals['branches']['exclude']) {
- if ($hasNumericMatchAll) {
- return new MatchAllConstraint;
- }
- // otherwise constraint should contain a != operator and already cover this
- }
- } else {
- foreach ($intervals['branches']['names'] as $branchName) {
- if ($intervals['branches']['exclude']) {
- $devConstraints[] = new Constraint('!=', $branchName);
- } else {
- $devConstraints[] = new Constraint('==', $branchName);
- }
- }
-
- // excluded branches, e.g. != dev-foo are conjunctive with the interval, so
- // > 2.0 != dev-foo must return a conjunctive constraint
- if ($intervals['branches']['exclude']) {
- if (\count($constraints) > 1) {
- return new MultiConstraint(array_merge(
- array(new MultiConstraint($constraints, false)),
- $devConstraints
- ), true);
- }
-
- if (\count($constraints) === 1 && (string)$constraints[0] === (string)Interval::fromZero()) {
- if (\count($devConstraints) > 1) {
- return new MultiConstraint($devConstraints, true);
- }
- return $devConstraints[0];
- }
-
- return new MultiConstraint(array_merge($constraints, $devConstraints), true);
- }
-
- // otherwise devConstraints contains a list of == operators for branches which are disjunctive with the
- // rest of the constraint
- $constraints = array_merge($constraints, $devConstraints);
- }
-
- if (\count($constraints) > 1) {
- return new MultiConstraint($constraints, false);
- }
-
- if (\count($constraints) === 1) {
- return $constraints[0];
- }
-
- return new MatchNoneConstraint;
- }
-
- /**
- * Creates an array of numeric intervals and branch constraints representing a given constraint
- *
- * if the returned numeric array is empty it means the constraint matches nothing in the numeric range (0 - +inf)
- * if the returned branches array is empty it means no dev-* versions are matched
- * if a constraint matches all possible dev-* versions, branches will contain Interval::anyDev()
- *
- * @return array
- * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
- */
- public static function get(ConstraintInterface $constraint)
- {
- $key = (string) $constraint;
-
- if (!isset(self::$intervalsCache[$key])) {
- self::$intervalsCache[$key] = self::generateIntervals($constraint);
- }
-
- return self::$intervalsCache[$key];
- }
-
- /**
- * @param bool $stopOnFirstValidInterval
- *
- * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
- */
- private static function generateIntervals(ConstraintInterface $constraint, $stopOnFirstValidInterval = false)
- {
- if ($constraint instanceof MatchAllConstraint) {
- return array('numeric' => array(new Interval(Interval::fromZero(), Interval::untilPositiveInfinity())), 'branches' => Interval::anyDev());
- }
-
- if ($constraint instanceof MatchNoneConstraint) {
- return array('numeric' => array(), 'branches' => array('names' => array(), 'exclude' => false));
- }
-
- if ($constraint instanceof Constraint) {
- return self::generateSingleConstraintIntervals($constraint);
- }
-
- if (!$constraint instanceof MultiConstraint) {
- throw new \UnexpectedValueException('The constraint passed in should be an MatchAllConstraint, Constraint or MultiConstraint instance, got '.\get_class($constraint).'.');
- }
-
- $constraints = $constraint->getConstraints();
-
- $numericGroups = array();
- $constraintBranches = array();
- foreach ($constraints as $c) {
- $res = self::get($c);
- $numericGroups[] = $res['numeric'];
- $constraintBranches[] = $res['branches'];
- }
-
- if ($constraint->isDisjunctive()) {
- $branches = Interval::noDev();
- foreach ($constraintBranches as $b) {
- if ($b['exclude']) {
- if ($branches['exclude']) {
- // disjunctive constraint, so only exclude what's excluded in all constraints
- // !=a,!=b || !=b,!=c => !=b
- $branches['names'] = array_intersect($branches['names'], $b['names']);
- } else {
- // disjunctive constraint so exclude all names which are not explicitly included in the alternative
- // (==b || ==c) || !=a,!=b => !=a
- $branches['exclude'] = true;
- $branches['names'] = array_diff($b['names'], $branches['names']);
- }
- } else {
- if ($branches['exclude']) {
- // disjunctive constraint so exclude all names which are not explicitly included in the alternative
- // !=a,!=b || (==b || ==c) => !=a
- $branches['names'] = array_diff($branches['names'], $b['names']);
- } else {
- // disjunctive constraint, so just add all the other branches
- // (==a || ==b) || ==c => ==a || ==b || ==c
- $branches['names'] = array_merge($branches['names'], $b['names']);
- }
- }
- }
- } else {
- $branches = Interval::anyDev();
- foreach ($constraintBranches as $b) {
- if ($b['exclude']) {
- if ($branches['exclude']) {
- // conjunctive, so just add all branch names to be excluded
- // !=a && !=b => !=a,!=b
- $branches['names'] = array_merge($branches['names'], $b['names']);
- } else {
- // conjunctive, so only keep included names which are not excluded
- // (==a||==c) && !=a,!=b => ==c
- $branches['names'] = array_diff($branches['names'], $b['names']);
- }
- } else {
- if ($branches['exclude']) {
- // conjunctive, so only keep included names which are not excluded
- // !=a,!=b && (==a||==c) => ==c
- $branches['names'] = array_diff($b['names'], $branches['names']);
- $branches['exclude'] = false;
- } else {
- // conjunctive, so only keep names that are included in both
- // (==a||==b) && (==a||==c) => ==a
- $branches['names'] = array_intersect($branches['names'], $b['names']);
- }
- }
- }
- }
-
- $branches['names'] = array_unique($branches['names']);
-
- if (\count($numericGroups) === 1) {
- return array('numeric' => $numericGroups[0], 'branches' => $branches);
- }
-
- $borders = array();
- foreach ($numericGroups as $group) {
- foreach ($group as $interval) {
- $borders[] = array('version' => $interval->getStart()->getVersion(), 'operator' => $interval->getStart()->getOperator(), 'side' => 'start');
- $borders[] = array('version' => $interval->getEnd()->getVersion(), 'operator' => $interval->getEnd()->getOperator(), 'side' => 'end');
- }
- }
-
- $opSortOrder = self::$opSortOrder;
- usort($borders, function ($a, $b) use ($opSortOrder) {
- $order = version_compare($a['version'], $b['version']);
- if ($order === 0) {
- return $opSortOrder[$a['operator']] - $opSortOrder[$b['operator']];
- }
-
- return $order;
- });
-
- $activeIntervals = 0;
- $intervals = array();
- $index = 0;
- $activationThreshold = $constraint->isConjunctive() ? \count($numericGroups) : 1;
- $start = null;
- foreach ($borders as $border) {
- if ($border['side'] === 'start') {
- $activeIntervals++;
- } else {
- $activeIntervals--;
- }
- if (!$start && $activeIntervals >= $activationThreshold) {
- $start = new Constraint($border['operator'], $border['version']);
- } elseif ($start && $activeIntervals < $activationThreshold) {
- // filter out invalid intervals like > x - <= x, or >= x - < x
- if (
- version_compare($start->getVersion(), $border['version'], '=')
- && (
- ($start->getOperator() === '>' && $border['operator'] === '<=')
- || ($start->getOperator() === '>=' && $border['operator'] === '<')
- )
- ) {
- unset($intervals[$index]);
- } else {
- $intervals[$index] = new Interval($start, new Constraint($border['operator'], $border['version']));
- $index++;
-
- if ($stopOnFirstValidInterval) {
- break;
- }
- }
-
- $start = null;
- }
- }
-
- return array('numeric' => $intervals, 'branches' => $branches);
- }
-
- /**
- * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
- */
- private static function generateSingleConstraintIntervals(Constraint $constraint)
- {
- $op = $constraint->getOperator();
-
- // handle branch constraints first
- if (strpos($constraint->getVersion(), 'dev-') === 0) {
- $intervals = array();
- $branches = array('names' => array(), 'exclude' => false);
-
- // != dev-foo means any numeric version may match, we treat >/< like != they are not really defined for branches
- if ($op === '!=') {
- $intervals[] = new Interval(Interval::fromZero(), Interval::untilPositiveInfinity());
- $branches = array('names' => array($constraint->getVersion()), 'exclude' => true);
- } elseif ($op === '==') {
- $branches['names'][] = $constraint->getVersion();
- }
-
- return array(
- 'numeric' => $intervals,
- 'branches' => $branches,
- );
- }
-
- if ($op[0] === '>') { // > & >=
- return array('numeric' => array(new Interval($constraint, Interval::untilPositiveInfinity())), 'branches' => Interval::noDev());
- }
- if ($op[0] === '<') { // < & <=
- return array('numeric' => array(new Interval(Interval::fromZero(), $constraint)), 'branches' => Interval::noDev());
- }
- if ($op === '!=') {
- // convert !=x to intervals of 0 -
",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e}()?parseInt:parseFloat)(getComputedStyle(o).lineHeight),p=Prism.util.isActive(o,t),g=o.querySelector("code"),m=p?o:g||o,v=[],y=g.textContent.match(n),b=y?y.length+1:1,A=g&&m!=g?function(e,t){var i=getComputedStyle(e),n=getComputedStyle(t);function r(e){return+e.substr(0,e.length-2)}return t.offsetTop+r(n.borderTopWidth)+r(n.paddingTop)-r(i.paddingTop)}(o,g):0;h.forEach((function(e){var t=e.split("-"),i=+t[0],n=+t[1]||i;if(!((n=Math.min(b+d,n))i&&r.setAttribute("data-end",String(n)),r.style.top=(i-d-1)*f+A+"px",r.textContent=new Array(n-i+2).join(" \n")}));v.push((function(){r.style.width=o.scrollWidth+"px"})),v.push((function(){m.appendChild(r)}))}}));var P=o.id;if(p&&Prism.util.isActive(o,i)&&P){l(o,i)||v.push((function(){o.classList.add(i)}));var E=parseInt(o.getAttribute("data-start")||"1");s(".line-numbers-rows > span",o).forEach((function(e,t){var i=t+E;e.onclick=function(){var e=P+"."+i;r=!1,location.hash=e,setTimeout((function(){r=!0}),1)}}))}return function(){v.forEach(a)}}};var o=0;Prism.hooks.add("before-sanity-check",(function(e){var t=e.element.parentElement;if(u(t)){var i=0;s(".line-highlight",t).forEach((function(e){i+=e.textContent.length,e.parentNode.removeChild(e)})),i&&/^(?: \n)+$/.test(e.code.slice(-i))&&(e.code=e.code.slice(0,-i))}})),Prism.hooks.add("complete",(function e(i){var n=i.element.parentElement;if(u(n)){clearTimeout(o);var r=Prism.plugins.lineNumbers,s=i.plugins&&i.plugins.lineNumbers;l(n,t)&&r&&!s?Prism.hooks.add("line-numbers",e):(Prism.plugins.lineHighlight.highlightLines(n)(),o=setTimeout(c,1))}})),window.addEventListener("hashchange",c),window.addEventListener("resize",(function(){s("pre").filter(u).map((function(e){return Prism.plugins.lineHighlight.highlightLines(e)})).forEach(a)}))}function s(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function l(e,t){return e.classList.contains(t)}function a(e){e()}function u(e){return!!(e&&/pre/i.test(e.nodeName)&&(e.hasAttribute("data-line")||e.id&&Prism.util.isActive(e,i)))}function c(){var e=location.hash.slice(1);s(".temporary.line-highlight").forEach((function(e){e.parentNode.removeChild(e)}));var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var i=e.slice(0,e.lastIndexOf(".")),n=document.getElementById(i);n&&(n.hasAttribute("data-line")||n.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(n,t,"temporary ")(),r&&document.querySelector(".temporary.line-highlight").scrollIntoView())}}}();
-!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){var e="line-numbers",n=/\n(?!$)/g,t=Prism.plugins.lineNumbers={getLine:function(n,t){if("PRE"===n.tagName&&n.classList.contains(e)){var i=n.querySelector(".line-numbers-rows");if(i){var r=parseInt(n.getAttribute("data-start"),10)||1,s=r+(i.children.length-1);t