aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/includes/template/twig/extension.php40
-rw-r--r--phpBB/includes/template/twig/lexer.php11
2 files changed, 46 insertions, 5 deletions
diff --git a/phpBB/includes/template/twig/extension.php b/phpBB/includes/template/twig/extension.php
index 44d694ce1a..a952d70076 100644
--- a/phpBB/includes/template/twig/extension.php
+++ b/phpBB/includes/template/twig/extension.php
@@ -35,12 +35,19 @@ class phpbb_template_twig_extension extends Twig_Extension
);
}
+ public function getFilters()
+ {
+ return array(
+ new Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)),
+ );
+ }
+
public function getOperators()
{
return array(
array(),
array(
- // @todo check if all these are needed (or others)
+ // @todo check if all these are needed (or others) and set precedence correctly
'eq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
'ne' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
@@ -60,4 +67,35 @@ class phpbb_template_twig_extension extends Twig_Extension
),
);
}
+
+ /**
+ * Grabs a subset of a loop
+ *
+ * @param Twig_Environment $env A Twig_Environment instance
+ * @param mixed $item A variable
+ * @param integer $start Start of the subset
+ * @param integer $end End of the subset
+ * @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array)
+ *
+ * @return mixed The sliced variable
+ */
+ function loop_subset(Twig_Environment $env, $item, $start, $end = null, $preserveKeys = false)
+ {
+ // We do almost the same thing as array_slice, except when $end is positive
+ if ($end >= 1)
+ {
+ // When end is > 1, subset will end on the last item in an array with the specified $end
+ // This is different from slice in that it is the number we end on rather than the number
+ // of items to grab (length)
+
+ // Start must always be the actual starting number for this calculation (not negative)
+ $start = ($start < 0) ? sizeof($item) + $start : $start;
+ $end = $end - $start;
+ }
+
+ // We always include the last element (this was the past design)
+ $end = ($end == -1 || $end === null) ? null : $end + 1;
+
+ return twig_slice($env, $item, $start, $end, $preserveKeys);
+ }
}
diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php
index 95b9bd4630..9d348535a5 100644
--- a/phpBB/includes/template/twig/lexer.php
+++ b/phpBB/includes/template/twig/lexer.php
@@ -78,7 +78,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer
$callback = function ($matches) use ($parent_class, $parent_nodes)
{
$name = $matches[1];
- $slice = $matches[2];
+ $subset = trim(substr($matches[2], 1, -1)); // Remove parenthesis
$body = $matches[3];
// Is the designer wanting to call another loop in a loop?
@@ -118,16 +118,19 @@ class phpbb_template_twig_lexer extends Twig_Lexer
array_pop($parent_nodes);
$parent = (!empty($parent_nodes)) ? end($parent_nodes) . '_loop_element.' : '';
- $slice = ($slice) ? '|slice(' . $slice . ')' : '';
+ if ($subset !== '')
+ {
+ $subset = '|subset(' . $subset . ')';
+ }
// Turn into a Twig for loop, using (loop name)_loop_element for each child
- return "{% for {$name}_loop_element in {$parent}{$name}{$slice} %}{$body}{% endfor %}";
+ return "{% for {$name}_loop_element in {$parent}{$name}{$subset} %}{$body}{% endfor %}";
};
// Replace <!-- BEGINELSE --> correctly, only needs to be done once
$code = str_replace('<!-- BEGINELSE -->', '{% else %}', $code);
- return preg_replace_callback('#<!-- BEGIN ([!a-zA-Z0-9_]+)\(?([0-9,]+)?\)? -->(.+?)<!-- END \1 -->#s', $callback, $code);
+ return preg_replace_callback('#<!-- BEGIN ([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1 -->#s', $callback, $code);
}
/**