diff options
author | Nathaniel Guse <nathaniel.guse@gmail.com> | 2013-06-29 11:07:10 -0500 |
---|---|---|
committer | Nathaniel Guse <nathaniel.guse@gmail.com> | 2013-06-29 11:07:10 -0500 |
commit | 64963b5962d9a4bf1888dd1642a32ba3f6037258 (patch) | |
tree | 005b45fe8b8aab32e69ca3a7e951fc25bf70837d /phpBB/includes | |
parent | abb7901edb61e551b5783254579fef737f6f5c37 (diff) | |
download | forums-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.php | 50 | ||||
-rw-r--r-- | phpBB/includes/template/twig/lexer.php | 82 | ||||
-rw-r--r-- | phpBB/includes/template/twig/node/define.php | 49 | ||||
-rw-r--r-- | phpBB/includes/template/twig/tokenparser/define.php | 33 | ||||
-rw-r--r-- | phpBB/includes/template/twig/twig.php | 15 |
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 |