From 4578c176e59910f3ebb3b56d7c8d9e9808a511be Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 14 Jan 2012 08:24:24 +0100 Subject: [PATCH] added string support for the reverse filter --- CHANGELOG | 1 + doc/filters/reverse.rst | 16 +++++++-- lib/Twig/Extension/Core.php | 45 ++++++++++++++++++------- test/Twig/Tests/Fixtures/filters/reverse.test | 12 +++++++ 4 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 test/Twig/Tests/Fixtures/filters/reverse.test diff --git a/CHANGELOG b/CHANGELOG index ca96018..0b4a7ad 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ * 1.6.0-DEV + * added string support for the reverse filter * fixed the empty test and the length filter for Twig_Markup instances * added a date function to ease date comparison * fixed unary operators precedence diff --git a/doc/filters/reverse.rst b/doc/filters/reverse.rst index 82bb7fb..54fafb4 100644 --- a/doc/filters/reverse.rst +++ b/doc/filters/reverse.rst @@ -1,8 +1,10 @@ ``reverse`` =========== -The ``reverse`` filter reverses an array (or an object if it implements the -`Iterator`_ interface): +.. versionadded:: 1.6 + Support for strings has been added in Twig 1.6. + +The ``reverse`` filter reverses a sequence, a mapping, or a string: .. code-block:: jinja @@ -10,4 +12,12 @@ The ``reverse`` filter reverses an array (or an object if it implements the ... {% endfor %} -.. _`Iterator`: http://fr.php.net/manual/en/class.iterator.php + {{ '1234'|reverse }} + + {# outputs 4321 #} + +.. note:: + + It also works with objects implementing the `Traversable`_ interface. + +.. _`Traversable`: http://php.net/Traversable diff --git a/lib/Twig/Extension/Core.php b/lib/Twig/Extension/Core.php index f78be90..2c5e215 100644 --- a/lib/Twig/Extension/Core.php +++ b/lib/Twig/Extension/Core.php @@ -120,11 +120,13 @@ class Twig_Extension_Core extends Twig_Extension // array helpers 'join' => new Twig_Filter_Function('twig_join_filter'), - 'reverse' => new Twig_Filter_Function('twig_reverse_filter'), - 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)), 'sort' => new Twig_Filter_Function('twig_sort_filter'), 'merge' => new Twig_Filter_Function('twig_array_merge'), + // string/array filters + 'reverse' => new Twig_Filter_Function('twig_reverse_filter', array('needs_environment' => true)), + 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)), + // iteration and runtime 'default' => new Twig_Filter_Node('Twig_Node_Expression_Filter_Default'), '_default' => new Twig_Filter_Function('_twig_default_filter'), @@ -560,24 +562,43 @@ function twig_get_array_keys_filter($array) } /** - * Reverses an array. + * Reverses a variable. * - * @param array|Traversable $array An array or a Traversable instance - * @param Boolean $preserveKeys Whether to preserve key or not + * @param Twig_Environment $env A Twig_Environment instance + * @param array|Traversable|string $item An array, a Traversable instance, or a string + * @param Boolean $preserveKeys Whether to preserve key or not * - * return array The array reversed + * @return mixed The reversed input */ -function twig_reverse_filter($array, $preserveKeys = false) +function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false) { - if (is_object($array) && $array instanceof Traversable) { - return array_reverse(iterator_to_array($array), $preserveKeys); + if (is_object($item) && $item instanceof Traversable) { + return array_reverse(iterator_to_array($item), $preserveKeys); } - if (!is_array($array)) { - return array(); + if (is_array($item)) { + return array_reverse($item, $preserveKeys); + } + + if (null !== $charset = $env->getCharset()) { + $string = (string) $item; + + if ('UTF-8' != $charset) { + $item = twig_convert_encoding($string, 'UTF-8', $charset); + } + + preg_match_all('/./us', $item, $matches); + + $string = implode('', array_reverse($matches[0])); + + if ('UTF-8' != $charset) { + $string = twig_convert_encoding($string, $charset, 'UTF-8'); + } + + return $string; } - return array_reverse($array, $preserveKeys); + return strrev((string) $item); } /** diff --git a/test/Twig/Tests/Fixtures/filters/reverse.test b/test/Twig/Tests/Fixtures/filters/reverse.test new file mode 100644 index 0000000..3c5f410 --- /dev/null +++ b/test/Twig/Tests/Fixtures/filters/reverse.test @@ -0,0 +1,12 @@ +--TEST-- +"reverse" filter +--TEMPLATE-- +{{ [1, 2, 3, 4]|reverse|join('') }} +{{ '1234évènement'|reverse }} +{{ arr|reverse|join('') }} +--DATA-- +return array('arr' => new ArrayObject(array(1, 2, 3, 4))) +--EXPECT-- +4321 +tnemenèvé4321 +4321 -- 1.7.2.5