Upgrade to 4.1.0
This commit is contained in:
@@ -655,7 +655,7 @@ class App
|
||||
* specified by the path
|
||||
*
|
||||
* Example:
|
||||
* <?= App::image('some/page/myimage.jpg') ?>
|
||||
* <?= $kirby->image('some/page/myimage.jpg') ?>
|
||||
*
|
||||
* @todo merge with App::file()
|
||||
*/
|
||||
@@ -831,9 +831,9 @@ class App
|
||||
}
|
||||
}
|
||||
|
||||
$data['kirby'] = $data['kirby'] ?? $this;
|
||||
$data['site'] = $data['site'] ?? $data['kirby']->site();
|
||||
$data['parent'] = $data['parent'] ?? $data['site']->page();
|
||||
$data['kirby'] ??= $this;
|
||||
$data['site'] ??= $data['kirby']->site();
|
||||
$data['parent'] ??= $data['site']->page();
|
||||
|
||||
return (new KirbyTag($type, $value, $attr, $data, $this->options))->render();
|
||||
}
|
||||
@@ -1464,9 +1464,7 @@ class App
|
||||
protected function setRoles(array $roles = null): static
|
||||
{
|
||||
if ($roles !== null) {
|
||||
$this->roles = Roles::factory($roles, [
|
||||
'kirby' => $this
|
||||
]);
|
||||
$this->roles = Roles::factory($roles);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -1480,9 +1478,7 @@ class App
|
||||
protected function setSite(Site|array $site = null): static
|
||||
{
|
||||
if (is_array($site) === true) {
|
||||
$site = new Site($site + [
|
||||
'kirby' => $this
|
||||
]);
|
||||
$site = new Site($site);
|
||||
}
|
||||
|
||||
$this->site = $site;
|
||||
@@ -1497,7 +1493,6 @@ class App
|
||||
return $this->site ??= new Site([
|
||||
'errorPageId' => $this->options['error'] ?? 'error',
|
||||
'homePageId' => $this->options['home'] ?? 'home',
|
||||
'kirby' => $this,
|
||||
'url' => $this->url('index'),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -86,9 +86,7 @@ trait AppUsers
|
||||
protected function setUsers(array $users = null): static
|
||||
{
|
||||
if ($users !== null) {
|
||||
$this->users = Users::factory($users, [
|
||||
'kirby' => $this
|
||||
]);
|
||||
$this->users = Users::factory($users);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -128,7 +126,6 @@ trait AppUsers
|
||||
{
|
||||
return $this->users ??= Users::load(
|
||||
$this->root('accounts'),
|
||||
['kirby' => $this]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,6 +696,10 @@ class Blueprint
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->sections[$name] instanceof Section) {
|
||||
return $this->sections[$name]; //@codeCoverageIgnore
|
||||
}
|
||||
|
||||
// get all props
|
||||
$props = $this->sections[$name];
|
||||
|
||||
@@ -703,7 +707,7 @@ class Blueprint
|
||||
$props['model'] = $this->model();
|
||||
|
||||
// create a new section object
|
||||
return new Section($props['type'], $props);
|
||||
return $this->sections[$name] = new Section($props['type'], $props);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -713,7 +717,10 @@ class Blueprint
|
||||
{
|
||||
return A::map(
|
||||
$this->sections,
|
||||
fn ($section) => $this->section($section['name'])
|
||||
fn ($section) => match (true) {
|
||||
$section instanceof Section => $section,
|
||||
default => $this->section($section['name'])
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,11 @@ use Kirby\Form\Field\LayoutField;
|
||||
*/
|
||||
class Core
|
||||
{
|
||||
/**
|
||||
* Optional override for the auto-detected index root
|
||||
*/
|
||||
public static string|null $indexRoot = null;
|
||||
|
||||
protected array $cache = [];
|
||||
protected string $root;
|
||||
|
||||
@@ -316,7 +321,7 @@ class Core
|
||||
'i18n:translations' => fn (array $roots) => $roots['i18n'] . '/translations',
|
||||
'i18n:rules' => fn (array $roots) => $roots['i18n'] . '/rules',
|
||||
|
||||
'index' => fn (array $roots) => dirname(__DIR__, 3),
|
||||
'index' => fn (array $roots) => static::$indexRoot ?? dirname(__DIR__, 3),
|
||||
'assets' => fn (array $roots) => $roots['index'] . '/assets',
|
||||
'content' => fn (array $roots) => $roots['index'] . '/content',
|
||||
'media' => fn (array $roots) => $roots['index'] . '/media',
|
||||
|
||||
@@ -229,9 +229,25 @@ trait FileActions
|
||||
// gather content
|
||||
$content = $props['content'] ?? [];
|
||||
|
||||
// make sure that a UUID gets generated and
|
||||
// added to content right away
|
||||
if (Uuids::enabled() === true) {
|
||||
// make sure that a UUID gets generated
|
||||
// and added to content right away
|
||||
if (
|
||||
Uuids::enabled() === true &&
|
||||
empty($content['uuid']) === true
|
||||
) {
|
||||
// sets the current uuid if it is the exact same file
|
||||
if ($file->exists() === true) {
|
||||
$existing = $file->parent()->file($file->filename());
|
||||
|
||||
if (
|
||||
$file->sha1() === $upload->sha1() &&
|
||||
$file->template() === $existing->template()
|
||||
) {
|
||||
// use existing content data if it is the exact same file
|
||||
$content = $existing->content()->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
$content['uuid'] ??= Uuid::generate();
|
||||
}
|
||||
|
||||
|
||||
@@ -90,11 +90,9 @@ class Files extends Collection
|
||||
public static function factory(array $files, Page|Site|User $parent): static
|
||||
{
|
||||
$collection = new static([], $parent);
|
||||
$kirby = $parent->kirby();
|
||||
|
||||
foreach ($files as $props) {
|
||||
$props['collection'] = $collection;
|
||||
$props['kirby'] = $kirby;
|
||||
$props['parent'] = $parent;
|
||||
|
||||
$file = File::factory($props);
|
||||
|
||||
@@ -135,9 +135,14 @@ class Helpers
|
||||
return true;
|
||||
});
|
||||
|
||||
$result = $action();
|
||||
|
||||
restore_error_handler();
|
||||
try {
|
||||
$result = $action();
|
||||
} finally {
|
||||
// always restore the error handler, even if the
|
||||
// action or the standard error handler threw an
|
||||
// exception; this avoids modifying global state
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
return $override ?? $result;
|
||||
}
|
||||
|
||||
@@ -49,9 +49,11 @@ class License
|
||||
/**
|
||||
* Returns the activation date if available
|
||||
*/
|
||||
public function activation(string|IntlDateFormatter|null $format = null): int|string|null
|
||||
{
|
||||
return $this->activation !== null ? Str::date(strtotime($this->activation), $format) : null;
|
||||
public function activation(
|
||||
string|IntlDateFormatter|null $format = null,
|
||||
string|null $handler = null
|
||||
): int|string|null {
|
||||
return $this->activation !== null ? Str::date(strtotime($this->activation), $format, $handler) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,9 +87,11 @@ class License
|
||||
/**
|
||||
* Returns the purchase date if available
|
||||
*/
|
||||
public function date(string|IntlDateFormatter|null $format = null): int|string|null
|
||||
{
|
||||
return $this->date !== null ? Str::date(strtotime($this->date), $format) : null;
|
||||
public function date(
|
||||
string|IntlDateFormatter|null $format = null,
|
||||
string|null $handler = null
|
||||
): int|string|null {
|
||||
return $this->date !== null ? Str::date(strtotime($this->date), $format, $handler) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -355,14 +359,16 @@ class License
|
||||
/**
|
||||
* Returns the renewal date
|
||||
*/
|
||||
public function renewal(string|IntlDateFormatter|null $format = null): int|string|null
|
||||
{
|
||||
public function renewal(
|
||||
string|IntlDateFormatter|null $format = null,
|
||||
string|null $handler = null
|
||||
): int|string|null {
|
||||
if ($this->activation === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$time = strtotime('+3 years', $this->activation());
|
||||
return Str::date($time, $format);
|
||||
return Str::date($time, $format, $handler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -784,10 +784,17 @@ abstract class ModelWithContent implements Identifiable
|
||||
]);
|
||||
}
|
||||
|
||||
$arguments = [static::CLASS_ALIAS => $this, 'values' => $form->data(), 'strings' => $form->strings(), 'languageCode' => $languageCode];
|
||||
return $this->commit('update', $arguments, function ($model, $values, $strings, $languageCode) {
|
||||
return $model->save($strings, $languageCode, true);
|
||||
});
|
||||
return $this->commit(
|
||||
'update',
|
||||
[
|
||||
static::CLASS_ALIAS => $this,
|
||||
'values' => $form->data(),
|
||||
'strings' => $form->strings(),
|
||||
'languageCode' => $languageCode
|
||||
],
|
||||
fn ($model, $values, $strings, $languageCode) =>
|
||||
$model->save($strings, $languageCode, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -282,10 +282,16 @@ trait PageActions
|
||||
return $this;
|
||||
}
|
||||
|
||||
$arguments = ['page' => $this, 'status' => 'listed', 'position' => $num];
|
||||
$page = $this->commit('changeStatus', $arguments, function ($page, $status, $position) {
|
||||
return $page->publish()->changeNum($position);
|
||||
});
|
||||
$page = $this->commit(
|
||||
'changeStatus',
|
||||
[
|
||||
'page' => $this,
|
||||
'status' => 'listed',
|
||||
'position' => $num
|
||||
],
|
||||
fn ($page, $status, $position) =>
|
||||
$page->publish()->changeNum($position)
|
||||
);
|
||||
|
||||
if ($this->blueprint()->num() === 'default') {
|
||||
$page->resortSiblingsAfterListing($num);
|
||||
@@ -303,10 +309,15 @@ trait PageActions
|
||||
return $this;
|
||||
}
|
||||
|
||||
$arguments = ['page' => $this, 'status' => 'unlisted', 'position' => null];
|
||||
$page = $this->commit('changeStatus', $arguments, function ($page) {
|
||||
return $page->publish()->changeNum(null);
|
||||
});
|
||||
$page = $this->commit(
|
||||
'changeStatus',
|
||||
[
|
||||
'page' => $this,
|
||||
'status' => 'unlisted',
|
||||
'position' => null
|
||||
],
|
||||
fn ($page) => $page->publish()->changeNum(null)
|
||||
);
|
||||
|
||||
$this->resortSiblingsAfterUnlisting();
|
||||
|
||||
@@ -355,7 +366,19 @@ trait PageActions
|
||||
string $title,
|
||||
string|null $languageCode = null
|
||||
): static {
|
||||
// if the `$languageCode` argument is not set and is not the default language
|
||||
// the `$languageCode` argument is sent as the current language
|
||||
if (
|
||||
$languageCode === null &&
|
||||
$language = $this->kirby()->language()
|
||||
) {
|
||||
if ($language->isDefault() === false) {
|
||||
$languageCode = $language->code();
|
||||
}
|
||||
}
|
||||
|
||||
$arguments = ['page' => $this, 'title' => $title, 'languageCode' => $languageCode];
|
||||
|
||||
return $this->commit('changeTitle', $arguments, function ($page, $title, $languageCode) {
|
||||
$page = $page->save(['title' => $title], $languageCode);
|
||||
|
||||
|
||||
@@ -147,7 +147,6 @@ class Pages extends Collection
|
||||
): static {
|
||||
$model ??= App::instance()->site();
|
||||
$children = new static([], $model);
|
||||
$kirby = $model->kirby();
|
||||
|
||||
if ($model instanceof Page) {
|
||||
$parent = $model;
|
||||
@@ -158,7 +157,6 @@ class Pages extends Collection
|
||||
}
|
||||
|
||||
foreach ($pages as $props) {
|
||||
$props['kirby'] = $kirby;
|
||||
$props['parent'] = $parent;
|
||||
$props['site'] = $site;
|
||||
$props['isDraft'] = $draft ?? $props['isDraft'] ?? $props['draft'] ?? false;
|
||||
@@ -445,9 +443,10 @@ class Pages extends Collection
|
||||
$templates = [$templates];
|
||||
}
|
||||
|
||||
return $this->filter(function ($page) use ($templates) {
|
||||
return !in_array($page->intendedTemplate()->name(), $templates);
|
||||
});
|
||||
return $this->filter(
|
||||
fn ($page) =>
|
||||
!in_array($page->intendedTemplate()->name(), $templates)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -480,9 +479,10 @@ class Pages extends Collection
|
||||
$templates = [$templates];
|
||||
}
|
||||
|
||||
return $this->filter(function ($page) use ($templates) {
|
||||
return in_array($page->intendedTemplate()->name(), $templates);
|
||||
});
|
||||
return $this->filter(
|
||||
fn ($page) =>
|
||||
in_array($page->intendedTemplate()->name(), $templates)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,15 +49,26 @@ trait SiteActions
|
||||
*/
|
||||
public function changeTitle(
|
||||
string $title,
|
||||
string $languageCode = null
|
||||
string|null $languageCode = null
|
||||
): static {
|
||||
$site = $this;
|
||||
$title = trim($title);
|
||||
$arguments = compact('site', 'title', 'languageCode');
|
||||
// if the `$languageCode` argument is not set and is not the default language
|
||||
// the `$languageCode` argument is sent as the current language
|
||||
if (
|
||||
$languageCode === null &&
|
||||
$language = $this->kirby()->language()
|
||||
) {
|
||||
if ($language->isDefault() === false) {
|
||||
$languageCode = $language->code();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->commit('changeTitle', $arguments, function ($site, $title, $languageCode) {
|
||||
return $site->save(['title' => $title], $languageCode);
|
||||
});
|
||||
$arguments = ['site' => $this, 'title' => trim($title), 'languageCode' => $languageCode];
|
||||
|
||||
return $this->commit(
|
||||
'changeTitle',
|
||||
$arguments,
|
||||
fn ($site, $title, $languageCode) => $site->save(['title' => $title], $languageCode)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,13 +33,17 @@ class Structure extends Items
|
||||
array $items = null,
|
||||
array $params = []
|
||||
): static {
|
||||
// Bake-in index as ID for all items
|
||||
// TODO: remove when adding UUID supports to Structures
|
||||
if (is_array($items) === true) {
|
||||
$items = array_map(function ($item, $index) {
|
||||
if (is_array($item) === true) {
|
||||
// pass a clean content array without special `Item` keys
|
||||
$item['content'] = $item;
|
||||
|
||||
// bake-in index as ID for all items
|
||||
// TODO: remove when adding UUID supports to Structures
|
||||
$item['id'] ??= $index;
|
||||
}
|
||||
|
||||
return $item;
|
||||
}, $items, array_keys($items));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user