Upgrade to 3.1.0
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "getkirby/cms",
|
||||
"description": "The Kirby 3 core",
|
||||
"version": "3.0.3",
|
||||
"version": "3.1.0",
|
||||
"license": "proprietary",
|
||||
"keywords": ["kirby", "cms", "core"],
|
||||
"homepage": "https://getkirby.com",
|
||||
|
@@ -17,6 +17,9 @@ return [
|
||||
'dimensions' => function (File $file) {
|
||||
return $file->dimensions()->toArray();
|
||||
},
|
||||
'dragText' => function (File $file) {
|
||||
return $file->dragText();
|
||||
},
|
||||
'exists' => function (File $file) {
|
||||
return $file->exists();
|
||||
},
|
||||
@@ -53,6 +56,15 @@ return [
|
||||
'options' => function (File $file) {
|
||||
return $file->permissions()->toArray();
|
||||
},
|
||||
'panelIcon' => function (File $file) {
|
||||
return $file->panelIcon();
|
||||
},
|
||||
'panelImage' => function (File $file) {
|
||||
return $file->panelImage();
|
||||
},
|
||||
'panelUrl' => function (File $file) {
|
||||
return $file->panelUrl(true);
|
||||
},
|
||||
'prev' => function (File $file) {
|
||||
return $file->prev();
|
||||
},
|
||||
|
@@ -7,6 +7,24 @@ use Kirby\Exception\InvalidArgumentException;
|
||||
*/
|
||||
return [
|
||||
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path, string $filename, string $sectionName) {
|
||||
if ($section = $this->file($path, $filename)->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $parent, string $filename, string $fieldName, string $path = null) {
|
||||
if ($file = $this->file($parent, $filename)) {
|
||||
return $this->fieldApi($file, $fieldName, $path);
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files',
|
||||
'method' => 'GET',
|
||||
@@ -29,9 +47,15 @@ return [
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/search',
|
||||
'method' => 'POST',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function (string $path) {
|
||||
return $this->parent($path)->files()->query($this->requestBody());
|
||||
$files = $this->parent($path)->files();
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $files->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $files->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -78,23 +102,5 @@ return [
|
||||
return $this->file($path, $filename)->changeName($this->requestBody('name'));
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)/sections/(:any)',
|
||||
'method' => 'GET',
|
||||
'action' => function (string $path, string $filename, string $sectionName) {
|
||||
if ($section = $this->file($path, $filename)->blueprint()->section($sectionName)) {
|
||||
return $section->toResponse();
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => '(:all)/files/(:any)/fields/(:any)/(:all?)',
|
||||
'method' => 'ALL',
|
||||
'action' => function (string $parent, string $filename, string $fieldName, string $path = null) {
|
||||
if ($file = $this->file($parent, $filename)) {
|
||||
return $this->fieldApi($file, $fieldName, $path);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
];
|
||||
|
@@ -51,9 +51,15 @@ return [
|
||||
],
|
||||
[
|
||||
'pattern' => 'pages/(:any)/children/search',
|
||||
'method' => 'POST',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function (string $id) {
|
||||
return $this->page($id)->children()->query($this->requestBody());
|
||||
$pages = $this->page($id)->children();
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $pages->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $pages->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
|
@@ -62,17 +62,18 @@ return [
|
||||
],
|
||||
[
|
||||
'pattern' => 'site/search',
|
||||
'method' => 'GET',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function () {
|
||||
return $this->site()
|
||||
->index(true)
|
||||
->filterBy('isReadable', true)
|
||||
->search($this->requestQuery('q'), [
|
||||
'score' => [
|
||||
'id' => 64,
|
||||
'title' => 64,
|
||||
]
|
||||
]);
|
||||
$pages = $this
|
||||
->site()
|
||||
->index(true)
|
||||
->filterBy('isReadable', true);
|
||||
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $pages->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $pages->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
|
@@ -23,9 +23,13 @@ return [
|
||||
],
|
||||
[
|
||||
'pattern' => 'users/search',
|
||||
'method' => 'POST',
|
||||
'method' => 'GET|POST',
|
||||
'action' => function () {
|
||||
return $this->users()->query($this->requestBody());
|
||||
if ($this->requestMethod() === 'GET') {
|
||||
return $this->users()->search($this->requestQuery('q'));
|
||||
} else {
|
||||
return $this->users()->query($this->requestBody());
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
|
@@ -9,6 +9,7 @@ use Kirby\Cms\Template;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Exception\NotFoundException;
|
||||
use Kirby\Image\Darkroom;
|
||||
use Kirby\Text\Markdown;
|
||||
use Kirby\Text\SmartyPants;
|
||||
use Kirby\Toolkit\F;
|
||||
use Kirby\Toolkit\Tpl as Snippet;
|
||||
@@ -50,17 +51,12 @@ return [
|
||||
'file::url' => function (App $kirby, $file) {
|
||||
return $file->mediaUrl();
|
||||
},
|
||||
'markdown' => function (App $kirby, string $text = null, array $options = []): string {
|
||||
'markdown' => function (App $kirby, string $text = null, array $options = [], bool $inline = false): string {
|
||||
static $markdown;
|
||||
|
||||
if (isset($markdown) === false) {
|
||||
$parser = ($options['extra'] ?? false) === true ? 'ParsedownExtra' : 'Parsedown';
|
||||
$markdown = new $parser;
|
||||
$markdown->setBreaksEnabled($options['breaks'] ?? true);
|
||||
}
|
||||
$markdown = $markdown ?? new Markdown($options);
|
||||
|
||||
// we need the @ here, because parsedown has some notice issues :(
|
||||
return @$markdown->text($text);
|
||||
return $markdown->parse($text, $inline);
|
||||
},
|
||||
'smartypants' => function (App $kirby, string $text = null, array $options = []): string {
|
||||
static $smartypants;
|
||||
|
@@ -22,7 +22,8 @@ return [
|
||||
return $search;
|
||||
},
|
||||
/**
|
||||
* If true, entries will be sorted alphabetically on selection
|
||||
* If true, selected entries will be sorted
|
||||
* according to their position in the dropdown
|
||||
*/
|
||||
'sort' => function (bool $sort = false) {
|
||||
return $sort;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Form\Form;
|
||||
use Kirby\Cms\Form;
|
||||
use Kirby\Cms\Blueprint;
|
||||
|
||||
return [
|
||||
|
@@ -29,6 +29,21 @@ return [
|
||||
return trim($default);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the options for the files picker
|
||||
*/
|
||||
'files' => function ($files = []) {
|
||||
if (is_string($files) === true) {
|
||||
return ['query' => $files];
|
||||
}
|
||||
|
||||
if (is_array($files) === false) {
|
||||
$files = [];
|
||||
}
|
||||
|
||||
return $files;
|
||||
},
|
||||
|
||||
/**
|
||||
* Maximum number of allowed characters
|
||||
*/
|
||||
@@ -50,10 +65,103 @@ return [
|
||||
return $size;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the upload options for linked files
|
||||
*/
|
||||
'uploads' => function ($uploads = []) {
|
||||
if ($uploads === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_string($uploads) === true) {
|
||||
return ['template' => $uploads];
|
||||
}
|
||||
|
||||
if (is_array($uploads) === false) {
|
||||
$uploads = [];
|
||||
}
|
||||
|
||||
return $uploads;
|
||||
},
|
||||
|
||||
'value' => function (string $value = null) {
|
||||
return trim($value);
|
||||
}
|
||||
],
|
||||
'api' => function () {
|
||||
return [
|
||||
[
|
||||
'pattern' => 'files',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$model = $field->model();
|
||||
|
||||
if (empty($filed->files['query']) === false) {
|
||||
$query = $filed->files['query'];
|
||||
} elseif (is_a($model, 'Kirby\Cms\File') === true) {
|
||||
$query = 'file.siblings';
|
||||
} else {
|
||||
$query = $model::CLASS_ALIAS . '.files';
|
||||
}
|
||||
|
||||
$files = $model->query($query, 'Kirby\Cms\Files');
|
||||
$data = [];
|
||||
|
||||
foreach ($files as $index => $file) {
|
||||
$image = $file->panelImage($field->files['image'] ?? []);
|
||||
$model = $field->model();
|
||||
|
||||
$data[] = [
|
||||
'filename' => $file->filename(),
|
||||
'dragText' => $file->dragText(),
|
||||
'image' => $image,
|
||||
'icon' => $file->panelIcon($image)
|
||||
];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
],
|
||||
[
|
||||
'pattern' => 'upload',
|
||||
'action' => function () {
|
||||
$field = $this->field();
|
||||
$uploads = $field->uploads();
|
||||
|
||||
if ($uploads === false) {
|
||||
throw new Exception('Uploads are disabled for this field');
|
||||
}
|
||||
|
||||
if ($parentQuery = ($uploads['parent'] ?? null)) {
|
||||
$parent = $field->model()->query($parentQuery);
|
||||
} else {
|
||||
$parent = $field->model();
|
||||
}
|
||||
|
||||
if (is_a($parent, 'Kirby\Cms\File') === true) {
|
||||
$parent = $parent->parent();
|
||||
}
|
||||
|
||||
return $this->upload(function ($source, $filename) use ($field, $parent, $uploads) {
|
||||
$file = $parent->createFile([
|
||||
'source' => $source,
|
||||
'template' => $uploads['template'] ?? null,
|
||||
'filename' => $filename,
|
||||
]);
|
||||
|
||||
if (is_a($file, 'Kirby\Cms\File') === false) {
|
||||
throw new Exception('The file could not be uploaded');
|
||||
}
|
||||
|
||||
return [
|
||||
'filename' => $file->filename(),
|
||||
'dragText' => $file->dragText(),
|
||||
];
|
||||
});
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'validations' => [
|
||||
'minlength',
|
||||
'maxlength'
|
||||
|
@@ -428,6 +428,45 @@ function kirbytext(string $text = null, array $data = []): string
|
||||
return App::instance()->kirbytext($text, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses KirbyTags and inline Markdown in the
|
||||
* given string.
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $text
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
function kirbytextinline(string $text = null, array $data = []): string
|
||||
{
|
||||
return App::instance()->kirbytext($text, $data, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for `kirbytext()` helper
|
||||
*
|
||||
* @param string $text
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
function kt(string $text = null, array $data = []): string
|
||||
{
|
||||
return kirbytext($text, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for `kirbytextinline()` helper
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $text
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
function kti(string $text = null, array $data = []): string
|
||||
{
|
||||
return kirbytextinline($text, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* A super simple class autoloader
|
||||
*
|
||||
|
@@ -298,6 +298,19 @@ return function (App $app) {
|
||||
return $field;
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts the field content from inline Markdown/Kirbytext to valid HTML
|
||||
* @since 3.1.0
|
||||
*/
|
||||
'kirbytextinline' => function (Field $field) use ($app) {
|
||||
$field->value = $app->kirbytext($field->value, [
|
||||
'parent' => $field->parent(),
|
||||
'field' => $field
|
||||
], true);
|
||||
|
||||
return $field;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses all KirbyTags without also parsing Markdown
|
||||
*/
|
||||
|
@@ -56,11 +56,7 @@ return function ($kirby) {
|
||||
'pattern' => 'media/plugins/(:any)/(:any)/(:all).(css|gif|js|jpg|png|svg|webp|woff2|woff)',
|
||||
'env' => 'media',
|
||||
'action' => function (string $provider, string $pluginName, string $filename, string $extension) use ($kirby) {
|
||||
if ($url = PluginAssets::resolve($provider . '/' . $pluginName, $filename . '.' . $extension)) {
|
||||
return $kirby
|
||||
->response()
|
||||
->redirect($url, 307);
|
||||
}
|
||||
return PluginAssets::resolve($provider . '/' . $pluginName, $filename . '.' . $extension);
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -115,7 +111,7 @@ return function ($kirby) {
|
||||
'action' => function () use ($kirby) {
|
||||
$home = $kirby->site()->homePage();
|
||||
|
||||
if ($kirby->url() !== $home->url()) {
|
||||
if ($home && $kirby->url() !== $home->url()) {
|
||||
if ($kirby->option('languages.detect') === true) {
|
||||
return $kirby
|
||||
->response()
|
||||
@@ -126,7 +122,7 @@ return function ($kirby) {
|
||||
->redirect($kirby->site()->url());
|
||||
}
|
||||
} else {
|
||||
return $home;
|
||||
return $kirby->resolve(null, $kirby->detectedLanguage()->code());
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -178,7 +174,7 @@ return function ($kirby) {
|
||||
'method' => 'ALL',
|
||||
'env' => 'site',
|
||||
'action' => function () use ($kirby) {
|
||||
return $kirby->site()->homePage();
|
||||
return $kirby->resolve();
|
||||
}
|
||||
];
|
||||
|
||||
|
@@ -8,6 +8,7 @@ return [
|
||||
'mixins' => [
|
||||
'empty',
|
||||
'headline',
|
||||
'help',
|
||||
'layout',
|
||||
'min',
|
||||
'max',
|
||||
|
@@ -4,7 +4,8 @@ use Kirby\Toolkit\I18n;
|
||||
|
||||
return [
|
||||
'mixins' => [
|
||||
'headline'
|
||||
'headline',
|
||||
'help'
|
||||
],
|
||||
'props' => [
|
||||
'text' => function ($text = null) {
|
||||
|
12
kirby/config/sections/mixins/help.php
Executable file
12
kirby/config/sections/mixins/help.php
Executable file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
/**
|
||||
* Sets the help text
|
||||
*/
|
||||
'help' => function ($help = null) {
|
||||
return I18n::translate($help, $help);
|
||||
}
|
||||
]
|
||||
];
|
@@ -10,6 +10,7 @@ return [
|
||||
'mixins' => [
|
||||
'empty',
|
||||
'headline',
|
||||
'help',
|
||||
'layout',
|
||||
'min',
|
||||
'max',
|
||||
|
2
kirby/panel/dist/css/app.css
vendored
2
kirby/panel/dist/css/app.css
vendored
File diff suppressed because one or more lines are too long
5
kirby/panel/dist/img/icons.svg
vendored
5
kirby/panel/dist/img/icons.svg
vendored
@@ -1,4 +1,4 @@
|
||||
<svg aria-hidden="true" style="position:absolute;width:0;height:0" xmlns="http://www.w3.org/2000/svg" overflow="hidden">
|
||||
<svg aria-hidden="true" class="k-icons" xmlns="http://www.w3.org/2000/svg" overflow="hidden">
|
||||
<defs>
|
||||
<symbol id="icon-account" viewBox="0 0 16 16">
|
||||
<path d="M11 7a3 3 0 1 1-6 0 3 3 0 0 1 6 0z" />
|
||||
@@ -27,6 +27,9 @@
|
||||
<symbol id="icon-angle-up" viewBox="0 0 16 16">
|
||||
<path d="M12 11.4l-4-4-4 4L2.6 10 8 4.6l5.4 5.4z" />
|
||||
</symbol>
|
||||
<symbol id="icon-attachment" viewBox="0 0 16 16">
|
||||
<path d="M5,5v4c0,1.7,1.3,3,3,3s3-1.3,3-3V4.5C11,2,9,0,6.5,0S2,2,2,4.5V10c0,3.3,2.7,6,6,6s6-2.7,6-6V4h-2v6 c0,2.2-1.8,4-4,4s-4-1.8-4-4V4.5C4,3.1,5.1,2,6.5,2S9,3.1,9,4.5V9c0,0.6-0.4,1-1,1S7,9.6,7,9V5H5z" />
|
||||
</symbol>
|
||||
<symbol id="icon-bars" viewBox="0 0 16 16">
|
||||
<path d="M15 7H1c-.6 0-1 .4-1 1s.4 1 1 1h14c.6 0 1-.4 1-1s-.4-1-1-1zM15 1H1c-.6 0-1 .4-1 1s.4 1 1 1h14c.6 0 1-.4 1-1s-.4-1-1-1zM15 13H1c-.6 0-1 .4-1 1s.4 1 1 1h14c.6 0 1-.4 1-1s-.4-1-1-1z"
|
||||
/>
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
2
kirby/panel/dist/js/app.js
vendored
2
kirby/panel/dist/js/app.js
vendored
File diff suppressed because one or more lines are too long
23
kirby/panel/jest.config.js
Executable file
23
kirby/panel/jest.config.js
Executable file
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
moduleFileExtensions: [
|
||||
'js',
|
||||
'jsx',
|
||||
'json',
|
||||
'vue'
|
||||
],
|
||||
transform: {
|
||||
'^.+\\.vue$': 'vue-jest',
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
|
||||
'^.+\\.jsx?$': 'babel-jest'
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1'
|
||||
},
|
||||
snapshotSerializers: [
|
||||
'jest-serializer-vue'
|
||||
],
|
||||
testMatch: [
|
||||
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
|
||||
],
|
||||
testURL: 'http://localhost/'
|
||||
}
|
@@ -22,25 +22,106 @@ class Api
|
||||
{
|
||||
use Properties;
|
||||
|
||||
/**
|
||||
* Authentication callback
|
||||
*
|
||||
* @var Closure
|
||||
*/
|
||||
protected $authentication;
|
||||
|
||||
/**
|
||||
* Debugging flag
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $debug = false;
|
||||
|
||||
/**
|
||||
* Collection definition
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $collections = [];
|
||||
|
||||
/**
|
||||
* Injected data/dependencies
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data = [];
|
||||
|
||||
/**
|
||||
* Model definitions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $models = [];
|
||||
|
||||
/**
|
||||
* The current route
|
||||
*
|
||||
* @var Route
|
||||
*/
|
||||
protected $route;
|
||||
|
||||
/**
|
||||
* The Router instance
|
||||
*
|
||||
* @var Router
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* Route definition
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routes = [];
|
||||
|
||||
/**
|
||||
* Request data
|
||||
* [query, body, files]
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $requestData = [];
|
||||
|
||||
/**
|
||||
* The applied request method
|
||||
* (GET, POST, PATCH, etc.)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $requestMethod;
|
||||
|
||||
public function __call($method, $args)
|
||||
/**
|
||||
* Magic accessor for any given data
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call(string $method, array $args = [])
|
||||
{
|
||||
return $this->data($method, ...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new API instance
|
||||
*
|
||||
* @param array $props
|
||||
*/
|
||||
public function __construct(array $props)
|
||||
{
|
||||
$this->setProperties($props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the authentication method
|
||||
* if set
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
if ($auth = $this->authentication()) {
|
||||
@@ -50,11 +131,25 @@ class Api
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authentication callback
|
||||
*
|
||||
* @return Closure|null
|
||||
*/
|
||||
public function authentication()
|
||||
{
|
||||
return $this->authentication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an API call for the given path,
|
||||
* request method and optional request data
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @param array $requestData
|
||||
* @return mixed
|
||||
*/
|
||||
public function call(string $path = null, string $method = 'GET', array $requestData = [])
|
||||
{
|
||||
$path = rtrim($path, '/');
|
||||
@@ -62,15 +157,15 @@ class Api
|
||||
$this->setRequestMethod($method);
|
||||
$this->setRequestData($requestData);
|
||||
|
||||
$router = new Router($this->routes());
|
||||
$result = $router->find($path, $method);
|
||||
$auth = $result->attributes()['auth'] ?? true;
|
||||
$this->router = new Router($this->routes());
|
||||
$this->route = $this->router->find($path, $method);
|
||||
$auth = $this->route->attributes()['auth'] ?? true;
|
||||
|
||||
if ($auth !== false) {
|
||||
$this->authenticate();
|
||||
}
|
||||
|
||||
$output = $result->action()->call($this, ...$result->arguments());
|
||||
$output = $this->route->action()->call($this, ...$this->route->arguments());
|
||||
|
||||
if (is_object($output) === true) {
|
||||
return $this->resolve($output)->toResponse();
|
||||
@@ -79,6 +174,13 @@ class Api
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter and getter for an API collection
|
||||
*
|
||||
* @param string $name
|
||||
* @param array|null $collection
|
||||
* @return Collection
|
||||
*/
|
||||
public function collection(string $name, $collection = null)
|
||||
{
|
||||
if (isset($this->collections[$name]) === false) {
|
||||
@@ -88,11 +190,24 @@ class Api
|
||||
return new Collection($this, $collection, $this->collections[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the collections definition
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function collections(): array
|
||||
{
|
||||
return $this->collections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the injected data array
|
||||
* or certain parts of it by key
|
||||
*
|
||||
* @param string|null $key
|
||||
* @param mixed ...$args
|
||||
* @return mixed
|
||||
*/
|
||||
public function data($key = null, ...$args)
|
||||
{
|
||||
if ($key === null) {
|
||||
@@ -111,11 +226,34 @@ class Api
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
public function hasData($key): bool
|
||||
/**
|
||||
* Returns the debugging flag
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function debug(): bool
|
||||
{
|
||||
return $this->debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if injected data exists for the given key
|
||||
*
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasData(string $key): bool
|
||||
{
|
||||
return isset($this->data[$key]) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an API model instance by name
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $object
|
||||
* @return Model
|
||||
*/
|
||||
public function model(string $name, $object = null)
|
||||
{
|
||||
if (isset($this->models[$name]) === false) {
|
||||
@@ -125,12 +263,27 @@ class Api
|
||||
return new Model($this, $object, $this->models[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all model definitions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function models(): array
|
||||
{
|
||||
return $this->models;
|
||||
}
|
||||
|
||||
public function requestData($type = null, $key = null, $default = null)
|
||||
/**
|
||||
* Getter for request data
|
||||
* Can either get all the data
|
||||
* or certain parts of it.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function requestData(string $type = null, string $key = null, $default = null)
|
||||
{
|
||||
if ($type === null) {
|
||||
return $this->requestData;
|
||||
@@ -146,31 +299,71 @@ class Api
|
||||
return $data[$key] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request body if available
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function requestBody(string $key = null, $default = null)
|
||||
{
|
||||
return $this->requestData('body', $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the files from the request if available
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function requestFiles(string $key = null, $default = null)
|
||||
{
|
||||
return $this->requestData('files', $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all headers from the request if available
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function requestHeaders(string $key = null, $default = null)
|
||||
{
|
||||
return $this->requestData('headers', $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function requestMethod(): string
|
||||
{
|
||||
return $this->requestMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request query if available
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function requestQuery(string $key = null, $default = null)
|
||||
{
|
||||
return $this->requestData('query', $key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a Kirby object into an
|
||||
* API model or collection representation
|
||||
*
|
||||
* @param mixed $object
|
||||
* @return Model|Collection
|
||||
*/
|
||||
public function resolve($object)
|
||||
{
|
||||
if (is_a($object, 'Kirby\Api\Model') === true || is_a($object, 'Kirby\Api\Collection') === true) {
|
||||
@@ -202,17 +395,34 @@ class Api
|
||||
throw new NotFoundException(sprintf('The object "%s" cannot be resolved', $className));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all defined routes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function routes(): array
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the authentication callback
|
||||
*
|
||||
* @param Closure $authentication
|
||||
* @return self
|
||||
*/
|
||||
protected function setAuthentication(Closure $authentication = null)
|
||||
{
|
||||
$this->authentication = $authentication;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the collections definition
|
||||
*
|
||||
* @param array $collections
|
||||
* @return self
|
||||
*/
|
||||
protected function setCollections(array $collections = null)
|
||||
{
|
||||
if ($collections !== null) {
|
||||
@@ -221,18 +431,36 @@ class Api
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the injected data
|
||||
*
|
||||
* @param array $data
|
||||
* @return self
|
||||
*/
|
||||
protected function setData(array $data = null)
|
||||
{
|
||||
$this->data = $data ?? [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the debug flag
|
||||
*
|
||||
* @param boolean $debug
|
||||
* @return self
|
||||
*/
|
||||
protected function setDebug(bool $debug = false)
|
||||
{
|
||||
$this->debug = $debug;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the model definitions
|
||||
*
|
||||
* @param array $models
|
||||
* @return self
|
||||
*/
|
||||
protected function setModels(array $models = null)
|
||||
{
|
||||
if ($models !== null) {
|
||||
@@ -242,6 +470,12 @@ class Api
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the request data
|
||||
*
|
||||
* @param array $requestData
|
||||
* @return self
|
||||
*/
|
||||
protected function setRequestData(array $requestData = null)
|
||||
{
|
||||
$defaults = [
|
||||
@@ -254,25 +488,48 @@ class Api
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the request method
|
||||
*
|
||||
* @param string $requestMethod
|
||||
* @return self
|
||||
*/
|
||||
protected function setRequestMethod(string $requestMethod = null)
|
||||
{
|
||||
$this->requestMethod = $requestMethod;
|
||||
$this->requestMethod = $requestMethod ?? 'GET';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the route definitions
|
||||
*
|
||||
* @param array $routes
|
||||
* @return self
|
||||
*/
|
||||
protected function setRoutes(array $routes = null)
|
||||
{
|
||||
$this->routes = $routes ?? [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the API call
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
* @param array $requestData
|
||||
* @return mixed
|
||||
*/
|
||||
public function render(string $path, $method = 'GET', array $requestData = [])
|
||||
{
|
||||
try {
|
||||
$result = $this->call($path, $method, $requestData);
|
||||
} catch (Throwable $e) {
|
||||
if (is_a($e, 'Kirby\Exception\Exception') === true) {
|
||||
$result = ['status' => 'error'] + $e->toArray();
|
||||
$result = [
|
||||
'status' => 'error',
|
||||
'route' => $this->route->pattern()
|
||||
] + $e->toArray();
|
||||
} else {
|
||||
$result = [
|
||||
'status' => 'error',
|
||||
@@ -280,7 +537,8 @@ class Api
|
||||
'message' => $e->getMessage(),
|
||||
'file' => ltrim($e->getFile(), $_SERVER['DOCUMENT_ROOT'] ?? null),
|
||||
'line' => $e->getLine(),
|
||||
'code' => empty($e->getCode()) === false ? $e->getCode() : 500
|
||||
'code' => empty($e->getCode()) === false ? $e->getCode() : 500,
|
||||
'route' => $this->route->pattern()
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -338,6 +596,13 @@ class Api
|
||||
return Response::json($result, 200, $pretty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload helper method
|
||||
*
|
||||
* @param Closure $callback
|
||||
* @param boolean $single
|
||||
* @return array
|
||||
*/
|
||||
public function upload(Closure $callback, $single = false): array
|
||||
{
|
||||
$trials = 0;
|
||||
|
@@ -29,9 +29,16 @@ use Kirby\Toolkit\Str;
|
||||
use Kirby\Toolkit\Url;
|
||||
|
||||
/**
|
||||
* The App object is a big-ass monolith that's
|
||||
* in the center between all the other CMS classes.
|
||||
* It's the $kirby object in templates and handles
|
||||
* The `$kirby` object is the app instance of
|
||||
* your Kirby installation. It's the central
|
||||
* starting point to get all the different
|
||||
* aspects of your site, like the options, urls,
|
||||
* roots, languages, roles, etc.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class App
|
||||
{
|
||||
@@ -148,6 +155,7 @@ class App
|
||||
/**
|
||||
* Returns the Api instance
|
||||
*
|
||||
* @internal
|
||||
* @return Api
|
||||
*/
|
||||
public function api(): Api
|
||||
@@ -170,8 +178,9 @@ class App
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a hook to the given value
|
||||
* Apply a hook to the given value
|
||||
*
|
||||
* @internal
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
@@ -264,12 +273,13 @@ class App
|
||||
*/
|
||||
public function collections(): Collections
|
||||
{
|
||||
return $this->collections = $this->collections ?? Collections::load($this);
|
||||
return $this->collections = $this->collections ?? new Collections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a core component
|
||||
*
|
||||
* @internal
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -281,6 +291,7 @@ class App
|
||||
/**
|
||||
* Returns the content extension
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function contentExtension(): string
|
||||
@@ -291,6 +302,7 @@ class App
|
||||
/**
|
||||
* Returns files that should be ignored when scanning folders
|
||||
*
|
||||
* @internal
|
||||
* @return array
|
||||
*/
|
||||
public function contentIgnore(): array
|
||||
@@ -302,6 +314,7 @@ class App
|
||||
* Calls a page controller by name
|
||||
* and with the given arguments
|
||||
*
|
||||
* @internal
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return array
|
||||
@@ -369,6 +382,8 @@ class App
|
||||
/**
|
||||
* Destroy the instance singleton and
|
||||
* purge other static props
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public static function destroy()
|
||||
{
|
||||
@@ -424,6 +439,10 @@ class App
|
||||
$id = dirname($path);
|
||||
$filename = basename($path);
|
||||
|
||||
if (is_a($parent, User::class) === true) {
|
||||
return $parent->file($filename);
|
||||
}
|
||||
|
||||
if (is_a($parent, File::class) === true) {
|
||||
$parent = $parent->parent();
|
||||
}
|
||||
@@ -468,6 +487,7 @@ class App
|
||||
* Takes almost any kind of input and
|
||||
* tries to convert it into a valid response
|
||||
*
|
||||
* @internal
|
||||
* @param mixed $input
|
||||
* @return Response
|
||||
*/
|
||||
@@ -553,6 +573,7 @@ class App
|
||||
/**
|
||||
* Renders a single KirbyTag with the given attributes
|
||||
*
|
||||
* @internal
|
||||
* @param string $type
|
||||
* @param string $value
|
||||
* @param array $attr
|
||||
@@ -571,6 +592,7 @@ class App
|
||||
/**
|
||||
* KirbyTags Parser
|
||||
*
|
||||
* @internal
|
||||
* @param string $text
|
||||
* @param array $data
|
||||
* @return string
|
||||
@@ -587,15 +609,16 @@ class App
|
||||
/**
|
||||
* Parses KirbyTags first and Markdown afterwards
|
||||
*
|
||||
* @internal
|
||||
* @param string $text
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function kirbytext(string $text = null, array $data = []): string
|
||||
public function kirbytext(string $text = null, array $data = [], bool $inline = false): string
|
||||
{
|
||||
$text = $this->apply('kirbytext:before', $text);
|
||||
$text = $this->kirbytags($text, $data);
|
||||
$text = $this->markdown($text);
|
||||
$text = $this->markdown($text, $inline);
|
||||
$text = $this->apply('kirbytext:after', $text);
|
||||
|
||||
return $text;
|
||||
@@ -627,6 +650,7 @@ class App
|
||||
/**
|
||||
* Returns the current language code
|
||||
*
|
||||
* @internal
|
||||
* @return string|null
|
||||
*/
|
||||
public function languageCode(string $languageCode = null): ?string
|
||||
@@ -651,12 +675,14 @@ class App
|
||||
/**
|
||||
* Parses Markdown
|
||||
*
|
||||
* @internal
|
||||
* @param string $text
|
||||
* @param bool $inline
|
||||
* @return string
|
||||
*/
|
||||
public function markdown(string $text = null): string
|
||||
public function markdown(string $text = null, bool $inline = false): string
|
||||
{
|
||||
return $this->extensions['components']['markdown']($this, $text, $this->options['markdown'] ?? []);
|
||||
return $this->extensions['components']['markdown']($this, $text, $this->options['markdown'] ?? [], $inline);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -794,6 +820,7 @@ class App
|
||||
/**
|
||||
* Path resolver for the router
|
||||
*
|
||||
* @internal
|
||||
* @param string $path
|
||||
* @param string|null $language
|
||||
* @return mixed
|
||||
@@ -811,7 +838,11 @@ class App
|
||||
|
||||
// use the home page
|
||||
if ($path === null) {
|
||||
return $site->homePage();
|
||||
if ($homePage = $site->homePage()) {
|
||||
return $homePage;
|
||||
}
|
||||
|
||||
throw new NotFoundException('The home page does not exist');
|
||||
}
|
||||
|
||||
// search for the page by path
|
||||
@@ -911,6 +942,7 @@ class App
|
||||
/**
|
||||
* Returns the Router singleton
|
||||
*
|
||||
* @internal
|
||||
* @return Router
|
||||
*/
|
||||
public function router(): Router
|
||||
@@ -921,6 +953,7 @@ class App
|
||||
/**
|
||||
* Returns all defined routes
|
||||
*
|
||||
* @internal
|
||||
* @return array
|
||||
*/
|
||||
public function routes(): array
|
||||
@@ -1052,6 +1085,7 @@ class App
|
||||
/**
|
||||
* Applies the smartypants rule on the text
|
||||
*
|
||||
* @internal
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
@@ -1064,6 +1098,7 @@ class App
|
||||
* Uses the snippet component to create
|
||||
* and return a template snippet
|
||||
*
|
||||
* @internal
|
||||
* @return Snippet
|
||||
*/
|
||||
public function snippet(string $name, array $data = []): ?string
|
||||
@@ -1085,6 +1120,7 @@ class App
|
||||
* Uses the template component to initialize
|
||||
* and return the Template object
|
||||
*
|
||||
* @internal
|
||||
* @return Template
|
||||
*/
|
||||
public function template(string $name, string $type = 'html', string $defaultType = 'html'): Template
|
||||
@@ -1106,8 +1142,9 @@ class App
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a hook by name
|
||||
* Trigger a hook by name
|
||||
*
|
||||
* @internal
|
||||
* @param string $name
|
||||
* @param mixed ...$arguments
|
||||
* @return void
|
||||
|
@@ -67,6 +67,7 @@ trait AppPlugins
|
||||
/**
|
||||
* Register all given extensions
|
||||
*
|
||||
* @internal
|
||||
* @param array $extensions
|
||||
* @param Plugin $plugin The plugin which defined those extensions
|
||||
* @return array
|
||||
@@ -133,7 +134,7 @@ trait AppPlugins
|
||||
|
||||
protected function extendFieldMethods(array $methods): array
|
||||
{
|
||||
return $this->extensions['fieldMethods'] = Field::$methods = array_merge(Field::$methods, $methods);
|
||||
return $this->extensions['fieldMethods'] = Field::$methods = array_merge(Field::$methods, array_change_key_case($methods));
|
||||
}
|
||||
|
||||
protected function extendFields(array $fields): array
|
||||
@@ -258,6 +259,7 @@ trait AppPlugins
|
||||
/**
|
||||
* Returns a given extension by type and name
|
||||
*
|
||||
* @internal
|
||||
* @param string $type i.e. `'hooks'`
|
||||
* @param string $name i.e. `'page.delete:before'`
|
||||
* @param mixed $fallback
|
||||
@@ -270,7 +272,9 @@ trait AppPlugins
|
||||
|
||||
/**
|
||||
* Returns the extensions registry
|
||||
*
|
||||
|
||||
* @internal
|
||||
* @param string|null $type
|
||||
* @return array
|
||||
*/
|
||||
public function extensions(string $type = null)
|
||||
@@ -376,6 +380,7 @@ trait AppPlugins
|
||||
'h' => 'html',
|
||||
'int' => 'toInt',
|
||||
'kt' => 'kirbytext',
|
||||
'kti' => 'kirbytextinline',
|
||||
'link' => 'toLink',
|
||||
'md' => 'markdown',
|
||||
'sp' => 'smartypants',
|
||||
@@ -404,6 +409,7 @@ trait AppPlugins
|
||||
// section mixins
|
||||
Section::$mixins['empty'] = include static::$root . '/config/sections/mixins/empty.php';
|
||||
Section::$mixins['headline'] = include static::$root . '/config/sections/mixins/headline.php';
|
||||
Section::$mixins['help'] = include static::$root . '/config/sections/mixins/help.php';
|
||||
Section::$mixins['layout'] = include static::$root . '/config/sections/mixins/layout.php';
|
||||
Section::$mixins['max'] = include static::$root . '/config/sections/mixins/max.php';
|
||||
Section::$mixins['min'] = include static::$root . '/config/sections/mixins/min.php';
|
||||
@@ -447,6 +453,7 @@ trait AppPlugins
|
||||
* Loads and returns all plugins in the site/plugins directory
|
||||
* Loading only happens on the first call.
|
||||
*
|
||||
* @internal
|
||||
* @param array $plugins Can be used to overwrite the plugins registry
|
||||
* @return array
|
||||
*/
|
||||
|
@@ -53,6 +53,7 @@ trait AppTranslations
|
||||
* Load and set the current language if it exists
|
||||
* Otherwise fall back to the default language
|
||||
*
|
||||
* @internal
|
||||
* @param string $languageCode
|
||||
* @return Language|null
|
||||
*/
|
||||
@@ -79,6 +80,7 @@ trait AppTranslations
|
||||
/**
|
||||
* Set the current translation
|
||||
*
|
||||
* @internal
|
||||
* @param string $translationCode
|
||||
* @return void
|
||||
*/
|
||||
@@ -90,6 +92,7 @@ trait AppTranslations
|
||||
/**
|
||||
* Set locale settings
|
||||
*
|
||||
* @internal
|
||||
* @param string|array $locale
|
||||
*/
|
||||
public function setLocale($locale)
|
||||
|
@@ -15,6 +15,7 @@ trait AppUsers
|
||||
/**
|
||||
* Returns the Authentication layer class
|
||||
*
|
||||
* @internal
|
||||
* @return Auth
|
||||
*/
|
||||
public function auth()
|
||||
|
@@ -230,6 +230,38 @@ class Collection extends BaseCollection
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a combination of filterBy, sortBy, not
|
||||
* offset, limit, search and paginate on the collection.
|
||||
* Any part of the query is optional.
|
||||
*
|
||||
* @param array $query
|
||||
* @return self
|
||||
*/
|
||||
public function query(array $query = [])
|
||||
{
|
||||
$paginate = $query['paginate'] ?? null;
|
||||
$search = $query['search'] ?? null;
|
||||
|
||||
unset($query['paginate']);
|
||||
|
||||
$result = parent::query($query);
|
||||
|
||||
if (empty($search) === false) {
|
||||
if (is_array($search) === true) {
|
||||
$result = $result->search($search['query'] ?? null, $search['options'] ?? []);
|
||||
} else {
|
||||
$result = $result->search($search);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($paginate) === false) {
|
||||
$result = $result->paginate($paginate);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an object
|
||||
*
|
||||
|
@@ -52,16 +52,6 @@ class Collections
|
||||
return $this->get($name, ...$arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Collections set
|
||||
*
|
||||
* @param array $collections
|
||||
*/
|
||||
public function __construct(array $collections = [])
|
||||
{
|
||||
$this->collections = $collections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a collection by name if registered
|
||||
*
|
||||
@@ -71,17 +61,23 @@ class Collections
|
||||
*/
|
||||
public function get(string $name, array $data = [])
|
||||
{
|
||||
if (isset($this->cache[$name]) === true) {
|
||||
return $this->cache[$name];
|
||||
}
|
||||
|
||||
// if not yet loaded
|
||||
if (isset($this->collections[$name]) === false) {
|
||||
return null;
|
||||
$this->collections[$name] = $this->load($name);
|
||||
}
|
||||
|
||||
$controller = new Controller($this->collections[$name]);
|
||||
// if not yet cached
|
||||
if (isset($this->cache[$name]) === false) {
|
||||
$controller = new Controller($this->collections[$name]);
|
||||
$this->cache[$name] = $controller->call(null, $data);
|
||||
}
|
||||
|
||||
return $this->cache[$name] = $controller->call(null, $data);
|
||||
// return cloned object
|
||||
if (is_object($this->cache[$name]) === true) {
|
||||
return clone $this->cache[$name];
|
||||
}
|
||||
|
||||
return $this->cache[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,30 +88,47 @@ class Collections
|
||||
*/
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return isset($this->collections[$name]) === true;
|
||||
if (isset($this->collections[$name]) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->load($name);
|
||||
return true;
|
||||
} catch (NotFoundException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads collections from php files in a
|
||||
* given directory.
|
||||
* Loads collection from php file in a
|
||||
* given directory or from plugin extension.
|
||||
*
|
||||
* @param string $root
|
||||
* @return self
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public static function load(App $app): self
|
||||
public function load(string $name)
|
||||
{
|
||||
$collections = $app->extensions('collections');
|
||||
$root = $app->root('collections');
|
||||
$kirby = App::instance();
|
||||
|
||||
foreach (glob($root . '/*.php') as $file) {
|
||||
// first check for collection file
|
||||
$file = $kirby->root('collections') . '/' . $name . '.php';
|
||||
|
||||
if (file_exists($file)) {
|
||||
$collection = require $file;
|
||||
|
||||
if (is_a($collection, 'Closure')) {
|
||||
$name = pathinfo($file, PATHINFO_FILENAME);
|
||||
$collections[$name] = $collection;
|
||||
return $collection;
|
||||
}
|
||||
}
|
||||
|
||||
return new static($collections);
|
||||
// fallback to collections from plugins
|
||||
$collections = $kirby->extensions('collections');
|
||||
|
||||
if (isset($collections[$name]) === true) {
|
||||
return $collections[$name];
|
||||
}
|
||||
|
||||
throw new NotFoundException('The collection cannot be found');
|
||||
}
|
||||
}
|
||||
|
@@ -87,7 +87,12 @@ class ContentTranslation
|
||||
|
||||
// merge with the default content
|
||||
if ($this->isDefault() === false && $defaultLanguage = $parent->kirby()->defaultLanguage()) {
|
||||
$default = $parent->translation($defaultLanguage->code())->content();
|
||||
$default = [];
|
||||
|
||||
if ($defaultTranslation = $parent->translation($defaultLanguage->code())) {
|
||||
$default = $defaultTranslation->content();
|
||||
}
|
||||
|
||||
$content = array_merge($default, $content);
|
||||
}
|
||||
|
||||
|
@@ -73,12 +73,14 @@ class Field
|
||||
*/
|
||||
public function __call(string $method, array $arguments = [])
|
||||
{
|
||||
$method = strtolower($method);
|
||||
|
||||
if (isset(static::$methods[$method]) === true) {
|
||||
return static::$methods[$method](clone $this, ...$arguments);
|
||||
}
|
||||
|
||||
if (isset(static::$aliases[$method]) === true) {
|
||||
$method = static::$aliases[$method];
|
||||
$method = strtolower(static::$aliases[$method]);
|
||||
|
||||
if (isset(static::$methods[$method]) === true) {
|
||||
return static::$methods[$method](clone $this, ...$arguments);
|
||||
@@ -142,7 +144,7 @@ class Field
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
return empty($this->value) === true;
|
||||
return empty($this->value) === true && in_array($this->value, [0, '0', false], true) === false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +154,7 @@ class Field
|
||||
*/
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
return empty($this->value) === false;
|
||||
return $this->isEmpty() === false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -12,6 +12,13 @@ use Kirby\Toolkit\Str;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* The `$file` object provides a set
|
||||
* of methods that can be used when
|
||||
* dealing with a single image or
|
||||
* other media file, like getting the
|
||||
* URL or resizing an image. It also
|
||||
* handles file meta data.
|
||||
*
|
||||
* The File class is a wrapper around
|
||||
* the Kirby\Image\Image class, which
|
||||
* is used to handle all file methods.
|
||||
@@ -148,6 +155,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Returns the url to api endpoint
|
||||
*
|
||||
* @internal
|
||||
* @param bool $relative
|
||||
* @return string
|
||||
*/
|
||||
@@ -157,8 +165,9 @@ class File extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Asset object
|
||||
* Returns the Image object
|
||||
*
|
||||
* @internal
|
||||
* @return Image
|
||||
*/
|
||||
public function asset(): Image
|
||||
@@ -183,7 +192,8 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Store the template in addition to the
|
||||
* other content.
|
||||
*
|
||||
|
||||
* @internal
|
||||
* @param array $data
|
||||
* @param string|null $languageCode
|
||||
* @return array
|
||||
@@ -199,6 +209,7 @@ class File extends ModelWithContent
|
||||
* Returns the directory in which
|
||||
* the content file is located
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function contentFileDirectory(): string
|
||||
@@ -209,6 +220,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Filename for the content file
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function contentFileName(): string
|
||||
@@ -222,6 +234,7 @@ class File extends ModelWithContent
|
||||
* used in the panel, when the file
|
||||
* gets dragged onto a textarea
|
||||
*
|
||||
* @internal
|
||||
* @param string $type
|
||||
* @param bool $absolute
|
||||
* @return string
|
||||
@@ -301,6 +314,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Create a unique media hash
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaHash(): string
|
||||
@@ -311,6 +325,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Returns the absolute path to the file in the public media folder
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaRoot(): string
|
||||
@@ -321,6 +336,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Returns the absolute Url to the file in the public media folder
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaUrl(): string
|
||||
@@ -329,9 +345,7 @@ class File extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for the old way of fetching File
|
||||
* content. Nowadays `File::content()` should
|
||||
* be used instead.
|
||||
* @deprecated 3.0.0 Use `File::content()` instead
|
||||
*
|
||||
* @return Content
|
||||
*/
|
||||
@@ -345,6 +359,7 @@ class File extends ModelWithContent
|
||||
* This is normally the parent page
|
||||
* or the site object.
|
||||
*
|
||||
* @internal
|
||||
* @return Site|Page
|
||||
*/
|
||||
public function model()
|
||||
@@ -365,6 +380,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Panel icon definition
|
||||
*
|
||||
* @internal
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
@@ -415,6 +431,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Panel image definition
|
||||
*
|
||||
* @internal
|
||||
* @param string|array|false $settings
|
||||
* @param array $thumbSettings
|
||||
* @return array
|
||||
@@ -455,6 +472,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Returns the full path without leading slash
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function panelPath(): string
|
||||
@@ -466,6 +484,7 @@ class File extends ModelWithContent
|
||||
* Returns the url to the editing view
|
||||
* in the panel
|
||||
*
|
||||
* @internal
|
||||
* @param bool $relative
|
||||
* @return string
|
||||
*/
|
||||
@@ -487,6 +506,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Returns the parent id if a parent exists
|
||||
*
|
||||
* @internal
|
||||
* @return string|null
|
||||
*/
|
||||
public function parentId(): ?string
|
||||
@@ -525,6 +545,7 @@ class File extends ModelWithContent
|
||||
/**
|
||||
* Creates a string query, starting from the model
|
||||
*
|
||||
* @internal
|
||||
* @param string|null $query
|
||||
* @param string|null $expect
|
||||
* @return mixed
|
||||
@@ -646,6 +667,7 @@ class File extends ModelWithContent
|
||||
|
||||
/**
|
||||
* Returns the parent Files collection
|
||||
* @internal
|
||||
*
|
||||
* @return Files
|
||||
*/
|
||||
|
@@ -206,6 +206,7 @@ trait FileActions
|
||||
|
||||
/**
|
||||
* Alias for changeName
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $name
|
||||
* @param bool $sanitize
|
||||
|
@@ -65,7 +65,7 @@ trait FileFoundation
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Asset object
|
||||
* Returns the Image object
|
||||
*^
|
||||
* @return Image
|
||||
*/
|
||||
@@ -148,7 +148,7 @@ trait FileFoundation
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the paren app instance
|
||||
* Returns the app instance
|
||||
*
|
||||
* @return App
|
||||
*/
|
||||
|
@@ -90,6 +90,46 @@ trait FileModifications
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a srcset definition for the given sizes
|
||||
* Sizes can be defined as a simple array. They can
|
||||
* also be set up in the config with the thumbs.srcsets option.
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param array|string $sizes
|
||||
* @return string
|
||||
*/
|
||||
public function srcset($sizes = null): ?string
|
||||
{
|
||||
if (empty($sizes) === true) {
|
||||
$sizes = $this->kirby()->option('thumbs.srcsets.default', []);
|
||||
}
|
||||
|
||||
if (is_string($sizes) === true) {
|
||||
$sizes = $this->kirby()->option('thumbs.srcsets.' . $sizes, []);
|
||||
}
|
||||
|
||||
if (is_array($sizes) === false || empty($sizes) === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$set = [];
|
||||
|
||||
foreach ($sizes as $key => $value) {
|
||||
if (is_string($value) === true) {
|
||||
$size = $key;
|
||||
$attr = $value;
|
||||
} else {
|
||||
$size = $value;
|
||||
$attr = $value . 'w';
|
||||
}
|
||||
|
||||
$set[] = $this->resize($size)->url() . ' ' . $attr;
|
||||
}
|
||||
|
||||
return implode(', ', $set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a modified version of images
|
||||
* The media manager takes care of generating
|
||||
|
@@ -64,7 +64,7 @@ class FileRules
|
||||
public static function delete(File $file): bool
|
||||
{
|
||||
if ($file->permissions()->delete() !== true) {
|
||||
throw new LogicException('The file cannot be deleted');
|
||||
throw new PermissionException('The file cannot be deleted');
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -73,7 +73,7 @@ class FileRules
|
||||
public static function replace(File $file, Image $upload): bool
|
||||
{
|
||||
if ($file->permissions()->replace() !== true) {
|
||||
throw new LogicException('The file cannot be replaced');
|
||||
throw new PermissionException('The file cannot be replaced');
|
||||
}
|
||||
|
||||
static::validMime($file, $upload->mime());
|
||||
@@ -94,7 +94,7 @@ class FileRules
|
||||
public static function update(File $file, array $content = []): bool
|
||||
{
|
||||
if ($file->permissions()->update() !== true) {
|
||||
throw new LogicException('The file cannot be updated');
|
||||
throw new PermissionException('The file cannot be updated');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -3,10 +3,17 @@
|
||||
namespace Kirby\Cms;
|
||||
|
||||
/**
|
||||
* An extended version of the Collection
|
||||
* class, that has custom find methods and
|
||||
* a Files::factory method to convert an array
|
||||
* into a Files collection.
|
||||
* The `$files` object extends the general
|
||||
* `Collection` class and refers to a
|
||||
* collection of files, i.e. images, documents
|
||||
* etc. Files can be filtered, searched,
|
||||
* converted, modified or evaluated with the
|
||||
* following methods:
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Files extends Collection
|
||||
{
|
||||
|
@@ -166,8 +166,7 @@ trait HasChildren
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated! Use Page::hasUnlistedChildren
|
||||
*
|
||||
* @deprecated 3.0.0 Use `Page::hasUnlistedChildren` instead
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasInvisibleChildren(): bool
|
||||
@@ -196,8 +195,7 @@ trait HasChildren
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated! Use Page::hasListedChildren
|
||||
*
|
||||
* @deprecated 3.0.0 Use `Page::hasListedChildren` instead
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasVisibleChildren(): bool
|
||||
|
@@ -16,6 +16,7 @@ trait HasMethods
|
||||
* Calls a registered method class with the
|
||||
* passed arguments
|
||||
*
|
||||
* @internal
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
@@ -28,6 +29,7 @@ trait HasMethods
|
||||
/**
|
||||
* Checks if the object has a registered method
|
||||
*
|
||||
* @internal
|
||||
* @param string $method
|
||||
* @return boolean
|
||||
*/
|
||||
|
@@ -3,9 +3,14 @@
|
||||
namespace Kirby\Cms;
|
||||
|
||||
/**
|
||||
* Custom extension of the Toolkit Html builder class
|
||||
* that overwrites the Html::a method to include Cms
|
||||
* Url handling.
|
||||
* The `Html` class provides methods for building
|
||||
* common HTML tags and also contains some helper
|
||||
* methods.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Html extends \Kirby\Toolkit\Html
|
||||
{
|
||||
|
@@ -65,6 +65,7 @@ class Ingredients
|
||||
* Resolves all ingredient callbacks
|
||||
* and creates a plain array
|
||||
*
|
||||
* @internal
|
||||
* @param array $ingredients
|
||||
* @return self
|
||||
*/
|
||||
|
@@ -11,8 +11,19 @@ use Kirby\Toolkit\F;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* Represents a content language
|
||||
* in a multi-language setup
|
||||
* The `$language` object represents
|
||||
* a single language in a multi-language
|
||||
* Kirby setup. You can, for example,
|
||||
* use the methods of this class to get
|
||||
* the name or locale of a language,
|
||||
* check for the default language,
|
||||
* get translation strings and many
|
||||
* more things.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Language extends Model
|
||||
{
|
||||
@@ -145,6 +156,7 @@ class Language extends Model
|
||||
/**
|
||||
* Creates a new language object
|
||||
*
|
||||
* @internal
|
||||
* @param array $props
|
||||
* @return self
|
||||
*/
|
||||
@@ -179,6 +191,7 @@ class Language extends Model
|
||||
* Delete the current language and
|
||||
* all its translation files
|
||||
*
|
||||
* @internal
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(): bool
|
||||
@@ -321,6 +334,7 @@ class Language extends Model
|
||||
/**
|
||||
* Saves the language settings in the languages folder
|
||||
*
|
||||
* @internal
|
||||
* @return self
|
||||
*/
|
||||
public function save(): self
|
||||
@@ -447,6 +461,7 @@ class Language extends Model
|
||||
/**
|
||||
* Update language properties and save them
|
||||
*
|
||||
* @internal
|
||||
* @param array $props
|
||||
* @return self
|
||||
*/
|
||||
|
@@ -23,6 +23,7 @@ class Languages extends Collection
|
||||
/**
|
||||
* Creates a new language with the given props
|
||||
*
|
||||
* @internal
|
||||
* @param array $props
|
||||
* @return Language
|
||||
*/
|
||||
@@ -46,8 +47,7 @@ class Languages extends Collection
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated version of static::default();
|
||||
*
|
||||
* @deprecated 3.0.0 Use `Languages::default()`instead
|
||||
* @return Language|null
|
||||
*/
|
||||
public function findDefault(): ?Language
|
||||
@@ -58,6 +58,7 @@ class Languages extends Collection
|
||||
/**
|
||||
* Convert all defined languages to a collection
|
||||
*
|
||||
* @internal
|
||||
* @return self
|
||||
*/
|
||||
public static function load(): self
|
||||
|
@@ -84,6 +84,7 @@ abstract class Model
|
||||
/**
|
||||
* Setter for the parent Site object
|
||||
*
|
||||
* @internal
|
||||
* @param Site|null $site
|
||||
* @return self
|
||||
*/
|
||||
|
@@ -88,6 +88,7 @@ abstract class ModelWithContent extends Model
|
||||
/**
|
||||
* Returns the absolute path to the content file
|
||||
*
|
||||
* @internal
|
||||
* @param string|null $languageCode
|
||||
* @param bool $force
|
||||
* @return string
|
||||
@@ -123,6 +124,7 @@ abstract class ModelWithContent extends Model
|
||||
* Prepares the content that should be written
|
||||
* to the text file
|
||||
*
|
||||
* @internal
|
||||
* @param array $data
|
||||
* @param string $languageCode
|
||||
* @return array
|
||||
@@ -137,6 +139,7 @@ abstract class ModelWithContent extends Model
|
||||
* folder in which the content file is
|
||||
* located
|
||||
*
|
||||
* @internal
|
||||
* @return string|null
|
||||
*/
|
||||
public function contentFileDirectory(): ?string
|
||||
@@ -147,6 +150,7 @@ abstract class ModelWithContent extends Model
|
||||
/**
|
||||
* Returns the extension of the content file
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function contentFileExtension(): string
|
||||
@@ -157,6 +161,7 @@ abstract class ModelWithContent extends Model
|
||||
/**
|
||||
* Needs to be declared by the final model
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
abstract public function contentFileName(): string;
|
||||
@@ -218,7 +223,7 @@ abstract class ModelWithContent extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the model data has any errors
|
||||
* Checks if the data has any errors
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -230,6 +235,7 @@ abstract class ModelWithContent extends Model
|
||||
/**
|
||||
* Read the content from the content file
|
||||
*
|
||||
* @internal
|
||||
* @param string|null $languageCode
|
||||
* @return array
|
||||
*/
|
||||
@@ -252,6 +258,7 @@ abstract class ModelWithContent extends Model
|
||||
/**
|
||||
* Stores the content on disk
|
||||
*
|
||||
* @internal
|
||||
* @param string $languageCode
|
||||
* @param array $data
|
||||
* @param bool $overwrite
|
||||
@@ -428,6 +435,7 @@ abstract class ModelWithContent extends Model
|
||||
* Low level data writer method
|
||||
* to store the given data on disk or anywhere else
|
||||
*
|
||||
* @internal
|
||||
* @param array $data
|
||||
* @param string $languageCode
|
||||
* @return boolean
|
||||
|
@@ -12,10 +12,10 @@ use Kirby\Toolkit\Str;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* The Page class is the heart and soul of
|
||||
* Kirby. It is used to construct pages and
|
||||
* all their dependencies like children,
|
||||
* files, content, etc.
|
||||
* The `$page` object is the heart and
|
||||
* soul of Kirby. It is used to construct
|
||||
* pages and all their dependencies like
|
||||
* children, files, content, etc.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
@@ -207,6 +207,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Returns the url to the api endpoint
|
||||
*
|
||||
* @internal
|
||||
* @param bool $relative
|
||||
* @return string
|
||||
*/
|
||||
@@ -295,6 +296,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Prepares the content for the write method
|
||||
*
|
||||
* @internal
|
||||
* @return array
|
||||
*/
|
||||
public function contentFileData(array $data, string $languageCode = null): array
|
||||
@@ -309,6 +311,7 @@ class Page extends ModelWithContent
|
||||
* Returns the content text file
|
||||
* which is found by the inventory method
|
||||
*
|
||||
* @internal
|
||||
* @param string $languageCode
|
||||
* @return string
|
||||
*/
|
||||
@@ -320,6 +323,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Call the page controller
|
||||
*
|
||||
* @internal
|
||||
* @param array $data
|
||||
* @param string $contentType
|
||||
* @return array
|
||||
@@ -397,6 +401,7 @@ class Page extends ModelWithContent
|
||||
* used in the panel, when the page
|
||||
* gets dragged onto a textarea
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function dragText($type = 'kirbytext'): string
|
||||
@@ -423,6 +428,7 @@ class Page extends ModelWithContent
|
||||
* Constructs a Page object and also
|
||||
* takes page models into account.
|
||||
*
|
||||
* @internal
|
||||
* @return self
|
||||
*/
|
||||
public static function factory($props): self
|
||||
@@ -483,6 +489,7 @@ class Page extends ModelWithContent
|
||||
* Returns the inventory of files
|
||||
* children and content files
|
||||
*
|
||||
* @internal
|
||||
* @return array
|
||||
*/
|
||||
public function inventory(): array
|
||||
@@ -703,8 +710,7 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page is invisible
|
||||
*
|
||||
* @deprecated 3.0.0 Use `Page::isUnlisted()` intead
|
||||
* @return bool
|
||||
*/
|
||||
public function isInvisible(): bool
|
||||
@@ -768,6 +774,7 @@ class Page extends ModelWithContent
|
||||
* Checks if the page access is verified.
|
||||
* This is only used for drafts so far.
|
||||
*
|
||||
* @internal
|
||||
* @param string $token
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -785,8 +792,7 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page is visible
|
||||
*
|
||||
* @deprecated 3.0.0 Use `Page::isListed()` intead
|
||||
* @return bool
|
||||
*/
|
||||
public function isVisible(): bool
|
||||
@@ -797,6 +803,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Returns the root to the media folder for the page
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaRoot(): string
|
||||
@@ -805,8 +812,9 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* The page's base url for any files
|
||||
* The page's base URL for any files
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaUrl(): string
|
||||
@@ -815,8 +823,9 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Page model if it has been registered
|
||||
* Creates a page model if it has been registered
|
||||
*
|
||||
* @internal
|
||||
* @param string $name
|
||||
* @param array $props
|
||||
* @return Page
|
||||
@@ -860,7 +869,8 @@ class Page extends ModelWithContent
|
||||
* Returns the panel icon definition
|
||||
* according to the blueprint settings
|
||||
*
|
||||
* @params array $params
|
||||
* @internal
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function panelIcon(array $params = null): array
|
||||
@@ -896,6 +906,7 @@ class Page extends ModelWithContent
|
||||
* Returns the escaped Id, which is
|
||||
* used in the panel to make routing work properly
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function panelId(): string
|
||||
@@ -904,6 +915,7 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param string|array|false $settings
|
||||
* @param array|null $thumbSettings
|
||||
* @return array|null
|
||||
@@ -939,6 +951,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Returns the full path without leading slash
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function panelPath(): string
|
||||
@@ -950,6 +963,7 @@ class Page extends ModelWithContent
|
||||
* Returns the url to the editing view
|
||||
* in the panel
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function panelUrl(bool $relative = false): string
|
||||
@@ -974,6 +988,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Returns the parent id, if a parent exists
|
||||
*
|
||||
* @internal
|
||||
* @return string|null
|
||||
*/
|
||||
public function parentId(): ?string
|
||||
@@ -990,6 +1005,7 @@ class Page extends ModelWithContent
|
||||
* which can either be another Page
|
||||
* or the Site
|
||||
*
|
||||
* @internal
|
||||
* @return Page|Site
|
||||
*/
|
||||
public function parentModel()
|
||||
@@ -1028,6 +1044,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Draft preview Url
|
||||
*
|
||||
* @internal
|
||||
* @return string|null
|
||||
*/
|
||||
public function previewUrl(): ?string
|
||||
@@ -1054,6 +1071,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Creates a string query, starting from the model
|
||||
*
|
||||
* @internal
|
||||
* @param string|null $query
|
||||
* @param string|null $expect
|
||||
* @return mixed
|
||||
@@ -1143,6 +1161,7 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return Template
|
||||
*/
|
||||
public function representation($type)
|
||||
@@ -1514,6 +1533,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Builds the Url for a specific language
|
||||
*
|
||||
* @internal
|
||||
* @param string $language
|
||||
* @param array $options
|
||||
* @return string
|
||||
|
@@ -28,7 +28,9 @@ class PageRules
|
||||
if ($page->permissions()->changeSlug() !== true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.changeSlug.permission',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -39,7 +41,9 @@ class PageRules
|
||||
if ($duplicate->is($page) === false) {
|
||||
throw new DuplicateException([
|
||||
'key' => 'page.duplicate',
|
||||
'data' => ['slug' => $slug]
|
||||
'data' => [
|
||||
'slug' => $slug
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -48,7 +52,9 @@ class PageRules
|
||||
if ($duplicate->is($page) === false) {
|
||||
throw new DuplicateException([
|
||||
'key' => 'page.draft.duplicate',
|
||||
'data' => ['slug' => $slug]
|
||||
'data' => [
|
||||
'slug' => $slug
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -79,14 +85,18 @@ class PageRules
|
||||
if ($page->permissions()->changeStatus() !== true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.changeStatus.permission',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
if ($page->isHomeOrErrorPage() === true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.changeStatus.toDraft.invalid',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -101,7 +111,9 @@ class PageRules
|
||||
if ($page->isSortable() !== true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.sort.permission',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -111,7 +123,9 @@ class PageRules
|
||||
if ($page->permissions()->changeStatus() !== true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.changeStatus.permission',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -134,7 +148,9 @@ class PageRules
|
||||
if ($page->permissions()->changeStatus() !== true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.changeStatus.permission',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -146,7 +162,9 @@ class PageRules
|
||||
if ($page->permissions()->changeTemplate() !== true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.changeTemplate.permission',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -171,7 +189,9 @@ class PageRules
|
||||
if ($page->permissions()->changeTitle() !== true) {
|
||||
throw new PermissionException([
|
||||
'key' => 'page.changeTitle.permission',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -183,12 +203,19 @@ class PageRules
|
||||
if ($page->exists() === true) {
|
||||
throw new DuplicateException([
|
||||
'key' => 'page.draft.duplicate',
|
||||
'data' => ['slug' => $page->slug()]
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
if ($page->permissions()->create() !== true) {
|
||||
throw new PermissionException(['key' => 'page.create.permission']);
|
||||
throw new PermissionException([
|
||||
'key' => 'page.create.permission',
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
$siblings = $page->parentModel()->children();
|
||||
@@ -215,7 +242,12 @@ class PageRules
|
||||
public static function delete(Page $page, bool $force = false): bool
|
||||
{
|
||||
if ($page->permissions()->delete() !== true) {
|
||||
throw new PermissionException(['key' => 'page.delete.permission']);
|
||||
throw new PermissionException([
|
||||
'key' => 'page.delete.permission',
|
||||
'data' => [
|
||||
'slug' => $page->slug()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
if (($page->hasChildren() === true || $page->hasDrafts() === true) && $force === false) {
|
||||
|
@@ -6,7 +6,7 @@ trait PageSiblings
|
||||
{
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::hasNextUnlisted instead
|
||||
* @deprecated 3.0.0 Use `Page::hasNextUnlisted` instead
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasNextInvisible(): bool
|
||||
@@ -26,7 +26,7 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::hasNextListed instead
|
||||
* @deprecated Use `Page::hasNextListed` instead
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasNextVisible(): bool
|
||||
@@ -46,7 +46,7 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::hasPrevUnlisted instead
|
||||
* @deprecated Use `Page::hasPrevUnlisted` instead
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasPrevInvisible(): bool
|
||||
@@ -77,7 +77,7 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::hasPrevListed instead
|
||||
* @deprecated Use `Page::hasPrevListed instead`
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasPrevVisible(): bool
|
||||
@@ -86,7 +86,7 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::nextUnlisted() instead
|
||||
* @deprecated Use `Page::nextUnlisted()` instead
|
||||
* @return self|null
|
||||
*/
|
||||
public function nextInvisible()
|
||||
@@ -115,7 +115,7 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::prevListed() instead
|
||||
* @deprecated Use `Page::prevListed()` instead
|
||||
* @return self|null
|
||||
*/
|
||||
public function nextVisible()
|
||||
@@ -124,7 +124,7 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::prevUnlisted() instead
|
||||
* @deprecated Use `Page::prevUnlisted()` instead
|
||||
* @return self|null
|
||||
*/
|
||||
public function prevInvisible()
|
||||
@@ -153,7 +153,7 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use Page::prevListed() instead
|
||||
* @deprecated Use `Page::prevListed()` instead
|
||||
* @return self|null
|
||||
*/
|
||||
public function prevVisible()
|
||||
|
@@ -5,22 +5,14 @@ namespace Kirby\Cms;
|
||||
use Kirby\Toolkit\F;
|
||||
|
||||
/**
|
||||
* The Pages collection contains
|
||||
* any number and mixture of page objects
|
||||
* They don't necessarily have to belong
|
||||
* to the same parent unless it is passed
|
||||
* as second argument in the constructor.
|
||||
*
|
||||
* Pages collection can be constructed very
|
||||
* easily:
|
||||
*
|
||||
* ```php
|
||||
* $collection = new Pages([
|
||||
* new Page(['id' => 'project-a']),
|
||||
* new Page(['id' => 'project-b']),
|
||||
* new Page(['id' => 'project-c']),
|
||||
* ]);
|
||||
* ```
|
||||
* The `$pages` object refers to a
|
||||
* collection of pages. The pages in this
|
||||
* collection can have the same or different
|
||||
* parents, they can actually exist as
|
||||
* subfolders in the content folder or be
|
||||
* virtual pages created from a database,
|
||||
* an Excel sheet, any API or any other
|
||||
* source.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
|
@@ -6,9 +6,13 @@ use Kirby\Http\Uri;
|
||||
use Kirby\Toolkit\Pagination as BasePagination;
|
||||
|
||||
/**
|
||||
* The extended Pagination class handles
|
||||
* URLs in addition to the pagination features
|
||||
* from Kirby\Toolkit\Pagination
|
||||
* The `$pagination` object divides
|
||||
* a collection of pages, files etc.
|
||||
* into discrete pages consisting of
|
||||
* the number of defined items. The
|
||||
* pagination object can then be used
|
||||
* to navigate between these pages,
|
||||
* create a navigation etc.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Http\Response;
|
||||
use Kirby\Toolkit\Dir;
|
||||
use Kirby\Toolkit\F;
|
||||
|
||||
@@ -104,9 +105,11 @@ class PluginAssets
|
||||
$target = $plugin->mediaRoot() . '/' . $filename;
|
||||
$url = $plugin->mediaUrl() . '/' . $filename;
|
||||
|
||||
F::link($source, $target, 'symlink');
|
||||
if (F::link($source, $target, 'symlink') === true) {
|
||||
return Response::redirect($url);
|
||||
}
|
||||
|
||||
return $url;
|
||||
return Response::file($source);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -57,6 +57,17 @@ class Search
|
||||
$keys = array_keys($data);
|
||||
$keys[] = 'id';
|
||||
|
||||
if (is_a($item, User::class) === true) {
|
||||
$keys[] = 'email';
|
||||
$keys[] = 'role';
|
||||
} elseif (is_a($item, Page::class) === true) {
|
||||
// apply the default score for pages
|
||||
$options['score'] = array_merge([
|
||||
'id' => 64,
|
||||
'title' => 64,
|
||||
], $options['score']);
|
||||
}
|
||||
|
||||
if (empty($options['fields']) === false) {
|
||||
$keys = array_intersect($keys, $options['fields']);
|
||||
}
|
||||
@@ -66,7 +77,7 @@ class Search
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$score = $options['score'][$key] ?? 1;
|
||||
$value = $key === 'id' ? $item->id() : $data[$key];
|
||||
$value = $data[$key] ?? (string)$item->$key();
|
||||
|
||||
$lowerValue = strtolower($value);
|
||||
|
||||
|
@@ -9,9 +9,10 @@ use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* The Site class is the root element
|
||||
* The `$site` object is the root element
|
||||
* for any site with pages. It represents
|
||||
* the main content folder with its site.txt
|
||||
* the main content folder with its
|
||||
* `site.txt`.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
@@ -143,6 +144,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Returns the url to the api endpoint
|
||||
*
|
||||
* @internal
|
||||
* @param bool $relative
|
||||
* @return string
|
||||
*/
|
||||
@@ -217,6 +219,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Prepares the content for the write method
|
||||
*
|
||||
* @internal
|
||||
* @return array
|
||||
*/
|
||||
public function contentFileData(array $data, string $languageCode = null): array
|
||||
@@ -229,6 +232,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Filename for the content file
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function contentFileName(): string
|
||||
@@ -257,6 +261,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Returns the global error page id
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function errorPageId(): string
|
||||
@@ -295,6 +300,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Returns the global home page id
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function homePageId(): string
|
||||
@@ -306,6 +312,7 @@ class Site extends ModelWithContent
|
||||
* Creates an inventory of all files
|
||||
* and children in the site directory
|
||||
*
|
||||
* @internal
|
||||
* @return array
|
||||
*/
|
||||
public function inventory(): array
|
||||
@@ -330,14 +337,19 @@ class Site extends ModelWithContent
|
||||
* @param Site $site
|
||||
* @return bool
|
||||
*/
|
||||
public function is(Site $site): bool
|
||||
public function is($site): bool
|
||||
{
|
||||
if (is_a($site, Site::class) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this === $site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root to the media folder for the site
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaRoot(): string
|
||||
@@ -348,6 +360,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* The site's base url for any files
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaUrl(): string
|
||||
@@ -410,6 +423,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Returns the full path without leading slash
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function panelPath(): string
|
||||
@@ -421,6 +435,7 @@ class Site extends ModelWithContent
|
||||
* Returns the url to the editing view
|
||||
* in the panel
|
||||
*
|
||||
* @internal
|
||||
* @param bool $relative
|
||||
* @return string
|
||||
*/
|
||||
@@ -446,6 +461,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Creates a string query, starting from the model
|
||||
*
|
||||
* @internal
|
||||
* @param string|null $query
|
||||
* @param string|null $expect
|
||||
* @return mixed
|
||||
@@ -551,6 +567,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Sets the current page object
|
||||
*
|
||||
* @internal
|
||||
* @param Page|null $page
|
||||
* @return self
|
||||
*/
|
||||
@@ -628,8 +645,9 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Returns the translated url
|
||||
*
|
||||
* @params string $languageCode
|
||||
* @params array $options
|
||||
* @internal
|
||||
* @param string $languageCode
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
public function urlForLanguage(string $languageCode = null, array $options = null): string
|
||||
@@ -646,6 +664,7 @@ class Site extends ModelWithContent
|
||||
* id or page object and
|
||||
* returns the current page
|
||||
*
|
||||
* @internal
|
||||
* @param string|Page $page
|
||||
* @param string|null $languageCode
|
||||
* @return Page
|
||||
|
@@ -91,18 +91,6 @@ class StructureObject extends Model
|
||||
return $this->content = new Content($this->content, $this->parent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted date field from the content
|
||||
*
|
||||
* @param string $format
|
||||
* @param string $field
|
||||
* @return Field
|
||||
*/
|
||||
public function date(string $format = null, $field = 'date')
|
||||
{
|
||||
return $this->content()->get($field)->toDate($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the required id
|
||||
*
|
||||
|
@@ -6,10 +6,18 @@ use Kirby\Http\Url as BaseUrl;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* Extension of the Kirby\Http\Url class
|
||||
* with a specific Url::home method that always
|
||||
* creates the correct base Url and a template asset
|
||||
* Url builder.
|
||||
* The `Url` class extends the
|
||||
* `Kirby\Http\Url` class. In addition
|
||||
* to the methods of that class for dealing
|
||||
* with URLs, it provides a specific
|
||||
* `Url::home` method that always creates
|
||||
* the correct base URL and a template asset
|
||||
* URL builder.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Url extends BaseUrl
|
||||
{
|
||||
@@ -68,7 +76,7 @@ class Url extends BaseUrl
|
||||
}
|
||||
|
||||
// get a language url for the linked page, if the page can be found
|
||||
if ($language !== null && $kirby->multilang() === true && $page = page($path)) {
|
||||
if ($kirby->multilang() === true && $page = page($path)) {
|
||||
$path = $page->url($language);
|
||||
}
|
||||
|
||||
|
@@ -14,8 +14,8 @@ use Kirby\Toolkit\V;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* The User class represents
|
||||
* panel users as well as frontend users.
|
||||
* The `$user` object represents a
|
||||
* single Panel or frontend user.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
@@ -134,6 +134,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Returns the url to the api endpoint
|
||||
*
|
||||
* @internal
|
||||
* @param bool $relative
|
||||
* @return string
|
||||
*/
|
||||
@@ -181,6 +182,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Prepares the content for the write method
|
||||
*
|
||||
* @internal
|
||||
* @param array $data
|
||||
* @param string $languageCode Not used so far
|
||||
* @return array
|
||||
@@ -202,6 +204,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Filename for the content file
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function contentFileName(): string
|
||||
@@ -237,6 +240,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Hashes user password
|
||||
*
|
||||
* @internal
|
||||
* @param string|null $password
|
||||
* @return string|null
|
||||
*/
|
||||
@@ -416,6 +420,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Returns the root to the media folder for the user
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaRoot(): string
|
||||
@@ -426,6 +431,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Returns the media url for the user object
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function mediaUrl(): string
|
||||
@@ -471,6 +477,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Create a dummy nobody
|
||||
*
|
||||
* @internal
|
||||
* @return self
|
||||
*/
|
||||
public static function nobody(): self
|
||||
@@ -484,6 +491,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Returns the full path without leading slash
|
||||
*
|
||||
* @internal
|
||||
* @return string
|
||||
*/
|
||||
public function panelPath(): string
|
||||
@@ -495,6 +503,7 @@ class User extends ModelWithContent
|
||||
* Returns the url to the editing view
|
||||
* in the panel
|
||||
*
|
||||
* @internal
|
||||
* @param bool $relative
|
||||
* @return string
|
||||
*/
|
||||
@@ -532,6 +541,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Creates a string query, starting from the model
|
||||
*
|
||||
* @internal
|
||||
* @param string|null $query
|
||||
* @param string|null $expect
|
||||
* @return mixed
|
||||
@@ -776,7 +786,7 @@ class User extends ModelWithContent
|
||||
throw new NotFoundException(['key' => 'user.password.undefined']);
|
||||
}
|
||||
|
||||
if ($password === null) {
|
||||
if (Str::length($password) < 8) {
|
||||
throw new InvalidArgumentException(['key' => 'user.password.invalid']);
|
||||
}
|
||||
|
||||
|
@@ -6,11 +6,15 @@ use Kirby\Toolkit\Dir;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* Extension of the Collection class that
|
||||
* provides a Users::factory method to convert
|
||||
* an array into a Users collection with User
|
||||
* objects and a Users::load method to load
|
||||
* user accounts from disk.
|
||||
* The `$users` object refers to a collection
|
||||
* of users with or without Panel access. Like
|
||||
* all collections, you can filter, modify,
|
||||
* convert or check the users collection.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Users extends Collection
|
||||
{
|
||||
|
@@ -6,20 +6,20 @@ use Exception;
|
||||
use Kirby\Toolkit\F;
|
||||
|
||||
/**
|
||||
* Universal Data writer and reader class.
|
||||
* The `Data` class provides readers and
|
||||
* writers for data. The class comes with
|
||||
* three handlers for `json`, `yaml` and
|
||||
* `txt` encoded data, but can be extended
|
||||
* and customized.
|
||||
*
|
||||
* The read and write methods automatically
|
||||
* detect, which data handler to use in order
|
||||
* to correctly encode and decode passed data.
|
||||
*
|
||||
* Data Handlers for the class can be
|
||||
* extended and customized.
|
||||
*
|
||||
* @package Kirby
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright 2012 Bastian Allgeier
|
||||
* @license MIT
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Data
|
||||
{
|
||||
|
@@ -102,6 +102,12 @@ class Field extends Component
|
||||
'before' => function ($before = null) {
|
||||
return I18n::translate($before, $before);
|
||||
},
|
||||
/**
|
||||
* Conditions when the field will be shown
|
||||
*/
|
||||
'when' => function ($when = null) {
|
||||
return $when;
|
||||
},
|
||||
/**
|
||||
* Default value for the field, which will be used when a Page/File/User is created
|
||||
*/
|
||||
|
@@ -5,13 +5,13 @@ namespace Kirby\Http;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* This class makes cookie handling easy
|
||||
* The `Cookie` class helps you to
|
||||
* handle cookies in your projects.
|
||||
*
|
||||
* @package Kirby Http
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license MIT
|
||||
*/
|
||||
class Cookie
|
||||
{
|
||||
|
@@ -5,13 +5,13 @@ namespace Kirby\Http;
|
||||
use Kirby\Toolkit\F;
|
||||
|
||||
/**
|
||||
* Makes sending HTTP headers a breeze
|
||||
* The Header class provides methods
|
||||
* for sending HTTP headers.
|
||||
*
|
||||
* @package Kirby Toolkit
|
||||
* @package Kirby Http
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
class Header
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* The Request class provides
|
||||
* The `Request` class provides
|
||||
* a simple API to inspect incoming
|
||||
* requests.
|
||||
*
|
||||
@@ -154,7 +154,7 @@ class Request
|
||||
|
||||
/**
|
||||
* Detects ajax requests
|
||||
*
|
||||
* @deprecated 3.1.0 No longer reliable, especially with the fetch api.
|
||||
* @return boolean
|
||||
*/
|
||||
public function ajax(): bool
|
||||
|
@@ -187,7 +187,7 @@ class Response
|
||||
*/
|
||||
public static function file(string $file)
|
||||
{
|
||||
return new static(F::read($file), F::mime($file));
|
||||
return new static(F::read($file), F::extensionToMime(F::extension($file)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -155,6 +155,7 @@ class Route
|
||||
/**
|
||||
* Throws a specific exception to tell
|
||||
* the router to jump to the next route
|
||||
* @since 3.0.3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
@@ -75,7 +75,13 @@ class ImageMagick extends Darkroom
|
||||
// remove all null values and join the parts
|
||||
$command = implode(' ', array_filter($command));
|
||||
|
||||
exec($command);
|
||||
// try to execute the command
|
||||
exec($command, $output, $return);
|
||||
|
||||
// log broken commands
|
||||
if ($return !== 0) {
|
||||
error_log('The imagemagick convert command could not be executed: ' . $command);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
@@ -6,6 +6,10 @@ use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* The session object can be used to
|
||||
* store visitor preferences for your
|
||||
* site throughout various requests.
|
||||
*
|
||||
* @package Kirby Session
|
||||
* @author Lukas Bestle <lukas@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
|
@@ -58,9 +58,10 @@ class Markdown
|
||||
* Parses the given text and returns the HTML
|
||||
*
|
||||
* @param string $text
|
||||
* @param bool $inline
|
||||
* @return string
|
||||
*/
|
||||
public function parse(string $text): string
|
||||
public function parse(string $text, bool $inline = false): string
|
||||
{
|
||||
if ($this->options['extra'] === true) {
|
||||
$parser = new ParsedownExtra;
|
||||
@@ -70,7 +71,10 @@ class Markdown
|
||||
|
||||
$parser->setBreaksEnabled($this->options['breaks']);
|
||||
|
||||
// we need the @ here, because parsedown has some notice issues :(
|
||||
return @$parser->text($text);
|
||||
if ($inline === true) {
|
||||
return @$parser->line($text);
|
||||
} else {
|
||||
return @$parser->text($text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,14 +5,16 @@ namespace Kirby\Toolkit;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* A set of handy methods to simplify array handling
|
||||
* and make it more consistent.
|
||||
* The `A` class provides a set of handy methods
|
||||
* to simplify array handling and make it more
|
||||
* consistent. The class contains methods for
|
||||
* fetching elements from arrays, merging and
|
||||
* sorting or shuffling arrays.
|
||||
*
|
||||
* @package Kirby Toolkit
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license MIT
|
||||
*/
|
||||
class A
|
||||
{
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace Kirby\Toolkit;
|
||||
|
||||
use Closure;
|
||||
use Countable;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
@@ -10,7 +11,7 @@ use Exception;
|
||||
* interface around arrays of arrays or objects,
|
||||
* with advanced filters, sorting, navigation and more.
|
||||
*/
|
||||
class Collection extends Iterator
|
||||
class Collection extends Iterator implements Countable
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -59,7 +60,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Low-level getter for items
|
||||
* Low-level getter for elements
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
@@ -74,7 +75,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Low-level setter for collection items
|
||||
* Low-level setter for elements
|
||||
*
|
||||
* @param string $key string or array
|
||||
* @param mixed $value
|
||||
@@ -96,7 +97,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Low-level item remover
|
||||
* Low-level element remover
|
||||
*
|
||||
* @param mixed $key the name of the key
|
||||
*/
|
||||
@@ -106,7 +107,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an element to the data array
|
||||
* Appends an element
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $item
|
||||
@@ -124,17 +125,17 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates chunks of the same size
|
||||
* Creates chunks of the same size.
|
||||
* The last chunk may be smaller
|
||||
*
|
||||
* @param int $size Number of items per chunk
|
||||
* @return Collection A new collection with an item for each chunk and
|
||||
* @param int $size Number of elements per chunk
|
||||
* @return Collection A new collection with an element for each chunk and
|
||||
* a sub collection in each chunk
|
||||
*/
|
||||
public function chunk(int $size): self
|
||||
{
|
||||
// create a multidimensional array that is chunked with the given
|
||||
// chunk size keep keys of the items
|
||||
// chunk size keep keys of the elements
|
||||
$chunks = array_chunk($this->data, $size, true);
|
||||
|
||||
// convert each chunk to a subcollection
|
||||
@@ -167,7 +168,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter and setter for the collection data
|
||||
* Getter and setter for the data
|
||||
*
|
||||
* @param array $data
|
||||
* @return array|Collection
|
||||
@@ -188,7 +189,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone and remove all items from the collection
|
||||
* Clone and remove all elements from the collection
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -201,7 +202,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all items to the collection
|
||||
* Adds all elements to the collection
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -212,7 +213,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the collection by a custom
|
||||
* Filters elements by a custom
|
||||
* filter function or an array of filters
|
||||
*
|
||||
* @param Closure $filter
|
||||
@@ -239,8 +240,8 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the collection by one of the predefined
|
||||
* filter methods.
|
||||
* Filters elements by one of the
|
||||
* predefined filter methods.
|
||||
*
|
||||
* @param string $field
|
||||
* @return self
|
||||
@@ -329,7 +330,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Find one or multiple collection items by id
|
||||
* Find one or multiple elements by id
|
||||
*
|
||||
* @param string ...$keys
|
||||
* @return mixed
|
||||
@@ -358,7 +359,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a single item by an attribute and its value
|
||||
* Find a single element by an attribute and its value
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
@@ -375,7 +376,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a single item by key (id)
|
||||
* Find a single element by key (id)
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
@@ -386,7 +387,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element from the array
|
||||
* Returns the first element
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -397,7 +398,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array in reverse order
|
||||
* Returns the elements in reverse order
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -421,8 +422,8 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts an attribute value from the given item
|
||||
* in the collection. This is useful if items in the collection
|
||||
* Extracts an attribute value from the given element
|
||||
* in the collection. This is useful if elements in the collection
|
||||
* might be objects, arrays or anything else and you need to
|
||||
* get the value independently from that. We use it for filterBy.
|
||||
*
|
||||
@@ -463,10 +464,10 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups the collection by a given callback
|
||||
* Groups the elements by a given callback
|
||||
*
|
||||
* @param Closure $callback
|
||||
* @return Collection A new collection with an item for each group and a subcollection in each group
|
||||
* @return Collection A new collection with an element for each group and a subcollection in each group
|
||||
*/
|
||||
public function group(Closure $callback): Collection
|
||||
{
|
||||
@@ -497,7 +498,7 @@ class Collection extends Iterator
|
||||
// create a new entry for the group if it does not exist yet
|
||||
$groups[$value] = new static([$key => $item]);
|
||||
} else {
|
||||
// add the item to an existing group
|
||||
// add the element to an existing group
|
||||
$groups[$value]->set($key, $item);
|
||||
}
|
||||
}
|
||||
@@ -506,11 +507,11 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups the collection by a given field
|
||||
* Groups the elements by a given field
|
||||
*
|
||||
* @param string $field
|
||||
* @param bool $i
|
||||
* @return Collection A new collection with an item for each group and a subcollection in each group
|
||||
* @return Collection A new collection with an element for each group and a subcollection in each group
|
||||
*/
|
||||
public function groupBy(string $field, bool $i = true)
|
||||
{
|
||||
@@ -527,7 +528,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the collection has no items
|
||||
* Checks if the number of elements is zero
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -537,7 +538,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the number of items in the collection is even
|
||||
* Checks if the number of elements is even
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -547,7 +548,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the collection has no items
|
||||
* Checks if the number of elements is more than zero
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -557,7 +558,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the number of items in the collection is odd
|
||||
* Checks if the number of elements is odd
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
@@ -567,7 +568,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element from the collection
|
||||
* Returns the last element
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -589,7 +590,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a function to each item in the collection
|
||||
* Map a function to each element
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return Collection
|
||||
@@ -771,7 +772,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new item to the collection
|
||||
* Adds a new element to the collection
|
||||
*
|
||||
* @param mixed $key string or array
|
||||
* @param mixed $value
|
||||
@@ -790,7 +791,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffle all elements in the array
|
||||
* Shuffle all elements
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
@@ -829,7 +830,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the object by any number of fields
|
||||
* Sorts the elements by any number of fields
|
||||
*
|
||||
* @param $field string|callable Field name or value callback to sort by
|
||||
* @param $direction string asc or desc
|
||||
@@ -918,7 +919,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the current object into an array
|
||||
* Converts the object into an array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -932,7 +933,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the current object into a json string
|
||||
* Converts the object into a JSON string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -942,7 +943,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Convertes the collection to a string
|
||||
* Convertes the object to a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
@@ -3,9 +3,19 @@
|
||||
namespace Kirby\Toolkit;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Low level directory handling utilities
|
||||
* The `Dir` class provides methods
|
||||
* for dealing with directories on the
|
||||
* file system level, like creating,
|
||||
* listing, moving, copying or
|
||||
* evaluating directories etc.
|
||||
*
|
||||
* @package Kirby Toolkit
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Dir
|
||||
{
|
||||
@@ -174,7 +184,11 @@ class Dir
|
||||
throw new Exception(sprintf('The directory "%s" does not exist and cannot be linked', $source));
|
||||
}
|
||||
|
||||
return symlink($source, $link);
|
||||
try {
|
||||
return symlink($source, $link) === true;
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -5,6 +5,13 @@ namespace Kirby\Toolkit;
|
||||
use Zend\Escaper\Escaper;
|
||||
|
||||
/**
|
||||
* The `Escape` class provides methods
|
||||
* for escaping common HTML attributes
|
||||
* data. This can be used to put
|
||||
* untrusted data into typical
|
||||
* attribute values like width, name,
|
||||
* value, etc.
|
||||
*
|
||||
* Wrapper for the Zend Escaper
|
||||
*
|
||||
* @link https://github.com/zendframework/zend-escaper
|
||||
|
@@ -3,12 +3,20 @@
|
||||
namespace Kirby\Toolkit;
|
||||
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Kirby\Http\Header;
|
||||
use Throwable;
|
||||
use ZipArchive;
|
||||
|
||||
/**
|
||||
* Low level file handling utilities
|
||||
* The `F` class provides methods for
|
||||
* dealing with files on the file system
|
||||
* level, like creating, reading,
|
||||
* deleting, copying or validatings files.
|
||||
*
|
||||
* @package Kirby Toolkit
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class F
|
||||
{
|
||||
@@ -324,7 +332,11 @@ class F
|
||||
throw new Exception(sprintf('The file "%s" does not exist and cannot be linked', $source));
|
||||
}
|
||||
|
||||
return $method($source, $link);
|
||||
try {
|
||||
return $method($source, $link) === true;
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -534,7 +546,7 @@ class F
|
||||
$parent = realpath($in);
|
||||
|
||||
if ($parent === false || is_dir($parent) === false) {
|
||||
throw new Exception(sprintf('The parent directory does not exist: "%s"', $parent));
|
||||
throw new Exception(sprintf('The parent directory does not exist: "%s"', $in));
|
||||
}
|
||||
|
||||
if (substr($realpath, 0, strlen($parent)) !== $parent) {
|
||||
|
@@ -28,7 +28,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current key from the array
|
||||
* Returns the current key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -38,7 +38,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all keys in the Iterator
|
||||
* Returns an array of all keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -48,7 +48,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current element of the array
|
||||
* Returns the current element
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -58,7 +58,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the cursor to the previous element in the array
|
||||
* Moves the cursor to the previous element
|
||||
* and returns it
|
||||
*
|
||||
* @return mixed
|
||||
@@ -69,7 +69,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the cursor to the next element in the array
|
||||
* Moves the cursor to the next element
|
||||
* and returns it
|
||||
*
|
||||
* @return mixed
|
||||
@@ -80,7 +80,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the cusor to the first element of the array
|
||||
* Moves the cusor to the first element
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
@@ -98,7 +98,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts all elements in the array
|
||||
* Counts all elements
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@@ -130,7 +130,7 @@ class Iterator implements \Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an element is in the collection by key.
|
||||
* Checks by key if an element is included
|
||||
*
|
||||
* @param mixed $key
|
||||
* @return boolean
|
||||
|
@@ -5,7 +5,15 @@ namespace Kirby\Toolkit;
|
||||
use SimpleXMLElement;
|
||||
|
||||
/**
|
||||
* Mime type detection/guessing
|
||||
* The `Mime` class provides method
|
||||
* for mime type detection or guessing
|
||||
* from different criteria like
|
||||
* extensions etc.
|
||||
*
|
||||
* @package Kirby Toolkit
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link http://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
*/
|
||||
class Mime
|
||||
{
|
||||
|
@@ -5,7 +5,9 @@ namespace Kirby\Toolkit;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* A set of handy string methods
|
||||
* The String class provides a set
|
||||
* of handy methods for string
|
||||
* handling and manipulation.
|
||||
*
|
||||
* @package Kirby Toolkit
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Заглавие 2",
|
||||
"toolbar.button.heading.3": "Заглавие 3",
|
||||
"toolbar.button.italic": "\u041d\u0430\u043a\u043b\u043e\u043d\u0435\u043d \u0448\u0440\u0438\u0444\u0442",
|
||||
"toolbar.button.file": "Файл",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "\u0412\u0440\u044a\u0437\u043a\u0430",
|
||||
"toolbar.button.ol": "Подреден списък",
|
||||
"toolbar.button.ul": "Списък",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Сигурни ли сте, че искате да изтриете <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Потребители",
|
||||
|
||||
"version": "\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Kirby",
|
||||
|
||||
"view.account": "\u0412\u0430\u0448\u0438\u044f \u0430\u043a\u0430\u0443\u043d\u0442",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Encapçalament 2",
|
||||
"toolbar.button.heading.3": "Encapçalament 3",
|
||||
"toolbar.button.italic": "Cursiva",
|
||||
"toolbar.button.file": "Arxiu",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Enlla\u00e7",
|
||||
"toolbar.button.ol": "Llista ordenada",
|
||||
"toolbar.button.ul": "Llista de vinyetes",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Segur que voleu eliminar <br> <strong>{email}</strong>?",
|
||||
|
||||
"users": "Usuaris",
|
||||
|
||||
"version": "Versi\u00f3 de Kirby",
|
||||
|
||||
"view.account": "La teva compta",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Nadpis 2",
|
||||
"toolbar.button.heading.3": "Nadpis 3",
|
||||
"toolbar.button.italic": "Kurz\u00edva",
|
||||
"toolbar.button.file": "Soubor",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Odkaz",
|
||||
"toolbar.button.ol": "Řazený seznam",
|
||||
"toolbar.button.ul": "Odrážkový seznam",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Opravdu chcete smazat tohoto u\u017eivatele?",
|
||||
|
||||
"users": "Uživatelé",
|
||||
|
||||
"version": "Verze Kirby",
|
||||
|
||||
"view.account": "V\u00e1\u0161 \u00fa\u010det",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Overskrift 2",
|
||||
"toolbar.button.heading.3": "Overskrift 3",
|
||||
"toolbar.button.italic": "Kursiv tekst",
|
||||
"toolbar.button.file": "Fil",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Ordnet liste",
|
||||
"toolbar.button.ul": "Punktliste",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"\u00d8nsker du virkelig at slette denne bruger?",
|
||||
|
||||
"users": "Brugere",
|
||||
|
||||
"version": "Kirby version",
|
||||
|
||||
"view.account": "Din konto",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Überschrift 2",
|
||||
"toolbar.button.heading.3": "Überschrift 3",
|
||||
"toolbar.button.italic": "Kursiver Text",
|
||||
"toolbar.button.file": "Datei",
|
||||
"toolbar.button.file.select": "Datei auswählen",
|
||||
"toolbar.button.file.upload": "Datei hochladen",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Geordnete Liste",
|
||||
"toolbar.button.ul": "Ungeordnete Liste",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Willst du den Benutzer <br><strong>{email}</strong> wirklich löschen?",
|
||||
|
||||
"users": "Benutzer",
|
||||
|
||||
"version": "Version",
|
||||
|
||||
"view.account": "Dein Account",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Επικεφαλίδα 2",
|
||||
"toolbar.button.heading.3": "Επικεφαλίδα 3",
|
||||
"toolbar.button.italic": "\u03a0\u03bb\u03ac\u03b3\u03b9\u03b1 \u03b3\u03c1\u03b1\u03c6\u03ae",
|
||||
"toolbar.button.file": "Αρχείο",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03bc\u03bf\u03c2",
|
||||
"toolbar.button.ol": "Ταξινομημένη λίστα",
|
||||
"toolbar.button.ul": "Λίστα κουκκίδων",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7;",
|
||||
|
||||
"users": "Χρήστες",
|
||||
|
||||
"version": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 Kirby",
|
||||
|
||||
"view.account": "\u039f \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c3\u03b1\u03c2",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Heading 2",
|
||||
"toolbar.button.heading.3": "Heading 3",
|
||||
"toolbar.button.italic": "Italic",
|
||||
"toolbar.button.file": "File",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Ordered list",
|
||||
"toolbar.button.ul": "Bullet list",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Do you really want to delete <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Users",
|
||||
|
||||
"version": "Version",
|
||||
|
||||
"view.account": "Your account",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Encabezado 2",
|
||||
"toolbar.button.heading.3": "Encabezado 3",
|
||||
"toolbar.button.italic": "Texto en It\u00e1licas",
|
||||
"toolbar.button.file": "Archivo",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Enlace",
|
||||
"toolbar.button.ol": "Lista en orden",
|
||||
"toolbar.button.ul": "Lista de viñetas",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"¿Estás seguro que deseas eliminar <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Usuarios",
|
||||
|
||||
"version": "Versión",
|
||||
|
||||
"view.account": "Tu cuenta",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Encabezado 2",
|
||||
"toolbar.button.heading.3": "Encabezado 3",
|
||||
"toolbar.button.italic": "Italica",
|
||||
"toolbar.button.file": "Archivo",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Enlace",
|
||||
"toolbar.button.ol": "Lista ordenada",
|
||||
"toolbar.button.ul": "Lista de viñetas",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"¿Realmente quieres eliminar <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Usuarios",
|
||||
|
||||
"version": "Versión",
|
||||
|
||||
"view.account": "Su cuenta",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "عنوان 2",
|
||||
"toolbar.button.heading.3": "عنوان 3",
|
||||
"toolbar.button.italic": "\u0645\u062a\u0646 \u0627\u0631\u06cc\u0628",
|
||||
"toolbar.button.file": "فایل",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "\u067e\u06cc\u0648\u0646\u062f",
|
||||
"toolbar.button.ol": "لیست مرتب",
|
||||
"toolbar.button.ul": "لیست معمولی",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"آیا واقعا میخواهید<strong> {email}</strong> را حذف کنید؟",
|
||||
|
||||
"users": "کاربران",
|
||||
|
||||
"version": "\u0646\u0633\u062e\u0647 \u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631",
|
||||
|
||||
"view.account": "حساب کاربری شما",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Otsikko 2",
|
||||
"toolbar.button.heading.3": "Otsikko 3",
|
||||
"toolbar.button.italic": "Kursivointi",
|
||||
"toolbar.button.file": "Tiedosto",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Linkki",
|
||||
"toolbar.button.ol": "Järjestetty lista",
|
||||
"toolbar.button.ul": "Järjestämätön lista",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Haluatko varmsti poistaa käyttäjän <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Käyttäjät",
|
||||
|
||||
"version": "Versio",
|
||||
|
||||
"view.account": "Oma käyttäjätili",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Titre 2",
|
||||
"toolbar.button.heading.3": "Titre 3",
|
||||
"toolbar.button.italic": "Italique",
|
||||
"toolbar.button.file": "Fichier",
|
||||
"toolbar.button.file.select": "Sélectionner un fichier",
|
||||
"toolbar.button.file.upload": "Transférer un fichier",
|
||||
"toolbar.button.link": "Lien",
|
||||
"toolbar.button.ol": "Liste ordonnée",
|
||||
"toolbar.button.ul": "Liste non-ordonnée",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Voulez-vous vraiment supprimer <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Utilisateurs",
|
||||
|
||||
"version": "Version",
|
||||
|
||||
"view.account": "Votre compte",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Cím 2",
|
||||
"toolbar.button.heading.3": "Cím 3",
|
||||
"toolbar.button.italic": "Dőlt szöveg",
|
||||
"toolbar.button.file": "Fájl",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Rendezett lista",
|
||||
"toolbar.button.ul": "Rendezetlen lista",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Biztos törlöd ezt a felhasználót: <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Felhasználók",
|
||||
|
||||
"version": "Kirby verzi\u00f3",
|
||||
|
||||
"view.account": "Fi\u00f3kod",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Penajukan 2",
|
||||
"toolbar.button.heading.3": "Penajukan 3",
|
||||
"toolbar.button.italic": "Miring",
|
||||
"toolbar.button.file": "Berkas",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Tautan",
|
||||
"toolbar.button.ol": "Daftar berurut",
|
||||
"toolbar.button.ul": "Daftar tidak berurut",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Anda yakin menghapus <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Pengguna",
|
||||
|
||||
"version": "Versi",
|
||||
|
||||
"view.account": "Akun Anda",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Titolo 2",
|
||||
"toolbar.button.heading.3": "Titolo 3",
|
||||
"toolbar.button.italic": "Corsivo",
|
||||
"toolbar.button.file": "File",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Elenco numerato",
|
||||
"toolbar.button.ul": "Elenco puntato",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Sei sicuro di voler eliminare questo utente?",
|
||||
|
||||
"users": "Utenti",
|
||||
|
||||
"version": "Versione di Kirby",
|
||||
|
||||
"view.account": "Il tuo account",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "제목 2",
|
||||
"toolbar.button.heading.3": "제목 3",
|
||||
"toolbar.button.italic": "강조 2",
|
||||
"toolbar.button.file": "파일",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "링크",
|
||||
"toolbar.button.ol": "숫자 목록",
|
||||
"toolbar.button.ul": "기호 목록",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"<strong>이메일({email})</strong>을 삭제할까요?",
|
||||
|
||||
"users": "사용자",
|
||||
|
||||
"version": "버전",
|
||||
|
||||
"view.account": "계정",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Overskrift 2",
|
||||
"toolbar.button.heading.3": "Overskrift 3",
|
||||
"toolbar.button.italic": "Kursiv tekst",
|
||||
"toolbar.button.file": "Fil",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Adresse",
|
||||
"toolbar.button.ol": "Ordnet liste",
|
||||
"toolbar.button.ul": "Punktliste",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Vil du virkelig slette denne konten?",
|
||||
|
||||
"users": "Brukere",
|
||||
|
||||
"version": "Kirby versjon",
|
||||
|
||||
"view.account": "Din konto",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Titel 2",
|
||||
"toolbar.button.heading.3": "Titel 3",
|
||||
"toolbar.button.italic": "Cursieve tekst",
|
||||
"toolbar.button.file": "Bestand",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Genummerde lijst",
|
||||
"toolbar.button.ul": "Opsomming",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Weet je zeker dat je <br><strong>{email}</strong>wil verwijderen?",
|
||||
|
||||
"users": "Gebruikers",
|
||||
|
||||
"version": "Kirby-versie",
|
||||
|
||||
"view.account": "Jouw account",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Nagłówek 2",
|
||||
"toolbar.button.heading.3": "Nagłówek 3",
|
||||
"toolbar.button.italic": "Kursywa",
|
||||
"toolbar.button.file": "Plik",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Lista numerowana",
|
||||
"toolbar.button.ul": "Lista wypunktowana",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Czy na pewno chcesz usunąć <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Użytkownicy",
|
||||
|
||||
"version": "Wersja",
|
||||
|
||||
"view.account": "Twoje konto",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Título 2",
|
||||
"toolbar.button.heading.3": "Título 3",
|
||||
"toolbar.button.italic": "Itálico",
|
||||
"toolbar.button.file": "Arquivo",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Lista ordenada",
|
||||
"toolbar.button.ul": "Lista não-ordenada",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Deseja realmente excluir <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Usuários",
|
||||
|
||||
"version": "Vers\u00e3o do Kirby",
|
||||
|
||||
"view.account": "Sua conta",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Título 2",
|
||||
"toolbar.button.heading.3": "Título 3",
|
||||
"toolbar.button.italic": "Itálico",
|
||||
"toolbar.button.file": "Ficheiro",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Link",
|
||||
"toolbar.button.ol": "Lista ordenada",
|
||||
"toolbar.button.ul": "Lista não-ordenada",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Deseja realmente excluir <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Utilizadores",
|
||||
|
||||
"version": "Vers\u00e3o do Kirby",
|
||||
|
||||
"view.account": "A sua conta",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Nadpis 2",
|
||||
"toolbar.button.heading.3": "Nadpis 3",
|
||||
"toolbar.button.italic": "Kurzíva",
|
||||
"toolbar.button.file": "Súbor",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "Odkaz",
|
||||
"toolbar.button.ol": "Číslovaný zoznam",
|
||||
"toolbar.button.ul": "Odrážkový zoznam",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Ste si istý, že chcete zmazať <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Užívatelia",
|
||||
|
||||
"version": "Verzia",
|
||||
|
||||
"view.account": "Váš účet",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Rubrik 2",
|
||||
"toolbar.button.heading.3": "Rubrik 3",
|
||||
"toolbar.button.italic": "Kursiv",
|
||||
"toolbar.button.file": "Fil",
|
||||
"toolbar.button.file.select": "Select a file",
|
||||
"toolbar.button.file.upload": "Upload a file",
|
||||
"toolbar.button.link": "L\u00e4nk",
|
||||
"toolbar.button.ol": "Sorterad lista",
|
||||
"toolbar.button.ul": "Punktlista",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"Vill du verkligen radera <br><strong>{email}</strong>?",
|
||||
|
||||
"users": "Användare",
|
||||
|
||||
"version": "Version",
|
||||
|
||||
"view.account": "Ditt konto",
|
||||
|
@@ -365,6 +365,9 @@
|
||||
"toolbar.button.heading.2": "Başlık 2",
|
||||
"toolbar.button.heading.3": "Başlık 3",
|
||||
"toolbar.button.italic": "Eğik Yazı",
|
||||
"toolbar.button.file": "Dosya",
|
||||
"toolbar.button.file.select": "Bir dosya seçin",
|
||||
"toolbar.button.file.upload": "Bir dosya yükleyin",
|
||||
"toolbar.button.link": "Ba\u011flant\u0131",
|
||||
"toolbar.button.ol": "Sıralı liste",
|
||||
"toolbar.button.ul": "Madde listesi",
|
||||
@@ -396,6 +399,8 @@
|
||||
"user.delete.confirm":
|
||||
"<strong>{email}</strong> kullanıcısını silmek istediğinizden emin misiniz?",
|
||||
|
||||
"users": "Kullanıcılar",
|
||||
|
||||
"version": "Versiyon",
|
||||
|
||||
"view.account": "Hesap Bilgilerin",
|
||||
|
Reference in New Issue
Block a user