diff options
Diffstat (limited to 'phpBB/phpbb/template/twig')
23 files changed, 510 insertions, 340 deletions
diff --git a/phpBB/phpbb/template/twig/definition.php b/phpBB/phpbb/template/twig/definition.php index 6557b209eb..945c46675e 100644 --- a/phpBB/phpbb/template/twig/definition.php +++ b/phpBB/phpbb/template/twig/definition.php @@ -7,18 +7,12 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig; /** * This class holds all DEFINE variables from the current page load */ -class phpbb_template_twig_definition +class definition { /** @var array **/ protected $definitions = array(); @@ -39,7 +33,7 @@ class phpbb_template_twig_definition * * @param string $name * @param mixed $value - * @return phpbb_template_twig_definition + * @return \phpbb\template\twig\definition */ public function set($name, $value) { @@ -53,7 +47,7 @@ class phpbb_template_twig_definition * * @param string $name * @param string $value - * @return phpbb_template_twig_definition + * @return \phpbb\template\twig\definition */ public function append($name, $value) { diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index b60cd72325..aa55f1e011 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -7,42 +7,47 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig; -class phpbb_template_twig_environment extends Twig_Environment +class environment extends \Twig_Environment { - /** @var array */ - protected $phpbb_extensions; - - /** @var phpbb_config */ + /** @var \phpbb\config\config */ protected $phpbb_config; + /** @var \phpbb\path_helper */ + protected $phpbb_path_helper; + + /** @var \phpbb\extension\manager */ + protected $extension_manager; + /** @var string */ protected $phpbb_root_path; + /** @var string */ + protected $web_root_path; + /** @var array **/ protected $namespace_look_up_order = array('__main__'); /** * Constructor * - * @param phpbb_config $phpbb_config - * @param array $phpbb_extensions Array of enabled extensions (name => path) + * @param \phpbb\config\config $phpbb_config + * @param \phpbb\path_helper + * @param \phpbb\extension\manager * @param string $phpbb_root_path * @param Twig_LoaderInterface $loader * @param array $options Array of options to pass to Twig */ - public function __construct($phpbb_config, $phpbb_extensions, $phpbb_root_path, Twig_LoaderInterface $loader = null, $options = array()) + public function __construct($phpbb_config, \phpbb\path_helper $path_helper, \phpbb\extension\manager $extension_manager = null, \Twig_LoaderInterface $loader = null, $options = array()) { $this->phpbb_config = $phpbb_config; - $this->phpbb_extensions = $phpbb_extensions; - $this->phpbb_root_path = $phpbb_root_path; + + $this->phpbb_path_helper = $path_helper; + $this->extension_manager = $extension_manager; + + $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); + $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); return parent::__construct($loader, $options); } @@ -56,13 +61,13 @@ class phpbb_template_twig_environment extends Twig_Environment */ public function get_phpbb_extensions() { - return $this->phpbb_extensions; + return ($this->extension_manager) ? $this->extension_manager->all_enabled() : array(); } /** * Get phpBB config * - * @return phpbb_config + * @return \phpbb\config\config */ public function get_phpbb_config() { @@ -80,6 +85,26 @@ class phpbb_template_twig_environment extends Twig_Environment } /** + * Get the web root path + * + * @return string + */ + public function get_web_root_path() + { + return $this->web_root_path; + } + + /** + * Get the phpbb path helper object + * + * @return \phpbb\path_helper + */ + public function get_path_helper() + { + return $this->phpbb_path_helper; + } + + /** * Get the namespace look up order * * @return array @@ -124,7 +149,7 @@ class phpbb_template_twig_environment extends Twig_Environment return parent::loadTemplate('@' . $namespace . '/' . $name, $index); } - catch (Twig_Error_Loader $e) + catch (\Twig_Error_Loader $e) { } } @@ -137,4 +162,39 @@ class phpbb_template_twig_environment extends Twig_Environment return parent::loadTemplate($name, $index); } } + + /** + * Finds a template by name. + * + * @param string $name The template name + * @return string + */ + public function findTemplate($name) + { + if (strpos($name, '@') === false) + { + foreach ($this->getNamespaceLookUpOrder() as $namespace) + { + try + { + if ($namespace === '__main__') + { + return parent::getLoader()->getCacheKey($name); + } + + return parent::getLoader()->getCacheKey('@' . $namespace . '/' . $name); + } + catch (Twig_Error_Loader $e) + { + } + } + + // We were unable to load any templates + throw $e; + } + else + { + return parent::getLoader()->getCacheKey($name); + } + } } diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index c279726434..6847dbd9f8 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -7,30 +7,24 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig; -class phpbb_template_twig_extension extends Twig_Extension +class extension extends \Twig_Extension { - /** @var phpbb_template_context */ + /** @var \phpbb\template\context */ protected $context; - /** @var phpbb_user */ + /** @var \phpbb\user */ protected $user; /** * Constructor * - * @param phpbb_template_context $context - * @param phpbb_user $user - * @return phpbb_template_twig_extension + * @param \phpbb\template\context $context + * @param \phpbb\user $user + * @return \phpbb\template\twig\extension */ - public function __construct(phpbb_template_context $context, $user) + public function __construct(\phpbb\template\context $context, $user) { $this->context = $context; $this->user = $user; @@ -46,54 +40,54 @@ class phpbb_template_twig_extension extends Twig_Extension return 'phpbb'; } - /** - * Returns the token parser instance to add to the existing list. - * - * @return array An array of Twig_TokenParser instances - */ + /** + * Returns the token parser instance to add to the existing list. + * + * @return array An array of Twig_TokenParser instances + */ public function getTokenParsers() { return array( - new phpbb_template_twig_tokenparser_define, - new phpbb_template_twig_tokenparser_include, - new phpbb_template_twig_tokenparser_includejs, - new phpbb_template_twig_tokenparser_includecss, - new phpbb_template_twig_tokenparser_event, - new phpbb_template_twig_tokenparser_includephp, - new phpbb_template_twig_tokenparser_php, + new \phpbb\template\twig\tokenparser\defineparser, + new \phpbb\template\twig\tokenparser\includeparser, + new \phpbb\template\twig\tokenparser\includejs, + new \phpbb\template\twig\tokenparser\includecss, + new \phpbb\template\twig\tokenparser\event, + new \phpbb\template\twig\tokenparser\includephp, + new \phpbb\template\twig\tokenparser\php, ); } - /** - * Returns a list of filters to add to the existing list. - * - * @return array An array of filters - */ - public function getFilters() - { + /** + * Returns a list of filters to add to the existing list. + * + * @return array An array of filters + */ + public function getFilters() + { return array( - new Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), - new Twig_SimpleFilter('addslashes', 'addslashes'), + new \Twig_SimpleFilter('subset', array($this, 'loop_subset'), array('needs_environment' => true)), + new \Twig_SimpleFilter('addslashes', 'addslashes'), ); - } - - /** - * Returns a list of global functions to add to the existing list. - * - * @return array An array of global functions - */ - public function getFunctions() - { + } + + /** + * Returns a list of global functions to add to the existing list. + * + * @return array An array of global functions + */ + public function getFunctions() + { return array( - new Twig_SimpleFunction('lang', array($this, 'lang')), + new \Twig_SimpleFunction('lang', array($this, 'lang')), ); } - /** - * Returns a list of operators to add to the existing list. - * - * @return array An array of operators - */ + /** + * Returns a list of operators to add to the existing list. + * + * @return array An array of operators + */ public function getOperators() { return array( @@ -102,42 +96,42 @@ class phpbb_template_twig_extension extends Twig_Extension ), array( // precedence settings are copied from similar operators in Twig core extension - '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), - 'eq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '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), - 'neq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '<>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'ne' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + 'neq' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + '<>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), - '===' => array('precedence' => 20, 'class' => 'phpbb_template_twig_node_expression_binary_equalequal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - '!==' => array('precedence' => 20, 'class' => 'phpbb_template_twig_node_expression_binary_notequalequal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + '===' => array('precedence' => 20, 'class' => '\phpbb\template\twig\node\expression\binary\equalequal', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + '!==' => array('precedence' => 20, 'class' => '\phpbb\template\twig\node\expression\binary\notequalequal', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), - 'gt' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'gte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'ge' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'lt' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'lte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'le' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'gt' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + 'gte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + 'ge' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + 'lt' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + 'lte' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), + 'le' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), - 'mod' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'mod' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT), ), ); - } + } /** - * 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) + * 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 Twig's slice (array_slice), except when $end is positive if ($end >= 1) diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index 7ab569313c..f4efc58540 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -7,15 +7,9 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig; -class phpbb_template_twig_lexer extends Twig_Lexer +class lexer extends \Twig_Lexer { public function tokenize($code, $filename = null) { @@ -74,8 +68,20 @@ class phpbb_template_twig_lexer extends Twig_Lexer ); // Fix tokens that may have inline variables (e.g. <!-- DEFINE $TEST = '{FOO}') + $code = $this->strip_surrounding_quotes(array( + 'INCLUDE', + 'INCLUDEPHP', + 'INCLUDEJS', + 'INCLUDECSS', + ), $code); $code = $this->fix_inline_variable_tokens(array( - 'DEFINE.+=', + 'DEFINE \$[a-zA-Z0-9_]+ =', + 'INCLUDE', + 'INCLUDEPHP', + 'INCLUDEJS', + 'INCLUDECSS', + ), $code); + $code = $this->add_surrounding_quotes(array( 'INCLUDE', 'INCLUDEPHP', 'INCLUDEJS', @@ -114,9 +120,29 @@ class phpbb_template_twig_lexer extends Twig_Lexer } /** + * Strip surrounding quotes + * + * First step to fix tokens that may have inline variables + * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE {TEST}.html + * + * @param array $tokens array of tokens to search for (imploded to a regular expression) + * @param string $code + * @return string + */ + protected function strip_surrounding_quotes($tokens, $code) + { + // Remove matching quotes at the beginning/end if a statement; + // E.g. 'asdf'"' -> asdf'" + // E.g. "asdf'"" -> asdf'" + // E.g. 'asdf'" -> 'asdf'" + return preg_replace('#<!-- (' . implode('|', $tokens) . ') (([\'"])?(.*?)\1) -->#', '<!-- $1 $2 -->', $code); + } + + /** * Fix tokens that may have inline variables * - * E.g. <!-- INCLUDE {TEST}.html + * Second step to fix tokens that may have inline variables + * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE ' ~ {TEST} ~ '.html * * @param array $tokens array of tokens to search for (imploded to a regular expression) * @param string $code @@ -126,23 +152,31 @@ class phpbb_template_twig_lexer extends Twig_Lexer { $callback = function($matches) { - // Remove matching quotes at the beginning/end if a statement; - // E.g. 'asdf'"' -> asdf'" - // E.g. "asdf'"" -> asdf'" - // E.g. 'asdf'" -> 'asdf'" - $matches[2] = preg_replace('#^([\'"])?(.*?)\1$#', '$2', $matches[2]); - // Replace template variables with start/end to parse variables (' ~ TEST ~ '.html) $matches[2] = preg_replace('#{([a-zA-Z0-9_\.$]+)}#', "'~ \$1 ~'", $matches[2]); - // Surround the matches in single quotes ('' ~ TEST ~ '.html') - return "<!-- {$matches[1]} '{$matches[2]}' -->"; + return "<!-- {$matches[1]} {$matches[2]} -->"; }; return preg_replace_callback('#<!-- (' . implode('|', $tokens) . ') (.+?) -->#', $callback, $code); } /** + * Add surrounding quotes + * + * Last step to fix tokens that may have inline variables + * E.g. <!-- INCLUDE '{TEST}.html' to <!-- INCLUDE '' ~ {TEST} ~ '.html' + * + * @param array $tokens array of tokens to search for (imploded to a regular expression) + * @param string $code + * @return string + */ + protected function add_surrounding_quotes($tokens, $code) + { + return preg_replace('#<!-- (' . implode('|', $tokens) . ') (.+?) -->#', '<!-- $1 \'$2\' -->', $code); + } + + /** * Fix begin tokens (convert our BEGIN to Twig for) * * Not meant to be used outside of this context, public because the anonymous function calls this @@ -161,6 +195,9 @@ class phpbb_template_twig_lexer extends Twig_Lexer $subset = trim(substr($matches[2], 1, -1)); // Remove parenthesis $body = $matches[3]; + // Replace <!-- BEGINELSE --> + $body = str_replace('<!-- BEGINELSE -->', '{% else %}', $body); + // Is the designer wanting to call another loop in a loop? // <!-- BEGIN loop --> // <!-- BEGIN !loop2 --> @@ -205,9 +242,6 @@ class phpbb_template_twig_lexer extends Twig_Lexer return "{% for {$name} 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); } @@ -229,18 +263,18 @@ class phpbb_template_twig_lexer extends Twig_Lexer { $inner = $matches[2]; // Replace $TEST with definition.TEST - $inner = preg_replace('#\s\$([a-zA-Z_0-9]+)#', ' definition.$1', $inner); + $inner = preg_replace('#(\s\(*!?)\$([a-zA-Z_0-9]+)#', '$1definition.$2', $inner); // Replace .foo with loops.foo|length - $inner = preg_replace('#\s\.([a-zA-Z_0-9]+)([^a-zA-Z_0-9\.])#', ' loops.$1|length$2', $inner); + $inner = preg_replace('#(\s\(*!?)\.([a-zA-Z_0-9]+)([^a-zA-Z_0-9\.])#', '$1loops.$2|length$3', $inner); // Replace .foo.bar with foo.bar|length - $inner = preg_replace('#\s\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', ' $1|length$2', $inner); + $inner = preg_replace('#(\s\(*!?)\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', '$1$2|length$3', $inner); return "<!-- {$matches[1]}IF{$inner}-->"; }; - return preg_replace_callback('#<!-- (ELSE)?IF((.*)[\s][\$|\.|!]([^\s]+)(.*))-->#', $callback, $code); + return preg_replace_callback('#<!-- (ELSE)?IF((.*?) \(*!?[\$|\.]([^\s]+)(.*?))-->#', $callback, $code); } /** @@ -264,10 +298,10 @@ class phpbb_template_twig_lexer extends Twig_Lexer */ // Replace <!-- DEFINE $NAME with {% DEFINE definition.NAME - $code = preg_replace('#<!-- DEFINE \$(.*)-->#', '{% DEFINE $1 %}', $code); + $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); + $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); diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php new file mode 100644 index 0000000000..e01e9de467 --- /dev/null +++ b/phpBB/phpbb/template/twig/loader.php @@ -0,0 +1,144 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\template\twig; + +/** +* Twig Template loader +* @package phpBB3 +*/ +class loader extends \Twig_Loader_Filesystem +{ + protected $safe_directories = array(); + + /** + * Set safe directories + * + * @param array $directories Array of directories that are safe (empty to clear) + * @return Twig_Loader_Filesystem + */ + public function setSafeDirectories($directories = array()) + { + $this->safe_directories = array(); + + if (!empty($directories)) + { + foreach ($directories as $directory) + { + $this->addSafeDirectory($directory); + } + } + + return $this; + } + + /** + * Add safe directory + * + * @param string $directory Directory that should be added + * @return Twig_Loader_Filesystem + */ + public function addSafeDirectory($directory) + { + $directory = phpbb_realpath($directory); + + if ($directory !== false) + { + $this->safe_directories[] = $directory; + } + + return $this; + } + + /** + * Get current safe directories + * + * @return array + */ + public function getSafeDirectories() + { + return $this->safe_directories; + } + + /** + * Override for parent::validateName() + * + * This is done because we added support for safe directories, and when Twig + * findTemplate() is called, validateName() is called first, which would + * always throw an exception if the file is outside of the configured + * template directories. + */ + protected function validateName($name) + { + return; + } + + /** + * Find the template + * + * Override for Twig_Loader_Filesystem::findTemplate to add support + * for loading from safe directories. + */ + protected function findTemplate($name) + { + $name = (string) $name; + + // normalize name + $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); + + // If this is in the cache we can skip the entire process below + // as it should have already been validated + if (isset($this->cache[$name])) { + return $this->cache[$name]; + } + + // First, find the template name. The override above of validateName + // causes the validateName process to be skipped for this call + $file = parent::findTemplate($name); + + try + { + // Try validating the name (which may throw an exception) + parent::validateName($name); + } + catch (Twig_Error_Loader $e) + { + if (strpos($e->getRawMessage(), 'Looks like you try to load a template outside configured directories') === 0) + { + // Ok, so outside of the configured template directories, we + // can now check if we're within a "safe" directory + + // Find the real path of the directory the file is in + $directory = phpbb_realpath(dirname($file)); + + if ($directory === false) + { + // Some sort of error finding the actual path, must throw the exception + throw $e; + } + + foreach ($this->safe_directories as $safe_directory) + { + if (strpos($directory, $safe_directory) === 0) + { + // The directory being loaded is below a directory + // that is "safe". We're good to load it! + return $file; + } + } + } + + // Not within any safe directories + throw $e; + } + + // No exception from validateName, safe to load. + return $file; + } +} diff --git a/phpBB/phpbb/template/twig/node/define.php b/phpBB/phpbb/template/twig/node/definenode.php index fcb19cc773..6a9969f8c6 100644 --- a/phpBB/phpbb/template/twig/node/define.php +++ b/phpBB/phpbb/template/twig/node/definenode.php @@ -7,18 +7,12 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\node; -class phpbb_template_twig_node_define extends Twig_Node +class definenode extends \Twig_Node { - public function __construct($capture, Twig_NodeInterface $name, Twig_NodeInterface $value, $lineno, $tag = null) + 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); } @@ -28,7 +22,7 @@ class phpbb_template_twig_node_define extends Twig_Node * * @param Twig_Compiler A Twig_Compiler instance */ - public function compile(Twig_Compiler $compiler) + public function compile(\Twig_Compiler $compiler) { $compiler->addDebugInfo($this); @@ -38,7 +32,7 @@ class phpbb_template_twig_node_define extends Twig_Node ->subcompile($this->getNode('value')) ; - $compiler->write("\$value = ('' === \$value = ob_get_clean()) ? '' : new Twig_Markup(\$value, \$this->env->getCharset());\n"); + $compiler->write("\$value = ('' === \$value = ob_get_clean()) ? '' : new \Twig_Markup(\$value, \$this->env->getCharset());\n"); } else { diff --git a/phpBB/phpbb/template/twig/node/event.php b/phpBB/phpbb/template/twig/node/event.php index c94e5fdf20..7a1181a866 100644 --- a/phpBB/phpbb/template/twig/node/event.php +++ b/phpBB/phpbb/template/twig/node/event.php @@ -7,18 +7,12 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\node; -class phpbb_template_twig_node_event extends Twig_Node +class event extends \Twig_Node { - /** + /** * The subdirectory in which all template listener files must be placed * @var string */ @@ -27,7 +21,7 @@ class phpbb_template_twig_node_event extends Twig_Node /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $lineno, $tag = null) + public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $tag = null) { $this->environment = $environment; @@ -39,7 +33,7 @@ class phpbb_template_twig_node_event extends Twig_Node * * @param Twig_Compiler A Twig_Compiler instance */ - public function compile(Twig_Compiler $compiler) + public function compile(\Twig_Compiler $compiler) { $compiler->addDebugInfo($this); @@ -55,10 +49,10 @@ class phpbb_template_twig_node_event extends Twig_Node // templates on page load rather than at compile. This is // slower, but makes developing extensions easier (no need to // purge the cache when a new event template file is added) - $compiler - ->write("if (\$this->env->getLoader()->exists('@{$ext_namespace}/{$location}.html')) {\n") - ->indent() - ; + $compiler + ->write("if (\$this->env->getLoader()->exists('@{$ext_namespace}/{$location}.html')) {\n") + ->indent() + ; } if (defined('DEBUG') || $this->environment->getLoader()->exists('@' . $ext_namespace . '/' . $location . '.html')) @@ -77,7 +71,7 @@ class phpbb_template_twig_node_event extends Twig_Node { $compiler ->outdent() - ->write("}\n\n") + ->write("}\n\n") ; } } diff --git a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php index 8ec2069114..f3bbfa6691 100644 --- a/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php +++ b/phpBB/phpbb/template/twig/node/expression/binary/equalequal.php @@ -7,18 +7,12 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\node\expression\binary; -class phpbb_template_twig_node_expression_binary_equalequal extends Twig_Node_Expression_Binary +class equalequal extends \Twig_Node_Expression_Binary { - public function operator(Twig_Compiler $compiler) + public function operator(\Twig_Compiler $compiler) { return $compiler->raw('==='); } diff --git a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php index 96f32c502e..c9c2687e08 100644 --- a/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php +++ b/phpBB/phpbb/template/twig/node/expression/binary/notequalequal.php @@ -7,18 +7,12 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\node\expression\binary; -class phpbb_template_twig_node_expression_binary_notequalequal extends Twig_Node_Expression_Binary +class notequalequal extends \Twig_Node_Expression_Binary { - public function operator(Twig_Compiler $compiler) + public function operator(\Twig_Compiler $compiler) { return $compiler->raw('!=='); } diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 1cab416c79..f6c9dc9c58 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -7,12 +7,14 @@ * */ -abstract class phpbb_template_twig_node_includeasset extends Twig_Node +namespace phpbb\template\twig\node; + +abstract class includeasset extends \Twig_Node { /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $lineno, $tag = null) + public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $tag = null) { $this->environment = $environment; @@ -23,7 +25,7 @@ abstract class phpbb_template_twig_node_includeasset extends Twig_Node * * @param Twig_Compiler A Twig_Compiler instance */ - public function compile(Twig_Compiler $compiler) + public function compile(\Twig_Compiler $compiler) { $compiler->addDebugInfo($this); @@ -33,17 +35,17 @@ abstract class phpbb_template_twig_node_includeasset extends Twig_Node ->write("\$asset_file = ") ->subcompile($this->getNode('expr')) ->raw(";\n") - ->write("\$asset = new phpbb_template_asset(\$asset_file);\n") + ->write("\$asset = new \phpbb\\template\\asset(\$asset_file, \$this->getEnvironment()->get_path_helper());\n") ->write("if (substr(\$asset_file, 0, 2) !== './' && \$asset->is_relative()) {\n") ->indent() ->write("\$asset_path = \$asset->get_path();") ->write("\$local_file = \$this->getEnvironment()->get_phpbb_root_path() . \$asset_path;\n") ->write("if (!file_exists(\$local_file)) {\n") ->indent() - ->write("\$local_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$asset_path);\n") + ->write("\$local_file = \$this->getEnvironment()->findTemplate(\$asset_path);\n") ->write("\$asset->set_path(\$local_file, true);\n") ->outdent() - ->write("\$asset->add_assets_version({$config['assets_version']});\n") + ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") ->write("\$asset_file = \$asset->get_url();\n") ->write("}\n") ->outdent() @@ -71,5 +73,5 @@ abstract class phpbb_template_twig_node_includeasset extends Twig_Node * @param Twig_Compiler A Twig_Compiler instance * @return null */ - abstract protected function append_asset(Twig_Compiler $compiler); + abstract protected function append_asset(\Twig_Compiler $compiler); } diff --git a/phpBB/phpbb/template/twig/node/includecss.php b/phpBB/phpbb/template/twig/node/includecss.php index a9d9b46d69..deb279fa4a 100644 --- a/phpBB/phpbb/template/twig/node/includecss.php +++ b/phpBB/phpbb/template/twig/node/includecss.php @@ -7,7 +7,9 @@ * */ -class phpbb_template_twig_node_includecss extends phpbb_template_twig_node_includeasset +namespace phpbb\template\twig\node; + +class includecss extends \phpbb\template\twig\node\includeasset { /** * {@inheritdoc} @@ -20,7 +22,7 @@ class phpbb_template_twig_node_includecss extends phpbb_template_twig_node_inclu /** * {@inheritdoc} */ - public function append_asset(Twig_Compiler $compiler) + public function append_asset(\Twig_Compiler $compiler) { $compiler ->raw("<link href=\"' . ") diff --git a/phpBB/phpbb/template/twig/node/includejs.php b/phpBB/phpbb/template/twig/node/includejs.php index 2b4b55fb0a..696b640eac 100644 --- a/phpBB/phpbb/template/twig/node/includejs.php +++ b/phpBB/phpbb/template/twig/node/includejs.php @@ -7,7 +7,9 @@ * */ -class phpbb_template_twig_node_includejs extends phpbb_template_twig_node_includeasset +namespace phpbb\template\twig\node; + +class includejs extends \phpbb\template\twig\node\includeasset { /** * {@inheritdoc} @@ -20,7 +22,7 @@ class phpbb_template_twig_node_includejs extends phpbb_template_twig_node_includ /** * {@inheritdoc} */ - protected function append_asset(Twig_Compiler $compiler) + protected function append_asset(\Twig_Compiler $compiler) { $config = $this->environment->get_phpbb_config(); diff --git a/phpBB/phpbb/template/twig/node/include.php b/phpBB/phpbb/template/twig/node/includenode.php index 5c6ae1bbcf..d9b45d6407 100644 --- a/phpBB/phpbb/template/twig/node/include.php +++ b/phpBB/phpbb/template/twig/node/includenode.php @@ -7,23 +7,17 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\node; -class phpbb_template_twig_node_include extends Twig_Node_Include +class includenode extends \Twig_Node_Include { /** * Compiles the node to PHP. * * @param Twig_Compiler A Twig_Compiler instance */ - public function compile(Twig_Compiler $compiler) + public function compile(\Twig_Compiler $compiler) { $compiler->addDebugInfo($this); diff --git a/phpBB/phpbb/template/twig/node/includephp.php b/phpBB/phpbb/template/twig/node/includephp.php index dbe54f0e1a..3f4621c0a9 100644 --- a/phpBB/phpbb/template/twig/node/includephp.php +++ b/phpBB/phpbb/template/twig/node/includephp.php @@ -7,21 +7,15 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\node; -class phpbb_template_twig_node_includephp extends Twig_Node +class includephp extends \Twig_Node { /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Expression $expr, phpbb_template_twig_environment $environment, $ignoreMissing = false, $lineno, $tag = null) + public function __construct(\Twig_Node_Expression $expr, \phpbb\template\twig\environment $environment, $lineno, $ignoreMissing = false, $tag = null) { $this->environment = $environment; @@ -33,7 +27,7 @@ class phpbb_template_twig_node_includephp extends Twig_Node * * @param Twig_Compiler A Twig_Compiler instance */ - public function compile(Twig_Compiler $compiler) + public function compile(\Twig_Compiler $compiler) { $compiler->addDebugInfo($this); @@ -80,7 +74,7 @@ class phpbb_template_twig_node_includephp extends Twig_Node if ($this->getAttribute('ignore_missing')) { $compiler ->outdent() - ->write("} catch (Twig_Error_Loader \$e) {\n") + ->write("} catch (\Twig_Error_Loader \$e) {\n") ->indent() ->write("// ignore missing template\n") ->outdent() diff --git a/phpBB/phpbb/template/twig/node/php.php b/phpBB/phpbb/template/twig/node/php.php index c11539ea7f..2b18551266 100644 --- a/phpBB/phpbb/template/twig/node/php.php +++ b/phpBB/phpbb/template/twig/node/php.php @@ -7,21 +7,15 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\node; -class phpbb_template_twig_node_php extends Twig_Node +class php extends \Twig_Node { /** @var Twig_Environment */ protected $environment; - public function __construct(Twig_Node_Text $text, phpbb_template_twig_environment $environment, $lineno, $tag = null) + public function __construct(\Twig_Node_Text $text, \phpbb\template\twig\environment $environment, $lineno, $tag = null) { $this->environment = $environment; @@ -33,7 +27,7 @@ class phpbb_template_twig_node_php extends Twig_Node * * @param Twig_Compiler A Twig_Compiler instance */ - public function compile(Twig_Compiler $compiler) + public function compile(\Twig_Compiler $compiler) { $compiler->addDebugInfo($this); diff --git a/phpBB/phpbb/template/twig/tokenparser/define.php b/phpBB/phpbb/template/twig/tokenparser/defineparser.php index 4ea15388c4..8484f2e81a 100644 --- a/phpBB/phpbb/template/twig/tokenparser/define.php +++ b/phpBB/phpbb/template/twig/tokenparser/defineparser.php @@ -7,16 +7,10 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\tokenparser; -class phpbb_template_twig_tokenparser_define extends Twig_TokenParser +class defineparser extends \Twig_TokenParser { /** * Parses a token and returns a node. @@ -25,31 +19,38 @@ class phpbb_template_twig_tokenparser_define extends Twig_TokenParser * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - public function parse(Twig_Token $token) + 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, '=')) { + if ($stream->test(\Twig_Token::OPERATOR_TYPE, '=')) { $stream->next(); $value = $this->parser->getExpressionParser()->parseExpression(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + if ($value instanceof \Twig_Node_Expression_Name) + { + // This would happen if someone improperly formed their DEFINE syntax + // e.g. <!-- DEFINE $VAR = foo --> + throw new \Twig_Error_Syntax('Invalid DEFINE', $token->getLine(), $this->parser->getFilename()); + } + + $stream->expect(\Twig_Token::BLOCK_END_TYPE); } else { $capture = true; - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); $value = $this->parser->subparse(array($this, 'decideBlockEnd'), true); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); } - return new phpbb_template_twig_node_define($capture, $name, $value, $lineno, $this->getTag()); + return new \phpbb\template\twig\node\definenode($capture, $name, $value, $lineno, $this->getTag()); } - public function decideBlockEnd(Twig_Token $token) + public function decideBlockEnd(\Twig_Token $token) { return $token->test('ENDDEFINE'); } diff --git a/phpBB/phpbb/template/twig/tokenparser/event.php b/phpBB/phpbb/template/twig/tokenparser/event.php index e4dddd6dcc..8864e879f8 100644 --- a/phpBB/phpbb/template/twig/tokenparser/event.php +++ b/phpBB/phpbb/template/twig/tokenparser/event.php @@ -7,16 +7,10 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\tokenparser; -class phpbb_template_twig_tokenparser_event extends Twig_TokenParser +class event extends \Twig_TokenParser { /** * Parses a token and returns a node. @@ -25,14 +19,14 @@ class phpbb_template_twig_tokenparser_event extends Twig_TokenParser * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - public function parse(Twig_Token $token) + public function parse(\Twig_Token $token) { $expr = $this->parser->getExpressionParser()->parseExpression(); $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_event($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); + return new \phpbb\template\twig\node\event($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); } /** diff --git a/phpBB/phpbb/template/twig/tokenparser/includecss.php b/phpBB/phpbb/template/twig/tokenparser/includecss.php index 6c24dda647..7bf4c610b1 100644 --- a/phpBB/phpbb/template/twig/tokenparser/includecss.php +++ b/phpBB/phpbb/template/twig/tokenparser/includecss.php @@ -7,7 +7,9 @@ * */ -class phpbb_template_twig_tokenparser_includecss extends Twig_TokenParser +namespace phpbb\template\twig\tokenparser; + +class includecss extends \Twig_TokenParser { /** * Parses a token and returns a node. @@ -16,14 +18,14 @@ class phpbb_template_twig_tokenparser_includecss extends Twig_TokenParser * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - public function parse(Twig_Token $token) + public function parse(\Twig_Token $token) { $expr = $this->parser->getExpressionParser()->parseExpression(); $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_includecss($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); + return new \phpbb\template\twig\node\includecss($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); } /** diff --git a/phpBB/phpbb/template/twig/tokenparser/includejs.php b/phpBB/phpbb/template/twig/tokenparser/includejs.php index b02b2f89ba..0e46915b86 100644 --- a/phpBB/phpbb/template/twig/tokenparser/includejs.php +++ b/phpBB/phpbb/template/twig/tokenparser/includejs.php @@ -7,16 +7,10 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\tokenparser; -class phpbb_template_twig_tokenparser_includejs extends Twig_TokenParser +class includejs extends \Twig_TokenParser { /** * Parses a token and returns a node. @@ -25,14 +19,14 @@ class phpbb_template_twig_tokenparser_includejs extends Twig_TokenParser * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - public function parse(Twig_Token $token) + public function parse(\Twig_Token $token) { $expr = $this->parser->getExpressionParser()->parseExpression(); $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_includejs($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); + return new \phpbb\template\twig\node\includejs($expr, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); } /** diff --git a/phpBB/phpbb/template/twig/tokenparser/include.php b/phpBB/phpbb/template/twig/tokenparser/includeparser.php index 520f9fd1a0..d351f1b4cd 100644 --- a/phpBB/phpbb/template/twig/tokenparser/include.php +++ b/phpBB/phpbb/template/twig/tokenparser/includeparser.php @@ -7,16 +7,10 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\tokenparser; -class phpbb_template_twig_tokenparser_include extends Twig_TokenParser_Include +class includeparser extends \Twig_TokenParser_Include { /** * Parses a token and returns a node. @@ -25,13 +19,13 @@ class phpbb_template_twig_tokenparser_include extends Twig_TokenParser_Include * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - public function parse(Twig_Token $token) + public function parse(\Twig_Token $token) { $expr = $this->parser->getExpressionParser()->parseExpression(); list($variables, $only, $ignoreMissing) = $this->parseArguments(); - return new phpbb_template_twig_node_include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + return new \phpbb\template\twig\node\includenode($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); } /** diff --git a/phpBB/phpbb/template/twig/tokenparser/includephp.php b/phpBB/phpbb/template/twig/tokenparser/includephp.php index 13fe6de8a6..1b3d1742e3 100644 --- a/phpBB/phpbb/template/twig/tokenparser/includephp.php +++ b/phpBB/phpbb/template/twig/tokenparser/includephp.php @@ -7,16 +7,10 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\tokenparser; -class phpbb_template_twig_tokenparser_includephp extends Twig_TokenParser +class includephp extends \Twig_TokenParser { /** * Parses a token and returns a node. @@ -25,23 +19,23 @@ class phpbb_template_twig_tokenparser_includephp extends Twig_TokenParser * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - public function parse(Twig_Token $token) + public function parse(\Twig_Token $token) { $expr = $this->parser->getExpressionParser()->parseExpression(); $stream = $this->parser->getStream(); $ignoreMissing = false; - if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) { + if ($stream->test(\Twig_Token::NAME_TYPE, 'ignore')) { $stream->next(); - $stream->expect(Twig_Token::NAME_TYPE, 'missing'); + $stream->expect(\Twig_Token::NAME_TYPE, 'missing'); $ignoreMissing = true; } - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_includephp($expr, $this->parser->getEnvironment(), $ignoreMissing, $token->getLine(), $this->getTag()); + return new \phpbb\template\twig\node\includephp($expr, $this->parser->getEnvironment(), $token->getLine(), $ignoreMissing, $this->getTag()); } /** diff --git a/phpBB/phpbb/template/twig/tokenparser/php.php b/phpBB/phpbb/template/twig/tokenparser/php.php index 197980a59a..b427969e2d 100644 --- a/phpBB/phpbb/template/twig/tokenparser/php.php +++ b/phpBB/phpbb/template/twig/tokenparser/php.php @@ -7,16 +7,10 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig\tokenparser; -class phpbb_template_twig_tokenparser_php extends Twig_TokenParser +class php extends \Twig_TokenParser { /** * Parses a token and returns a node. @@ -25,20 +19,20 @@ class phpbb_template_twig_tokenparser_php extends Twig_TokenParser * * @return Twig_NodeInterface A Twig_NodeInterface instance */ - public function parse(Twig_Token $token) + public function parse(\Twig_Token $token) { $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); $body = $this->parser->subparse(array($this, 'decideEnd'), true); - $stream->expect(Twig_Token::BLOCK_END_TYPE); + $stream->expect(\Twig_Token::BLOCK_END_TYPE); - return new phpbb_template_twig_node_php($body, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); + return new \phpbb\template\twig\node\php($body, $this->parser->getEnvironment(), $token->getLine(), $this->getTag()); } - public function decideEnd(Twig_Token $token) + public function decideEnd(\Twig_Token $token) { return $token->test('ENDPHP'); } @@ -51,5 +45,5 @@ class phpbb_template_twig_tokenparser_php extends Twig_TokenParser public function getTag() { return 'PHP'; - } + } } diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 1ed89d3ccc..83630f5992 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -7,19 +7,13 @@ * */ -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} +namespace phpbb\template\twig; /** * Twig Template class. * @package phpBB3 */ -class phpbb_template_twig extends phpbb_template_base +class twig extends \phpbb\template\base { /** * Path of the cache directory for the template @@ -31,6 +25,12 @@ class phpbb_template_twig extends phpbb_template_base private $cachepath = ''; /** + * phpBB path helper + * @var \phpbb\path_helper + */ + protected $path_helper; + + /** * phpBB root path * @var string */ @@ -44,20 +44,20 @@ class phpbb_template_twig extends phpbb_template_base /** * phpBB config instance - * @var phpbb_config + * @var \phpbb\config\config */ protected $config; /** * Current user - * @var phpbb_user + * @var \phpbb\user */ protected $user; /** * Extension manager. * - * @var phpbb_extension_manager + * @var \phpbb\extension\manager */ protected $extension_manager; @@ -71,32 +71,31 @@ class phpbb_template_twig extends phpbb_template_base /** * Constructor. * - * @param string $phpbb_root_path phpBB root path - * @param string $php_ext php extension (typically 'php') - * @param phpbb_config $config - * @param phpbb_user $user - * @param phpbb_template_context $context template context - * @param phpbb_extension_manager $extension_manager extension manager, if null then template events will not be invoked - * @param string $adm_relative_path relative path to adm directory + * @param \phpbb\path_helper $path_helper + * @param \phpbb\config\config $config + * @param \phpbb\user $user + * @param \phpbb\template\context $context template context + * @param \phpbb\extension\manager $extension_manager extension manager, if null then template events will not be invoked */ - public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_context $context, phpbb_extension_manager $extension_manager = null, $adm_relative_path = null) + public function __construct(\phpbb\path_helper $path_helper, $config, $user, \phpbb\template\context $context, \phpbb\extension\manager $extension_manager = null) { - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $php_ext; + $this->path_helper = $path_helper; + $this->phpbb_root_path = $path_helper->get_phpbb_root_path(); + $this->php_ext = $path_helper->get_php_ext(); $this->config = $config; $this->user = $user; $this->context = $context; $this->extension_manager = $extension_manager; - $this->cachepath = $phpbb_root_path . 'cache/twig/'; + $this->cachepath = $this->phpbb_root_path . 'cache/twig/'; // Initiate the loader, __main__ namespace paths will be setup later in set_style_names() - $loader = new Twig_Loader_Filesystem(''); + $loader = new \phpbb\template\twig\loader(''); - $this->twig = new phpbb_template_twig_environment( + $this->twig = new \phpbb\template\twig\environment( $this->config, - ($this->extension_manager) ? $this->extension_manager->all_enabled() : array(), - $this->phpbb_root_path, + $this->path_helper, + $this->extension_manager, $loader, array( 'cache' => (defined('IN_INSTALL')) ? false : $this->cachepath, @@ -107,27 +106,27 @@ class phpbb_template_twig extends phpbb_template_base ); $this->twig->addExtension( - new phpbb_template_twig_extension( + new \phpbb\template\twig\extension( $this->context, $this->user ) ); - $lexer = new phpbb_template_twig_lexer($this->twig); + $lexer = new \phpbb\template\twig\lexer($this->twig); $this->twig->setLexer($lexer); // Add admin namespace - if ($adm_relative_path !== null && is_dir($this->phpbb_root_path . $adm_relative_path . 'style/')) + if ($this->path_helper->get_adm_relative_path() !== null && is_dir($this->phpbb_root_path . $this->path_helper->get_adm_relative_path() . 'style/')) { - $this->twig->getLoader()->setPaths($this->phpbb_root_path . $adm_relative_path . 'style/', 'admin'); + $this->twig->getLoader()->setPaths($this->phpbb_root_path . $this->path_helper->get_adm_relative_path() . 'style/', 'admin'); } } /** * Clear the cache * - * @return phpbb_template + * @return \phpbb\template\template */ public function clear_cache() { @@ -164,7 +163,7 @@ class phpbb_template_twig extends phpbb_template_base * @param array $style_directories The directories to add style paths for * E.g. array('ext/foo/bar/styles', 'styles') * Default: array('styles') (phpBB's style directory) - * @return phpbb_template $this + * @return \phpbb\template\template $this */ public function set_style($style_directories = array('styles')) { @@ -181,11 +180,15 @@ class phpbb_template_twig extends phpbb_template_base { foreach ($names as $name) { - $path = $this->phpbb_root_path . trim($directory, '/') . "/{$name}/template/"; + $path = $this->phpbb_root_path . trim($directory, '/') . "/{$name}/"; + $template_path = $path . 'template/'; - if (is_dir($path)) + if (is_dir($template_path)) { - $paths[] = $path; + // Add the base style directory as a safe directory + $this->twig->getLoader()->addSafeDirectory($path); + + $paths[] = $template_path; } } } @@ -221,7 +224,7 @@ class phpbb_template_twig extends phpbb_template_base $this->twig->getLoader()->setPaths($paths); // Add all namespaces for all extensions - if ($this->extension_manager instanceof phpbb_extension_manager) + if ($this->extension_manager instanceof \phpbb\extension\manager) { $names[] = 'all'; @@ -233,11 +236,15 @@ class phpbb_template_twig extends phpbb_template_base foreach ($names as $style_name) { - $ext_style_path = $ext_path . 'styles/' . $style_name . '/template'; + $ext_style_path = $ext_path . 'styles/' . $style_name . '/'; + $ext_style_template_path = $ext_style_path . 'template/'; - if (is_dir($ext_style_path)) + if (is_dir($ext_style_template_path)) { - $paths[] = $ext_style_path; + // Add the base style directory as a safe directory + $this->twig->getLoader()->addSafeDirectory($ext_style_path); + + $paths[] = $ext_style_template_path; } } @@ -256,7 +263,7 @@ class phpbb_template_twig extends phpbb_template_base * This function calls hooks. * * @param string $handle Handle to display - * @return phpbb_template $this + * @return \phpbb\template\template $this */ public function display($handle) { @@ -278,7 +285,7 @@ class phpbb_template_twig extends phpbb_template_base * @param string $handle Handle to operate on * @param string $template_var Template variable to assign compiled handle to * @param bool $return_content If true return compiled handle, otherwise assign to $template_var - * @return phpbb_template|string if $return_content is true return string of the compiled handle, otherwise return $this + * @return \phpbb\template\template|string if $return_content is true return string of the compiled handle, otherwise return $this */ public function assign_display($handle, $template_var = '', $return_content = true) { @@ -304,7 +311,7 @@ class phpbb_template_twig extends phpbb_template_base $vars = array_merge( $context_vars['.'][0], // To get normal vars array( - 'definition' => new phpbb_template_twig_definition(), + 'definition' => new \phpbb\template\twig\definition(), 'user' => $this->user, 'loops' => $context_vars, // To get loops ) |
