Upgrade to 3.7.0
This commit is contained in:
0
kirby/src/Toolkit/A.php
Normal file → Executable file
0
kirby/src/Toolkit/A.php
Normal file → Executable file
0
kirby/src/Toolkit/Collection.php
Normal file → Executable file
0
kirby/src/Toolkit/Collection.php
Normal file → Executable file
0
kirby/src/Toolkit/Component.php
Normal file → Executable file
0
kirby/src/Toolkit/Component.php
Normal file → Executable file
0
kirby/src/Toolkit/Config.php
Normal file → Executable file
0
kirby/src/Toolkit/Config.php
Normal file → Executable file
0
kirby/src/Toolkit/Controller.php
Normal file → Executable file
0
kirby/src/Toolkit/Controller.php
Normal file → Executable file
26
kirby/src/Toolkit/Date.php
Normal file → Executable file
26
kirby/src/Toolkit/Date.php
Normal file → Executable file
@@ -359,6 +359,32 @@ class Date extends DateTime
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds the minutes of the given date
|
||||
* by the defined step
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string|null $date
|
||||
* @param int|array|null $step array of `unit` and `size` to round to nearest
|
||||
* @return int|null
|
||||
*/
|
||||
public static function roundedTimestamp(?string $date = null, $step = null): ?int
|
||||
{
|
||||
if ($date = static::optional($date)) {
|
||||
if ($step !== null) {
|
||||
$step = static::stepConfig($step, [
|
||||
'unit' => 'minute',
|
||||
'size' => 1
|
||||
]);
|
||||
$date->round($step['unit'], $step['size']);
|
||||
}
|
||||
|
||||
return $date->timestamp();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or sets the second value
|
||||
*
|
||||
|
0
kirby/src/Toolkit/Dom.php
Normal file → Executable file
0
kirby/src/Toolkit/Dom.php
Normal file → Executable file
0
kirby/src/Toolkit/Escape.php
Normal file → Executable file
0
kirby/src/Toolkit/Escape.php
Normal file → Executable file
0
kirby/src/Toolkit/Facade.php
Normal file → Executable file
0
kirby/src/Toolkit/Facade.php
Normal file → Executable file
12
kirby/src/Toolkit/Html.php
Normal file → Executable file
12
kirby/src/Toolkit/Html.php
Normal file → Executable file
@@ -133,9 +133,11 @@ class Html extends Xml
|
||||
* Key-value array: A list of attributes will be generated. Don't pass a second argument in that case.
|
||||
* @param mixed $value If used with a `$name` string, pass the value of the attribute here.
|
||||
* If used with a `$name` array, this can be set to `false` to disable attribute sorting.
|
||||
* @param string|null $before An optional string that will be prepended if the result is not empty
|
||||
* @param string|null $after An optional string that will be appended if the result is not empty
|
||||
* @return string|null The generated HTML attributes string
|
||||
*/
|
||||
public static function attr($name, $value = null): ?string
|
||||
public static function attr($name, $value = null, ?string $before = null, ?string $after = null): ?string
|
||||
{
|
||||
// HTML supports boolean attributes without values
|
||||
if (is_array($name) === false && is_bool($value) === true) {
|
||||
@@ -153,7 +155,13 @@ class Html extends Xml
|
||||
$entities = parent::entities();
|
||||
$html = array_keys($entities);
|
||||
$xml = array_values($entities);
|
||||
return str_replace($xml, $html, $attr);
|
||||
$attr = str_replace($xml, $html, $attr);
|
||||
|
||||
if ($attr) {
|
||||
return $before . $attr . $after;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
16
kirby/src/Toolkit/I18n.php
Normal file → Executable file
16
kirby/src/Toolkit/I18n.php
Normal file → Executable file
@@ -52,22 +52,6 @@ class I18n
|
||||
*/
|
||||
protected static $decimalsFormatters = [];
|
||||
|
||||
/**
|
||||
* Returns the first fallback locale
|
||||
*
|
||||
* @deprecated 3.5.1 Use `\Kirby\Toolkit\I18n::fallbacks()` instead
|
||||
* @todo Remove in 3.7.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function fallback(): string
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
deprecated('I18n::fallback() has been deprecated. Use I18n::fallbacks() instead.');
|
||||
return static::fallbacks()[0];
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of fallback locales
|
||||
*
|
||||
|
0
kirby/src/Toolkit/Iterator.php
Normal file → Executable file
0
kirby/src/Toolkit/Iterator.php
Normal file → Executable file
0
kirby/src/Toolkit/Locale.php
Normal file → Executable file
0
kirby/src/Toolkit/Locale.php
Normal file → Executable file
0
kirby/src/Toolkit/Obj.php
Normal file → Executable file
0
kirby/src/Toolkit/Obj.php
Normal file → Executable file
0
kirby/src/Toolkit/Pagination.php
Normal file → Executable file
0
kirby/src/Toolkit/Pagination.php
Normal file → Executable file
0
kirby/src/Toolkit/Properties.php
Normal file → Executable file
0
kirby/src/Toolkit/Properties.php
Normal file → Executable file
0
kirby/src/Toolkit/Query.php
Normal file → Executable file
0
kirby/src/Toolkit/Query.php
Normal file → Executable file
0
kirby/src/Toolkit/Silo.php
Normal file → Executable file
0
kirby/src/Toolkit/Silo.php
Normal file → Executable file
202
kirby/src/Toolkit/Str.php
Normal file → Executable file
202
kirby/src/Toolkit/Str.php
Normal file → Executable file
@@ -5,6 +5,7 @@ namespace Kirby\Toolkit;
|
||||
use DateTime;
|
||||
use Exception;
|
||||
use IntlDateFormatter;
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
@@ -170,7 +171,7 @@ class Str
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rest of the string after the given character
|
||||
* Returns the rest of the string after the given substring or character
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $needle
|
||||
@@ -188,6 +189,28 @@ class Str
|
||||
return static::substr($string, $position + static::length($needle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given substring or character only from the start of the string
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $needle
|
||||
* @param bool $caseInsensitive
|
||||
* @return string
|
||||
*/
|
||||
public static function afterStart(string $string, string $needle, bool $caseInsensitive = false): string
|
||||
{
|
||||
if ($needle === '') {
|
||||
return $string;
|
||||
}
|
||||
|
||||
if (static::startsWith($string, $needle, $caseInsensitive) === true) {
|
||||
return static::substr($string, static::length($needle));
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string to 7-bit ASCII.
|
||||
*
|
||||
@@ -212,7 +235,7 @@ class Str
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the beginning of a string before the given character
|
||||
* Returns the beginning of a string before the given substring or character
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $needle
|
||||
@@ -230,6 +253,28 @@ class Str
|
||||
return static::substr($string, 0, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given substring or character only from the end of the string
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $string
|
||||
* @param string $needle
|
||||
* @param bool $caseInsensitive
|
||||
* @return string
|
||||
*/
|
||||
public static function beforeEnd(string $string, string $needle, bool $caseInsensitive = false): string
|
||||
{
|
||||
if ($needle === '') {
|
||||
return $string;
|
||||
}
|
||||
|
||||
if (static::endsWith($string, $needle, $caseInsensitive) === true) {
|
||||
return static::substr($string, 0, -static::length($needle));
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns everything between two strings from the first occurrence of a given string
|
||||
*
|
||||
@@ -243,6 +288,17 @@ class Str
|
||||
return static::before(static::after($string, $start), $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to camel case
|
||||
*
|
||||
* @param string $value The string to convert
|
||||
* @return string
|
||||
*/
|
||||
public static function camel(string $value = null): string
|
||||
{
|
||||
return lcfirst(static::studly($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a str contains another string
|
||||
*
|
||||
@@ -366,7 +422,7 @@ class Str
|
||||
* @param bool $caseInsensitive
|
||||
* @return bool
|
||||
*/
|
||||
public static function endsWith(string $string, string $needle, bool $caseInsensitive = false): bool
|
||||
public static function endsWith(string $string = null, string $needle, bool $caseInsensitive = false): bool
|
||||
{
|
||||
if ($needle === '') {
|
||||
return true;
|
||||
@@ -382,6 +438,23 @@ class Str
|
||||
return $needle === $probe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape string for context specific output
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $string Untrusted data
|
||||
* @param string $context Location of output (`html`, `attr`, `js`, `css`, `url` or `xml`)
|
||||
* @return string Escaped data
|
||||
*/
|
||||
public static function esc(string $string, string $context = 'html'): string
|
||||
{
|
||||
if (method_exists('Kirby\Toolkit\Escape', $context) === true) {
|
||||
return Escape::$context($string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an excerpt of a string
|
||||
* It removes all html tags first and then cuts the string
|
||||
@@ -457,18 +530,40 @@ class Str
|
||||
return static::substr($string, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `-1` to a string or increments the ending number to allow `-2`, `-3`, etc.
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $string The string to increment
|
||||
* @param string $separator
|
||||
* @param int $first Starting number
|
||||
* @return string
|
||||
*/
|
||||
public static function increment(string $string, string $separator = '-', int $first = 1): string
|
||||
{
|
||||
preg_match('/(.+)' . preg_quote($separator, '/') . '([0-9]+)$/', $string, $matches);
|
||||
|
||||
if (isset($matches[2]) === true) {
|
||||
// increment the existing ending number
|
||||
return $matches[1] . $separator . ((int)$matches[2] + 1);
|
||||
}
|
||||
|
||||
// append a new ending number
|
||||
return $string . $separator . $first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given string is a URL
|
||||
*
|
||||
* @param string|null $string
|
||||
* @return bool
|
||||
* @deprecated 3.6.0 use `Kirby\Toolkit\V::url()` instead
|
||||
* @todo Throw deprecation warning in 3.7.0
|
||||
* @todo Remove in 3.8.0
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public static function isURL(?string $string = null): bool
|
||||
{
|
||||
Helpers::deprecated('Toolkit\Str::isUrl() has been deprecated and will be removed in Kirby 3.8.0. Use Toolkit\V::url() instead.');
|
||||
return filter_var($string, FILTER_VALIDATE_URL) !== false;
|
||||
}
|
||||
|
||||
@@ -1050,6 +1145,18 @@ class Str
|
||||
return static::position($string, $needle, $caseInsensitive) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to studly caps case
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $value The string to convert
|
||||
* @return string
|
||||
*/
|
||||
public static function studly(string $value = null): string
|
||||
{
|
||||
return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* A UTF-8 safe version of substr()
|
||||
*
|
||||
@@ -1077,36 +1184,19 @@ class Str
|
||||
* @param array $data Associative array with placeholders as
|
||||
* keys and replacements as values.
|
||||
* Supports query syntax.
|
||||
* @param string|array|null $fallback An options array that contains:
|
||||
* - fallback: if a token does not have any matches
|
||||
* - callback: to be able to handle each matching result
|
||||
* - start: start placeholder
|
||||
* - end: end placeholder
|
||||
* A simple fallback string is supported for compatibility (but deprecated).
|
||||
* @param string $start Placeholder start characters (deprecated)
|
||||
* @param string $end Placeholder end characters (deprecated)
|
||||
*
|
||||
* @todo Remove `$start` and `$end` parameters, rename `$fallback` to `$options` and only support `array` type for `$options` in 3.7.0
|
||||
*
|
||||
* @param array $options An options array that contains:
|
||||
* - fallback: if a token does not have any matches
|
||||
* - callback: to be able to handle each matching result
|
||||
* - start: start placeholder
|
||||
* - end: end placeholder
|
||||
* @return string The filled-in string
|
||||
*/
|
||||
public static function template(string $string = null, array $data = [], $fallback = null, string $start = '{{', string $end = '}}'): string
|
||||
public static function template(string $string = null, array $data = [], array $options = []): string
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
if (
|
||||
is_string($fallback) === true ||
|
||||
$start !== '{{' ||
|
||||
$end !== '}}'
|
||||
) {
|
||||
deprecated('Str::template(): The $fallback, $start and $end parameters have been deprecated. Please pass an array to the $options parameter instead with `fallback`, `start` or `end` keys: Str::template($string, $data, $options)');
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$options = $fallback;
|
||||
$fallback = is_string($options) === true ? $options : ($options['fallback'] ?? null);
|
||||
$fallback = $options['fallback'] ?? null;
|
||||
$callback = is_a(($options['callback'] ?? null), 'Closure') === true ? $options['callback'] : null;
|
||||
$start = (string)($options['start'] ?? $start);
|
||||
$end = (string)($options['end'] ?? $end);
|
||||
$start = (string)($options['start'] ?? '{{');
|
||||
$end = (string)($options['end'] ?? '}}');
|
||||
|
||||
// make sure $string is string
|
||||
$string ??= '';
|
||||
@@ -1144,15 +1234,11 @@ class Str
|
||||
* Converts a filesize string with shortcuts
|
||||
* like M, G or K to an integer value
|
||||
*
|
||||
* @param mixed $size
|
||||
* @param string $size
|
||||
* @return int
|
||||
*/
|
||||
public static function toBytes($size): int
|
||||
public static function toBytes(string $size): int
|
||||
{
|
||||
// TODO: remove in 3.7.0
|
||||
// in favor of strict parameter type hint
|
||||
$size ??= '';
|
||||
|
||||
$size = trim($size);
|
||||
$last = strtolower($size[strlen($size)-1] ?? '');
|
||||
$size = (int)$size;
|
||||
@@ -1283,6 +1369,36 @@ class Str
|
||||
return mb_strtoupper($string ?? '', 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a compliant v4 UUID
|
||||
* Taken from: https://github.com/symfony/polyfill
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function uuid(): string
|
||||
{
|
||||
$uuid = bin2hex(random_bytes(16));
|
||||
|
||||
return sprintf(
|
||||
'%08s-%04s-4%03s-%04x-%012s',
|
||||
// 32 bits for "time_low"
|
||||
substr($uuid, 0, 8),
|
||||
// 16 bits for "time_mid"
|
||||
substr($uuid, 8, 4),
|
||||
// 16 bits for "time_hi_and_version",
|
||||
// four most significant bits holds version number 4
|
||||
substr($uuid, 13, 3),
|
||||
// 16 bits:
|
||||
// * 8 bits for "clk_seq_hi_res",
|
||||
// * 8 bits for "clk_seq_low",
|
||||
// two most significant bits holds zero and one for variant DCE1.1
|
||||
hexdec(substr($uuid, 16, 4)) & 0x3fff | 0x8000,
|
||||
// 48 bits for "node"
|
||||
substr($uuid, 20, 12)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The widont function makes sure that there are no
|
||||
* typographical widows at the end of a paragraph –
|
||||
@@ -1309,4 +1425,18 @@ class Str
|
||||
return ' ' . $matches[2];
|
||||
}, $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the string with the given string(s)
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param string $string String to wrap
|
||||
* @param string $before String to prepend
|
||||
* @param string|null $after String to append (if different from `$before`)
|
||||
* @return string
|
||||
*/
|
||||
public static function wrap(string $string, string $before, string $after = null): string
|
||||
{
|
||||
return $before . $string . ($after ?? $before);
|
||||
}
|
||||
}
|
||||
|
0
kirby/src/Toolkit/Tpl.php
Normal file → Executable file
0
kirby/src/Toolkit/Tpl.php
Normal file → Executable file
119
kirby/src/Toolkit/V.php
Normal file → Executable file
119
kirby/src/Toolkit/V.php
Normal file → Executable file
@@ -43,6 +43,75 @@ class V
|
||||
return $errors === true ? [] : $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a number of validators on a set of data and
|
||||
* checks if the data is invalid
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $rules
|
||||
* @param array $messages
|
||||
* @return array
|
||||
*/
|
||||
public static function invalid(array $data = [], array $rules = [], array $messages = []): array
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
foreach ($rules as $field => $validations) {
|
||||
$validationIndex = -1;
|
||||
|
||||
// See: http://php.net/manual/en/types.comparisons.php
|
||||
// only false for: null, undefined variable, '', []
|
||||
$value = $data[$field] ?? null;
|
||||
$filled = $value !== null && $value !== '' && $value !== [];
|
||||
$message = $messages[$field] ?? $field;
|
||||
|
||||
// True if there is an error message for each validation method.
|
||||
$messageArray = is_array($message);
|
||||
|
||||
foreach ($validations as $method => $options) {
|
||||
// If the index is numeric, there is no option
|
||||
// and `$value` is sent directly as a `$options` parameter
|
||||
if (is_numeric($method) === true) {
|
||||
$method = $options;
|
||||
$options = [$value];
|
||||
} else {
|
||||
if (is_array($options) === false) {
|
||||
$options = [$options];
|
||||
}
|
||||
|
||||
array_unshift($options, $value);
|
||||
}
|
||||
|
||||
$validationIndex++;
|
||||
|
||||
if ($method === 'required') {
|
||||
if ($filled) {
|
||||
// Field is required and filled.
|
||||
continue;
|
||||
}
|
||||
} elseif ($filled) {
|
||||
if (V::$method(...$options) === true) {
|
||||
// Field is filled and passes validation method.
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// If a field is not required and not filled, no validation should be done.
|
||||
continue;
|
||||
}
|
||||
|
||||
// If no continue was called we have a failed validation.
|
||||
if ($messageArray) {
|
||||
$errors[$field][] = $message[$validationIndex] ?? $field;
|
||||
} else {
|
||||
$errors[$field] = $message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a useful error message for the given validator
|
||||
* and the arguments. This is used mainly internally
|
||||
@@ -321,6 +390,23 @@ V::$validators = [
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks for empty values
|
||||
*/
|
||||
'empty' => function ($value = null): bool {
|
||||
$empty = ['', null, []];
|
||||
|
||||
if (in_array($value, $empty, true) === true) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_countable($value) === true) {
|
||||
return count($value) === 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the given string ends with the given value
|
||||
*/
|
||||
@@ -360,6 +446,19 @@ V::$validators = [
|
||||
return filter_var($value, FILTER_VALIDATE_IP) !== false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks for valid json
|
||||
*/
|
||||
'json' => function ($value): bool {
|
||||
if (!is_string($value) || $value === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
json_decode($value);
|
||||
|
||||
return json_last_error() === JSON_ERROR_NONE;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the value is lower than the second value
|
||||
*/
|
||||
@@ -430,6 +529,13 @@ V::$validators = [
|
||||
return V::contains($value, $needle) === false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks that the given value is not empty
|
||||
*/
|
||||
'notEmpty' => function ($value): bool {
|
||||
return V::empty($value) === false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks that the given value is not in the given list of values
|
||||
*/
|
||||
@@ -445,11 +551,16 @@ V::$validators = [
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the value is present in the given array
|
||||
* Checks if the value is present
|
||||
*/
|
||||
'required' => function ($key, array $array): bool {
|
||||
return isset($array[$key]) === true &&
|
||||
V::notIn($array[$key], [null, '', []]) === true;
|
||||
'required' => function ($value, $array = null): bool {
|
||||
// with reference array
|
||||
if (is_array($array) === true) {
|
||||
return isset($array[$value]) === true && V::notEmpty($array[$value]) === true;
|
||||
}
|
||||
|
||||
// without reference array
|
||||
return V::notEmpty($value);
|
||||
},
|
||||
|
||||
/**
|
||||
|
0
kirby/src/Toolkit/View.php
Normal file → Executable file
0
kirby/src/Toolkit/View.php
Normal file → Executable file
3
kirby/src/Toolkit/Xml.php
Normal file → Executable file
3
kirby/src/Toolkit/Xml.php
Normal file → Executable file
@@ -421,8 +421,7 @@ class Xml
|
||||
return $value;
|
||||
}
|
||||
|
||||
// TODO: in 3.7.0 use ENT_NOQUOTES | ENT_XML1 instead
|
||||
$encoded = htmlentities($value, ENT_COMPAT);
|
||||
$encoded = htmlentities($value, ENT_NOQUOTES | ENT_XML1);
|
||||
if ($encoded === $value) {
|
||||
// no CDATA block needed
|
||||
return $value;
|
||||
|
Reference in New Issue
Block a user