added string support for the reverse filter
authorFabien Potencier <fabien.potencier@gmail.com>
Sat, 14 Jan 2012 07:24:24 +0000 (08:24 +0100)
committerFabien Potencier <fabien.potencier@gmail.com>
Sat, 14 Jan 2012 07:49:13 +0000 (08:49 +0100)
CHANGELOG
doc/filters/reverse.rst
lib/Twig/Extension/Core.php
test/Twig/Tests/Fixtures/filters/reverse.test [new file with mode: 0644]

index ca96018..0b4a7ad 100644 (file)
--- 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
index 82bb7fb..54fafb4 100644 (file)
@@ -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
index f78be90..2c5e215 100644 (file)
@@ -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 (file)
index 0000000..3c5f410
--- /dev/null
@@ -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