Upgrade to 3.1.0

This commit is contained in:
Bastian Allgeier
2019-03-19 11:07:14 +01:00
parent 418db4b09b
commit 6e074142f1
98 changed files with 1266 additions and 299 deletions

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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)

View File

@@ -15,6 +15,7 @@ trait AppUsers
/**
* Returns the Authentication layer class
*
* @internal
* @return Auth
*/
public function auth()

View File

@@ -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
*

View File

@@ -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');
}
}

View File

@@ -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);
}

View File

@@ -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;
}
/**

View File

@@ -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
*/

View File

@@ -206,6 +206,7 @@ trait FileActions
/**
* Alias for changeName
* @deprecated
*
* @param string $name
* @param bool $sanitize

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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

View File

@@ -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
*/

View File

@@ -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
{

View File

@@ -65,6 +65,7 @@ class Ingredients
* Resolves all ingredient callbacks
* and creates a plain array
*
* @internal
* @param array $ingredients
* @return self
*/

View File

@@ -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
*/

View File

@@ -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

View File

@@ -84,6 +84,7 @@ abstract class Model
/**
* Setter for the parent Site object
*
* @internal
* @param Site|null $site
* @return self
*/

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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()

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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
*

View File

@@ -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);
}

View File

@@ -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']);
}

View File

@@ -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
{