예제 #1
0
 public function getFunctionNode($name, $line)
 {
     $args = $this->parseArguments();
     switch ($name) {
         case 'parent':
             if (!count($this->parser->getBlockStack())) {
                 throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line);
             }
             if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
                 throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line);
             }
             return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
         case 'block':
             return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line);
         case 'attribute':
             if (count($args) < 2) {
                 throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line);
             }
             return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line);
         default:
             if (null !== ($alias = $this->parser->getImportedFunction($name))) {
                 $arguments = new Twig_Node_Expression_Array(array(), $line);
                 foreach ($args as $n) {
                     $arguments->addElement($n);
                 }
                 $node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line);
                 $node->setAttribute('safe', true);
                 return $node;
             }
             $class = $this->getFunctionNodeClass($name);
             return new $class($name, $args, $line);
     }
 }
예제 #2
0
 public function parseSubscriptExpression($node)
 {
     $stream = $this->parser->getStream();
     $token = $stream->next();
     $lineno = $token->getLine();
     $arguments = new Twig_Node_Expression_Array(array(), $lineno);
     $type = Twig_Template::ANY_CALL;
     if ($token->getValue() == '.') {
         $token = $stream->next();
         if ($token->getType() == Twig_Token::NAME_TYPE || $token->getType() == Twig_Token::NUMBER_TYPE || $token->getType() == Twig_Token::OPERATOR_TYPE && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue())) {
             $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
             if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
                 $type = Twig_TemplateInterface::METHOD_CALL;
                 foreach ($this->parseArguments() as $n) {
                     $arguments->addElement($n);
                 }
             }
         } else {
             throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename());
         }
         if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
             if (!$arg instanceof Twig_Node_Expression_Constant) {
                 throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
             }
             $node = new Twig_Node_Expression_MethodCall($node, 'get' . $arg->getAttribute('value'), $arguments, $lineno);
             $node->setAttribute('safe', true);
             return $node;
         }
     } else {
         $type = Twig_Template::ARRAY_CALL;
         // slice?
         $slice = false;
         if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
             $slice = true;
             $arg = new Twig_Node_Expression_Constant(0, $token->getLine());
         } else {
             $arg = $this->parseExpression();
         }
         if ($stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
             $slice = true;
         }
         if ($slice) {
             if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
                 $length = new Twig_Node_Expression_Constant(null, $token->getLine());
             } else {
                 $length = $this->parseExpression();
             }
             $class = $this->getFilterNodeClass('slice', $token->getLine());
             $arguments = new Twig_Node(array($arg, $length));
             $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());
             $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
             return $filter;
         }
         $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
     }
     return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
 }
예제 #3
0
 public function parseSubscriptExpression($node)
 {
     $stream = $this->parser->getStream();
     $token = $stream->next();
     $lineno = $token->getLine();
     $arguments = new Twig_Node_Expression_Array(array(), $lineno);
     $type = Twig_Template::ANY_CALL;
     if ($token->getValue() == '.') {
         $token = $stream->next();
         if ($token->getType() == Twig_Token::NAME_TYPE || $token->getType() == Twig_Token::NUMBER_TYPE || $token->getType() == Twig_Token::OPERATOR_TYPE && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue())) {
             $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
             if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
                 $type = Twig_Template::METHOD_CALL;
                 foreach ($this->parseArguments() as $n) {
                     $arguments->addElement($n);
                 }
             }
         } else {
             throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename());
         }
         if ($node instanceof Twig_Node_Expression_Name && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
             if (!$arg instanceof Twig_Node_Expression_Constant) {
                 throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
             }
             $name = $arg->getAttribute('value');
             $node = new Twig_Node_Expression_MethodCall($node, 'macro_' . $name, $arguments, $lineno);
             $node->setAttribute('safe', true);
             return $node;
         }
         if ($node instanceof Twig_Node_Expression_Name && null !== ($symbol = $this->parser->getImportedSymbol('types', $node->getAttribute('name'))) && false === $this->parser->getEnvironment()->hasExtension('sandbox')) {
             $class = $symbol['name'];
             if (0 === strcasecmp($class, 'array')) {
                 $type = Twig_Template::ARRAY_CALL;
                 return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
             }
             if (!class_exists($class)) {
                 throw new Twig_Error_Syntax(sprintf('Class "%s" set for %s was not found.', $class, $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
             }
             $name = $arg->getAttribute('value');
             if (Twig_Template::METHOD_CALL !== $type) {
                 $vars = get_class_vars($class);
                 if (isset($vars[$name])) {
                     if ($this->parser->getEnvironment()->hasExtension('sandbox')) {
                         $this->parser->getEnvironment()->getExtension('sandbox')->checkPropertyAllowed($class, $name);
                     }
                     return new Twig_Node_Expression_GetProperty($node, $name, $lineno);
                 }
             }
             $methods = array_change_key_case(array_flip(get_class_methods($class)));
             $lcItem = strtolower($name);
             if (isset($methods[$lcItem])) {
                 $method = (string) $name;
             } elseif (isset($methods['get' . $lcItem])) {
                 $method = 'get' . $name;
             } elseif (isset($methods['is' . $lcItem])) {
                 $method = 'is' . $name;
             } elseif (isset($methods['__call'])) {
                 $method = (string) $name;
             }
             if (isset($method)) {
                 return new Twig_Node_Expression_MethodCall($node, $method, $arguments, $lineno);
             }
         }
     } else {
         $type = Twig_Template::ARRAY_CALL;
         // slice?
         $slice = false;
         if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
             $slice = true;
             $arg = new Twig_Node_Expression_Constant(0, $token->getLine());
         } else {
             $arg = $this->parseExpression();
         }
         if ($stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
             $slice = true;
         }
         if ($slice) {
             if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
                 $length = new Twig_Node_Expression_Constant(null, $token->getLine());
             } else {
                 $length = $this->parseExpression();
             }
             $class = $this->getFilterNodeClass('slice', $token->getLine());
             $arguments = new Twig_Node(array($arg, $length));
             $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());
             $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
             return $filter;
         }
         $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
     }
     return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
 }