Upgrade to 3.5.1

This commit is contained in:
Bastian Allgeier
2021-01-19 12:20:38 +01:00
parent 8f55019e01
commit 99c36fa137
119 changed files with 2973 additions and 3707 deletions

View File

@@ -1,11 +1,15 @@
{
"name": "getkirby/cms",
"description": "The Kirby 3 core",
"version": "3.5.0",
"license": "proprietary",
"keywords": ["kirby", "cms", "core"],
"homepage": "https://getkirby.com",
"type": "kirby-cms",
"description": "The Kirby 3 core",
"keywords": [
"kirby",
"cms",
"core"
],
"homepage": "https://getkirby.com",
"version": "3.5.1",
"license": "proprietary",
"authors": [
{
"name": "Kirby Team",
@@ -13,42 +17,61 @@
"homepage": "https://getkirby.com"
}
],
"require": {
"php": ">=7.3.0 <8.1.0",
"ext-ctype": "*",
"ext-mbstring": "*",
"claviska/simpleimage": "3.5.1",
"filp/whoops": "2.9.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.2.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.haxx.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 --config .php_cs",
"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"
},
"require": {
"php": ">=7.3.0 <8.1.0",
"ext-mbstring": "*",
"ext-ctype": "*",
"getkirby/composer-installer": "^1.2.0",
"mustangostang/spyc": "0.6.3",
"michelf/php-smartypants": "1.8.1",
"claviska/simpleimage": "3.5.1",
"phpmailer/phpmailer": "6.2.0",
"filp/whoops": "2.9.1",
"true/punycode": "2.1.1",
"laminas/laminas-escaper": "2.7.0"
},
"autoload": {
"files": ["config/setup.php"],
"classmap": ["dependencies/"],
"psr-4": {
"Kirby\\": "src/"
}
},
"scripts": {
"analyze": "phpstan analyse",
"build": "./scripts/build",
"fix": "php-cs-fixer fix --config .php_cs",
"post-update-cmd": "curl -o cacert.pem https://curl.haxx.se/ca/cacert.pem",
"test": "phpunit --stderr --coverage-html=tests/coverage",
"zip": "composer archive --format=zip --file=dist"
},
"config": {
"optimize-autoloader": true,
"platform-check": false
}
}

41
kirby/composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1ec5fdc421a405fb7b885ff3ed7cc137",
"content-hash": "0960cd0d8666490230ea33ff2557c4ac",
"packages": [
{
"name": "claviska/simpleimage",
@@ -122,24 +122,23 @@
},
{
"name": "getkirby/composer-installer",
"version": "1.2.0",
"version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/getkirby/composer-installer.git",
"reference": "240a8b2c275d61b66601feb58222b7d34bc6cf1e"
"reference": "c98ece30bfba45be7ce457e1102d1b169d922f3d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/getkirby/composer-installer/zipball/240a8b2c275d61b66601feb58222b7d34bc6cf1e",
"reference": "240a8b2c275d61b66601feb58222b7d34bc6cf1e",
"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.*@dev",
"phpunit/phpunit": "^7.0"
"composer/composer": "^1.8 || ^2.0"
},
"type": "composer-plugin",
"extra": {
@@ -158,9 +157,15 @@
"homepage": "https://getkirby.com",
"support": {
"issues": "https://github.com/getkirby/composer-installer/issues",
"source": "https://github.com/getkirby/composer-installer/tree/1.2.0"
"source": "https://github.com/getkirby/composer-installer/tree/1.2.1"
},
"time": "2020-09-13T14:43:34+00:00"
"funding": [
{
"url": "https://getkirby.com/buy",
"type": "custom"
}
],
"time": "2020-12-28T12:54:39+00:00"
},
{
"name": "laminas/laminas-escaper",
@@ -575,16 +580,16 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.20.0",
"version": "v1.22.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531"
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"shasum": ""
},
"require": {
@@ -596,7 +601,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -635,7 +640,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0"
},
"funding": [
{
@@ -651,7 +656,7 @@
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
"time": "2021-01-07T16:49:33+00:00"
},
{
"name": "true/punycode",
@@ -712,8 +717,8 @@
"prefer-lowest": false,
"platform": {
"php": ">=7.3.0 <8.1.0",
"ext-mbstring": "*",
"ext-ctype": "*"
"ext-ctype": "*",
"ext-mbstring": "*"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"

View File

@@ -11,8 +11,11 @@ return [
'ascii' => function () {
return Str::$ascii;
},
'authStatus' => function () {
return $this->kirby()->auth()->status()->toArray();
},
'defaultLanguage' => function () {
return $this->kirby()->option('panel.language', 'en');
return $this->kirby()->panelLanguage();
},
'isOk' => function (System $system) {
return $system->isOk();
@@ -35,21 +38,17 @@ return [
'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());
},
'pendingChallenge' => function () {
if ($this->session()->get('kirby.challenge.email') === null) {
return null;
}
// fake the email challenge if no challenge was created
// to avoid leaking whether the user exists
return $this->session()->get('kirby.challenge.type', 'email');
},
'pendingEmail' => function () {
return $this->session()->get('kirby.challenge.email');
},
'requirements' => function (System $system) {
return $system->toArray();
},
@@ -70,7 +69,7 @@ return [
if ($user = $this->user()) {
$translationCode = $user->language();
} else {
$translationCode = $this->kirby()->option('panel.language', 'en');
$translationCode = $this->kirby()->panelLanguage();
}
if ($translation = $this->kirby()->translation($translationCode)) {
@@ -98,12 +97,11 @@ return [
'type' => 'Kirby\Cms\System',
'views' => [
'login' => [
'authStatus',
'isOk',
'isInstallable',
'isInstalled',
'loginMethods',
'pendingChallenge',
'pendingEmail',
'title',
'translation'
],
@@ -124,6 +122,7 @@ return [
'kirbytext',
'languages',
'license',
'locales',
'multilang',
'requirements',
'site',

View File

@@ -65,7 +65,7 @@ return [
isset($methods['password']['2fa']) === true &&
$methods['password']['2fa'] === true
) {
$challenge = $auth->login2fa($email, $password, $long);
$status = $auth->login2fa($email, $password, $long);
} else {
$user = $auth->login($email, $password, $long);
}
@@ -78,7 +78,7 @@ return [
throw new InvalidArgumentException('Login without password is not enabled');
}
$challenge = $auth->createChallenge($email, $long, $mode);
$status = $auth->createChallenge($email, $long, $mode);
}
if (isset($user)) {
@@ -89,11 +89,9 @@ return [
];
} else {
return [
'code' => 200,
'status' => 'ok',
// don't leak users that don't exist at this point
'challenge' => $challenge ?? 'email'
'code' => 200,
'status' => 'ok',
'challenge' => $status->challenge()
];
}
}

View File

@@ -1 +1,2 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<pre><code class="language-<?= $block->language()->or('text') ?>"><?= $block->code()->html(false) ?></code></pre>

View File

@@ -1,3 +1,4 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<figure>
<ul>
<?php foreach ($block->images()->toFiles() as $image): ?>

View File

@@ -1 +1,2 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<<?= $level = $block->level()->or('h2') ?>><?= $block->text() ?></<?= $level ?>>

View File

@@ -1,5 +1,6 @@
<?php
/** @var \Kirby\Cms\Block $block */
$alt = $block->alt();
$caption = $block->caption();
$crop = $block->crop()->isTrue();

View File

@@ -1 +1,2 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<?= $block->text();

View File

@@ -1 +1,2 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<?= $block->text()->kt();

View File

@@ -1,3 +1,4 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<blockquote>
<?= $block->text() ?>
<?php if ($block->citation()->isNotEmpty()): ?>

View File

@@ -1 +1,2 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<?= $block->text();

View File

@@ -1,3 +1,4 @@
<?php /** @var \Kirby\Cms\Block $block */ ?>
<?php if ($block->url()->isNotEmpty()): ?>
<figure>
<?= video($block->url()) ?>

View File

@@ -106,6 +106,9 @@ return [
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;
@@ -127,10 +130,6 @@ return [
return $this->toDatetime($this->value);
},
],
'save' => function ($value) {
$format = $this->time === false ? 'Y-m-d' : 'Y-m-d H:i:s';
return $this->toContent($value, $format);
},
'validations' => [
'date',
'minMax' => function ($value) {

View File

@@ -1,6 +1,14 @@
<?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)) {
@@ -8,13 +16,13 @@ return [
}
return null;
},
'toContent' => function ($value, string $format = 'Y-m-d H:i:s') {
if ($value !== null && $timestamp = strtotime($value)) {
return date($format, $timestamp);
}
return '';
}
]
],
'save' => function ($value) {
if ($value !== null && $timestamp = strtotime($value)) {
return date($this->format, $timestamp);
}
return '';
},
];

View File

@@ -95,13 +95,13 @@ return [
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');
}
],
'save' => function ($value): string {
return $this->toContent($value, 'H:i:s');
},
'validations' => [
'time',
'minMax' => function ($value) {

View File

@@ -5,6 +5,7 @@ use Kirby\Cms\Asset;
use Kirby\Cms\Html;
use Kirby\Cms\Response;
use Kirby\Cms\Url;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Toolkit\Escape;
use Kirby\Toolkit\F;
use Kirby\Toolkit\I18n;
@@ -110,7 +111,7 @@ function css($url, $options = null): ?string
}
}
$url = $kirby->component('css')($kirby, $url, $options);
$url = ($kirby->component('css'))($kirby, $url, $options);
$url = Url::to($url);
$attr = array_merge((array)$options, [
'href' => $url,
@@ -148,7 +149,7 @@ if (function_exists('dump') === false) {
function dump($variable, bool $echo = true): string
{
$kirby = App::instance();
return $kirby->component('dump')($kirby, $variable, $echo);
return ($kirby->component('dump'))($kirby, $variable, $echo);
}
}
@@ -382,7 +383,7 @@ function js($url, $options = null): ?string
}
}
$url = $kirby->component('js')($kirby, $url, $options);
$url = ($kirby->component('js'))($kirby, $url, $options);
$url = Url::to($url);
$attr = array_merge((array)$options, ['src' => $url]);
@@ -623,7 +624,7 @@ function site()
function size($value): int
{
if (is_numeric($value)) {
return $value;
return (int)$value;
}
if (is_string($value)) {
@@ -643,6 +644,8 @@ function size($value): int
return $value->count();
}
}
throw new InvalidArgumentException('Could not determine the size of the given value');
}
/**
@@ -744,9 +747,9 @@ function tc($key, int $count)
*
* @param string $date
* @param int $step array of `unit` and `size` to round to nearest
* @return string|null
* @return int|null
*/
function timestamp(string $date = null, $step = null): ?string
function timestamp(string $date = null, $step = null): ?int
{
if (V::date($date) === false) {
return null;
@@ -791,7 +794,7 @@ function timestamp(string $date = null, $step = null): ?string
$parts[$part] = 0;
}
return strtotime(
$timestamp = strtotime(
$parts['year'] . '-' .
str_pad($parts['month'], 2, 0, STR_PAD_LEFT) . '-' .
str_pad($parts['day'], 2, 0, STR_PAD_LEFT) . ' ' .
@@ -799,6 +802,9 @@ function timestamp(string $date = null, $step = null): ?string
str_pad($parts['minute'], 2, 0, STR_PAD_LEFT) . ':' .
str_pad($parts['second'], 2, 0, STR_PAD_LEFT)
);
// on error, convert `false` into `null`
return $timestamp ? $timestamp : null;
}
/**

View File

@@ -127,7 +127,7 @@ return function (App $app) {
return $time;
}
return $app->option('date.handler', 'date')($format, $time);
return ($app->option('date.handler', 'date'))($format, $time);
},
/**

View File

@@ -5,11 +5,6 @@
*/
define('DS', '/');
/**
* Load files that can't be autoloaded
*/
require_once __DIR__ . '/helpers.php';
/**
* Class aliases
*/

View File

@@ -1,3 +1,8 @@
<?php
/**
* @var \Kirby\Cms\User $user
* @var string $code
* @var int $timeout
*/
echo I18n::template('login.email.login.body', null, compact('user', 'code', 'timeout'));

View File

@@ -1,3 +1,8 @@
<?php
/**
* @var \Kirby\Cms\User $user
* @var string $code
* @var int $timeout
*/
echo I18n::template('login.email.password-reset.body', null, compact('user', 'code', 'timeout'));

View File

@@ -63,7 +63,7 @@
"error.field.converter.invalid": "컨버터({converter})가 올바르지 않습니다.",
"error.file.changeName.empty": "사용자명을 입력하세요.",
"error.file.changeName.empty": "파일명을 입력하세요.",
"error.file.changeName.permission": "파일명({filename})을 변경할 권한이 없습니다.",
"error.file.duplicate": "파일명이 같은 파일({filename})이 있습니다.",
"error.file.extension.forbidden": "이 확장자({extension})는 업로드할 수 없습니다.",
@@ -78,7 +78,7 @@
"error.file.mime.missing": "파일({filename})의 MIME 형식을 확인할 수 없습니다.",
"error.file.minheight": "{height}픽셀 이상으로 이미지의 높이를 설정하세요.",
"error.file.minsize": "파일이 너무 작습니다.",
"error.file.minwidth": "{width}픽셀 이상으로 이미지의 너비를 설정하세요.",
"error.file.minwidth": "이미지의 너비를 {width}픽셀 이상으로 설정하세요.",
"error.file.name.missing": "파일명을 입력하세요.",
"error.file.notFound": "파일({filename})이 없습니다.",
"error.file.orientation": "이미지의 비율({orientation})을 확인하세요.",
@@ -271,8 +271,8 @@
"hide": "숨기기",
"hour": "시",
"insert": "\uc0bd\uc785",
"insert.after": "에 삽입",
"insert.before": "에 삽입",
"insert.after": "에 삽입",
"insert.before": "에 삽입",
"install": "설치",
"installation": "설치",
@@ -300,7 +300,7 @@
"language.direction.rtl": "오른쪽에서 왼쪽",
"language.locale": "PHP 로캘 문자열",
"language.locale.warning": "사용자 지정 로캘을 사용 중입니다. 폴더(<code>/site/languages</code>)의 언어 파일을 수정하세요.",
"language.name": "사용자명",
"language.name": "언어명",
"language.updated": "언어를 변경했습니다.",
"languages": "언어",
@@ -368,7 +368,7 @@
"months.september": "9\uc6d4",
"more": "더 보기",
"name": "사용자명",
"name": "파일명",
"next": "다음",
"off": "끔",
"on": "켬",
@@ -417,7 +417,7 @@
"prev": "이전",
"preview": "미리 보기",
"remove": "삭제",
"rename": "제목 변경",
"rename": "파일명 변경",
"replace": "\uad50\uccb4",
"retry": "\ub2e4\uc2dc \uc2dc\ub3c4",
"revert": "복원",
@@ -479,7 +479,7 @@
"upload.error.extension": "파일 확장자를 확인하세요.",
"upload.error.formSize": "업로드한 파일이 허용된 크기(MAX_FILE_SIZE)를 초과했습니다.",
"upload.error.iniPostSize": "업로드한 파일이 PHP 환경 설정 파일(php.ini)에서 허용된 크기(post_max_size)를 초과했습니다.",
"upload.error.iniSize": "업로드한 파일이 PHP 환경 설정 파일(php.ini)에서 허용된 허용된 크기(upload_max_filesize)를 초과했습니다.",
"upload.error.iniSize": "업로드한 파일이 PHP 환경 설정 파일(php.ini)에서 허용된 크기(upload_max_filesize)를 초과했습니다.",
"upload.error.noFile": "업로드한 파일이 없습니다.",
"upload.error.noFiles": "업로드한 파일이 없습니다.",
"upload.error.partial": "일부 파일을 업로드했습니다.",

View File

@@ -67,7 +67,7 @@
"error.file.changeName.permission": "У вас нет права поменять название \"{filename}\"",
"error.file.duplicate": "Файл с названием \"{filename}\" уже есть",
"error.file.extension.forbidden": "Расширение файла \"{extension}\" неразрешено",
"error.file.extension.invalid": "Invalid extension: {extension}",
"error.file.extension.invalid": "Неверное разрешение: {extension}",
"error.file.extension.missing": "Файлу \"{filename}\" не хватает расширения",
"error.file.maxheight": "Высота картинки не должна превышать {height} px",
"error.file.maxsize": "Файл слишком большой",
@@ -83,7 +83,7 @@
"error.file.notFound": "\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d",
"error.file.orientation": "Ориентация картинки должна быть \"{orientation}\"",
"error.file.type.forbidden": "У вас нет права загружать файлы {type}",
"error.file.type.invalid": "Invalid file type: {type}",
"error.file.type.invalid": "Неверный тип файла: {type}",
"error.file.undefined": "\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d",
"error.form.incomplete": "Пожалуйста, исправьте все ошибки в форме",
@@ -93,8 +93,8 @@
"error.language.duplicate": "Язык уже есть",
"error.language.name": "Пожалуйста, впишите правильное название языка",
"error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}",
"error.layout.validation.settings": "There's an error in layout {index} settings",
"error.layout.validation.block": "Ошибка в блоке {blockIndex} в макете {layoutIndex}",
"error.layout.validation.settings": "Ошибка в настройках макета {index}",
"error.license.format": "Пожалуйста, введите правильный лицензионный код",
"error.license.email": "Пожалуйста, введите правильный адрес эл. почты",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
namespace Kirby\Cache;
use APCuIterator;
use APCUIterator;
/**
* APCu Cache Driver
@@ -35,7 +35,7 @@ class ApcuCache extends Cache
public function flush(): bool
{
if (empty($this->options['prefix']) === false) {
return apcu_delete(new APCuIterator('!^' . preg_quote($this->options['prefix']) . '!'));
return apcu_delete(new APCUIterator('!^' . preg_quote($this->options['prefix']) . '!'));
} else {
return apcu_clear_cache();
}

View File

@@ -2,6 +2,8 @@
namespace Kirby\Cache;
use Memcached as MemcachedExt;
/**
* Memcached Driver
*
@@ -15,7 +17,7 @@ class MemCached extends Cache
{
/**
* store for the memache connection
* @var Memcached
* @var \Memcached
*/
protected $connection;
@@ -36,7 +38,7 @@ class MemCached extends Cache
parent::__construct(array_merge($defaults, $options));
$this->connection = new \Memcached();
$this->connection = new MemcachedExt();
$this->connection->addServer($this->options['host'], $this->options['port']);
}

View File

@@ -41,8 +41,11 @@ class Api extends BaseApi
$allowImpersonation = $this->kirby()->option('api.allowImpersonation', false);
if ($user = $this->kirby->user(null, $allowImpersonation)) {
$this->kirby->setCurrentTranslation($user->language());
$translation = $user->language();
} else {
$translation = $this->kirby->panelLanguage();
}
$this->kirby->setCurrentTranslation($translation);
return parent::call($path, $method, $requestData);
}

View File

@@ -852,7 +852,7 @@ class App
*/
public function markdown(string $text = null, bool $inline = false): string
{
return $this->component('markdown')($this, $text, $this->options['markdown'] ?? [], $inline);
return ($this->component('markdown'))($this, $text, $this->options['markdown'] ?? [], $inline);
}
/**
@@ -1101,6 +1101,7 @@ class App
if ($page) {
try {
$response = $this->response();
$output = $page->render([], $extension);
// attach a MIME type based on the representation
// only if no custom MIME type was set
@@ -1108,7 +1109,7 @@ class App
$response->type($extension);
}
return $response->body($page->render([], $extension));
return $response->body($output);
} catch (NotFoundException $e) {
return null;
}
@@ -1373,7 +1374,7 @@ class App
}
}
return $this->component('smartypants')($this, $text, $options);
return ($this->component('smartypants'))($this, $text, $options);
}
/**
@@ -1387,7 +1388,7 @@ class App
*/
public function snippet($name, array $data = []): ?string
{
return $this->component('snippet')($this, $name, array_merge($this->data, $data));
return ($this->component('snippet'))($this, $name, array_merge($this->data, $data));
}
/**
@@ -1412,7 +1413,7 @@ class App
*/
public function template(string $name, string $type = 'html', string $defaultType = 'html')
{
return $this->component('template')($this, $name, $type, $defaultType);
return ($this->component('template'))($this, $name, $type, $defaultType);
}
/**
@@ -1425,7 +1426,7 @@ class App
*/
public function thumb(string $src, string $dst, array $options = []): string
{
return $this->component('thumb')($this, $src, $dst, $options);
return ($this->component('thumb'))($this, $src, $dst, $options);
}
/**

View File

@@ -2,7 +2,6 @@
namespace Kirby\Cms;
use Kirby\Cache\Cache;
use Kirby\Cache\NullCache;
use Kirby\Exception\InvalidArgumentException;
@@ -73,7 +72,7 @@ trait AppCaches
*/
protected function cacheOptions(string $key): array
{
$options = $this->option($cacheKey = $this->cacheOptionsKey($key), false);
$options = $this->option($this->cacheOptionsKey($key), false);
if ($options === false) {
return [

View File

@@ -2,7 +2,6 @@
namespace Kirby\Cms;
use Kirby\Data\Data;
use Kirby\Toolkit\I18n;
use Kirby\Toolkit\Locale;
use Kirby\Toolkit\Str;
@@ -46,6 +45,7 @@ trait AppTranslations
return $data;
};
// the actual locale is set using $app->setCurrentTranslation()
I18n::$locale = function (): string {
if ($this->multilang() === true) {
return $this->defaultLanguage()->code();
@@ -54,11 +54,25 @@ trait AppTranslations
}
};
I18n::$fallback = function (): string {
I18n::$fallback = function (): array {
if ($this->multilang() === true) {
return $this->defaultLanguage()->code();
// first try to fall back to the configured default language
$defaultCode = $this->defaultLanguage()->code();
$fallback = [$defaultCode];
// if the default language is specified with a country code
// (e.g. `en-us`), also try with just the language code
if (preg_match('/^([a-z]{2})-[a-z]+$/i', $defaultCode, $matches) === 1) {
$fallback[] = $matches[1];
}
// fall back to the complete English translation
// as a last resort
$fallback[] = 'en';
return $fallback;
} else {
return 'en';
return ['en'];
}
};
@@ -74,6 +88,30 @@ trait AppTranslations
}
}
/**
* Returns the language code that will be used
* for the Panel if no user is logged in or if
* no language is configured for the user
*
* @return string
*/
public function panelLanguage(): string
{
if ($this->multilang() === true) {
$defaultCode = $this->defaultLanguage()->code();
// extract the language code from a language that
// contains the country code (e.g. `en-us`)
if (preg_match('/^([a-z]{2})-[a-z]+$/i', $defaultCode, $matches) === 1) {
$defaultCode = $matches[1];
}
} else {
$defaultCode = 'en';
}
return $this->option('panel.language', $defaultCode);
}
/**
* Load and set the current language if it exists
* Otherwise fall back to the default language
@@ -132,10 +170,10 @@ trait AppTranslations
/**
* Load a specific translation by locale
*
* @param string|null $locale
* @param string|null $locale Locale name or `null` for the current locale
* @return \Kirby\Cms\Translation|null
*/
public function translation(string $locale = null)
public function translation(?string $locale = null)
{
$locale = $locale ?? I18n::locale();
$locale = basename($locale);

View File

@@ -2,6 +2,7 @@
namespace Kirby\Cms;
use Kirby\Cms\Auth\Status;
use Kirby\Data\Data;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\LogicException;
@@ -32,9 +33,41 @@ class Auth
*/
public static $challenges = [];
/**
* Currently impersonated user
*
* @var \Kirby\Cms\User|null
*/
protected $impersonate;
/**
* Kirby instance
*
* @var \Kirby\Cms\App
*/
protected $kirby;
/**
* Cache of the auth status object
*
* @var \Kirby\Cms\Auth\Status
*/
protected $status;
/**
* Instance of the currently logged in user or
* `false` if the user was not yet determined
*
* @var \Kirby\Cms\User|null|false
*/
protected $user = false;
/**
* Exception that was thrown while
* determining the current user
*
* @var \Throwable
*/
protected $userException;
/**
@@ -53,15 +86,13 @@ class Auth
* @param string $email
* @param bool $long If `true`, a long session will be created
* @param string $mode Either 'login' or 'password-reset'
* @return string|null Name of the challenge that was created;
* `null` if the user does not exist or no
* challenge was available for the user
* @return \Kirby\Cms\Auth\Status
*
* @throws \Kirby\Exception\LogicException If there is no suitable authentication challenge (only in debug mode)
* @throws \Kirby\Exception\NotFoundException If the user does not exist (only in debug mode)
* @throws \Kirby\Exception\PermissionException If the rate limit is exceeded
*/
public function createChallenge(string $email, bool $long = false, string $mode = 'login'): ?string
public function createChallenge(string $email, bool $long = false, string $mode = 'login')
{
// ensure that email addresses with IDN domains are in Unicode format
$email = Idn::decodeEmail($email);
@@ -91,8 +122,7 @@ class Auth
if ($user = $this->kirby->users()->find($email)) {
$timeout = $this->kirby->option('auth.challenge.timeout', 10 * 60);
$challenges = $this->kirby->option('auth.challenges', ['email']);
foreach (A::wrap($challenges) as $name) {
foreach ($this->enabledChallenges() as $name) {
$class = static::$challenges[$name] ?? null;
if (
$class &&
@@ -115,7 +145,7 @@ class Auth
}
// if no suitable challenge was found, `$challenge === null` at this point;
// only leak this in debug mode, otherwise `null` is returned below
// only leak this in debug mode
if ($challenge === null && $this->kirby->option('debug') === true) {
throw new LogicException('Could not find a suitable authentication challenge');
}
@@ -142,7 +172,10 @@ class Auth
// avoid leaking whether the user exists
usleep(random_int(1000, 300000));
return $challenge;
// clear the status cache
$this->status = null;
return $this->status($session, false);
}
/**
@@ -230,15 +263,7 @@ class Auth
*/
public function currentUserFromSession($session = null)
{
// use passed session options or session object if set
if (is_array($session) === true) {
$session = $this->kirby->session($session);
}
// try session in header or cookie
if (is_a($session, 'Kirby\Session\Session') === false) {
$session = $this->kirby->session(['detect' => true]);
}
$session = $this->session($session);
$id = $session->data()->get('kirby.userId');
@@ -256,6 +281,17 @@ class Auth
return null;
}
/**
* Returns the list of enabled challenges in the
* configured order
*
* @return array
*/
public function enabledChallenges(): array
{
return A::wrap($this->kirby->option('auth.challenges', ['email']));
}
/**
* Become any existing user or disable the current user
*
@@ -268,6 +304,9 @@ class Auth
*/
public function impersonate(?string $who = null)
{
// clear the status cache
$this->status = null;
switch ($who) {
case null:
return $this->impersonate = null;
@@ -359,6 +398,9 @@ class Auth
$user = $this->validatePassword($email, $password);
$user->loginPasswordless($options);
// clear the status cache
$this->status = null;
return $user;
}
@@ -368,8 +410,7 @@ class Auth
* @param string $email
* @param string $password
* @param bool $long
* @return string|null Name of the challenge that was created;
* `null` if no challenge was available for the user
* @return \Kirby\Cms\Auth\Status
*
* @throws \Kirby\Exception\PermissionException If the rate limit was exceeded or if any other error occured with debug mode off
* @throws \Kirby\Exception\NotFoundException If the email was invalid
@@ -394,6 +435,57 @@ class Auth
$this->impersonate = null;
$this->user = $user;
// clear the status cache
$this->status = null;
}
/**
* Returns the authentication status object
*
* @param \Kirby\Session\Session|array|null $session
* @param bool $allowImpersonation If set to false, only the actually
* logged in user will be returned
* @return \Kirby\Cms\Auth\Status
*/
public function status($session = null, bool $allowImpersonation = true)
{
// try to return from cache
if ($this->status && $session === null && $allowImpersonation === true) {
return $this->status;
}
$sessionObj = $this->session($session);
$props = ['kirby' => $this->kirby];
if ($user = $this->user($sessionObj, $allowImpersonation)) {
// a user is currently logged in
if ($allowImpersonation === true && $this->impersonate !== null) {
$props['status'] = 'impersonated';
} else {
$props['status'] = 'active';
}
$props['email'] = $user->email();
} elseif ($email = $sessionObj->get('kirby.challenge.email')) {
// a challenge is currently pending
$props['status'] = 'pending';
$props['email'] = $email;
$props['challenge'] = $sessionObj->get('kirby.challenge.type');
$props['challengeFallback'] = A::last($this->enabledChallenges());
} else {
// no active authentication
$props['status'] = 'inactive';
}
$status = new Status($props);
// only cache the default object
if ($session === null && $allowImpersonation === true) {
$this->status = $status;
}
return $status;
}
/**
@@ -534,6 +626,9 @@ class Auth
$session->remove('kirby.challenge.email');
$session->remove('kirby.challenge.timeout');
$session->remove('kirby.challenge.type');
// clear the status cache
$this->status = null;
}
/**
@@ -545,6 +640,7 @@ class Auth
public function flush(): void
{
$this->impersonate = null;
$this->status = null;
$this->user = null;
}
@@ -718,6 +814,9 @@ class Auth
$this->logout();
$user->loginPasswordless();
// clear the status cache
$this->status = null;
return $user;
} else {
throw new PermissionException(['key' => 'access.code']);
@@ -744,4 +843,25 @@ class Auth
}
}
}
/**
* Creates a session object from the passed options
*
* @param \Kirby\Session\Session|array|null $session
* @return \Kirby\Session\Session
*/
protected function session($session = null)
{
// use passed session options or session object if set
if (is_array($session) === true) {
return $this->kirby->session($session);
}
// try session in header or cookie
if (is_a($session, 'Kirby\Session\Session') === false) {
return $this->kirby->session(['detect' => true]);
}
return $session;
}
}

218
kirby/src/Cms/Auth/Status.php Executable file
View File

@@ -0,0 +1,218 @@
<?php
namespace Kirby\Cms\Auth;
use Kirby\Cms\App;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Toolkit\Properties;
/**
* Information container for the
* authentication status
*
* @package Kirby Cms
* @author Lukas Bestle <lukas@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @license https://getkirby.com/license
*/
class Status
{
use Properties;
/**
* Type of the active challenge
*
* @var string|null
*/
protected $challenge = null;
/**
* Challenge type to use as a fallback
* when $challenge is `null`
*
* @var string|null
*/
protected $challengeFallback = null;
/**
* Email address of the current/pending user
*
* @var string|null
*/
protected $email = null;
/**
* Kirby instance for user lookup
*
* @var \Kirby\Cms\App
*/
protected $kirby;
/**
* Authentication status:
* `active|impersonated|pending|inactive`
*
* @var string
*/
protected $status;
/**
* Class constructor
*
* @param array $props
*/
public function __construct(array $props)
{
$this->setProperties($props);
}
/**
* Returns the authentication status
*
* @return string
*/
public function __toString(): string
{
return $this->status();
}
/**
* Returns the type of the active challenge
*
* @param bool $automaticFallback If set to `false`, no faked challenge is returned;
* WARNING: never send the resulting `null` value to the
* user to avoid leaking whether the pending user exists
* @return string|null
*/
public function challenge(bool $automaticFallback = true): ?string
{
// never return a challenge type if the status doesn't match
if ($this->status() !== 'pending') {
return null;
}
if ($automaticFallback === false) {
return $this->challenge;
} else {
return $this->challenge ?? $this->challengeFallback;
}
}
/**
* Returns the email address of the current/pending user
*
* @return string|null
*/
public function email(): ?string
{
return $this->email;
}
/**
* Returns the authentication status
*
* @return string `active|impersonated|pending|inactive`
*/
public function status(): string
{
return $this->status;
}
/**
* Returns an array with all public status data
*
* @return array
*/
public function toArray(): array
{
return [
'challenge' => $this->challenge(),
'email' => $this->email(),
'status' => $this->status()
];
}
/**
* Returns the currently logged in user
*
* @return \Kirby\Cms\User
*/
public function user()
{
// for security, only return the user if they are
// already logged in
if (in_array($this->status(), ['active', 'impersonated']) !== true) {
return null;
}
return $this->kirby->user($this->email());
}
/**
* Sets the type of the active challenge
*
* @param string|null $challenge
* @return self
*/
protected function setChallenge(?string $challenge = null)
{
$this->challenge = $challenge;
return $this;
}
/**
* Sets the challenge type to use as
* a fallback when $challenge is `null`
*
* @param string|null $challengeFallback
* @return self
*/
protected function setChallengeFallback(?string $challengeFallback = null)
{
$this->challengeFallback = $challengeFallback;
return $this;
}
/**
* Sets the email address of the current/pending user
*
* @param string|null $email
* @return self
*/
protected function setEmail(?string $email = null)
{
$this->email = $email;
return $this;
}
/**
* Sets the Kirby instance for user lookup
*
* @param \Kirby\Cms\App $kirby
* @return self
*/
protected function setKirby(App $kirby)
{
$this->kirby = $kirby;
return $this;
}
/**
* Sets the authentication status
*
* @param string $status `active|impersonated|pending|inactive`
* @return self
*/
protected function setStatus(string $status)
{
if (in_array($status, ['active', 'impersonated', 'pending', 'inactive']) !== true) {
throw new InvalidArgumentException([
'data' => ['argument' => '$props[\'status\']', 'method' => 'Status::__construct']
]);
}
$this->status = $status;
return $this;
}
}

View File

@@ -194,7 +194,7 @@ class Block extends Item
* object. This can be used further
* with all available field methods
*
* @return \Kirby\Cms\Field;
* @return \Kirby\Cms\Field
*/
public function toField()
{

View File

@@ -74,7 +74,10 @@ class BlockConverter
'type' => 'list'
];
for ($x = $listStart+1; $x <= $listStart + count($list); $x++) {
$start = $listStart + 1;
$end = $listStart + count($list);
for ($x = $start; $x <= $end; $x++) {
$blocks[$x] = false;
}

View File

@@ -56,12 +56,12 @@ class Blocks extends Items
* @param array $params
* @return \Kirby\Cms\Blocks
*/
public static function factory(array $blocks = null, array $params = [])
public static function factory(array $items = null, array $params = [])
{
$blocks = static::extractFromLayouts($blocks);
$blocks = BlockConverter::editorBlocks($blocks);
$items = static::extractFromLayouts($items);
$items = BlockConverter::editorBlocks($items);
return parent::factory($blocks, $params);
return parent::factory($items, $params);
}
/**

View File

@@ -86,7 +86,7 @@ class Collection extends BaseCollection
*/
public function add($object)
{
if (is_a($object, static::class) === true) {
if (is_a($object, self::class) === true) {
$this->data = array_merge($this->data, $object->data);
} elseif (is_object($object) === true && method_exists($object, 'id') === true) {
$this->__set($object->id(), $object);

View File

@@ -50,7 +50,6 @@ class Fieldset extends Item
$this->disabled = $params['disabled'] ?? false;
$this->icon = $params['icon'] ?? null;
$this->model = $this->parent;
$this->kirby = $this->parent->kirby();
$this->name = $this->createName($params['name'] ?? Str::ucfirst($this->type));
$this->label = $this->createLabel($params['label'] ?? null);
$this->preview = $params['preview'] ?? null;
@@ -61,8 +60,8 @@ class Fieldset extends Item
if (
$this->translate === false &&
$this->kirby->multilang() === true &&
$this->kirby->language()->isDefault() === false
$this->kirby()->multilang() === true &&
$this->kirby()->language()->isDefault() === false
) {
// disable and unset the fieldset if it's not translatable
$this->unset = true;

View File

@@ -66,9 +66,9 @@ class Fieldsets extends Items
];
}
public static function factory(array $fieldsets = null, array $options = [])
public static function factory(array $items = null, array $params = [])
{
$fieldsets = $fieldsets ?? option('blocks.fieldsets', [
$items = $items ?? option('blocks.fieldsets', [
'code' => 'blocks/code',
'gallery' => 'blocks/gallery',
'heading' => 'blocks/heading',
@@ -80,9 +80,9 @@ class Fieldsets extends Items
'video' => 'blocks/video',
]);
$result = static::createFieldsets($fieldsets);
$result = static::createFieldsets($items);
return parent::factory($result['fieldsets'], ['groups' => $result['groups']] + $options);
return parent::factory($result['fieldsets'], ['groups' => $result['groups']] + $params);
}
public function groups(): array

View File

@@ -5,6 +5,7 @@ namespace Kirby\Cms;
use Kirby\Image\Image;
use Kirby\Toolkit\A;
use Kirby\Toolkit\F;
use Throwable;
/**
* The `$file` object provides a set
@@ -504,6 +505,31 @@ class File extends ModelWithContent
return parent::panelImageSource($query);
}
/**
* Returns an array of all actions
* that can be performed in the Panel
*
* @since 3.3.0 This also checks for the lock status
* @since 3.5.1 This also checks for matching accept settings
*
* @param array $unlock An array of options that will be force-unlocked
* @return array
*/
public function panelOptions(array $unlock = []): array
{
$options = parent::panelOptions($unlock);
try {
// check if the file type is allowed at all,
// otherwise it cannot be replaced
$this->match($this->blueprint()->accept());
} catch (Throwable $e) {
$options['replace'] = false;
}
return $options;
}
/**
* Returns the full path without leading slash
*
@@ -767,6 +793,6 @@ class File extends ModelWithContent
*/
public function url(): string
{
return $this->url ?? $this->url = $this->kirby()->component('file::url')($this->kirby(), $this);
return $this->url ?? $this->url = ($this->kirby()->component('file::url'))($this->kirby(), $this);
}
}

View File

@@ -191,7 +191,7 @@ trait FileModifications
return $this;
}
$result = $this->kirby()->component('file::version')($this->kirby(), $this, $options);
$result = ($this->kirby()->component('file::version'))($this->kirby(), $this, $options);
if (is_a($result, 'Kirby\Cms\FileVersion') === false && is_a($result, 'Kirby\Cms\File') === false) {
throw new InvalidArgumentException('The file::version component must return a File or FileVersion object');

View File

@@ -36,7 +36,7 @@ class Files extends Collection
public function add($object)
{
// add a page collection
if (is_a($object, static::class) === true) {
if (is_a($object, self::class) === true) {
$this->data = array_merge($this->data, $object->data);
// add a file by id

View File

@@ -33,6 +33,11 @@ class Item
*/
protected $params;
/**
* @var \Kirby\Cms\Page|\Kirby\Cms\Site|\Kirby\Cms\File|\Kirby\Cms\User
*/
protected $parent;
/**
* @var \Kirby\Cms\Items
*/
@@ -98,7 +103,7 @@ class Item
/**
* Returns the parent model
*
* @return \Kirby\Cms\Page | \Kirby\Cms\Site | \Kirby\Cms\File | \Kirby\Cms\User
* @return \Kirby\Cms\Page|\Kirby\Cms\Site|\Kirby\Cms\File|\Kirby\Cms\User
*/
public function parent()
{
@@ -109,7 +114,8 @@ class Item
* Returns the sibling collection
* This is required by the HasSiblings trait
*
* @return \Kirby\Editor\Blocks
* @return \Kirby\Cms\Items
* @psalm-return self::ITEMS_CLASS
*/
protected function siblingsCollection()
{

View File

@@ -40,6 +40,7 @@ class LanguageRoutes
// jump through to the fallback if nothing
// can be found for this language
/** @var \Kirby\Http\Route $this */
$this->next();
}
];

View File

@@ -15,25 +15,25 @@ class Layouts extends Items
{
const ITEM_CLASS = '\Kirby\Cms\Layout';
public static function factory(array $layouts = null, array $options = [])
public static function factory(array $items = null, array $params = [])
{
$first = $layouts[0] ?? [];
$first = $items[0] ?? [];
// if there are no wrapping layouts for blocks yet …
if (array_key_exists('content', $first) === true || array_key_exists('type', $first) === true) {
$layouts = [
$items = [
[
'id' => uuid(),
'columns' => [
[
'width' => '1/1',
'blocks' => $layouts
'blocks' => $items
]
]
]
];
}
return parent::factory($layouts, $options);
return parent::factory($items, $params);
}
}

View File

@@ -837,17 +837,17 @@ trait PageActions
* Updates the page data
*
* @param array|null $input
* @param string|null $language
* @param string|null $languageCode
* @param bool $validate
* @return self
*/
public function update(array $input = null, string $language = null, bool $validate = false)
public function update(array $input = null, string $languageCode = null, bool $validate = false)
{
if ($this->isDraft() === true) {
$validate = false;
}
$page = parent::update($input, $language, $validate);
$page = parent::update($input, $languageCode, $validate);
// if num is created from page content, update num on content update
if ($page->isListed() === true && in_array($page->blueprint()->num(), ['zero', 'default']) === false) {

View File

@@ -313,14 +313,14 @@ class PageRules
$drafts = $page->parentModel()->drafts();
$slug = $page->slug();
if ($duplicate = $siblings->find($slug)) {
if ($siblings->find($slug)) {
throw new DuplicateException([
'key' => 'page.duplicate',
'data' => ['slug' => $slug]
]);
}
if ($duplicate = $drafts->find($slug)) {
if ($drafts->find($slug)) {
throw new DuplicateException([
'key' => 'page.draft.duplicate',
'data' => ['slug' => $slug]

View File

@@ -48,7 +48,7 @@ class Pages extends Collection
public function add($object)
{
// add a page collection
if (is_a($object, static::class) === true) {
if (is_a($object, self::class) === true) {
$this->data = array_merge($this->data, $object->data);
// add a page by id
@@ -398,7 +398,7 @@ class Pages extends Collection
}
// merge an entire collection
if (is_a($args[0], static::class) === true) {
if (is_a($args[0], self::class) === true) {
$collection = clone $this;
$collection->data = array_merge($collection->data, $args[0]->data);
return $collection;

View File

@@ -28,7 +28,7 @@ class Panel
* Returns custom css path for panel ui
*
* @param \Kirby\Cms\App $kirby
* @return bool|string
* @return string|false
*/
public static function customCss(App $kirby)
{

View File

@@ -2,7 +2,6 @@
namespace Kirby\Cms;
use Kirby\Session\Session;
use Kirby\Toolkit\Facade;
/**

View File

@@ -37,7 +37,7 @@ class Search
public static function collection(Collection $collection, string $query = null, $params = [])
{
$kirby = App::instance();
return $kirby->component('search')($kirby, $collection, $query, $params);
return ($kirby->component('search'))($kirby, $collection, $query, $params);
}
/**

View File

@@ -44,6 +44,10 @@ class Section extends Component
throw new InvalidArgumentException('Undefined section model');
}
if (is_a($attrs['model'], 'Kirby\Cms\Model') === false) {
throw new InvalidArgumentException('Invalid section model');
}
// use the type as fallback for the name
$attrs['name'] = $attrs['name'] ?? $type;
$attrs['type'] = $type;
@@ -65,7 +69,7 @@ class Section extends Component
*/
public function kirby()
{
return $this->model->kirby();
return $this->model()->kirby();
}
/**

View File

@@ -62,8 +62,8 @@ class Url extends BaseUrl
{
$kirby = App::instance();
return $kirby->component('url')($kirby, $path, $options, function (string $path = null, $options = null) use ($kirby) {
return $kirby->nativeComponent('url')($kirby, $path, $options);
return ($kirby->component('url'))($kirby, $path, $options, function (string $path = null, $options = null) use ($kirby) {
return ($kirby->nativeComponent('url'))($kirby, $path, $options);
});
}
}

View File

@@ -400,7 +400,7 @@ class User extends ModelWithContent
*/
public function language(): string
{
return $this->language ?? $this->language = $this->credentials()['language'] ?? $this->kirby()->option('panel.language', 'en');
return $this->language ?? $this->language = $this->credentials()['language'] ?? $this->kirby()->panelLanguage();
}
/**

View File

@@ -302,13 +302,13 @@ trait UserActions
* Updates the user data
*
* @param array|null $input
* @param string|null $language
* @param string|null $languageCode
* @param bool $validate
* @return self
*/
public function update(array $input = null, string $language = null, bool $validate = false)
public function update(array $input = null, string $languageCode = null, bool $validate = false)
{
$user = parent::update($input, $language, $validate);
$user = parent::update($input, $languageCode, $validate);
// set auth user data only if the current user is this user
if ($user->isLoggedIn() === true) {

View File

@@ -43,7 +43,7 @@ class Users extends Collection
public function add($object)
{
// add a page collection
if (is_a($object, static::class) === true) {
if (is_a($object, self::class) === true) {
$this->data = array_merge($this->data, $object->data);
// add a user by id

View File

@@ -38,7 +38,7 @@ class PHP extends Handler
return "[\n" . implode(",\n", $array) . "\n" . $indent . ']';
case 'boolean':
return $data ? 'true' : 'false';
case 'int':
case 'integer':
case 'double':
return $data;
default:

View File

@@ -3,7 +3,6 @@
namespace Kirby\Database;
use Closure;
use Exception;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Toolkit\A;
use Kirby\Toolkit\Str;

View File

@@ -73,6 +73,24 @@ class PHPMailer extends Email
$mailer->Password = $this->transport()['password'] ?? null;
$mailer->SMTPSecure = $this->transport()['security'] ?? 'ssl';
$mailer->Port = $this->transport()['port'] ?? null;
if ($mailer->SMTPSecure === true) {
switch ($mailer->Port) {
case null:
case 587:
$mailer->SMTPSecure = 'tls';
$mailer->Port = 587;
break;
case 465:
$mailer->SMTPSecure = 'ssl';
break;
default:
throw new InvalidArgumentException(
'Could not automatically detect the "security" protocol from the ' .
'"port" option, please set it explicitly to "tls" or "ssl".'
);
}
}
}
// accessible phpMailer instance

View File

@@ -84,7 +84,10 @@ class Field extends Component
*/
public function api()
{
if (isset($this->options['api']) === true && is_callable($this->options['api']) === true) {
if (
isset($this->options['api']) === true &&
is_a($this->options['api'], 'Closure') === true
) {
return $this->options['api']->call($this);
}
}
@@ -107,11 +110,13 @@ class Field extends Component
if ($save === false) {
return null;
} elseif (is_callable($save) === true) {
return $save->call($this, $value);
} else {
return $value;
}
if (is_a($save, 'Closure') === true) {
return $save->call($this, $value);
}
return $value;
}
/**
@@ -207,16 +212,19 @@ class Field extends Component
],
'computed' => [
'after' => function () {
/** @var \Kirby\Form\Field $this */
if ($this->after !== null) {
return $this->model()->toString($this->after);
}
},
'before' => function () {
/** @var \Kirby\Form\Field $this */
if ($this->before !== null) {
return $this->model()->toString($this->before);
}
},
'default' => function () {
/** @var \Kirby\Form\Field $this */
if ($this->default === null) {
return;
}
@@ -228,6 +236,7 @@ class Field extends Component
return $this->model()->toString($this->default);
},
'help' => function () {
/** @var \Kirby\Form\Field $this */
if ($this->help) {
$help = $this->model()->toString($this->help);
$help = $this->kirby()->kirbytext($help);
@@ -235,11 +244,13 @@ class Field extends Component
}
},
'label' => function () {
/** @var \Kirby\Form\Field $this */
if ($this->label !== null) {
return $this->model()->toString($this->label);
}
},
'placeholder' => function () {
/** @var \Kirby\Form\Field $this */
if ($this->placeholder !== null) {
return $this->model()->toString($this->placeholder);
}
@@ -350,13 +361,13 @@ class Field extends Component
*/
public function kirby()
{
return $this->model->kirby();
return $this->model()->kirby();
}
/**
* Returns the parent model
*
* @return mixed|null
* @return mixed
*/
public function model()
{

View File

@@ -20,8 +20,10 @@ class BlocksField extends FieldClass
use Max;
use Min;
protected $fieldsets;
protected $blocks;
protected $fieldsets;
protected $group;
protected $pretty;
protected $value = [];
public function __construct(array $params = [])

View File

@@ -2,6 +2,7 @@
namespace Kirby\Form\Field;
use Kirby\Cms\Blueprint;
use Kirby\Cms\Fieldset;
use Kirby\Cms\Form;
use Kirby\Cms\Layout;
@@ -19,7 +20,7 @@ class LayoutField extends BlocksField
{
$this->setModel($params['model'] ?? site());
$this->setLayouts($params['layouts'] ?? ['1/1']);
$this->setSettings($params['settings'] ?? []);
$this->setSettings($params['settings'] ?? null);
parent::__construct($params);
}
@@ -120,13 +121,15 @@ class LayoutField extends BlocksField
}, $layouts);
}
protected function setSettings(array $settings = [])
protected function setSettings($settings = null)
{
if (empty($settings) === true) {
$this->settings = null;
return;
}
$settings = Blueprint::extend($settings);
$settings['icon'] = 'dashboard';
$settings['type'] = 'layout';
$settings['parent'] = $this->model();

View File

@@ -353,6 +353,7 @@ abstract class FieldClass
'saveable' => $this->isSaveable(),
'translate' => $this->translate(),
'type' => $this->type(),
'when' => $this->when(),
'width' => $this->width(),
];
}
@@ -614,6 +615,16 @@ abstract class FieldClass
return Data::encode($value, 'yaml');
}
/**
* Conditions when the field will be shown
*
* @return array|null
*/
public function when(): ?array
{
return $this->when;
}
/**
* Returns the width of the field in
* the Panel grid

View File

@@ -29,6 +29,7 @@ class Options
return [
'Kirby\Cms\File' => 'file',
'Kirby\Toolkit\Obj' => 'arrayItem',
'Kirby\Cms\Block' => 'block',
'Kirby\Cms\Page' => 'page',
'Kirby\Cms\StructureObject' => 'structureItem',
'Kirby\Cms\User' => 'user',
@@ -169,6 +170,7 @@ class Options
// default text setup
$text = [
'arrayItem' => '{{ arrayItem.value }}',
'block' => '{{ block.type }}: {{ block.id }}',
'file' => '{{ file.filename }}',
'page' => '{{ page.title }}',
'structureItem' => '{{ structureItem.title }}',
@@ -178,6 +180,7 @@ class Options
// default value setup
$value = [
'arrayItem' => '{{ arrayItem.value }}',
'block' => '{{ block.id }}',
'file' => '{{ file.id }}',
'page' => '{{ page.id }}',
'structureItem' => '{{ structureItem.id }}',

View File

@@ -98,7 +98,8 @@ class Cookie
*/
public static function forever(string $key, string $value, array $options = []): bool
{
$options['lifetime'] = 253402214400; // 9999-12-31
// 9999-12-31 if supported (lower on 32-bit servers)
$options['lifetime'] = min(253402214400, PHP_INT_MAX);
return static::set($key, $value, $options);
}

View File

@@ -119,6 +119,12 @@ class Params extends Query
* @param bool $leadingSlash
* @param bool $trailingSlash
* @return string|null
*
* @todo The argument $leadingSlash is incompatible with
* Query::toString($questionMark = false); the Query class
* should be extracted into a common parent class for both
* Query and Params
* @psalm-suppress ParamNameMismatch
*/
public function toString($leadingSlash = false, $trailingSlash = false): string
{

View File

@@ -129,7 +129,7 @@ class Uri
/**
* Creates a new URI object
*
* @param array $props
* @param array|string $props
* @param array $inject
*/
public function __construct($props = [], array $inject = [])

View File

@@ -161,7 +161,7 @@ class Url
* @param string|array|null $url
* @param bool $leadingSlash
* @param bool $trailingSlash
* @return xtring
* @return string
*/
public static function path($url = null, bool $leadingSlash = false, bool $trailingSlash = false): string
{

View File

@@ -3,7 +3,7 @@
namespace Kirby\Parsley;
use DOMElement;
use DOMXpath;
use DOMXPath;
use Kirby\Toolkit\Str;
class Element

View File

@@ -35,8 +35,6 @@ class Inline
public function parseNode($node)
{
$html = '';
if (is_a($node, 'DOMText') === true) {
return $node->textContent;
}

View File

@@ -11,6 +11,7 @@ class Parsley
protected $blocks = [];
protected $body;
protected $doc;
protected $inline;
protected $marks = [];
protected $nodes = [];
protected $schema;

View File

@@ -115,7 +115,6 @@ class FileSessionStore extends SessionStore
public function lock(int $expiryTime, string $id)
{
$name = $this->name($expiryTime, $id);
$path = $this->path($name);
// check if the file is already locked
if (isset($this->isLocked[$name])) {
@@ -153,7 +152,6 @@ class FileSessionStore extends SessionStore
public function unlock(int $expiryTime, string $id)
{
$name = $this->name($expiryTime, $id);
$path = $this->path($name);
// check if the file is already unlocked or doesn't exist
if (!isset($this->isLocked[$name])) {
@@ -258,7 +256,6 @@ class FileSessionStore extends SessionStore
public function set(int $expiryTime, string $id, string $data)
{
$name = $this->name($expiryTime, $id);
$path = $this->path($name);
$handle = $this->handle($name);
// validate that we have an exclusive lock already

View File

@@ -335,6 +335,10 @@ class Session
public function commit()
{
// nothing to do if nothing changed or the session has been just created or destroyed
/**
* @todo The $this->destroyed check gets flagged by Psalm for unknown reasons
* @psalm-suppress ParadoxicalCondition
*/
if ($this->writeMode !== true || $this->tokenExpiry === null || $this->destroyed === true) {
return;
}
@@ -515,12 +519,20 @@ class Session
// using $session->ensureToken() -> lazy session creation
// - destroyed sessions are never written to
// - no need to lock and re-init if we are already in write mode
/**
* @todo The $this->destroyed check gets flagged by Psalm for unknown reasons
* @psalm-suppress ParadoxicalCondition
*/
if ($this->tokenExpiry === null || $this->destroyed === true || $this->writeMode === true) {
return;
}
// don't allow writing for read-only sessions
// (only the case for moved sessions)
/**
* @todo This check gets flagged by Psalm for unknown reasons
* @psalm-suppress ParadoxicalCondition
*/
if ($this->tokenKey === null) {
throw new LogicException([
'key' => 'session.readonly',

View File

@@ -242,7 +242,7 @@ class Collection extends Iterator implements Countable
* custom filter function or an array of filters
*
* @param string|array|\Closure $field
* @param array ...$args
* @param mixed ...$args
* @return \Kirby\Toolkit\Collection
*/
public function filter($field, ...$args)

View File

@@ -178,7 +178,7 @@ class Component
protected function applyProps(array $props): void
{
foreach ($props as $propName => $propFunction) {
if (is_callable($propFunction) === true) {
if (is_a($propFunction, 'Closure') === true) {
if (isset($this->attrs[$propName]) === true) {
try {
$this->$propName = $this->props[$propName] = $propFunction->call($this, $this->attrs[$propName]);
@@ -208,7 +208,7 @@ class Component
protected function applyComputed(array $computed): void
{
foreach ($computed as $computedName => $computedFunction) {
if (is_callable($computedFunction) === true) {
if (is_a($computedFunction, 'Closure') === true) {
$this->$computedName = $this->computed[$computedName] = $computedFunction->call($this);
}
}

View File

@@ -588,7 +588,7 @@ class F
return $newRoot;
}
if (F::move($file, $newRoot) !== true) {
if (F::move($file, $newRoot, $overwrite) !== true) {
return false;
}

View File

@@ -175,6 +175,8 @@ class Html extends Xml
* @param string|null $string
* @param bool $keepTags If true, existing tags won't be escaped
* @return string The HTML string
*
* @psalm-suppress ParamNameMismatch
*/
public static function encode(?string $string, bool $keepTags = false): string
{

View File

@@ -38,35 +38,51 @@ class I18n
public static $translations = [];
/**
* The fallback locale
* The fallback locale or a
* list of fallback locales
*
* @var string
* @var string|array
*/
public static $fallback = 'en';
public static $fallback = ['en'];
/**
* Cache of `NumberFormatter` objects by locale
*
* @var array
*/
protected static $decimalNumberFormatters = [];
protected static $decimalsFormatters = [];
/**
* Returns the fallback code
* Returns the first fallback locale
*
* @deprecated 3.5.1 Use \Kirby\Toolkit\I18n::fallbacks() instead
*
* @return string
*/
public static function fallback(): string
{
if (is_string(static::$fallback) === true) {
return static::$fallback;
return static::fallbacks()[0];
}
/**
* Returns the list of fallback locales
*
* @return array
*/
public static function fallbacks(): array
{
if (
is_array(static::$fallback) === true ||
is_string(static::$fallback) === true
) {
return A::wrap(static::$fallback);
}
if (is_callable(static::$fallback) === true) {
return static::$fallback = (static::$fallback)();
return static::$fallback = A::wrap((static::$fallback)());
}
return static::$fallback = 'en';
return static::$fallback = ['en'];
}
/**
@@ -154,8 +170,15 @@ class I18n
return $fallback;
}
if ($locale !== static::fallback()) {
return static::translation(static::fallback())[$key] ?? null;
foreach (static::fallbacks() as $fallback) {
// skip locales we have already tried
if ($locale === $fallback) {
continue;
}
if ($translation = static::translation($fallback)[$key] ?? null) {
return $translation;
}
}
return null;
@@ -166,12 +189,12 @@ class I18n
* placeholders in the text
*
* @param string $key
* @param string $fallback
* @param array $replace
* @param string $locale
* @param string|array|null $fallback
* @param array|null $replace
* @param string|null $locale
* @return string
*/
public static function template(string $key, $fallback = null, array $replace = null, string $locale = null)
public static function template(string $key, $fallback = null, ?array $replace = null, ?string $locale = null): string
{
if (is_array($fallback) === true) {
$replace = $fallback;
@@ -223,15 +246,15 @@ class I18n
*/
protected static function decimalNumberFormatter(string $locale): ?NumberFormatter
{
if (isset(static::$decimalNumberFormatters[$locale])) {
return static::$decimalNumberFormatters[$locale];
if (isset(static::$decimalsFormatters[$locale])) {
return static::$decimalsFormatters[$locale];
}
if (extension_loaded('intl') !== true || class_exists('NumberFormatter') !== true) {
return null;
return null; // @codeCoverageIgnore
}
return static::$decimalNumberFormatters[$locale] = new NumberFormatter($locale, NumberFormatter::DECIMAL);
return static::$decimalsFormatters[$locale] = new NumberFormatter($locale, NumberFormatter::DECIMAL);
}
/**

View File

@@ -76,7 +76,7 @@ class Query
* @param string $query
* @return mixed
*
* @throws Kirby\Exception\BadMethodCallException If an invalid method is accessed by the query
* @throws \Kirby\Exception\BadMethodCallException If an invalid method is accessed by the query
*/
protected function resolve(string $query)
{
@@ -227,7 +227,7 @@ class Query
* @param string $label Type of the name (`method`, `property` or `method/property`)
* @return void
*
* @throws Kirby\Exception\BadMethodCallException
* @throws \Kirby\Exception\BadMethodCallException
*/
protected static function accessError($data, string $name, string $label): void
{

View File

@@ -0,0 +1,7 @@
Copyright 2017 A Beautiful Site, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,22 @@
{
"name": "claviska/simpleimage",
"description": "A PHP class that makes working with images as simple as possible.",
"license": "MIT",
"require": {
"php": ">=5.6.0",
"ext-gd": "*",
"league/color-extractor": "0.3.*"
},
"authors": [
{
"name": "Cory LaViska",
"homepage": "http://www.abeautifulsite.net/",
"role": "Developer"
}
],
"autoload": {
"psr-0": {
"claviska": "src/"
}
}
}

View File

@@ -14,8 +14,8 @@ class InstalledVersions
private static $installed = array (
'root' =>
array (
'pretty_version' => '3.5.0',
'version' => '3.5.0.0',
'pretty_version' => '3.5.1',
'version' => '3.5.1.0',
'aliases' =>
array (
),
@@ -44,8 +44,8 @@ private static $installed = array (
),
'getkirby/cms' =>
array (
'pretty_version' => '3.5.0',
'version' => '3.5.0.0',
'pretty_version' => '3.5.1',
'version' => '3.5.1.0',
'aliases' =>
array (
),
@@ -53,12 +53,12 @@ private static $installed = array (
),
'getkirby/composer-installer' =>
array (
'pretty_version' => '1.2.0',
'version' => '1.2.0.0',
'pretty_version' => '1.2.1',
'version' => '1.2.1.0',
'aliases' =>
array (
),
'reference' => '240a8b2c275d61b66601feb58222b7d34bc6cf1e',
'reference' => 'c98ece30bfba45be7ce457e1102d1b169d922f3d',
),
'laminas/laminas-escaper' =>
array (
@@ -132,12 +132,12 @@ private static $installed = array (
),
'symfony/polyfill-mbstring' =>
array (
'pretty_version' => 'v1.20.0',
'version' => '1.20.0.0',
'pretty_version' => 'v1.22.0',
'version' => '1.22.0.0',
'aliases' =>
array (
),
'reference' => '39d483bdf39be819deabf04ec872eb0b2410b531',
'reference' => 'f377a3dd1fde44d37b9831d68dc8dea3ffd28e13',
),
'true/punycode' =>
array (

21
kirby/vendor/composer/LICENSE vendored Executable file
View File

@@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -28,6 +28,7 @@ return array(
'Kirby\\Cms\\Auth' => $baseDir . '/src/Cms/Auth.php',
'Kirby\\Cms\\Auth\\Challenge' => $baseDir . '/src/Cms/Auth/Challenge.php',
'Kirby\\Cms\\Auth\\EmailChallenge' => $baseDir . '/src/Cms/Auth/EmailChallenge.php',
'Kirby\\Cms\\Auth\\Status' => $baseDir . '/src/Cms/Auth/Status.php',
'Kirby\\Cms\\Block' => $baseDir . '/src/Cms/Block.php',
'Kirby\\Cms\\BlockConverter' => $baseDir . '/src/Cms/BlockConverter.php',
'Kirby\\Cms\\Blocks' => $baseDir . '/src/Cms/Blocks.php',
@@ -125,10 +126,6 @@ return array(
'Kirby\\Cms\\UserRules' => $baseDir . '/src/Cms/UserRules.php',
'Kirby\\Cms\\Users' => $baseDir . '/src/Cms/Users.php',
'Kirby\\Cms\\Visitor' => $baseDir . '/src/Cms/Visitor.php',
'Kirby\\ComposerInstaller\\CmsInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php',
'Kirby\\ComposerInstaller\\Installer' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php',
'Kirby\\ComposerInstaller\\Plugin' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php',
'Kirby\\ComposerInstaller\\PluginInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php',
'Kirby\\Data\\Data' => $baseDir . '/src/Data/Data.php',
'Kirby\\Data\\Handler' => $baseDir . '/src/Data/Handler.php',
'Kirby\\Data\\Json' => $baseDir . '/src/Data/Json.php',

View File

@@ -10,4 +10,5 @@ return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'04c6c5c2f7095ccf6c481d3e53e1776f' => $vendorDir . '/mustangostang/spyc/Spyc.php',
'f864ae44e8154e5ff6f4eec32f46d37f' => $baseDir . '/config/setup.php',
'87988fc7b1c1f093da22a1a3de972f3a' => $baseDir . '/config/helpers.php',
);

View File

@@ -11,6 +11,7 @@ class ComposerStaticInitc26333d865e0329b638bdc17afd29896
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'04c6c5c2f7095ccf6c481d3e53e1776f' => __DIR__ . '/..' . '/mustangostang/spyc/Spyc.php',
'f864ae44e8154e5ff6f4eec32f46d37f' => __DIR__ . '/../..' . '/config/setup.php',
'87988fc7b1c1f093da22a1a3de972f3a' => __DIR__ . '/../..' . '/config/helpers.php',
);
public static $prefixLengthsPsr4 = array (
@@ -122,6 +123,7 @@ class ComposerStaticInitc26333d865e0329b638bdc17afd29896
'Kirby\\Cms\\Auth' => __DIR__ . '/../..' . '/src/Cms/Auth.php',
'Kirby\\Cms\\Auth\\Challenge' => __DIR__ . '/../..' . '/src/Cms/Auth/Challenge.php',
'Kirby\\Cms\\Auth\\EmailChallenge' => __DIR__ . '/../..' . '/src/Cms/Auth/EmailChallenge.php',
'Kirby\\Cms\\Auth\\Status' => __DIR__ . '/../..' . '/src/Cms/Auth/Status.php',
'Kirby\\Cms\\Block' => __DIR__ . '/../..' . '/src/Cms/Block.php',
'Kirby\\Cms\\BlockConverter' => __DIR__ . '/../..' . '/src/Cms/BlockConverter.php',
'Kirby\\Cms\\Blocks' => __DIR__ . '/../..' . '/src/Cms/Blocks.php',
@@ -219,10 +221,6 @@ class ComposerStaticInitc26333d865e0329b638bdc17afd29896
'Kirby\\Cms\\UserRules' => __DIR__ . '/../..' . '/src/Cms/UserRules.php',
'Kirby\\Cms\\Users' => __DIR__ . '/../..' . '/src/Cms/Users.php',
'Kirby\\Cms\\Visitor' => __DIR__ . '/../..' . '/src/Cms/Visitor.php',
'Kirby\\ComposerInstaller\\CmsInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php',
'Kirby\\ComposerInstaller\\Installer' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php',
'Kirby\\ComposerInstaller\\Plugin' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php',
'Kirby\\ComposerInstaller\\PluginInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php',
'Kirby\\Data\\Data' => __DIR__ . '/../..' . '/src/Data/Data.php',
'Kirby\\Data\\Handler' => __DIR__ . '/../..' . '/src/Data/Handler.php',
'Kirby\\Data\\Json' => __DIR__ . '/../..' . '/src/Data/Json.php',

744
kirby/vendor/composer/installed.json vendored Executable file
View File

@@ -0,0 +1,744 @@
{
"packages": [
{
"name": "claviska/simpleimage",
"version": "3.5.1",
"version_normalized": "3.5.1.0",
"source": {
"type": "git",
"url": "https://github.com/claviska/SimpleImage.git",
"reference": "ab2ab8a4672738ab77b39b00922ee4e79aeadb11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/ab2ab8a4672738ab77b39b00922ee4e79aeadb11",
"reference": "ab2ab8a4672738ab77b39b00922ee4e79aeadb11",
"shasum": ""
},
"require": {
"ext-gd": "*",
"league/color-extractor": "0.3.*",
"php": ">=5.6.0"
},
"time": "2020-10-30T20:47:26+00:00",
"type": "library",
"installation-source": "dist",
"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.5.1"
},
"funding": [
{
"url": "https://github.com/claviska",
"type": "github"
}
],
"install-path": "../claviska/simpleimage"
},
{
"name": "filp/whoops",
"version": "2.9.1",
"version_normalized": "2.9.1.0",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "307fb34a5ab697461ec4c9db865b20ff2fd40771"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/307fb34a5ab697461ec4c9db865b20ff2fd40771",
"reference": "307fb34a5ab697461ec4c9db865b20ff2fd40771",
"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"
},
"time": "2020-11-01T12:00:00+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
}
},
"installation-source": "dist",
"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.9.1"
},
"install-path": "../filp/whoops"
},
{
"name": "getkirby/composer-installer",
"version": "1.2.1",
"version_normalized": "1.2.1.0",
"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"
},
"time": "2020-12-28T12:54:39+00:00",
"type": "composer-plugin",
"extra": {
"class": "Kirby\\ComposerInstaller\\Plugin"
},
"installation-source": "dist",
"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"
}
],
"install-path": "../getkirby/composer-installer"
},
{
"name": "laminas/laminas-escaper",
"version": "2.7.0",
"version_normalized": "2.7.0.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": "*"
},
"time": "2020-11-17T21:26:43+00:00",
"type": "library",
"installation-source": "dist",
"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"
}
],
"install-path": "../laminas/laminas-escaper"
},
{
"name": "laminas/laminas-zendframework-bridge",
"version": "1.1.1",
"version_normalized": "1.1.1.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-zendframework-bridge.git",
"reference": "6ede70583e101030bcace4dcddd648f760ddf642"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642",
"reference": "6ede70583e101030bcace4dcddd648f760ddf642",
"shasum": ""
},
"require": {
"php": "^5.6 || ^7.0 || ^8.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3",
"squizlabs/php_codesniffer": "^3.5"
},
"time": "2020-09-14T14:23:00+00:00",
"type": "library",
"extra": {
"laminas": {
"module": "Laminas\\ZendFrameworkBridge"
}
},
"installation-source": "dist",
"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"
}
],
"install-path": "../laminas/laminas-zendframework-bridge"
},
{
"name": "league/color-extractor",
"version": "0.3.2",
"version_normalized": "0.3.2.0",
"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"
},
"time": "2016-12-15T09:30:02+00:00",
"type": "library",
"installation-source": "dist",
"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"
},
"install-path": "../league/color-extractor"
},
{
"name": "michelf/php-smartypants",
"version": "1.8.1",
"version_normalized": "1.8.1.0",
"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"
},
"time": "2016-12-13T01:01:17+00:00",
"type": "library",
"installation-source": "dist",
"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"
},
"install-path": "../michelf/php-smartypants"
},
{
"name": "mustangostang/spyc",
"version": "0.6.3",
"version_normalized": "0.6.3.0",
"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"
},
"time": "2019-09-10T13:16:29+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.5.x-dev"
}
},
"installation-source": "dist",
"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"
],
"install-path": "../mustangostang/spyc"
},
{
"name": "phpmailer/phpmailer",
"version": "v6.2.0",
"version_normalized": "6.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "e38888a75c070304ca5514197d4847a59a5c853f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e38888a75c070304ca5514197d4847a59a5c853f",
"reference": "e38888a75c070304ca5514197d4847a59a5c853f",
"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",
"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)"
},
"time": "2020-11-25T15:24:57+00:00",
"type": "library",
"installation-source": "dist",
"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.2.0"
},
"funding": [
{
"url": "https://github.com/Synchro",
"type": "github"
}
],
"install-path": "../phpmailer/phpmailer"
},
{
"name": "psr/log",
"version": "1.1.3",
"version_normalized": "1.1.3.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2020-03-23T09:12:05+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://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.3"
},
"install-path": "../psr/log"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.22.0",
"version_normalized": "1.22.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2021-01-07T16:49:33+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"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.22.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"
}
],
"install-path": "../symfony/polyfill-mbstring"
},
{
"name": "true/punycode",
"version": "v2.1.1",
"version_normalized": "2.1.1.0",
"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"
},
"time": "2016-11-16T10:37:54+00:00",
"type": "library",
"installation-source": "dist",
"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"
},
"install-path": "../true/punycode"
}
],
"dev": true,
"dev-package-names": []
}

View File

@@ -1,8 +1,8 @@
<?php return array (
'root' =>
array (
'pretty_version' => '3.5.0',
'version' => '3.5.0.0',
'pretty_version' => '3.5.1',
'version' => '3.5.1.0',
'aliases' =>
array (
),
@@ -31,8 +31,8 @@
),
'getkirby/cms' =>
array (
'pretty_version' => '3.5.0',
'version' => '3.5.0.0',
'pretty_version' => '3.5.1',
'version' => '3.5.1.0',
'aliases' =>
array (
),
@@ -40,12 +40,12 @@
),
'getkirby/composer-installer' =>
array (
'pretty_version' => '1.2.0',
'version' => '1.2.0.0',
'pretty_version' => '1.2.1',
'version' => '1.2.1.0',
'aliases' =>
array (
),
'reference' => '240a8b2c275d61b66601feb58222b7d34bc6cf1e',
'reference' => 'c98ece30bfba45be7ce457e1102d1b169d922f3d',
),
'laminas/laminas-escaper' =>
array (
@@ -119,12 +119,12 @@
),
'symfony/polyfill-mbstring' =>
array (
'pretty_version' => 'v1.20.0',
'version' => '1.20.0.0',
'pretty_version' => 'v1.22.0',
'version' => '1.22.0.0',
'aliases' =>
array (
),
'reference' => '39d483bdf39be819deabf04ec872eb0b2410b531',
'reference' => 'f377a3dd1fde44d37b9831d68dc8dea3ffd28e13',
),
'true/punycode' =>
array (

19
kirby/vendor/filp/whoops/LICENSE.md vendored Executable file
View File

@@ -0,0 +1,19 @@
# The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

42
kirby/vendor/filp/whoops/composer.json vendored Executable file
View File

@@ -0,0 +1,42 @@
{
"name": "filp/whoops",
"license": "MIT",
"description": "php error handling for cool kids",
"keywords": ["library", "error", "handling", "exception", "whoops", "throwable"],
"homepage": "https://filp.github.io/whoops/",
"authors": [
{
"name": "Filipe Dobreira",
"homepage": "https://github.com/filp",
"role": "Developer"
}
],
"require": {
"php": "^5.5.9 || ^7.0 || ^8.0",
"psr/log": "^1.0.1"
},
"require-dev": {
"phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3",
"mockery/mockery": "^0.9 || ^1.0",
"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"
},
"autoload": {
"psr-4": {
"Whoops\\": "src/Whoops/"
}
},
"autoload-dev": {
"psr-4": {
"Whoops\\": "tests/Whoops/"
}
},
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,64 +0,0 @@
<?php
namespace Kirby\ComposerInstaller;
use Composer\Config;
use Composer\Package\PackageInterface;
use InvalidArgumentException;
/**
* @package Kirby Composer Installer
* @author Lukas Bestle <lukas@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @license https://opensource.org/licenses/MIT
*/
class CmsInstaller extends Installer
{
/**
* Decides if the installer supports the given type
*
* @param string $packageType
* @return bool
*/
public function supports($packageType): bool
{
return $packageType === 'kirby-cms';
}
/**
* Returns the installation path of a package
*
* @param PackageInterface $package
* @return string path
*/
public function getInstallPath(PackageInterface $package): string
{
// get the extra configuration of the top-level package
if ($rootPackage = $this->composer->getPackage()) {
$extra = $rootPackage->getExtra();
} else {
$extra = [];
}
// use path from configuration, otherwise fall back to default
if (isset($extra['kirby-cms-path'])) {
$path = $extra['kirby-cms-path'];
} else {
$path = 'kirby';
}
// if explicitly set to something invalid (e.g. `false`), install to vendor dir
if (!is_string($path)) {
return parent::getInstallPath($package);
}
// don't allow unsafe directories
$vendorDir = $this->composer->getConfig()->get('vendor-dir', Config::RELATIVE_PATHS) ?? 'vendor';
if ($path === $vendorDir || $path === '.') {
throw new InvalidArgumentException('The path ' . $path . ' is an unsafe installation directory for ' . $package->getPrettyName() . '.');
}
return $path;
}
}

View File

@@ -1,101 +0,0 @@
<?php
namespace Kirby\ComposerInstaller;
use Composer\Installer\LibraryInstaller;
use Composer\Package\PackageInterface;
use Composer\Repository\InstalledRepositoryInterface;
use React\Promise\PromiseInterface;
use RuntimeException;
/**
* @package Kirby Composer Installer
* @author Lukas Bestle <lukas@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @license https://opensource.org/licenses/MIT
*/
class Installer extends LibraryInstaller
{
/**
* Decides if the installer supports the given type
*
* @param string $packageType
* @return bool
*/
public function supports($packageType): bool
{
throw new RuntimeException('This method needs to be overridden.'); // @codeCoverageIgnore
}
/**
* Installs specific package.
*
* @param InstalledRepositoryInterface $repo repository in which to check
* @param PackageInterface $package package instance
*/
public function install(InstalledRepositoryInterface $repo, PackageInterface $package)
{
// first install the package normally...
$promise = parent::install($repo, $package);
// ...then run custom code
$postInstall = function () use ($package) {
$this->postInstall($package);
};
// Composer 2 in async mode
if ($promise instanceof PromiseInterface) {
return $promise->then($postInstall);
}
// Composer 1 or Composer 2 without async
$postInstall();
}
/**
* Updates specific package.
*
* @param InstalledRepositoryInterface $repo repository in which to check
* @param PackageInterface $initial already installed package version
* @param PackageInterface $target updated version
*
* @throws InvalidArgumentException if $initial package is not installed
*/
public function update(InstalledRepositoryInterface $repo, PackageInterface $initial, PackageInterface $target)
{
// first update the package normally...
$promise = parent::update($repo, $initial, $target);
// ...then run custom code
$postInstall = function () use ($target) {
$this->postInstall($target);
};
// Composer 2 in async mode
if ($promise instanceof PromiseInterface) {
return $promise->then($postInstall);
}
// Composer 1 or Composer 2 without async
$postInstall();
}
/**
* Custom handler that will be called after each package
* installation or update
*
* @param PackageInterface $package
*/
protected function postInstall(PackageInterface $package)
{
// remove the package's `vendor` directory to avoid duplicated autoloader and vendor code
$packageVendorDir = $this->getInstallPath($package) . '/vendor';
if (is_dir($packageVendorDir)) {
$success = $this->filesystem->removeDirectory($packageVendorDir);
if (!$success) {
throw new RuntimeException('Could not completely delete ' . $path . ', aborting.'); // @codeCoverageIgnore
}
}
}
}

View File

@@ -1,54 +0,0 @@
<?php
namespace Kirby\ComposerInstaller;
use Composer\Composer;
use Composer\IO\IOInterface;
use Composer\Plugin\PluginInterface;
/**
* @package Kirby Composer Installer
* @author Lukas Bestle <lukas@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @license https://opensource.org/licenses/MIT
*/
class Plugin implements PluginInterface
{
/**
* Apply plugin modifications to Composer
*
* @param Composer $composer
* @param IOInterface $io
*/
public function activate(Composer $composer, IOInterface $io)
{
$installationManager = $composer->getInstallationManager();
$installationManager->addInstaller(new CmsInstaller($io, $composer));
$installationManager->addInstaller(new PluginInstaller($io, $composer));
}
/**
* Remove any hooks from Composer
* @codeCoverageIgnore
*
* @param Composer $composer
* @param IOInterface $io
*/
public function deactivate(Composer $composer, IOInterface $io)
{
// nothing to do
}
/**
* Prepare the plugin to be uninstalled
* @codeCoverageIgnore
*
* @param Composer $composer
* @param IOInterface $io
*/
public function uninstall(Composer $composer, IOInterface $io)
{
// nothing to do
}
}

View File

@@ -1,102 +0,0 @@
<?php
namespace Kirby\ComposerInstaller;
use Composer\Package\PackageInterface;
/**
* @package Kirby Composer Installer
* @author Lukas Bestle <lukas@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier GmbH
* @license https://opensource.org/licenses/MIT
*/
class PluginInstaller extends Installer
{
/**
* Decides if the installer supports the given type
*
* @param string $packageType
* @return bool
*/
public function supports($packageType): bool
{
return $packageType === 'kirby-plugin';
}
/**
* Returns the installation path of a package
*
* @param PackageInterface $package
* @return string path
*/
public function getInstallPath(PackageInterface $package): string
{
// place into `vendor` directory as usual if Pluginkit is not supported
if ($this->supportsPluginkit($package) !== true) {
return parent::getInstallPath($package);
}
// get the extra configuration of the top-level package
if ($rootPackage = $this->composer->getPackage()) {
$extra = $rootPackage->getExtra();
} else {
$extra = [];
}
// use base path from configuration, otherwise fall back to default
$basePath = $extra['kirby-plugin-path'] ?? 'site/plugins';
// determine the plugin name from its package name;
// can be overridden in the plugin's `composer.json`
$prettyName = $package->getPrettyName();
$pluginExtra = $package->getExtra();
if (!empty($pluginExtra['installer-name'])) {
$name = $pluginExtra['installer-name'];
} elseif (strpos($prettyName, '/') !== false) {
// use name after the slash
$name = explode('/', $prettyName)[1];
} else {
$name = $prettyName;
}
// build destination path from base path and plugin name
return $basePath . '/' . $name;
}
/**
* Custom handler that will be called after each package
* installation or update
*
* @param PackageInterface $package
*/
protected function postInstall(PackageInterface $package)
{
// only continue if Pluginkit is supported
if ($this->supportsPluginkit($package) !== true) {
return;
}
parent::postInstall($package);
}
/**
* Checks if the package has explicitly required this installer;
* otherwise (if the Pluginkit is not yet supported by the plugin)
* the installer will fall back to the behavior of the LibraryInstaller
*
* @param PackageInterface $package
* @return bool
*/
protected function supportsPluginkit(PackageInterface $package): bool
{
foreach ($package->getRequires() as $link) {
if ($link->getTarget() === 'getkirby/composer-installer') {
return true;
}
}
// no required package is the installer
return false;
}
}

View File

@@ -0,0 +1 @@
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/)

View File

@@ -0,0 +1,26 @@
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of Laminas Foundation nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,61 @@
{
"name": "laminas/laminas-escaper",
"description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs",
"license": "BSD-3-Clause",
"keywords": [
"laminas",
"escaper"
],
"homepage": "https://laminas.dev",
"support": {
"docs": "https://docs.laminas.dev/laminas-escaper/",
"issues": "https://github.com/laminas/laminas-escaper/issues",
"source": "https://github.com/laminas/laminas-escaper",
"rss": "https://github.com/laminas/laminas-escaper/releases.atom",
"chat": "https://laminas.dev/chat",
"forum": "https://discourse.laminas.dev"
},
"config": {
"sort-packages": true
},
"extra": {
},
"require": {
"php": "^7.3 || ~8.0.0",
"laminas/laminas-zendframework-bridge": "^1.0"
},
"suggest": {
"ext-iconv": "*",
"ext-mbstring": "*"
},
"require-dev": {
"laminas/laminas-coding-standard": "~1.0.0",
"phpunit/phpunit": "^9.3",
"psalm/plugin-phpunit": "^0.12.2",
"vimeo/psalm": "^3.16"
},
"autoload": {
"psr-4": {
"Laminas\\Escaper\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"LaminasTest\\Escaper\\": "test/"
}
},
"scripts": {
"check": [
"@cs-check",
"@test"
],
"cs-check": "phpcs",
"cs-fix": "phpcbf",
"static-analysis": "psalm --shepherd --stats",
"test": "phpunit --colors=always",
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml"
},
"replace": {
"zendframework/zend-escaper": "^2.6.1"
}
}

View File

@@ -0,0 +1 @@
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/)

View File

@@ -0,0 +1,26 @@
Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither the name of Laminas Foundation nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Some files were not shown because too many files have changed in this diff Show More