Upgrade to 3.6.5

This commit is contained in:
Bastian Allgeier
2022-04-19 14:59:34 +02:00
parent fee3f5253d
commit 5c64df9e2b
30 changed files with 266 additions and 279 deletions

View File

@@ -10,6 +10,7 @@ use Kirby\Exception\NotFoundException;
use Kirby\Filesystem\Dir;
use Kirby\Filesystem\F;
use Kirby\Http\Request;
use Kirby\Http\Response;
use Kirby\Http\Router;
use Kirby\Http\Server;
use Kirby\Http\Uri;
@@ -709,14 +710,25 @@ class App
return $this->io(new NotFoundException());
}
// Response Configuration
// (Modified) global response configuration, e.g. in routes
if (is_a($input, 'Kirby\Cms\Responder') === true) {
// return the passed object unmodified (without injecting headers
// from the global object) to allow a complete response override
// https://github.com/getkirby/kirby/pull/4144#issuecomment-1034766726
return $input->send();
}
// Responses
if (is_a($input, 'Kirby\Http\Response') === true) {
return $input;
$data = $input->toArray();
// inject headers from the global response configuration
// lazily (only if they are not already set);
// the case-insensitive nature of headers will be
// handled by PHP's `header()` function
$data['headers'] = array_merge($response->headers(), $data['headers']);
return new Response($data);
}
// Pages

View File

@@ -353,12 +353,12 @@ class File extends ModelWithContent
/**
* Get the file's last modification time.
*
* @param string|null $format
* @param string|null $handler date or strftime
* @param string|\IntlDateFormatter|null $format
* @param string|null $handler date, intl or strftime
* @param string|null $languageCode
* @return mixed
*/
public function modified(string $format = null, string $handler = null, string $languageCode = null)
public function modified($format = null, string $handler = null, string $languageCode = null)
{
$file = $this->modifiedFile();
$content = $this->modifiedContent($languageCode);

View File

@@ -80,15 +80,30 @@ class FileRules
*/
public static function create(File $file, BaseFile $upload): bool
{
// We want to ensure that we are not creating duplicate files.
// If a file with the same name already exists
if ($file->exists() === true) {
if ($file->sha1() !== $upload->sha1()) {
throw new DuplicateException([
'key' => 'file.duplicate',
'data' => [
'filename' => $file->filename()
]
]);
// $file will be based on the props of the new file,
// to compare templates, we need to get the props of
// the already existing file from meta content file
$existing = $file->parent()->file($file->filename());
// if the new upload is the exact same file
// and uses the same template, we can continue
if (
$file->sha1() === $upload->sha1() &&
$file->template() === $existing->template()
) {
return true;
}
// otherwise throw an error for duplicate file
throw new DuplicateException([
'key' => 'file.duplicate',
'data' => [
'filename' => $file->filename()
]
]);
}
if ($file->permissions()->create() !== true) {

View File

@@ -775,7 +775,11 @@ class Query
// apply it to the dataset and retrieve all rows. make sure to use Collection as the iterator to be able to attach the pagination object
$iterator = $this->iterator;
$collection = $this->offset($pagination->offset())->limit($pagination->limit())->iterator('Collection')->all();
$collection = $this
->offset($pagination->offset())
->limit($pagination->limit())
->iterator('Kirby\Toolkit\Collection')
->all();
$this->iterator($iterator);
@@ -968,6 +972,11 @@ class Query
$this->bindings($sql['bindings']);
} elseif (is_callable($args[0]) === true) {
$query = clone $this;
// since the callback uses its own where condition
// it is necessary to clear/reset the cloned where condition
$query->where = null;
call_user_func($args[0], $query);
// copy over the bindings from the nested query

View File

@@ -853,8 +853,14 @@ abstract class Sql
$query = [];
$bindings = [];
foreach ($values as $key => $value) {
$fields[] = $this->columnName($table, $key, $enforceQualified);
foreach ($values as $column => $value) {
$key = $this->columnName($table, $column, $enforceQualified);
if ($key === null) {
continue;
}
$fields[] = $key;
if (in_array($value, static::$literals, true) === true) {
$query[] = $value ?: 'null';
@@ -896,6 +902,10 @@ abstract class Sql
foreach ($values as $column => $value) {
$key = $this->columnName($table, $column, $enforceQualified);
if ($key === null) {
continue;
}
if (in_array($value, static::$literals, true) === true) {
$query[] = $key . ' = ' . ($value ?: 'null');
continue;

View File

@@ -137,7 +137,7 @@ class Sqlite extends Sql
public function tables(): array
{
return [
'query' => 'SELECT name FROM sqlite_master WHERE type = "table"',
'query' => 'SELECT name FROM sqlite_master WHERE type = "table" OR type = "view"',
'bindings' => []
];
}

View File

@@ -463,11 +463,11 @@ class F
* Get the file's last modification time.
*
* @param string $file
* @param string $format
* @param string $handler date or strftime
* @param string|\IntlDateFormatter|null $format
* @param string $handler date, intl or strftime
* @return mixed
*/
public static function modified(string $file, string $format = null, string $handler = 'date')
public static function modified(string $file, $format = null, string $handler = 'date')
{
if (file_exists($file) !== true) {
return false;

View File

@@ -372,11 +372,11 @@ class File
/**
* Returns the file's last modification time
*
* @param string $format
* @param string|null $handler date or strftime
* @param string|\IntlDateFormatter|null $format
* @param string|null $handler date, intl or strftime
* @return mixed
*/
public function modified(?string $format = null, ?string $handler = null)
public function modified($format = null, ?string $handler = null)
{
$kirby = $this->kirby();

View File

@@ -16,6 +16,11 @@ use Throwable;
*/
class File extends Model
{
/**
* @var \Kirby\Cms\File
*/
protected $model;
/**
* Breadcrumb array
*
@@ -423,11 +428,11 @@ class File extends Model
return [
'next' => function () use ($file, $siblings): ?array {
$next = $siblings->nth($siblings->indexOf($file) + 1);
return $next ? $next->panel()->toLink('filename') : null;
return $this->toPrevNextLink($next, 'filename');
},
'prev' => function () use ($file, $siblings): ?array {
$prev = $siblings->nth($siblings->indexOf($file) - 1);
return $prev ? $prev->panel()->toLink('filename') : null;
return $this->toPrevNextLink($prev, 'filename');
}
];
}

View File

@@ -3,6 +3,7 @@
namespace Kirby\Panel;
use Kirby\Form\Form;
use Kirby\Http\Uri;
use Kirby\Toolkit\A;
/**
@@ -387,6 +388,36 @@ abstract class Model
];
}
/**
* Returns link url and tooltip
* for optional sibling model and
* preserves tab selection
*
* @internal
*
* @param \Kirby\Cms\ModelWithContent|null $model
* @param string $tooltip
* @return array
*/
protected function toPrevNextLink($model = null, string $tooltip = 'title'): ?array
{
if ($model === null) {
return null;
}
$data = $model->panel()->toLink($tooltip);
if ($tab = get('tab')) {
$uri = new Uri($data['link'], [
'query' => ['tab' => $tab]
]);
$data['link'] = $uri->toString();
}
return $data;
}
/**
* Returns the url to the editing view
* in the Panel

View File

@@ -14,6 +14,11 @@ namespace Kirby\Panel;
*/
class Page extends Model
{
/**
* @var \Kirby\Cms\Page
*/
protected $model;
/**
* Breadcrumb array
*
@@ -309,14 +314,8 @@ class Page extends Model
};
return [
'next' => function () use ($siblings) {
$next = $siblings('next')->first();
return $next ? $next->panel()->toLink('title') : null;
},
'prev' => function () use ($siblings) {
$prev = $siblings('prev')->last();
return $prev ? $prev->panel()->toLink('title') : null;
}
'next' => fn () => $this->toPrevNextLink($siblings('next')->first()),
'prev' => fn () => $this->toPrevNextLink($siblings('prev')->last())
];
}

View File

@@ -14,6 +14,11 @@ namespace Kirby\Panel;
*/
class Site extends Model
{
/**
* @var \Kirby\Cms\Site
*/
protected $model;
/**
* Returns the setup for a dropdown option
* which is used in the changes dropdown

View File

@@ -14,6 +14,11 @@ namespace Kirby\Panel;
*/
class User extends Model
{
/**
* @var \Kirby\Cms\User
*/
protected $model;
/**
* Breadcrumb array
*
@@ -193,14 +198,8 @@ class User extends Model
$user = $this->model;
return [
'next' => function () use ($user) {
$next = $user->next();
return $next ? $next->panel()->toLink('username') : null;
},
'prev' => function () use ($user) {
$prev = $user->prev();
return $prev ? $prev->panel()->toLink('username') : null;
}
'next' => fn () => $this->toPrevNextLink($user->next(), 'username'),
'prev' => fn () => $this->toPrevNextLink($user->prev(), 'username')
];
}

View File

@@ -726,4 +726,37 @@ class A
return $array;
}
}
/**
* Filter the array using the given callback
* using both value and key
* @since 3.6.5
*
* @param array $array
* @param callable $callback
* @return array
*/
public static function filter(array $array, callable $callback): array
{
return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
}
/**
* Remove key(s) from an array
* @since 3.6.5
*
* @param array $array
* @param int|string|array $keys
* @return array
*/
public static function without(array $array, $keys): array
{
if (is_int($keys) || is_string($keys)) {
$keys = static::wrap($keys);
}
return static::filter($array, function ($value, $key) use ($keys) {
return in_array($key, $keys, true) === false;
});
}
}

View File

@@ -75,7 +75,12 @@ class Pagination
$params = [];
if (is_array($a) === true) {
if (is_a($a, static::class) === true) {
/**
* First argument is a pagination/self object
*/
return $a;
} elseif (is_array($a) === true) {
/**
* First argument is an option array

View File

@@ -2,7 +2,9 @@
namespace Kirby\Toolkit;
use DateTime;
use Exception;
use IntlDateFormatter;
use Kirby\Exception\InvalidArgumentException;
/**
@@ -264,17 +266,33 @@ class Str
* according to locale settings
*
* @param int|null $time
* @param string|null $format
* @param string $handler date or strftime
* @param string|\IntlDateFormatter|null $format
* @param string $handler date, intl or strftime
* @return string|int
*/
public static function date(?int $time = null, ?string $format = null, string $handler = 'date')
public static function date(?int $time = null, $format = null, string $handler = 'date')
{
if (is_null($format) === true) {
return $time;
}
// separately handle strftime to be able
// $format is an IntlDateFormatter instance
if (is_a($format, 'IntlDateFormatter') === true) {
return $format->format($time ?? time());
}
// `intl` handler
if ($handler === 'intl') {
$datetime = new DateTime();
if ($time !== null) {
$datetime->setTimestamp($time);
}
return IntlDateFormatter::formatObject($datetime, $format);
}
// handle `strftime` to be able
// to suppress deprecation warning
// TODO: remove strftime support for PHP 9.0
if ($handler === 'strftime') {