ajout d'un toggle pour désactiver le bandeau du haut de la page
This commit is contained in:
parent
c5ae72945d
commit
f771bb3f24
95 changed files with 22574 additions and 1 deletions
243
kirby/src/Cms/ModelCommit.php
Normal file
243
kirby/src/Cms/ModelCommit.php
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Closure;
|
||||
use Kirby\Exception\Exception;
|
||||
|
||||
/**
|
||||
* The ModelCommit class is used to commit a given model action
|
||||
* in the model action classes. It takes care of running
|
||||
* the `before` and `after` hooks and updating the state
|
||||
* of the given model.
|
||||
*
|
||||
* @package Kirby Cms
|
||||
* @author Bastian Allgeier <bastian@getkirby.com>
|
||||
* @link https://getkirby.com
|
||||
* @copyright Bastian Allgeier
|
||||
* @license https://getkirby.com/license
|
||||
*/
|
||||
class ModelCommit
|
||||
{
|
||||
protected App $kirby;
|
||||
protected string $prefix;
|
||||
|
||||
public function __construct(
|
||||
protected ModelWithContent $model,
|
||||
protected string $action
|
||||
) {
|
||||
$this->kirby = $this->model->kirby();
|
||||
$this->prefix = $this->model::CLASS_ALIAS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the `after` hook and returns the result.
|
||||
*/
|
||||
public function after(mixed $state): mixed
|
||||
{
|
||||
// run the `after` hook
|
||||
$arguments = $this->afterHookArguments($state);
|
||||
$hook = $this->hook('after', $arguments);
|
||||
|
||||
// flush the page cache after any model action
|
||||
$this->kirby->cache('pages')->flush();
|
||||
|
||||
return $hook['result'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate arguments for the `after` hook
|
||||
* for the given model action. It's a wrapper around the
|
||||
* more specific `afterHookArgumentsFor*Actions` methods.
|
||||
*/
|
||||
public function afterHookArguments(mixed $state): array
|
||||
{
|
||||
return match (true) {
|
||||
$this->model instanceof File =>
|
||||
$this->afterHookArgumentsForFileActions($this->model, $this->action, $state),
|
||||
$this->model instanceof Page =>
|
||||
$this->afterHookArgumentsForPageActions($this->model, $this->action, $state),
|
||||
$this->model instanceof Site =>
|
||||
$this->afterHookArgumentsForSiteActions($this->model, $state),
|
||||
$this->model instanceof User =>
|
||||
$this->afterHookArgumentsForUserActions($this->model, $this->action, $state),
|
||||
default =>
|
||||
throw new Exception('Invalid model class')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate arguments for the `after` hook
|
||||
* for the given page action.
|
||||
*/
|
||||
protected function afterHookArgumentsForPageActions(
|
||||
Page $model,
|
||||
string $action,
|
||||
mixed $state
|
||||
): array {
|
||||
return match ($action) {
|
||||
'create' => [
|
||||
'page' => $state
|
||||
],
|
||||
'duplicate' => [
|
||||
'duplicatePage' => $state,
|
||||
'originalPage' => $model
|
||||
],
|
||||
'delete' => [
|
||||
'status' => $state,
|
||||
'page' => $model
|
||||
],
|
||||
default => [
|
||||
'newPage' => $state,
|
||||
'oldPage' => $model
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate arguments for the `after` hook
|
||||
* for the given file action.
|
||||
*/
|
||||
protected function afterHookArgumentsForFileActions(
|
||||
File $model,
|
||||
string $action,
|
||||
mixed $state
|
||||
): array {
|
||||
return match ($action) {
|
||||
'create' => [
|
||||
'file' => $state
|
||||
],
|
||||
'delete' => [
|
||||
'status' => $state,
|
||||
'file' => $model
|
||||
],
|
||||
default => [
|
||||
'newFile' => $state,
|
||||
'oldFile' => $model
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate arguments for the `after` hook
|
||||
* for the given site action.
|
||||
*/
|
||||
protected function afterHookArgumentsForSiteActions(
|
||||
Site $model,
|
||||
mixed $state
|
||||
): array {
|
||||
return [
|
||||
'newSite' => $state,
|
||||
'oldSite' => $model
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate arguments for the `after` hook
|
||||
* for the given user action.
|
||||
*/
|
||||
protected function afterHookArgumentsForUserActions(
|
||||
User $model,
|
||||
string $action,
|
||||
mixed $state
|
||||
): array {
|
||||
return match ($action) {
|
||||
'create' => [
|
||||
'user' => $state
|
||||
],
|
||||
'delete' => [
|
||||
'status' => $state,
|
||||
'user' => $model
|
||||
],
|
||||
default => [
|
||||
'newUser' => $state,
|
||||
'oldUser' => $model
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the `before` hook and modifies the arguments
|
||||
*/
|
||||
public function before(array $arguments): array
|
||||
{
|
||||
// check model rules
|
||||
$this->validate($arguments);
|
||||
|
||||
// run the `before` hook
|
||||
$hook = $this->hook('before', $arguments);
|
||||
|
||||
// check model rules again, after the hook got applied
|
||||
$this->validate($hook['arguments']);
|
||||
|
||||
return $hook['arguments'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the full call of the given action,
|
||||
* runs the `before` and `after` hooks and updates
|
||||
* the state of the given model.
|
||||
*/
|
||||
public function call(array $arguments, Closure $callback): mixed
|
||||
{
|
||||
// run the before hook
|
||||
$arguments = $this->before($arguments);
|
||||
|
||||
// run the commit action
|
||||
$state = $callback(...array_values($arguments));
|
||||
|
||||
// update the state for the after hook
|
||||
ModelState::update(
|
||||
method: $this->action,
|
||||
current: $this->model,
|
||||
next: $state
|
||||
);
|
||||
|
||||
// run the after hook and return the result
|
||||
return $this->after($state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given hook and modifies the first argument
|
||||
* of the given arguments array. It returns an array with
|
||||
* `arguments` and `result` keys.
|
||||
*/
|
||||
public function hook(string $hook, array $arguments): array
|
||||
{
|
||||
// the very first argument (which should be the model)
|
||||
// is modified by the return value from the hook (if any returned)
|
||||
$appliedTo = array_key_first($arguments);
|
||||
|
||||
// run the hook and modify the first argument
|
||||
$arguments[$appliedTo] = $this->kirby->apply(
|
||||
// e.g. page.create:before
|
||||
$this->prefix . '.' . $this->action . ':' . $hook,
|
||||
$arguments,
|
||||
$appliedTo
|
||||
);
|
||||
|
||||
return [
|
||||
'arguments' => $arguments,
|
||||
'result' => $arguments[$appliedTo],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the model rules for the given action
|
||||
* if there's a matching rule method.
|
||||
*/
|
||||
public function validate(array $arguments): void
|
||||
{
|
||||
$rules = match (true) {
|
||||
$this->model instanceof File => FileRules::class,
|
||||
$this->model instanceof Page => PageRules::class,
|
||||
$this->model instanceof Site => SiteRules::class,
|
||||
$this->model instanceof User => UserRules::class,
|
||||
default => throw new Exception('Invalid model class') // @codeCoverageIgnore
|
||||
};
|
||||
|
||||
if (method_exists($rules, $this->action) === true) {
|
||||
$rules::{$this->action}(...array_values($arguments));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue