diff options
| author | Benjamin Southall <applemansigloo@gmail.com> | 2019-02-26 10:11:12 +1000 |
|---|---|---|
| committer | Benjamin Southall <applemansigloo@gmail.com> | 2019-02-26 10:11:12 +1000 |
| commit | f79395851b044689567e0e6c9504acbcaa742782 (patch) | |
| tree | ee539aee9ffa90e8accd6f130b30a8ebed7a232e /inc/lib/Twig/Parser.php | |
| parent | 28f32baf0125ca5085266e73dc5071e5814d8e3b (diff) | |
Twig update to latest Twig 1.x legacy as per vichan
Diffstat (limited to 'inc/lib/Twig/Parser.php')
| -rw-r--r-- | inc/lib/Twig/Parser.php | 140 |
1 files changed, 79 insertions, 61 deletions
diff --git a/inc/lib/Twig/Parser.php b/inc/lib/Twig/Parser.php index bebdd9bb..6de879a5 100644 --- a/inc/lib/Twig/Parser.php +++ b/inc/lib/Twig/Parser.php @@ -3,8 +3,8 @@ /* * This file is part of Twig. * - * (c) 2009 Fabien Potencier - * (c) 2009 Armin Ronacher + * (c) Fabien Potencier + * (c) Armin Ronacher * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -31,44 +31,49 @@ class Twig_Parser implements Twig_ParserInterface protected $importedSymbols; protected $traits; protected $embeddedTemplates = array(); + private $varNameSalt = 0; - /** - * Constructor. - * - * @param Twig_Environment $env A Twig_Environment instance - */ public function __construct(Twig_Environment $env) { $this->env = $env; } + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function getEnvironment() { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED); + return $this->env; } public function getVarName() { - return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false)); + return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->stream->getSourceContext()->getCode().$this->varNameSalt++)); } + /** + * @deprecated since 1.27 (to be removed in 2.0). Use $parser->getStream()->getSourceContext()->getPath() instead. + */ public function getFilename() { - return $this->stream->getFilename(); + @trigger_error(sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use $parser->getStream()->getSourceContext()->getPath() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->stream->getSourceContext()->getName(); } - /** - * Converts a token stream to a node tree. - * - * @param Twig_TokenStream $stream A token stream instance - * - * @return Twig_Node_Module A node tree - */ public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false) { // push all variables into the stack to keep the current state of the parser - $vars = get_object_vars($this); - unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser']); + // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336 + // This hack can be removed when min version if PHP 7.0 + $vars = array(); + foreach ($this as $k => $v) { + $vars[$k] = $v; + } + + unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser'], $vars['reservedMacroNames']); $this->stack[] = $vars; // tag handlers @@ -83,7 +88,7 @@ class Twig_Parser implements Twig_ParserInterface } if (null === $this->expressionParser) { - $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators()); + $this->expressionParser = new Twig_ExpressionParser($this, $this->env); } $this->stream = $stream; @@ -94,18 +99,17 @@ class Twig_Parser implements Twig_ParserInterface $this->blockStack = array(); $this->importedSymbols = array(array()); $this->embeddedTemplates = array(); + $this->varNameSalt = 0; try { $body = $this->subparse($test, $dropNeedle); - if (null !== $this->parent) { - if (null === $body = $this->filterBodyNodes($body)) { - $body = new Twig_Node(); - } + if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) { + $body = new Twig_Node(); } } catch (Twig_Error_Syntax $e) { - if (!$e->getTemplateFile()) { - $e->setTemplateFile($this->getFilename()); + if (!$e->getSourceContext()) { + $e->setSourceContext($this->stream->getSourceContext()); } if (!$e->getTemplateLine()) { @@ -115,7 +119,7 @@ class Twig_Parser implements Twig_ParserInterface throw $e; } - $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename()); + $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext()); $traverser = new Twig_NodeTraverser($this->env, $this->visitors); @@ -151,8 +155,8 @@ class Twig_Parser implements Twig_ParserInterface $this->stream->next(); $token = $this->getCurrentToken(); - if ($token->getType() !== Twig_Token::NAME_TYPE) { - throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->getFilename()); + if (Twig_Token::NAME_TYPE !== $token->getType()) { + throw new Twig_Error_Syntax('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext()); } if (null !== $test && call_user_func($test, $token)) { @@ -170,20 +174,17 @@ class Twig_Parser implements Twig_ParserInterface $subparser = $this->handlers->getTokenParser($token->getValue()); if (null === $subparser) { if (null !== $test) { - $error = sprintf('Unexpected tag name "%s"', $token->getValue()); + $e = new Twig_Error_Syntax(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()); + if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) { - $error .= sprintf(' (expecting closing tag for the "%s" tag defined near line %s)', $test[0]->getTag(), $lineno); + $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno)); } - - throw new Twig_Error_Syntax($error, $token->getLine(), $this->getFilename()); - } - - $message = sprintf('Unknown tag name "%s"', $token->getValue()); - if ($alternatives = $this->env->computeAlternatives($token->getValue(), array_keys($this->env->getTags()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } else { + $e = new Twig_Error_Syntax(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()); + $e->addSuggestions($token->getValue(), array_keys($this->env->getTags())); } - throw new Twig_Error_Syntax($message, $token->getLine(), $this->getFilename()); + throw $e; } $this->stream->next(); @@ -195,7 +196,7 @@ class Twig_Parser implements Twig_ParserInterface break; default: - throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename()); + throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext()); } } @@ -206,13 +207,23 @@ class Twig_Parser implements Twig_ParserInterface return new Twig_Node($rv, array(), $lineno); } + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function addHandler($name, $class) { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED); + $this->handlers[$name] = $class; } + /** + * @deprecated since 1.27 (to be removed in 2.0) + */ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) { + @trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0.', E_USER_DEPRECATED); + $this->visitors[] = $visitor; } @@ -246,9 +257,9 @@ class Twig_Parser implements Twig_ParserInterface return $this->blocks[$name]; } - public function setBlock($name, $value) + public function setBlock($name, Twig_Node_Block $value) { - $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine()); + $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getTemplateLine()); } public function hasMacro($name) @@ -258,19 +269,28 @@ class Twig_Parser implements Twig_ParserInterface public function setMacro($name, Twig_Node_Macro $node) { + if ($this->isReservedMacroName($name)) { + throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext()); + } + + $this->macros[$name] = $node; + } + + public function isReservedMacroName($name) + { if (null === $this->reservedMacroNames) { $this->reservedMacroNames = array(); $r = new ReflectionClass($this->env->getBaseTemplateClass()); foreach ($r->getMethods() as $method) { - $this->reservedMacroNames[] = $method->getName(); - } - } + $methodName = strtolower($method->getName()); - if (in_array($name, $this->reservedMacroNames)) { - throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename()); + if ('get' === substr($methodName, 0, 3) && isset($methodName[3])) { + $this->reservedMacroNames[] = substr($methodName, 3); + } + } } - $this->macros[$name] = $node; + return in_array(strtolower($name), $this->reservedMacroNames); } public function addTrait($trait) @@ -320,9 +340,7 @@ class Twig_Parser implements Twig_ParserInterface } /** - * Gets the expression parser. - * - * @return Twig_ExpressionParser The expression parser + * @return Twig_ExpressionParser */ public function getExpressionParser() { @@ -340,9 +358,7 @@ class Twig_Parser implements Twig_ParserInterface } /** - * Gets the token stream. - * - * @return Twig_TokenStream The token stream + * @return Twig_TokenStream */ public function getStream() { @@ -350,9 +366,7 @@ class Twig_Parser implements Twig_ParserInterface } /** - * Gets the current token. - * - * @return Twig_Token The current token + * @return Twig_Token */ public function getCurrentToken() { @@ -368,14 +382,14 @@ class Twig_Parser implements Twig_ParserInterface (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface) ) { if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) { - throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename()); + throw new Twig_Error_Syntax('A template that extends another one cannot start with a byte order mark (BOM); it must be removed.', $node->getTemplateLine(), $this->stream->getSourceContext()); } - throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename()); + throw new Twig_Error_Syntax('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext()); } - // bypass "set" nodes as they "capture" the output - if ($node instanceof Twig_Node_Set) { + // bypass nodes that will "capture" the output + if ($node instanceof Twig_NodeCaptureInterface) { return $node; } @@ -384,7 +398,7 @@ class Twig_Parser implements Twig_ParserInterface } foreach ($node as $k => $n) { - if (null !== $n && null === $n = $this->filterBodyNodes($n)) { + if (null !== $n && null === $this->filterBodyNodes($n)) { $node->removeNode($k); } } @@ -392,3 +406,7 @@ class Twig_Parser implements Twig_ParserInterface return $node; } } + +class_alias('Twig_Parser', 'Twig\Parser', false); +class_exists('Twig_Node'); +class_exists('Twig_TokenStream'); |
