mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-30 12:06:56 +00:00
Allow null when Twig expects a string
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 2.14.9 (2021-XX-XX)
|
||||
# 2.14.9 (2022-XX-XX)
|
||||
|
||||
* n/a
|
||||
* Allow null when Twig expects a string (for better 8.1 support)
|
||||
|
||||
# 2.14.8 (2021-11-25)
|
||||
|
||||
|
||||
@@ -543,7 +543,7 @@ function twig_date_converter(Environment $env, $date = null, $timezone = null)
|
||||
/**
|
||||
* Replaces strings within a string.
|
||||
*
|
||||
* @param string $str String to replace in
|
||||
* @param string|null $str String to replace in
|
||||
* @param array|\Traversable $from Replace values
|
||||
*
|
||||
* @return string
|
||||
@@ -554,15 +554,15 @@ function twig_replace_filter($str, $from)
|
||||
throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
|
||||
}
|
||||
|
||||
return strtr($str, twig_to_array($from));
|
||||
return strtr($str ?? '', twig_to_array($from));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds a number.
|
||||
*
|
||||
* @param int|float $value The value to round
|
||||
* @param int|float $precision The rounding precision
|
||||
* @param string $method The method to use for rounding
|
||||
* @param int|float|string|null $value The value to round
|
||||
* @param int|float $precision The rounding precision
|
||||
* @param string $method The method to use for rounding
|
||||
*
|
||||
* @return int|float The rounded number
|
||||
*/
|
||||
@@ -576,6 +576,8 @@ function twig_round($value, $precision = 0, $method = 'common')
|
||||
throw new RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
|
||||
}
|
||||
|
||||
$value = (float) $value;
|
||||
|
||||
return $method($value * 10 ** $precision) / 10 ** $precision;
|
||||
}
|
||||
|
||||
@@ -583,7 +585,7 @@ function twig_round($value, $precision = 0, $method = 'common')
|
||||
* Number format filter.
|
||||
*
|
||||
* All of the formatting options can be left null, in that case the defaults will
|
||||
* be used. Supplying any of the parameters will override the defaults set in the
|
||||
* be used. Supplying any of the parameters will override the defaults set in the
|
||||
* environment object.
|
||||
*
|
||||
* @param mixed $number A float/int/string of the number to format
|
||||
@@ -614,7 +616,7 @@ function twig_number_format_filter(Environment $env, $number, $decimal = null, $
|
||||
/**
|
||||
* URL encodes (RFC 3986) a string as a path segment or an array as a query string.
|
||||
*
|
||||
* @param string|array $url A URL or an array of query parameters
|
||||
* @param string|array|null $url A URL or an array of query parameters
|
||||
*
|
||||
* @return string The URL encoded value
|
||||
*/
|
||||
@@ -624,7 +626,7 @@ function twig_urlencode_filter($url)
|
||||
return http_build_query($url, '', '&', \PHP_QUERY_RFC3986);
|
||||
}
|
||||
|
||||
return rawurlencode($url);
|
||||
return rawurlencode($url ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -686,9 +688,7 @@ function twig_slice(Environment $env, $item, $start, $length = null, $preserveKe
|
||||
return \array_slice($item, $start, $length, $preserveKeys);
|
||||
}
|
||||
|
||||
$item = (string) $item;
|
||||
|
||||
return (string) mb_substr($item, $start, $length, $env->getCharset());
|
||||
return (string) mb_substr((string) $item, $start, $length, $env->getCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -777,14 +777,16 @@ function twig_join_filter($value, $glue = '', $and = null)
|
||||
* {{ "aabbcc"|split('', 2) }}
|
||||
* {# returns [aa, bb, cc] #}
|
||||
*
|
||||
* @param string $value A string
|
||||
* @param string $delimiter The delimiter
|
||||
* @param int $limit The limit
|
||||
* @param string|null $value A string
|
||||
* @param string $delimiter The delimiter
|
||||
* @param int $limit The limit
|
||||
*
|
||||
* @return array The split string as an array
|
||||
*/
|
||||
function twig_split_filter(Environment $env, $value, $delimiter, $limit = null)
|
||||
{
|
||||
$value = $value ?? '';
|
||||
|
||||
if (\strlen($delimiter) > 0) {
|
||||
return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
|
||||
}
|
||||
@@ -870,8 +872,8 @@ function twig_get_array_keys_filter($array)
|
||||
/**
|
||||
* Reverses a variable.
|
||||
*
|
||||
* @param array|\Traversable|string $item An array, a \Traversable instance, or a string
|
||||
* @param bool $preserveKeys Whether to preserve key or not
|
||||
* @param array|\Traversable|string|null $item An array, a \Traversable instance, or a string
|
||||
* @param bool $preserveKeys Whether to preserve key or not
|
||||
*
|
||||
* @return mixed The reversed input
|
||||
*/
|
||||
@@ -890,10 +892,10 @@ function twig_reverse_filter(Environment $env, $item, $preserveKeys = false)
|
||||
$charset = $env->getCharset();
|
||||
|
||||
if ('UTF-8' !== $charset) {
|
||||
$item = twig_convert_encoding($string, 'UTF-8', $charset);
|
||||
$string = twig_convert_encoding($string, 'UTF-8', $charset);
|
||||
}
|
||||
|
||||
preg_match_all('/./us', $item, $matches);
|
||||
preg_match_all('/./us', $string, $matches);
|
||||
|
||||
$string = implode('', array_reverse($matches[0]));
|
||||
|
||||
@@ -968,6 +970,10 @@ function twig_in_filter($value, $compare)
|
||||
/**
|
||||
* Returns a trimmed string.
|
||||
*
|
||||
* @param string|null $string
|
||||
* @param string|null $characterMask
|
||||
* @param string $side
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeError When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
|
||||
@@ -980,11 +986,11 @@ function twig_trim_filter($string, $characterMask = null, $side = 'both')
|
||||
|
||||
switch ($side) {
|
||||
case 'both':
|
||||
return trim($string, $characterMask);
|
||||
return trim($string ?? '', $characterMask);
|
||||
case 'left':
|
||||
return ltrim($string, $characterMask);
|
||||
return ltrim($string ?? '', $characterMask);
|
||||
case 'right':
|
||||
return rtrim($string, $characterMask);
|
||||
return rtrim($string ?? '', $characterMask);
|
||||
default:
|
||||
throw new RuntimeError('Trimming side must be "left", "right" or "both".');
|
||||
}
|
||||
@@ -993,20 +999,29 @@ function twig_trim_filter($string, $characterMask = null, $side = 'both')
|
||||
/**
|
||||
* Removes whitespaces between HTML tags.
|
||||
*
|
||||
* @param string|null $string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function twig_spaceless($content)
|
||||
{
|
||||
return trim(preg_replace('/>\s+</', '><', $content));
|
||||
return trim(preg_replace('/>\s+</', '><', $content ?? ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $string
|
||||
* @param string $to
|
||||
* @param string $from
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function twig_convert_encoding($string, $to, $from)
|
||||
{
|
||||
if (!\function_exists('iconv')) {
|
||||
throw new RuntimeError('Unable to convert encoding: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');
|
||||
}
|
||||
|
||||
return iconv($from, $to, $string);
|
||||
return iconv($from, $to, $string ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1044,47 +1059,47 @@ function twig_length_filter(Environment $env, $thing)
|
||||
/**
|
||||
* Converts a string to uppercase.
|
||||
*
|
||||
* @param string $string A string
|
||||
* @param string|null $string A string
|
||||
*
|
||||
* @return string The uppercased string
|
||||
*/
|
||||
function twig_upper_filter(Environment $env, $string)
|
||||
{
|
||||
return mb_strtoupper($string, $env->getCharset());
|
||||
return mb_strtoupper($string ?? '', $env->getCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to lowercase.
|
||||
*
|
||||
* @param string $string A string
|
||||
* @param string|null $string A string
|
||||
*
|
||||
* @return string The lowercased string
|
||||
*/
|
||||
function twig_lower_filter(Environment $env, $string)
|
||||
{
|
||||
return mb_strtolower($string, $env->getCharset());
|
||||
return mb_strtolower($string ?? '', $env->getCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a titlecased string.
|
||||
*
|
||||
* @param string $string A string
|
||||
* @param string|null $string A string
|
||||
*
|
||||
* @return string The titlecased string
|
||||
*/
|
||||
function twig_title_string_filter(Environment $env, $string)
|
||||
{
|
||||
if (null !== $charset = $env->getCharset()) {
|
||||
return mb_convert_case($string, \MB_CASE_TITLE, $charset);
|
||||
return mb_convert_case($string ?? '', \MB_CASE_TITLE, $charset);
|
||||
}
|
||||
|
||||
return ucwords(strtolower($string));
|
||||
return ucwords(strtolower($string ?? ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a capitalized string.
|
||||
*
|
||||
* @param string $string A string
|
||||
* @param string|null $string A string
|
||||
*
|
||||
* @return string The capitalized string
|
||||
*/
|
||||
@@ -1092,7 +1107,7 @@ function twig_capitalize_string_filter(Environment $env, $string)
|
||||
{
|
||||
$charset = $env->getCharset();
|
||||
|
||||
return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, null, $charset), $charset);
|
||||
return mb_strtoupper(mb_substr($string ?? '', 0, 1, $charset), $charset).mb_strtolower(mb_substr($string ?? '', 1, null, $charset), $charset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
"capitalize" filter
|
||||
--TEMPLATE--
|
||||
{{ "super helpful"|capitalize }}
|
||||
{{ "a"|capitalize }}
|
||||
*{{ ""|capitalize }}*
|
||||
*{{ null|capitalize }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
Super helpful
|
||||
A
|
||||
**
|
||||
**
|
||||
@@ -2,7 +2,11 @@
|
||||
"convert_encoding" filter
|
||||
--TEMPLATE--
|
||||
{{ "愛していますか?"|convert_encoding('ISO-2022-JP', 'UTF-8')|convert_encoding('UTF-8', 'ISO-2022-JP') }}
|
||||
*{{ ""|convert_encoding('ISO-2022-JP', 'UTF-8')|convert_encoding('UTF-8', 'ISO-2022-JP') }}*
|
||||
*{{ null|convert_encoding('ISO-2022-JP', 'UTF-8')|convert_encoding('UTF-8', 'ISO-2022-JP') }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
愛していますか?
|
||||
**
|
||||
**
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"escape" filter
|
||||
--TEMPLATE--
|
||||
{{ "foo <br />"|e }}
|
||||
*{{ ""|e }}*
|
||||
*{{ null|e }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
foo <br />
|
||||
**
|
||||
**
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
{{ '1234'|first }}
|
||||
{{ arr|first }}
|
||||
{{ 'Ä€é'|first }}
|
||||
{{ ''|first }}
|
||||
*{{ ''|first }}*
|
||||
*{{ null|first }}*
|
||||
--DATA--
|
||||
return ['arr' => new \ArrayObject([1, 2, 3, 4])]
|
||||
--EXPECT--
|
||||
@@ -15,3 +16,5 @@ return ['arr' => new \ArrayObject([1, 2, 3, 4])]
|
||||
1
|
||||
1
|
||||
Ä
|
||||
**
|
||||
**
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
{{ '1234'|last }}
|
||||
{{ arr|last }}
|
||||
{{ 'Ä€é'|last }}
|
||||
{{ ''|last }}
|
||||
*{{ ''|last }}*
|
||||
*{{ null|last }}*
|
||||
--DATA--
|
||||
return ['arr' => new \ArrayObject([1, 2, 3, 4])]
|
||||
--EXPECT--
|
||||
@@ -15,3 +16,5 @@ return ['arr' => new \ArrayObject([1, 2, 3, 4])]
|
||||
4
|
||||
4
|
||||
é
|
||||
**
|
||||
**
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
{{ to_string_able|length }}
|
||||
{{ countable|length }}
|
||||
{{ iterator_aggregate|length }}
|
||||
{{ ""|length }}
|
||||
{{ null|length }}
|
||||
{{ magic|length }}
|
||||
{{ non_countable|length }}
|
||||
@@ -34,6 +35,7 @@ return [
|
||||
42
|
||||
3
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
2
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
"lower" filter
|
||||
--TEMPLATE--
|
||||
{{ "I like Twig."|lower }}
|
||||
*{{ ""|lower }}*
|
||||
*{{ null|lower }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
i like twig.
|
||||
**
|
||||
**
|
||||
@@ -7,6 +7,9 @@
|
||||
{{ 20.25|number_format(2, ',') }}
|
||||
{{ 1020.25|number_format(2, ',') }}
|
||||
{{ 1020.25|number_format(2, ',', '.') }}
|
||||
{{ '1020.25'|number_format(2, ',', '.') }}
|
||||
{{ ''|number_format(2, ',', '.') }}
|
||||
{{ null|number_format(2, ',', '.') }}
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
@@ -16,3 +19,6 @@ return []
|
||||
20,25
|
||||
1,020,25
|
||||
1.020,25
|
||||
1.020,25
|
||||
0,00
|
||||
0,00
|
||||
|
||||
@@ -4,9 +4,13 @@
|
||||
{{ "I liké %this% and %that%."|replace({'%this%': "foo", '%that%': "bar"}) }}
|
||||
{{ 'I like single replace operation only %that%'|replace({'%that%' : '%that%1'}) }}
|
||||
{{ 'I like %this% and %that%.'|replace(traversable) }}
|
||||
*{{ ''|replace(traversable) }}*
|
||||
*{{ null|replace(traversable) }}*
|
||||
--DATA--
|
||||
return ['traversable' => new \ArrayObject(['%this%' => 'foo', '%that%' => 'bar'])]
|
||||
--EXPECT--
|
||||
I liké foo and bar.
|
||||
I like single replace operation only %that%1
|
||||
I like foo and bar.
|
||||
**
|
||||
**
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
{{ {'a': 'c', 'b': 'a'}|reverse()|join(',') }}
|
||||
{{ {'a': 'c', 'b': 'a'}|reverse(preserveKeys=true)|join(glue=',') }}
|
||||
{{ {'a': 'c', 'b': 'a'}|reverse(preserve_keys=true)|join(glue=',') }}
|
||||
*{{ ''|reverse }}*
|
||||
*{{ null|reverse }}*
|
||||
--DATA--
|
||||
return ['arr' => new \ArrayObject([1, 2, 3, 4])]
|
||||
--EXPECT--
|
||||
@@ -16,3 +18,5 @@ tnemenèvé4321
|
||||
a,c
|
||||
a,c
|
||||
a,c
|
||||
**
|
||||
**
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
{{ 21.3|round(-1)}}
|
||||
{{ 21.3|round(-1, 'ceil')}}
|
||||
{{ 21.3|round(-1, 'floor')}}
|
||||
{{ '21.3'|round(-1, 'floor')}}
|
||||
|
||||
{{ ''|round(-1, 'floor')}}
|
||||
{{ null|round(-1, 'floor')}}
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
@@ -20,3 +24,7 @@ return []
|
||||
20
|
||||
30
|
||||
20
|
||||
20
|
||||
|
||||
0
|
||||
0
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"spaceless" filter
|
||||
--TEMPLATE--
|
||||
{{ " <div> <div> foo </div> </div>"|spaceless }}
|
||||
*{{ ""|spaceless }}*
|
||||
*{{ null|spaceless }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
<div><div> foo </div></div>
|
||||
**
|
||||
**
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
{{ baz|split('', 2)|join('-') }}
|
||||
{{ foo|split(',', -2)|join('-') }}
|
||||
{{ "hello0world"|split('0')|join('-') }}
|
||||
*{{ ""|split(',')|join('-') }}*
|
||||
*{{ null|split(',')|join('-') }}*
|
||||
--DATA--
|
||||
return ['foo' => "one,two,three,four,five", 'baz' => '12345',]
|
||||
--EXPECT--
|
||||
@@ -19,4 +21,6 @@ one-two-three,four,five
|
||||
1-2-3-4-5
|
||||
12-34-5
|
||||
one-two-three
|
||||
hello-world
|
||||
hello-world
|
||||
**
|
||||
**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
"title" filter
|
||||
--TEMPLATE--
|
||||
{{ "I like Twig."|title }}
|
||||
*{{ ""|title }}*
|
||||
*{{ null|title }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
I Like Twig.
|
||||
**
|
||||
**
|
||||
@@ -10,6 +10,12 @@
|
||||
{{ "/ foo/"|trim("/", "left") }}
|
||||
{{ "/ foo/"|trim(character_mask="/", side="left") }}
|
||||
{{ " do nothing. "|trim("", "right") }}
|
||||
*{{ ""|trim }}*
|
||||
*{{ ""|trim("", "left") }}*
|
||||
*{{ ""|trim("", "right") }}*
|
||||
*{{ null|trim }}*
|
||||
*{{ null|trim("", "left") }}*
|
||||
*{{ null|trim("", "right") }}*
|
||||
--DATA--
|
||||
return ['text' => " If you have some <strong>HTML</strong> it will be escaped. "]
|
||||
--EXPECT--
|
||||
@@ -22,3 +28,9 @@ xxxI like Twig.
|
||||
foo/
|
||||
foo/
|
||||
do nothing.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
"upper" filter
|
||||
--TEMPLATE--
|
||||
{{ "I like Twig."|upper }}
|
||||
*{{ ""|upper }}*
|
||||
*{{ null|upper }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
I LIKE TWIG.
|
||||
**
|
||||
**
|
||||
@@ -5,6 +5,8 @@
|
||||
{{ {foo: "bar", number: 3, "spéßi%l": "e%c0d@d", "spa ce": ""}|url_encode|raw }}
|
||||
{{ {}|url_encode|default("default") }}
|
||||
{{ 'spéßi%le%c0d@dspa ce'|url_encode }}
|
||||
*{{ ''|url_encode }}*
|
||||
*{{ null|url_encode }}*
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
@@ -12,3 +14,5 @@ foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce=
|
||||
foo=bar&number=3&sp%C3%A9%C3%9Fi%25l=e%25c0d%40d&spa%20ce=
|
||||
default
|
||||
sp%C3%A9%C3%9Fi%25le%25c0d%40dspa%20ce
|
||||
**
|
||||
**
|
||||
|
||||
Reference in New Issue
Block a user