Initial commit
This commit is contained in:
commit
1ff19bf38f
830 changed files with 159212 additions and 0 deletions
15
kirby/.editorconfig
Normal file
15
kirby/.editorconfig
Normal file
|
@ -0,0 +1,15 @@
|
|||
# This file is for unifying the coding style for different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
# PHP PSR-2 Coding Standards
|
||||
# http://www.php-fig.org/psr/psr-2/
|
||||
|
||||
root = true
|
||||
|
||||
[*.php]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
3
kirby/SECURITY.md
Normal file
3
kirby/SECURITY.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Security Policy
|
||||
|
||||
Please see the [Security Policy on the Kirby website](https://getkirby.com/security) for a list of the currently supported Kirby versions and of past security incidents as well as for information on how to report security vulnerabilities in the Kirby core or in the Panel.
|
83
kirby/assets/whoops.css
Normal file
83
kirby/assets/whoops.css
Normal file
|
@ -0,0 +1,83 @@
|
|||
body {
|
||||
background: #efefef;
|
||||
font: normal normal 400 12px/1.5 -apple-system, BlinkMacSystemFont, Segoe UI,
|
||||
Roboto, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.left-panel {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #313740;
|
||||
}
|
||||
|
||||
.exc-title-primary {
|
||||
color: hsl(0, 71%, 55%);
|
||||
}
|
||||
|
||||
.frame.active {
|
||||
color: hsl(0, 71%, 55%);
|
||||
box-shadow: inset -5px 0 0 0 #d16464;
|
||||
}
|
||||
|
||||
.frame:not(.active):hover {
|
||||
background: rgba(203, 215, 229, 0.5);
|
||||
}
|
||||
|
||||
.rightButton {
|
||||
color: #999;
|
||||
box-shadow: inset 0 0 0 1px #777;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.rightButton:hover {
|
||||
box-shadow: inset 0 0 0 1px #555;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.details-heading {
|
||||
color: #7e9abf;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.frame-code {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
pre.code-block,
|
||||
code.code-block,
|
||||
.frame-args.code-block,
|
||||
.frame-args.code-block samp {
|
||||
background: #16171a;
|
||||
}
|
||||
|
||||
.linenums li.current {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.linenums li.current.active {
|
||||
background: rgba(209, 100, 100, 0.3);
|
||||
}
|
||||
|
||||
pre .atv,
|
||||
code .atv,
|
||||
pre .str,
|
||||
code .str {
|
||||
color: #a7bd68;
|
||||
}
|
||||
|
||||
pre .tag,
|
||||
code .tag {
|
||||
color: #d16464;
|
||||
}
|
||||
|
||||
pre .kwd,
|
||||
code .kwd {
|
||||
color: #8abeb7;
|
||||
}
|
||||
|
||||
pre .atn,
|
||||
code .atn {
|
||||
color: #de935f;
|
||||
}
|
35
kirby/bootstrap.php
Normal file
35
kirby/bootstrap.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Validate the PHP version to already
|
||||
* stop at older or too recent versions
|
||||
*/
|
||||
if (
|
||||
version_compare(PHP_VERSION, '7.3.0', '>=') === false ||
|
||||
version_compare(PHP_VERSION, '8.1.0', '<') === false
|
||||
) {
|
||||
die(include __DIR__ . '/views/php.php');
|
||||
}
|
||||
|
||||
if (is_file($autoloader = dirname(__DIR__) . '/vendor/autoload.php')) {
|
||||
|
||||
/**
|
||||
* Always prefer a site-wide Composer autoloader
|
||||
* if it exists, it means that the user has probably
|
||||
* installed additional packages
|
||||
*/
|
||||
include $autoloader;
|
||||
} elseif (is_file($autoloader = __DIR__ . '/vendor/autoload.php')) {
|
||||
|
||||
/**
|
||||
* Fall back to the local autoloader if that exists
|
||||
*/
|
||||
include $autoloader;
|
||||
} else {
|
||||
|
||||
/**
|
||||
* If neither one exists, don't bother searching;
|
||||
* it's a custom directory setup and the users need to
|
||||
* load the autoloader themselves
|
||||
*/
|
||||
}
|
3174
kirby/cacert.pem
Normal file
3174
kirby/cacert.pem
Normal file
File diff suppressed because it is too large
Load diff
77
kirby/composer.json
Normal file
77
kirby/composer.json
Normal file
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"name": "getkirby/cms",
|
||||
"type": "kirby-cms",
|
||||
"description": "The Kirby 3 core",
|
||||
"keywords": [
|
||||
"kirby",
|
||||
"cms",
|
||||
"core"
|
||||
],
|
||||
"homepage": "https://getkirby.com",
|
||||
"version": "3.5.7.1",
|
||||
"license": "proprietary",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kirby Team",
|
||||
"email": "support@getkirby.com",
|
||||
"homepage": "https://getkirby.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.3.0 <8.1.0",
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*",
|
||||
"claviska/simpleimage": "3.6.3",
|
||||
"filp/whoops": "2.12.1",
|
||||
"getkirby/composer-installer": "^1.2.0",
|
||||
"laminas/laminas-escaper": "2.7.0",
|
||||
"michelf/php-smartypants": "1.8.1",
|
||||
"mustangostang/spyc": "0.6.3",
|
||||
"phpmailer/phpmailer": "6.5.0",
|
||||
"true/punycode": "2.1.1"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"platform-check": false
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kirby\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"dependencies/"
|
||||
],
|
||||
"files": [
|
||||
"config/setup.php",
|
||||
"config/helpers.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"post-update-cmd": "curl -o cacert.pem https://curl.se/ca/cacert.pem",
|
||||
"analyze": [
|
||||
"@analyze:composer",
|
||||
"@analyze:psalm",
|
||||
"@analyze:phpcpd",
|
||||
"@analyze:phpmd"
|
||||
],
|
||||
"analyze:composer": "composer validate --strict --no-check-version --no-check-all",
|
||||
"analyze:phpcpd": "phpcpd --fuzzy --exclude tests --exclude vendor .",
|
||||
"analyze:phpmd": "phpmd . ansi phpmd.xml.dist --exclude 'dependencies/*,tests/*,vendor/*'",
|
||||
"analyze:psalm": "psalm",
|
||||
"build": "./scripts/build",
|
||||
"ci": [
|
||||
"@fix",
|
||||
"@analyze",
|
||||
"@test"
|
||||
],
|
||||
"fix": "php-cs-fixer fix",
|
||||
"test": "phpunit --stderr --coverage-html=tests/coverage",
|
||||
"zip": "composer archive --format=zip --file=dist"
|
||||
},
|
||||
"support": {
|
||||
"email": "support@getkirby.com",
|
||||
"issues": "https://github.com/getkirby/kirby/issues",
|
||||
"forum": "https://forum.getkirby.com",
|
||||
"source": "https://github.com/getkirby/kirby"
|
||||
}
|
||||
}
|
733
kirby/composer.lock
generated
Normal file
733
kirby/composer.lock
generated
Normal file
|
@ -0,0 +1,733 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "c087786719948c60e5d74492f70440a5",
|
||||
"packages": [
|
||||
{
|
||||
"name": "claviska/simpleimage",
|
||||
"version": "3.6.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/claviska/SimpleImage.git",
|
||||
"reference": "21b6f4bf4ef1927158b3e29bd0c2d99c6681c750"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/21b6f4bf4ef1927158b3e29bd0c2d99c6681c750",
|
||||
"reference": "21b6f4bf4ef1927158b3e29bd0c2d99c6681c750",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"league/color-extractor": "0.3.*",
|
||||
"php": ">=5.6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"claviska": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Cory LaViska",
|
||||
"homepage": "http://www.abeautifulsite.net/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"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/3.6.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/claviska",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-20T12:18:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.12.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "c13c0be93cff50f88bbd70827d993026821914dd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/c13c0be93cff50f88bbd70827d993026821914dd",
|
||||
"reference": "c13c0be93cff50f88bbd70827d993026821914dd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.5.9 || ^7.0 || ^8.0",
|
||||
"psr/log": "^1.0.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9 || ^1.0",
|
||||
"phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3",
|
||||
"symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
|
||||
"whoops/soap": "Formats errors as SOAP responses"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Whoops\\": "src/Whoops/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Filipe Dobreira",
|
||||
"homepage": "https://github.com/filp",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "php error handling for cool kids",
|
||||
"homepage": "https://filp.github.io/whoops/",
|
||||
"keywords": [
|
||||
"error",
|
||||
"exception",
|
||||
"handling",
|
||||
"library",
|
||||
"throwable",
|
||||
"whoops"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/filp/whoops/issues",
|
||||
"source": "https://github.com/filp/whoops/tree/2.12.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/denis-sokolov",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-25T12:00:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "getkirby/composer-installer",
|
||||
"version": "1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/getkirby/composer-installer.git",
|
||||
"reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/getkirby/composer-installer/zipball/c98ece30bfba45be7ce457e1102d1b169d922f3d",
|
||||
"reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-plugin-api": "^1.0 || ^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"composer/composer": "^1.8 || ^2.0"
|
||||
},
|
||||
"type": "composer-plugin",
|
||||
"extra": {
|
||||
"class": "Kirby\\ComposerInstaller\\Plugin"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kirby\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Kirby's custom Composer installer for the Kirby CMS and for Kirby plugins",
|
||||
"homepage": "https://getkirby.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/getkirby/composer-installer/issues",
|
||||
"source": "https://github.com/getkirby/composer-installer/tree/1.2.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://getkirby.com/buy",
|
||||
"type": "custom"
|
||||
}
|
||||
],
|
||||
"time": "2020-12-28T12:54:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-escaper",
|
||||
"version": "2.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-escaper.git",
|
||||
"reference": "5e04bc5ae5990b17159d79d331055e2c645e5cc5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/5e04bc5ae5990b17159d79d331055e2c645e5cc5",
|
||||
"reference": "5e04bc5ae5990b17159d79d331055e2c645e5cc5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"laminas/laminas-zendframework-bridge": "^1.0",
|
||||
"php": "^7.3 || ~8.0.0"
|
||||
},
|
||||
"replace": {
|
||||
"zendframework/zend-escaper": "^2.6.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"laminas/laminas-coding-standard": "~1.0.0",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"psalm/plugin-phpunit": "^0.12.2",
|
||||
"vimeo/psalm": "^3.16"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-iconv": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laminas\\Escaper\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs",
|
||||
"homepage": "https://laminas.dev",
|
||||
"keywords": [
|
||||
"escaper",
|
||||
"laminas"
|
||||
],
|
||||
"support": {
|
||||
"chat": "https://laminas.dev/chat",
|
||||
"docs": "https://docs.laminas.dev/laminas-escaper/",
|
||||
"forum": "https://discourse.laminas.dev",
|
||||
"issues": "https://github.com/laminas/laminas-escaper/issues",
|
||||
"rss": "https://github.com/laminas/laminas-escaper/releases.atom",
|
||||
"source": "https://github.com/laminas/laminas-escaper"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://funding.communitybridge.org/projects/laminas-project",
|
||||
"type": "community_bridge"
|
||||
}
|
||||
],
|
||||
"time": "2020-11-17T21:26:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-zendframework-bridge",
|
||||
"version": "1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-zendframework-bridge.git",
|
||||
"reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/13af2502d9bb6f7d33be2de4b51fb68c6cdb476e",
|
||||
"reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3",
|
||||
"psalm/plugin-phpunit": "^0.15.1",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"vimeo/psalm": "^4.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laminas": {
|
||||
"module": "Laminas\\ZendFrameworkBridge"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/autoload.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Laminas\\ZendFrameworkBridge\\": "src//"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "Alias legacy ZF class names to Laminas Project equivalents.",
|
||||
"keywords": [
|
||||
"ZendFramework",
|
||||
"autoloading",
|
||||
"laminas",
|
||||
"zf"
|
||||
],
|
||||
"support": {
|
||||
"forum": "https://discourse.laminas.dev/",
|
||||
"issues": "https://github.com/laminas/laminas-zendframework-bridge/issues",
|
||||
"rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom",
|
||||
"source": "https://github.com/laminas/laminas-zendframework-bridge"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://funding.communitybridge.org/projects/laminas-project",
|
||||
"type": "community_bridge"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-24T12:49:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/color-extractor",
|
||||
"version": "0.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/color-extractor.git",
|
||||
"reference": "837086ec60f50c84c611c613963e4ad2e2aec806"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/color-extractor/zipball/837086ec60f50c84c611c613963e4ad2e2aec806",
|
||||
"reference": "837086ec60f50c84c611c613963e4ad2e2aec806",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-gd": "*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"replace": {
|
||||
"matthecat/colorextractor": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "~2",
|
||||
"phpunit/phpunit": "~5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mathieu Lechat",
|
||||
"email": "math.lechat@gmail.com",
|
||||
"homepage": "http://matthecat.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Extract colors from an image as a human would do.",
|
||||
"homepage": "https://github.com/thephpleague/color-extractor",
|
||||
"keywords": [
|
||||
"color",
|
||||
"extract",
|
||||
"human",
|
||||
"image",
|
||||
"palette"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/color-extractor/issues",
|
||||
"source": "https://github.com/thephpleague/color-extractor/tree/master"
|
||||
},
|
||||
"time": "2016-12-15T09:30:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "michelf/php-smartypants",
|
||||
"version": "1.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/michelf/php-smartypants.git",
|
||||
"reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/michelf/php-smartypants/zipball/47d17c90a4dfd0ccf1f87e25c65e6c8012415aad",
|
||||
"reference": "47d17c90a4dfd0ccf1f87e25c65e6c8012415aad",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Michelf": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michel Fortin",
|
||||
"email": "michel.fortin@michelf.ca",
|
||||
"homepage": "https://michelf.ca/",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "John Gruber",
|
||||
"homepage": "https://daringfireball.net/"
|
||||
}
|
||||
],
|
||||
"description": "PHP SmartyPants",
|
||||
"homepage": "https://michelf.ca/projects/php-smartypants/",
|
||||
"keywords": [
|
||||
"dashes",
|
||||
"quotes",
|
||||
"spaces",
|
||||
"typographer",
|
||||
"typography"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/michelf/php-smartypants/issues",
|
||||
"source": "https://github.com/michelf/php-smartypants/tree/1.8.1"
|
||||
},
|
||||
"time": "2016-12-13T01:01:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mustangostang/spyc",
|
||||
"version": "0.6.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:mustangostang/spyc.git",
|
||||
"reference": "4627c838b16550b666d15aeae1e5289dd5b77da0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0",
|
||||
"reference": "4627c838b16550b666d15aeae1e5289dd5b77da0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.3.*@dev"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.5.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Spyc.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "mustangostang",
|
||||
"email": "vlad.andersen@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A simple YAML loader/dumper class for PHP",
|
||||
"homepage": "https://github.com/mustangostang/spyc/",
|
||||
"keywords": [
|
||||
"spyc",
|
||||
"yaml",
|
||||
"yml"
|
||||
],
|
||||
"time": "2019-09-10T13:16:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a5b5c43e50b7fba655f793ad27303cd74c57363c",
|
||||
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-filter": "*",
|
||||
"ext-hash": "*",
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"doctrine/annotations": "^1.2",
|
||||
"phpcompatibility/php-compatibility": "^9.3.5",
|
||||
"roave/security-advisories": "dev-latest",
|
||||
"squizlabs/php_codesniffer": "^3.5.6",
|
||||
"yoast/phpunit-polyfills": "^0.2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
|
||||
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"psr/log": "For optional PSR-3 debug logging",
|
||||
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PHPMailer\\PHPMailer\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-only"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marcus Bointon",
|
||||
"email": "phpmailer@synchromedia.co.uk"
|
||||
},
|
||||
{
|
||||
"name": "Jim Jagielski",
|
||||
"email": "jimjag@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Andy Prevost",
|
||||
"email": "codeworxtech@users.sourceforge.net"
|
||||
},
|
||||
{
|
||||
"name": "Brent R. Matzelle"
|
||||
}
|
||||
],
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/Synchro",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-16T14:33:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
|
||||
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Log\\": "Psr/Log/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"homepage": "https://github.com/php-fig/log",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/log/tree/1.1.4"
|
||||
},
|
||||
"time": "2021-05-03T11:20:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.23.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
|
||||
"reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.23-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
},
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-05-27T09:27:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "true/punycode",
|
||||
"version": "v2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/true/php-punycode.git",
|
||||
"reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/true/php-punycode/zipball/a4d0c11a36dd7f4e7cd7096076cab6d3378a071e",
|
||||
"reference": "a4d0c11a36dd7f4e7cd7096076cab6d3378a071e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"symfony/polyfill-mbstring": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.7",
|
||||
"squizlabs/php_codesniffer": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"TrueBV\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Renan Gonçalves",
|
||||
"email": "renan.saddam@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)",
|
||||
"homepage": "https://github.com/true/php-punycode",
|
||||
"keywords": [
|
||||
"idna",
|
||||
"punycode"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/true/php-punycode/issues",
|
||||
"source": "https://github.com/true/php-punycode/tree/master"
|
||||
},
|
||||
"time": "2016-11-16T10:37:54+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=7.3.0 <8.1.0",
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.1.0"
|
||||
}
|
62
kirby/config/aliases.php
Normal file
62
kirby/config/aliases.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return [
|
||||
// cms classes
|
||||
'asset' => 'Kirby\Cms\Asset',
|
||||
'collection' => 'Kirby\Cms\Collection',
|
||||
'dir' => 'Kirby\Cms\Dir',
|
||||
'field' => 'Kirby\Cms\Field',
|
||||
'file' => 'Kirby\Cms\File',
|
||||
'files' => 'Kirby\Cms\Files',
|
||||
'html' => 'Kirby\Cms\Html',
|
||||
'kirby' => 'Kirby\Cms\App',
|
||||
'page' => 'Kirby\Cms\Page',
|
||||
'pages' => 'Kirby\Cms\Pages',
|
||||
'pagination' => 'Kirby\Cms\Pagination',
|
||||
'r' => 'Kirby\Cms\R',
|
||||
'response' => 'Kirby\Cms\Response',
|
||||
's' => 'Kirby\Cms\S',
|
||||
'site' => 'Kirby\Cms\Site',
|
||||
'structure' => 'Kirby\Cms\Structure',
|
||||
'url' => 'Kirby\Cms\Url',
|
||||
'user' => 'Kirby\Cms\User',
|
||||
'users' => 'Kirby\Cms\Users',
|
||||
'visitor' => 'Kirby\Cms\Visitor',
|
||||
|
||||
// data handler
|
||||
'data' => 'Kirby\Data\Data',
|
||||
'json' => 'Kirby\Data\Json',
|
||||
'yaml' => 'Kirby\Data\Yaml',
|
||||
|
||||
// data classes
|
||||
'database' => 'Kirby\Database\Database',
|
||||
'db' => 'Kirby\Database\Db',
|
||||
|
||||
// exceptions
|
||||
'errorpageexception' => 'Kirby\Exception\ErrorPageException',
|
||||
|
||||
// http classes
|
||||
'cookie' => 'Kirby\Http\Cookie',
|
||||
'header' => 'Kirby\Http\Header',
|
||||
'remote' => 'Kirby\Http\Remote',
|
||||
'server' => 'Kirby\Http\Server',
|
||||
|
||||
// image classes
|
||||
'dimensions' => 'Kirby\Image\Dimensions',
|
||||
|
||||
// toolkit classes
|
||||
'a' => 'Kirby\Toolkit\A',
|
||||
'c' => 'Kirby\Toolkit\Config',
|
||||
'config' => 'Kirby\Toolkit\Config',
|
||||
'escape' => 'Kirby\Toolkit\Escape',
|
||||
'f' => 'Kirby\Toolkit\F',
|
||||
'i18n' => 'Kirby\Toolkit\I18n',
|
||||
'mime' => 'Kirby\Toolkit\Mime',
|
||||
'obj' => 'Kirby\Toolkit\Obj',
|
||||
'str' => 'Kirby\Toolkit\Str',
|
||||
'tpl' => 'Kirby\Toolkit\Tpl',
|
||||
'v' => 'Kirby\Toolkit\V',
|
||||
'xml' => 'Kirby\Toolkit\Xml'
|
||||
];
|
||||
// @codeCoverageIgnoreEnd
|
24
kirby/config/api/authentication.php
Normal file
24
kirby/config/api/authentication.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\PermissionException;
|
||||
|
||||
return function () {
|
||||
$auth = $this->kirby()->auth();
|
||||
$allowImpersonation = $this->kirby()->option('api.allowImpersonation') ?? false;
|
||||
|
||||
// csrf token check
|
||||
if ($auth->type($allowImpersonation) === 'session' && $auth->csrf() === false) {
|
||||
throw new PermissionException('Unauthenticated');
|
||||
}
|
||||
|
||||
// get user from session or basic auth
|
||||
if ($user = $auth->user(null, $allowImpersonation)) {
|
||||
if ($user->role()->permissions()->for('access', 'panel') === false) {
|
||||
throw new PermissionException(['key' => 'access.panel']);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
throw new PermissionException('Unauthenticated');
|
||||
};
|
72
kirby/config/api/collections.php
Normal file
72
kirby/config/api/collections.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Api Collection Definitions
|
||||
*/
|
||||
return [
|
||||
|
||||
/**
|
||||
* Children
|
||||
*/
|
||||
'children' => [
|
||||
'model' => 'page',
|
||||
'type' => 'Kirby\Cms\Pages',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
/**
|
||||
* Files
|
||||
*/
|
||||
'files' => [
|
||||
'model' => 'file',
|
||||
'type' => 'Kirby\Cms\Files'
|
||||
],
|
||||
|
||||
/**
|
||||
* Languages
|
||||
*/
|
||||
'languages' => [
|
||||
'model' => 'language',
|
||||
'type' => 'Kirby\Cms\Languages'
|
||||
],
|
||||
|
||||
/**
|
||||
* Pages
|
||||
*/
|
||||
'pages' => [
|
||||
'model' => 'page',
|
||||
'type' => 'Kirby\Cms\Pages',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
/**
|
||||
* Roles
|
||||
*/
|
||||
'roles' => [
|
||||
'model' => 'role',
|
||||
'type' => 'Kirby\Cms\Roles',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
/**
|
||||
* Translations
|
||||
*/
|
||||
'translations' => [
|
||||
'model' => 'translation',
|
||||
'type' => 'Kirby\Cms\Translations',
|
||||
'view' => 'compact'
|
||||
],
|
||||
|
||||
/**
|
||||
* Users
|
||||
*/
|
||||
'users' => [
|
||||
'default' => function () {
|
||||
return $this->users();
|
||||
},
|
||||
'model' => 'user',
|
||||
'type' => 'Kirby\Cms\Users',
|
||||
'view' => 'compact'
|
||||
]
|
||||
|
||||
];
|
20
kirby/config/api/models.php
Normal file
20
kirby/config/api/models.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Api Model Definitions
|
||||
*/
|
||||
return [
|
||||
'File' => include __DIR__ . '/models/File.php',
|
||||
'FileBlueprint' => include __DIR__ . '/models/FileBlueprint.php',
|
||||
'FileVersion' => include __DIR__ . '/models/FileVersion.php',
|
||||
'Language' => include __DIR__ . '/models/Language.php',
|
||||
'Page' => include __DIR__ . '/models/Page.php',
|
||||
'PageBlueprint' => include __DIR__ . '/models/PageBlueprint.php',
|
||||
'Role' => include __DIR__ . '/models/Role.php',
|
||||
'Site' => include __DIR__ . '/models/Site.php',
|
||||
'SiteBlueprint' => include __DIR__ . '/models/SiteBlueprint.php',
|
||||
'System' => include __DIR__ . '/models/System.php',
|
||||
'Translation' => include __DIR__ . '/models/Translation.php',
|
||||
'User' => include __DIR__ . '/models/User.php',
|
||||
'UserBlueprint' => include __DIR__ . '/models/UserBlueprint.php',
|
||||
];
|
166
kirby/config/api/models/File.php
Normal file
166
kirby/config/api/models/File.php
Normal file
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\File;
|
||||
use Kirby\Cms\Form;
|
||||
|
||||
/**
|
||||
* File
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'blueprint' => function (File $file) {
|
||||
return $file->blueprint();
|
||||
},
|
||||
'content' => function (File $file) {
|
||||
return Form::for($file)->values();
|
||||
},
|
||||
'dimensions' => function (File $file) {
|
||||
return $file->dimensions()->toArray();
|
||||
},
|
||||
'dragText' => function (File $file) {
|
||||
return $file->dragText();
|
||||
},
|
||||
'exists' => function (File $file) {
|
||||
return $file->exists();
|
||||
},
|
||||
'extension' => function (File $file) {
|
||||
return $file->extension();
|
||||
},
|
||||
'filename' => function (File $file) {
|
||||
return $file->filename();
|
||||
},
|
||||
'id' => function (File $file) {
|
||||
return $file->id();
|
||||
},
|
||||
'link' => function (File $file) {
|
||||
return $file->panelUrl(true);
|
||||
},
|
||||
'mime' => function (File $file) {
|
||||
return $file->mime();
|
||||
},
|
||||
'modified' => function (File $file) {
|
||||
return $file->modified('c');
|
||||
},
|
||||
'name' => function (File $file) {
|
||||
return $file->name();
|
||||
},
|
||||
'next' => function (File $file) {
|
||||
return $file->next();
|
||||
},
|
||||
'nextWithTemplate' => function (File $file) {
|
||||
$files = $file->templateSiblings()->sort('sort', 'asc', 'filename', 'asc');
|
||||
$index = $files->indexOf($file);
|
||||
|
||||
return $files->nth($index + 1);
|
||||
},
|
||||
'niceSize' => function (File $file) {
|
||||
return $file->niceSize();
|
||||
},
|
||||
'options' => function (File $file) {
|
||||
return $file->panelOptions();
|
||||
},
|
||||
'panelIcon' => function (File $file) {
|
||||
return $file->panelIcon();
|
||||
},
|
||||
'panelImage' => function (File $file) {
|
||||
return $file->panelImage();
|
||||
},
|
||||
'panelUrl' => function (File $file) {
|
||||
return $file->panelUrl(true);
|
||||
},
|
||||
'prev' => function (File $file) {
|
||||
return $file->prev();
|
||||
},
|
||||
'prevWithTemplate' => function (File $file) {
|
||||
$files = $file->templateSiblings()->sort('sort', 'asc', 'filename', 'asc');
|
||||
$index = $files->indexOf($file);
|
||||
|
||||
return $files->nth($index - 1);
|
||||
},
|
||||
'parent' => function (File $file) {
|
||||
return $file->parent();
|
||||
},
|
||||
'parents' => function (File $file) {
|
||||
return $file->parents()->flip();
|
||||
},
|
||||
'size' => function (File $file) {
|
||||
return $file->size();
|
||||
},
|
||||
'template' => function (File $file) {
|
||||
return $file->template();
|
||||
},
|
||||
'thumbs' => function ($file) {
|
||||
if ($file->isResizable() === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'tiny' => $file->resize(128)->url(),
|
||||
'small' => $file->resize(256)->url(),
|
||||
'medium' => $file->resize(512)->url(),
|
||||
'large' => $file->resize(768)->url(),
|
||||
'huge' => $file->resize(1024)->url(),
|
||||
];
|
||||
},
|
||||
'type' => function (File $file) {
|
||||
return $file->type();
|
||||
},
|
||||
'url' => function (File $file) {
|
||||
return $file->url(true);
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\File',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'content',
|
||||
'dimensions',
|
||||
'exists',
|
||||
'extension',
|
||||
'filename',
|
||||
'id',
|
||||
'link',
|
||||
'mime',
|
||||
'modified',
|
||||
'name',
|
||||
'next' => 'compact',
|
||||
'niceSize',
|
||||
'parent' => 'compact',
|
||||
'options',
|
||||
'prev' => 'compact',
|
||||
'size',
|
||||
'template',
|
||||
'type',
|
||||
'url'
|
||||
],
|
||||
'compact' => [
|
||||
'filename',
|
||||
'id',
|
||||
'link',
|
||||
'type',
|
||||
'url',
|
||||
],
|
||||
'panel' => [
|
||||
'blueprint',
|
||||
'content',
|
||||
'dimensions',
|
||||
'extension',
|
||||
'filename',
|
||||
'id',
|
||||
'link',
|
||||
'mime',
|
||||
'modified',
|
||||
'name',
|
||||
'nextWithTemplate' => 'compact',
|
||||
'niceSize',
|
||||
'options',
|
||||
'panelIcon',
|
||||
'panelImage',
|
||||
'parent' => 'compact',
|
||||
'parents' => ['id', 'slug', 'title'],
|
||||
'prevWithTemplate' => 'compact',
|
||||
'template',
|
||||
'type',
|
||||
'url'
|
||||
]
|
||||
],
|
||||
];
|
26
kirby/config/api/models/FileBlueprint.php
Normal file
26
kirby/config/api/models/FileBlueprint.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\FileBlueprint;
|
||||
|
||||
/**
|
||||
* FileBlueprint
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'name' => function (FileBlueprint $blueprint) {
|
||||
return $blueprint->name();
|
||||
},
|
||||
'options' => function (FileBlueprint $blueprint) {
|
||||
return $blueprint->options();
|
||||
},
|
||||
'tabs' => function (FileBlueprint $blueprint) {
|
||||
return $blueprint->tabs();
|
||||
},
|
||||
'title' => function (FileBlueprint $blueprint) {
|
||||
return $blueprint->title();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\FileBlueprint',
|
||||
'views' => [
|
||||
],
|
||||
];
|
83
kirby/config/api/models/FileVersion.php
Normal file
83
kirby/config/api/models/FileVersion.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\FileVersion;
|
||||
|
||||
/**
|
||||
* FileVersion
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'dimensions' => function (FileVersion $file) {
|
||||
return $file->dimensions()->toArray();
|
||||
},
|
||||
'exists' => function (FileVersion $file) {
|
||||
return $file->exists();
|
||||
},
|
||||
'extension' => function (FileVersion $file) {
|
||||
return $file->extension();
|
||||
},
|
||||
'filename' => function (FileVersion $file) {
|
||||
return $file->filename();
|
||||
},
|
||||
'id' => function (FileVersion $file) {
|
||||
return $file->id();
|
||||
},
|
||||
'mime' => function (FileVersion $file) {
|
||||
return $file->mime();
|
||||
},
|
||||
'modified' => function (FileVersion $file) {
|
||||
return $file->modified('c');
|
||||
},
|
||||
'name' => function (FileVersion $file) {
|
||||
return $file->name();
|
||||
},
|
||||
'niceSize' => function (FileVersion $file) {
|
||||
return $file->niceSize();
|
||||
},
|
||||
'size' => function (FileVersion $file) {
|
||||
return $file->size();
|
||||
},
|
||||
'type' => function (FileVersion $file) {
|
||||
return $file->type();
|
||||
},
|
||||
'url' => function (FileVersion $file) {
|
||||
return $file->url(true);
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\FileVersion',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'dimensions',
|
||||
'exists',
|
||||
'extension',
|
||||
'filename',
|
||||
'id',
|
||||
'mime',
|
||||
'modified',
|
||||
'name',
|
||||
'niceSize',
|
||||
'size',
|
||||
'type',
|
||||
'url'
|
||||
],
|
||||
'compact' => [
|
||||
'filename',
|
||||
'id',
|
||||
'type',
|
||||
'url',
|
||||
],
|
||||
'panel' => [
|
||||
'dimensions',
|
||||
'extension',
|
||||
'filename',
|
||||
'id',
|
||||
'mime',
|
||||
'modified',
|
||||
'name',
|
||||
'niceSize',
|
||||
'template',
|
||||
'type',
|
||||
'url'
|
||||
]
|
||||
],
|
||||
];
|
44
kirby/config/api/models/Language.php
Normal file
44
kirby/config/api/models/Language.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Language;
|
||||
|
||||
/**
|
||||
* Language
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'code' => function (Language $language) {
|
||||
return $language->code();
|
||||
},
|
||||
'default' => function (Language $language) {
|
||||
return $language->isDefault();
|
||||
},
|
||||
'direction' => function (Language $language) {
|
||||
return $language->direction();
|
||||
},
|
||||
'locale' => function (Language $language) {
|
||||
return $language->locale();
|
||||
},
|
||||
'name' => function (Language $language) {
|
||||
return $language->name();
|
||||
},
|
||||
'rules' => function (Language $language) {
|
||||
return $language->rules();
|
||||
},
|
||||
'url' => function (Language $language) {
|
||||
return $language->url();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\Language',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'code',
|
||||
'default',
|
||||
'direction',
|
||||
'locale',
|
||||
'name',
|
||||
'rules',
|
||||
'url'
|
||||
]
|
||||
]
|
||||
];
|
157
kirby/config/api/models/Page.php
Normal file
157
kirby/config/api/models/Page.php
Normal file
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Form;
|
||||
use Kirby\Cms\Page;
|
||||
|
||||
/**
|
||||
* Page
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'blueprint' => function (Page $page) {
|
||||
return $page->blueprint();
|
||||
},
|
||||
'blueprints' => function (Page $page) {
|
||||
return $page->blueprints();
|
||||
},
|
||||
'children' => function (Page $page) {
|
||||
return $page->children();
|
||||
},
|
||||
'content' => function (Page $page) {
|
||||
return Form::for($page)->values();
|
||||
},
|
||||
'drafts' => function (Page $page) {
|
||||
return $page->drafts();
|
||||
},
|
||||
'errors' => function (Page $page) {
|
||||
return $page->errors();
|
||||
},
|
||||
'files' => function (Page $page) {
|
||||
return $page->files()->sort('sort', 'asc', 'filename', 'asc');
|
||||
},
|
||||
'hasChildren' => function (Page $page) {
|
||||
return $page->hasChildren();
|
||||
},
|
||||
'hasDrafts' => function (Page $page) {
|
||||
return $page->hasDrafts();
|
||||
},
|
||||
'hasFiles' => function (Page $page) {
|
||||
return $page->hasFiles();
|
||||
},
|
||||
'id' => function (Page $page) {
|
||||
return $page->id();
|
||||
},
|
||||
'isSortable' => function (Page $page) {
|
||||
return $page->isSortable();
|
||||
},
|
||||
'next' => function (Page $page) {
|
||||
return $page
|
||||
->nextAll()
|
||||
->filter('intendedTemplate', $page->intendedTemplate())
|
||||
->filter('status', $page->status())
|
||||
->filter('isReadable', true)
|
||||
->first();
|
||||
},
|
||||
'num' => function (Page $page) {
|
||||
return $page->num();
|
||||
},
|
||||
'options' => function (Page $page) {
|
||||
return $page->panelOptions(['preview']);
|
||||
},
|
||||
'panelIcon' => function (Page $page) {
|
||||
return $page->panelIcon();
|
||||
},
|
||||
'panelImage' => function (Page $page) {
|
||||
return $page->panelImage();
|
||||
},
|
||||
'parent' => function (Page $page) {
|
||||
return $page->parent();
|
||||
},
|
||||
'parents' => function (Page $page) {
|
||||
return $page->parents()->flip();
|
||||
},
|
||||
'prev' => function (Page $page) {
|
||||
return $page
|
||||
->prevAll()
|
||||
->filter('intendedTemplate', $page->intendedTemplate())
|
||||
->filter('status', $page->status())
|
||||
->filter('isReadable', true)
|
||||
->last();
|
||||
},
|
||||
'previewUrl' => function (Page $page) {
|
||||
return $page->previewUrl();
|
||||
},
|
||||
'siblings' => function (Page $page) {
|
||||
if ($page->isDraft() === true) {
|
||||
return $page->parentModel()->children()->not($page);
|
||||
} else {
|
||||
return $page->siblings();
|
||||
}
|
||||
},
|
||||
'slug' => function (Page $page) {
|
||||
return $page->slug();
|
||||
},
|
||||
'status' => function (Page $page) {
|
||||
return $page->status();
|
||||
},
|
||||
'template' => function (Page $page) {
|
||||
return $page->intendedTemplate()->name();
|
||||
},
|
||||
'title' => function (Page $page) {
|
||||
return $page->title()->value();
|
||||
},
|
||||
'url' => function (Page $page) {
|
||||
return $page->url();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\Page',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'id',
|
||||
'title',
|
||||
'url',
|
||||
'num'
|
||||
],
|
||||
'default' => [
|
||||
'content',
|
||||
'id',
|
||||
'status',
|
||||
'num',
|
||||
'options',
|
||||
'parent' => 'compact',
|
||||
'slug',
|
||||
'template',
|
||||
'title',
|
||||
'url'
|
||||
],
|
||||
'panel' => [
|
||||
'id',
|
||||
'blueprint',
|
||||
'content',
|
||||
'status',
|
||||
'options',
|
||||
'next' => ['id', 'slug', 'title'],
|
||||
'parents' => ['id', 'slug', 'title'],
|
||||
'prev' => ['id', 'slug', 'title'],
|
||||
'previewUrl',
|
||||
'slug',
|
||||
'title',
|
||||
'url'
|
||||
],
|
||||
'selector' => [
|
||||
'id',
|
||||
'title',
|
||||
'parent' => [
|
||||
'id',
|
||||
'title'
|
||||
],
|
||||
'children' => [
|
||||
'hasChildren',
|
||||
'id',
|
||||
'panelIcon',
|
||||
'panelImage',
|
||||
'title',
|
||||
],
|
||||
]
|
||||
],
|
||||
];
|
35
kirby/config/api/models/PageBlueprint.php
Normal file
35
kirby/config/api/models/PageBlueprint.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\PageBlueprint;
|
||||
|
||||
/**
|
||||
* PageBlueprint
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'name' => function (PageBlueprint $blueprint) {
|
||||
return $blueprint->name();
|
||||
},
|
||||
'num' => function (PageBlueprint $blueprint) {
|
||||
return $blueprint->num();
|
||||
},
|
||||
'options' => function (PageBlueprint $blueprint) {
|
||||
return $blueprint->options();
|
||||
},
|
||||
'preview' => function (PageBlueprint $blueprint) {
|
||||
return $blueprint->preview();
|
||||
},
|
||||
'status' => function (PageBlueprint $blueprint) {
|
||||
return $blueprint->status();
|
||||
},
|
||||
'tabs' => function (PageBlueprint $blueprint) {
|
||||
return $blueprint->tabs();
|
||||
},
|
||||
'title' => function (PageBlueprint $blueprint) {
|
||||
return $blueprint->title();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\PageBlueprint',
|
||||
'views' => [
|
||||
],
|
||||
];
|
31
kirby/config/api/models/Role.php
Normal file
31
kirby/config/api/models/Role.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Role;
|
||||
|
||||
/**
|
||||
* Role
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'description' => function (Role $role) {
|
||||
return $role->description();
|
||||
},
|
||||
'name' => function (Role $role) {
|
||||
return $role->name();
|
||||
},
|
||||
'permissions' => function (Role $role) {
|
||||
return $role->permissions()->toArray();
|
||||
},
|
||||
'title' => function (Role $role) {
|
||||
return $role->title();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\Role',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'description',
|
||||
'name',
|
||||
'title'
|
||||
]
|
||||
]
|
||||
];
|
72
kirby/config/api/models/Site.php
Normal file
72
kirby/config/api/models/Site.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Form;
|
||||
use Kirby\Cms\Site;
|
||||
|
||||
/**
|
||||
* Site
|
||||
*/
|
||||
return [
|
||||
'default' => function () {
|
||||
return $this->site();
|
||||
},
|
||||
'fields' => [
|
||||
'blueprint' => function (Site $site) {
|
||||
return $site->blueprint();
|
||||
},
|
||||
'children' => function (Site $site) {
|
||||
return $site->children();
|
||||
},
|
||||
'content' => function (Site $site) {
|
||||
return Form::for($site)->values();
|
||||
},
|
||||
'drafts' => function (Site $site) {
|
||||
return $site->drafts();
|
||||
},
|
||||
'files' => function (Site $site) {
|
||||
return $site->files()->sort('sort', 'asc', 'filename', 'asc');
|
||||
},
|
||||
'options' => function (Site $site) {
|
||||
return $site->permissions()->toArray();
|
||||
},
|
||||
'previewUrl' => function (Site $site) {
|
||||
return $site->previewUrl();
|
||||
},
|
||||
'title' => function (Site $site) {
|
||||
return $site->title()->value();
|
||||
},
|
||||
'url' => function (Site $site) {
|
||||
return $site->url();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\Site',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'title',
|
||||
'url'
|
||||
],
|
||||
'default' => [
|
||||
'content',
|
||||
'options',
|
||||
'title',
|
||||
'url'
|
||||
],
|
||||
'panel' => [
|
||||
'title',
|
||||
'blueprint',
|
||||
'content',
|
||||
'options',
|
||||
'previewUrl',
|
||||
'url'
|
||||
],
|
||||
'selector' => [
|
||||
'title',
|
||||
'children' => [
|
||||
'id',
|
||||
'title',
|
||||
'panelIcon',
|
||||
'hasChildren'
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
26
kirby/config/api/models/SiteBlueprint.php
Normal file
26
kirby/config/api/models/SiteBlueprint.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\SiteBlueprint;
|
||||
|
||||
/**
|
||||
* SiteBlueprint
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'name' => function (SiteBlueprint $blueprint) {
|
||||
return $blueprint->name();
|
||||
},
|
||||
'options' => function (SiteBlueprint $blueprint) {
|
||||
return $blueprint->options();
|
||||
},
|
||||
'tabs' => function (SiteBlueprint $blueprint) {
|
||||
return $blueprint->tabs();
|
||||
},
|
||||
'title' => function (SiteBlueprint $blueprint) {
|
||||
return $blueprint->title();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\SiteBlueprint',
|
||||
'views' => [
|
||||
],
|
||||
];
|
136
kirby/config/api/models/System.php
Normal file
136
kirby/config/api/models/System.php
Normal file
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\System;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* System
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'ascii' => function () {
|
||||
return Str::$ascii;
|
||||
},
|
||||
'authStatus' => function () {
|
||||
return $this->kirby()->auth()->status()->toArray();
|
||||
},
|
||||
'defaultLanguage' => function () {
|
||||
return $this->kirby()->panelLanguage();
|
||||
},
|
||||
'isOk' => function (System $system) {
|
||||
return $system->isOk();
|
||||
},
|
||||
'isInstallable' => function (System $system) {
|
||||
return $system->isInstallable();
|
||||
},
|
||||
'isInstalled' => function (System $system) {
|
||||
return $system->isInstalled();
|
||||
},
|
||||
'isLocal' => function (System $system) {
|
||||
return $system->isLocal();
|
||||
},
|
||||
'multilang' => function () {
|
||||
return $this->kirby()->option('languages', false) !== false;
|
||||
},
|
||||
'languages' => function () {
|
||||
return $this->kirby()->languages();
|
||||
},
|
||||
'license' => function (System $system) {
|
||||
return $system->license();
|
||||
},
|
||||
'locales' => function () {
|
||||
$locales = [];
|
||||
$translations = $this->kirby()->translations();
|
||||
foreach ($translations as $translation) {
|
||||
$locales[$translation->code()] = $translation->locale();
|
||||
}
|
||||
return $locales;
|
||||
},
|
||||
'loginMethods' => function (System $system) {
|
||||
return array_keys($system->loginMethods());
|
||||
},
|
||||
'requirements' => function (System $system) {
|
||||
return $system->toArray();
|
||||
},
|
||||
'site' => function () {
|
||||
try {
|
||||
return $this->site()->blueprint()->title();
|
||||
} catch (Throwable $e) {
|
||||
return $this->site()->title()->value();
|
||||
}
|
||||
},
|
||||
'slugs' => function () {
|
||||
return Str::$language;
|
||||
},
|
||||
'title' => function () {
|
||||
return $this->site()->title()->value();
|
||||
},
|
||||
'translation' => function () {
|
||||
if ($user = $this->user()) {
|
||||
$translationCode = $user->language();
|
||||
} else {
|
||||
$translationCode = $this->kirby()->panelLanguage();
|
||||
}
|
||||
|
||||
if ($translation = $this->kirby()->translation($translationCode)) {
|
||||
return $translation;
|
||||
} else {
|
||||
return $this->kirby()->translation('en');
|
||||
}
|
||||
},
|
||||
'kirbytext' => function () {
|
||||
return $this->kirby()->option('panel.kirbytext') ?? true;
|
||||
},
|
||||
'user' => function () {
|
||||
return $this->user();
|
||||
},
|
||||
'version' => function () {
|
||||
$user = $this->user();
|
||||
|
||||
if ($user && $user->role()->permissions()->for('access', 'settings') === true) {
|
||||
return $this->kirby()->version();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
],
|
||||
'type' => 'Kirby\Cms\System',
|
||||
'views' => [
|
||||
'login' => [
|
||||
'authStatus',
|
||||
'isOk',
|
||||
'isInstallable',
|
||||
'isInstalled',
|
||||
'loginMethods',
|
||||
'title',
|
||||
'translation'
|
||||
],
|
||||
'troubleshooting' => [
|
||||
'isOk',
|
||||
'isInstallable',
|
||||
'isInstalled',
|
||||
'title',
|
||||
'translation',
|
||||
'requirements'
|
||||
],
|
||||
'panel' => [
|
||||
'ascii',
|
||||
'defaultLanguage',
|
||||
'isOk',
|
||||
'isInstalled',
|
||||
'isLocal',
|
||||
'kirbytext',
|
||||
'languages',
|
||||
'license',
|
||||
'locales',
|
||||
'multilang',
|
||||
'requirements',
|
||||
'site',
|
||||
'slugs',
|
||||
'title',
|
||||
'translation',
|
||||
'user' => 'auth',
|
||||
'version'
|
||||
]
|
||||
],
|
||||
];
|
34
kirby/config/api/models/Translation.php
Normal file
34
kirby/config/api/models/Translation.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Translation;
|
||||
|
||||
/**
|
||||
* Translation
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'author' => function (Translation $translation) {
|
||||
return $translation->author();
|
||||
},
|
||||
'data' => function (Translation $translation) {
|
||||
return $translation->dataWithFallback();
|
||||
},
|
||||
'direction' => function (Translation $translation) {
|
||||
return $translation->direction();
|
||||
},
|
||||
'id' => function (Translation $translation) {
|
||||
return $translation->id();
|
||||
},
|
||||
'name' => function (Translation $translation) {
|
||||
return $translation->name();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\Translation',
|
||||
'views' => [
|
||||
'compact' => [
|
||||
'direction',
|
||||
'id',
|
||||
'name'
|
||||
]
|
||||
]
|
||||
];
|
108
kirby/config/api/models/User.php
Normal file
108
kirby/config/api/models/User.php
Normal file
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Form;
|
||||
use Kirby\Cms\User;
|
||||
|
||||
/**
|
||||
* User
|
||||
*/
|
||||
return [
|
||||
'default' => function () {
|
||||
return $this->user();
|
||||
},
|
||||
'fields' => [
|
||||
'avatar' => function (User $user) {
|
||||
return $user->avatar() ? $user->avatar()->crop(512) : null;
|
||||
},
|
||||
'blueprint' => function (User $user) {
|
||||
return $user->blueprint();
|
||||
},
|
||||
'content' => function (User $user) {
|
||||
return Form::for($user)->values();
|
||||
},
|
||||
'email' => function (User $user) {
|
||||
return $user->email();
|
||||
},
|
||||
'files' => function (User $user) {
|
||||
return $user->files()->sort('sort', 'asc', 'filename', 'asc');
|
||||
},
|
||||
'id' => function (User $user) {
|
||||
return $user->id();
|
||||
},
|
||||
'language' => function (User $user) {
|
||||
return $user->language();
|
||||
},
|
||||
'name' => function (User $user) {
|
||||
return $user->name()->value();
|
||||
},
|
||||
'next' => function (User $user) {
|
||||
return $user->next();
|
||||
},
|
||||
'options' => function (User $user) {
|
||||
return $user->panelOptions();
|
||||
},
|
||||
'permissions' => function (User $user) {
|
||||
return $user->role()->permissions()->toArray();
|
||||
},
|
||||
'prev' => function (User $user) {
|
||||
return $user->prev();
|
||||
},
|
||||
'role' => function (User $user) {
|
||||
return $user->role();
|
||||
},
|
||||
'roles' => function (User $user) {
|
||||
return $user->roles();
|
||||
},
|
||||
'username' => function (User $user) {
|
||||
return $user->username();
|
||||
}
|
||||
],
|
||||
'type' => 'Kirby\Cms\User',
|
||||
'views' => [
|
||||
'default' => [
|
||||
'avatar',
|
||||
'content',
|
||||
'email',
|
||||
'id',
|
||||
'language',
|
||||
'name',
|
||||
'next' => 'compact',
|
||||
'options',
|
||||
'prev' => 'compact',
|
||||
'role',
|
||||
'username'
|
||||
],
|
||||
'compact' => [
|
||||
'avatar' => 'compact',
|
||||
'id',
|
||||
'email',
|
||||
'language',
|
||||
'name',
|
||||
'role' => 'compact',
|
||||
'username'
|
||||
],
|
||||
'auth' => [
|
||||
'avatar' => 'compact',
|
||||
'permissions',
|
||||
'email',
|
||||
'id',
|
||||
'name',
|
||||
'role',
|
||||
'language'
|
||||
],
|
||||
'panel' => [
|
||||
'avatar' => 'compact',
|
||||
'blueprint',
|
||||
'content',
|
||||
'email',
|
||||
'id',
|
||||
'language',
|
||||
'name',
|
||||
'next' => ['id', 'name'],
|
||||
'options',
|
||||
'prev' => ['id', 'name'],
|
||||
'role',
|
||||
'username',
|
||||
],
|
||||
]
|
||||
];
|
26
kirby/config/api/models/UserBlueprint.php
Normal file
26
kirby/config/api/models/UserBlueprint.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\UserBlueprint;
|
||||
|
||||
/**
|
||||
* UserBlueprint
|
||||
*/
|
||||
return [
|
||||
'fields' => [
|
||||
'name' => function (UserBlueprint $blueprint) {
|
||||
return $blueprint->name();
|
||||
},
|
||||
'options' => function (UserBlueprint $blueprint) {
|
||||
return $blueprint->options();
|
||||
},
|
||||
'tabs' => function (UserBlueprint $blueprint) {
|
||||
return $blueprint->tabs();
|
||||
},
|
||||
'title' => function (UserBlueprint $blueprint) {
|
||||
return $blueprint->title();
|
||||
},
|
||||
],
|
||||
'type' => 'Kirby\Cms\UserBlueprint',
|
||||
'views' => [
|
||||
],
|
||||
];
|
26
kirby/config/api/routes.php
Normal file
26
kirby/config/api/routes.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Api Routes Definitions
|
||||
*/
|
||||
return function ($kirby) {
|
||||
$routes = array_merge(
|
||||
include __DIR__ . '/routes/auth.php',
|
||||
include __DIR__ . '/routes/pages.php',
|
||||
include __DIR__ . '/routes/roles.php',
|
||||
include __DIR__ . '/routes/site.php',
|
||||
include __DIR__ . '/routes/users.php',
|
||||
include __DIR__ . '/routes/files.php',
|
||||
include __DIR__ . '/routes/lock.php',
|
||||
include __DIR__ . '/routes/system.php',
|
||||
include __DIR__ . '/routes/translations.php'
|
||||
);
|
||||
|
||||
// only add the language routes if the
|
||||
// multi language setup is activated
|
||||
if ($kirby->option('languages', false) !== false) {
|
||||
$routes = array_merge($routes, include __DIR__ . '/routes/languages.php');
|
||||
}
|
||||
|
||||
return $routes;
|
||||
};
|
108
kirby/config/api/routes/auth.php
Normal file
108
kirby/config/api/routes/auth.php
Normal file
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Exception\NotFoundException;
|
||||
|
||||
/**
|
||||
* Authentication
|
||||
*/
|
||||
return [
|
||||
[
|
||||
'pattern' => 'auth',
|
||||
'method' => 'GET',
|
||||
'action' => function () {
|
||||
if ($user = $this->kirby()->auth()->user()) {
|
||||
return $this->resolve($user)->view('auth');
|
||||
}
|
||||
|
||||
throw new NotFoundException('The user cannot be found');
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'auth/code',
|
||||
'method' => 'POST',
|
||||
'auth' => false,
|
||||
'action' => function () {
|
||||
$auth = $this->kirby()->auth();
|
||||
|
||||
// csrf token check
|
||||
if ($auth->type() === 'session' && $auth->csrf() === false) {
|
||||
throw new InvalidArgumentException('Invalid CSRF token');
|
||||
}
|
||||
|
||||
$user = $auth->verifyChallenge($this->requestBody('code'));
|
||||
|
||||
return [
|
||||
'code' => 200,
|
||||
'status' => 'ok',
|
||||
'user' => $this->resolve($user)->view('auth')->toArray()
|
||||
];
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'auth/login',
|
||||
'method' => 'POST',
|
||||
'auth' => false,
|
||||
'action' => function () {
|
||||
$auth = $this->kirby()->auth();
|
||||
$methods = $this->kirby()->system()->loginMethods();
|
||||
|
||||
// csrf token check
|
||||
if ($auth->type() === 'session' && $auth->csrf() === false) {
|
||||
throw new InvalidArgumentException('Invalid CSRF token');
|
||||
}
|
||||
|
||||
$email = $this->requestBody('email');
|
||||
$long = $this->requestBody('long');
|
||||
$password = $this->requestBody('password');
|
||||
|
||||
if ($password) {
|
||||
if (isset($methods['password']) !== true) {
|
||||
throw new InvalidArgumentException('Login with password is not enabled');
|
||||
}
|
||||
|
||||
if (
|
||||
isset($methods['password']['2fa']) === true &&
|
||||
$methods['password']['2fa'] === true
|
||||
) {
|
||||
$status = $auth->login2fa($email, $password, $long);
|
||||
} else {
|
||||
$user = $auth->login($email, $password, $long);
|
||||
}
|
||||
} else {
|
||||
if (isset($methods['code']) === true) {
|
||||
$mode = 'login';
|
||||
} elseif (isset($methods['password-reset']) === true) {
|
||||
$mode = 'password-reset';
|
||||
} else {
|
||||
throw new InvalidArgumentException('Login without password is not enabled');
|
||||
}
|
||||
|
||||
$status = $auth->createChallenge($email, $long, $mode);
|
||||
}
|
||||
|
||||
if (isset($user)) {
|
||||
return [
|
||||
'code' => 200,
|
||||
'status' => 'ok',
|
||||
'user' => $this->resolve($user)->view('auth')->toArray()
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'code' => 200,
|
||||
'status' => 'ok',
|
||||
'challenge' => $status->challenge()
|
||||
];
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'auth/logout',
|
||||
'method' => 'POST',
|
||||
'auth' => false,
|
||||
'action' => function () {
|
||||
$this->kirby()->auth()->logout();
|
||||
return true;
|
||||
}
|
||||
],
|
||||
];
|
123
kirby/config/api/routes/files.php
Normal file
123
kirby/config/api/routes/files.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Files Routes
|
||||
*/
|
||||
return [
|
||||
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path, string $filename, string $sectionName) {
|
||||
if ($section = $this->file($path, $filename)->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $parent, string $filename, string $fieldName, string $path = null) {
|
||||
if ($file = $this->file($parent, $filename)) {
|
||||
return $this->fieldApi($file, $fieldName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path) {
|
||||
return $this->parent($path)->files()->sort('sort', 'asc', 'filename', 'asc');
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files',
|
||||
'method' => 'POST',
|
||||
'action' => function (string $path) {
|
||||
return $this->upload(function ($source, $filename) use ($path) {
|
||||
return $this->parent($path)->createFile([
|
||||
'source' => $source,
|
||||
'template' => $this->requestBody('template'),
|
||||
'filename' => $filename
|
||||
]);
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function (string $path) {
|
||||
$files = $this->parent($path)->files();
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $files->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $files->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/sort',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path) {
|
||||
return $this->parent($path)->files()->changeSort(
|
||||
$this->requestBody('files'),
|
||||
$this->requestBody('index')
|
||||
);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename)->update($this->requestBody(), $this->language(), true);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)',
|
||||
'method' => 'POST',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->upload(function ($source) use ($path, $filename) {
|
||||
return $this->file($path, $filename)->replace($source);
|
||||
});
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename)->delete();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)/name',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path, string $filename) {
|
||||
return $this->file($path, $filename)->changeName($this->requestBody('name'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'files/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function () {
|
||||
$files = $this
|
||||
->site()
|
||||
->index(true)
|
||||
->filter('isReadable', true)
|
||||
->files();
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $files->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $files->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
];
|
46
kirby/config/api/routes/languages.php
Normal file
46
kirby/config/api/routes/languages.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Roles Routes
|
||||
*/
|
||||
return [
|
||||
[
|
||||
'pattern' => 'languages',
|
||||
'method' => 'GET',
|
||||
'action' => function () {
|
||||
return $this->kirby()->languages();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'languages',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
return $this->kirby()->languages()->create($this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'languages/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $code) {
|
||||
return $this->kirby()->languages()->find($code);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'languages/(:any)',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $code) {
|
||||
if ($language = $this->kirby()->languages()->find($code)) {
|
||||
return $language->update($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'languages/(:any)',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $code) {
|
||||
if ($language = $this->kirby()->languages()->find($code)) {
|
||||
return $language->delete();
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
99
kirby/config/api/routes/lock.php
Normal file
99
kirby/config/api/routes/lock.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\Exception;
|
||||
|
||||
/**
|
||||
* Content Lock Routes
|
||||
*/
|
||||
return [
|
||||
[
|
||||
'pattern' => '(:all)/lock',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path) {
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return [
|
||||
'supported' => true,
|
||||
'locked' => $lock->get()
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'supported' => false,
|
||||
'locked' => null
|
||||
];
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/lock',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path) {
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->create();
|
||||
}
|
||||
|
||||
throw new Exception([
|
||||
'key' => 'lock.notImplemented',
|
||||
'httpCode' => 501
|
||||
]);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/lock',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $path) {
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->remove();
|
||||
}
|
||||
|
||||
throw new Exception([
|
||||
'key' => 'lock.notImplemented',
|
||||
'httpCode' => 501
|
||||
]);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/unlock',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path) {
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return [
|
||||
'supported' => true,
|
||||
'unlocked' => $lock->isUnlocked()
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'supported' => false,
|
||||
'unlocked' => null
|
||||
];
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/unlock',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $path) {
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->unlock();
|
||||
}
|
||||
|
||||
throw new Exception([
|
||||
'key' => 'lock.notImplemented',
|
||||
'httpCode' => 501
|
||||
]);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/unlock',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $path) {
|
||||
if ($lock = $this->parent($path)->lock()) {
|
||||
return $lock->resolve();
|
||||
}
|
||||
|
||||
throw new Exception([
|
||||
'key' => 'lock.notImplemented',
|
||||
'httpCode' => 501
|
||||
]);
|
||||
}
|
||||
],
|
||||
];
|
127
kirby/config/api/routes/pages.php
Normal file
127
kirby/config/api/routes/pages.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Page Routes
|
||||
*/
|
||||
return [
|
||||
|
||||
[
|
||||
'pattern' => 'pages/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->update($this->requestBody(), $this->language(), true);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->delete($this->requestBody('force', false));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/blueprint',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->blueprint();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => [
|
||||
'pages/(:any)/blueprints',
|
||||
/**
|
||||
* @deprecated
|
||||
* @todo remove in 3.6.0
|
||||
*/
|
||||
'pages/(:any)/children/blueprints',
|
||||
],
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->blueprints($this->requestQuery('section'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/children',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->pages($id, $this->requestQuery('status'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/children',
|
||||
'method' => 'POST',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->createChild($this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/children/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function (string $id) {
|
||||
return $this->searchPages($id);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/duplicate',
|
||||
'method' => 'POST',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->duplicate($this->requestBody('slug'), [
|
||||
'children' => $this->requestBody('children'),
|
||||
'files' => $this->requestBody('files'),
|
||||
]);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/slug',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->changeSlug($this->requestBody('slug'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/status',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->changeStatus($this->requestBody('status'), $this->requestBody('position'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/template',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->changeTemplate($this->requestBody('template'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/title',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->changeTitle($this->requestBody('title'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id, string $sectionName) {
|
||||
if ($section = $this->page($id)->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $id, string $fieldName, string $path = null) {
|
||||
if ($page = $this->page($id)) {
|
||||
return $this->fieldApi($page, $fieldName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
];
|
28
kirby/config/api/routes/roles.php
Normal file
28
kirby/config/api/routes/roles.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Roles Routes
|
||||
*/
|
||||
return [
|
||||
[
|
||||
'pattern' => 'roles',
|
||||
'method' => 'GET',
|
||||
'action' => function () {
|
||||
switch (get('canBe')) {
|
||||
case 'changed':
|
||||
return $this->kirby()->roles()->canBeChanged();
|
||||
case 'created':
|
||||
return $this->kirby()->roles()->canBeCreated();
|
||||
default:
|
||||
return $this->kirby()->roles();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'roles/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $name) {
|
||||
return $this->kirby()->roles()->find($name);
|
||||
}
|
||||
]
|
||||
];
|
110
kirby/config/api/routes/site.php
Normal file
110
kirby/config/api/routes/site.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Site Routes
|
||||
*/
|
||||
return [
|
||||
|
||||
[
|
||||
'pattern' => 'site',
|
||||
'action' => function () {
|
||||
return $this->site();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site',
|
||||
'method' => 'PATCH',
|
||||
'action' => function () {
|
||||
return $this->site()->update($this->requestBody(), $this->language(), true);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/children',
|
||||
'method' => 'GET',
|
||||
'action' => function () {
|
||||
return $this->pages(null, $this->requestQuery('status'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/children',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
return $this->site()->createChild($this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/children/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function () {
|
||||
return $this->searchPages();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/blueprint',
|
||||
'method' => 'GET',
|
||||
'action' => function () {
|
||||
return $this->site()->blueprint();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => [
|
||||
'site/blueprints',
|
||||
/**
|
||||
* @deprecated
|
||||
* @todo remove in 3.6.0
|
||||
*/
|
||||
'site/children/blueprints',
|
||||
],
|
||||
'method' => 'GET',
|
||||
'action' => function () {
|
||||
return $this->site()->blueprints($this->requestQuery('section'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/find',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
return $this->site()->find(false, ...$this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/title',
|
||||
'method' => 'PATCH',
|
||||
'action' => function () {
|
||||
return $this->site()->changeTitle($this->requestBody('title'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function () {
|
||||
$pages = $this
|
||||
->site()
|
||||
->index(true)
|
||||
->filter('isReadable', true);
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $pages->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $pages->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $sectionName) {
|
||||
if ($section = $this->site()->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $fieldName, string $path = null) {
|
||||
return $this->fieldApi($this->site(), $fieldName, $path);
|
||||
}
|
||||
]
|
||||
|
||||
];
|
79
kirby/config/api/routes/system.php
Normal file
79
kirby/config/api/routes/system.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\Exception;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* System Routes
|
||||
*/
|
||||
return [
|
||||
|
||||
[
|
||||
'pattern' => 'system',
|
||||
'method' => 'GET',
|
||||
'auth' => false,
|
||||
'action' => function () {
|
||||
$system = $this->kirby()->system();
|
||||
|
||||
if ($this->kirby()->user()) {
|
||||
return $system;
|
||||
} else {
|
||||
if ($system->isOk() === true) {
|
||||
$info = $this->resolve($system)->view('login')->toArray();
|
||||
} else {
|
||||
$info = $this->resolve($system)->view('troubleshooting')->toArray();
|
||||
}
|
||||
|
||||
return [
|
||||
'status' => 'ok',
|
||||
'data' => $info,
|
||||
'type' => 'model'
|
||||
];
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'system/register',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
return $this->kirby()->system()->register($this->requestBody('license'), $this->requestBody('email'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'system/install',
|
||||
'method' => 'POST',
|
||||
'auth' => false,
|
||||
'action' => function () {
|
||||
$system = $this->kirby()->system();
|
||||
$auth = $this->kirby()->auth();
|
||||
|
||||
// csrf token check
|
||||
if ($auth->type() === 'session' && $auth->csrf() === false) {
|
||||
throw new InvalidArgumentException('Invalid CSRF token');
|
||||
}
|
||||
|
||||
if ($system->isOk() === false) {
|
||||
throw new Exception('The server is not setup correctly');
|
||||
}
|
||||
|
||||
if ($system->isInstallable() === false) {
|
||||
throw new Exception('The Panel cannot be installed');
|
||||
}
|
||||
|
||||
if ($system->isInstalled() === true) {
|
||||
throw new Exception('The Panel is already installed');
|
||||
}
|
||||
|
||||
// create the first user
|
||||
$user = $this->users()->create($this->requestBody());
|
||||
$token = $user->login($this->requestBody('password'));
|
||||
|
||||
return [
|
||||
'status' => 'ok',
|
||||
'token' => $token,
|
||||
'user' => $this->resolve($user)->view('auth')->toArray()
|
||||
];
|
||||
}
|
||||
]
|
||||
|
||||
];
|
24
kirby/config/api/routes/translations.php
Normal file
24
kirby/config/api/routes/translations.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Translations Routes
|
||||
*/
|
||||
return [
|
||||
[
|
||||
'pattern' => 'translations',
|
||||
'method' => 'GET',
|
||||
'auth' => false,
|
||||
'action' => function () {
|
||||
return $this->kirby()->translations();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'translations/(:any)',
|
||||
'method' => 'GET',
|
||||
'auth' => false,
|
||||
'action' => function (string $code) {
|
||||
return $this->kirby()->translations()->find($code);
|
||||
}
|
||||
]
|
||||
|
||||
];
|
160
kirby/config/api/routes/users.php
Normal file
160
kirby/config/api/routes/users.php
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\F;
|
||||
|
||||
/**
|
||||
* User Routes
|
||||
*/
|
||||
return [
|
||||
|
||||
[
|
||||
'pattern' => 'users',
|
||||
'method' => 'GET',
|
||||
'action' => function () {
|
||||
return $this->users()->sort('username', 'asc', 'email', 'asc');
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
return $this->users()->create($this->requestBody());
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/search',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function () {
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $this->users()->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $this->users()->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->update($this->requestBody(), $this->language(), true);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->delete();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/avatar',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->avatar();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/avatar',
|
||||
'method' => 'POST',
|
||||
'action' => function (string $id) {
|
||||
if ($avatar = $this->user($id)->avatar()) {
|
||||
$avatar->delete();
|
||||
}
|
||||
|
||||
return $this->upload(function ($source, $filename) use ($id) {
|
||||
return $this->user($id)->createFile([
|
||||
'filename' => 'profile.' . F::extension($filename),
|
||||
'template' => 'avatar',
|
||||
'source' => $source
|
||||
]);
|
||||
}, $single = true);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/avatar',
|
||||
'method' => 'DELETE',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->avatar()->delete();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/blueprint',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->blueprint();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/blueprints',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->blueprints($this->requestQuery('section'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/email',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->changeEmail($this->requestBody('email'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $id, string $fieldName, string $path = null) {
|
||||
if ($user = $this->user($id)) {
|
||||
return $this->fieldApi($user, $fieldName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/language',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->changeLanguage($this->requestBody('language'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/name',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->changeName($this->requestBody('name'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/password',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->changePassword($this->requestBody('password'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/role',
|
||||
'method' => 'PATCH',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->changeRole($this->requestBody('role'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/roles',
|
||||
'action' => function (string $id) {
|
||||
return $this->user($id)->roles();
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $id, string $sectionName) {
|
||||
if ($section = $this->user($id)->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
];
|
2
kirby/config/blocks/code/code.php
Normal file
2
kirby/config/blocks/code/code.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<pre><code class="language-<?= $block->language()->or('text') ?>"><?= $block->code()->html(false) ?></code></pre>
|
59
kirby/config/blocks/code/code.yml
Normal file
59
kirby/config/blocks/code/code.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
name: field.blocks.code.name
|
||||
icon: code
|
||||
wysiwyg: true
|
||||
preview: code
|
||||
fields:
|
||||
code:
|
||||
label: field.blocks.code.name
|
||||
type: textarea
|
||||
placeholder: field.blocks.code.placeholder
|
||||
buttons: false
|
||||
font: monospace
|
||||
language:
|
||||
label: field.blocks.code.language
|
||||
type: select
|
||||
default: text
|
||||
options:
|
||||
bash: Bash
|
||||
basic: BASIC
|
||||
c: C
|
||||
clojure: Clojure
|
||||
cpp: C++
|
||||
csharp: C#
|
||||
css: CSS
|
||||
diff: Diff
|
||||
elixir: Elixir
|
||||
elm: Elm
|
||||
erlang: Erlang
|
||||
go: Go
|
||||
graphql: GraphQL
|
||||
haskell: Haskell
|
||||
html: HTML
|
||||
java: Java
|
||||
js: JavaScript
|
||||
json: JSON
|
||||
latext: LaTeX
|
||||
less: Less
|
||||
lisp: Lisp
|
||||
lua: Lua
|
||||
makefile: Makefile
|
||||
markdown: Markdown
|
||||
markup: Markup
|
||||
objectivec: Objective-C
|
||||
pascal: Pascal
|
||||
perl: Perl
|
||||
php: PHP
|
||||
text: Plain Text
|
||||
python: Python
|
||||
r: R
|
||||
ruby: Ruby
|
||||
rust: Rust
|
||||
sass: Sass
|
||||
scss: SCSS
|
||||
shell: Shell
|
||||
sql: SQL
|
||||
swift: Swift
|
||||
typescript: TypeScript
|
||||
vbnet: VB.net
|
||||
xml: XML
|
||||
yaml: YAML
|
10
kirby/config/blocks/gallery/gallery.php
Normal file
10
kirby/config/blocks/gallery/gallery.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<figure>
|
||||
<ul>
|
||||
<?php foreach ($block->images()->toFiles() as $image): ?>
|
||||
<li>
|
||||
<?= $image ?>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
</figure>
|
15
kirby/config/blocks/gallery/gallery.yml
Normal file
15
kirby/config/blocks/gallery/gallery.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
name: field.blocks.gallery.name
|
||||
icon: dashboard
|
||||
preview: gallery
|
||||
fields:
|
||||
images:
|
||||
label: field.blocks.gallery.images.label
|
||||
type: files
|
||||
multiple: true
|
||||
layout: cards
|
||||
size: tiny
|
||||
empty: field.blocks.gallery.images.empty
|
||||
uploads:
|
||||
template: blocks/image
|
||||
image:
|
||||
ratio: 1/1
|
2
kirby/config/blocks/heading/heading.php
Normal file
2
kirby/config/blocks/heading/heading.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<<?= $level = $block->level()->or('h2') ?>><?= $block->text() ?></<?= $level ?>>
|
24
kirby/config/blocks/heading/heading.yml
Normal file
24
kirby/config/blocks/heading/heading.yml
Normal file
|
@ -0,0 +1,24 @@
|
|||
name: field.blocks.heading.name
|
||||
icon: title
|
||||
wysiwyg: true
|
||||
preview: heading
|
||||
fields:
|
||||
level:
|
||||
label: field.blocks.heading.level
|
||||
type: select
|
||||
empty: false
|
||||
default: "h2"
|
||||
width: 1/6
|
||||
options:
|
||||
- h1
|
||||
- h2
|
||||
- h3
|
||||
- h4
|
||||
- h5
|
||||
- h6
|
||||
text:
|
||||
label: field.blocks.heading.text
|
||||
type: writer
|
||||
inline: true
|
||||
width: 5/6
|
||||
placeholder: field.blocks.heading.placeholder
|
35
kirby/config/blocks/image/image.php
Normal file
35
kirby/config/blocks/image/image.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Block $block */
|
||||
$alt = $block->alt();
|
||||
$caption = $block->caption();
|
||||
$crop = $block->crop()->isTrue();
|
||||
$link = $block->link();
|
||||
$ratio = $block->ratio()->or('auto');
|
||||
$src = null;
|
||||
|
||||
if ($block->location() == 'web') {
|
||||
$src = $block->src();
|
||||
} elseif ($image = $block->image()->toFile()) {
|
||||
$alt = $alt ?? $image->alt();
|
||||
$src = $image->url();
|
||||
}
|
||||
|
||||
?>
|
||||
<?php if ($src): ?>
|
||||
<figure<?= attr(['data-ratio' => $ratio, 'data-crop' => $crop], ' ') ?>>
|
||||
<?php if ($link->isNotEmpty()): ?>
|
||||
<a href="<?= $link->toUrl() ?>">
|
||||
<img src="<?= $src ?>" alt="<?= $alt ?>">
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<img src="<?= $src ?>" alt="<?= $alt ?>">
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($caption->isNotEmpty()): ?>
|
||||
<figcaption>
|
||||
<?= $caption ?>
|
||||
</figcaption>
|
||||
<?php endif ?>
|
||||
</figure>
|
||||
<?php endif ?>
|
59
kirby/config/blocks/image/image.yml
Normal file
59
kirby/config/blocks/image/image.yml
Normal file
|
@ -0,0 +1,59 @@
|
|||
name: field.blocks.image.name
|
||||
icon: image
|
||||
preview: image
|
||||
fields:
|
||||
location:
|
||||
label: field.blocks.image.location
|
||||
type: radio
|
||||
columns: 2
|
||||
default: "kirby"
|
||||
options:
|
||||
kirby: Kirby
|
||||
web: Web
|
||||
image:
|
||||
label: field.blocks.image.name
|
||||
type: files
|
||||
multiple: false
|
||||
image:
|
||||
back: black
|
||||
uploads:
|
||||
template: blocks/image
|
||||
when:
|
||||
location: kirby
|
||||
src:
|
||||
label: field.blocks.image.url
|
||||
type: url
|
||||
when:
|
||||
location: web
|
||||
alt:
|
||||
label: field.blocks.image.alt
|
||||
type: text
|
||||
icon: title
|
||||
caption:
|
||||
label: field.blocks.image.caption
|
||||
type: writer
|
||||
icon: text
|
||||
inline: true
|
||||
link:
|
||||
label: field.blocks.image.link
|
||||
type: text
|
||||
icon: url
|
||||
ratio:
|
||||
label: field.blocks.image.ratio
|
||||
type: select
|
||||
placeholder: Auto
|
||||
width: 1/2
|
||||
options:
|
||||
1/1: "1:1"
|
||||
16/9: "16:9"
|
||||
10/8: "10:8"
|
||||
21/9: "21:9"
|
||||
7/5: "7:5"
|
||||
4/3: "4:3"
|
||||
5/3: "5:3"
|
||||
3/2: "3:2"
|
||||
3/1: "3:1"
|
||||
crop:
|
||||
label: field.blocks.image.crop
|
||||
type: toggle
|
||||
width: 1/2
|
2
kirby/config/blocks/list/list.php
Normal file
2
kirby/config/blocks/list/list.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<?= $block->text();
|
8
kirby/config/blocks/list/list.yml
Normal file
8
kirby/config/blocks/list/list.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
name: field.blocks.list.name
|
||||
icon: list-bullet
|
||||
wysiwyg: true
|
||||
preview: list
|
||||
fields:
|
||||
text:
|
||||
label: field.blocks.list.name
|
||||
type: list
|
2
kirby/config/blocks/markdown/markdown.php
Normal file
2
kirby/config/blocks/markdown/markdown.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<?= $block->text()->kt();
|
11
kirby/config/blocks/markdown/markdown.yml
Normal file
11
kirby/config/blocks/markdown/markdown.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
name: field.blocks.markdown.name
|
||||
icon: markdown
|
||||
preview: markdown
|
||||
wysiwyg: true
|
||||
fields:
|
||||
text:
|
||||
label: field.blocks.markdown.label
|
||||
placeholder: field.blocks.markdown.placeholder
|
||||
type: textarea
|
||||
buttons: false
|
||||
font: monospace
|
9
kirby/config/blocks/quote/quote.php
Normal file
9
kirby/config/blocks/quote/quote.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<blockquote>
|
||||
<?= $block->text() ?>
|
||||
<?php if ($block->citation()->isNotEmpty()): ?>
|
||||
<footer>
|
||||
<?= $block->citation() ?>
|
||||
</footer>
|
||||
<?php endif ?>
|
||||
</blockquote>
|
17
kirby/config/blocks/quote/quote.yml
Normal file
17
kirby/config/blocks/quote/quote.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
name: field.blocks.quote.name
|
||||
icon: quote
|
||||
wysiwyg: true
|
||||
preview: quote
|
||||
fields:
|
||||
text:
|
||||
label: field.blocks.quote.text.label
|
||||
placeholder: field.blocks.quote.text.placeholder
|
||||
type: writer
|
||||
inline: true
|
||||
icon: quote
|
||||
citation:
|
||||
label: field.blocks.quote.citation.label
|
||||
placeholder: field.blocks.quote.citation.placeholder
|
||||
type: writer
|
||||
inline: true
|
||||
icon: user
|
3
kirby/config/blocks/table/table.yml
Normal file
3
kirby/config/blocks/table/table.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
name: Table
|
||||
icon: menu
|
||||
preview: table
|
2
kirby/config/blocks/text/text.php
Normal file
2
kirby/config/blocks/text/text.php
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<?= $block->text();
|
9
kirby/config/blocks/text/text.yml
Normal file
9
kirby/config/blocks/text/text.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
name: field.blocks.text.name
|
||||
icon: text
|
||||
wysiwyg: true
|
||||
preview: text
|
||||
fields:
|
||||
text:
|
||||
type: writer
|
||||
nodes: false
|
||||
placeholder: field.blocks.text.placeholder
|
9
kirby/config/blocks/video/video.php
Normal file
9
kirby/config/blocks/video/video.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php /** @var \Kirby\Cms\Block $block */ ?>
|
||||
<?php if ($block->url()->isNotEmpty()): ?>
|
||||
<figure>
|
||||
<?= video($block->url()) ?>
|
||||
<?php if ($block->caption()->isNotEmpty()): ?>
|
||||
<figcaption><?= $block->caption() ?></figcaption>
|
||||
<?php endif ?>
|
||||
</figure>
|
||||
<?php endif ?>
|
12
kirby/config/blocks/video/video.yml
Normal file
12
kirby/config/blocks/video/video.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
name: field.blocks.video.name
|
||||
icon: video
|
||||
preview: video
|
||||
fields:
|
||||
url:
|
||||
label: field.blocks.video.url.label
|
||||
type: url
|
||||
placeholder: field.blocks.video.url.placeholder
|
||||
caption:
|
||||
label: field.blocks.video.caption
|
||||
type: writer
|
||||
inline: true
|
26
kirby/config/blueprints.php
Normal file
26
kirby/config/blueprints.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
$blocksRoot = __DIR__ . '/blocks';
|
||||
|
||||
return [
|
||||
// blocks
|
||||
'blocks/code' => $blocksRoot . '/code/code.yml',
|
||||
'blocks/gallery' => $blocksRoot . '/gallery/gallery.yml',
|
||||
'blocks/heading' => $blocksRoot . '/heading/heading.yml',
|
||||
'blocks/image' => $blocksRoot . '/image/image.yml',
|
||||
'blocks/list' => $blocksRoot . '/list/list.yml',
|
||||
'blocks/markdown' => $blocksRoot . '/markdown/markdown.yml',
|
||||
'blocks/quote' => $blocksRoot . '/quote/quote.yml',
|
||||
'blocks/table' => $blocksRoot . '/table/table.yml',
|
||||
'blocks/text' => $blocksRoot . '/text/text.yml',
|
||||
'blocks/video' => $blocksRoot . '/video/video.yml',
|
||||
|
||||
// file blueprints
|
||||
'files/default' => __DIR__ . '/blueprints/files/default.yml',
|
||||
|
||||
// page blueprints
|
||||
'pages/default' => __DIR__ . '/blueprints/pages/default.yml',
|
||||
|
||||
// site blueprints
|
||||
'site' => __DIR__ . '/blueprints/site.yml'
|
||||
];
|
56
kirby/config/blueprints/blocks/code.yml
Normal file
56
kirby/config/blueprints/blocks/code.yml
Normal file
|
@ -0,0 +1,56 @@
|
|||
name: Code
|
||||
icon: code
|
||||
fields:
|
||||
code:
|
||||
label: Code
|
||||
type: textarea
|
||||
buttons: false
|
||||
font: monospace
|
||||
language:
|
||||
label: Language
|
||||
type: select
|
||||
default: text
|
||||
options:
|
||||
bash: Bash
|
||||
basic: BASIC
|
||||
c: C
|
||||
clojure: Clojure
|
||||
cpp: C++
|
||||
csharp: C#
|
||||
css: CSS
|
||||
diff: Diff
|
||||
elixir: Elixir
|
||||
elm: Elm
|
||||
erlang: Erlang
|
||||
go: Go
|
||||
graphql: GraphQL
|
||||
haskell: Haskell
|
||||
html: HTML
|
||||
java: Java
|
||||
js: JavaScript
|
||||
json: JSON
|
||||
latext: LaTeX
|
||||
less: Less
|
||||
lisp: Lisp
|
||||
lua: Lua
|
||||
makefile: Makefile
|
||||
markdown: Markdown
|
||||
markup: Markup
|
||||
objectivec: Objective-C
|
||||
pascal: Pascal
|
||||
perl: Perl
|
||||
php: PHP
|
||||
text: Plain Text
|
||||
python: Python
|
||||
r: R
|
||||
ruby: Ruby
|
||||
rust: Rust
|
||||
sass: Sass
|
||||
scss: SCSS
|
||||
shell: Shell
|
||||
sql: SQL
|
||||
swift: Swift
|
||||
typescript: TypeScript
|
||||
vbnet: VB.net
|
||||
xml: XML
|
||||
yaml: YAML
|
21
kirby/config/blueprints/blocks/heading.yml
Normal file
21
kirby/config/blueprints/blocks/heading.yml
Normal file
|
@ -0,0 +1,21 @@
|
|||
icon: title
|
||||
fields:
|
||||
text:
|
||||
type: text
|
||||
level:
|
||||
type: select
|
||||
width: 1/2
|
||||
default: 1
|
||||
empty: false
|
||||
default: "2"
|
||||
options:
|
||||
- value: "1"
|
||||
text: Heading 1
|
||||
- value: "2"
|
||||
text: Heading 2
|
||||
- value: "3"
|
||||
text: Heading 3
|
||||
id:
|
||||
type: text
|
||||
label: ID
|
||||
width: 1/2
|
16
kirby/config/blueprints/blocks/image.yml
Normal file
16
kirby/config/blueprints/blocks/image.yml
Normal file
|
@ -0,0 +1,16 @@
|
|||
name: Image
|
||||
icon: image
|
||||
fields:
|
||||
image:
|
||||
type: files
|
||||
multiple: false
|
||||
alt:
|
||||
type: text
|
||||
icon: title
|
||||
caption:
|
||||
type: writer
|
||||
inline: true
|
||||
icon: text
|
||||
link:
|
||||
type: text
|
||||
icon: url
|
12
kirby/config/blueprints/blocks/quote.yml
Normal file
12
kirby/config/blueprints/blocks/quote.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
name: Quote
|
||||
icon: quote
|
||||
fields:
|
||||
text:
|
||||
label: Quote Text
|
||||
type: writer
|
||||
inline: true
|
||||
citation:
|
||||
label: Citation
|
||||
type: writer
|
||||
inline: true
|
||||
placeholder: by …
|
25
kirby/config/blueprints/blocks/table.yml
Normal file
25
kirby/config/blueprints/blocks/table.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
name: Table
|
||||
icon: menu
|
||||
fields:
|
||||
rows:
|
||||
label: Menu
|
||||
type: structure
|
||||
columns:
|
||||
dish: true
|
||||
description: true
|
||||
price:
|
||||
before: €
|
||||
width: 1/4
|
||||
align: right
|
||||
fields:
|
||||
dish:
|
||||
label: Dish
|
||||
type: text
|
||||
description:
|
||||
label: Description
|
||||
type: text
|
||||
price:
|
||||
label: Price
|
||||
type: number
|
||||
before: €
|
||||
step: 0.01
|
5
kirby/config/blueprints/blocks/text.yml
Normal file
5
kirby/config/blueprints/blocks/text.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: Text
|
||||
icon: text
|
||||
fields:
|
||||
text:
|
||||
type: writer
|
8
kirby/config/blueprints/blocks/video.yml
Normal file
8
kirby/config/blueprints/blocks/video.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
name: Video
|
||||
icon: video
|
||||
label: "{{ url }}"
|
||||
fields:
|
||||
url:
|
||||
type: url
|
||||
caption:
|
||||
type: writer
|
2
kirby/config/blueprints/files/default.yml
Normal file
2
kirby/config/blueprints/files/default.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
name: File
|
||||
title: file
|
3
kirby/config/blueprints/pages/default.yml
Normal file
3
kirby/config/blueprints/pages/default.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
name: Page
|
||||
title: Page
|
||||
|
7
kirby/config/blueprints/site.yml
Normal file
7
kirby/config/blueprints/site.yml
Normal file
|
@ -0,0 +1,7 @@
|
|||
name: Site
|
||||
title: Site
|
||||
sections:
|
||||
pages:
|
||||
headline: Pages
|
||||
type: pages
|
||||
|
378
kirby/config/components.php
Normal file
378
kirby/config/components.php
Normal file
|
@ -0,0 +1,378 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Collection;
|
||||
use Kirby\Cms\File;
|
||||
use Kirby\Cms\Filename;
|
||||
use Kirby\Cms\FileVersion;
|
||||
use Kirby\Cms\Template;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Http\Server;
|
||||
use Kirby\Http\Uri;
|
||||
use Kirby\Http\Url;
|
||||
use Kirby\Image\Darkroom;
|
||||
use Kirby\Text\Markdown;
|
||||
use Kirby\Text\SmartyPants;
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\F;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Toolkit\Tpl as Snippet;
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Used by the `css()` helper
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $url Relative or absolute URL
|
||||
* @param string|array $options An array of attributes for the link tag or a media attribute string
|
||||
*/
|
||||
'css' => function (App $kirby, string $url, $options = null): string {
|
||||
return $url;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Object and variable dumper
|
||||
* to help with debugging.
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param mixed $variable
|
||||
* @param bool $echo
|
||||
* @return string
|
||||
*/
|
||||
'dump' => function (App $kirby, $variable, bool $echo = true) {
|
||||
if (Server::cli() === true) {
|
||||
$output = print_r($variable, true) . PHP_EOL;
|
||||
} else {
|
||||
$output = '<pre>' . print_r($variable, true) . '</pre>';
|
||||
}
|
||||
|
||||
if ($echo === true) {
|
||||
echo $output;
|
||||
}
|
||||
|
||||
return $output;
|
||||
},
|
||||
|
||||
/**
|
||||
* Modify URLs for file objects
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param \Kirby\Cms\File $file The original file object
|
||||
* @return string
|
||||
*/
|
||||
'file::url' => function (App $kirby, File $file): string {
|
||||
return $file->mediaUrl();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adapt file characteristics
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param \Kirby\Cms\File|\Kirby\Cms\FileModifications $file The file object
|
||||
* @param array $options All thumb options (width, height, crop, blur, grayscale)
|
||||
* @return \Kirby\Cms\File|\Kirby\Cms\FileVersion
|
||||
*/
|
||||
'file::version' => function (App $kirby, $file, array $options = []) {
|
||||
if ($file->isResizable() === false) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
// create url and root
|
||||
$mediaRoot = dirname($file->mediaRoot());
|
||||
$template = $mediaRoot . '/{{ name }}{{ attributes }}.{{ extension }}';
|
||||
$thumbRoot = (new Filename($file->root(), $template, $options))->toString();
|
||||
$thumbName = basename($thumbRoot);
|
||||
$job = $mediaRoot . '/.jobs/' . $thumbName . '.json';
|
||||
|
||||
if (file_exists($thumbRoot) === false) {
|
||||
try {
|
||||
Data::write($job, array_merge($options, [
|
||||
'filename' => $file->filename()
|
||||
]));
|
||||
} catch (Throwable $e) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
return new FileVersion([
|
||||
'modifications' => $options,
|
||||
'original' => $file,
|
||||
'root' => $thumbRoot,
|
||||
'url' => dirname($file->mediaUrl()) . '/' . $thumbName,
|
||||
]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Used by the `js()` helper
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $url Relative or absolute URL
|
||||
* @param string|array $options An array of attributes for the link tag or a media attribute string
|
||||
*/
|
||||
'js' => function (App $kirby, string $url, $options = null): string {
|
||||
return $url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own Markdown parser
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $text Text to parse
|
||||
* @param array $options Markdown options
|
||||
* @param bool $inline Whether to wrap the text in `<p>` tags
|
||||
* @return string
|
||||
*/
|
||||
'markdown' => function (App $kirby, string $text = null, array $options = [], bool $inline = false): string {
|
||||
static $markdown;
|
||||
static $config;
|
||||
|
||||
// if the config options have changed or the component is called for the first time,
|
||||
// (re-)initialize the parser object
|
||||
if ($config !== $options) {
|
||||
$markdown = new Markdown($options);
|
||||
$config = $options;
|
||||
}
|
||||
|
||||
return $markdown->parse($text, $inline);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own search engine
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param \Kirby\Cms\Collection $collection Collection of searchable models
|
||||
* @param string $query
|
||||
* @param mixed $params
|
||||
* @return \Kirby\Cms\Collection|bool
|
||||
*/
|
||||
'search' => function (App $kirby, Collection $collection, string $query = null, $params = []) {
|
||||
if (empty(trim($query)) === true) {
|
||||
return $collection->limit(0);
|
||||
}
|
||||
|
||||
if (is_string($params) === true) {
|
||||
$params = ['fields' => Str::split($params, '|')];
|
||||
}
|
||||
|
||||
$defaults = [
|
||||
'fields' => [],
|
||||
'minlength' => 2,
|
||||
'score' => [],
|
||||
'words' => false,
|
||||
];
|
||||
|
||||
$options = array_merge($defaults, $params);
|
||||
$collection = clone $collection;
|
||||
$searchWords = preg_replace('/(\s)/u', ',', $query);
|
||||
$searchWords = Str::split($searchWords, ',', $options['minlength']);
|
||||
$lowerQuery = Str::lower($query);
|
||||
$exactQuery = $options['words'] ? '(\b' . preg_quote($query) . '\b)' : preg_quote($query);
|
||||
|
||||
if (empty($options['stopwords']) === false) {
|
||||
$searchWords = array_diff($searchWords, $options['stopwords']);
|
||||
}
|
||||
|
||||
$searchWords = array_map(function ($value) use ($options) {
|
||||
return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value);
|
||||
}, $searchWords);
|
||||
|
||||
$preg = '!(' . implode('|', $searchWords) . ')!i';
|
||||
$results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery, $exactQuery) {
|
||||
$data = $item->content()->toArray();
|
||||
$keys = array_keys($data);
|
||||
$keys[] = 'id';
|
||||
|
||||
if (is_a($item, 'Kirby\Cms\User') === true) {
|
||||
$keys[] = 'name';
|
||||
$keys[] = 'email';
|
||||
$keys[] = 'role';
|
||||
} elseif (is_a($item, 'Kirby\Cms\Page') === true) {
|
||||
// apply the default score for pages
|
||||
$options['score'] = array_merge([
|
||||
'id' => 64,
|
||||
'title' => 64,
|
||||
], $options['score']);
|
||||
}
|
||||
|
||||
if (empty($options['fields']) === false) {
|
||||
$fields = array_map('strtolower', $options['fields']);
|
||||
$keys = array_intersect($keys, $fields);
|
||||
}
|
||||
|
||||
$item->searchHits = 0;
|
||||
$item->searchScore = 0;
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$score = $options['score'][$key] ?? 1;
|
||||
$value = $data[$key] ?? (string)$item->$key();
|
||||
|
||||
$lowerValue = Str::lower($value);
|
||||
|
||||
// check for exact matches
|
||||
if ($lowerQuery == $lowerValue) {
|
||||
$item->searchScore += 16 * $score;
|
||||
$item->searchHits += 1;
|
||||
|
||||
// check for exact beginning matches
|
||||
} elseif ($options['words'] === false && Str::startsWith($lowerValue, $lowerQuery) === true) {
|
||||
$item->searchScore += 8 * $score;
|
||||
$item->searchHits += 1;
|
||||
|
||||
// check for exact query matches
|
||||
} elseif ($matches = preg_match_all('!' . $exactQuery . '!i', $value, $r)) {
|
||||
$item->searchScore += 2 * $score;
|
||||
$item->searchHits += $matches;
|
||||
}
|
||||
|
||||
// check for any match
|
||||
if ($matches = preg_match_all($preg, $value, $r)) {
|
||||
$item->searchHits += $matches;
|
||||
$item->searchScore += $matches * $score;
|
||||
}
|
||||
}
|
||||
|
||||
return $item->searchHits > 0 ? true : false;
|
||||
});
|
||||
|
||||
return $results->sort('searchScore', 'desc');
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own SmartyPants parser
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $text Text to parse
|
||||
* @param array $options SmartyPants options
|
||||
* @return string
|
||||
*/
|
||||
'smartypants' => function (App $kirby, string $text = null, array $options = []): string {
|
||||
static $smartypants;
|
||||
static $config;
|
||||
|
||||
// if the config options have changed or the component is called for the first time,
|
||||
// (re-)initialize the parser object
|
||||
if ($config !== $options) {
|
||||
$smartypants = new Smartypants($options);
|
||||
$config = $options;
|
||||
}
|
||||
|
||||
return $smartypants->parse($text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own snippet loader
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string|array $name Snippet name
|
||||
* @param array $data Data array for the snippet
|
||||
* @return string|null
|
||||
*/
|
||||
'snippet' => function (App $kirby, $name, array $data = []): ?string {
|
||||
$snippets = A::wrap($name);
|
||||
|
||||
foreach ($snippets as $name) {
|
||||
$name = (string)$name;
|
||||
$file = $kirby->root('snippets') . '/' . $name . '.php';
|
||||
|
||||
if (file_exists($file) === false) {
|
||||
$file = $kirby->extensions('snippets')[$name] ?? null;
|
||||
}
|
||||
|
||||
if ($file) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Snippet::load($file, $data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own template engine
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $name Template name
|
||||
* @param string $type Extension type
|
||||
* @param string $defaultType Default extension type
|
||||
* @return \Kirby\Cms\Template
|
||||
*/
|
||||
'template' => function (App $kirby, string $name, string $type = 'html', string $defaultType = 'html') {
|
||||
return new Template($name, $type, $defaultType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add your own thumb generator
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $src The root of the original file
|
||||
* @param string $template The template for the root to the desired destination
|
||||
* @param array $options All thumb options that should be applied: `width`, `height`, `crop`, `blur`, `grayscale`
|
||||
* @return string
|
||||
*/
|
||||
'thumb' => function (App $kirby, string $src, string $template, array $options): string {
|
||||
$darkroom = Darkroom::factory(option('thumbs.driver', 'gd'), option('thumbs', []));
|
||||
$options = $darkroom->preprocess($src, $options);
|
||||
$root = (new Filename($src, $template, $options))->toString();
|
||||
|
||||
F::copy($src, $root, true);
|
||||
$darkroom->process($root, $options);
|
||||
|
||||
return $root;
|
||||
},
|
||||
|
||||
/**
|
||||
* Modify all URLs
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby Kirby instance
|
||||
* @param string $path URL path
|
||||
* @param array|string|null $options Array of options for the Uri class
|
||||
* @param Closure $originalHandler Deprecated: Callback function to the original URL handler with `$path` and `$options` as parameters
|
||||
* Use `$kirby->nativeComponent('url')` inside your URL component instead.
|
||||
* @return string
|
||||
*
|
||||
* @todo Remove $originalHandler parameter in 3.6.0
|
||||
*/
|
||||
'url' => function (App $kirby, string $path = null, $options = null, Closure $originalHandler = null): string {
|
||||
$language = null;
|
||||
|
||||
// get language from simple string option
|
||||
if (is_string($options) === true) {
|
||||
$language = $options;
|
||||
$options = null;
|
||||
}
|
||||
|
||||
// get language from array
|
||||
if (is_array($options) === true && isset($options['language']) === true) {
|
||||
$language = $options['language'];
|
||||
unset($options['language']);
|
||||
}
|
||||
|
||||
// get a language url for the linked page, if the page can be found
|
||||
if ($kirby->multilang() === true) {
|
||||
$parts = Str::split($path, '#');
|
||||
|
||||
if ($page = page($parts[0] ?? null)) {
|
||||
$path = $page->url($language);
|
||||
|
||||
if (isset($parts[1]) === true) {
|
||||
$path .= '#' . $parts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// keep relative urls
|
||||
if (substr($path, 0, 2) === './' || substr($path, 0, 3) === '../') {
|
||||
return $path;
|
||||
}
|
||||
|
||||
$url = Url::makeAbsolute($path, $kirby->url());
|
||||
|
||||
if ($options === null) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
return (new Uri($url, $options))->toString();
|
||||
},
|
||||
|
||||
];
|
32
kirby/config/fields.php
Normal file
32
kirby/config/fields.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'blocks' => 'Kirby\Form\Field\BlocksField',
|
||||
'checkboxes' => __DIR__ . '/fields/checkboxes.php',
|
||||
'date' => __DIR__ . '/fields/date.php',
|
||||
'email' => __DIR__ . '/fields/email.php',
|
||||
'files' => __DIR__ . '/fields/files.php',
|
||||
'gap' => __DIR__ . '/fields/gap.php',
|
||||
'headline' => __DIR__ . '/fields/headline.php',
|
||||
'hidden' => __DIR__ . '/fields/hidden.php',
|
||||
'info' => __DIR__ . '/fields/info.php',
|
||||
'layout' => 'Kirby\Form\Field\LayoutField',
|
||||
'line' => __DIR__ . '/fields/line.php',
|
||||
'list' => __DIR__ . '/fields/list.php',
|
||||
'multiselect' => __DIR__ . '/fields/multiselect.php',
|
||||
'number' => __DIR__ . '/fields/number.php',
|
||||
'pages' => __DIR__ . '/fields/pages.php',
|
||||
'radio' => __DIR__ . '/fields/radio.php',
|
||||
'range' => __DIR__ . '/fields/range.php',
|
||||
'select' => __DIR__ . '/fields/select.php',
|
||||
'structure' => __DIR__ . '/fields/structure.php',
|
||||
'tags' => __DIR__ . '/fields/tags.php',
|
||||
'tel' => __DIR__ . '/fields/tel.php',
|
||||
'text' => __DIR__ . '/fields/text.php',
|
||||
'textarea' => __DIR__ . '/fields/textarea.php',
|
||||
'time' => __DIR__ . '/fields/time.php',
|
||||
'toggle' => __DIR__ . '/fields/toggle.php',
|
||||
'url' => __DIR__ . '/fields/url.php',
|
||||
'users' => __DIR__ . '/fields/users.php',
|
||||
'writer' => __DIR__ . '/fields/writer.php'
|
||||
];
|
61
kirby/config/fields/checkboxes.php
Normal file
61
kirby/config/fields/checkboxes.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'options'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Arranges the checkboxes in the given number of columns
|
||||
*/
|
||||
'columns' => function (int $columns = 1) {
|
||||
return $columns;
|
||||
},
|
||||
/**
|
||||
* Default value for the field, which will be used when a page/file/user is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return Str::split($default, ',');
|
||||
},
|
||||
/**
|
||||
* Maximum number of checked boxes
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Minimum number of checked boxes
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return Str::split($value, ',');
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->sanitizeOptions($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->sanitizeOptions($this->value);
|
||||
},
|
||||
],
|
||||
'save' => function ($value): string {
|
||||
return A::join($value, ', ');
|
||||
},
|
||||
'validations' => [
|
||||
'options',
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
179
kirby/config/fields/date.php
Normal file
179
kirby/config/fields/date.php
Normal file
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\Exception;
|
||||
use Kirby\Form\Field;
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'mixins' => ['datetime'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Activate/deactivate the dropdown calendar
|
||||
*/
|
||||
'calendar' => function (bool $calendar = true) {
|
||||
return $calendar;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Default date when a new page/file/user gets created
|
||||
*/
|
||||
'default' => function (string $default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom format (dayjs tokens: `DD`, `MM`, `YYYY`) that is
|
||||
* used to display the field in the Panel
|
||||
*/
|
||||
'display' => function ($display = 'YYYY-MM-DD') {
|
||||
return I18n::translate($display, $display);
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the calendar icon to something custom
|
||||
*/
|
||||
'icon' => function (string $icon = 'calendar') {
|
||||
return $icon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Latest date, which can be selected/saved (Y-m-d)
|
||||
*/
|
||||
'max' => function (string $max = null) {
|
||||
return $this->toDatetime($max);
|
||||
},
|
||||
/**
|
||||
* Earliest date, which can be selected/saved (Y-m-d)
|
||||
*/
|
||||
'min' => function (string $min = null) {
|
||||
return $this->toDatetime($min);
|
||||
},
|
||||
|
||||
/**
|
||||
* Round to the nearest: sub-options for `unit` (day) and `size` (1)
|
||||
*/
|
||||
'step' => function ($step = null) {
|
||||
$default = [
|
||||
'size' => 1,
|
||||
'unit' => 'day'
|
||||
];
|
||||
|
||||
if ($step === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (is_array($step) === true) {
|
||||
$step = array_merge($default, $step);
|
||||
$step['unit'] = strtolower($step['unit']);
|
||||
return $step;
|
||||
}
|
||||
|
||||
if (is_int($step) === true) {
|
||||
return array_merge($default, ['size' => $step]);
|
||||
}
|
||||
|
||||
if (is_string($step) === true) {
|
||||
return array_merge($default, ['unit' => strtolower($step)]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Pass `true` or an array of time field options to show the time selector.
|
||||
*/
|
||||
'time' => function ($time = false) {
|
||||
return $time;
|
||||
},
|
||||
/**
|
||||
* Must be a parseable date string
|
||||
*/
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toDatetime($this->default);
|
||||
},
|
||||
'display' => function () {
|
||||
if ($this->display) {
|
||||
return Str::upper($this->display);
|
||||
}
|
||||
},
|
||||
'format' => function () {
|
||||
return $this->props['format'] ?? ($this->time === false ? 'Y-m-d' : 'Y-m-d H:i:s');
|
||||
},
|
||||
'time' => function () {
|
||||
if ($this->time === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$props = is_array($this->time) ? $this->time : [];
|
||||
$props['model'] = $this->model();
|
||||
$field = new Field('time', $props);
|
||||
return $field->toArray();
|
||||
},
|
||||
'step' => function () {
|
||||
if ($this->time === false) {
|
||||
return $this->step;
|
||||
}
|
||||
|
||||
return $this->time['step'];
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toDatetime($this->value);
|
||||
},
|
||||
],
|
||||
'validations' => [
|
||||
'date',
|
||||
'minMax' => function ($value) {
|
||||
$min = $this->min ? strtotime($this->min) : null;
|
||||
$max = $this->max ? strtotime($this->max) : null;
|
||||
$value = strtotime($this->value());
|
||||
$format = $this->time === false ? 'd.m.Y' : 'd.m.Y H:i';
|
||||
$errors = [];
|
||||
|
||||
if ($value && $min && $value < $min) {
|
||||
$errors['min'] = $min;
|
||||
}
|
||||
|
||||
if ($value && $max && $value > $max) {
|
||||
$errors['max'] = $max;
|
||||
}
|
||||
|
||||
if (empty($errors) === false) {
|
||||
if ($min && $max) {
|
||||
throw new Exception([
|
||||
'key' => 'validation.date.between',
|
||||
'data' => [
|
||||
'min' => date($format, $min),
|
||||
'max' => date($format, $max)
|
||||
]
|
||||
]);
|
||||
} elseif ($min) {
|
||||
throw new Exception([
|
||||
'key' => 'validation.date.after',
|
||||
'data' => [
|
||||
'date' => date($format, $min),
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
throw new Exception([
|
||||
'key' => 'validation.date.before',
|
||||
'data' => [
|
||||
'date' => date($format, $max),
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
]
|
||||
];
|
40
kirby/config/fields/email.php
Normal file
40
kirby/config/fields/email.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete mode for the input
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'email') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the email icon to something custom
|
||||
*/
|
||||
'icon' => function (string $icon = 'email') {
|
||||
return $icon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom placeholder text, when the field is empty.
|
||||
*/
|
||||
'placeholder' => function ($value = null) {
|
||||
return I18n::translate($value, $value) ?? I18n::translate('email.placeholder');
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'email'
|
||||
]
|
||||
];
|
138
kirby/config/fields/files.php
Normal file
138
kirby/config/fields/files.php
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
return [
|
||||
'mixins' => [
|
||||
'picker',
|
||||
'filepicker',
|
||||
'min',
|
||||
'upload'
|
||||
],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'autofocus' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Sets the file(s), which are selected by default when a new page is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the layout of the selected files. Available layouts: `list`, `cards`
|
||||
*/
|
||||
'layout' => function (string $layout = 'list') {
|
||||
return $layout;
|
||||
},
|
||||
|
||||
/**
|
||||
* Layout size for cards: `tiny`, `small`, `medium`, `large` or `huge`
|
||||
*/
|
||||
'size' => function (string $size = 'auto') {
|
||||
return $size;
|
||||
},
|
||||
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'parentModel' => function () {
|
||||
if (is_string($this->parent) === true && $model = $this->model()->query($this->parent, 'Kirby\Cms\Model')) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
return $this->model();
|
||||
},
|
||||
'parent' => function () {
|
||||
return $this->parentModel->apiUrl(true);
|
||||
},
|
||||
'query' => function () {
|
||||
return $this->query ?? $this->parentModel::CLASS_ALIAS . '.files';
|
||||
},
|
||||
'default' => function () {
|
||||
return $this->toFiles($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toFiles($this->value);
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'fileResponse' => function ($file) {
|
||||
return $file->panelPickerData([
|
||||
'image' => $this->image,
|
||||
'info' => $this->info ?? false,
|
||||
'model' => $this->model(),
|
||||
'text' => $this->text,
|
||||
]);
|
||||
},
|
||||
'toFiles' => function ($value = null) {
|
||||
$files = [];
|
||||
|
||||
foreach (Data::decode($value, 'yaml') as $id) {
|
||||
if (is_array($id) === true) {
|
||||
$id = $id['id'] ?? null;
|
||||
}
|
||||
|
||||
if ($id !== null && ($file = $this->kirby()->file($id, $this->model()))) {
|
||||
$files[] = $this->fileResponse($file);
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
|
||||
return $field->filepicker([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'limit' => $field->limit(),
|
||||
'page' => $this->requestQuery('page'),
|
||||
'query' => $field->query(),
|
||||
'search' => $this->requestQuery('search'),
|
||||
'text' => $field->text()
|
||||
]);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'upload',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$uploads = $field->uploads();
|
||||
|
||||
return $field->upload($this, $uploads, function ($file, $parent) use ($field) {
|
||||
return $file->panelPickerData([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'model' => $field->model(),
|
||||
'text' => $field->text(),
|
||||
]);
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'uuid');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
5
kirby/config/fields/gap.php
Normal file
5
kirby/config/fields/gap.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'save' => false
|
||||
];
|
26
kirby/config/fields/headline.php
Normal file
26
kirby/config/fields/headline.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'save' => false,
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'default' => null,
|
||||
'disabled' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
'required' => null,
|
||||
'translate' => null,
|
||||
|
||||
/**
|
||||
* If `false`, the prepended number will be hidden
|
||||
*/
|
||||
'numbered' => function (bool $numbered = true) {
|
||||
return $numbered;
|
||||
}
|
||||
]
|
||||
];
|
3
kirby/config/fields/hidden.php
Normal file
3
kirby/config/fields/hidden.php
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
return [];
|
44
kirby/config/fields/info.php
Normal file
44
kirby/config/fields/info.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'default' => null,
|
||||
'disabled' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
'required' => null,
|
||||
'translate' => null,
|
||||
|
||||
/**
|
||||
* Text to be displayed
|
||||
*/
|
||||
'text' => function ($value = null) {
|
||||
return I18n::translate($value, $value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the design of the info box
|
||||
*/
|
||||
'theme' => function (string $theme = null) {
|
||||
return $theme;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'text' => function () {
|
||||
if ($text = $this->text) {
|
||||
$text = $this->model()->toString($text);
|
||||
$text = $this->kirby()->kirbytext($text);
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
],
|
||||
'save' => false,
|
||||
];
|
5
kirby/config/fields/line.php
Normal file
5
kirby/config/fields/line.php
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'save' => false
|
||||
];
|
17
kirby/config/fields/list.php
Normal file
17
kirby/config/fields/list.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Sets the allowed HTML formats. Available formats: `bold`, `italic`, `underline`, `strike`, `code`, `link`. Activate them all by passing `true`. Deactivate them all by passing `false`
|
||||
*/
|
||||
'marks' => function ($marks = true) {
|
||||
return $marks;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'value' => function () {
|
||||
return trim($this->value);
|
||||
}
|
||||
]
|
||||
];
|
28
kirby/config/fields/mixins/datetime.php
Normal file
28
kirby/config/fields/mixins/datetime.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Defines a custom format that is used when the field is saved
|
||||
*/
|
||||
'format' => function (string $format = null) {
|
||||
return $format;
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toDatetime' => function ($value, string $format = 'Y-m-d H:i:s') {
|
||||
if ($timestamp = timestamp($value, $this->step)) {
|
||||
return date($format, $timestamp);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
],
|
||||
'save' => function ($value) {
|
||||
if ($value !== null && $timestamp = strtotime($value)) {
|
||||
return date($this->format, $timestamp);
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
];
|
14
kirby/config/fields/mixins/filepicker.php
Normal file
14
kirby/config/fields/mixins/filepicker.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\FilePicker;
|
||||
|
||||
return [
|
||||
'methods' => [
|
||||
'filepicker' => function (array $params = []) {
|
||||
// fetch the parent model
|
||||
$params['model'] = $this->model();
|
||||
|
||||
return (new FilePicker($params))->toArray();
|
||||
}
|
||||
]
|
||||
];
|
22
kirby/config/fields/mixins/min.php
Normal file
22
kirby/config/fields/mixins/min.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'computed' => [
|
||||
'min' => function () {
|
||||
// set min to at least 1, if required
|
||||
if ($this->required === true) {
|
||||
return $this->min ?? 1;
|
||||
}
|
||||
|
||||
return $this->min;
|
||||
},
|
||||
'required' => function () {
|
||||
// set required to true if min is set
|
||||
if ($this->min) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->required;
|
||||
}
|
||||
]
|
||||
];
|
48
kirby/config/fields/mixins/options.php
Normal file
48
kirby/config/fields/mixins/options.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Form\Options;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* API settings for options requests. This will only take affect when `options` is set to `api`.
|
||||
*/
|
||||
'api' => function ($api = null) {
|
||||
return $api;
|
||||
},
|
||||
/**
|
||||
* An array with options
|
||||
*/
|
||||
'options' => function ($options = []) {
|
||||
return $options;
|
||||
},
|
||||
/**
|
||||
* Query settings for options queries. This will only take affect when `options` is set to `query`.
|
||||
*/
|
||||
'query' => function ($query = null) {
|
||||
return $query;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'options' => function (): array {
|
||||
return $this->getOptions();
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'getOptions' => function () {
|
||||
return Options::factory(
|
||||
$this->options(),
|
||||
$this->props,
|
||||
$this->model()
|
||||
);
|
||||
},
|
||||
'sanitizeOption' => function ($option) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return in_array($option, $allowed, true) === true ? $option : null;
|
||||
},
|
||||
'sanitizeOptions' => function ($options) {
|
||||
$allowed = array_column($this->options(), 'value');
|
||||
return array_intersect($options, $allowed);
|
||||
},
|
||||
]
|
||||
];
|
14
kirby/config/fields/mixins/pagepicker.php
Normal file
14
kirby/config/fields/mixins/pagepicker.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\PagePicker;
|
||||
|
||||
return [
|
||||
'methods' => [
|
||||
'pagepicker' => function (array $params = []) {
|
||||
// inject the current model
|
||||
$params['model'] = $this->model();
|
||||
|
||||
return (new PagePicker($params))->toArray();
|
||||
}
|
||||
]
|
||||
];
|
78
kirby/config/fields/mixins/picker.php
Normal file
78
kirby/config/fields/mixins/picker.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* The placeholder text if none have been selected yet
|
||||
*/
|
||||
'empty' => function ($empty = null) {
|
||||
return I18n::translate($empty, $empty);
|
||||
},
|
||||
|
||||
/**
|
||||
* Image settings for each item
|
||||
*/
|
||||
'image' => function ($image = null) {
|
||||
return $image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Info text for each item
|
||||
*/
|
||||
'info' => function (string $info = null) {
|
||||
return $info;
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether each item should be clickable
|
||||
*/
|
||||
'link' => function (bool $link = true) {
|
||||
return $link;
|
||||
},
|
||||
|
||||
/**
|
||||
* The minimum number of required selected
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
|
||||
/**
|
||||
* The maximum number of allowed selected
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
|
||||
/**
|
||||
* If `false`, only a single one can be selected
|
||||
*/
|
||||
'multiple' => function (bool $multiple = true) {
|
||||
return $multiple;
|
||||
},
|
||||
|
||||
/**
|
||||
* Query for the items to be included in the picker
|
||||
*/
|
||||
'query' => function (string $query = null) {
|
||||
return $query;
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable/disable the search field in the picker
|
||||
*/
|
||||
'search' => function (bool $search = true) {
|
||||
return $search;
|
||||
},
|
||||
|
||||
/**
|
||||
* Main text for each item
|
||||
*/
|
||||
'text' => function (string $text = null) {
|
||||
return $text;
|
||||
},
|
||||
|
||||
],
|
||||
];
|
72
kirby/config/fields/mixins/upload.php
Normal file
72
kirby/config/fields/mixins/upload.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Api;
|
||||
use Kirby\Cms\File;
|
||||
use Kirby\Exception\Exception;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Sets the upload options for linked files (since 3.2.0)
|
||||
*/
|
||||
'uploads' => function ($uploads = []) {
|
||||
if ($uploads === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_string($uploads) === true) {
|
||||
$uploads = ['template' => $uploads];
|
||||
}
|
||||
|
||||
if (is_array($uploads) === false) {
|
||||
$uploads = [];
|
||||
}
|
||||
|
||||
$template = $uploads['template'] ?? null;
|
||||
|
||||
if ($template) {
|
||||
$file = new File([
|
||||
'filename' => 'tmp',
|
||||
'template' => $template
|
||||
]);
|
||||
|
||||
$uploads['accept'] = $file->blueprint()->acceptMime();
|
||||
} else {
|
||||
$uploads['accept'] = '*';
|
||||
}
|
||||
|
||||
return $uploads;
|
||||
},
|
||||
],
|
||||
'methods' => [
|
||||
'upload' => function (Api $api, $params, Closure $map) {
|
||||
if ($params === false) {
|
||||
throw new Exception('Uploads are disabled for this field');
|
||||
}
|
||||
|
||||
if ($parentQuery = ($params['parent'] ?? null)) {
|
||||
$parent = $this->model()->query($parentQuery);
|
||||
} else {
|
||||
$parent = $this->model();
|
||||
}
|
||||
|
||||
if (is_a($parent, 'Kirby\Cms\File') === true) {
|
||||
$parent = $parent->parent();
|
||||
}
|
||||
|
||||
return $api->upload(function ($source, $filename) use ($parent, $params, $map) {
|
||||
$file = $parent->createFile([
|
||||
'source' => $source,
|
||||
'template' => $params['template'] ?? null,
|
||||
'filename' => $filename,
|
||||
]);
|
||||
|
||||
if (is_a($file, 'Kirby\Cms\File') === false) {
|
||||
throw new Exception('The file could not be uploaded');
|
||||
}
|
||||
|
||||
return $map($file, $parent);
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
13
kirby/config/fields/mixins/userpicker.php
Normal file
13
kirby/config/fields/mixins/userpicker.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\UserPicker;
|
||||
|
||||
return [
|
||||
'methods' => [
|
||||
'userpicker' => function (array $params = []) {
|
||||
$params['model'] = $this->model();
|
||||
|
||||
return (new UserPicker($params))->toArray();
|
||||
}
|
||||
]
|
||||
];
|
32
kirby/config/fields/multiselect.php
Normal file
32
kirby/config/fields/multiselect.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'tags',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'accept' => null,
|
||||
/**
|
||||
* Custom icon to replace the arrow down.
|
||||
*/
|
||||
'icon' => function (string $icon = null) {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Enable/disable the search in the dropdown
|
||||
* Also limit displayed items (display: 20)
|
||||
* and set minimum number of characters to search (min: 3)
|
||||
*/
|
||||
'search' => function ($search = true) {
|
||||
return $search;
|
||||
},
|
||||
/**
|
||||
* If `true`, selected entries will be sorted
|
||||
* according to their position in the dropdown
|
||||
*/
|
||||
'sort' => function (bool $sort = false) {
|
||||
return $sort;
|
||||
},
|
||||
]
|
||||
];
|
48
kirby/config/fields/number.php
Normal file
48
kirby/config/fields/number.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Default number that will be saved when a new page/user/file is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->toNumber($default);
|
||||
},
|
||||
/**
|
||||
* The lowest allowed number
|
||||
*/
|
||||
'min' => function (float $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* The highest allowed number
|
||||
*/
|
||||
'max' => function (float $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Allowed incremental steps between numbers (i.e `0.5`)
|
||||
*/
|
||||
'step' => function ($step = null) {
|
||||
return $this->toNumber($step);
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return $this->toNumber($value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toNumber' => function ($value) {
|
||||
if ($this->isEmpty($value) === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return is_float($value) === true ? $value : (float)Str::float($value);
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
117
kirby/config/fields/pages.php
Normal file
117
kirby/config/fields/pages.php
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'pagepicker', 'picker'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default selected page(s) when a new page/file/user is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->toPages($default);
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the layout of the selected files. Available layouts: `list`, `cards`
|
||||
*/
|
||||
'layout' => function (string $layout = 'list') {
|
||||
return $layout;
|
||||
},
|
||||
|
||||
/**
|
||||
* Optional query to select a specific set of pages
|
||||
*/
|
||||
'query' => function (string $query = null) {
|
||||
return $query;
|
||||
},
|
||||
|
||||
/**
|
||||
* Layout size for cards: `tiny`, `small`, `medium`, `large` or `huge`
|
||||
*/
|
||||
'size' => function (string $size = 'auto') {
|
||||
return $size;
|
||||
},
|
||||
|
||||
/**
|
||||
* Optionally include subpages of pages
|
||||
*/
|
||||
'subpages' => function (bool $subpages = true) {
|
||||
return $subpages;
|
||||
},
|
||||
|
||||
'value' => function ($value = null) {
|
||||
return $this->toPages($value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
/**
|
||||
* Unset inherited computed
|
||||
*/
|
||||
'default' => null
|
||||
],
|
||||
'methods' => [
|
||||
'pageResponse' => function ($page) {
|
||||
return $page->panelPickerData([
|
||||
'image' => $this->image,
|
||||
'info' => $this->info,
|
||||
'text' => $this->text,
|
||||
]);
|
||||
},
|
||||
'toPages' => function ($value = null) {
|
||||
$pages = [];
|
||||
$kirby = kirby();
|
||||
|
||||
foreach (Data::decode($value, 'yaml') as $id) {
|
||||
if (is_array($id) === true) {
|
||||
$id = $id['id'] ?? null;
|
||||
}
|
||||
|
||||
if ($id !== null && ($page = $kirby->page($id))) {
|
||||
$pages[] = $this->pageResponse($page);
|
||||
}
|
||||
}
|
||||
|
||||
return $pages;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
|
||||
return $field->pagepicker([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'limit' => $field->limit(),
|
||||
'page' => $this->requestQuery('page'),
|
||||
'parent' => $this->requestQuery('parent'),
|
||||
'query' => $field->query(),
|
||||
'search' => $this->requestQuery('search'),
|
||||
'subpages' => $field->subpages(),
|
||||
'text' => $field->text()
|
||||
]);
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'id');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
29
kirby/config/fields/radio.php
Normal file
29
kirby/config/fields/radio.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'mixins' => ['options'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Arranges the radio buttons in the given number of columns
|
||||
*/
|
||||
'columns' => function (int $columns = 1) {
|
||||
return $columns;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->sanitizeOption($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->sanitizeOption($this->value) ?? '';
|
||||
}
|
||||
]
|
||||
];
|
24
kirby/config/fields/range.php
Normal file
24
kirby/config/fields/range.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'number',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* The maximum value on the slider
|
||||
*/
|
||||
'max' => function (float $max = 100) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Enables/disables the tooltip and set the before and after values
|
||||
*/
|
||||
'tooltip' => function ($tooltip = true) {
|
||||
return $tooltip;
|
||||
},
|
||||
]
|
||||
];
|
24
kirby/config/fields/select.php
Normal file
24
kirby/config/fields/select.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'radio',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'columns' => null,
|
||||
|
||||
/**
|
||||
* Custom icon to replace the arrow down.
|
||||
*/
|
||||
'icon' => function (string $icon = null) {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Custom placeholder string for empty option.
|
||||
*/
|
||||
'placeholder' => function (string $placeholder = '—') {
|
||||
return $placeholder;
|
||||
},
|
||||
]
|
||||
];
|
193
kirby/config/fields/structure.php
Normal file
193
kirby/config/fields/structure.php
Normal file
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Cms\Form;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'mixins' => ['min'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'autofocus' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Optional columns definition to only show selected fields in the structure table.
|
||||
*/
|
||||
'columns' => function (array $columns = []) {
|
||||
// lower case all keys, because field names will
|
||||
// be lowercase as well.
|
||||
return array_change_key_case($columns);
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles duplicating rows for the structure
|
||||
*/
|
||||
'duplicate' => function (bool $duplicate = true) {
|
||||
return $duplicate;
|
||||
},
|
||||
|
||||
/**
|
||||
* The placeholder text if no items have been added yet
|
||||
*/
|
||||
'empty' => function ($empty = null) {
|
||||
return I18n::translate($empty, $empty);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the default rows for the structure
|
||||
*/
|
||||
'default' => function (array $default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fields setup for the structure form. Works just like fields in regular forms.
|
||||
*/
|
||||
'fields' => function (array $fields) {
|
||||
return $fields;
|
||||
},
|
||||
/**
|
||||
* The number of entries that will be displayed on a single page. Afterwards pagination kicks in.
|
||||
*/
|
||||
'limit' => function (int $limit = null) {
|
||||
return $limit;
|
||||
},
|
||||
/**
|
||||
* Maximum allowed entries in the structure. Afterwards the "Add" button will be switched off.
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Minimum required entries in the structure
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* Toggles adding to the top or bottom of the list
|
||||
*/
|
||||
'prepend' => function (bool $prepend = null) {
|
||||
return $prepend;
|
||||
},
|
||||
/**
|
||||
* Toggles drag & drop sorting
|
||||
*/
|
||||
'sortable' => function (bool $sortable = null) {
|
||||
return $sortable;
|
||||
},
|
||||
/**
|
||||
* Sorts the entries by the given field and order (i.e. `title desc`)
|
||||
* Drag & drop is disabled in this case
|
||||
*/
|
||||
'sortBy' => function (string $sort = null) {
|
||||
return $sort;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->rows($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->rows($this->value);
|
||||
},
|
||||
'fields' => function () {
|
||||
if (empty($this->fields) === true) {
|
||||
throw new Exception('Please provide some fields for the structure');
|
||||
}
|
||||
|
||||
return $this->form()->fields()->toArray();
|
||||
},
|
||||
'columns' => function () {
|
||||
$columns = [];
|
||||
|
||||
if (empty($this->columns)) {
|
||||
foreach ($this->fields as $field) {
|
||||
|
||||
// Skip hidden and unsaveable fields
|
||||
// They should never be included as column
|
||||
if ($field['type'] === 'hidden' || $field['saveable'] === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$columns[$field['name']] = [
|
||||
'type' => $field['type'],
|
||||
'label' => $field['label'] ?? $field['name']
|
||||
];
|
||||
}
|
||||
} else {
|
||||
foreach ($this->columns as $columnName => $columnProps) {
|
||||
if (is_array($columnProps) === false) {
|
||||
$columnProps = [];
|
||||
}
|
||||
|
||||
$field = $this->fields[$columnName] ?? null;
|
||||
|
||||
if (empty($field) === true || $field['saveable'] === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$columns[$columnName] = array_merge($columnProps, [
|
||||
'type' => $field['type'],
|
||||
'label' => $field['label'] ?? $field['name']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'rows' => function ($value) {
|
||||
$rows = Data::decode($value, 'yaml');
|
||||
$value = [];
|
||||
|
||||
foreach ($rows as $index => $row) {
|
||||
if (is_array($row) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value[] = $this->form($row)->values();
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
'form' => function (array $values = []) {
|
||||
return new Form([
|
||||
'fields' => $this->attrs['fields'],
|
||||
'values' => $values,
|
||||
'model' => $this->model
|
||||
]);
|
||||
},
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => 'validate',
|
||||
'method' => 'ALL',
|
||||
'action' => function () {
|
||||
return array_values($this->field()->form($this->requestBody())->errors());
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value) {
|
||||
$data = [];
|
||||
|
||||
foreach ($value as $row) {
|
||||
$data[] = $this->form($row)->content();
|
||||
}
|
||||
|
||||
return $data;
|
||||
},
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
103
kirby/config/fields/tags.php
Normal file
103
kirby/config/fields/tags.php
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Toolkit\V;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'options'],
|
||||
'props' => [
|
||||
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* If set to `all`, any type of input is accepted. If set to `options` only the predefined options are accepted as input.
|
||||
*/
|
||||
'accept' => function ($value = 'all') {
|
||||
return V::in($value, ['all', 'options']) ? $value : 'all';
|
||||
},
|
||||
/**
|
||||
* Changes the tag icon
|
||||
*/
|
||||
'icon' => function ($icon = 'tag') {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Set to `list` to display each tag with 100% width,
|
||||
* otherwise the tags are displayed inline
|
||||
*/
|
||||
'layout' => function (?string $layout = null) {
|
||||
return $layout;
|
||||
},
|
||||
/**
|
||||
* Minimum number of required entries/tags
|
||||
*/
|
||||
'min' => function (int $min = null) {
|
||||
return $min;
|
||||
},
|
||||
/**
|
||||
* Maximum number of allowed entries/tags
|
||||
*/
|
||||
'max' => function (int $max = null) {
|
||||
return $max;
|
||||
},
|
||||
/**
|
||||
* Custom tags separator, which will be used to store tags in the content file
|
||||
*/
|
||||
'separator' => function (string $separator = ',') {
|
||||
return $separator;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function (): array {
|
||||
return $this->toTags($this->default);
|
||||
},
|
||||
'value' => function (): array {
|
||||
return $this->toTags($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toTags' => function ($value) {
|
||||
if (is_null($value) === true) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$options = $this->options();
|
||||
|
||||
// transform into value-text objects
|
||||
return array_map(function ($option) use ($options) {
|
||||
|
||||
// already a valid object
|
||||
if (is_array($option) === true && isset($option['value'], $option['text']) === true) {
|
||||
return $option;
|
||||
}
|
||||
|
||||
$index = array_search($option, array_column($options, 'value'));
|
||||
|
||||
if ($index !== false) {
|
||||
return $options[$index];
|
||||
}
|
||||
|
||||
return [
|
||||
'value' => $option,
|
||||
'text' => $option,
|
||||
];
|
||||
}, Str::split($value, $this->separator()));
|
||||
}
|
||||
],
|
||||
'save' => function (array $value = null): string {
|
||||
return A::join(
|
||||
A::pluck($value, 'value'),
|
||||
$this->separator() . ' '
|
||||
);
|
||||
},
|
||||
'validations' => [
|
||||
'min',
|
||||
'max'
|
||||
]
|
||||
];
|
27
kirby/config/fields/tel.php
Normal file
27
kirby/config/fields/tel.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
'spellcheck' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete attribute
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'tel') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the phone icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'phone') {
|
||||
return $icon;
|
||||
}
|
||||
]
|
||||
];
|
103
kirby/config/fields/text.php
Normal file
103
kirby/config/fields/text.php
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
|
||||
/**
|
||||
* The field value will be converted with the selected converter before the value gets saved. Available converters: `lower`, `upper`, `ucfirst`, `slug`
|
||||
*/
|
||||
'converter' => function ($value = null) {
|
||||
if ($value !== null && in_array($value, array_keys($this->converters())) === false) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'field.converter.invalid',
|
||||
'data' => ['converter' => $value]
|
||||
]);
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows or hides the character counter in the top right corner
|
||||
*/
|
||||
'counter' => function (bool $counter = true) {
|
||||
return $counter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed characters
|
||||
*/
|
||||
'maxlength' => function (int $maxlength = null) {
|
||||
return $maxlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Minimum number of required characters
|
||||
*/
|
||||
'minlength' => function (int $minlength = null) {
|
||||
return $minlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* A regular expression, which will be used to validate the input
|
||||
*/
|
||||
'pattern' => function (string $pattern = null) {
|
||||
return $pattern;
|
||||
},
|
||||
|
||||
/**
|
||||
* If `false`, spellcheck will be switched off
|
||||
*/
|
||||
'spellcheck' => function (bool $spellcheck = false) {
|
||||
return $spellcheck;
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->convert($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
return (string)$this->convert($this->value);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'convert' => function ($value) {
|
||||
if ($this->converter() === null) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$value = trim($value);
|
||||
$converter = $this->converters()[$this->converter()];
|
||||
|
||||
if (is_array($value) === true) {
|
||||
return array_map($converter, $value);
|
||||
}
|
||||
|
||||
return call_user_func($converter, $value);
|
||||
},
|
||||
'converters' => function (): array {
|
||||
return [
|
||||
'lower' => function ($value) {
|
||||
return Str::lower($value);
|
||||
},
|
||||
'slug' => function ($value) {
|
||||
return Str::slug($value);
|
||||
},
|
||||
'ucfirst' => function ($value) {
|
||||
return Str::ucfirst($value);
|
||||
},
|
||||
'upper' => function ($value) {
|
||||
return Str::upper($value);
|
||||
},
|
||||
];
|
||||
},
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'pattern'
|
||||
]
|
||||
];
|
123
kirby/config/fields/textarea.php
Normal file
123
kirby/config/fields/textarea.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'mixins' => ['filepicker', 'upload'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'before' => null,
|
||||
|
||||
/**
|
||||
* Enables/disables the format buttons. Can either be `true`/`false` or a list of allowed buttons. Available buttons: `headlines`, `italic`, `bold`, `link`, `email`, `file`, `code`, `ul`, `ol` (as well as `|` for a divider)
|
||||
*/
|
||||
'buttons' => function ($buttons = true) {
|
||||
return $buttons;
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables/disables the character counter in the top right corner
|
||||
*/
|
||||
'counter' => function (bool $counter = true) {
|
||||
return $counter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the default text when a new page/file/user is created
|
||||
*/
|
||||
'default' => function (string $default = null) {
|
||||
return trim($default);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the options for the files picker
|
||||
*/
|
||||
'files' => function ($files = []) {
|
||||
if (is_string($files) === true) {
|
||||
return ['query' => $files];
|
||||
}
|
||||
|
||||
if (is_array($files) === false) {
|
||||
$files = [];
|
||||
}
|
||||
|
||||
return $files;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the font family (sans or monospace)
|
||||
*/
|
||||
'font' => function (string $font = null) {
|
||||
return $font === 'monospace' ? 'monospace' : 'sans-serif';
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed characters
|
||||
*/
|
||||
'maxlength' => function (int $maxlength = null) {
|
||||
return $maxlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Minimum number of required characters
|
||||
*/
|
||||
'minlength' => function (int $minlength = null) {
|
||||
return $minlength;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the size of the textarea. Available sizes: `small`, `medium`, `large`, `huge`
|
||||
*/
|
||||
'size' => function (string $size = null) {
|
||||
return $size;
|
||||
},
|
||||
|
||||
/**
|
||||
* If `false`, spellcheck will be switched off
|
||||
*/
|
||||
'spellcheck' => function (bool $spellcheck = true) {
|
||||
return $spellcheck;
|
||||
},
|
||||
|
||||
'value' => function (string $value = null) {
|
||||
return trim($value);
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => 'files',
|
||||
'action' => function () {
|
||||
$params = array_merge($this->field()->files(), [
|
||||
'page' => $this->requestQuery('page'),
|
||||
'search' => $this->requestQuery('search')
|
||||
]);
|
||||
|
||||
return $this->field()->filepicker($params);
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'upload',
|
||||
'method' => 'POST',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$uploads = $field->uploads();
|
||||
|
||||
return $this->field()->upload($this, $uploads, function ($file, $parent) use ($field) {
|
||||
$absolute = $field->model()->is($parent) === false;
|
||||
|
||||
return [
|
||||
'filename' => $file->filename(),
|
||||
'dragText' => $file->dragText('auto', $absolute),
|
||||
];
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength'
|
||||
]
|
||||
];
|
151
kirby/config/fields/time.php
Normal file
151
kirby/config/fields/time.php
Normal file
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\Exception;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'mixins' => ['datetime'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
|
||||
/**
|
||||
* Sets the default time when a new page/file/user is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $default;
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom format (dayjs tokens: `HH`, `hh`, `mm`, `ss`, `a`) that is
|
||||
* used to display the field in the Panel
|
||||
*/
|
||||
'display' => function ($display = null) {
|
||||
return I18n::translate($display, $display);
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the clock icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'clock') {
|
||||
return $icon;
|
||||
},
|
||||
/**
|
||||
* Latest time, which can be selected/saved (H:i or H:i:s)
|
||||
*/
|
||||
'max' => function (string $max = null) {
|
||||
return $max ? $this->toDatetime(date('Y-m-d ') . $max) : null;
|
||||
},
|
||||
/**
|
||||
* Earliest time, which can be selected/saved (H:i or H:i:s)
|
||||
*/
|
||||
'min' => function (string $min = null) {
|
||||
return $min ? $this->toDatetime(date('Y-m-d ') . $min) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* `12` or `24` hour notation. If `12`, an AM/PM selector will be shown.
|
||||
* If `display` is defined, that option will take priority.
|
||||
*/
|
||||
'notation' => function (int $value = 24) {
|
||||
return $value === 24 ? 24 : 12;
|
||||
},
|
||||
/**
|
||||
* Round to the nearest: sub-options for `unit` (minute) and `size` (5)
|
||||
*/
|
||||
'step' => function ($step = null) {
|
||||
$default = [
|
||||
'size' => 5,
|
||||
'unit' => 'minute'
|
||||
];
|
||||
|
||||
if ($step === null) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (is_array($step) === true) {
|
||||
$step = array_merge($default, $step);
|
||||
$step['unit'] = strtolower($step['unit']);
|
||||
return $step;
|
||||
}
|
||||
|
||||
if (is_int($step) === true) {
|
||||
return array_merge($default, ['size' => $step]);
|
||||
}
|
||||
|
||||
if (is_string($step) === true) {
|
||||
return array_merge($default, ['unit' => strtolower($step)]);
|
||||
}
|
||||
},
|
||||
'value' => function ($value = null) {
|
||||
return $value;
|
||||
}
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toDatetime($this->default, 'H:i:s');
|
||||
},
|
||||
'display' => function () {
|
||||
if ($this->display) {
|
||||
return $this->display;
|
||||
}
|
||||
|
||||
return $this->notation === 24 ? 'HH:mm' : 'h:mm a';
|
||||
},
|
||||
'format' => function () {
|
||||
return $this->props['format'] ?? 'H:i:s';
|
||||
},
|
||||
'value' => function () {
|
||||
return $this->toDatetime($this->value, 'H:i:s');
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'time',
|
||||
'minMax' => function ($value) {
|
||||
$min = $this->min ? strtotime($this->min) : null;
|
||||
$max = $this->max ? strtotime($this->max) : null;
|
||||
$value = strtotime($this->value());
|
||||
$format = 'H:i:s';
|
||||
$errors = [];
|
||||
|
||||
if ($value && $min && $value < $min) {
|
||||
$errors['min'] = $min;
|
||||
}
|
||||
|
||||
if ($value && $max && $value > $max) {
|
||||
$errors['max'] = $max;
|
||||
}
|
||||
|
||||
if (empty($errors) === false) {
|
||||
if ($min && $max) {
|
||||
throw new Exception([
|
||||
'key' => 'validation.time.between',
|
||||
'data' => [
|
||||
'min' => date($format, $min),
|
||||
'max' => date($format, $max)
|
||||
]
|
||||
]);
|
||||
} elseif ($min) {
|
||||
throw new Exception([
|
||||
'key' => 'validation.time.after',
|
||||
'data' => [
|
||||
'time' => date($format, $min),
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
throw new Exception([
|
||||
'key' => 'validation.time.before',
|
||||
'data' => [
|
||||
'time' => date($format, $max),
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
]
|
||||
];
|
66
kirby/config/fields/toggle.php
Normal file
66
kirby/config/fields/toggle.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default value which will be saved when a new page/user/file is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
return $this->default = $default;
|
||||
},
|
||||
/**
|
||||
* Sets the text next to the toggle. The text can be a string or an array of two options. The first one is the negative text and the second one the positive. The text will automatically switch when the toggle is triggered.
|
||||
*/
|
||||
'text' => function ($value = null) {
|
||||
if (is_array($value) === true) {
|
||||
if (A::isAssociative($value) === true) {
|
||||
return I18n::translate($value, $value);
|
||||
}
|
||||
|
||||
foreach ($value as $key => $val) {
|
||||
$value[$key] = I18n::translate($val, $val);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
return I18n::translate($value, $value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
'default' => function () {
|
||||
return $this->toBool($this->default);
|
||||
},
|
||||
'value' => function () {
|
||||
if ($this->props['value'] === null) {
|
||||
return $this->default();
|
||||
} else {
|
||||
return $this->toBool($this->props['value']);
|
||||
}
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
'toBool' => function ($value) {
|
||||
return in_array($value, [true, 'true', 1, '1', 'on'], true) === true;
|
||||
}
|
||||
],
|
||||
'save' => function (): string {
|
||||
return $this->value() === true ? 'true' : 'false';
|
||||
},
|
||||
'validations' => [
|
||||
'boolean',
|
||||
'required' => function ($value) {
|
||||
if ($this->isRequired() && ($value === false || $this->isEmpty($value))) {
|
||||
throw new InvalidArgumentException(I18n::translate('field.required'));
|
||||
}
|
||||
},
|
||||
]
|
||||
];
|
41
kirby/config/fields/url.php
Normal file
41
kirby/config/fields/url.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'extends' => 'text',
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'converter' => null,
|
||||
'counter' => null,
|
||||
'spellcheck' => null,
|
||||
|
||||
/**
|
||||
* Sets the HTML5 autocomplete attribute
|
||||
*/
|
||||
'autocomplete' => function (string $autocomplete = 'url') {
|
||||
return $autocomplete;
|
||||
},
|
||||
|
||||
/**
|
||||
* Changes the link icon
|
||||
*/
|
||||
'icon' => function (string $icon = 'url') {
|
||||
return $icon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets custom placeholder text, when the field is empty
|
||||
*/
|
||||
'placeholder' => function ($value = null) {
|
||||
return I18n::translate($value, $value) ?? 'https://example.com';
|
||||
}
|
||||
],
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength',
|
||||
'url'
|
||||
],
|
||||
];
|
97
kirby/config/fields/users.php
Normal file
97
kirby/config/fields/users.php
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Toolkit\A;
|
||||
|
||||
return [
|
||||
'mixins' => ['min', 'picker', 'userpicker'],
|
||||
'props' => [
|
||||
/**
|
||||
* Unset inherited props
|
||||
*/
|
||||
'after' => null,
|
||||
'autofocus' => null,
|
||||
'before' => null,
|
||||
'icon' => null,
|
||||
'placeholder' => null,
|
||||
|
||||
/**
|
||||
* Default selected user(s) when a new page/file/user is created
|
||||
*/
|
||||
'default' => function ($default = null) {
|
||||
if ($default === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($default === null && $user = $this->kirby()->user()) {
|
||||
return [
|
||||
$this->userResponse($user)
|
||||
];
|
||||
}
|
||||
|
||||
return $this->toUsers($default);
|
||||
},
|
||||
|
||||
'value' => function ($value = null) {
|
||||
return $this->toUsers($value);
|
||||
},
|
||||
],
|
||||
'computed' => [
|
||||
/**
|
||||
* Unset inherited computed
|
||||
*/
|
||||
'default' => null
|
||||
],
|
||||
'methods' => [
|
||||
'userResponse' => function ($user) {
|
||||
return $user->panelPickerData([
|
||||
'info' => $this->info,
|
||||
'image' => $this->image,
|
||||
'text' => $this->text,
|
||||
]);
|
||||
},
|
||||
'toUsers' => function ($value = null) {
|
||||
$users = [];
|
||||
$kirby = kirby();
|
||||
|
||||
foreach (Data::decode($value, 'yaml') as $email) {
|
||||
if (is_array($email) === true) {
|
||||
$email = $email['email'] ?? null;
|
||||
}
|
||||
|
||||
if ($email !== null && ($user = $kirby->user($email))) {
|
||||
$users[] = $this->userResponse($user);
|
||||
}
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => '/',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
|
||||
return $field->userpicker([
|
||||
'image' => $field->image(),
|
||||
'info' => $field->info(),
|
||||
'limit' => $field->limit(),
|
||||
'page' => $this->requestQuery('page'),
|
||||
'query' => $field->query(),
|
||||
'search' => $this->requestQuery('search'),
|
||||
'text' => $field->text()
|
||||
]);
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'save' => function ($value = null) {
|
||||
return A::pluck($value, 'id');
|
||||
},
|
||||
'validations' => [
|
||||
'max',
|
||||
'min'
|
||||
]
|
||||
];
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue