aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
authorNathaniel Guse <nathaniel.guse@gmail.com>2013-06-29 11:07:10 -0500
committerNathaniel Guse <nathaniel.guse@gmail.com>2013-06-29 11:07:10 -0500
commit64963b5962d9a4bf1888dd1642a32ba3f6037258 (patch)
tree005b45fe8b8aab32e69ca3a7e951fc25bf70837d /phpBB/includes
parentabb7901edb61e551b5783254579fef737f6f5c37 (diff)
downloadforums-64963b5962d9a4bf1888dd1642a32ba3f6037258.tar
forums-64963b5962d9a4bf1888dd1642a32ba3f6037258.tar.gz
forums-64963b5962d9a4bf1888dd1642a32ba3f6037258.tar.bz2
forums-64963b5962d9a4bf1888dd1642a32ba3f6037258.tar.xz
forums-64963b5962d9a4bf1888dd1642a32ba3f6037258.zip
[feature/twig] Fixing DEFINE statements
PHPBB3-11598
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/template/twig/definition.php50
-rw-r--r--phpBB/includes/template/twig/lexer.php82
-rw-r--r--phpBB/includes/template/twig/node/define.php49
-rw-r--r--phpBB/includes/template/twig/tokenparser/define.php33
-rw-r--r--phpBB/includes/template/twig/twig.php15
5 files changed, 196 insertions, 33 deletions
diff --git a/phpBB/includes/template/twig/definition.php b/phpBB/includes/template/twig/definition.php
new file mode 100644
index 0000000000..110437eb32
--- /dev/null
+++ b/phpBB/includes/template/twig/definition.php
@@ -0,0 +1,50 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* This class holds all DEFINE variables from the current page load
+*/
+class phpbb_template_twig_definition
+{
+ /** @var array **/
+ protected $definitions = array();
+
+ /**
+ * Get a DEFINE'd variable
+ *
+ * @param string $name
+ * @return mixed Null if not found
+ */
+ public function __call($name, $arguments)
+ {
+ return (isset($this->definitions[$name])) ? $this->definitions[$name] : null;
+ }
+
+ /**
+ * DEFINE a variable
+ *
+ * @param string $name
+ * @param mixed $value
+ * @return phpbb_template_twig_definition
+ */
+ public function set($name, $value)
+ {
+ $this->definitions[$name] = $value;
+
+ return $this;
+ }
+}
diff --git a/phpBB/includes/template/twig/lexer.php b/phpBB/includes/template/twig/lexer.php
index 9d348535a5..e8ceef3d13 100644
--- a/phpBB/includes/template/twig/lexer.php
+++ b/phpBB/includes/template/twig/lexer.php
@@ -20,6 +20,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer
public function tokenize($code, $filename = null)
{
$valid_starting_tokens = array(
+ // Commented out tokens are handled separately from the main replace
/*'BEGIN',
'BEGINELSE',
'END',*/
@@ -27,9 +28,8 @@ class phpbb_template_twig_lexer extends Twig_Lexer
'ELSE',
'ELSEIF',
'ENDIF',
- 'DEFINE',
- 'DEFINE',
- 'UNDEFINE',
+ /*'DEFINE',
+ 'UNDEFINE',*/
'ENDDEFINE',
/*'INCLUDE',
'INCLUDEPHP',*/
@@ -42,22 +42,21 @@ class phpbb_template_twig_lexer extends Twig_Lexer
// Fix our BEGIN statements
$code = $this->fix_begin_tokens($code);
- // Replace <!-- INCLUDE blah.html --> with {% include 'blah.html' %}
- $code = preg_replace('#<!-- INCLUDE(PHP)? (.*?) -->#', "{% INCLUDE$1 '$2' %}", $code);
+ // Fix our IF tokens
+ $code = $this->fix_if_tokens($code);
- // This strips the $ inside of a tag directly after the token, which was used in <!-- DEFINE $NAME
- $code = preg_replace('#<!-- DEFINE \$(.*)-->#', '<!-- DEFINE $1-->', $code);
+ // Fix our DEFINE tokens
+ $code = $this->fix_define_tokens($code);
- // This strips the . or $ inside of a tag directly before a variable name, which was used in <!-- IF .blah and <!-- IF $BLAH
- // In case of .varname, it replaces it with varname|length (as this is how it was treated before)
- $code = preg_replace_callback('#<!-- IF((.*)[\s][\$|\.]([^\s]+)(.*))-->#', array($this, 'tag_if_cleanup'), $code);
+ // Replace <!-- INCLUDE blah.html --> with {% include 'blah.html' %}
+ $code = preg_replace('#<!-- INCLUDE(PHP)? (.*?) -->#', "{% INCLUDE$1 '$2' %}", $code);
// Replace all of our starting tokens, <!-- TOKEN --> with Twig style, {% TOKEN %}
// This also strips outer parenthesis, <!-- IF (blah) --> becomes <!-- IF blah -->
$code = preg_replace('#<!-- (' . implode('|', $valid_starting_tokens) . ')(?: (.*?) ?)?-->#', '{% $1 $2 %}', $code);
- // Replace all of our variables, {VARNAME} or {$VARNAME}, with Twig style, {{ VARNAME }}
- $code = preg_replace('#{\$?([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code);
+ // Replace all of our variables, {VARNAME}, with Twig style, {{ VARNAME }}
+ $code = preg_replace('#{([a-zA-Z0-9_\.]+)}#', '{{ $1 }}', $code);
return parent::tokenize($code, $filename);
}
@@ -68,7 +67,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer
* Not meant to be used outside of this context, public because the anonymous function calls this
*
* @param string $code
- * @param array $parent_nodes
+ * @param array $parent_nodes (used in recursion)
* @return string
*/
public function fix_begin_tokens($code, $parent_nodes = array())
@@ -134,19 +133,56 @@ class phpbb_template_twig_lexer extends Twig_Lexer
}
/**
- * preg_replace_callback to clean up IF statements
- *
- * This strips the . or $ inside of a tag directly before a variable name.
- * Was used in <!-- IF .blah or <!-- IF $BLAH
+ * Fix IF statements
*
- * @param mixed $matches
+ * @param string $code
+ * @return string
*/
- protected function tag_if_cleanup($matches)
+ protected function fix_if_tokens($code)
{
- // Replace $TEST with TEST
- $matches[1] = preg_replace('#\s\$([a-zA-Z_0-9]+)#', ' $1', $matches[1]);
- $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9]+)#', ' $1|length', $matches[1]);
+ $callback = function($matches)
+ {
+ // Replace $TEST with definition.TEST
+ $matches[1] = preg_replace('#\s\$([a-zA-Z_0-9]+)#', ' definition.$1', $matches[1]);
- return '<!-- IF ' . $matches[1] . ' -->';
+ // Replace .test with test|length
+ $matches[1] = preg_replace('#\s\.([a-zA-Z_0-9]+)#', ' $1|length', $matches[1]);
+
+ return '<!-- IF ' . $matches[1] . ' -->';
+ };
+
+ return preg_replace_callback('#<!-- IF((.*)[\s][\$|\.]([^\s]+)(.*))-->#', $callback, $code);
+ }
+
+ /**
+ * Fix DEFINE statements and {$VARNAME} variables
+ *
+ * @param string $code
+ * @return string
+ */
+ protected function fix_define_tokens($code)
+ {
+ /**
+ * Changing $VARNAME to definition.varname because set is only local
+ * context (e.g. DEFINE $TEST will only make $TEST available in current
+ * template and any child templates, but not any parent templates).
+ *
+ * DEFINE handles setting it properly to definition in its node, but the
+ * variables reading FROM it need to be altered to definition.VARNAME
+ *
+ * Setting up definition as a class in the array passed to Twig
+ * ($context) makes set definition.TEST available in the global context
+ */
+
+ // Replace <!-- DEFINE $NAME with {% DEFINE definition.NAME
+ $code = preg_replace('#<!-- DEFINE \$(.*)-->#', '{% DEFINE $1 %}', $code);
+
+ // Changing UNDEFINE NAME to DEFINE NAME = null to save from creating an extra token parser/node
+ $code = preg_replace('#<!-- UNDEFINE \$(.*)-->#', '{% DEFINE $1= null %}', $code);
+
+ // Replace all of our variables, {$VARNAME}, with Twig style, {{ definition.VARNAME }}
+ $code = preg_replace('#{\$([a-zA-Z0-9_\.]+)}#', '{{ definition.$1 }}', $code);
+
+ return $code;
}
}
diff --git a/phpBB/includes/template/twig/node/define.php b/phpBB/includes/template/twig/node/define.php
new file mode 100644
index 0000000000..ef7565d27d
--- /dev/null
+++ b/phpBB/includes/template/twig/node/define.php
@@ -0,0 +1,49 @@
+<?php
+/**
+*
+* @package phpBB3
+* @copyright (c) 2013 phpBB Group, sections (c) 2009 Fabien Potencier, Armin Ronacher
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+class phpbb_template_twig_node_define extends Twig_Node
+{
+ public function __construct($capture, Twig_NodeInterface $name, Twig_NodeInterface $value, $lineno, $tag = null)
+ {
+ parent::__construct(array('name' => $name, 'value' => $value), array('capture' => $capture, 'safe' => false), $lineno, $tag);
+ }
+
+ /**
+ * Compiles the node to PHP.
+ *
+ * @param Twig_Compiler A Twig_Compiler instance
+ */
+ public function compile(Twig_Compiler $compiler)
+ {
+ $compiler->addDebugInfo($this);
+
+ if ($this->getAttribute('capture')) {
+ $compiler
+ ->write("ob_start();\n")
+ ->subcompile($this->getNode('value'))
+ ;
+
+ $compiler->raw(" = ('' === \$value = ob_get_clean()) ? '' : new Twig_Markup(\$value, \$this->env->getCharset())");
+ }
+ else
+ {
+ $compiler
+ ->write("\$value = '")
+ ->raw($this->getNode('value')->getAttribute('value'))
+ ->raw("';\n")
+ ;
+ }
+
+ $compiler
+ ->raw("\$context['definition']->set('")
+ ->raw($this->getNode('name')->getAttribute('name'))
+ ->raw("', \$value);\n")
+ ;
+ }
+}
diff --git a/phpBB/includes/template/twig/tokenparser/define.php b/phpBB/includes/template/twig/tokenparser/define.php
index 83f537a1ea..ebf7cb4c4a 100644
--- a/phpBB/includes/template/twig/tokenparser/define.php
+++ b/phpBB/includes/template/twig/tokenparser/define.php
@@ -7,8 +7,39 @@
*
*/
-class phpbb_template_twig_tokenparser_define extends Twig_TokenParser_Set
+class phpbb_template_twig_tokenparser_define extends Twig_TokenParser
{
+ /**
+ * Parses a token and returns a node.
+ *
+ * @param Twig_Token $token A Twig_Token instance
+ *
+ * @return Twig_NodeInterface A Twig_NodeInterface instance
+ */
+ public function parse(Twig_Token $token)
+ {
+ $lineno = $token->getLine();
+ $stream = $this->parser->getStream();
+ $name = $this->parser->getExpressionParser()->parseExpression();
+
+ $capture = false;
+ if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) {
+ $stream->next();
+ $value = $this->parser->getExpressionParser()->parseExpression();
+
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ } else {
+ $capture = true;
+
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+ $value = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ }
+
+ return new phpbb_template_twig_node_define($capture, $name, $value, $lineno, $this->getTag());
+ }
+
public function decideBlockEnd(Twig_Token $token)
{
return $token->test('ENDDEFINE');
diff --git a/phpBB/includes/template/twig/twig.php b/phpBB/includes/template/twig/twig.php
index cb2899a2fd..65776b7b6e 100644
--- a/phpBB/includes/template/twig/twig.php
+++ b/phpBB/includes/template/twig/twig.php
@@ -261,14 +261,8 @@ class phpbb_template_twig implements phpbb_template
return $result[0];
}
- try
- {
- $this->twig->display($this->filenames[$handle], $this->get_template_vars());
- }
- catch (Twig_Error $e)
- {
- throw $e;
- }
+ $context = &$this->get_template_vars();
+ $this->twig->display($this->filenames[$handle], $context);
return true;
}
@@ -454,7 +448,10 @@ class phpbb_template_twig implements phpbb_template
$vars = array_merge(
$vars,
$this->context->get_rootref(),
- $this->context->get_tpldata()
+ $this->context->get_tpldata(),
+ array(
+ 'definition' => new phpbb_template_twig_definition(),
+ )
);
// cleanup