Upgrade to 3.3.0
This commit is contained in:
@@ -37,9 +37,7 @@ class Api extends BaseApi
|
||||
$this->setRequestMethod($method);
|
||||
$this->setRequestData($requestData);
|
||||
|
||||
if ($languageCode = $this->language()) {
|
||||
$this->kirby->setCurrentLanguage($languageCode);
|
||||
}
|
||||
$this->kirby->setCurrentLanguage($this->language());
|
||||
|
||||
if ($user = $this->kirby->user()) {
|
||||
$this->kirby->setCurrentTranslation($user->language());
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Email\PHPMailer as Emailer;
|
||||
use Kirby\Exception\ErrorPageException;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Exception\NotFoundException;
|
||||
use Kirby\Http\Request;
|
||||
@@ -56,6 +57,7 @@ class App
|
||||
protected $languages;
|
||||
protected $locks;
|
||||
protected $multilang;
|
||||
protected $nonce;
|
||||
protected $options;
|
||||
protected $path;
|
||||
protected $request;
|
||||
@@ -120,9 +122,15 @@ class App
|
||||
$this->extensionsFromOptions();
|
||||
$this->extensionsFromFolders();
|
||||
|
||||
// trigger hook for use in plugins
|
||||
$this->trigger('system.loadPlugins:after');
|
||||
|
||||
// handle those damn errors
|
||||
$this->handleErrors();
|
||||
|
||||
// execute a ready callback from the config
|
||||
$this->optionsFromReadyCallback();
|
||||
|
||||
// bake config
|
||||
Config::$data = $this->options;
|
||||
}
|
||||
@@ -475,7 +483,7 @@ class App
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $parent
|
||||
* @param boolean $drafts
|
||||
* @param bool $drafts
|
||||
* @return \Kirby\Cms\File|null
|
||||
*/
|
||||
public function file(string $path, $parent = null, bool $drafts = true)
|
||||
@@ -586,7 +594,11 @@ class App
|
||||
|
||||
// Pages
|
||||
if (is_a($input, 'Kirby\Cms\Page')) {
|
||||
$html = $input->render();
|
||||
try {
|
||||
$html = $input->render();
|
||||
} catch (ErrorPageException $e) {
|
||||
return $this->io($e);
|
||||
}
|
||||
|
||||
if ($input->isErrorPage() === true) {
|
||||
if ($response->code() === null) {
|
||||
@@ -758,7 +770,7 @@ class App
|
||||
/**
|
||||
* Check for a multilang setup
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function multilang(): bool
|
||||
{
|
||||
@@ -769,6 +781,17 @@ class App
|
||||
return $this->multilang = $this->languages()->count() !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the nonce, which is used
|
||||
* in the panel for inline scripts
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function nonce(): string
|
||||
{
|
||||
return $this->nonce = $this->nonce ?? base64_encode(random_bytes(20));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a specific configuration option
|
||||
*
|
||||
@@ -791,17 +814,6 @@ class App
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject options from Kirby instance props
|
||||
*
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
protected function optionsFromProps(array $options = []): array
|
||||
{
|
||||
return $this->options = array_replace_recursive($this->options, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all options from files in site/config
|
||||
*
|
||||
@@ -823,16 +835,49 @@ class App
|
||||
return $this->options = array_replace_recursive($config, $main, $host, $addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject options from Kirby instance props
|
||||
*
|
||||
* @param array $options
|
||||
* @return array
|
||||
*/
|
||||
protected function optionsFromProps(array $options = []): array
|
||||
{
|
||||
return $this->options = array_replace_recursive($this->options, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge last-minute options from ready callback
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function optionsFromReadyCallback(): array
|
||||
{
|
||||
if (isset($this->options['ready']) === true && is_callable($this->options['ready']) === true) {
|
||||
// fetch last-minute options from the callback
|
||||
$options = (array)$this->options['ready']($this);
|
||||
|
||||
// inject all last-minute options recursively
|
||||
$this->options = array_replace_recursive($this->options, $options);
|
||||
}
|
||||
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any page from the content folder
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $id|null
|
||||
* @param \Kirby\Cms\Page|\Kirby\Cms\Site|null $parent
|
||||
* @param bool $drafts
|
||||
* @return \Kirby\Cms\Page|null
|
||||
*/
|
||||
public function page(string $id, $parent = null, bool $drafts = true)
|
||||
public function page(?string $id = null, $parent = null, bool $drafts = true)
|
||||
{
|
||||
if ($id === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parent = $parent ?? $this->site();
|
||||
|
||||
if ($page = $parent->find($id)) {
|
||||
@@ -1184,10 +1229,20 @@ class App
|
||||
{
|
||||
$options = $this->option('smartypants', []);
|
||||
|
||||
if ($options === true) {
|
||||
if ($options === false) {
|
||||
return $text;
|
||||
} elseif (is_array($options) === false) {
|
||||
$options = [];
|
||||
}
|
||||
|
||||
if ($this->multilang() === true) {
|
||||
$languageSmartypants = $this->language()->smartypants() ?? [];
|
||||
|
||||
if (empty($languageSmartypants) === false) {
|
||||
$options = array_merge($options, $languageSmartypants);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->component('smartypants')($this, $text, $options);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,18 +29,17 @@ trait AppErrors
|
||||
|
||||
protected function handleErrors()
|
||||
{
|
||||
$request = $this->request();
|
||||
|
||||
// TODO: implement acceptance
|
||||
if ($request->ajax()) {
|
||||
return $this->handleJsonErrors();
|
||||
if ($this->request()->cli() === true) {
|
||||
$this->handleCliErrors();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($request->cli()) {
|
||||
return $this->handleCliErrors();
|
||||
if ($this->visitor()->prefersJson() === true) {
|
||||
$this->handleJsonErrors();
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->handleHtmlErrors();
|
||||
$this->handleHtmlErrors();
|
||||
}
|
||||
|
||||
protected function handleHtmlErrors()
|
||||
|
||||
@@ -701,7 +701,6 @@ trait AppPlugins
|
||||
protected function pluginsLoader(): array
|
||||
{
|
||||
$root = $this->root('plugins');
|
||||
$kirby = $this;
|
||||
$loaded = [];
|
||||
|
||||
foreach (Dir::read($root) as $dirname) {
|
||||
@@ -709,14 +708,10 @@ trait AppPlugins
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir($root . '/' . $dirname) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dir = $root . '/' . $dirname;
|
||||
$entry = $dir . '/index.php';
|
||||
|
||||
if (file_exists($entry) === false) {
|
||||
if (is_dir($dir) !== true || is_file($entry) !== true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ trait AppTranslations
|
||||
$inject = $this->extensions['translations'][$locale] ?? [];
|
||||
|
||||
// load from disk instead
|
||||
return Translation::load($locale, $this->root('translations') . '/' . $locale . '.json', $inject);
|
||||
return Translation::load($locale, $this->root('i18n:translations') . '/' . $locale . '.json', $inject);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,6 +172,6 @@ trait AppTranslations
|
||||
return $this->translations;
|
||||
}
|
||||
|
||||
return Translations::load($this->root('translations'), $this->extensions['translations'] ?? []);
|
||||
return Translations::load($this->root('i18n:translations'), $this->extensions['translations'] ?? []);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ trait AppUsers
|
||||
* Returns a specific user by id
|
||||
* or the current user if no id is given
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $id
|
||||
* @return \Kirby\Cms\User|null
|
||||
*/
|
||||
public function user(string $id = null)
|
||||
|
||||
@@ -165,7 +165,7 @@ class Auth
|
||||
* Check if logins are blocked for the current ip or email
|
||||
*
|
||||
* @param string $email
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isBlocked(string $email): bool
|
||||
{
|
||||
@@ -195,7 +195,7 @@ class Auth
|
||||
*
|
||||
* @param string $email
|
||||
* @param string $password
|
||||
* @param boolean $long
|
||||
* @param bool $long
|
||||
* @return \Kirby\Cms\User
|
||||
*
|
||||
* @throws PermissionException If the rate limit was exceeded or if any other error occured with debug mode off
|
||||
@@ -243,7 +243,7 @@ class Auth
|
||||
$message = 'Invalid email or password';
|
||||
}
|
||||
|
||||
throw new PermissionException($message, 403);
|
||||
throw new PermissionException($message);
|
||||
}
|
||||
|
||||
// validate the user
|
||||
@@ -334,7 +334,7 @@ class Auth
|
||||
/**
|
||||
* Logout the current user
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function logout(): bool
|
||||
{
|
||||
@@ -354,7 +354,7 @@ class Auth
|
||||
* Tracks a login
|
||||
*
|
||||
* @param string $email
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function track(string $email): bool
|
||||
{
|
||||
|
||||
@@ -472,7 +472,7 @@ class Blueprint
|
||||
return [
|
||||
'label' => 'Error',
|
||||
'name' => $name,
|
||||
'text' => $message,
|
||||
'text' => strip_tags($message),
|
||||
'theme' => 'negative',
|
||||
'type' => 'info',
|
||||
];
|
||||
@@ -595,12 +595,17 @@ class Blueprint
|
||||
continue;
|
||||
}
|
||||
|
||||
// fallback to default props when true is passed
|
||||
if ($sectionProps === true) {
|
||||
$sectionProps = [];
|
||||
}
|
||||
|
||||
// inject all section extensions
|
||||
$sectionProps = $this->extend($sectionProps);
|
||||
|
||||
$sections[$sectionName] = $sectionProps = array_merge($sectionProps, [
|
||||
'name' => $sectionName,
|
||||
'type' => $type = $sectionProps['type'] ?? null
|
||||
'type' => $type = $sectionProps['type'] ?? $sectionName
|
||||
]);
|
||||
|
||||
if (empty($type) === true || is_string($type) === false) {
|
||||
|
||||
@@ -38,8 +38,8 @@ class Collection extends BaseCollection
|
||||
/**
|
||||
* Magic getter function
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $arguments
|
||||
* @param string $key
|
||||
* @param mixed $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call(string $key, $arguments)
|
||||
@@ -101,8 +101,8 @@ class Collection extends BaseCollection
|
||||
/**
|
||||
* Appends an element to the data array
|
||||
*
|
||||
* @param mixed $key Optional collection key, will be determined from the item if not given
|
||||
* @param mixed $item
|
||||
* @param mixed $key Optional collection key, will be determined from the item if not given
|
||||
* @param mixed $item
|
||||
* @return \Kirby\Cms\Collection
|
||||
*/
|
||||
public function append(...$args)
|
||||
@@ -165,7 +165,7 @@ class Collection extends BaseCollection
|
||||
* is in the collection
|
||||
*
|
||||
* @param string|object $id
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function has($id): bool
|
||||
{
|
||||
@@ -181,7 +181,7 @@ class Collection extends BaseCollection
|
||||
* The method will automatically detect objects
|
||||
* or ids and then search accordingly.
|
||||
*
|
||||
* @param string|object $object
|
||||
* @param string|object $object
|
||||
* @return int
|
||||
*/
|
||||
public function indexOf($object): int
|
||||
@@ -196,7 +196,7 @@ class Collection extends BaseCollection
|
||||
/**
|
||||
* Returns a Collection without the given element(s)
|
||||
*
|
||||
* @param mixed ...$keys any number of keys, passed as individual arguments
|
||||
* @param mixed ...$keys any number of keys, passed as individual arguments
|
||||
* @return \Kirby\Cms\Collection
|
||||
*/
|
||||
public function not(...$keys)
|
||||
@@ -216,7 +216,7 @@ class Collection extends BaseCollection
|
||||
/**
|
||||
* Add pagination and return a sliced set of data.
|
||||
*
|
||||
* @param mixed ...$arguments
|
||||
* @param mixed ...$arguments
|
||||
* @return \Kirby\Cms\Collection
|
||||
*/
|
||||
public function paginate(...$arguments)
|
||||
@@ -240,9 +240,9 @@ class Collection extends BaseCollection
|
||||
/**
|
||||
* Prepends an element to the data array
|
||||
*
|
||||
* @param mixed $key Optional collection key, will be determined from the item if not given
|
||||
* @param mixed $item
|
||||
* @return Kirby\Cms\Collection
|
||||
* @param mixed $key Optional collection key, will be determined from the item if not given
|
||||
* @param mixed $item
|
||||
* @return \Kirby\Cms\Collection
|
||||
*/
|
||||
public function prepend(...$args)
|
||||
{
|
||||
@@ -321,7 +321,7 @@ class Collection extends BaseCollection
|
||||
* to an array. This can also take a callback
|
||||
* function to further modify the array result.
|
||||
*
|
||||
* @param Closure $map
|
||||
* @param Closure $map
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(Closure $map = null): array
|
||||
|
||||
@@ -42,8 +42,8 @@ class Collections
|
||||
* Magic caller to enable something like
|
||||
* `$collections->myCollection()`
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return \Kirby\Cms\Collection|null
|
||||
*/
|
||||
public function __call(string $name, array $arguments = [])
|
||||
@@ -89,7 +89,7 @@ class Collections
|
||||
* Checks if a collection exists
|
||||
*
|
||||
* @param string $name
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $name): bool
|
||||
{
|
||||
@@ -109,7 +109,7 @@ class Collections
|
||||
* Loads collection from php file in a
|
||||
* given directory or from plugin extension.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function load(string $name)
|
||||
|
||||
@@ -69,7 +69,7 @@ class Content
|
||||
* Same as `self::data()` to improve
|
||||
* `var_dump` output
|
||||
*
|
||||
* @see self::data()
|
||||
* @see self::data()
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
@@ -146,7 +146,7 @@ class Content
|
||||
* Returns either a single field object
|
||||
* or all registered fields
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $key
|
||||
* @return \Kirby\Cms\Field|array
|
||||
*/
|
||||
public function get(string $key = null)
|
||||
@@ -172,7 +172,7 @@ class Content
|
||||
* Checks if a content field is set
|
||||
*
|
||||
* @param string $key
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function has(string $key): bool
|
||||
{
|
||||
@@ -197,7 +197,7 @@ class Content
|
||||
* without the fields, specified by the
|
||||
* passed key(s)
|
||||
*
|
||||
* @param string ...$keys
|
||||
* @param string ...$keys
|
||||
* @return self
|
||||
*/
|
||||
public function not(...$keys)
|
||||
@@ -238,8 +238,8 @@ class Content
|
||||
/**
|
||||
* Returns the raw data array
|
||||
*
|
||||
* @see self::data()
|
||||
* @return array
|
||||
* @see self::data()
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
@@ -250,8 +250,8 @@ class Content
|
||||
* Updates the content and returns
|
||||
* a cloned object
|
||||
*
|
||||
* @param array $content
|
||||
* @param bool $overwrite
|
||||
* @param array $content
|
||||
* @param bool $overwrite
|
||||
* @return self
|
||||
*/
|
||||
public function update(array $content = null, bool $overwrite = false)
|
||||
|
||||
@@ -85,7 +85,7 @@ class ContentLock
|
||||
'user' => $user->id(),
|
||||
'email' => $user->email(),
|
||||
'time' => $time,
|
||||
'unlockable' => ($time + 200) <= time()
|
||||
'unlockable' => ($time + 60) <= time()
|
||||
];
|
||||
}
|
||||
|
||||
@@ -144,7 +144,10 @@ class ContentLock
|
||||
|
||||
// check if lock was set by another user
|
||||
if ($this->data['lock']['user'] !== $this->user()->id()) {
|
||||
throw new LogicException('The content lock can only be removed by the user who created it. Use unlock instead.', 409);
|
||||
throw new LogicException([
|
||||
'fallback' => 'The content lock can only be removed by the user who created it. Use unlock instead.',
|
||||
'httpCode' => 409
|
||||
]);
|
||||
}
|
||||
|
||||
// remove lock
|
||||
|
||||
@@ -121,7 +121,7 @@ class ContentLocks
|
||||
* Returns the file handle to a `.lock` file
|
||||
*
|
||||
* @param string $file
|
||||
* @param boolean $create Whether to create the file if it does not exist
|
||||
* @param bool $create Whether to create the file if it does not exist
|
||||
* @return resource|null File handle
|
||||
*/
|
||||
protected function handle(string $file, bool $create = false)
|
||||
@@ -167,7 +167,7 @@ class ContentLocks
|
||||
*
|
||||
* @param \Kirby\Cms\ModelWithContent $model
|
||||
* @param array $data
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function set(ModelWithContent $model, array $data): bool
|
||||
{
|
||||
|
||||
@@ -119,7 +119,7 @@ class ContentTranslation
|
||||
/**
|
||||
* Checks if the translation file exists
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
@@ -140,7 +140,7 @@ class ContentTranslation
|
||||
* Checks if the this is the default translation
|
||||
* of the model
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isDefault(): bool
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ class Dir extends \Kirby\Toolkit\Dir
|
||||
* @param string $dir
|
||||
* @param string $contentExtension
|
||||
* @param array $contentIgnore
|
||||
* @param boolean $multilang
|
||||
* @param bool $multilang
|
||||
* @return array
|
||||
*/
|
||||
public static function inventory(string $dir, string $contentExtension = 'txt', array $contentIgnore = null, bool $multilang = false): array
|
||||
|
||||
@@ -95,7 +95,7 @@ class Field
|
||||
*
|
||||
* @param object $parent
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __construct($parent = null, string $key, $value)
|
||||
{
|
||||
@@ -130,7 +130,7 @@ class Field
|
||||
/**
|
||||
* Checks if the field exists in the content data array
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
@@ -140,7 +140,7 @@ class Field
|
||||
/**
|
||||
* Checks if the field content is empty
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty(): bool
|
||||
{
|
||||
@@ -150,7 +150,7 @@ class Field
|
||||
/**
|
||||
* Checks if the field content is not empty
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
@@ -232,7 +232,7 @@ class Field
|
||||
* the modified field will be returned. Otherwise it
|
||||
* will return the field value.
|
||||
*
|
||||
* @param string|Closure $value
|
||||
* @param string|Closure $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function value($value = null)
|
||||
|
||||
@@ -231,12 +231,14 @@ class File extends ModelWithContent
|
||||
* gets dragged onto a textarea
|
||||
*
|
||||
* @internal
|
||||
* @param string $type (auto|kirbytext|markdown)
|
||||
* @param string $type (null|auto|kirbytext|markdown)
|
||||
* @param bool $absolute
|
||||
* @return string
|
||||
*/
|
||||
public function dragText($type = 'auto', bool $absolute = false): string
|
||||
public function dragText(string $type = null, bool $absolute = false): string
|
||||
{
|
||||
$type = $type ?? 'auto';
|
||||
|
||||
if ($type === 'auto') {
|
||||
$type = option('panel.kirbytext', true) ? 'kirbytext' : 'markdown';
|
||||
}
|
||||
@@ -363,14 +365,16 @@ class File extends ModelWithContent
|
||||
*/
|
||||
public function meta()
|
||||
{
|
||||
deprecated('$file->meta() is deprecated, use $file->content() instead. $file->meta() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->content();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file's last modification time.
|
||||
*
|
||||
* @param string $format
|
||||
* @param string|null $handler date or strftime
|
||||
* @param string $format
|
||||
* @param string|null $handler date or strftime
|
||||
* @return mixed
|
||||
*/
|
||||
public function modified(string $format = null, string $handler = null)
|
||||
@@ -392,7 +396,7 @@ class File extends ModelWithContent
|
||||
* Timestamp of the last modification
|
||||
* of the content file
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
protected function modifiedContent(): int
|
||||
{
|
||||
@@ -403,7 +407,7 @@ class File extends ModelWithContent
|
||||
* Timestamp of the last modification
|
||||
* of the source file
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
protected function modifiedFile(): int
|
||||
{
|
||||
|
||||
@@ -82,7 +82,7 @@ trait FileActions
|
||||
/**
|
||||
* Changes the file's sorting number in the meta file
|
||||
*
|
||||
* @param integer $sort
|
||||
* @param int $sort
|
||||
* @return self
|
||||
*/
|
||||
public function changeSort(int $sort)
|
||||
@@ -256,6 +256,8 @@ trait FileActions
|
||||
*/
|
||||
public function rename(string $name, bool $sanitize = true)
|
||||
{
|
||||
deprecated('$file->rename() is deprecated, use $file->changeName() instead. $file->rename() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->changeName($name, $sanitize);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class FileBlueprint extends Blueprint
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $accept
|
||||
* @param mixed $accept
|
||||
* @return array
|
||||
*/
|
||||
protected function normalizeAccept($accept = null): array
|
||||
|
||||
@@ -82,7 +82,7 @@ trait FileFoundation
|
||||
/**
|
||||
* Checks if the file exists on disk
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
@@ -102,7 +102,7 @@ trait FileFoundation
|
||||
/**
|
||||
* Converts the file to html
|
||||
*
|
||||
* @param array $attr
|
||||
* @param array $attr
|
||||
* @return string
|
||||
*/
|
||||
public function html(array $attr = []): string
|
||||
@@ -117,7 +117,7 @@ trait FileFoundation
|
||||
/**
|
||||
* Checks if the file is a resizable image
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isResizable(): bool
|
||||
{
|
||||
@@ -136,7 +136,7 @@ trait FileFoundation
|
||||
* Checks if a preview can be displayed for the file
|
||||
* in the panel or in the frontend
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isViewable(): bool
|
||||
{
|
||||
@@ -165,8 +165,8 @@ trait FileFoundation
|
||||
/**
|
||||
* Get the file's last modification time.
|
||||
*
|
||||
* @param string $format
|
||||
* @param string|null $handler date or strftime
|
||||
* @param string $format
|
||||
* @param string|null $handler date or strftime
|
||||
* @return mixed
|
||||
*/
|
||||
public function modified(string $format = null, string $handler = null)
|
||||
|
||||
@@ -18,7 +18,7 @@ trait FileModifications
|
||||
/**
|
||||
* Blurs the image by the given amount of pixels
|
||||
*
|
||||
* @param boolean $pixels
|
||||
* @param bool $pixels
|
||||
* @return \Kirby\Cms\FileVersion|\Kirby\Cms\File
|
||||
*/
|
||||
public function blur($pixels = true)
|
||||
@@ -39,8 +39,8 @@ trait FileModifications
|
||||
/**
|
||||
* Crops the image by the given width and height
|
||||
*
|
||||
* @param integer $width
|
||||
* @param integer $height
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param string|array $options
|
||||
* @return \Kirby\Cms\FileVersion|\Kirby\Cms\File
|
||||
*/
|
||||
@@ -71,7 +71,7 @@ trait FileModifications
|
||||
/**
|
||||
* Sets the JPEG compression quality
|
||||
*
|
||||
* @param integer $quality
|
||||
* @param int $quality
|
||||
* @return \Kirby\Cms\FileVersion|\Kirby\Cms\File
|
||||
*/
|
||||
public function quality(int $quality)
|
||||
@@ -83,9 +83,9 @@ trait FileModifications
|
||||
* Resizes the file with the given width and height
|
||||
* while keeping the aspect ratio.
|
||||
*
|
||||
* @param integer $width
|
||||
* @param integer $height
|
||||
* @param integer $quality
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param int $quality
|
||||
* @return \Kirby\Cms\FileVersion|\Kirby\Cms\File
|
||||
*/
|
||||
public function resize(int $width = null, int $height = null, int $quality = null)
|
||||
|
||||
73
kirby/src/Cms/FilePicker.php
Executable file
73
kirby/src/Cms/FilePicker.php
Executable file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* The FilePicker class helps to
|
||||
* fetch the right files for the API calls
|
||||
* for the file picker component in the panel.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier GmbH
|
||||
* @license https://getkirby.com/license
|
||||
*/
|
||||
class FilePicker extends Picker
|
||||
{
|
||||
/**
|
||||
* Extends the basic defaults
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function defaults(): array
|
||||
{
|
||||
$defaults = parent::defaults();
|
||||
$defaults['text'] = '{{ file.filename }}';
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all files for the picker
|
||||
*
|
||||
* @return \Kirby\Cms\Files|null
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
$model = $this->options['model'];
|
||||
|
||||
// find the right default query
|
||||
if (empty($this->options['query']) === false) {
|
||||
$query = $this->options['query'];
|
||||
} elseif (is_a($model, 'Kirby\Cms\File') === true) {
|
||||
$query = 'file.siblings';
|
||||
} else {
|
||||
$query = $model::CLASS_ALIAS . '.files';
|
||||
}
|
||||
|
||||
// fetch all files for the picker
|
||||
$files = $model->query($query);
|
||||
|
||||
// help mitigate some typical query usage issues
|
||||
// by converting site and page objects to proper
|
||||
// pages by returning their children
|
||||
if (is_a($files, 'Kirby\Cms\Site') === true) {
|
||||
$files = $files->files();
|
||||
} elseif (is_a($files, 'Kirby\Cms\Page') === true) {
|
||||
$files = $files->files();
|
||||
} elseif (is_a($files, 'Kirby\Cms\User') === true) {
|
||||
$files = $files->files();
|
||||
} elseif (is_a($files, 'Kirby\Cms\Files') === false) {
|
||||
throw new InvalidArgumentException('Your query must return a set of files');
|
||||
}
|
||||
|
||||
// search
|
||||
$files = $this->search($files);
|
||||
|
||||
// paginate
|
||||
return $this->paginate($files);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ class Filename
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $template
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(string $filename, string $template, array $attributes = [])
|
||||
{
|
||||
@@ -118,7 +118,7 @@ class Filename
|
||||
* to a string, that can be used in the
|
||||
* new filename
|
||||
*
|
||||
* @param string $prefix The prefix will be used in the filename creation
|
||||
* @param string $prefix The prefix will be used in the filename creation
|
||||
* @return string
|
||||
*/
|
||||
public function attributesToString(string $prefix = null): string
|
||||
@@ -265,7 +265,7 @@ class Filename
|
||||
* to lowercase and `jpeg` will be
|
||||
* replaced with `jpg`
|
||||
*
|
||||
* @param string $extension
|
||||
* @param string $extension
|
||||
* @return string
|
||||
*/
|
||||
protected function sanitizeExtension(string $extension): string
|
||||
@@ -279,7 +279,7 @@ class Filename
|
||||
* Sanitizes the name with Kirby's
|
||||
* Str::slug function
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function sanitizeName(string $name): string
|
||||
|
||||
@@ -157,7 +157,7 @@ trait HasChildren
|
||||
/**
|
||||
* Checks if the model has any children
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildren(): bool
|
||||
{
|
||||
@@ -167,7 +167,7 @@ trait HasChildren
|
||||
/**
|
||||
* Checks if the model has any drafts
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function hasDrafts(): bool
|
||||
{
|
||||
@@ -175,18 +175,20 @@ trait HasChildren
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::hasUnlistedChildren` instead
|
||||
* @return boolean
|
||||
* @deprecated 3.0.0 Use `Page::hasUnlistedChildren()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function hasInvisibleChildren(): bool
|
||||
{
|
||||
deprecated('$page->hasInvisibleChildren() is deprecated, use $page->hasUnlistedChildren() instead. $page->hasInvisibleChildren() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->hasUnlistedChildren();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page has any listed children
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function hasListedChildren(): bool
|
||||
{
|
||||
@@ -196,7 +198,7 @@ trait HasChildren
|
||||
/**
|
||||
* Checks if the page has any unlisted children
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUnlistedChildren(): bool
|
||||
{
|
||||
@@ -204,11 +206,13 @@ trait HasChildren
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::hasListedChildren` instead
|
||||
* @return boolean
|
||||
* @deprecated 3.0.0 Use `Page::hasListedChildren()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function hasVisibleChildren(): bool
|
||||
{
|
||||
deprecated('$page->hasVisibleChildren() is deprecated, use $page->hasListedChildren() instead. $page->hasVisibleChildren() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->hasListedChildren();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ trait HasMethods
|
||||
* passed arguments
|
||||
*
|
||||
* @internal
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return mixed
|
||||
*/
|
||||
public function callMethod(string $method, array $args = [])
|
||||
@@ -39,7 +39,7 @@ trait HasMethods
|
||||
*
|
||||
* @internal
|
||||
* @param string $method
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMethod(string $method): bool
|
||||
{
|
||||
|
||||
@@ -58,6 +58,11 @@ class Language extends Model
|
||||
*/
|
||||
protected $slugs;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
protected $smartypants;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
@@ -85,6 +90,7 @@ class Language extends Model
|
||||
'locale',
|
||||
'name',
|
||||
'slugs',
|
||||
'smartypants',
|
||||
'translations',
|
||||
'url',
|
||||
]);
|
||||
@@ -111,6 +117,28 @@ class Language extends Model
|
||||
return $this->code();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base Url for the language
|
||||
* without the path or other cruft
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function baseUrl(): string
|
||||
{
|
||||
$kirbyUrl = $this->kirby()->url();
|
||||
$languageUrl = $this->url();
|
||||
|
||||
if (empty($this->url)) {
|
||||
return $kirbyUrl;
|
||||
}
|
||||
|
||||
if (Str::startsWith($languageUrl, $kirbyUrl) === true) {
|
||||
return $kirbyUrl;
|
||||
}
|
||||
|
||||
return Url::base($languageUrl) ?? $kirbyUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language code/id.
|
||||
* The language code is used in
|
||||
@@ -129,7 +157,7 @@ class Language extends Model
|
||||
*
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
protected static function converter(string $from, string $to): bool
|
||||
{
|
||||
@@ -201,7 +229,7 @@ class Language extends Model
|
||||
* all its translation files
|
||||
*
|
||||
* @internal
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(): bool
|
||||
{
|
||||
@@ -270,7 +298,7 @@ class Language extends Model
|
||||
/**
|
||||
* Check if the language file exists
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
@@ -281,7 +309,7 @@ class Language extends Model
|
||||
* Checks if this is the default language
|
||||
* for the site.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isDefault(): bool
|
||||
{
|
||||
@@ -325,6 +353,20 @@ class Language extends Model
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL path for the language
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function path(): string
|
||||
{
|
||||
if ($this->url === null) {
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
return Url::path($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the routing pattern for the language
|
||||
*
|
||||
@@ -332,11 +374,13 @@ class Language extends Model
|
||||
*/
|
||||
public function pattern(): string
|
||||
{
|
||||
if (empty($this->url) === true) {
|
||||
return $this->code;
|
||||
$path = $this->path();
|
||||
|
||||
if (empty($path) === true) {
|
||||
return '(:all)';
|
||||
}
|
||||
|
||||
return trim($this->url, '/');
|
||||
return $path . '/(:all?)';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,7 +474,7 @@ class Language extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $default
|
||||
* @param bool $default
|
||||
* @return self
|
||||
*/
|
||||
protected function setDefault(bool $default = false)
|
||||
@@ -488,6 +532,16 @@ class Language extends Model
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $smartypants
|
||||
* @return self
|
||||
*/
|
||||
protected function setSmartypants(array $smartypants = null)
|
||||
{
|
||||
$this->smartypants = $smartypants ?? [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $translations
|
||||
* @return self
|
||||
@@ -518,6 +572,16 @@ class Language extends Model
|
||||
return $this->slugs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the custom SmartyPants options for this language
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function smartypants(): array
|
||||
{
|
||||
return $this->smartypants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most important
|
||||
* properties as array
|
||||
@@ -554,7 +618,13 @@ class Language extends Model
|
||||
*/
|
||||
public function url(): string
|
||||
{
|
||||
return Url::makeAbsolute($this->pattern(), $this->kirby()->url());
|
||||
$url = $this->url;
|
||||
|
||||
if ($url === null) {
|
||||
$url = '/' . $this->code;
|
||||
}
|
||||
|
||||
return Url::makeAbsolute($url, $this->kirby()->url());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
143
kirby/src/Cms/LanguageRoutes.php
Executable file
143
kirby/src/Cms/LanguageRoutes.php
Executable file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Toolkit\F;
|
||||
|
||||
class LanguageRoutes
|
||||
{
|
||||
/**
|
||||
* Creates all multi-language routes
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby
|
||||
* @return array
|
||||
*/
|
||||
public static function create(App $kirby): array
|
||||
{
|
||||
$routes = [];
|
||||
|
||||
// add the route for the home page
|
||||
$routes[] = static::home($kirby);
|
||||
|
||||
// Kirby's base url
|
||||
$baseurl = $kirby->url();
|
||||
|
||||
foreach ($kirby->languages() as $language) {
|
||||
|
||||
// ignore languages with a different base url
|
||||
if ($language->baseurl() !== $baseurl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$routes[] = [
|
||||
'pattern' => $language->pattern(),
|
||||
'method' => 'ALL',
|
||||
'env' => 'site',
|
||||
'action' => function ($path = null) use ($language) {
|
||||
if ($result = $language->router()->call($path)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// jump through to the fallback if nothing
|
||||
// can be found for this language
|
||||
$this->next();
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
$routes[] = static::fallback($kirby);
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the fallback route
|
||||
* for unprefixed default language URLs.
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby
|
||||
* @return array
|
||||
*/
|
||||
public static function fallback(App $kirby): array
|
||||
{
|
||||
return [
|
||||
'pattern' => '(:all)',
|
||||
'method' => 'ALL',
|
||||
'env' => 'site',
|
||||
'action' => function (string $path) use ($kirby) {
|
||||
|
||||
// check for content representations or files
|
||||
$extension = F::extension($path);
|
||||
|
||||
// try to redirect prefixed pages
|
||||
if (empty($extension) === true && $page = $kirby->page($path)) {
|
||||
$url = $kirby->request()->url([
|
||||
'query' => null,
|
||||
'params' => null,
|
||||
'fragment' => null
|
||||
]);
|
||||
|
||||
if ($url->toString() !== $page->url()) {
|
||||
return $kirby
|
||||
->response()
|
||||
->redirect($page->url());
|
||||
}
|
||||
}
|
||||
|
||||
return $kirby->defaultLanguage()->router()->call($path);
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the multi-language home page route
|
||||
*
|
||||
* @param \Kirby\Cms\App $kirby
|
||||
* @return array
|
||||
*/
|
||||
public static function home(App $kirby): array
|
||||
{
|
||||
// Multi-language home
|
||||
return [
|
||||
'pattern' => '',
|
||||
'method' => 'ALL',
|
||||
'env' => 'site',
|
||||
'action' => function () use ($kirby) {
|
||||
|
||||
// find all languages with the same base url as the current installation
|
||||
$languages = $kirby->languages()->filterBy('baseurl', $kirby->url());
|
||||
|
||||
// if there's no language with a matching base url,
|
||||
// redirect to the default language
|
||||
if ($languages->count() === 0) {
|
||||
return $kirby
|
||||
->response()
|
||||
->redirect($kirby->defaultLanguage()->url());
|
||||
}
|
||||
|
||||
// if there's just one language, we take that to render the home page
|
||||
if ($languages->count() === 1) {
|
||||
$currentLanguage = $languages->first();
|
||||
} else {
|
||||
$currentLanguage = $kirby->defaultLanguage();
|
||||
}
|
||||
|
||||
// language detection on the home page with / as URL
|
||||
if ($kirby->url() !== $currentLanguage->url()) {
|
||||
if ($kirby->option('languages.detect') === true) {
|
||||
return $kirby
|
||||
->response()
|
||||
->redirect($kirby->detectedLanguage()->url());
|
||||
}
|
||||
|
||||
return $kirby
|
||||
->response()
|
||||
->redirect($currentLanguage->url());
|
||||
}
|
||||
|
||||
// render the home page of the current language
|
||||
return $currentLanguage->router()->call();
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -72,11 +72,13 @@ class Languages extends Collection
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Languages::default()`instead
|
||||
* @deprecated 3.0.0 Use `Languages::default()` instead
|
||||
* @return \Kirby\Cms\Language|null
|
||||
*/
|
||||
public function findDefault()
|
||||
{
|
||||
deprecated('$languages->findDefault() is deprecated, use $languages->default() instead. $languages->findDefault() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->default();
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class Media
|
||||
*
|
||||
* @param string $src
|
||||
* @param string $dest
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function publish(string $src, string $dest): bool
|
||||
{
|
||||
|
||||
@@ -19,6 +19,14 @@ use Throwable;
|
||||
*/
|
||||
abstract class ModelWithContent extends Model
|
||||
{
|
||||
/**
|
||||
* Each model must define a CLASS_ALIAS
|
||||
* which will be used in template queries.
|
||||
* The CLASS_ALIAS is a short human-readable
|
||||
* version of the class name. I.e. page.
|
||||
*/
|
||||
const CLASS_ALIAS = null;
|
||||
|
||||
/**
|
||||
* The content
|
||||
*
|
||||
@@ -194,8 +202,8 @@ abstract class ModelWithContent extends Model
|
||||
* Decrement a given field value
|
||||
*
|
||||
* @param string $field
|
||||
* @param integer $by
|
||||
* @param integer $min
|
||||
* @param int $by
|
||||
* @param int $min
|
||||
* @return self
|
||||
*/
|
||||
public function decrement(string $field, int $by = 1, int $min = 0)
|
||||
@@ -231,8 +239,8 @@ abstract class ModelWithContent extends Model
|
||||
* Increment a given field value
|
||||
*
|
||||
* @param string $field
|
||||
* @param integer $by
|
||||
* @param integer $max
|
||||
* @param int $by
|
||||
* @param int $max
|
||||
* @return self
|
||||
*/
|
||||
public function increment(string $field, int $by = 1, int $max = null)
|
||||
@@ -246,10 +254,21 @@ abstract class ModelWithContent extends Model
|
||||
return $this->update([$field => $value]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the model is locked for the current user
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLocked(): bool
|
||||
{
|
||||
$lock = $this->lock();
|
||||
return $lock && $lock->isLocked() === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the data has any errors
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid(): bool
|
||||
{
|
||||
@@ -382,6 +401,38 @@ abstract class ModelWithContent extends Model
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all actions
|
||||
* that can be performed in the Panel
|
||||
* This also checks for the lock status
|
||||
*
|
||||
* @param array $unlock An array of options that will be force-unlocked
|
||||
* @return array
|
||||
*/
|
||||
public function panelOptions(array $unlock = []): array
|
||||
{
|
||||
$options = $this->permissions()->toArray();
|
||||
|
||||
if ($this->isLocked()) {
|
||||
foreach ($options as $key => $value) {
|
||||
if (in_array($key, $unlock)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$options[$key] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must return the permissions object for the model
|
||||
*
|
||||
* @return \Kirby\Cms\ModelPermissions
|
||||
*/
|
||||
abstract public function permissions();
|
||||
|
||||
/**
|
||||
* Creates a string query, starting from the model
|
||||
*
|
||||
@@ -618,7 +669,7 @@ abstract class ModelWithContent extends Model
|
||||
*
|
||||
* @param array $input
|
||||
* @param string $languageCode
|
||||
* @param boolean $validate
|
||||
* @param bool $validate
|
||||
* @return self
|
||||
*/
|
||||
public function update(array $input = null, string $languageCode = null, bool $validate = false)
|
||||
@@ -657,7 +708,7 @@ abstract class ModelWithContent extends Model
|
||||
* @internal
|
||||
* @param array $data
|
||||
* @param string $languageCode
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function writeContent(array $data, string $languageCode = null): bool
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ class NestCollection extends BaseCollection
|
||||
* to an array. This can also take a callback
|
||||
* function to further modify the array result.
|
||||
*
|
||||
* @param Closure $map
|
||||
* @param Closure $map
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(Closure $map = null): array
|
||||
|
||||
@@ -104,7 +104,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* The sorting number
|
||||
*
|
||||
* @var integer|null
|
||||
* @var int|null
|
||||
*/
|
||||
protected $num;
|
||||
|
||||
@@ -253,15 +253,14 @@ class Page extends ModelWithContent
|
||||
$templates = [];
|
||||
}
|
||||
|
||||
// add the current template to the array
|
||||
$templates[] = $currentTemplate;
|
||||
// add the current template to the array if it's not already there
|
||||
if (in_array($currentTemplate, $templates) === false) {
|
||||
array_unshift($templates, $currentTemplate);
|
||||
}
|
||||
|
||||
// make sure every template is only included once
|
||||
$templates = array_unique($templates);
|
||||
|
||||
// sort the templates
|
||||
asort($templates);
|
||||
|
||||
foreach ($templates as $template) {
|
||||
try {
|
||||
$props = Blueprint::load('pages/' . $template);
|
||||
@@ -352,7 +351,7 @@ class Page extends ModelWithContent
|
||||
* Returns a number indicating how deep the page
|
||||
* is nested within the content folder
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function depth(): int
|
||||
{
|
||||
@@ -408,11 +407,13 @@ class Page extends ModelWithContent
|
||||
* gets dragged onto a textarea
|
||||
*
|
||||
* @internal
|
||||
* @param string $type (auto|kirbytext|markdown)
|
||||
* @param string $type (null|auto|kirbytext|markdown)
|
||||
* @return string
|
||||
*/
|
||||
public function dragText(string $type = 'auto'): string
|
||||
public function dragText(string $type = null): string
|
||||
{
|
||||
$type = $type ?? 'auto';
|
||||
|
||||
if ($type === 'auto') {
|
||||
$type = option('panel.kirbytext', true) ? 'kirbytext' : 'markdown';
|
||||
}
|
||||
@@ -456,7 +457,7 @@ class Page extends ModelWithContent
|
||||
* Checks if the intended template
|
||||
* for the page exists.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTemplate(): bool
|
||||
{
|
||||
@@ -563,7 +564,7 @@ class Page extends ModelWithContent
|
||||
* Checks if the page is a direct or indirect ancestor of the given $page object
|
||||
*
|
||||
* @param Page $child
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isAncestorOf(Page $child): bool
|
||||
{
|
||||
@@ -575,7 +576,7 @@ class Page extends ModelWithContent
|
||||
* pages cache. This will also check if one
|
||||
* of the ignore rules from the config kick in.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isCacheable(): bool
|
||||
{
|
||||
@@ -628,12 +629,12 @@ class Page extends ModelWithContent
|
||||
* Checks if the page is a child of the given page
|
||||
*
|
||||
* @param \Kirby\Cms\Page|string $parent
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isChildOf($parent): bool
|
||||
{
|
||||
if ($parent = $this->parent()) {
|
||||
return $parent->is($parent);
|
||||
if ($parentObj = $this->parent()) {
|
||||
return $parentObj->is($parent);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -643,7 +644,7 @@ class Page extends ModelWithContent
|
||||
* Checks if the page is a descendant of the given page
|
||||
*
|
||||
* @param \Kirby\Cms\Page|string $parent
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isDescendantOf($parent): bool
|
||||
{
|
||||
@@ -661,7 +662,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Checks if the page is a descendant of the currently active page
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isDescendantOfActive(): bool
|
||||
{
|
||||
@@ -675,7 +676,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Checks if the current page is a draft
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isDraft(): bool
|
||||
{
|
||||
@@ -695,7 +696,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Check if the page can be read by the current user
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable(): bool
|
||||
{
|
||||
@@ -725,7 +726,7 @@ class Page extends ModelWithContent
|
||||
* home and error page to stop certain
|
||||
* actions. That's why there's a shortcut.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isHomeOrErrorPage(): bool
|
||||
{
|
||||
@@ -733,18 +734,20 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::isUnlisted()` intead
|
||||
* @deprecated 3.0.0 Use `Page::isUnlisted()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function isInvisible(): bool
|
||||
{
|
||||
deprecated('$page->isInvisible() is deprecated, use $page->isUnlisted() instead. $page->isInvisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->isUnlisted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page has a sorting number
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isListed(): bool
|
||||
{
|
||||
@@ -776,7 +779,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Checks if the page is sortable
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isSortable(): bool
|
||||
{
|
||||
@@ -786,7 +789,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Checks if the page has no sorting number
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isUnlisted(): bool
|
||||
{
|
||||
@@ -794,11 +797,13 @@ class Page extends ModelWithContent
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::isListed()` intead
|
||||
* @deprecated 3.0.0 Use `Page::isListed()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function isVisible(): bool
|
||||
{
|
||||
deprecated('$page->isVisible() is deprecated, use $page->isListed() instead. $page->isVisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->isListed();
|
||||
}
|
||||
|
||||
@@ -808,7 +813,7 @@ class Page extends ModelWithContent
|
||||
*
|
||||
* @internal
|
||||
* @param string $token
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isVerified(string $token = null)
|
||||
{
|
||||
@@ -884,7 +889,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Returns the sorting number
|
||||
*
|
||||
* @return integer|null
|
||||
* @return int|null
|
||||
*/
|
||||
public function num(): ?int
|
||||
{
|
||||
@@ -1099,7 +1104,7 @@ class Page extends ModelWithContent
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $contentType
|
||||
* @param integer $code
|
||||
* @param int $code
|
||||
* @return string
|
||||
*/
|
||||
public function render(array $data = [], $contentType = 'html'): string
|
||||
@@ -1241,7 +1246,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Sets the draft flag
|
||||
*
|
||||
* @param boolean $isDraft
|
||||
* @param bool $isDraft
|
||||
* @return self
|
||||
*/
|
||||
protected function setIsDraft(bool $isDraft = null)
|
||||
@@ -1253,7 +1258,7 @@ class Page extends ModelWithContent
|
||||
/**
|
||||
* Sets the sorting number
|
||||
*
|
||||
* @param integer $num
|
||||
* @param int $num
|
||||
* @return self
|
||||
*/
|
||||
protected function setNum(int $num = null)
|
||||
|
||||
@@ -160,7 +160,7 @@ trait PageActions
|
||||
* to either draft, listed or unlisted
|
||||
*
|
||||
* @param string $status "draft", "listed" or "unlisted"
|
||||
* @param integer $position Optional sorting number
|
||||
* @param int $position Optional sorting number
|
||||
* @return self
|
||||
*/
|
||||
public function changeStatus(string $status, int $position = null)
|
||||
@@ -462,8 +462,8 @@ trait PageActions
|
||||
* Create the sorting number for the page
|
||||
* depending on the blueprint settings
|
||||
*
|
||||
* @param integer $num
|
||||
* @return integer
|
||||
* @param int $num
|
||||
* @return int
|
||||
*/
|
||||
public function createNum(int $num = null): int
|
||||
{
|
||||
@@ -631,12 +631,13 @@ trait PageActions
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$this->children = null;
|
||||
$this->blueprint = null;
|
||||
$this->drafts = null;
|
||||
$this->files = null;
|
||||
$this->content = null;
|
||||
$this->inventory = null;
|
||||
$this->blueprint = null;
|
||||
$this->children = null;
|
||||
$this->content = null;
|
||||
$this->drafts = null;
|
||||
$this->files = null;
|
||||
$this->inventory = null;
|
||||
$this->translations = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -756,7 +757,7 @@ trait PageActions
|
||||
*
|
||||
* @param array $input
|
||||
* @param string $language
|
||||
* @param boolean $validate
|
||||
* @param bool $validate
|
||||
* @return self
|
||||
*/
|
||||
public function update(array $input = null, string $language = null, bool $validate = false)
|
||||
|
||||
@@ -75,7 +75,6 @@ class PageBlueprint extends Blueprint
|
||||
protected function normalizeNum($num): string
|
||||
{
|
||||
$aliases = [
|
||||
0 => 'zero',
|
||||
'0' => 'zero',
|
||||
'sort' => 'default',
|
||||
];
|
||||
@@ -185,7 +184,7 @@ class PageBlueprint extends Blueprint
|
||||
* button in the panel and redirects it to a
|
||||
* different URL if necessary.
|
||||
*
|
||||
* @return string|boolean
|
||||
* @return string|bool
|
||||
*/
|
||||
public function preview()
|
||||
{
|
||||
|
||||
264
kirby/src/Cms/PagePicker.php
Executable file
264
kirby/src/Cms/PagePicker.php
Executable file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* The PagePicker class helps to
|
||||
* fetch the right pages and the parent
|
||||
* model for the API calls for the
|
||||
* page picker component in the panel.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier GmbH
|
||||
* @license https://getkirby.com/license
|
||||
*/
|
||||
class PagePicker extends Picker
|
||||
{
|
||||
/**
|
||||
* @var \Kirby\Cms\Pages
|
||||
*/
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* @var \Kirby\Cms\Pages
|
||||
*/
|
||||
protected $itemsForQuery;
|
||||
|
||||
/**
|
||||
* @var \Kirby\Cms\Page|\Kirby\Cms\Site|null
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Extends the basic defaults
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function defaults(): array
|
||||
{
|
||||
return array_merge(parent::defaults(), [
|
||||
// Page ID of the selected parent. Used to navigate
|
||||
'parent' => null,
|
||||
// enable/disable subpage navigation
|
||||
'subpages' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent model object that
|
||||
* is currently selected in the page picker.
|
||||
* It normally starts at the site, but can
|
||||
* also be any subpage. When a query is given
|
||||
* and subpage navigation is deactivated,
|
||||
* there will be no model available at all.
|
||||
*
|
||||
* @return \Kirby\Cms\Page|\Kirby\Cms\Site|null
|
||||
*/
|
||||
public function model()
|
||||
{
|
||||
// no subpages navigation = no model
|
||||
if ($this->options['subpages'] === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// the model for queries is a bit more tricky to find
|
||||
if (empty($this->options['query']) === false) {
|
||||
return $this->modelForQuery();
|
||||
}
|
||||
|
||||
return $this->parent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a model object for the given
|
||||
* query, depending on the parent and subpages
|
||||
* options.
|
||||
*
|
||||
* @return \Kirby\Cms\Page|\Kirby\Cms\Site|null
|
||||
*/
|
||||
public function modelForQuery()
|
||||
{
|
||||
if ($this->options['subpages'] === true && empty($this->options['parent']) === false) {
|
||||
return $this->parent();
|
||||
}
|
||||
|
||||
if ($items = $this->items()) {
|
||||
return $items->parent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns basic information about the
|
||||
* parent model that is currently selected
|
||||
* in the page picker.
|
||||
*
|
||||
* @param \Kirby\Cms\Site|\Kirby\Cms\Page|null
|
||||
* @return array|null
|
||||
*/
|
||||
public function modelToArray($model = null): ?array
|
||||
{
|
||||
if ($model === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// the selected model is the site. there's nothing above
|
||||
if (is_a($model, 'Kirby\Cms\Site') === true) {
|
||||
return [
|
||||
'id' => null,
|
||||
'parent' => null,
|
||||
'title' => $model->title()->value()
|
||||
];
|
||||
}
|
||||
|
||||
// the top-most page has been reached
|
||||
// the missing id indicates that there's nothing above
|
||||
if ($model->id() === $this->start()->id()) {
|
||||
return [
|
||||
'id' => null,
|
||||
'parent' => null,
|
||||
'title' => $model->title()->value()
|
||||
];
|
||||
}
|
||||
|
||||
// the model is a regular page
|
||||
return [
|
||||
'id' => $model->id(),
|
||||
'parent' => $model->parentModel()->id(),
|
||||
'title' => $model->title()->value()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all pages for the picker
|
||||
*
|
||||
* @return \Kirby\Cms\Pages|null
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
// cache
|
||||
if ($this->items !== null) {
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
// no query? simple parent-based search for pages
|
||||
if (empty($this->options['query']) === true) {
|
||||
$items = $this->itemsForParent();
|
||||
|
||||
// when subpage navigation is enabled, a parent
|
||||
// might be passed in addition to the query.
|
||||
// The parent then takes priority.
|
||||
} elseif ($this->options['subpages'] === true && empty($this->options['parent']) === false) {
|
||||
$items = $this->itemsForParent();
|
||||
|
||||
// search by query
|
||||
} else {
|
||||
$items = $this->itemsForQuery();
|
||||
}
|
||||
|
||||
// filter protected pages
|
||||
$items = $items->filterBy('isReadable', true);
|
||||
|
||||
// search
|
||||
$items = $this->search($items);
|
||||
|
||||
// paginate the result
|
||||
return $this->items = $this->paginate($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for pages by parent
|
||||
*
|
||||
* @return \Kirby\Cms\Pages
|
||||
*/
|
||||
public function itemsForParent()
|
||||
{
|
||||
return $this->parent()->children();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for pages by query string
|
||||
*
|
||||
* @return \Kirby\Cms\Pages
|
||||
*/
|
||||
public function itemsForQuery()
|
||||
{
|
||||
// cache
|
||||
if ($this->itemsForQuery !== null) {
|
||||
return $this->itemsForQuery;
|
||||
}
|
||||
|
||||
$model = $this->options['model'];
|
||||
$items = $model->query($this->options['query']);
|
||||
|
||||
// help mitigate some typical query usage issues
|
||||
// by converting site and page objects to proper
|
||||
// pages by returning their children
|
||||
if (is_a($items, 'Kirby\Cms\Site') === true) {
|
||||
$items = $items->children();
|
||||
} elseif (is_a($items, 'Kirby\Cms\Page') === true) {
|
||||
$items = $items->children();
|
||||
} elseif (is_a($items, 'Kirby\Cms\Pages') === false) {
|
||||
throw new InvalidArgumentException('Your query must return a set of pages');
|
||||
}
|
||||
|
||||
return $this->itemsForQuery = $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent model.
|
||||
* The model will be used to fetch
|
||||
* subpages unless there's a specific
|
||||
* query to find pages instead.
|
||||
*
|
||||
* @return \Kirby\Cms\Page|\Kirby\Cms\Site
|
||||
*/
|
||||
public function parent()
|
||||
{
|
||||
if ($this->parent !== null) {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
return $this->parent = $this->kirby->page($this->options['parent']) ?? $this->site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the top-most model (page or site)
|
||||
* that can be accessed when navigating
|
||||
* through pages.
|
||||
*
|
||||
* @return \Kirby\Cms\Page|\Kirby\Cms\Site
|
||||
*/
|
||||
public function start()
|
||||
{
|
||||
if (empty($this->options['query']) === false) {
|
||||
if ($items = $this->itemsForQuery()) {
|
||||
return $items->parent();
|
||||
}
|
||||
|
||||
return $this->site;
|
||||
}
|
||||
|
||||
return $this->site;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an associative array
|
||||
* with all information for the picker.
|
||||
* This will be passed directly to the API.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$array = parent::toArray();
|
||||
$array['model'] = $this->modelToArray($this->model());
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
@@ -205,6 +205,12 @@ class PageRules
|
||||
|
||||
public static function create(Page $page): bool
|
||||
{
|
||||
if (Str::length($page->slug()) < 1) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'page.slug.invalid',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($page->exists() === true) {
|
||||
throw new DuplicateException([
|
||||
'key' => 'page.draft.duplicate',
|
||||
|
||||
@@ -14,11 +14,13 @@ namespace Kirby\Cms;
|
||||
trait PageSiblings
|
||||
{
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::hasNextUnlisted` instead
|
||||
* @return boolean
|
||||
* @deprecated 3.0.0 Use `Page::hasNextUnlisted()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNextInvisible(): bool
|
||||
{
|
||||
deprecated('$page->hasNextInvisible() is deprecated, use $page->hasNextUnlisted() instead. $page->hasNextInvisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->hasNextUnlisted();
|
||||
}
|
||||
|
||||
@@ -45,20 +47,24 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::hasNextListed` instead
|
||||
* @return boolean
|
||||
* @deprecated 3.0.0 Use `Page::hasNextListed()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNextVisible(): bool
|
||||
{
|
||||
deprecated('$page->hasNextVisible() is deprecated, use $page->hasNextListed() instead. $page->hasNextVisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->hasNextListed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::hasPrevUnlisted` instead
|
||||
* @return boolean
|
||||
* @deprecated 3.0.0 Use `Page::hasPrevUnlisted()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPrevInvisible(): bool
|
||||
{
|
||||
deprecated('$page->hasPrevInvisible() is deprecated, use $page->hasPrevUnlisted() instead. $page->hasPrevInvisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->hasPrevUnlisted();
|
||||
}
|
||||
|
||||
@@ -85,11 +91,13 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::hasPrevListed instead`
|
||||
* @return boolean
|
||||
* @deprecated 3.0.0 Use `Page::hasPrevListed()` instead
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPrevVisible(): bool
|
||||
{
|
||||
deprecated('$page->hasPrevVisible() is deprecated, use $page->hasPrevListed() instead. $page->hasPrevVisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->hasPrevListed();
|
||||
}
|
||||
|
||||
@@ -99,6 +107,8 @@ trait PageSiblings
|
||||
*/
|
||||
public function nextInvisible()
|
||||
{
|
||||
deprecated('$page->nextInvisible() is deprecated, use $page->nextUnlisted() instead. $page->nextInvisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->nextUnlisted();
|
||||
}
|
||||
|
||||
@@ -123,11 +133,13 @@ trait PageSiblings
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 3.0.0 Use `Page::prevListed()` instead
|
||||
* @deprecated 3.0.0 Use `Page::nextListed()` instead
|
||||
* @return self|null
|
||||
*/
|
||||
public function nextVisible()
|
||||
{
|
||||
deprecated('$page->nextVisible() is deprecated, use $page->nextListed() instead. $page->nextVisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->nextListed();
|
||||
}
|
||||
|
||||
@@ -137,6 +149,8 @@ trait PageSiblings
|
||||
*/
|
||||
public function prevInvisible()
|
||||
{
|
||||
deprecated('$page->prevInvisible() is deprecated, use $page->prevUnlisted() instead. $page->prevInvisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->prevUnlisted();
|
||||
}
|
||||
|
||||
@@ -166,6 +180,8 @@ trait PageSiblings
|
||||
*/
|
||||
public function prevVisible()
|
||||
{
|
||||
deprecated('$page->prevVisible() is deprecated, use $page->prevListed() instead. $page->prevVisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->prevListed();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* The `$pages` object refers to a
|
||||
* collection of pages. The pages in this
|
||||
@@ -55,6 +57,10 @@ class Pages extends Collection
|
||||
// add a page object
|
||||
} elseif (is_a($object, 'Kirby\Cms\Page') === true) {
|
||||
$this->__set($object->id(), $object);
|
||||
|
||||
// give a useful error message on invalid input
|
||||
} elseif (in_array($object, [null, false, true], true) !== true) {
|
||||
throw new InvalidArgumentException('You must pass a Page object to the Pages collection');
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -344,13 +350,15 @@ class Pages extends Collection
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated alias for Pages::unlisted()
|
||||
* @deprecated 3.0.0 Use `Pages::unlisted()` instead
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function invisible()
|
||||
{
|
||||
return $this->filterBy('isUnlisted', '==', true);
|
||||
deprecated('$pages->invisible() is deprecated, use $pages->unlisted() instead. $pages->invisible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->unlisted();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -428,6 +436,27 @@ class Pages extends Collection
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter all pages by excluding the given template
|
||||
*
|
||||
* @param string|array $templates
|
||||
* @return \Kirby\Cms\Pages
|
||||
*/
|
||||
public function notTemplate($templates)
|
||||
{
|
||||
if (empty($templates) === true) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (is_array($templates) === false) {
|
||||
$templates = [$templates];
|
||||
}
|
||||
|
||||
return $this->filter(function ($page) use ($templates) {
|
||||
return !in_array($page->intendedTemplate()->name(), $templates);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with all page numbers
|
||||
*
|
||||
@@ -480,12 +509,14 @@ class Pages extends Collection
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated alias for Pages::listed()
|
||||
* @deprecated 3.0.0 Use `Pages::listed()` instead
|
||||
*
|
||||
* @return \Kirby\Cms\Pages
|
||||
*/
|
||||
public function visible()
|
||||
{
|
||||
return $this->filterBy('isListed', '==', true);
|
||||
deprecated('$pages->visible() is deprecated, use $pages->listed() instead. $pages->visible() will be removed in Kirby 3.5.0.');
|
||||
|
||||
return $this->listed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +81,9 @@ class Pagination extends BasePagination
|
||||
}
|
||||
|
||||
if ($params['method'] === 'query') {
|
||||
$params['page'] = $params['page'] ?? $params['url']->query()->get($params['variable'], 1);
|
||||
$params['page'] = $params['page'] ?? $params['url']->query()->get($params['variable']);
|
||||
} else {
|
||||
$params['page'] = $params['page'] ?? $params['url']->params()->get($params['variable'], 1);
|
||||
$params['page'] = $params['page'] ?? $params['url']->params()->get($params['variable']);
|
||||
}
|
||||
|
||||
parent::__construct($params);
|
||||
|
||||
@@ -107,6 +107,7 @@ class Panel
|
||||
'pluginCss' => $plugins->url('css'),
|
||||
'pluginJs' => $plugins->url('js'),
|
||||
'panelUrl' => $uri->path()->toString(true) . '/',
|
||||
'nonce' => $kirby->nonce(),
|
||||
'options' => [
|
||||
'url' => $url,
|
||||
'site' => $kirby->url('index'),
|
||||
|
||||
176
kirby/src/Cms/Picker.php
Executable file
176
kirby/src/Cms/Picker.php
Executable file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
/**
|
||||
* The Picker abstract is the foundation
|
||||
* for the UserPicker, PagePicker and FilePicker
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier GmbH
|
||||
* @license https://getkirby.com/license
|
||||
*/
|
||||
abstract class Picker
|
||||
{
|
||||
/**
|
||||
* @var \Kirby\Cms\App
|
||||
*/
|
||||
protected $kirby;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* @var \Kirby\Cms\Site
|
||||
*/
|
||||
protected $site;
|
||||
|
||||
/**
|
||||
* Creates a new Picker instance
|
||||
*
|
||||
* @param array $params
|
||||
*/
|
||||
public function __construct(array $params = [])
|
||||
{
|
||||
$this->options = array_merge($this->defaults(), $params);
|
||||
$this->kirby = $this->options['model']->kirby();
|
||||
$this->site = $this->kirby->site();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the array of default values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function defaults(): array
|
||||
{
|
||||
// default params
|
||||
return [
|
||||
// image settings (ratio, cover, etc.)
|
||||
'image' => [],
|
||||
// query template for the info field
|
||||
'info' => false,
|
||||
// number of users displayed per pagination page
|
||||
'limit' => 20,
|
||||
// optional mapping function for the result array
|
||||
'map' => null,
|
||||
// the reference model
|
||||
'model' => site(),
|
||||
// current page when paginating
|
||||
'page' => 1,
|
||||
// a query string to fetch specific items
|
||||
'query' => null,
|
||||
// search query
|
||||
'search' => null,
|
||||
// query template for the text field
|
||||
'text' => null
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all items for the picker
|
||||
*
|
||||
* @return \Kirby\Cms\Collection|null
|
||||
*/
|
||||
abstract public function items();
|
||||
|
||||
/**
|
||||
* Converts all given items to an associative
|
||||
* array that is already optimized for the
|
||||
* panel picker component.
|
||||
*
|
||||
* @param \Kirby\Cms\Collection|null $items
|
||||
* @return array
|
||||
*/
|
||||
public function itemsToArray($items = null): array
|
||||
{
|
||||
if ($items === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($items as $index => $item) {
|
||||
if (empty($this->options['map']) === false) {
|
||||
$result[] = $this->options['map']($item);
|
||||
} else {
|
||||
$result[] = $item->panelPickerData([
|
||||
'image' => $this->options['image'],
|
||||
'info' => $this->options['info'],
|
||||
'model' => $this->options['model'],
|
||||
'text' => $this->options['text'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply pagination to the collection
|
||||
* of items according to the options.
|
||||
*
|
||||
* @param \Kirby\Cms\Collection $items
|
||||
* @return \Kirby\Cms\Collection
|
||||
*/
|
||||
public function paginate($items)
|
||||
{
|
||||
return $items->paginate([
|
||||
'limit' => $this->options['limit'],
|
||||
'page' => $this->options['page']
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the most relevant pagination
|
||||
* info as array
|
||||
*
|
||||
* @param \Kirby\Cms\Pagination $pagination
|
||||
* @return array
|
||||
*/
|
||||
public function paginationToArray(Pagination $pagination): array
|
||||
{
|
||||
return [
|
||||
'limit' => $pagination->limit(),
|
||||
'page' => $pagination->page(),
|
||||
'total' => $pagination->total()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search through the collection of items
|
||||
* if not deactivate in the options
|
||||
*
|
||||
* @param \Kirby\Cms\Collection $items
|
||||
* @return \Kirby\Cms\Collection
|
||||
*/
|
||||
public function search($items)
|
||||
{
|
||||
if (empty($this->options['search']) === false) {
|
||||
return $items->search($this->options['search']);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an associative array
|
||||
* with all information for the picker.
|
||||
* This will be passed directly to the API.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$items = $this->items();
|
||||
|
||||
return [
|
||||
'data' => $this->itemsToArray($items),
|
||||
'pagination' => $this->paginationToArray($items->pagination()),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class Responder
|
||||
/**
|
||||
* HTTP status code
|
||||
*
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
protected $code = null;
|
||||
|
||||
@@ -73,8 +73,8 @@ class Responder
|
||||
/**
|
||||
* Setter and getter for the status code
|
||||
*
|
||||
* @param integer $code
|
||||
* @return integer|self
|
||||
* @param int $code
|
||||
* @return int|self
|
||||
*/
|
||||
public function code(int $code = null)
|
||||
{
|
||||
@@ -156,7 +156,7 @@ class Responder
|
||||
* Shortcut to create a redirect response
|
||||
*
|
||||
* @param string|null $location
|
||||
* @param integer|null $code
|
||||
* @param int|null $code
|
||||
* @return self
|
||||
*/
|
||||
public function redirect(?string $location = null, ?int $code = null)
|
||||
|
||||
@@ -29,8 +29,8 @@ class Roles extends Collection
|
||||
*/
|
||||
public function canBeChanged()
|
||||
{
|
||||
if ($user = App::instance()->user()) {
|
||||
return $this->filter(function ($role) use ($user) {
|
||||
if (App::instance()->user()) {
|
||||
return $this->filter(function ($role) {
|
||||
$newUser = new User([
|
||||
'email' => 'test@getkirby.com',
|
||||
'role' => $role->id()
|
||||
@@ -52,8 +52,8 @@ class Roles extends Collection
|
||||
*/
|
||||
public function canBeCreated()
|
||||
{
|
||||
if ($user = App::instance()->user()) {
|
||||
return $this->filter(function ($role) use ($user) {
|
||||
if (App::instance()->user()) {
|
||||
return $this->filter(function ($role) {
|
||||
$newUser = new User([
|
||||
'email' => 'test@getkirby.com',
|
||||
'role' => $role->id()
|
||||
|
||||
@@ -73,6 +73,7 @@ class Search
|
||||
$keys[] = 'id';
|
||||
|
||||
if (is_a($item, 'Kirby\Cms\User') === true) {
|
||||
$keys[] = 'name';
|
||||
$keys[] = 'email';
|
||||
$keys[] = 'role';
|
||||
} elseif (is_a($item, 'Kirby\Cms\Page') === true) {
|
||||
|
||||
@@ -273,7 +273,7 @@ class Site extends ModelWithContent
|
||||
/**
|
||||
* Checks if the site exists on disk
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
@@ -391,7 +391,7 @@ class Site extends ModelWithContent
|
||||
* prop, the home page will be returned if
|
||||
* it can be found. (see `Site::homePage()`)
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
* @return \Kirby\Cms\Page|null
|
||||
*/
|
||||
public function page(string $path = null)
|
||||
@@ -645,8 +645,8 @@ class Site extends ModelWithContent
|
||||
* returns the current page
|
||||
*
|
||||
* @internal
|
||||
* @param string|\Kirby\Cms\Page $page
|
||||
* @param string|null $languageCode
|
||||
* @param string|\Kirby\Cms\Page $page
|
||||
* @param string|null $languageCode
|
||||
* @return \Kirby\Cms\Page
|
||||
*/
|
||||
public function visit($page, string $languageCode = null)
|
||||
|
||||
@@ -81,11 +81,12 @@ trait SiteActions
|
||||
*/
|
||||
public function purge()
|
||||
{
|
||||
$this->children = null;
|
||||
$this->blueprint = null;
|
||||
$this->files = null;
|
||||
$this->content = null;
|
||||
$this->inventory = null;
|
||||
$this->blueprint = null;
|
||||
$this->children = null;
|
||||
$this->content = null;
|
||||
$this->files = null;
|
||||
$this->inventory = null;
|
||||
$this->translations = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class SiteBlueprint extends Blueprint
|
||||
* button in the panel and redirects it to a
|
||||
* different URL if necessary.
|
||||
*
|
||||
* @return string|boolean
|
||||
* @return string|bool
|
||||
*/
|
||||
public function preview()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Exception\PermissionException;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/**
|
||||
* Validators for all site actions
|
||||
@@ -21,6 +23,10 @@ class SiteRules
|
||||
throw new PermissionException(['key' => 'site.changeTitle.permission']);
|
||||
}
|
||||
|
||||
if (Str::length($title) === 0) {
|
||||
throw new InvalidArgumentException(['key' => 'site.changeTitle.empty']);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ class System
|
||||
/**
|
||||
* Check for a writable accounts folder
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function accounts(): bool
|
||||
{
|
||||
@@ -89,7 +89,7 @@ class System
|
||||
/**
|
||||
* Check for a writable content folder
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function content(): bool
|
||||
{
|
||||
@@ -99,7 +99,7 @@ class System
|
||||
/**
|
||||
* Check for an existing curl extension
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function curl(): bool
|
||||
{
|
||||
@@ -165,7 +165,7 @@ class System
|
||||
* option must be explicitly set to true
|
||||
* to get the installer up and running.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isInstallable(): bool
|
||||
{
|
||||
@@ -175,7 +175,7 @@ class System
|
||||
/**
|
||||
* Check if Kirby is already installed
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isInstalled(): bool
|
||||
{
|
||||
@@ -185,7 +185,7 @@ class System
|
||||
/**
|
||||
* Check if this is a local installation
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isLocal(): bool
|
||||
{
|
||||
@@ -218,7 +218,7 @@ class System
|
||||
/**
|
||||
* Check if all tests pass
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isOk(): bool
|
||||
{
|
||||
@@ -318,7 +318,7 @@ class System
|
||||
/**
|
||||
* Check for an existing mbstring extension
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function mbString(): bool
|
||||
{
|
||||
@@ -328,7 +328,7 @@ class System
|
||||
/**
|
||||
* Check for a writable media folder
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function media(): bool
|
||||
{
|
||||
@@ -338,7 +338,7 @@ class System
|
||||
/**
|
||||
* Check for a valid PHP version
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function php(): bool
|
||||
{
|
||||
@@ -352,7 +352,7 @@ class System
|
||||
*
|
||||
* @param string $license
|
||||
* @param string $email
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function register(string $license = null, string $email = null): bool
|
||||
{
|
||||
@@ -404,7 +404,7 @@ class System
|
||||
/**
|
||||
* Check for a valid server environment
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function server(): bool
|
||||
{
|
||||
@@ -424,7 +424,7 @@ class System
|
||||
/**
|
||||
* Check for a writable sessions folder
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function sessions(): bool
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ class Template
|
||||
/**
|
||||
* Checks if the template exists
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
@@ -190,7 +190,7 @@ class Template
|
||||
/**
|
||||
* Checks if the template uses the default type
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function hasDefaultType(): bool
|
||||
{
|
||||
|
||||
@@ -248,7 +248,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Checks if the user exists
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
@@ -342,7 +342,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Checks if this user has the admin role
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isAdmin(): bool
|
||||
{
|
||||
@@ -353,7 +353,7 @@ class User extends ModelWithContent
|
||||
* Checks if the current user is the virtual
|
||||
* Kirby user
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isKirby(): bool
|
||||
{
|
||||
@@ -363,7 +363,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Checks if the current user is this user
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isLoggedIn(): bool
|
||||
{
|
||||
@@ -374,7 +374,7 @@ class User extends ModelWithContent
|
||||
* Checks if the user is the last one
|
||||
* with the admin role
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isLastAdmin(): bool
|
||||
{
|
||||
@@ -384,7 +384,7 @@ class User extends ModelWithContent
|
||||
/**
|
||||
* Checks if the user is the last user
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isLastUser(): bool
|
||||
{
|
||||
@@ -426,10 +426,16 @@ class User extends ModelWithContent
|
||||
*/
|
||||
public function loginPasswordless($session = null): void
|
||||
{
|
||||
$kirby = $this->kirby();
|
||||
|
||||
$session = $this->sessionFromOptions($session);
|
||||
|
||||
$kirby->trigger('user.login:before', $this, $session);
|
||||
|
||||
$session->regenerateToken(); // privilege change
|
||||
$session->data()->set('user.id', $this->id());
|
||||
|
||||
$kirby->trigger('user.login:after', $this, $session);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -440,16 +446,23 @@ class User extends ModelWithContent
|
||||
*/
|
||||
public function logout($session = null): void
|
||||
{
|
||||
$kirby = $this->kirby();
|
||||
$session = $this->sessionFromOptions($session);
|
||||
|
||||
$kirby->trigger('user.logout:before', $this, $session);
|
||||
|
||||
$session->data()->remove('user.id');
|
||||
|
||||
if ($session->data()->get() === []) {
|
||||
// session is now empty, we might as well destroy it
|
||||
$session->destroy();
|
||||
|
||||
$kirby->trigger('user.logout:after', $this, null);
|
||||
} else {
|
||||
// privilege change
|
||||
$session->regenerateToken();
|
||||
|
||||
$kirby->trigger('user.logout:after', $this, $session);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,7 +870,7 @@ class User extends ModelWithContent
|
||||
* Compares the given password with the stored one
|
||||
*
|
||||
* @param string $password
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*
|
||||
* @throws NotFoundException If the user has no password
|
||||
* @throws InvalidArgumentException If the entered password is not valid
|
||||
|
||||
@@ -293,7 +293,7 @@ trait UserActions
|
||||
* Writes the account information to disk
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
protected function writeCredentials(array $credentials): bool
|
||||
{
|
||||
|
||||
68
kirby/src/Cms/UserPicker.php
Executable file
68
kirby/src/Cms/UserPicker.php
Executable file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* The UserPicker class helps to
|
||||
* fetch the right files for the API calls
|
||||
* for the user picker component in the panel.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier GmbH
|
||||
* @license https://getkirby.com/license
|
||||
*/
|
||||
class UserPicker extends Picker
|
||||
{
|
||||
/**
|
||||
* Extends the basic defaults
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function defaults(): array
|
||||
{
|
||||
$defaults = parent::defaults();
|
||||
$defaults['text'] = '{{ user.username }}';
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search all users for the picker
|
||||
*
|
||||
* @return \Kirby\Cms\Users|null
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
$model = $this->options['model'];
|
||||
|
||||
// find the right default query
|
||||
if (empty($this->options['query']) === false) {
|
||||
$query = $this->options['query'];
|
||||
} elseif (is_a($model, 'Kirby\Cms\User') === true) {
|
||||
$query = 'user.siblings';
|
||||
} else {
|
||||
$query = 'kirby.users';
|
||||
}
|
||||
|
||||
// fetch all users for the picker
|
||||
$users = $model->query($query);
|
||||
|
||||
// catch invalid data
|
||||
if (is_a($users, 'Kirby\Cms\Users') === false) {
|
||||
throw new InvalidArgumentException('Your query must return a set of users');
|
||||
}
|
||||
|
||||
// search
|
||||
$users = $this->search($users);
|
||||
|
||||
// sort
|
||||
$users = $users->sortBy('username', 'asc');
|
||||
|
||||
// paginate
|
||||
return $this->paginate($users);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user