Upgrade to 4.2.0

This commit is contained in:
Bastian Allgeier
2024-04-10 11:09:52 +02:00
parent 77d9337371
commit 7f4eb7509d
88 changed files with 1187 additions and 490 deletions

View File

@@ -1,7 +1,7 @@
##
## Bundle of CA Root Certificates
##
## Certificate data from Mozilla as of: Tue Dec 12 04:12:04 2023 GMT
## Certificate data from Mozilla as of: Mon Mar 11 15:25:27 2024 GMT
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,7 +14,7 @@
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.29.
## SHA256: 1970dd65858925d68498d2356aea6d03f764422523c5887deca8ce3ba9e1f845
## SHA256: 4d96bd539f4719e9ace493757afbe4a23ee8579de1c97fbebc50bba3c12e8c1e
##
@@ -3532,3 +3532,50 @@ dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ
iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN
lM47ni3niAIi9G7oyOzWPPO5std3eqx7
-----END CERTIFICATE-----
Telekom Security TLS ECC Root 2020
==================================
-----BEGIN CERTIFICATE-----
MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE
RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl
a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz
NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg
R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG
SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1
2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC
MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ
Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU
ga/sf+Rn27iQ7t0l
-----END CERTIFICATE-----
Telekom Security TLS RSA Root 2023
==================================
-----BEGIN CERTIFICATE-----
MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG
EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU
ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy
NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp
dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC
KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP
GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx
UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo
l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9
FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v
zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg
rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML
KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S
WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV
HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+
sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp
kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy
/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4
mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz
aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa
oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8
wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE
HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0
o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
-----END CERTIFICATE-----

View File

@@ -3,7 +3,7 @@
"description": "The Kirby core",
"license": "proprietary",
"type": "kirby-cms",
"version": "4.1.2",
"version": "4.2.0",
"keywords": [
"kirby",
"cms",
@@ -37,16 +37,16 @@
"ext-mbstring": "*",
"ext-openssl": "*",
"christian-riesen/base32": "1.6.0",
"claviska/simpleimage": "4.0.6",
"claviska/simpleimage": "4.1.0",
"composer/semver": "3.4.0",
"filp/whoops": "2.15.4",
"getkirby/composer-installer": "^1.2.1",
"laminas/laminas-escaper": "2.13.0",
"michelf/php-smartypants": "1.8.1",
"phpmailer/phpmailer": "6.9.1",
"symfony/polyfill-intl-idn": "1.28.0",
"symfony/polyfill-mbstring": "1.28.0",
"symfony/yaml": "6.4.0"
"symfony/polyfill-intl-idn": "1.29.0",
"symfony/polyfill-mbstring": "1.29.0",
"symfony/yaml": "6.4.3"
},
"replace": {
"symfony/polyfill-php72": "*"

86
kirby/composer.lock generated
View File

@@ -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": "91cceb6b0d22bbcb152456ab27e0fdbb",
"content-hash": "43b28f916503f0f7a7fcfaf5ce174692",
"packages": [
{
"name": "christian-riesen/base32",
@@ -67,16 +67,16 @@
},
{
"name": "claviska/simpleimage",
"version": "4.0.6",
"version": "4.1.0",
"source": {
"type": "git",
"url": "https://github.com/claviska/SimpleImage.git",
"reference": "969de5e61810ef91f6f83c475b192c4841367dfa"
"reference": "1dcb9c785c44960890970d26e25c437a2a252bbf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/969de5e61810ef91f6f83c475b192c4841367dfa",
"reference": "969de5e61810ef91f6f83c475b192c4841367dfa",
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/1dcb9c785c44960890970d26e25c437a2a252bbf",
"reference": "1dcb9c785c44960890970d26e25c437a2a252bbf",
"shasum": ""
},
"require": {
@@ -108,7 +108,7 @@
"description": "A PHP class that makes working with images as simple as possible.",
"support": {
"issues": "https://github.com/claviska/SimpleImage/issues",
"source": "https://github.com/claviska/SimpleImage/tree/4.0.6"
"source": "https://github.com/claviska/SimpleImage/tree/4.1.0"
},
"funding": [
{
@@ -116,7 +116,7 @@
"type": "github"
}
],
"time": "2023-07-27T16:48:12+00:00"
"time": "2024-03-04T15:41:11+00:00"
},
{
"name": "composer/semver",
@@ -694,16 +694,16 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": ""
},
"require": {
@@ -717,9 +717,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -756,7 +753,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
},
"funding": [
{
@@ -772,20 +769,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d"
"reference": "a287ed7475f85bf6f61890146edbc932c0fff919"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d",
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919",
"reference": "a287ed7475f85bf6f61890146edbc932c0fff919",
"shasum": ""
},
"require": {
@@ -798,9 +795,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -843,7 +837,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0"
},
"funding": [
{
@@ -859,20 +853,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:30:37+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"shasum": ""
},
"require": {
@@ -883,9 +877,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -927,7 +918,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
},
"funding": [
{
@@ -943,20 +934,20 @@
"type": "tidelift"
}
],
"time": "2023-01-26T09:26:14+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.28.0",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "42292d99c55abe617799667f454222c54c60e229"
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "42292d99c55abe617799667f454222c54c60e229",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": ""
},
"require": {
@@ -970,9 +961,6 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1010,7 +998,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
},
"funding": [
{
@@ -1026,20 +1014,20 @@
"type": "tidelift"
}
],
"time": "2023-07-28T09:04:16+00:00"
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/yaml",
"version": "v6.4.0",
"version": "v6.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "4f9237a1bb42455d609e6687d2613dde5b41a587"
"reference": "d75715985f0f94f978e3a8fa42533e10db921b90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587",
"reference": "4f9237a1bb42455d609e6687d2613dde5b41a587",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d75715985f0f94f978e3a8fa42533e10db921b90",
"reference": "d75715985f0f94f978e3a8fa42533e10db921b90",
"shasum": ""
},
"require": {
@@ -1082,7 +1070,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v6.4.0"
"source": "https://github.com/symfony/yaml/tree/v6.4.3"
},
"funding": [
{
@@ -1098,7 +1086,7 @@
"type": "tidelift"
}
],
"time": "2023-11-06T11:00:25+00:00"
"time": "2024-01-23T14:51:35+00:00"
}
],
"packages-dev": [],

View File

@@ -8,7 +8,15 @@ $parentPattern = '(account|pages/[^/]+|site|users/[^/]+)/files';
* Files Routes
*/
return [
[
'pattern' => $filePattern . '/fields/(:any)/(:all?)',
'method' => 'ALL',
'action' => function (string $parent, string $filename, string $fieldName, string|null $path = null) {
if ($file = $this->file($parent, $filename)) {
return $this->fieldApi($file, $fieldName, $path);
}
}
],
[
'pattern' => $filePattern . '/sections/(:any)',
'method' => 'GET',
@@ -17,11 +25,11 @@ return [
}
],
[
'pattern' => $filePattern . '/fields/(:any)/(:all?)',
'pattern' => $filePattern . '/sections/(:any)/(:all?)',
'method' => 'ALL',
'action' => function (string $parent, string $filename, string $fieldName, string $path = null) {
'action' => function (string $parent, string $filename, string $sectionName, string|null $path = null) {
if ($file = $this->file($parent, $filename)) {
return $this->fieldApi($file, $fieldName, $path);
return $this->sectionApi($file, $sectionName, $path);
}
}
],

View File

@@ -4,9 +4,8 @@
/**
* Page Routes
*/
return [
// @codeCoverageIgnoreStart
[
'pattern' => 'pages/(:any)',
'method' => 'GET',
@@ -101,6 +100,15 @@ return [
return $this->page($id)->changeTitle($this->requestBody('title'));
}
],
[
'pattern' => 'pages/(:any)/fields/(:any)/(:all?)',
'method' => 'ALL',
'action' => function (string $id, string $fieldName, string|null $path = null) {
if ($page = $this->page($id)) {
return $this->fieldApi($page, $fieldName, $path);
}
}
],
[
'pattern' => 'pages/(:any)/sections/(:any)',
'method' => 'GET',
@@ -109,12 +117,13 @@ return [
}
],
[
'pattern' => 'pages/(:any)/fields/(:any)/(:all?)',
'pattern' => 'pages/(:any)/sections/(:any)/(:all?)',
'method' => 'ALL',
'action' => function (string $id, string $fieldName, string $path = null) {
'action' => function (string $id, string $sectionName, string|null $path = null) {
if ($page = $this->page($id)) {
return $this->fieldApi($page, $fieldName, $path);
return $this->sectionApi($page, $sectionName, $path);
}
}
],
// @codeCoverageIgnoreEnd
];

View File

@@ -5,7 +5,7 @@
* Site Routes
*/
return [
// @codeCoverageIgnoreStart
[
'pattern' => 'site',
'action' => function () {
@@ -84,6 +84,13 @@ return [
return $pages->query($this->requestBody());
}
],
[
'pattern' => 'site/fields/(:any)/(:all?)',
'method' => 'ALL',
'action' => function (string $fieldName, string|null $path = null) {
return $this->fieldApi($this->site(), $fieldName, $path);
}
],
[
'pattern' => 'site/sections/(:any)',
'method' => 'GET',
@@ -92,11 +99,11 @@ return [
}
],
[
'pattern' => 'site/fields/(:any)/(:all?)',
'pattern' => 'site/sections/(:any)/(:all?)',
'method' => 'ALL',
'action' => function (string $fieldName, string $path = null) {
return $this->fieldApi($this->site(), $fieldName, $path);
'action' => function (string $sectionName, string|null $path = null) {
return $this->sectionApi($this->site(), $sectionName, $path);
}
]
],
// @codeCoverageIgnoreEnd
];

View File

@@ -8,6 +8,7 @@ use Kirby\Toolkit\Str;
* User Routes
*/
return [
// @codeCoverageIgnoreStart
[
'pattern' => 'users',
'method' => 'GET',
@@ -205,6 +206,16 @@ return [
return $this->user($id)->roles();
}
],
[
'pattern' => [
'(account)/fields/(:any)/(:all?)',
'users/(:any)/fields/(:any)/(:all?)',
],
'method' => 'ALL',
'action' => function (string $id, string $fieldName, string|null $path = null) {
return $this->fieldApi($this->user($id), $fieldName, $path);
}
],
[
'pattern' => [
'(account)/sections/(:any)',
@@ -219,12 +230,13 @@ return [
],
[
'pattern' => [
'(account)/fields/(:any)/(:all?)',
'users/(:any)/fields/(:any)/(:all?)',
'(account)/sections/(:any)/(:all?)',
'users/(:any)/sections/(:any)/(:all?)',
],
'method' => 'ALL',
'action' => function (string $id, string $fieldName, string $path = null) {
return $this->fieldApi($this->user($id), $fieldName, $path);
'action' => function (string $id, string $sectionName, string|null $path = null) {
return $this->sectionApi($this->user($id), $sectionName, $path);
}
],
// @codeCoverageIgnoreEnd
];

View File

@@ -109,6 +109,16 @@ return [
$props = $example->props();
$vue = $example->vue();
if (Docs::installed() === true && $docs = $props['docs'] ?? null) {
$docs = new Docs($docs);
}
$github = $docs?->github();
if ($source = $props['source'] ?? null) {
$github ??= 'https://github.com/getkirby/kirby/tree/main/' . $source;
}
return [
'component' => 'k-lab-playground-view',
'breadcrumb' => [
@@ -121,10 +131,10 @@ return [
]
],
'props' => [
'docs' => $props['docs'] ?? null,
'docs' => $docs?->name(),
'examples' => $vue['examples'],
'file' => $example->module(),
'github' => $example->github(),
'github' => $github,
'props' => $props,
'styles' => $vue['style'],
'tab' => $example->tab(),

View File

@@ -2,12 +2,30 @@
use Kirby\Cms\Html;
/** @var \Kirby\Cms\Block $block */
$caption = $block->caption();
if (
$block->location() == 'kirby' &&
$video = $block->video()->toFile()
) {
$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(),
]);
} else {
$url = $block->url();
}
?>
<?php if ($video = Html::video($block->url())): ?>
<?php if ($video = Html::video($url, [], $attrs ?? [])): ?>
<figure>
<?= $video ?>
<?php if ($block->caption()->isNotEmpty()): ?>
<figcaption><?= $block->caption() ?></figcaption>
<?php if ($caption->isNotEmpty()): ?>
<figcaption><?= $caption ?></figcaption>
<?php endif ?>
</figure>
<?php endif ?>

View File

@@ -2,11 +2,77 @@ name: field.blocks.video.name
icon: video
preview: video
fields:
location:
label: field.blocks.video.location
type: radio
columns: 2
default: "web"
options:
kirby: "{{ t('field.blocks.image.location.internal') }}"
web: "{{ t('field.blocks.image.location.external') }}"
url:
label: field.blocks.video.url.label
type: url
placeholder: field.blocks.video.url.placeholder
when:
location: web
video:
label: field.blocks.video.name
type: files
query: model.videos
multiple: false
# you might want to add a template for videos here
when:
location: kirby
poster:
label: field.blocks.video.poster
type: files
query: model.images
multiple: false
image:
back: black
uploads:
template: blocks/image
when:
location: kirby
caption:
label: field.blocks.video.caption
type: writer
inline: true
autoplay:
label: field.blocks.video.autoplay
type: toggle
width: 1/3
when:
location: kirby
muted:
label: field.blocks.video.muted
type: toggle
width: 1/3
default: true
when:
location: kirby
loop:
label: field.blocks.video.loop
type: toggle
width: 1/3
when:
location: kirby
controls:
label: field.blocks.video.controls
type: toggle
width: 1/3
default: true
when:
location: kirby
preload:
label: field.blocks.video.preload
type: select
width: 2/3
default: auto
options:
- auto
- metadata
- none
when:
location: kirby

View File

@@ -39,7 +39,7 @@ return [
'template' => $template
]);
$uploads['accept'] = $file->blueprint()->acceptMime();
$uploads['accept'] = $file->blueprint()->acceptAttribute();
}
return $uploads;

View File

@@ -1,5 +1,7 @@
<?php
use Kirby\Toolkit\I18n;
return [
'extends' => 'number',
'props' => [
@@ -18,6 +20,13 @@ return [
* Enables/disables the tooltip and set the before and after values
*/
'tooltip' => function ($tooltip = true) {
if (is_array($tooltip) === true) {
$after = $tooltip['after'] ?? null;
$before = $tooltip['before'] ?? null;
$tooltip['after'] = I18n::translate($after, $after);
$tooltip['before'] = I18n::translate($before, $before);
}
return $tooltip;
},
]

View File

@@ -47,7 +47,7 @@ return [
'template' => $this->template
]);
return $file->blueprint()->acceptMime();
return $file->blueprint()->acceptAttribute();
}
return null;
@@ -205,13 +205,31 @@ return [
];
}
],
// @codeCoverageIgnoreStart
'api' => function () {
return [
[
'pattern' => 'sort',
'method' => 'PATCH',
'action' => function () {
$this->section()->model()->files()->changeSort(
$this->requestBody('files'),
$this->requestBody('index')
);
return true;
}
]
];
},
// @codeCoverageIgnoreEnd
'toArray' => function () {
return [
'data' => $this->data,
'errors' => $this->errors,
'options' => [
'accept' => $this->accept,
'apiUrl' => $this->parent->apiUrl(true),
'apiUrl' => $this->parent->apiUrl(true) . '/sections/' . $this->name,
'columns' => $this->columnsWithTypes(),
'empty' => $this->empty,
'headline' => $this->headline,

View File

@@ -1,6 +1,7 @@
<?php
use Kirby\Cms\ModelWithContent;
use Kirby\Form\Form;
use Kirby\Toolkit\I18n;
use Kirby\Toolkit\Str;
@@ -77,9 +78,12 @@ return [
// keep the original column name as id
$column['id'] = $columnName;
// add the custom column to the array with a key that won't
// override the system columns
$columns[$columnName . 'Cell'] = $column;
// add the custom column to the array
// allowing to extend/overwrite existing columns
$columns[$columnName] = [
...$columns[$columnName] ?? [],
...$column
];
}
if ($this->type === 'pages') {
@@ -129,19 +133,20 @@ return [
$item['info'] = $model->toString($this->info);
}
// Use form to get the proper values for the columns
$form = Form::for($model)->values();
foreach ($this->columns as $columnName => $column) {
// don't overwrite essential columns
if (isset($item[$columnName]) === true) {
continue;
}
if (empty($column['value']) === false) {
$value = $model->toString($column['value']);
} else {
$value = $model->content()->get($column['id'] ?? $columnName)->value();
}
$item[$columnName] = $value;
$item[$columnName] = match (empty($column['value'])) {
// if column value defined, resolve the query
false => $model->toString($column['value']),
// otherwise use the form value,
// but don't overwrite columns
default =>
$item[$columnName] ??
$form[$column['id'] ?? $columnName] ??
null,
};
}
return $item;

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "by …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Caption",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Location",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Enter a video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "by …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Caption",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Location",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Enter a video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "od …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Titulek",
"field.blocks.video.controls": "Ovládání",
"field.blocks.video.location": "Umístění",
"field.blocks.video.loop": "Smyčka",
"field.blocks.video.muted": "Ztlumené",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Zadejte URL adresu videa",
"field.blocks.video.poster": "Náhledový obrázek",
"field.blocks.video.preload": "Předběžně načíst",
"field.blocks.video.url.label": "URL adresa videa",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "af …",
"field.blocks.text.name": "Tekst",
"field.blocks.text.placeholder": "Tekst …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Billedtekst",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Placering",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Indtast URL til en video",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "Quelle …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Bildunterschrift",
"field.blocks.video.controls": "Steuerung",
"field.blocks.video.location": "Ort",
"field.blocks.video.loop": "Schleife",
"field.blocks.video.muted": "Stumm",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Video-URL eingeben",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Vorladen",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "by …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Caption",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Location",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Enter a video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "by …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Caption",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Location",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Enter a video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "de ...",
"field.blocks.text.name": "Teksto",
"field.blocks.text.placeholder": "Teksto ...",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Apudskribo",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Loko",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Videâjo",
"field.blocks.video.placeholder": "Entajpi URL de videaĵo",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "Por ...",
"field.blocks.text.name": "Texto",
"field.blocks.text.placeholder": "Texto ...",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Leyenda",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Ubicación",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Introduce la URL de un vídeo",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Vídeo-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "Por ...",
"field.blocks.text.name": "Texto",
"field.blocks.text.placeholder": "Texto ...",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Leyenda",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Ubicación",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Introduce la URL de un vídeo",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Vídeo-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "by …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Caption",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Location",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Enter a video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "Lähde …",
"field.blocks.text.name": "Teksti",
"field.blocks.text.placeholder": "Teksti …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Videon teksti",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Sijainti",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Anna videon URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Videon URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "par…",
"field.blocks.text.name": "Texte",
"field.blocks.text.placeholder": "Texte…",
"field.blocks.video.autoplay": "Lecture automatique",
"field.blocks.video.caption": "Légende",
"field.blocks.video.controls": "Contrôles",
"field.blocks.video.location": "Emplacement",
"field.blocks.video.loop": "Boucle",
"field.blocks.video.muted": "Muet",
"field.blocks.video.name": "Vidéo",
"field.blocks.video.placeholder": "Saisissez lURL dune vidéo",
"field.blocks.video.poster": "Vignette",
"field.blocks.video.preload": "Préchargement",
"field.blocks.video.url.label": "URL de la vidéo",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "Szerző …",
"field.blocks.text.name": "Szöveg",
"field.blocks.text.placeholder": "Szöveg …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Képaláírás",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "A kép helye",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Videó",
"field.blocks.video.placeholder": "Videó URL-jének megadása",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Videó URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "oleh …",
"field.blocks.text.name": "Teks",
"field.blocks.text.placeholder": "Teks …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Deskripsi",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Lokasi",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Masukkan URL video",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "URL Video",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "eftir …",
"field.blocks.text.name": "Prósi",
"field.blocks.text.placeholder": "Þessi prósi …",
"field.blocks.video.autoplay": "Sjálfspila",
"field.blocks.video.caption": "Myndskeiðstexti",
"field.blocks.video.controls": "Stjórnhnappar",
"field.blocks.video.location": "Staðsetning",
"field.blocks.video.loop": "Lykkja",
"field.blocks.video.muted": "Þaggað",
"field.blocks.video.name": "Myndskeið",
"field.blocks.video.placeholder": "Vefslóð myndskeiðs (URL)",
"field.blocks.video.poster": "Plakkat",
"field.blocks.video.preload": "Forhlaða",
"field.blocks.video.url.label": "Vefslóð",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "di …",
"field.blocks.text.name": "Testo",
"field.blocks.text.placeholder": "Testo …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Didascalia",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Posizione",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Inserisci un URL di un video",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "URL Video",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "출처",
"field.blocks.text.name": "텍스트",
"field.blocks.text.placeholder": "텍스트",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "캡션",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "위치",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "영상",
"field.blocks.video.placeholder": "영상 URL 입력",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "영상 URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "autorius",
"field.blocks.text.name": "Tekstas",
"field.blocks.text.placeholder": "Tekstas ...",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Aprašymas",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Šaltinis",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Įrašykite video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "av…",
"field.blocks.text.name": "Tekst",
"field.blocks.text.placeholder": "Tekst…",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Caption",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Plassering",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Legg til en video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "door ...",
"field.blocks.text.name": "Tekst",
"field.blocks.text.placeholder": "Tekst ...",
"field.blocks.video.autoplay": "Automatisch afspelen",
"field.blocks.video.caption": "Beschrijving",
"field.blocks.video.controls": "Besturingselementen",
"field.blocks.video.location": "Locatie",
"field.blocks.video.loop": "Herhalen",
"field.blocks.video.muted": "Gedempt",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Voer een video link in",
"field.blocks.video.poster": "Afbeelding",
"field.blocks.video.preload": "Vooral laden",
"field.blocks.video.url.label": "Video link",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "autorstwa …",
"field.blocks.text.name": "Tekst",
"field.blocks.text.placeholder": "Tekst …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Podpis",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Lokalizacja",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Wprowadź URL video",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "URL video",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "de …",
"field.blocks.text.name": "Texto",
"field.blocks.text.placeholder": "Texto …",
"field.blocks.video.autoplay": "Reprodução automática",
"field.blocks.video.caption": "Legenda",
"field.blocks.video.controls": "Controlos",
"field.blocks.video.location": "Localização ",
"field.blocks.video.loop": "Repetir",
"field.blocks.video.muted": "Sem som",
"field.blocks.video.name": "Vídeo ",
"field.blocks.video.placeholder": "Entre uma URL de vídeo ",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Pré-carregamento",
"field.blocks.video.url.label": "URL-Vídeo",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "de …",
"field.blocks.text.name": "Texto",
"field.blocks.text.placeholder": "Texto …",
"field.blocks.video.autoplay": "Reprodução automática",
"field.blocks.video.caption": "Legenda",
"field.blocks.video.controls": "Controlos",
"field.blocks.video.location": "Localização ",
"field.blocks.video.loop": "Repetir",
"field.blocks.video.muted": "Sem som",
"field.blocks.video.name": "Vídeo ",
"field.blocks.video.placeholder": "Insira um URL de vídeo ",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Pré-carregamento",
"field.blocks.video.url.label": "URL-Vídeo",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "de …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Etichetă",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Localizare",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Introdu URL-ul video-ului",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "URL-ul video-ului",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -71,7 +71,7 @@
"error": "Ошибка",
"error.access.code": "Неверный код",
"error.access.login": "Неправильный логин",
"error.access.login": "Неверный логин или пароль",
"error.access.panel": "У вас нет права доступа к панели",
"error.access.view": "У вас нет прав доступа к этой части панели",
@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "Автор …",
"field.blocks.text.name": "Текст",
"field.blocks.text.placeholder": "Текст …",
"field.blocks.video.autoplay": "Автовоспроизведение",
"field.blocks.video.caption": "Подпись",
"field.blocks.video.controls": "Элементы управления",
"field.blocks.video.location": "Расположение",
"field.blocks.video.loop": "Зациклить",
"field.blocks.video.muted": "Без звука",
"field.blocks.video.name": "Видео",
"field.blocks.video.placeholder": "Введите ссылку на видео",
"field.blocks.video.poster": "Обложка",
"field.blocks.video.preload": "Предзагрузка",
"field.blocks.video.url.label": "Ссылка на видео",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",
@@ -447,7 +454,7 @@
"lock.unsaved": "Несохраненные изменения",
"lock.unsaved.empty": "Несохраненных изменений нет",
"lock.isLocked": "Несохраненные изменения <strong>{email}</strong>",
"lock.isLocked": "Несохраненные изменения {email}",
"lock.unlock": "Разблокировать",
"lock.unlock.submit": "Разблокируйте и перезапишите несохраненные изменения <strong>{email}</strong>",
"lock.isUnlocked": "Были перезаписаны другим пользователем",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "by …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Popis",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Poloha",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Enter a video URL",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "av …",
"field.blocks.text.name": "Text",
"field.blocks.text.placeholder": "Text …",
"field.blocks.video.autoplay": "Autoplay",
"field.blocks.video.caption": "Rubrik",
"field.blocks.video.controls": "Controls",
"field.blocks.video.location": "Plats",
"field.blocks.video.loop": "Loop",
"field.blocks.video.muted": "Muted",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Ange en URL till en video",
"field.blocks.video.poster": "Poster",
"field.blocks.video.preload": "Preload",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

View File

@@ -317,9 +317,16 @@
"field.blocks.quote.citation.placeholder": "yazar …",
"field.blocks.text.name": "Metin",
"field.blocks.text.placeholder": "Metin …",
"field.blocks.video.autoplay": "Otomatik oynatma",
"field.blocks.video.caption": "Altyazı",
"field.blocks.video.controls": "Kontroller",
"field.blocks.video.location": "Lokasyon",
"field.blocks.video.loop": "Döngü",
"field.blocks.video.muted": "Sessiz",
"field.blocks.video.name": "Video",
"field.blocks.video.placeholder": "Bir video URL'si girin",
"field.blocks.video.poster": "Kapak",
"field.blocks.video.preload": "Önyükleme",
"field.blocks.video.url.label": "Video-URL",
"field.blocks.video.url.placeholder": "https://youtube.com/?v=",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

BIN
kirby/panel/dist/favicon-dark.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

View File

@@ -86,7 +86,7 @@
<path d="M4.00488 16V4H2.00488V2H5.00488C5.55717 2 6.00488 2.44772 6.00488 3V15H18.4433L20.4433 7H8.00488V5H21.7241C22.2764 5 22.7241 5.44772 22.7241 6C22.7241 6.08176 22.7141 6.16322 22.6942 6.24254L20.1942 16.2425C20.083 16.6877 19.683 17 19.2241 17H5.00488C4.4526 17 4.00488 16.5523 4.00488 16ZM6.00488 23C4.90031 23 4.00488 22.1046 4.00488 21C4.00488 19.8954 4.90031 19 6.00488 19C7.10945 19 8.00488 19.8954 8.00488 21C8.00488 22.1046 7.10945 23 6.00488 23ZM18.0049 23C16.9003 23 16.0049 22.1046 16.0049 21C16.0049 19.8954 16.9003 19 18.0049 19C19.1095 19 20.0049 19.8954 20.0049 21C20.0049 22.1046 19.1095 23 18.0049 23Z"/>
</symbol>
<symbol id="icon-chart" viewBox="0 0 24 24">
<path d="M3 12H7V21H3V12ZM17 8H21V21H17V8ZM10 2H14V21H10V2Z"/>
<path d="M2 9H4V21H2V9ZM8 3H10V21H8V3ZM14 12H16V21H14V12ZM20 6H22V21H20V6Z" />
</symbol>
<symbol id="icon-chat" viewBox="0 0 24 24">
<path d="M5.45455 15L1 18.5V3C1 2.44772 1.44772 2 2 2H17C17.5523 2 18 2.44772 18 3V15H5.45455ZM4.76282 13H16V4H3V14.3851L4.76282 13ZM8 17H18.2372L20 18.3851V8H21C21.5523 8 22 8.44772 22 9V22.5L17.5455 19H9C8.44772 19 8 18.5523 8 18V17Z"/>
@@ -126,8 +126,7 @@
<path d="M2.21329 14.0601C1.92026 12.6755 1.93213 11.2743 2.21413 9.94038C3.32405 10.0711 4.29284 9.7035 4.60963 8.93871C4.92641 8.17392 4.50129 7.22896 3.62405 6.53655C4.36788 5.3939 5.35029 4.39471 6.53651 3.62289C7.22898 4.50059 8.17422 4.92601 8.9392 4.60914C9.70418 4.29227 10.0717 3.32308 9.94077 2.21281C11.3253 1.91977 12.7265 1.93164 14.0605 2.21364C13.9298 3.32356 14.2973 4.29235 15.0621 4.60914C15.8269 4.92593 16.7719 4.5008 17.4643 3.62356C18.6069 4.36739 19.6061 5.3498 20.3779 6.53602C19.5002 7.22849 19.0748 8.17373 19.3917 8.93871C19.7086 9.70369 20.6778 10.0713 21.788 9.94028C22.0811 11.3248 22.0692 12.726 21.7872 14.06C20.6773 13.9293 19.7085 14.2969 19.3917 15.0616C19.0749 15.8264 19.5 16.7714 20.3773 17.4638C19.6335 18.6064 18.651 19.6056 17.4648 20.3775C16.7724 19.4998 15.8271 19.0743 15.0621 19.3912C14.2971 19.7081 13.9296 20.6773 14.0606 21.7875C12.676 22.0806 11.2748 22.0687 9.94087 21.7867C10.0716 20.6768 9.70399 19.708 8.9392 19.3912C8.17441 19.0744 7.22945 19.4995 6.53703 20.3768C5.39439 19.633 4.3952 18.6506 3.62338 17.4643C4.50108 16.7719 4.92649 15.8266 4.60963 15.0616C4.29276 14.2967 3.32356 13.9291 2.21329 14.0601ZM4.00073 12.2104C5.10054 12.5148 6.00815 13.2117 6.45739 14.2963C6.90662 15.3808 6.75764 16.5154 6.19519 17.5083C6.29175 17.61 6.39096 17.7092 6.4927 17.8056C7.48558 17.2432 8.6201 17.0943 9.70456 17.5435C10.789 17.9927 11.4859 18.9002 11.7904 19.9999C11.9305 20.0037 12.0707 20.0038 12.2109 20.0001C12.5153 18.9003 13.2122 17.9927 14.2968 17.5435C15.3813 17.0942 16.5159 17.2432 17.5088 17.8057C17.6105 17.7091 17.7096 17.6099 17.806 17.5081C17.2437 16.5153 17.0947 15.3807 17.5439 14.2963C17.9931 13.2118 18.9007 12.5149 20.0004 12.2105C20.0042 12.0704 20.0043 11.9301 20.0006 11.7899C18.9008 11.4856 17.9932 10.7886 17.5439 9.70407C17.0947 8.61953 17.2437 7.48494 17.8061 6.49204C17.7096 6.39031 17.6104 6.2912 17.5086 6.19479C16.5158 6.75717 15.3812 6.9061 14.2968 6.4569C13.2123 6.0077 12.5154 5.10016 12.211 4.00044C12.0709 3.99666 11.9306 3.99659 11.7904 4.00024C11.486 5.10005 10.7891 6.00767 9.70456 6.4569C8.62002 6.90613 7.48543 6.75715 6.49252 6.1947C6.39079 6.29126 6.29169 6.39047 6.19528 6.49222C6.75766 7.48509 6.90659 8.61961 6.45739 9.70407C6.00819 10.7885 5.10065 11.4855 4.00092 11.7899C3.99715 11.93 3.99708 12.0702 4.00073 12.2104ZM12.0007 15.0002C10.3438 15.0002 9.00066 13.657 9.00066 12.0002C9.00066 10.3433 10.3438 9.00018 12.0007 9.00018C13.6575 9.00018 15.0007 10.3433 15.0007 12.0002C15.0007 13.657 13.6575 15.0002 12.0007 15.0002ZM12.0007 13.0002C12.5529 13.0002 13.0007 12.5525 13.0007 12.0002C13.0007 11.4479 12.5529 11.0002 12.0007 11.0002C11.4484 11.0002 11.0007 11.4479 11.0007 12.0002C11.0007 12.5525 11.4484 13.0002 12.0007 13.0002Z"/>
</symbol>
<symbol id="icon-collapse" viewBox="0 0 24 24">
<path d="M 7.277948 17.761471 L 3.03918 22.000246 L 1.97949 20.940571 L 6.218198 16.701794 L 2.509335 12.992909 L 10.986812 12.992909 L 10.986812 21.470409 L 7.277948 17.761471 Z"/>
<path d="M 17.761225 6.27887 L 21.470163 9.987807 L 12.992662 9.987807 L 12.992662 1.510315 L 16.70155 5.219193 L 20.940325 0.980471 L 22 2.040154 L 17.761225 6.27887 Z"/>
<path d="M15 4.00008H13V11.0001H20V9.00008H16.4142L20.7071 4.70718L19.2929 3.29297L15 7.58586V4.00008ZM4.00008 15H7.58586L3.29297 19.2929L4.70718 20.7071L9.00008 16.4142V20H11.0001V13H4.00008V15Z" />
</symbol>
<symbol id="icon-copy" viewBox="0 0 24 24">
<path d="M6.9998 6V3C6.9998 2.44772 7.44752 2 7.9998 2H19.9998C20.5521 2 20.9998 2.44772 20.9998 3V17C20.9998 17.5523 20.5521 18 19.9998 18H16.9998V20.9991C16.9998 21.5519 16.5499 22 15.993 22H4.00666C3.45059 22 3 21.5554 3 20.9991L3.0026 7.00087C3.0027 6.44811 3.45264 6 4.00942 6H6.9998ZM5.00242 8L5.00019 20H14.9998V8H5.00242ZM8.9998 6H16.9998V16H18.9998V4H8.9998V6Z" />
@@ -151,7 +150,7 @@
<path d="M4 16H20V5H4V16ZM13 18V20H17V22H7V20H11V18H2.9918C2.44405 18 2 17.5511 2 16.9925V4.00748C2 3.45107 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44892 22 4.00748V16.9925C22 17.5489 21.5447 18 21.0082 18H13Z"/>
</symbol>
<symbol id="icon-divider" viewBox="0 0 24 24">
<path d="M17 21V17H7V21H5V16C5 15.4477 5.44772 15 6 15H18C18.5523 15 19 15.4477 19 16V21H17ZM7 3V7H17V3H19V8C19 8.55228 18.5523 9 18 9H6C5.44772 9 5 8.55228 5 8V3H7ZM2 9L6 12L2 15V9ZM22 9V15L18 12L22 9Z"/>
<path d="M22 11L2 11L2 13L22 13V11ZM18 2C19.1046 2 20 2.89543 20 4V7C20 8.10457 19.1046 9 18 9L6 9C4.89543 9 4 8.10457 4 7L4 4C4 2.89543 4.89543 2 6 2L18 2ZM18 20H6V17L18 17V20ZM20 17C20 15.8954 19.1046 15 18 15L6 15C4.89543 15 4 15.8954 4 17L4 20C4 21.1046 4.89543 22 6 22H18C19.1046 22 20 21.1046 20 20V17Z" />
</symbol>
<symbol id="icon-document" viewBox="0 0 24 24">
<path d="M20 22H4C3.44772 22 3 21.5523 3 21V3C3 2.44772 3.44772 2 4 2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22ZM19 20V4H5V20H19ZM7 6H11V10H7V6ZM7 12H17V14H7V12ZM7 16H17V18H7V16ZM13 7H17V9H13V7Z"/>
@@ -175,8 +174,7 @@
<path d="M3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3ZM20 7.23792L12.0718 14.338L4 7.21594V19H20V7.23792ZM4.51146 5L12.0619 11.662L19.501 5H4.51146Z"/>
</symbol>
<symbol id="icon-expand" viewBox="0 0 24 24">
<path d="M 18.277948 6.761469 L 14.03918 11.000246 L 12.979489 9.940571 L 17.218199 5.701796 L 13.509336 1.992908 L 21.986811 1.992908 L 21.986811 10.470408 L 18.277948 6.761469 Z"/>
<path d="M 6.761224 18.27887 L 10.470162 21.987808 L 1.992663 21.987808 L 1.992663 13.510315 L 5.701549 17.219193 L 9.940325 12.980471 L 11 14.040153 L 6.761224 18.27887 Z"/>
<path d="M17.5858 5H14V3H21V10H19V6.41421L14.7071 10.7071L13.2929 9.29289L17.5858 5ZM3 14H5V17.5858L9.29289 13.2929L10.7071 14.7071L6.41421 19H10V21H3V14Z" />
</symbol>
<symbol id="icon-facebook" viewBox="0 0 24 24">
<path d="M15.4024 21V14.0344H17.7347L18.0838 11.3265H15.4024V9.59765C15.4024 8.81364 15.62 8.27934 16.7443 8.27934L18.1783 8.27867V5.85676C17.9302 5.82382 17.0791 5.75006 16.0888 5.75006C14.0213 5.75006 12.606 7.01198 12.606 9.32952V11.3265H10.2677V14.0344H12.606V21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H15.4024Z"/>

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 99 KiB

View File

@@ -1,7 +1,7 @@
import{n as t,_ as e}from"./index.min.js";import{D as n}from"./Docs.min.js";import"./vendor.min.js";const l=t({props:{docs:Object},emits:["cancel"],computed:{options(){const t=[{icon:"expand",link:"lab/docs/"+this.docs.component}];return this.docs.github&&t.unshift({icon:"github",link:this.docs.github,target:"_blank"}),t}}},(function(){var t=this,e=t._self._c;return e("k-drawer",t._b({ref:"drawer",staticClass:"k-form-drawer",attrs:{options:t.options},on:{submit:function(e){return t.$emit("cancel")}}},"k-drawer",t.$attrs,!1),[e("k-lab-docs",t._b({},"k-lab-docs",t.docs,!1))],1)}),[],!1,null,null,null,null).exports;const a=t({props:{code:{type:Boolean,default:!0},label:String,flex:Boolean},data:()=>({mode:"preview"}),computed:{component(){return window.UiExamples[this.label]}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-lab-example",attrs:{"data-flex":t.flex,tabindex:"0"}},[e("header",{staticClass:"k-lab-example-header"},[e("h3",{staticClass:"k-lab-example-label"},[t._v(t._s(t.label))]),t.code?e("k-button-group",{staticClass:"k-lab-example-inspector",attrs:{layout:"collapsed"}},[e("k-button",{attrs:{theme:"preview"===t.mode?"info":null,icon:"preview",size:"xs",title:"Preview"},on:{click:function(e){t.mode="preview"}}}),e("k-button",{attrs:{theme:"inspect"===t.mode?"info":null,icon:"code",size:"xs",title:"Vue code"},on:{click:function(e){t.mode="inspect"}}})],1):t._e()],1),"preview"===t.mode?e("div",{staticClass:"k-lab-example-canvas"},[t._t("default")],2):t._e(),"inspect"===t.mode?e("div",{staticClass:"k-lab-example-code"},[e("k-code",{attrs:{language:"html"}},[t._v(t._s(t.component))])],1):t._e()])}),[],!1,null,null,null,null).exports;const s=t({},(function(){return(0,this._self._c)("div",{staticClass:"k-lab-examples"},[this._t("default")],2)}),[],!1,null,null,null,null).exports;const o=t({methods:{submit(t){const e=Object.fromEntries(new FormData(t));this.$panel.dialog.open({component:"k-lab-output-dialog",props:{code:JSON.stringify(e,null,2)}})}}},(function(){var t=this,e=t._self._c;return e("form",{staticClass:"k-lab-form",on:{submit:function(e){return e.preventDefault(),t.submit(e.target)}}},[t._t("default"),e("footer",[e("k-button",{attrs:{type:"submit",icon:"check",theme:"positive",variant:"filled"}},[t._v(" Submit ")])],1)],2)}),[],!1,null,null,null,null).exports;const i=t({props:{code:String,language:{default:"js",type:String}},emits:["cancel"]},(function(){var t=this,e=t._self._c;return e("k-dialog",t._b({attrs:{size:"large","cancel-button":!1,"submit-button":!1},on:{cancel:function(e){return t.$emit("cancel")}}},"k-dialog",t.$attrs,!1),[e("k-code",{attrs:{language:t.language}},[t._v(t._s(t.code))])],1)}),[],!1,null,null,null,null).exports;const r=t({},(function(){var t=this._self._c;return t("div",{staticClass:"k-table"},[t("table",[t("tbody",[t("tr",[t("td",{staticClass:"k-table-cell",attrs:{"data-mobile":"true"}},[this._t("default")],2)])])])])}),[],!1,null,null,null,null).exports;Vue.component("k-lab-docs",n),Vue.component("k-lab-docs-drawer",l),Vue.component("k-lab-example",a),Vue.component("k-lab-examples",s),Vue.component("k-lab-form",o),Vue.component("k-lab-output-dialog",i),Vue.component("k-lab-table-cell",r);const c=t({props:{docs:String,examples:[Object,Array],file:String,github:String,props:[Object,Array],styles:String,tab:String,tabs:{type:Array,default:()=>[]},template:String,title:String},data:()=>({component:null}),watch:{tab:{handler(){this.createComponent()},immediate:!0}},mounted(){this.$panel.view.path.replace(/lab\//,"")},methods:{async createComponent(){if(!this.file)return;const{default:t}=await e((()=>import(this.$panel.url(this.file)+"?cache="+Date.now())),__vite__mapDeps([]),import.meta.url);t.template=this.template,this.component={...t},window.UiExamples=this.examples},openDocs(){this.$panel.drawer.open(`lab/docs/${this.docs}`)},async reloadComponent(){await this.$panel.view.refresh(),this.createComponent()},reloadDocs(){this.$panel.drawer.isOpen&&this.$panel.drawer.refresh()}}},(function(){var t=this,e=t._self._c;return e("k-panel-inside",{staticClass:"k-lab-playground-view",attrs:{"data-has-tabs":t.tabs.length>1}},[e("k-header",[t._v(" "+t._s(t.title)+" "),t.docs||t.github?e("k-button-group",{attrs:{slot:"buttons"},slot:"buttons"},[t.docs?e("k-button",{attrs:{text:t.docs,icon:"book",size:"sm",variant:"filled"},on:{click:t.openDocs}}):t._e(),t.github?e("k-button",{attrs:{icon:"github",size:"sm",variant:"filled",link:t.github,target:"_blank"}}):t._e()],1):t._e()],1),e("k-tabs",{attrs:{tab:t.tab,tabs:t.tabs}}),t.component?e(t.component,t._b({tag:"component"},"component",t.props,!1)):t._e(),t.styles?e("style",{tag:"component",domProps:{innerHTML:t._s(t.styles)}}):t._e()],1)}),[],!1,null,null,null,null).exports;export{c as default};
function __vite__mapDeps(indexes) {
if (!__vite__mapDeps.viteFileDeps) {
__vite__mapDeps.viteFileDeps = []
}
return indexes.map((i) => __vite__mapDeps.viteFileDeps[i])
}
import{n as t,_ as e}from"./index.min.js";import{D as n}from"./Docs.min.js";import"./vendor.min.js";const l=t({props:{docs:Object},emits:["cancel"],computed:{options(){const t=[{icon:"expand",link:"lab/docs/"+this.docs.component}];return this.docs.github&&t.unshift({icon:"github",link:this.docs.github,target:"_blank"}),t}}},(function(){var t=this,e=t._self._c;return e("k-drawer",t._b({ref:"drawer",staticClass:"k-form-drawer",attrs:{options:t.options},on:{submit:function(e){return t.$emit("cancel")}}},"k-drawer",t.$attrs,!1),[e("k-lab-docs",t._b({},"k-lab-docs",t.docs,!1))],1)}),[],!1,null,null,null,null).exports;const a=t({props:{code:{type:Boolean,default:!0},label:String,flex:Boolean},data:()=>({mode:"preview"}),computed:{component(){return window.UiExamples[this.label]}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-lab-example",attrs:{"data-flex":t.flex,tabindex:"0"}},[e("header",{staticClass:"k-lab-example-header"},[e("h3",{staticClass:"k-lab-example-label"},[t._v(t._s(t.label))]),t.code?e("k-button-group",{staticClass:"k-lab-example-inspector",attrs:{layout:"collapsed"}},[e("k-button",{attrs:{theme:"preview"===t.mode?"info":null,icon:"preview",size:"xs",title:"Preview"},on:{click:function(e){t.mode="preview"}}}),e("k-button",{attrs:{theme:"inspect"===t.mode?"info":null,icon:"code",size:"xs",title:"Vue code"},on:{click:function(e){t.mode="inspect"}}})],1):t._e()],1),"preview"===t.mode?e("div",{staticClass:"k-lab-example-canvas"},[t._t("default")],2):t._e(),"inspect"===t.mode?e("div",{staticClass:"k-lab-example-code"},[e("k-code",{attrs:{language:"html"}},[t._v(t._s(t.component))])],1):t._e()])}),[],!1,null,null,null,null).exports;const o=t({},(function(){return(0,this._self._c)("div",{staticClass:"k-lab-examples"},[this._t("default")],2)}),[],!1,null,null,null,null).exports;const s=t({methods:{submit(t){const e=Object.fromEntries(new FormData(t));this.$panel.dialog.open({component:"k-lab-output-dialog",props:{code:JSON.stringify(e,null,2)}})}}},(function(){var t=this,e=t._self._c;return e("form",{staticClass:"k-lab-form",on:{submit:function(e){return e.preventDefault(),t.submit(e.target)}}},[t._t("default"),e("footer",[e("k-button",{attrs:{type:"submit",icon:"check",theme:"positive",variant:"filled"}},[t._v(" Submit ")])],1)],2)}),[],!1,null,null,null,null).exports;const i=t({props:{code:String,language:{default:"js",type:String}},emits:["cancel"]},(function(){var t=this,e=t._self._c;return e("k-dialog",t._b({attrs:{size:"large","cancel-button":!1,"submit-button":!1},on:{cancel:function(e){return t.$emit("cancel")}}},"k-dialog",t.$attrs,!1),[e("k-code",{attrs:{language:t.language}},[t._v(t._s(t.code))])],1)}),[],!1,null,null,null,null).exports;const r=t({},(function(){var t=this._self._c;return t("div",{staticClass:"k-table"},[t("table",[t("tbody",[t("tr",[t("td",{staticClass:"k-table-cell",attrs:{"data-mobile":"true"}},[this._t("default")],2)])])])])}),[],!1,null,null,null,null).exports;Vue.component("k-lab-docs",n),Vue.component("k-lab-docs-drawer",l),Vue.component("k-lab-example",a),Vue.component("k-lab-examples",o),Vue.component("k-lab-form",s),Vue.component("k-lab-output-dialog",i),Vue.component("k-lab-table-cell",r);const c=t({props:{docs:String,examples:[Object,Array],file:String,github:String,props:[Object,Array],styles:String,tab:String,tabs:{type:Array,default:()=>[]},template:String,title:String},data:()=>({component:null}),watch:{tab:{handler(){this.createComponent()},immediate:!0}},mounted(){this.$panel.view.path.replace(/lab\//,"")},methods:{async createComponent(){if(!this.file)return;const{default:t}=await e((()=>import(this.$panel.url(this.file)+"?cache="+Date.now())),__vite__mapDeps([]),import.meta.url);t.template=this.template,this.component={...t},window.UiExamples=this.examples},openDocs(){this.$panel.drawer.open(`lab/docs/${this.docs}`)},async reloadComponent(){await this.$panel.view.refresh(),this.createComponent()},reloadDocs(){this.$panel.drawer.isOpen&&this.$panel.drawer.refresh()}}},(function(){var t=this,e=t._self._c;return e("k-panel-inside",{staticClass:"k-lab-playground-view",attrs:{"data-has-tabs":t.tabs.length>1}},[e("k-header",{scopedSlots:t._u([{key:"buttons",fn:function(){return[t.docs||t.github?e("k-button-group",[t.docs?e("k-button",{attrs:{text:t.docs,icon:"book",size:"sm",variant:"filled"},on:{click:t.openDocs}}):t._e(),t.github?e("k-button",{attrs:{link:t.github,icon:"github",size:"sm",target:"_blank",variant:"filled"}}):t._e()],1):t._e()]},proxy:!0}])},[t._v(" "+t._s(t.title)+" ")]),e("k-tabs",{attrs:{tab:t.tab,tabs:t.tabs}}),t.component?e(t.component,t._b({tag:"component"},"component",t.props,!1)):t._e(),t.styles?e("style",{tag:"component",domProps:{innerHTML:t._s(t.styles)}}):t._e()],1)}),[],!1,null,null,null,null).exports;export{c as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -71,7 +71,7 @@ class Api extends BaseApi
$field = Form::for($model)->field($name);
$fieldApi = $this->clone([
'data' => array_merge($this->data(), ['field' => $field]),
'data' => [...$this->data(), 'field' => $field],
'routes' => $field->api(),
]);
@@ -185,6 +185,30 @@ class Api extends BaseApi
return $pages->query($this->requestBody());
}
/**
* @throws \Kirby\Exception\NotFoundException if the section type cannot be found or the section cannot be loaded
*/
public function sectionApi(
ModelWithContent $model,
string $name,
string|null $path = null
): mixed {
if (!$section = $model->blueprint()?->section($name)) {
throw new NotFoundException('The section "' . $name . '" could not be found');
}
$sectionApi = $this->clone([
'data' => [...$this->data(), 'section' => $section],
'routes' => $section->api(),
]);
return $sectionApi->call(
$path,
$this->requestMethod(),
$this->requestData()
);
}
/**
* Returns the current Session instance
*

View File

@@ -659,6 +659,11 @@ trait AppPlugins
*/
protected function extensionsFromSystem(): void
{
// Always start with fresh fields and sections
// from the core and add plugins on top of that
FormField::$types = [];
Section::$types = [];
// mixins
FormField::$mixins = $this->core->fieldMixins();
Section::$mixins = $this->core->sectionMixins();
@@ -674,8 +679,8 @@ trait AppPlugins
$this->extendCacheTypes($this->core->cacheTypes());
$this->extendComponents($this->core->components());
$this->extendBlueprints($this->core->blueprints());
$this->extendFields($this->core->fields());
$this->extendFieldMethods($this->core->fieldMethods());
$this->extendFields($this->core->fields());
$this->extendSections($this->core->sections());
$this->extendSnippets($this->core->snippets());
$this->extendTags($this->core->kirbyTags());

View File

@@ -34,6 +34,8 @@ class Blueprint
protected $sections = [];
protected $tabs = [];
protected array|null $fileTemplates = null;
/**
* Magic getter/caller for any blueprint prop
*/
@@ -96,6 +98,115 @@ class Blueprint
return $this->props ?? [];
}
/**
* Gathers what file templates are allowed in
* this model based on the blueprint
*/
public function acceptedFileTemplates(string $inSection = null): array
{
// get cached results for the current file model
// (except when collecting for a specific section)
if ($inSection === null && $this->fileTemplates !== null) {
return $this->fileTemplates; // @codeCoverageIgnore
}
$templates = [];
// collect all allowed file templates from blueprint…
foreach ($this->sections() as $section) {
// if collecting for a specific section, skip all others
if ($inSection !== null && $section->name() !== $inSection) {
continue;
}
$templates = match ($section->type()) {
'files' => [...$templates, $section->template() ?? 'default'],
'fields' => [
...$templates,
...$this->acceptedFileTemplatesFromFields($section->fields())
],
default => $templates
};
}
// no caching for when collecting for specific section
if ($inSection !== null) {
return $templates; // @codeCoverageIgnore
}
return $this->fileTemplates = $templates;
}
/**
* Gathers the allowed file templates from model's fields
*/
protected function acceptedFileTemplatesFromFields(array $fields): array
{
$templates = [];
foreach ($fields as $field) {
// fields with uploads settings
if (isset($field['uploads']) === true && is_array($field['uploads']) === true) {
$templates = [
...$templates,
...$this->acceptedFileTemplatesFromFieldUploads($field['uploads'])
];
continue;
}
// structure and object fields
if (isset($field['fields']) === true && is_array($field['fields']) === true) {
$templates = [
...$templates,
...$this->acceptedFileTemplatesFromFields($field['fields']),
];
continue;
}
// layout and blocks fields
if (isset($field['fieldsets']) === true && is_array($field['fieldsets']) === true) {
$templates = [
...$templates,
...$this->acceptedFileTemplatesFromFieldsets($field['fieldsets'])
];
continue;
}
}
return $templates;
}
/**
* Gathers the allowed file templates from fieldsets
*/
protected function acceptedFileTemplatesFromFieldsets(array $fieldsets): array
{
$templates = [];
foreach ($fieldsets as $fieldset) {
foreach (($fieldset['tabs'] ?? []) as $tab) {
$templates = array_merge($templates, $this->acceptedFileTemplatesFromFields($tab['fields'] ?? []));
}
}
return $templates;
}
/**
* Extracts templates from field uploads settings
*/
protected function acceptedFileTemplatesFromFieldUploads(array $uploads): array
{
// only if the `uploads` parent is this model
if ($target = $uploads['parent'] ?? null) {
if ($this->model->id() !== $target) {
return [];
}
}
return [($uploads['template'] ?? 'default')];
}
/**
* Converts all column definitions, that
* are not wrapped in a tab, into a generic tab
@@ -186,24 +297,20 @@ class Blueprint
];
}
$extends = $props['extends'] ?? null;
if ($extends === null) {
return $props;
}
foreach (A::wrap($extends) as $extend) {
try {
$mixin = static::find($extend);
$mixin = static::extend($mixin);
$props = A::merge($mixin, $props, A::MERGE_REPLACE);
} catch (Exception) {
// keep the props unextended if the snippet wasn't found
if ($extends = $props['extends'] ?? null) {
foreach (A::wrap($extends) as $extend) {
try {
$mixin = static::find($extend);
$mixin = static::extend($mixin);
$props = A::merge($mixin, $props, A::MERGE_REPLACE);
} catch (Exception) {
// keep the props unextended if the snippet wasn't found
}
}
}
// remove the extends flag
unset($props['extends']);
// remove the extends flag
unset($props['extends']);
}
return $props;
}
@@ -280,6 +387,7 @@ class Blueprint
if (is_string($file) === true && F::exists($file) === true) {
return static::$loaded[$name] = Data::read($file);
}
if (is_array($file) === true) {
return static::$loaded[$name] = $file;
}
@@ -354,7 +462,10 @@ class Blueprint
continue;
}
$columnProps = $this->convertFieldsToSections($tabName . '-col-' . $columnKey, $columnProps);
$columnProps = $this->convertFieldsToSections(
$tabName . '-col-' . $columnKey,
$columnProps
);
// inject getting started info, if the sections are empty
if (empty($columnProps['sections']) === true) {
@@ -367,10 +478,14 @@ class Blueprint
];
}
$columns[$columnKey] = array_merge($columnProps, [
$columns[$columnKey] = [
...$columnProps,
'width' => $columnProps['width'] ?? '1/1',
'sections' => $this->normalizeSections($tabName, $columnProps['sections'] ?? [])
]);
'sections' => $this->normalizeSections(
$tabName,
$columnProps['sections'] ?? []
)
];
}
return $columns;
@@ -390,10 +505,9 @@ class Blueprint
/**
* Normalize field props for a single field
*
* @param array|string $props
* @throws \Kirby\Exception\InvalidArgumentException If the filed name is missing or the field type is invalid
*/
public static function fieldProps($props): array
public static function fieldProps(array|string $props): array
{
$props = static::extend($props);
@@ -432,12 +546,13 @@ class Blueprint
}
// add some useful defaults
return array_merge($props, [
return [
...$props,
'label' => $props['label'] ?? ucfirst($name),
'name' => $name,
'type' => $type,
'width' => $props['width'] ?? '1/1',
]);
];
}
/**
@@ -496,11 +611,16 @@ class Blueprint
// resolve field groups
if ($fieldProps['type'] === 'group') {
if (empty($fieldProps['fields']) === false && is_array($fieldProps['fields']) === true) {
if (
empty($fieldProps['fields']) === false &&
is_array($fieldProps['fields']) === true
) {
$index = array_search($fieldName, array_keys($fields));
$before = array_slice($fields, 0, $index);
$after = array_slice($fields, $index + 1);
$fields = array_merge($before, $fieldProps['fields'] ?? [], $after);
$fields = [
...array_slice($fields, 0, $index),
...$fieldProps['fields'] ?? [],
...array_slice($fields, $index + 1)
];
} else {
unset($fields[$fieldName]);
}
@@ -515,11 +635,9 @@ class Blueprint
/**
* Normalizes blueprint options. This must be used in the
* constructor of an extended class, if you want to make use of it.
*
* @param array|true|false|null|string $options
*/
protected function normalizeOptions(
$options,
array|string|bool|null $options,
array $defaults,
array $aliases = []
): array {
@@ -545,7 +663,7 @@ class Blueprint
}
}
return array_merge($defaults, $options);
return [...$defaults, ...$options];
}
/**
@@ -570,10 +688,11 @@ class Blueprint
// inject all section extensions
$sectionProps = $this->extend($sectionProps);
$sections[$sectionName] = $sectionProps = array_merge($sectionProps, [
$sections[$sectionName] = $sectionProps = [
...$sectionProps,
'name' => $sectionName,
'type' => $type = $sectionProps['type'] ?? $sectionName
]);
];
if (empty($type) === true || is_string($type) === false) {
$sections[$sectionName] = [
@@ -623,7 +742,7 @@ class Blueprint
}
// store all normalized sections
$this->sections = array_merge($this->sections, $sections);
$this->sections = [...$this->sections, ...$sections];
return $sections;
}
@@ -653,13 +772,14 @@ class Blueprint
$tabProps = $this->convertFieldsToSections($tabName, $tabProps);
$tabProps = $this->convertSectionsToColumns($tabName, $tabProps);
$tabs[$tabName] = array_merge($tabProps, [
$tabs[$tabName] = [
...$tabProps,
'columns' => $this->normalizeColumns($tabName, $tabProps['columns'] ?? []),
'icon' => $tabProps['icon'] ?? null,
'label' => $this->i18n($tabProps['label'] ?? ucfirst($tabName)),
'link' => $this->model->panel()->url(true) . '/?tab=' . $tabName,
'name' => $tabName,
]);
];
}
return $this->tabs = $tabs;

View File

@@ -157,72 +157,17 @@ class File extends ModelWithContent
*/
public function blueprints(string $inSection = null): array
{
// get cached results for the current file model
// (except when collecting for a specific section)
if ($inSection === null && $this->blueprints !== null) {
return $this->blueprints; // @codeCoverageIgnore
}
// always include the current template as option
$template = $this->template() ?? 'default';
$templates = [$template];
$parent = $this->parent();
// what file templates/blueprints should be considered is
// defined bythe parent's blueprint: which templates it allows
// in files sections as well as files fields
$blueprint = $parent->blueprint();
$fromFields = function ($fields) use (&$fromFields, $parent) {
$templates = [];
foreach ($fields as $field) {
// files or textare field
if (
$field['type'] === 'files' ||
$field['type'] === 'textarea'
) {
$uploads = $field['uploads'] ?? null;
// only if the `uploads` parent is the actual parent
if ($target = $uploads['parent'] ?? null) {
if ($parent->id() !== $target) {
continue;
}
}
$templates[] = $uploads['template'] ?? 'default';
continue;
}
// structure field
if ($field['type'] === 'structure') {
$fields = $fromFields($field['fields']);
$templates = array_merge($templates, $fields);
continue;
}
}
return $templates;
};
// collect all allowed templates…
foreach ($blueprint->sections() as $section) {
// if collecting for a specific section, skip all others
if ($inSection !== null && $section->name() !== $inSection) {
continue;
}
// …from files sections
if ($section->type() === 'files') {
$templates[] = $section->template() ?? 'default';
continue;
}
// …from fields
if ($section->type() === 'fields') {
$fields = $fromFields($section->fields());
$templates = array_merge($templates, $fields);
}
}
$templates = [
$this->template() ?? 'default',
...$this->parent()->blueprint()->acceptedFileTemplates($inSection)
];
// make sure every template is only included once
$templates = array_unique(array_filter($templates));

View File

@@ -100,6 +100,11 @@ trait FileActions
*/
public function changeSort(int $sort): static
{
// skip if the sort number stays the same
if ($this->sort()->value() === $sort) {
return $this;
}
return $this->commit(
'changeSort',
['file' => $this, 'position' => $sort],

View File

@@ -57,6 +57,9 @@ class FileBlueprint extends Blueprint
/**
* Returns the list of all accepted MIME types for
* file upload or `*` if all MIME types are allowed
*
* @deprecated 4.2.0 Use `acceptAttribute` instead
* @todo 5.0.0 Remove method
*/
public function acceptMime(): string
{
@@ -116,6 +119,74 @@ class FileBlueprint extends Blueprint
return '*';
}
/**
* Returns the list of all accepted file extensions
* for file upload or `*` if all extensions are allowed
*
* If a MIME type is specified in the blueprint, the `extension` and `type` options are ignored for the browser.
* Extensions and types, however, are still used to validate an uploaded file on the server.
* This behavior might change in the future to better represent which file extensions are actually allowed.
*
* If no MIME type is specified, the intersection between manually defined extensions and the Kirby "file types" is returned.
* If the intersection is empty, an empty string is returned.
* This behavior might change in the future to instead return the union of `mime`, `extension` and `type`.
*
* @since 4.2.0
*/
public function acceptAttribute(): string
{
// don't disclose the specific default types
if ($this->defaultTypes === true) {
return '*';
}
$accept = $this->accept();
// get extensions from "mime" option
if (is_array($accept['mime']) === true) {
// determine the extensions for each MIME type
$extensions = array_map(
fn ($pattern) => Mime::toExtensions($pattern, true),
$accept['mime']
);
$fromMime = array_unique(array_merge(...array_values($extensions)));
// return early to ignore the other options
return implode(',', array_map(fn ($ext) => ".$ext", $fromMime));
}
$restrictions = [];
// get extensions from "type" option
if (is_array($accept['type']) === true) {
$extensions = array_map(
fn ($type) => F::typeToExtensions($type) ?? [],
$accept['type']
);
$fromType = array_merge(...array_values($extensions));
$restrictions[] = $fromType;
}
// get extensions from "extension" option
if (is_array($accept['extension']) === true) {
$restrictions[] = $accept['extension'];
}
// intersect all restrictions
$list = match (count($restrictions)) {
0 => [],
1 => $restrictions[0],
default => array_intersect(...$restrictions)
};
$list = array_unique($list);
// format the list to include a leading dot on each extension
return implode(',', array_map(fn ($ext) => ".$ext", $list));
}
protected function normalizeAccept(mixed $accept = null): array
{
$accept = match (true) {

View File

@@ -110,6 +110,9 @@ class Helpers
) {
$override = null;
/**
* @psalm-suppress UndefinedVariable
*/
$handler = set_error_handler(function () use (&$override, &$handler, $condition, $fallback) {
// check if suppress condition is met
$suppress = $condition(...func_get_args());

View File

@@ -2,6 +2,7 @@
namespace Kirby\Cms;
use Closure;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Toolkit\Component;
@@ -46,6 +47,21 @@ class Section extends Component
parent::__construct($type, $attrs);
}
/**
* Returns field api call
*/
public function api(): mixed
{
if (
isset($this->options['api']) === true &&
$this->options['api'] instanceof Closure
) {
return $this->options['api']->call($this);
}
return null;
}
public function errors(): array
{
if (array_key_exists('errors', $this->methods) === true) {

View File

@@ -158,7 +158,9 @@ class UpdateStatus
// collect all matching custom messages
$filters = [
'kirby' => $this->app->version(),
'php' => phpversion()
// some PHP version strings contain extra info that makes them
// invalid so we need to strip it off
'php' => preg_replace('/^([^~+-]+).*$/', '$1', phpversion())
];
if ($type === 'plugin') {

View File

@@ -305,7 +305,23 @@ class Database
// try to prepare and execute the sql
try {
$this->statement = $this->connection->prepare($query);
$this->statement->execute($bindings);
// bind parameters to statement
foreach ($bindings as $parameter => $value) {
// positional parameters start at 1
if (is_int($parameter)) {
$parameter++;
}
$type = match (gettype($value)) {
'integer' => PDO::PARAM_INT,
'boolean' => PDO::PARAM_BOOL,
'NULL' => PDO::PARAM_NULL,
default => PDO::PARAM_STR
};
$this->statement->bindValue($parameter, $value, $type);
}
$this->statement->execute();
$this->affected = $this->statement->rowCount();
$this->lastId = Str::startsWith($query, 'insert ', true) ? $this->connection->lastInsertId() : null;

View File

@@ -869,7 +869,7 @@ class Query
$this->bindings($args[1]);
// ->where('username like ?', 'myuser')
} elseif (is_string($args[0]) === true && is_string($args[1]) === true) {
} elseif (is_string($args[0]) === true && is_scalar($args[1]) === true) {
// prepared where clause
$result = $args[0];
@@ -887,9 +887,10 @@ class Query
$key = $sql->columnName($this->table, $args[0]);
// ->where('username', 'in', ['myuser', 'myotheruser']);
// ->where('quantity', 'between', [10, 50]);
$predicate = trim(strtoupper($args[1]));
if (is_array($args[2]) === true) {
if (in_array($predicate, ['IN', 'NOT IN']) === false) {
if (in_array($predicate, ['IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) === false) {
throw new InvalidArgumentException('Invalid predicate ' . $predicate);
}
@@ -903,15 +904,20 @@ class Query
$values[] = $valueBinding;
}
// add that to the where clause in parenthesis
$result = $key . ' ' . $predicate . ' (' . implode(', ', $values) . ')';
// add that to the where clause in parenthesis or seperated by AND
$values = match ($predicate) {
'IN',
'NOT IN' => '(' . implode(', ', $values) . ')',
'BETWEEN',
'NOT BETWEEN' => $values[0] . ' AND ' . $values[1]
};
$result = $key . ' ' . $predicate . ' ' . $values;
// ->where('username', 'like', 'myuser');
} else {
$predicates = [
'=', '>=', '>', '<=', '<', '<>', '!=', '<=>',
'IS', 'IS NOT',
'BETWEEN', 'NOT BETWEEN',
'LIKE', 'NOT LIKE',
'SOUNDS LIKE',
'REGEXP', 'NOT REGEXP'

View File

@@ -132,11 +132,13 @@ abstract class Sql
{
return [
'id' => '{{ name }} INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
'varchar' => '{{ name }} varchar(255) {{ null }} {{ default }} {{ unique }}',
'varchar' => '{{ name }} varchar({{ size }}) {{ null }} {{ default }} {{ unique }}',
'text' => '{{ name }} TEXT {{ unique }}',
'int' => '{{ name }} INT(11) UNSIGNED {{ null }} {{ default }} {{ unique }}',
'int' => '{{ name }} INT(11) {{ unsigned }} {{ null }} {{ default }} {{ unique }}',
'timestamp' => '{{ name }} TIMESTAMP {{ null }} {{ default }} {{ unique }}',
'bool' => '{{ name }} TINYINT(1) {{ null }} {{ default }} {{ unique }}'
'bool' => '{{ name }} TINYINT(1) {{ null }} {{ default }} {{ unique }}',
'float' => '{{ name }} DOUBLE {{ null }} {{ default }} {{ unique }}',
'decimal' => '{{ name }} DECIMAL({{ precision }}, {{ decimalPlaces }}) {{ null }} {{ default }} {{ unique }}'
];
}
@@ -157,6 +159,10 @@ abstract class Sql
* @param string $name Column name
* @param array $column Column definition array; valid keys:
* - `type` (required): Column template to use
* - `unsigned`: Whether an int column is signed or unsigned (boolean)
* - `size`: The size of varchar (int)
* - `precision`: The precision of a decimal type
* - `decimalPlaces`: The number of decimal places for a decimal type
* - `null`: Whether the column may be NULL (boolean)
* - `key`: Index this column is part of; special values `'primary'` for PRIMARY KEY and `true` for automatic naming
* - `unique`: Whether the index (or if not set the column itself) has a UNIQUE constraint
@@ -191,6 +197,13 @@ abstract class Sql
}
}
// unsigned (defaults to true for backwards compatibility)
if (isset($column['unsigned']) === true && $column['unsigned'] === false) {
$unsigned = '';
} else {
$unsigned = 'UNSIGNED';
}
// unique
$uniqueKey = false;
$uniqueColumn = null;
@@ -208,11 +221,15 @@ abstract class Sql
$columnDefault = $this->columnDefault($name, $column);
$query = trim(Str::template($template, [
'name' => $this->quoteIdentifier($name),
'null' => $null,
'default' => $columnDefault['query'],
'unique' => $uniqueColumn
], ['fallback' => '']));
'name' => $this->quoteIdentifier($name),
'unsigned' => $unsigned,
'size' => $column['size'] ?? 255,
'precision' => $column['precision'] ?? 14,
'decimalPlaces' => $column['decimalPlaces'] ?? 4,
'null' => $null,
'default' => $columnDefault['query'],
'unique' => $uniqueColumn
], ['fallback' => '']));
return [
'query' => $query,

View File

@@ -42,7 +42,9 @@ class Sqlite extends Sql
'text' => '{{ name }} TEXT {{ null }} {{ default }} {{ unique }}',
'int' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
'timestamp' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
'bool' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}'
'bool' => '{{ name }} INTEGER {{ null }} {{ default }} {{ unique }}',
'float' => '{{ name }} REAL {{ null }} {{ default }} {{ unique }}',
'decimal' => '{{ name }} REAL {{ null }} {{ default }} {{ unique }}'
];
}

View File

@@ -220,143 +220,145 @@ class Dir
array|null $contentIgnore = null,
bool $multilang = false
): array {
$dir = realpath($dir);
$inventory = [
'children' => [],
'files' => [],
'template' => 'default',
];
$dir = realpath($dir);
if ($dir === false) {
return $inventory;
}
$items = static::read($dir, $contentIgnore);
// a temporary store for all content files
$content = [];
// sort all items naturally to avoid sorting issues later
// read and sort all items naturally to avoid sorting issues later
$items = static::read($dir, $contentIgnore);
natsort($items);
// loop through all directory items and collect all relevant information
foreach ($items as $item) {
// ignore all items with a leading dot
// ignore all items with a leading dot or underscore
if (in_array(substr($item, 0, 1), ['.', '_']) === true) {
continue;
}
$root = $dir . '/' . $item;
// collect all directories as children
if (is_dir($root) === true) {
// extract the slug and num of the directory
if (preg_match('/^([0-9]+)' . static::$numSeparator . '(.*)$/', $item, $match)) {
$num = (int)$match[1];
$slug = $match[2];
} else {
$num = null;
$slug = $item;
}
$inventory['children'][] = [
'dirname' => $item,
'model' => null,
'num' => $num,
'root' => $root,
'slug' => $slug,
];
} else {
$extension = pathinfo($item, PATHINFO_EXTENSION);
switch ($extension) {
case 'htm':
case 'html':
case 'php':
// don't track those files
break;
case $contentExtension:
$content[] = pathinfo($item, PATHINFO_FILENAME);
break;
default:
$inventory['files'][$item] = [
'filename' => $item,
'extension' => $extension,
'root' => $root,
];
}
}
}
// remove the language codes from all content filenames
if ($multilang === true) {
foreach ($content as $key => $filename) {
$content[$key] = pathinfo($filename, PATHINFO_FILENAME);
$inventory['children'][] = static::inventoryChild(
$item,
$root,
$contentExtension,
$multilang
);
continue;
}
$content = array_unique($content);
$extension = pathinfo($item, PATHINFO_EXTENSION);
// don't track files with these extensions
if (in_array($extension, ['htm', 'html', 'php']) === true) {
continue;
}
// collect all content files separately,
// not as inventory entries
if ($extension === $contentExtension) {
$filename = pathinfo($item, PATHINFO_FILENAME);
// remove the language codes from all content filenames
if ($multilang === true) {
$filename = pathinfo($filename, PATHINFO_FILENAME);
}
$content[] = $filename;
continue;
}
// collect all other files
$inventory['files'][$item] = [
'filename' => $item,
'extension' => $extension,
'root' => $root,
];
}
$inventory = static::inventoryContent($inventory, $content);
$inventory = static::inventoryModels($inventory, $contentExtension, $multilang);
$content = array_unique($content);
$inventory['template'] = static::inventoryTemplate(
$content,
$inventory['files']
);
return $inventory;
}
/**
* Take all content files,
* remove those who are meta files and
* detect the main content file
* Collect information for a child for the inventory
*/
protected static function inventoryContent(array $inventory, array $content): array
{
// filter meta files from the content file
if (empty($content) === true) {
$inventory['template'] = 'default';
return $inventory;
protected static function inventoryChild(
string $item,
string $root,
string $contentExtension = 'txt',
bool $multilang = false
): array {
// extract the slug and num of the directory
if ($separator = strpos($item, static::$numSeparator)) {
$num = (int)substr($item, 0, $separator);
$slug = substr($item, $separator + 1);
}
foreach ($content as $contentName) {
// could be a meta file. i.e. cover.jpg
if (isset($inventory['files'][$contentName]) === true) {
// determine the model
if (empty(Page::$models) === false) {
if ($multilang === true) {
$code = App::instance()->defaultLanguage()->code();
$contentExtension = $code . '.' . $contentExtension;
}
// look if a content file can be found
// for any of the available models
foreach (Page::$models as $modelName => $modelClass) {
if (is_file($root . '/' . $modelName . '.' . $contentExtension) === true) {
$model = $modelName;
break;
}
}
}
return [
'dirname' => $item,
'model' => $model ?? null,
'num' => $num ?? null,
'root' => $root,
'slug' => $slug ?? $item,
];
}
/**
* Determines the main template for the inventory
* from all collected content files, ignore file meta files
*/
protected static function inventoryTemplate(
array $content,
array $files,
): string {
foreach ($content as $name) {
// is a meta file corresponding to an actual file, i.e. cover.jpg
if (isset($files[$name]) === true) {
continue;
}
// it's most likely the template
$inventory['template'] = $contentName;
// (will overwrite and use the last match for historic reasons)
$template = $name;
}
return $inventory;
}
/**
* Go through all inventory children
* and inject a model for each
*/
protected static function inventoryModels(
array $inventory,
string $contentExtension,
bool $multilang = false
): array {
// inject models
if (
empty($inventory['children']) === false &&
empty(Page::$models) === false
) {
if ($multilang === true) {
$contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension;
}
foreach ($inventory['children'] as $key => $child) {
foreach (Page::$models as $modelName => $modelClass) {
if (file_exists($child['root'] . '/' . $modelName . '.' . $contentExtension) === true) {
$inventory['children'][$key]['model'] = $modelName;
break;
}
}
}
}
return $inventory;
return $template ?? 'default';
}
/**

View File

@@ -2,6 +2,7 @@
namespace Kirby\Filesystem;
use Kirby\Toolkit\A;
use Kirby\Toolkit\Str;
use SimpleXMLElement;
@@ -268,18 +269,32 @@ class Mime
/**
* Returns all available extensions for a given MIME type
*/
public static function toExtensions(string $mime = null): array
public static function toExtensions(string $mime = null, bool $matchWildcards = false): array
{
$extensions = [];
$testMime = fn (string $v) => static::matches($v, $mime);
foreach (static::$types as $key => $value) {
if (is_array($value) === true && in_array($mime, $value) === true) {
$extensions[] = $key;
continue;
}
if ($value === $mime) {
$extensions[] = $key;
if (is_array($value) === true) {
if ($matchWildcards === true) {
if (A::some($value, $testMime)) {
$extensions[] = $key;
}
} else {
if (in_array($mime, $value) === true) {
$extensions[] = $key;
}
}
} else {
if ($matchWildcards === true) {
if ($testMime($value) === true) {
$extensions[] = $key;
}
} else {
if ($value === $mime) {
$extensions[] = $key;
}
}
}
}

View File

@@ -62,8 +62,8 @@ class ImageMagick extends Darkroom
{
$command = escapeshellarg($options['bin']);
// limit to single-threading to keep CPU usage sane
$command .= ' -limit thread 1';
// default is limiting to single-threading to keep CPU usage sane
$command .= ' -limit thread ' . escapeshellarg($options['threads']);
// append input file
return $command . ' ' . escapeshellarg($file);
@@ -77,6 +77,7 @@ class ImageMagick extends Darkroom
return parent::defaults() + [
'bin' => 'convert',
'interlace' => false,
'threads' => 1,
];
}

View File

@@ -121,35 +121,72 @@ class Assets
* Returns array of favicon icons
* based on config option
*
* @todo Deprecate `url` option in v5, use `href` option instead
* @todo Deprecate `rel` usage as array key in v5, use `rel` option instead
*
* @throws \Kirby\Exception\InvalidArgumentException
*/
public function favicons(): array
{
$icons = $this->kirby->option('panel.favicon', [
'apple-touch-icon' => [
'type' => 'image/png',
'url' => $this->url . '/apple-touch-icon.png',
[
'rel' => 'apple-touch-icon',
'type' => 'image/png',
'href' => $this->url . '/apple-touch-icon.png'
],
'alternate icon' => [
'type' => 'image/png',
'url' => $this->url . '/favicon.png',
[
'rel' => 'alternate icon',
'type' => 'image/png',
'href' => $this->url . '/favicon.png'
],
'shortcut icon' => [
'type' => 'image/svg+xml',
'url' => $this->url . '/favicon.svg',
[
'rel' => 'shortcut icon',
'type' => 'image/svg+xml',
'href' => $this->url . '/favicon.svg'
],
[
'rel' => 'apple-touch-icon',
'type' => 'image/png',
'href' => $this->url . '/apple-touch-icon-dark.png',
'media' => '(prefers-color-scheme: dark)'
],
[
'rel' => 'alternate icon',
'type' => 'image/png',
'href' => $this->url . '/favicon-dark.png',
'media' => '(prefers-color-scheme: dark)'
]
]);
if (is_array($icons) === true) {
return $icons;
// normalize options
foreach ($icons as $rel => &$icon) {
// TODO: remove this backward compatibility check in v6
if (isset($icon['url']) === true) {
$icon['href'] = $icon['url'];
unset($icon['url']);
}
// TODO: remove this backward compatibility check in v6
if (is_string($rel) === true && isset($icon['rel']) === false) {
$icon['rel'] = $rel;
}
$icon['href'] = Url::to($icon['href']);
$icon['nonce'] = $this->nonce;
}
return array_values($icons);
}
// make sure to convert favicon string to array
if (is_string($icons) === true) {
return [
'shortcut icon' => [
'type' => F::mime($icons),
'url' => $icons,
[
'rel' => 'shortcut icon',
'type' => F::mime($icons),
'href' => Url::to($icons),
'nonce' => $this->nonce
]
];
}

View File

@@ -2,12 +2,10 @@
namespace Kirby\Panel\Lab;
use Kirby\Cms\App;
use Kirby\Exception\NotFoundException;
use Kirby\Filesystem\Dir;
use Kirby\Filesystem\F;
use Kirby\Http\Response;
use Kirby\Toolkit\Str;
/**
* One or multiple lab examples with one or multiple tabs
@@ -81,17 +79,6 @@ class Example
return $this->parent->root() . '/' . $this->path() . '/' . $filename;
}
public function github(): string
{
$path = Str::after($this->root(), App::instance()->root('kirby'));
if ($tab = $this->tab()) {
$path .= '/' . $tab;
}
return 'https://github.com/getkirby/kirby/tree/main' . $path;
}
public function id(): string
{
return $this->id;
@@ -204,22 +191,48 @@ class Example
$file ??= '';
// extract parts
$parts['template'] = $this->vueTemplate($file);
$parts['examples'] = $this->vueExamples($parts['template']);
$parts['script'] = $this->vueScript($file);
$parts['template'] = $this->vueTemplate($file);
$parts['examples'] = $this->vueExamples($parts['template'], $parts['script']);
$parts['style'] = $this->vueStyle($file);
return $parts;
}
public function vueExamples(string|null $template): array
public function vueExamples(string|null $template, string|null $script): array
{
$template ??= '';
$examples = [];
$scripts = [];
if (preg_match_all('!<k-lab-example[\s|\n].*?label="(.*?)".*?>(.*?)<\/k-lab-example>!s', $template, $matches)) {
if (preg_match_all('!\/\*\* \@script: (.*?)\*\/(.*?)\/\*\* \@script-end \*\/!s', $script, $matches)) {
foreach ($matches[1] as $key => $name) {
$code = $matches[2][$key];
$code = preg_replace('!const (.*?) \=!', 'default', $code);
$scripts[trim($name)] = $code;
}
}
if (preg_match_all('!<k-lab-example[\s|\n].*?label="(.*?)"(.*?)>(.*?)<\/k-lab-example>!s', $template, $matches)) {
foreach ($matches[1] as $key => $name) {
$tail = $matches[2][$key];
$code = $matches[3][$key];
$scriptId = trim(preg_replace_callback('!script="(.*?)"!', function ($match) {
return trim($match[1]);
}, $tail));
$scriptBlock = $scripts[$scriptId] ?? null;
if (empty($scriptBlock) === false) {
$js = PHP_EOL . PHP_EOL;
$js .= '<script>';
$js .= $scriptBlock;
$js .= '</script>';
} else {
$js = '';
}
// only use the code between the @code and @code-end comments
if (preg_match('$<!-- @code -->(.*?)<!-- @code-end -->$s', $code, $match)) {
@@ -231,11 +244,21 @@ class Example
$indents = array_map(fn ($i) => strlen($i), $indents[1]);
$indents = min($indents);
if (empty($js) === false) {
$indents--;
}
// strip minimum indent from each line
$code = preg_replace('/^\t{' . $indents . '}/m', '', $code);
}
$examples[$name] = trim($code);
$code = trim($code);
if (empty($js) === false) {
$code = '<template>' . PHP_EOL . "\t" . $code . PHP_EOL . '</template>';
}
$examples[$name] = $code . $js;
}
}

View File

@@ -128,7 +128,7 @@ class Menu
'link' => $area['link'] ?? null,
'dialog' => $area['dialog'] ?? null,
'drawer' => $area['drawer'] ?? null,
'text' => $area['label'],
'text' => I18n::translate($area['label'], $area['label'])
], $menu);
// unset the link (which is always added by default to an area)

View File

@@ -2,11 +2,13 @@
namespace Kirby\Panel;
use Kirby\Cms\File;
use Kirby\Cms\Find;
use Kirby\Cms\Page;
use Kirby\Cms\PageBlueprint;
use Kirby\Cms\PageRules;
use Kirby\Cms\Site;
use Kirby\Cms\User;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Form\Form;
use Kirby\Toolkit\A;
@@ -32,7 +34,7 @@ class PageCreateDialog
protected string|null $slug;
protected string|null $template;
protected string|null $title;
protected Page|Site $view;
protected Page|Site|User|File $view;
protected string|null $viewId;
public static array $fieldTypes = [
@@ -369,9 +371,9 @@ class PageCreateDialog
$value = [
'parent' => $this->parentId,
'section' => $this->sectionId,
'slug' => '',
'slug' => $this->slug ?? '',
'template' => $this->template,
'title' => '',
'title' => $this->title ?? '',
'view' => $this->viewId,
];

View File

@@ -219,7 +219,7 @@ class KirbyTag
*/
public function parent(): ModelWithContent|null
{
return $this->data['parent'];
return $this->data['parent'] ?? null;
}
public function render(): string

View File

@@ -255,7 +255,7 @@ class A
* // result: ['cat' => 'miao', 'dog' => 'wuff'];
* </code>
*
* @param array $array The source array
* @param mixed $array The source array
* @param string|int|array|null $key The key to look for
* @param mixed $default Optional default value, which
* should be returned if no element
@@ -588,7 +588,7 @@ class A
*/
public static function prepend(array $array, array $prepend): array
{
return $prepend + $array;
return static::merge($prepend, $array, A::MERGE_APPEND);
}
/**

View File

@@ -107,16 +107,16 @@ class Date extends DateTime
static::validateUnit($unit);
$formats = [
'year' => 'Y-01-01P',
'month' => 'Y-m-01P',
'day' => 'Y-m-dP',
'hour' => 'Y-m-d H:00:00P',
'minute' => 'Y-m-d H:i:00P',
'second' => 'Y-m-d H:i:sP'
'year' => 'Y-01-01',
'month' => 'Y-m-01',
'day' => 'Y-m-d',
'hour' => 'Y-m-d H:00:00',
'minute' => 'Y-m-d H:i:00',
'second' => 'Y-m-d H:i:s'
];
$flooredDate = date($formats[$unit], $this->timestamp());
$this->set($flooredDate);
$flooredDate = $this->format($formats[$unit]);
$this->set($flooredDate, $this->timezone());
return $this;
}

View File

@@ -710,7 +710,7 @@ class Dom
return $options;
}
$options = array_merge([
return [
'allowedAttrPrefixes' => [],
'allowedAttrs' => true,
'allowedDataUris' => true,
@@ -724,11 +724,9 @@ class Dom
'doctypeCallback' => null,
'elementCallback' => null,
'urlAttrs' => ['href', 'src', 'xlink:href'],
], $options);
$options['_normalized'] = true;
return $options;
...$options,
'_normalized' => true
];
}
/**

View File

@@ -283,6 +283,14 @@ V::$validators = [
V::max($value, $max) === true;
},
/**
* Checks with the callback sent by the user
* It's ideal for one-time custom validations
*/
'callback' => function ($value, callable $callback): bool {
return $callback($value);
},
/**
* Checks if the given string contains the given value
*/

View File

@@ -1616,12 +1616,12 @@ class SimpleImage
* @param int $width The ellipse width.
* @param int $height The ellipse height.
* @param string|array $color The ellipse color.
* @param int|array $thickness Line thickness in pixels or 'filled' (default 1).
* @param string|int|array $thickness Line thickness in pixels or 'filled' (default 1).
* @return SimpleImage
*
* @throws Exception
*/
public function ellipse(int $x, int $y, int $width, int $height, string|array $color, int|array $thickness = 1): static
public function ellipse(int $x, int $y, int $width, int $height, string|array $color, string|int|array $thickness = 1): static
{
// Allocate the color
$tempColor = $this->allocateColor($color);
@@ -2337,18 +2337,24 @@ class SimpleImage
$hex = strval(preg_replace('/^#/', '', $color));
// Support short and standard hex codes
if (strlen($hex) === 3) {
if (strlen($hex) === 3 || strlen($hex) === 4) {
[$red, $green, $blue] = [
$hex[0].$hex[0],
$hex[1].$hex[1],
$hex[2].$hex[2],
];
} elseif (strlen($hex) === 6) {
if (strlen($hex) === 4) {
$alpha = hexdec($hex[3]) / 255;
}
} elseif (strlen($hex) === 6 || strlen($hex) === 8) {
[$red, $green, $blue] = [
$hex[0].$hex[1],
$hex[2].$hex[3],
$hex[4].$hex[5],
];
if (strlen($hex) === 8) {
$alpha = hexdec($hex[6].$hex[7]) / 255;
}
} else {
throw new Exception("Invalid color value: $color", self::ERR_INVALID_COLOR);
}

View File

@@ -64,17 +64,17 @@
},
{
"name": "claviska/simpleimage",
"version": "4.0.6",
"version_normalized": "4.0.6.0",
"version": "4.1.0",
"version_normalized": "4.1.0.0",
"source": {
"type": "git",
"url": "https://github.com/claviska/SimpleImage.git",
"reference": "969de5e61810ef91f6f83c475b192c4841367dfa"
"reference": "1dcb9c785c44960890970d26e25c437a2a252bbf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/969de5e61810ef91f6f83c475b192c4841367dfa",
"reference": "969de5e61810ef91f6f83c475b192c4841367dfa",
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/1dcb9c785c44960890970d26e25c437a2a252bbf",
"reference": "1dcb9c785c44960890970d26e25c437a2a252bbf",
"shasum": ""
},
"require": {
@@ -86,7 +86,7 @@
"laravel/pint": "^1.5",
"phpstan/phpstan": "^1.10"
},
"time": "2023-07-27T16:48:12+00:00",
"time": "2024-03-04T15:41:11+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -108,7 +108,7 @@
"description": "A PHP class that makes working with images as simple as possible.",
"support": {
"issues": "https://github.com/claviska/SimpleImage/issues",
"source": "https://github.com/claviska/SimpleImage/tree/4.0.6"
"source": "https://github.com/claviska/SimpleImage/tree/4.1.0"
},
"funding": [
{
@@ -721,17 +721,17 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.28.0",
"version_normalized": "1.28.0.0",
"version": "v1.29.0",
"version_normalized": "1.29.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": ""
},
"require": {
@@ -743,12 +743,9 @@
"suggest": {
"ext-ctype": "For best performance"
},
"time": "2023-01-26T09:26:14+00:00",
"time": "2024-01-29T20:11:03+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -786,7 +783,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
},
"funding": [
{
@@ -806,17 +803,17 @@
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.28.0",
"version_normalized": "1.28.0.0",
"version": "v1.29.0",
"version_normalized": "1.29.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d"
"reference": "a287ed7475f85bf6f61890146edbc932c0fff919"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d",
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919",
"reference": "a287ed7475f85bf6f61890146edbc932c0fff919",
"shasum": ""
},
"require": {
@@ -827,12 +824,9 @@
"suggest": {
"ext-intl": "For best performance"
},
"time": "2023-01-26T09:30:37+00:00",
"time": "2024-01-29T20:11:03+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -876,7 +870,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0"
},
"funding": [
{
@@ -896,17 +890,17 @@
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.28.0",
"version_normalized": "1.28.0.0",
"version": "v1.29.0",
"version_normalized": "1.29.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"shasum": ""
},
"require": {
@@ -915,12 +909,9 @@
"suggest": {
"ext-intl": "For best performance"
},
"time": "2023-01-26T09:26:14+00:00",
"time": "2024-01-29T20:11:03+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -963,7 +954,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
},
"funding": [
{
@@ -983,17 +974,17 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.28.0",
"version_normalized": "1.28.0.0",
"version": "v1.29.0",
"version_normalized": "1.29.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "42292d99c55abe617799667f454222c54c60e229"
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "42292d99c55abe617799667f454222c54c60e229",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": ""
},
"require": {
@@ -1005,12 +996,9 @@
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2023-07-28T09:04:16+00:00",
"time": "2024-01-29T20:11:03+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1049,7 +1037,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
},
"funding": [
{
@@ -1069,17 +1057,17 @@
},
{
"name": "symfony/yaml",
"version": "v6.4.0",
"version_normalized": "6.4.0.0",
"version": "v6.4.3",
"version_normalized": "6.4.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "4f9237a1bb42455d609e6687d2613dde5b41a587"
"reference": "d75715985f0f94f978e3a8fa42533e10db921b90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587",
"reference": "4f9237a1bb42455d609e6687d2613dde5b41a587",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d75715985f0f94f978e3a8fa42533e10db921b90",
"reference": "d75715985f0f94f978e3a8fa42533e10db921b90",
"shasum": ""
},
"require": {
@@ -1093,7 +1081,7 @@
"require-dev": {
"symfony/console": "^5.4|^6.0|^7.0"
},
"time": "2023-11-06T11:00:25+00:00",
"time": "2024-01-23T14:51:35+00:00",
"bin": [
"Resources/bin/yaml-lint"
],
@@ -1124,7 +1112,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v6.4.0"
"source": "https://github.com/symfony/yaml/tree/v6.4.3"
},
"funding": [
{

View File

@@ -1,8 +1,8 @@
<?php return array(
'root' => array(
'name' => 'getkirby/cms',
'pretty_version' => '4.1.2',
'version' => '4.1.2.0',
'pretty_version' => '4.2.0',
'version' => '4.2.0.0',
'reference' => null,
'type' => 'kirby-cms',
'install_path' => __DIR__ . '/../../',
@@ -20,9 +20,9 @@
'dev_requirement' => false,
),
'claviska/simpleimage' => array(
'pretty_version' => '4.0.6',
'version' => '4.0.6.0',
'reference' => '969de5e61810ef91f6f83c475b192c4841367dfa',
'pretty_version' => '4.1.0',
'version' => '4.1.0.0',
'reference' => '1dcb9c785c44960890970d26e25c437a2a252bbf',
'type' => 'library',
'install_path' => __DIR__ . '/../claviska/simpleimage',
'aliases' => array(),
@@ -47,8 +47,8 @@
'dev_requirement' => false,
),
'getkirby/cms' => array(
'pretty_version' => '4.1.2',
'version' => '4.1.2.0',
'pretty_version' => '4.2.0',
'version' => '4.2.0.0',
'reference' => null,
'type' => 'kirby-cms',
'install_path' => __DIR__ . '/../../',
@@ -125,36 +125,36 @@
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.28.0',
'version' => '1.28.0.0',
'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb',
'pretty_version' => 'v1.29.0',
'version' => '1.29.0.0',
'reference' => 'ef4d7e442ca910c4764bce785146269b30cb5fc4',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-intl-idn' => array(
'pretty_version' => 'v1.28.0',
'version' => '1.28.0.0',
'reference' => 'ecaafce9f77234a6a449d29e49267ba10499116d',
'pretty_version' => 'v1.29.0',
'version' => '1.29.0.0',
'reference' => 'a287ed7475f85bf6f61890146edbc932c0fff919',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-intl-normalizer' => array(
'pretty_version' => 'v1.28.0',
'version' => '1.28.0.0',
'reference' => '8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92',
'pretty_version' => 'v1.29.0',
'version' => '1.29.0.0',
'reference' => 'bc45c394692b948b4d383a08d7753968bed9a83d',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.28.0',
'version' => '1.28.0.0',
'reference' => '42292d99c55abe617799667f454222c54c60e229',
'pretty_version' => 'v1.29.0',
'version' => '1.29.0.0',
'reference' => '9773676c8a1bb1f8d4340a62efe641cf76eda7ec',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
@@ -167,9 +167,9 @@
),
),
'symfony/yaml' => array(
'pretty_version' => 'v6.4.0',
'version' => '6.4.0.0',
'reference' => '4f9237a1bb42455d609e6687d2613dde5b41a587',
'pretty_version' => 'v6.4.3',
'version' => '6.4.3.0',
'reference' => 'd75715985f0f94f978e3a8fa42533e10db921b90',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/yaml',
'aliases' => array(),

View File

@@ -30,9 +30,6 @@
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"

View File

@@ -33,9 +33,6 @@
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"

View File

@@ -28,9 +28,6 @@
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"

View File

@@ -30,9 +30,6 @@
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"

View File

@@ -42,7 +42,7 @@ class LintCommand extends Command
private ?\Closure $directoryIteratorProvider;
private ?\Closure $isReadableProvider;
public function __construct(string $name = null, callable $directoryIteratorProvider = null, callable $isReadableProvider = null)
public function __construct(?string $name = null, ?callable $directoryIteratorProvider = null, ?callable $isReadableProvider = null)
{
parent::__construct($name);
@@ -127,7 +127,7 @@ EOF
return $this->display($io, $filesInfo);
}
private function validate(string $content, int $flags, string $file = null): array
private function validate(string $content, int $flags, ?string $file = null): array
{
$prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) {
if (\E_USER_DEPRECATED === $level) {

View File

@@ -29,7 +29,7 @@ class ParseException extends RuntimeException
* @param string|null $snippet The snippet of code near the problem
* @param string|null $parsedFile The file name where the error occurred
*/
public function __construct(string $message, int $parsedLine = -1, string $snippet = null, string $parsedFile = null, \Throwable $previous = null)
public function __construct(string $message, int $parsedLine = -1, ?string $snippet = null, ?string $parsedFile = null, ?\Throwable $previous = null)
{
$this->parsedFile = $parsedFile;
$this->parsedLine = $parsedLine;

View File

@@ -34,7 +34,7 @@ class Inline
private static bool $objectForMap = false;
private static bool $constantSupport = false;
public static function initialize(int $flags, int $parsedLineNumber = null, string $parsedFilename = null): void
public static function initialize(int $flags, ?int $parsedLineNumber = null, ?string $parsedFilename = null): void
{
self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags);
self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
@@ -267,7 +267,7 @@ class Inline
*
* @throws ParseException When malformed inline YAML string is parsed
*/
public static function parseScalar(string $scalar, int $flags = 0, array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [], bool &$isQuoted = null): mixed
public static function parseScalar(string $scalar, int $flags = 0, ?array $delimiters = null, int &$i = 0, bool $evaluate = true, array &$references = [], ?bool &$isQuoted = null): mixed
{
if (\in_array($scalar[$i], ['"', "'"], true)) {
// quoted scalar
@@ -556,7 +556,7 @@ class Inline
*
* @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved
*/
private static function evaluateScalar(string $scalar, int $flags, array &$references = [], bool &$isQuotedString = null): mixed
private static function evaluateScalar(string $scalar, int $flags, array &$references = [], ?bool &$isQuotedString = null): mixed
{
$isQuotedString = false;
$scalar = trim($scalar);

View File

@@ -561,7 +561,7 @@ class Parser
*
* @throws ParseException When indentation problem are detected
*/
private function getNextEmbedBlock(int $indentation = null, bool $inSequence = false): string
private function getNextEmbedBlock(?int $indentation = null, bool $inSequence = false): string
{
$oldLineIndentation = $this->getCurrentLineIndentation();
@@ -1043,7 +1043,7 @@ class Parser
*
* @internal
*/
public static function preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int
public static function preg_match(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0): int
{
if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) {
throw new ParseException(preg_last_error_msg());

View File

@@ -1,6 +1,5 @@
<?php
use Kirby\Cms\Url;
use Kirby\Toolkit\Html;
/**
@@ -35,8 +34,8 @@ use Kirby\Toolkit\Html;
<link nonce="<?= $nonce ?>" rel="stylesheet" href="<?= $css ?>">
<?php endforeach ?>
<?php foreach ($assets['icons'] as $rel => $icon): ?>
<link nonce="<?= $nonce ?>" rel="<?= $rel ?>" href="<?= Url::to($icon['url']) ?>" type="<?= $icon['type'] ?>">
<?php foreach ($assets['icons'] as $icon): ?>
<?= Html::tag('link', null, $icon) ?>
<?php endforeach ?>
<?php foreach ($assets['js'] as $js): ?>