Upgrade to 4.4.0

This commit is contained in:
Bastian Allgeier
2024-09-12 14:43:02 +02:00
parent a955c7822e
commit 8bc7250b68
87 changed files with 637 additions and 352 deletions

View File

@@ -782,7 +782,7 @@ class App
if ($input instanceof Page) {
try {
$html = $input->render();
} catch (ErrorPageException $e) {
} catch (ErrorPageException|NotFoundException $e) {
return $this->io($e);
}

View File

@@ -190,8 +190,19 @@ trait AppErrors
protected function getAdditionalWhoopsHandler(): CallbackHandler
{
return new CallbackHandler(function ($exception, $inspector, $run) {
$this->trigger('system.exception', compact('exception'));
error_log($exception);
$isLogged = true;
// allow hook to modify whether the exception should be logged
$isLogged = $this->apply(
'system.exception',
compact('exception', 'isLogged'),
'isLogged'
);
if ($isLogged !== false) {
error_log($exception);
}
return Handler::DONE;
});
}

View File

@@ -624,7 +624,7 @@ class File extends ModelWithContent
* Page URL and the filename as a more stable
* alternative for the media URLs.
*/
public function previewUrl(): string
public function previewUrl(): string|null
{
$parent = $this->parent();
$url = Url::to($this->id());
@@ -633,6 +633,12 @@ class File extends ModelWithContent
case 'page':
$preview = $parent->blueprint()->preview();
// user has no permission to preview page,
// also return null for file preview
if ($preview === false) {
return null;
}
// the page has a custom preview setting,
// thus the file is only accessible through
// the direct media URL

View File

@@ -315,7 +315,7 @@ class FileRules
public static function validMime(File $file, string $mime = null): bool
{
// make it easier to compare the mime
$mime = strtolower($mime);
$mime = strtolower($mime ?? '');
if (empty($mime)) {
throw new InvalidArgumentException([

View File

@@ -7,6 +7,7 @@ use Kirby\Exception\NotFoundException;
use Kirby\Http\Router;
use Kirby\Toolkit\A;
use Kirby\Toolkit\Str;
use Kirby\Uuid\Uuid;
/**
* The language router is used internally
@@ -84,6 +85,27 @@ class LanguageRouter
}
}
// Language-specific UUID URLs
$routes[] = [
'pattern' => '@/(page|file)/(:all)',
'method' => 'ALL',
'env' => 'site',
'action' => function (string $languageCode, string $type, string $id) use ($kirby, $language) {
// try to resolve to model, but only from UUID cache;
// this ensures that only existing UUIDs can be queried
// and attackers can't force Kirby to go through the whole
// site index with a non-existing UUID
if ($model = Uuid::for($type . '://' . $id)?->model(true)) {
return $kirby
->response()
->redirect($model->url($language->code()));
}
// render the error page
return false;
}
];
return $routes;
}

View File

@@ -3,6 +3,7 @@
namespace Kirby\Cms;
use Kirby\Filesystem\F;
use Kirby\Toolkit\Str;
class LanguageRoutes
{
@@ -29,9 +30,26 @@ class LanguageRoutes
'pattern' => $language->pattern(),
'method' => 'ALL',
'env' => 'site',
'action' => function ($path = null) use ($language) {
'action' => function ($path = null) use ($kirby, $language) {
$result = $language->router()->call($path);
// redirect secondary-language pages that have
// been accessed with non-translated slugs in their path
// to their fully translated URL
if ($path !== null && $result instanceof Page) {
if (Str::endsWith($result->url(), $path) === false) {
$url = $result->url();
$query = $kirby->request()->query()->toString();
// preserve query across redirect
if (empty($query) === false) {
$url .= '?' . $query;
}
return $kirby->response()->redirect($url);
}
}
// explicitly test for null as $result can
// contain falsy values that should still be returned
if ($result !== null) {

View File

@@ -22,7 +22,7 @@ use Throwable;
*/
class License
{
protected const HISTORY = [
public const HISTORY = [
'3' => '2019-02-05',
'4' => '2023-11-28'
];

View File

@@ -43,8 +43,16 @@ abstract class ModelPermissions
return $this->toArray();
}
public function can(string $action): bool
{
/**
* Returns whether the current user is allowed to do
* a certain action on the model
*
* @param bool $default Will be returned if $action does not exist
*/
public function can(
string $action,
bool $default = false
): bool {
$user = $this->user->id();
$role = $this->user->role()->id();
@@ -95,12 +103,20 @@ abstract class ModelPermissions
}
}
return $this->permissions->for($this->category, $action);
return $this->permissions->for($this->category, $action, $default);
}
public function cannot(string $action): bool
{
return $this->can($action) === false;
/**
* Returns whether the current user is not allowed to do
* a certain action on the model
*
* @param bool $default Will be returned if $action does not exist
*/
public function cannot(
string $action,
bool $default = true
): bool {
return $this->can($action, !$default) === false;
}
public function toArray(): array

View File

@@ -180,7 +180,7 @@ class PageBlueprint extends Blueprint
return $this->model->toString($preview);
}
return $preview;
return $this->model->permissions()->can('preview', true);
}
/**

View File

@@ -110,18 +110,21 @@ class Permissions
}
}
public function for(string $category = null, string $action = null): bool
{
public function for(
string|null $category = null,
string|null $action = null,
bool $default = false
): bool {
if ($action === null) {
if ($this->hasCategory($category) === false) {
return false;
return $default;
}
return $this->actions[$category];
}
if ($this->hasAction($category, $action) === false) {
return false;
return $default;
}
return $this->actions[$category][$action];

View File

@@ -51,6 +51,6 @@ class SiteBlueprint extends Blueprint
return $this->model->toString($preview);
}
return $preview;
return $this->model->permissions()->can('preview', true);
}
}