Upgrade to 3.6.1
This commit is contained in:
@@ -467,10 +467,7 @@ class A
|
||||
{
|
||||
// convert a simple ignore list to a nested $key => true array
|
||||
if (isset($ignore[0]) === true) {
|
||||
$ignore = array_map(function () {
|
||||
return true;
|
||||
}, array_flip($ignore));
|
||||
|
||||
$ignore = array_map(fn () => true, array_flip($ignore));
|
||||
$ignore = A::nest($ignore);
|
||||
}
|
||||
|
||||
|
@@ -138,7 +138,7 @@ class Dom
|
||||
*/
|
||||
public function body()
|
||||
{
|
||||
return $this->body = $this->body ?? $this->query('/html/body')[0] ?? null;
|
||||
return $this->body ??= $this->query('/html/body')[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,11 +455,20 @@ class Dom
|
||||
};
|
||||
}
|
||||
|
||||
if ($allowedNamespaces === true) {
|
||||
// take the list as it is and only consider
|
||||
// if the configuration does not define namespace URIs or if the
|
||||
// currently checked node is from the special `xml:` namespace
|
||||
// that has a fixed namespace according to the XML spec...
|
||||
if ($allowedNamespaces === true || $node->namespaceURI === 'http://www.w3.org/XML/1998/namespace') {
|
||||
// ...take the list as it is and only consider
|
||||
// exact matches of the local name (which will
|
||||
// contain a namespace if that namespace name
|
||||
// is not defined in the document)
|
||||
|
||||
// the list contains the `xml:` prefix, so add it to the name as well
|
||||
if ($node->namespaceURI === 'http://www.w3.org/XML/1998/namespace') {
|
||||
$localName = 'xml:' . $localName;
|
||||
}
|
||||
|
||||
foreach ($list as $item) {
|
||||
if ($compare($item, $localName) === true) {
|
||||
return $item;
|
||||
|
@@ -81,7 +81,7 @@ class Escape
|
||||
*/
|
||||
protected static function escaper()
|
||||
{
|
||||
return static::$escaper = static::$escaper ?? new Escaper('utf-8');
|
||||
return static::$escaper ??= new Escaper('utf-8');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -24,6 +24,34 @@ class Html extends Xml
|
||||
*/
|
||||
public static $entities;
|
||||
|
||||
/**
|
||||
* List of HTML tags that can be used inline
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $inlineList = [
|
||||
'b',
|
||||
'i',
|
||||
'small',
|
||||
'abbr',
|
||||
'cite',
|
||||
'code',
|
||||
'dfn',
|
||||
'em',
|
||||
'kbd',
|
||||
'strong',
|
||||
'samp',
|
||||
'var',
|
||||
'a',
|
||||
'bdo',
|
||||
'br',
|
||||
'img',
|
||||
'q',
|
||||
'span',
|
||||
'sub',
|
||||
'sup'
|
||||
];
|
||||
|
||||
/**
|
||||
* Closing string for void tags;
|
||||
* can be used to switch to trailing slashes if required
|
||||
@@ -117,6 +145,10 @@ class Html extends Xml
|
||||
// all other cases can share the XML variant
|
||||
$attr = parent::attr($name, $value);
|
||||
|
||||
if ($attr === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// HTML supports named entities
|
||||
$entities = parent::entities();
|
||||
$html = array_keys($entities);
|
||||
@@ -205,7 +237,7 @@ class Html extends Xml
|
||||
*/
|
||||
public static function entities(): array
|
||||
{
|
||||
return self::$entities = self::$entities ?? get_html_translation_table(HTML_ENTITIES);
|
||||
return self::$entities ??= get_html_translation_table(HTML_ENTITIES);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,7 +357,7 @@ class Html extends Xml
|
||||
*/
|
||||
public static function rel(?string $rel = null, ?string $target = null): ?string
|
||||
{
|
||||
$rel = trim($rel);
|
||||
$rel = trim($rel ?? '');
|
||||
|
||||
if ($target === '_blank') {
|
||||
if (empty($rel) === false) {
|
||||
|
@@ -115,7 +115,7 @@ class I18n
|
||||
*/
|
||||
public static function formatNumber($number, string $locale = null): string
|
||||
{
|
||||
$locale = $locale ?? static::locale();
|
||||
$locale ??= static::locale();
|
||||
|
||||
$formatter = static::decimalNumberFormatter($locale);
|
||||
if ($formatter !== null) {
|
||||
@@ -154,7 +154,7 @@ class I18n
|
||||
*/
|
||||
public static function translate($key, $fallback = null, string $locale = null)
|
||||
{
|
||||
$locale = $locale ?? static::locale();
|
||||
$locale ??= static::locale();
|
||||
|
||||
if (is_array($key) === true) {
|
||||
if (isset($key[$locale])) {
|
||||
@@ -224,7 +224,7 @@ class I18n
|
||||
*/
|
||||
public static function translation(string $locale = null): array
|
||||
{
|
||||
$locale = $locale ?? static::locale();
|
||||
$locale ??= static::locale();
|
||||
|
||||
if (isset(static::$translations[$locale]) === true) {
|
||||
return static::$translations[$locale];
|
||||
@@ -283,8 +283,7 @@ class I18n
|
||||
*/
|
||||
public static function translateCount(string $key, int $count, string $locale = null, bool $formatNumber = true)
|
||||
{
|
||||
$locale = $locale ?? static::locale();
|
||||
|
||||
$locale ??= static::locale();
|
||||
$translation = static::translate($key, null, $locale);
|
||||
|
||||
if ($translation === null) {
|
||||
|
@@ -40,7 +40,7 @@ class Iterator implements IteratorAggregate
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
public function getIterator(): ArrayIterator
|
||||
{
|
||||
return new ArrayIterator($this->data);
|
||||
}
|
||||
|
@@ -115,7 +115,7 @@ trait Properties
|
||||
}
|
||||
|
||||
// fetch the default value from the property
|
||||
$value = $value ?? $this->$name ?? null;
|
||||
$value ??= $this->$name ?? null;
|
||||
|
||||
// store all original properties, to be able to clone them later
|
||||
$this->propertyData[$name] = $value;
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace Kirby\Toolkit;
|
||||
|
||||
use Exception;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* The String class provides a set
|
||||
@@ -180,9 +181,9 @@ class Str
|
||||
|
||||
if ($position === false) {
|
||||
return '';
|
||||
} else {
|
||||
return static::substr($string, $position + static::length($needle));
|
||||
}
|
||||
|
||||
return static::substr($string, $position + static::length($needle));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,9 +223,9 @@ class Str
|
||||
|
||||
if ($position === false) {
|
||||
return '';
|
||||
} else {
|
||||
return static::substr($string, 0, $position);
|
||||
}
|
||||
|
||||
return static::substr($string, 0, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +251,40 @@ class Str
|
||||
*/
|
||||
public static function contains(string $string = null, string $needle, bool $caseInsensitive = false): bool
|
||||
{
|
||||
return call_user_func($caseInsensitive === true ? 'stripos' : 'strpos', $string, $needle) !== false;
|
||||
if ($needle === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
$method = $caseInsensitive === true ? 'stripos' : 'strpos';
|
||||
return call_user_func($method, $string, $needle) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert timestamp to date string
|
||||
* according to locale settings
|
||||
*
|
||||
* @param int|null $time
|
||||
* @param string|null $format
|
||||
* @param string $handler date or strftime
|
||||
* @return string|int
|
||||
*/
|
||||
public static function date(?int $time = null, ?string $format = null, string $handler = 'date')
|
||||
{
|
||||
if (is_null($format) === true) {
|
||||
return $time;
|
||||
}
|
||||
|
||||
// separately handle strftime to be able
|
||||
// to suppress deprecation warning
|
||||
// TODO: remove strftime support for PHP 9.0
|
||||
if ($handler === 'strftime') {
|
||||
// make sure timezone is set correctly
|
||||
date_default_timezone_get();
|
||||
|
||||
return @strftime($format, $time);
|
||||
}
|
||||
|
||||
return $handler($format, $time);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,6 +407,9 @@ class Str
|
||||
*/
|
||||
public static function float($value): string
|
||||
{
|
||||
// make sure $value is not null
|
||||
$value ??= '';
|
||||
|
||||
// Convert exponential to decimal, 1e-8 as 0.00000001
|
||||
if (strpos(strtolower($value), 'e') !== false) {
|
||||
$value = rtrim(sprintf('%.16f', (float)$value), '0');
|
||||
@@ -397,9 +434,9 @@ class Str
|
||||
|
||||
if ($position === false) {
|
||||
return '';
|
||||
} else {
|
||||
return static::substr($string, $position);
|
||||
}
|
||||
|
||||
return static::substr($string, $position);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,7 +473,7 @@ class Str
|
||||
*/
|
||||
public static function length(string $string = null): int
|
||||
{
|
||||
return mb_strlen($string, 'UTF-8');
|
||||
return mb_strlen($string ?? '', 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -512,6 +549,10 @@ class Str
|
||||
*/
|
||||
public static function position(string $string = null, string $needle, bool $caseInsensitive = false)
|
||||
{
|
||||
if ($needle === '') {
|
||||
throw new InvalidArgumentException('The needle must not be empty');
|
||||
}
|
||||
|
||||
if ($caseInsensitive === true) {
|
||||
$string = static::lower($string);
|
||||
$needle = static::lower($needle);
|
||||
@@ -899,10 +940,10 @@ class Str
|
||||
*/
|
||||
public static function slug(string $string = null, string $separator = null, string $allowed = null, int $maxlength = 128): string
|
||||
{
|
||||
$separator = $separator ?? static::$defaults['slug']['separator'];
|
||||
$allowed = $allowed ?? static::$defaults['slug']['allowed'];
|
||||
$separator ??= static::$defaults['slug']['separator'];
|
||||
$allowed ??= static::$defaults['slug']['allowed'];
|
||||
|
||||
$string = trim($string);
|
||||
$string = trim($string ?? '');
|
||||
$string = static::lower($string);
|
||||
$string = static::ascii($string);
|
||||
|
||||
@@ -958,8 +999,11 @@ class Str
|
||||
return $string;
|
||||
}
|
||||
|
||||
$parts = explode($separator, $string);
|
||||
$out = [];
|
||||
// make sure $string is string
|
||||
$string ??= '';
|
||||
|
||||
$parts = explode($separator, $string);
|
||||
$out = [];
|
||||
|
||||
foreach ($parts as $p) {
|
||||
$p = trim($p);
|
||||
@@ -1046,6 +1090,9 @@ class Str
|
||||
$start = (string)($options['start'] ?? $start);
|
||||
$end = (string)($options['end'] ?? $end);
|
||||
|
||||
// make sure $string is string
|
||||
$string ??= '';
|
||||
|
||||
return preg_replace_callback('!' . $start . '(.*?)' . $end . '!', function ($match) use ($data, $fallback, $callback) {
|
||||
$query = trim($match[1]);
|
||||
|
||||
@@ -1084,8 +1131,12 @@ class Str
|
||||
*/
|
||||
public static function toBytes($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] ?? null);
|
||||
$last = strtolower($size[strlen($size)-1] ?? '');
|
||||
$size = (int)$size;
|
||||
|
||||
switch ($last) {
|
||||
@@ -1198,9 +1249,9 @@ class Str
|
||||
|
||||
if ($position === false) {
|
||||
return '';
|
||||
} else {
|
||||
return static::substr($string, 0, $position + static::length($needle));
|
||||
}
|
||||
|
||||
return static::substr($string, 0, $position + static::length($needle));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1224,6 +1275,9 @@ class Str
|
||||
*/
|
||||
public static function widont(string $string = null): string
|
||||
{
|
||||
// make sure $string is string
|
||||
$string ??= '';
|
||||
|
||||
// Replace space between last word and punctuation
|
||||
$string = preg_replace_callback('|(\S)\s(\S?)$|u', function ($matches) {
|
||||
return $matches[1] . ' ' . $matches[2];
|
||||
|
@@ -249,6 +249,9 @@ V::$validators = [
|
||||
* third argument to compare them.
|
||||
*/
|
||||
'date' => function (?string $value, string $operator = null, string $test = null): bool {
|
||||
// make sure $value is a string
|
||||
$value ??= '';
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
// simple date validation
|
||||
@@ -522,6 +525,6 @@ V::$validators = [
|
||||
// In search for the perfect regular expression: https://mathiasbynens.be/demo/url-regex
|
||||
// Added localhost support and removed 127.*.*.* ip restriction
|
||||
$regex = '_^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:localhost)|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$_iu';
|
||||
return preg_match($regex, $value) !== 0;
|
||||
return preg_match($regex, $value ?? '') !== 0;
|
||||
}
|
||||
];
|
||||
|
@@ -106,9 +106,10 @@ class Xml
|
||||
if (isset($value['value'], $value['escape'])) {
|
||||
$value = $value['escape'] === true ? static::encode($value['value']) : $value['value'];
|
||||
} else {
|
||||
$value = implode(' ', array_filter($value, function ($value) {
|
||||
return !empty($value) || is_numeric($value);
|
||||
}));
|
||||
$value = implode(' ', array_filter(
|
||||
$value,
|
||||
fn ($value) => !empty($value) || is_numeric($value)
|
||||
));
|
||||
}
|
||||
} else {
|
||||
$value = static::encode($value);
|
||||
@@ -420,7 +421,8 @@ class Xml
|
||||
return $value;
|
||||
}
|
||||
|
||||
$encoded = htmlentities($value);
|
||||
// TODO: in 3.7.0 use ENT_NOQUOTES | ENT_XML1 instead
|
||||
$encoded = htmlentities($value, ENT_COMPAT);
|
||||
if ($encoded === $value) {
|
||||
// no CDATA block needed
|
||||
return $value;
|
||||
|
Reference in New Issue
Block a user