Upgrade to 3.3.4
This commit is contained in:
@@ -18,6 +18,7 @@ class FileCache extends Cache
|
||||
{
|
||||
/**
|
||||
* Full root including prefix
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $root;
|
||||
@@ -49,6 +50,16 @@ class FileCache extends Cache
|
||||
Dir::make($this->root, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full root including prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function root(): string
|
||||
{
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full path to a file for a given key
|
||||
*
|
||||
|
@@ -198,22 +198,16 @@ class Blueprint
|
||||
return $props;
|
||||
}
|
||||
|
||||
$mixin = static::find($extends);
|
||||
|
||||
if ($mixin === null) {
|
||||
$props = $props;
|
||||
} elseif (is_array($mixin) === true) {
|
||||
try {
|
||||
$mixin = static::find($extends);
|
||||
$props = A::merge($mixin, $props, A::MERGE_REPLACE);
|
||||
} else {
|
||||
try {
|
||||
$props = A::merge(Data::read($mixin), $props, A::MERGE_REPLACE);
|
||||
} catch (Exception $e) {
|
||||
$props = $props;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// keep the props unextended if the snippet wasn't found
|
||||
}
|
||||
|
||||
// remove the extends flag
|
||||
unset($props['extends']);
|
||||
|
||||
return $props;
|
||||
}
|
||||
|
||||
@@ -268,22 +262,32 @@ class Blueprint
|
||||
* Find a blueprint by name
|
||||
*
|
||||
* @param string $name
|
||||
* @return string|array
|
||||
* @return array
|
||||
*/
|
||||
public static function find(string $name)
|
||||
public static function find(string $name): array
|
||||
{
|
||||
if (isset(static::$loaded[$name]) === true) {
|
||||
return static::$loaded[$name];
|
||||
}
|
||||
|
||||
$kirby = App::instance();
|
||||
$root = $kirby->root('blueprints');
|
||||
$file = $root . '/' . $name . '.yml';
|
||||
|
||||
if (F::exists($file, $root) === true) {
|
||||
return $file;
|
||||
// first try to find a site blueprint,
|
||||
// then check in the plugin extensions
|
||||
if (F::exists($file, $root) !== true) {
|
||||
$file = $kirby->extension('blueprints', $name);
|
||||
}
|
||||
|
||||
if ($blueprint = $kirby->extension('blueprints', $name)) {
|
||||
return $blueprint;
|
||||
// now ensure that we always return the data array
|
||||
if (is_string($file) === true && F::exists($file) === true) {
|
||||
return static::$loaded[$name] = Data::read($file);
|
||||
} elseif (is_array($file) === true) {
|
||||
return static::$loaded[$name] = $file;
|
||||
}
|
||||
|
||||
// neither a valid file nor array data
|
||||
throw new NotFoundException([
|
||||
'key' => 'blueprint.notFound',
|
||||
'data' => ['name' => $name]
|
||||
@@ -320,13 +324,9 @@ class Blueprint
|
||||
*/
|
||||
public static function load(string $name): array
|
||||
{
|
||||
if (isset(static::$loaded[$name]) === true) {
|
||||
return static::$loaded[$name];
|
||||
}
|
||||
$props = static::find($name);
|
||||
|
||||
$props = static::find($name);
|
||||
$normalize = function ($props) use ($name) {
|
||||
|
||||
// inject the filename as name if no name is set
|
||||
$props['name'] = $props['name'] ?? $name;
|
||||
|
||||
@@ -339,14 +339,7 @@ class Blueprint
|
||||
return $props;
|
||||
};
|
||||
|
||||
if (is_array($props) === true) {
|
||||
return $normalize($props);
|
||||
}
|
||||
|
||||
$file = $props;
|
||||
$props = Data::read($file);
|
||||
|
||||
return static::$loaded[$name] = $normalize($props);
|
||||
return $normalize($props);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -40,6 +40,24 @@ class ContentLock
|
||||
$this->data = $this->kirby()->locks()->get($model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the lock unconditionally
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function clearLock(): bool
|
||||
{
|
||||
// if no lock exists, skip
|
||||
if (isset($this->data['lock']) === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// remove lock
|
||||
unset($this->data['lock']);
|
||||
|
||||
return $this->kirby()->locks()->set($this->model, $this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets lock with the current user
|
||||
*
|
||||
@@ -74,19 +92,20 @@ class ContentLock
|
||||
{
|
||||
$data = $this->data['lock'] ?? [];
|
||||
|
||||
if (
|
||||
empty($data) === false &&
|
||||
$data['user'] !== $this->user()->id() &&
|
||||
$user = $this->kirby()->user($data['user'])
|
||||
) {
|
||||
$time = (int)($data['time']);
|
||||
if (empty($data) === false && $data['user'] !== $this->user()->id()) {
|
||||
if ($user = $this->kirby()->user($data['user'])) {
|
||||
$time = (int)($data['time']);
|
||||
|
||||
return [
|
||||
'user' => $user->id(),
|
||||
'email' => $user->email(),
|
||||
'time' => $time,
|
||||
'unlockable' => ($time + 60) <= time()
|
||||
];
|
||||
return [
|
||||
'user' => $user->id(),
|
||||
'email' => $user->email(),
|
||||
'time' => $time,
|
||||
'unlockable' => ($time + 60) <= time()
|
||||
];
|
||||
}
|
||||
|
||||
// clear lock if user not found
|
||||
$this->clearLock();
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -150,10 +169,7 @@ class ContentLock
|
||||
]);
|
||||
}
|
||||
|
||||
// remove lock
|
||||
unset($this->data['lock']);
|
||||
|
||||
return $this->kirby()->locks()->set($this->model, $this->data);
|
||||
return $this->clearLock();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,10 +209,7 @@ class ContentLock
|
||||
$this->data['unlock'] = $this->data['unlock'] ?? [];
|
||||
$this->data['unlock'][] = $this->data['lock']['user'];
|
||||
|
||||
// remove lock
|
||||
unset($this->data['lock']);
|
||||
|
||||
return $this->kirby()->locks()->set($this->model, $this->data);
|
||||
return $this->clearLock();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -364,7 +364,7 @@ class Language extends Model
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
return Url::path($this->url());
|
||||
return Url::path($this->url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -636,9 +636,17 @@ class Language extends Model
|
||||
*/
|
||||
public function update(array $props = null)
|
||||
{
|
||||
// don't change the language code
|
||||
unset($props['code']);
|
||||
|
||||
// make sure the slug is nice and clean
|
||||
$props['slug'] = Str::slug($props['slug'] ?? null);
|
||||
$kirby = App::instance();
|
||||
$updated = $this->clone($props);
|
||||
|
||||
$kirby = App::instance();
|
||||
$updated = $this->clone($props);
|
||||
|
||||
// validate the updated language
|
||||
LanguageRules::update($updated);
|
||||
|
||||
// convert the current default to a non-default language
|
||||
if ($updated->isDefault() === true) {
|
||||
|
@@ -19,25 +19,8 @@ class LanguageRules
|
||||
{
|
||||
public static function create(Language $language): bool
|
||||
{
|
||||
if (Str::length($language->code()) < 2) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'language.code',
|
||||
'data' => [
|
||||
'code' => $language->code(),
|
||||
'name' => $language->name()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
if (Str::length($language->name()) < 1) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'language.name',
|
||||
'data' => [
|
||||
'code' => $language->code(),
|
||||
'name' => $language->name()
|
||||
]
|
||||
]);
|
||||
}
|
||||
static::validLanguageCode($language);
|
||||
static::validLanguageName($language);
|
||||
|
||||
if ($language->exists() === true) {
|
||||
throw new DuplicateException([
|
||||
@@ -50,4 +33,40 @@ class LanguageRules
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function update(Language $language)
|
||||
{
|
||||
static::validLanguageCode($language);
|
||||
static::validLanguageName($language);
|
||||
}
|
||||
|
||||
public static function validLanguageCode(Language $language): bool
|
||||
{
|
||||
if (Str::length($language->code()) < 2) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'language.code',
|
||||
'data' => [
|
||||
'code' => $language->code(),
|
||||
'name' => $language->name()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function validLanguageName(Language $language): bool
|
||||
{
|
||||
if (Str::length($language->name()) < 1) {
|
||||
throw new InvalidArgumentException([
|
||||
'key' => 'language.name',
|
||||
'data' => [
|
||||
'code' => $language->code(),
|
||||
'name' => $language->name()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -56,7 +56,7 @@ class Search
|
||||
$collection = clone $collection;
|
||||
$searchwords = preg_replace('/(\s)/u', ',', $query);
|
||||
$searchwords = Str::split($searchwords, ',', $options['minlength']);
|
||||
$lowerQuery = strtolower($query);
|
||||
$lowerQuery = mb_strtolower($query);
|
||||
|
||||
if (empty($options['stopwords']) === false) {
|
||||
$searchwords = array_diff($searchwords, $options['stopwords']);
|
||||
@@ -96,7 +96,7 @@ class Search
|
||||
$score = $options['score'][$key] ?? 1;
|
||||
$value = $data[$key] ?? (string)$item->$key();
|
||||
|
||||
$lowerValue = strtolower($value);
|
||||
$lowerValue = mb_strtolower($value);
|
||||
|
||||
// check for exact matches
|
||||
if ($lowerQuery == $lowerValue) {
|
||||
|
@@ -361,7 +361,7 @@ class Str
|
||||
return $string;
|
||||
}
|
||||
|
||||
return static::substr($string, 0, strrpos(static::substr($string, 0, $chars), ' ')) . ' ' . $rep;
|
||||
return static::substr($string, 0, mb_strrpos(static::substr($string, 0, $chars), ' ')) . ' ' . $rep;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,6 +373,11 @@ class Str
|
||||
*/
|
||||
public static function float($value): string
|
||||
{
|
||||
// Convert exponential to decimal, 1e-8 as 0.00000001
|
||||
if (strpos(strtolower($value), 'e') !== false) {
|
||||
$value = rtrim(sprintf('%.16f', (float)$value), '0');
|
||||
}
|
||||
|
||||
$value = str_replace(',', '.', $value);
|
||||
$decimal = strlen(substr(strrchr($value, '.'), 1));
|
||||
return number_format((float)$value, $decimal, '.', false);
|
||||
|
Reference in New Issue
Block a user