Example #1
0
 protected function compileString(\Twig_NodeInterface $body, \Twig_Node_Expression_Array $vars)
 {
     if ($body instanceof \Twig_Node_Expression_Constant) {
         $msg = $body->getAttribute('value');
     } elseif ($body instanceof \Twig_Node_Text) {
         $msg = $body->getAttribute('data');
     } else {
         return array($body, $vars);
     }
     preg_match_all('/(?<!%)%([^%]+)%/', $msg, $matches);
     if (version_compare(\Twig_Environment::VERSION, '1.5', '>=')) {
         foreach ($matches[1] as $var) {
             $key = new \Twig_Node_Expression_Constant('%' . $var . '%', $body->getLine());
             if (!$vars->hasElement($key)) {
                 $vars->addElement(new \Twig_Node_Expression_Name($var, $body->getLine()), $key);
             }
         }
     } else {
         $current = array();
         foreach ($vars as $name => $var) {
             $current[$name] = true;
         }
         foreach ($matches[1] as $var) {
             if (!isset($current['%' . $var . '%'])) {
                 $vars->setNode('%' . $var . '%', new \Twig_Node_Expression_Name($var, $body->getLine()));
             }
         }
     }
     return array(new \Twig_Node_Expression_Constant(str_replace('%%', '%', trim($msg)), $body->getLine()), $vars);
 }
 public function parse(\Twig_Token $token)
 {
     $lineno = $token->getLine();
     $stream = $this->parser->getStream();
     $resources = new \Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
     do {
         $resources->addElement($this->parser->getExpressionParser()->parseExpression());
     } while (!$stream->test(\Twig_Token::BLOCK_END_TYPE));
     $stream->expect(\Twig_Token::BLOCK_END_TYPE);
     return new GitThemeNode($resources, $lineno, $this->getTag());
 }
 /**
  * @param ArrayNode $node
  * @return array
  */
 protected function nodeToArray(ArrayNode $node)
 {
     $array = array();
     foreach ($node->getKeyValuePairs() as $pair) {
         if (!$pair['key'] instanceof ConstantNode) {
             continue;
         }
         $array[$pair['key']->getAttribute('value')] = $pair['value'];
     }
     return $array;
 }
Example #4
0
 public function valueNode()
 {
     // date value (either a DateTime object, or null)
     $valueNode = parent::valueNode();
     // format('Y-m-d') method call on date object
     $args = new \Twig_Node_Expression_Array([], $this->lineno);
     $args->addElement(new \Twig_Node_Expression_Constant('j M, Y', $this->lineno));
     $formatNode = new \Twig_Node_Expression_MethodCall($valueNode, 'format', $args, $this->lineno);
     // conditional to check for a null value
     $conditionalNode = new \Twig_Node_Expression_Conditional($valueNode, $formatNode, $valueNode, $this->lineno);
     return $conditionalNode;
 }
Example #5
0
 protected function convertToViewArguments(\Twig_Node_Expression_Array $array)
 {
     $arguments = array();
     foreach (array_chunk($array->getIterator()->getArrayCopy(), 2) as $pair) {
         if (count($pair) == 2) {
             $key = $pair[0]->getAttribute('value');
             $value = $pair[1]->getAttribute('value');
             // @todo support for multiple types
             $arguments[$key] = $value;
         }
     }
     return $arguments;
 }
 /**
  * @param  string                      $msg
  * @param  \Twig_Node_Expression_Array $vars
  * @param  int                         $lineno
  * @return \Twig_Node_Expression_Array
  */
 protected function escapeContextVariables($msg, $vars, $lineno)
 {
     preg_match_all('/(?<!%)%([^%]+)%/', $msg, $matches);
     foreach ($matches[1] as $var) {
         $key = new \Twig_Node_Expression_Constant('%' . $var . '%', $lineno);
         if (!$vars->hasElement($key)) {
             $node = new \Twig_Node_Expression_Name($var, $lineno);
             $node = $this->escapeNodeIfNecessary($node, $lineno);
             $vars->addElement($node, $key);
         }
     }
     return $vars;
 }
Example #7
0
 public function getTests()
 {
     $tests = array();
     $expr = new Twig_Node_Expression_Name('foo', 1);
     $attr = new Twig_Node_Expression_Constant('bar', 1);
     $args = new Twig_Node_Expression_Array(array(), 1);
     $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_Template::ANY_CALL, 1);
     $tests[] = array($node, sprintf('%s%s, "bar", [])', $this->getAttributeGetter(), $this->getVariableGetter('foo', 1)));
     $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_Template::ARRAY_CALL, 1);
     $tests[] = array($node, sprintf('%s%s, "bar", [], "array")', $this->getAttributeGetter(), $this->getVariableGetter('foo', 1)));
     $args = new Twig_Node_Expression_Array(array(), 1);
     $args->addElement(new Twig_Node_Expression_Name('foo', 1));
     $args->addElement(new Twig_Node_Expression_Constant('bar', 1));
     $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_Template::METHOD_CALL, 1);
     $tests[] = array($node, sprintf('%s%s, "bar", [0 => %s, 1 => "bar"], "method")', $this->getAttributeGetter(), $this->getVariableGetter('foo', 1), $this->getVariableGetter('foo')));
     return $tests;
 }
 /**
  * {@inheritdoc}
  */
 public function parse(\Twig_Token $token)
 {
     $lineno = $token->getLine();
     $stream = $this->parser->getStream();
     $datagrid = $this->parser->getExpressionParser()->parseExpression();
     if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'with')) {
         $this->parser->getStream()->next();
         $resources = $this->parser->getExpressionParser()->parseExpression();
     } else {
         $resources = new \Twig_Node_Expression_Array([], $stream->getCurrent()->getLine());
         do {
             $resources->addElement($this->parser->getExpressionParser()->parseExpression());
         } while (!$stream->test(\Twig_Token::BLOCK_END_TYPE));
     }
     $stream->expect(\Twig_Token::BLOCK_END_TYPE);
     return new DatagridThemeNode($datagrid, $resources, $lineno, $this->getTag());
 }
 /**
  * @param \Twig_NodeInterface $node
  * @param \Twig_Environment $env
  * @return \Twig_NodeInterface
  */
 public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
 {
     if (!$this->enabled) {
         return $node;
     }
     if ($node instanceof \Twig_Node_Expression_Filter && 'desc' === $node->getNode('filter')->getAttribute('value')) {
         $transNode = $node->getNode('node');
         while ($transNode instanceof \Twig_Node_Expression_Filter && 'trans' !== $transNode->getNode('filter')->getAttribute('value') && 'transchoice' !== $transNode->getNode('filter')->getAttribute('value')) {
             $transNode = $transNode->getNode('node');
         }
         if (!$transNode instanceof \Twig_Node_Expression_Filter) {
             throw new RuntimeException(sprintf('The "desc" filter must be applied after a "trans", or "transchoice" filter.'));
         }
         $wrappingNode = $node->getNode('node');
         $testNode = clone $wrappingNode;
         $defaultNode = $node->getNode('arguments')->getNode(0);
         // if the |transchoice filter is used, delegate the call to the TranslationExtension
         // so that we can catch a possible exception when the default translation has not yet
         // been extracted
         if ('transchoice' === $transNode->getNode('filter')->getAttribute('value')) {
             $transchoiceArguments = new \Twig_Node_Expression_Array(array(), $transNode->getLine());
             $transchoiceArguments->addElement($wrappingNode->getNode('node'));
             $transchoiceArguments->addElement($defaultNode);
             foreach ($wrappingNode->getNode('arguments') as $arg) {
                 $transchoiceArguments->addElement($arg);
             }
             $transchoiceNode = new \Twig_Node_Expression_MethodCall(new \Twig_Node_Expression_ExtensionReference('jms_translation', $transNode->getLine()), 'transchoiceWithDefault', $transchoiceArguments, $transNode->getLine());
             $node->setNode('node', $transchoiceNode);
             return $node;
         }
         // if the |trans filter has replacements parameters
         // (e.g. |trans({'%foo%': 'bar'}))
         if ($wrappingNode->getNode('arguments')->hasNode(0)) {
             $lineno = $wrappingNode->getLine();
             // remove the replacements from the test node
             $testNode->setNode('arguments', clone $testNode->getNode('arguments'));
             $testNode->getNode('arguments')->setNode(0, new \Twig_Node_Expression_Array(array(), $lineno));
             // wrap the default node in a |replace filter
             $defaultNode = new \Twig_Node_Expression_Filter(clone $node->getNode('arguments')->getNode(0), new \Twig_Node_Expression_Constant('replace', $lineno), new \Twig_Node(array(clone $wrappingNode->getNode('arguments')->getNode(0))), $lineno);
         }
         $condition = new \Twig_Node_Expression_Conditional(new \Twig_Node_Expression_Binary_Equal($testNode, $transNode->getNode('node'), $wrappingNode->getLine()), $defaultNode, clone $wrappingNode, $wrappingNode->getLine());
         $node->setNode('node', $condition);
     }
     return $node;
 }
Example #10
0
 protected function compileString(\Twig_NodeInterface $body, \Twig_Node_Expression_Array $vars)
 {
     if ($body instanceof \Twig_Node_Expression_Constant) {
         $msg = $body->getAttribute('value');
     } elseif ($body instanceof \Twig_Node_Text) {
         $msg = $body->getAttribute('data');
     } else {
         return array($body, $vars);
     }
     preg_match_all('/(?<!%)%([^%]+)%/', $msg, $matches);
     foreach ($matches[1] as $var) {
         $key = new \Twig_Node_Expression_Constant('%' . $var . '%', $body->getLine());
         if (!$vars->hasElement($key)) {
             $vars->addElement(new \Twig_Node_Expression_Name($var, $body->getLine()), $key);
         }
     }
     return array(new \Twig_Node_Expression_Constant(str_replace('%%', '%', trim($msg)), $body->getLine()), $vars);
 }
 /**
  * @param \Twig_Token $token
  * @return array
  */
 protected function parseArguments(\Twig_Token $token)
 {
     $stream = $this->parser->getStream();
     $location = null;
     if ($stream->nextIf(\Twig_Token::OPERATOR_TYPE, 'in')) {
         $location = $this->parser->getExpressionParser()->parseExpression();
     } else {
         $lineno = $token->getLine();
         $location = new \Twig_Node_Expression_Constant('head', $lineno);
     }
     if ($stream->nextIf(\Twig_Token::NAME_TYPE, 'with')) {
         $variables = $this->parser->getExpressionParser()->parseExpression();
     } else {
         $lineno = $token->getLine();
         $variables = new \Twig_Node_Expression_Array([], $lineno);
         $variables->setAttribute('priority', 0);
     }
     $stream->expect(\Twig_Token::BLOCK_END_TYPE);
     return [$location, $variables];
 }
 protected function compileString(\Twig_NodeInterface $body, \Twig_Node_Expression_Array $vars)
 {
     if ($body instanceof \Twig_Node_Expression_Constant) {
         $msg = $body->getAttribute('value');
     } elseif ($body instanceof \Twig_Node_Text) {
         $msg = $body->getAttribute('data');
     } else {
         return array($body, $vars);
     }
     $current = array();
     foreach ($vars as $name => $var) {
         $current[$name] = true;
     }
     preg_match_all('/\\%([^\\%]+)\\%/', $msg, $matches);
     foreach ($matches[1] as $var) {
         if (!isset($current['%' . $var . '%'])) {
             $vars->setNode('%' . $var . '%', new \Twig_Node_Expression_Name($var, $body->getLine()));
         }
     }
     return array(new \Twig_Node_Expression_Constant(trim($msg), $body->getLine()), $vars);
 }
Example #13
0
 public function parse(\Twig_Token $token)
 {
     $lineno = $token->getLine();
     $arguments = new \Twig_Node_Expression_Array(array(), $lineno);
     $wherearguments = null;
     // name - the new variable with the results
     $name = $this->parser->getStream()->expect(\Twig_Token::NAME_TYPE)->getValue();
     $this->parser->getStream()->expect(\Twig_Token::OPERATOR_TYPE, '=');
     // contenttype, or simple expression to content.
     $contenttype = $this->parser->getExpressionParser()->parseExpression();
     $counter = 0;
     do {
         // where parameter
         if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'where')) {
             $this->parser->getStream()->next();
             $wherearguments = $this->parser->getExpressionParser()->parseExpression();
         }
         // limit parameter
         if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'limit')) {
             $this->parser->getStream()->next();
             $limit = $this->parser->getExpressionParser()->parseExpression();
             $arguments->addElement($limit, new \Twig_Node_Expression_Constant('limit', $lineno));
         }
         // order / orderby parameter
         if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'order') || $this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'orderby')) {
             $this->parser->getStream()->next();
             $order = $this->parser->getExpressionParser()->parseExpression();
             $arguments->addElement($order, new \Twig_Node_Expression_Constant('order', $lineno));
         }
         // paging / allowpaging parameter
         if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'paging') || $this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'allowpaging')) {
             $this->parser->getStream()->next();
             $arguments->addElement(new \Twig_Node_Expression_Constant(true, $lineno), new \Twig_Node_Expression_Constant('paging', $lineno));
         }
         // printquery parameter
         if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'printquery')) {
             $this->parser->getStream()->next();
             $arguments->addElement(new \Twig_Node_Expression_Constant(true, $lineno), new \Twig_Node_Expression_Constant('printquery', $lineno));
         }
         // returnsingle parameter
         if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'returnsingle')) {
             $this->parser->getStream()->next();
             $arguments->addElement(new \Twig_Node_Expression_Constant(true, $lineno), new \Twig_Node_Expression_Constant('returnsingle', $lineno));
         }
         // nohydrate parameter
         if ($this->parser->getStream()->test(\Twig_Token::NAME_TYPE, 'nohydrate')) {
             $this->parser->getStream()->next();
             $arguments->addElement(new \Twig_Node_Expression_Constant(false, $lineno), new \Twig_Node_Expression_Constant('hydrate', $lineno));
         }
         // Make sure we don't get stuck in a loop, if a token can't be parsed.
         $counter++;
     } while (!$this->parser->getStream()->test(\Twig_Token::BLOCK_END_TYPE) && $counter < 10);
     $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
     return new SetcontentNode($name, $contenttype, $arguments, $wherearguments, $lineno, $this->getTag());
 }
Example #14
0
 protected function compileString(\Twig_NodeInterface $body, \Twig_Node_Expression_Array $vars, $ignoreStrictCheck = false)
 {
     if ($body instanceof \Twig_Node_Expression_Constant) {
         $msg = $body->getAttribute('value');
     } elseif ($body instanceof \Twig_Node_Text) {
         $msg = $body->getAttribute('data');
     } else {
         return array($body, $vars);
     }
     preg_match_all('/(?<!%)%([^%]+)%/', $msg, $matches);
     foreach ($matches[1] as $var) {
         $key = new \Twig_Node_Expression_Constant('%' . $var . '%', $body->getLine());
         if (!$vars->hasElement($key)) {
             if ('count' === $var && null !== $this->getNode('count')) {
                 $vars->addElement($this->getNode('count'), $key);
             } else {
                 $varExpr = new \Twig_Node_Expression_Name($var, $body->getLine());
                 $varExpr->setAttribute('ignore_strict_check', $ignoreStrictCheck);
                 $vars->addElement($varExpr, $key);
             }
         }
     }
     return array(new \Twig_Node_Expression_Constant(str_replace('%%', '%', trim($msg)), $body->getLine()), $vars);
 }
Example #15
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);
 }
Example #16
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_TemplateInterface::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);
         }
     } else {
         $type = Twig_TemplateInterface::ARRAY_CALL;
         $arg = $this->parseExpression();
         // slice?
         if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
             $stream->next();
             if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
                 $length = new Twig_Node_Expression_Constant(null, $token->getLine());
             } else {
                 $length = $this->parseExpression();
             }
             $class = $this->getFilterNodeClass('slice');
             $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);
 }
Example #17
0
 protected function getArguments($callable, $arguments)
 {
     $callType = $this->getAttribute('type');
     $callName = $this->getAttribute('name');
     $parameters = array();
     $named = false;
     foreach ($arguments as $name => $node) {
         if (!is_int($name)) {
             $named = true;
             $name = $this->normalizeName($name);
         } elseif ($named) {
             throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
         }
         $parameters[$name] = $node;
     }
     $isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
     if (!$named && !$isVariadic) {
         return $parameters;
     }
     if (!$callable) {
         if ($named) {
             $message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
         } else {
             $message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
         }
         throw new LogicException($message);
     }
     // manage named arguments
     if (is_array($callable)) {
         $r = new ReflectionMethod($callable[0], $callable[1]);
     } elseif (is_object($callable) && !$callable instanceof Closure) {
         $r = new ReflectionObject($callable);
         $r = $r->getMethod('__invoke');
     } elseif (is_string($callable) && false !== strpos($callable, '::')) {
         $r = new ReflectionMethod($callable);
     } else {
         $r = new ReflectionFunction($callable);
     }
     $definition = $r->getParameters();
     if ($this->hasNode('node')) {
         array_shift($definition);
     }
     if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
         array_shift($definition);
     }
     if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
         array_shift($definition);
     }
     if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
         foreach ($this->getAttribute('arguments') as $argument) {
             array_shift($definition);
         }
     }
     if ($isVariadic) {
         $argument = end($definition);
         if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
             array_pop($definition);
         } else {
             $callableName = $r->name;
             if ($r->getDeclaringClass()) {
                 $callableName = $r->getDeclaringClass()->name . '::' . $callableName;
             }
             throw new LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = array()".', $callableName, $callType, $callName));
         }
     }
     $arguments = array();
     $names = array();
     $missingArguments = array();
     $optionalArguments = array();
     $pos = 0;
     foreach ($definition as $param) {
         $names[] = $name = $this->normalizeName($param->name);
         if (array_key_exists($name, $parameters)) {
             if (array_key_exists($pos, $parameters)) {
                 throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName));
             }
             if (!empty($missingArguments)) {
                 throw new Twig_Error_Syntax(sprintf('Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".', $name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments)));
             }
             $arguments = array_merge($arguments, $optionalArguments);
             $arguments[] = $parameters[$name];
             unset($parameters[$name]);
             $optionalArguments = array();
         } elseif (array_key_exists($pos, $parameters)) {
             $arguments = array_merge($arguments, $optionalArguments);
             $arguments[] = $parameters[$pos];
             unset($parameters[$pos]);
             $optionalArguments = array();
             ++$pos;
         } elseif ($param->isDefaultValueAvailable()) {
             $optionalArguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
         } elseif ($param->isOptional()) {
             if (empty($parameters)) {
                 break;
             } else {
                 $missingArguments[] = $name;
             }
         } else {
             throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName));
         }
     }
     if ($isVariadic) {
         $arbitraryArguments = new Twig_Node_Expression_Array(array(), -1);
         foreach ($parameters as $key => $value) {
             if (is_int($key)) {
                 $arbitraryArguments->addElement($value);
             } else {
                 $arbitraryArguments->addElement($value, new Twig_Node_Expression_Constant($key, -1));
             }
             unset($parameters[$key]);
         }
         if ($arbitraryArguments->count()) {
             $arguments = array_merge($arguments, $optionalArguments);
             $arguments[] = $arbitraryArguments;
         }
     }
     if (!empty($parameters)) {
         $unknownParameter = null;
         foreach ($parameters as $parameter) {
             if ($parameter instanceof Twig_Node) {
                 $unknownParameter = $parameter;
                 break;
             }
         }
         throw new Twig_Error_Syntax(sprintf('Unknown argument%s "%s" for %s "%s(%s)".', count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)), $unknownParameter ? $unknownParameter->getLine() : -1);
     }
     return $arguments;
 }
 public function compile(\Twig_Compiler $compiler)
 {
     $compiler->addDebugInfo($this);
     $compiler->raw('$this->env->getRuntime(\'' . TwigRenderer::class . '\')->searchAndRenderBlock(');
     preg_match('/_([^_]+)$/', $this->getAttribute('name'), $matches);
     // Use the suffix to determine which properties must be extracted, from the view.
     // Allow the label to be overwritten?
     $label = null;
     $arguments = iterator_to_array($this->getNode('arguments'));
     $blockNameSuffix = $matches[1];
     // The suffix is extracted from the function name, but calling the
     // function `rollerworks_datagrid_container` is rather redundant.
     // Else the block would be named `datagrid_datagrid`...
     if ('datagrid' === $blockNameSuffix) {
         $blockNameSuffix = 'container';
     }
     if (isset($arguments[0])) {
         $compiler->subcompile($arguments[0]);
         $compiler->raw(', \'' . $blockNameSuffix . '\'');
         if (isset($arguments[1])) {
             if ('header' === $blockNameSuffix) {
                 // The "label" function expects the label in the second and
                 // the variables in the third argument
                 $label = $arguments[1];
                 $variables = isset($arguments[2]) ? $arguments[2] : null;
                 $lineno = $label->getLine();
                 if ($label instanceof \Twig_Node_Expression_Constant) {
                     // If the label argument is given as a constant, we can either
                     // strip it away if it is empty, or integrate it into the array
                     // of variables at compile time.
                     $labelIsExpression = false;
                     // Only insert the label into the array if it is not empty
                     if (!twig_test_empty($label->getAttribute('value'))) {
                         $originalVariables = $variables;
                         $variables = new \Twig_Node_Expression_Array([], $lineno);
                         $labelKey = new \Twig_Node_Expression_Constant('label', $lineno);
                         if (null !== $originalVariables) {
                             foreach ($originalVariables->getKeyValuePairs() as $pair) {
                                 // Don't copy the original label attribute over if it exists
                                 if ((string) $labelKey !== (string) $pair['key']) {
                                     $variables->addElement($pair['value'], $pair['key']);
                                 }
                             }
                         }
                         // Insert the label argument into the array
                         $variables->addElement($label, $labelKey);
                     }
                 } else {
                     // The label argument is not a constant, but some kind of
                     // expression. This expression needs to be evaluated at runtime.
                     // Depending on the result (whether it is null or not), the
                     // label in the arguments should take precedence over the label
                     // in the attributes or not.
                     $labelIsExpression = true;
                 }
             } else {
                 // All other functions than "label" expect the variables
                 // in the second argument
                 $label = null;
                 $variables = $arguments[1];
                 $labelIsExpression = false;
             }
             if (null !== $variables || $labelIsExpression) {
                 $compiler->raw(', ');
                 if (null !== $variables) {
                     $compiler->subcompile($variables);
                 }
                 if ($labelIsExpression) {
                     if (null !== $variables) {
                         $compiler->raw(' + ');
                     }
                     // Check at runtime whether the label is empty.
                     // If not, add it to the array at runtime.
                     $compiler->raw('(twig_test_empty($_label_ = ');
                     $compiler->subcompile($label);
                     $compiler->raw(') ? [] : ["label" => $_label_])');
                 }
             }
         }
     }
     $compiler->raw(')');
 }
 protected function getArguments($callable, $arguments)
 {
     $callType = $this->getAttribute('type');
     $callName = $this->getAttribute('name');
     $parameters = array();
     $named = false;
     foreach ($arguments as $name => $node) {
         if (!is_int($name)) {
             $named = true;
             $name = $this->normalizeName($name);
         } elseif ($named) {
             throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
         }
         $parameters[$name] = $node;
     }
     $isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
     if (!$named && !$isVariadic) {
         return $parameters;
     }
     if (!$callable) {
         if ($named) {
             $message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
         } else {
             $message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
         }
         throw new LogicException($message);
     }
     $callableParameters = $this->getCallableParameters($callable, $isVariadic);
     $arguments = array();
     $names = array();
     $missingArguments = array();
     $optionalArguments = array();
     $pos = 0;
     foreach ($callableParameters as $callableParameter) {
         $names[] = $name = $this->normalizeName($callableParameter->name);
         if (array_key_exists($name, $parameters)) {
             if (array_key_exists($pos, $parameters)) {
                 throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName));
             }
             if (!empty($missingArguments)) {
                 throw new Twig_Error_Syntax(sprintf('Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".', $name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments)));
             }
             $arguments = array_merge($arguments, $optionalArguments);
             $arguments[] = $parameters[$name];
             unset($parameters[$name]);
             $optionalArguments = array();
         } elseif (array_key_exists($pos, $parameters)) {
             $arguments = array_merge($arguments, $optionalArguments);
             $arguments[] = $parameters[$pos];
             unset($parameters[$pos]);
             $optionalArguments = array();
             ++$pos;
         } elseif ($callableParameter->isDefaultValueAvailable()) {
             $optionalArguments[] = new Twig_Node_Expression_Constant($callableParameter->getDefaultValue(), -1);
         } elseif ($callableParameter->isOptional()) {
             if (empty($parameters)) {
                 break;
             } else {
                 $missingArguments[] = $name;
             }
         } else {
             throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName));
         }
     }
     if ($isVariadic) {
         $arbitraryArguments = new Twig_Node_Expression_Array(array(), -1);
         foreach ($parameters as $key => $value) {
             if (is_int($key)) {
                 $arbitraryArguments->addElement($value);
             } else {
                 $arbitraryArguments->addElement($value, new Twig_Node_Expression_Constant($key, -1));
             }
             unset($parameters[$key]);
         }
         if ($arbitraryArguments->count()) {
             $arguments = array_merge($arguments, $optionalArguments);
             $arguments[] = $arbitraryArguments;
         }
     }
     if (!empty($parameters)) {
         $unknownParameter = null;
         foreach ($parameters as $parameter) {
             if ($parameter instanceof Twig_Node) {
                 $unknownParameter = $parameter;
                 break;
             }
         }
         throw new Twig_Error_Syntax(sprintf('Unknown argument%s "%s" for %s "%s(%s)".', count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)), $unknownParameter ? $unknownParameter->getTemplateLine() : -1);
     }
     return $arguments;
 }
 public function compile(\Twig_Compiler $compiler)
 {
     $compiler->addDebugInfo($this);
     $compiler->raw('$this->env->getExtension(\'table\')->renderer->searchAndRenderBlock(');
     preg_match('/_([^_]+)$/', $this->getAttribute('name'), $matches);
     $label = null;
     $arguments = iterator_to_array($this->getNode('arguments'));
     $blockNameSuffix = $matches[1];
     if (isset($arguments[0])) {
         $compiler->subcompile($arguments[0]);
         $compiler->raw(', \'' . $blockNameSuffix . '\'');
         if (isset($arguments[1])) {
             if ('label' === $blockNameSuffix) {
                 // The "label" function expects the label in the second and
                 // the variables in the third argument
                 $label = $arguments[1];
                 $variables = isset($arguments[2]) ? $arguments[2] : null;
                 $lineno = $label->getLine();
                 if ($label instanceof \Twig_Node_Expression_Constant) {
                     // If the label argument is given as a constant, we can either
                     // strip it away if it is empty, or integrate it into the array
                     // of variables at compile time.
                     $labelIsExpression = false;
                     // Only insert the label into the array if it is not empty
                     if (!twig_test_empty($label->getAttribute('value'))) {
                         $originalVariables = $variables;
                         $variables = new \Twig_Node_Expression_Array(array(), $lineno);
                         $labelKey = new \Twig_Node_Expression_Constant('label', $lineno);
                         if (null !== $originalVariables) {
                             foreach ($originalVariables->getKeyValuePairs() as $pair) {
                                 // Don't copy the original label attribute over if it exists
                                 if ((string) $labelKey !== (string) $pair['key']) {
                                     $variables->addElement($pair['value'], $pair['key']);
                                 }
                             }
                         }
                         // Insert the label argument into the array
                         $variables->addElement($label, $labelKey);
                     }
                 } else {
                     // The label argument is not a constant, but some kind of
                     // expression. This expression needs to be evaluated at runtime.
                     // Depending on the result (whether it is null or not), the
                     // label in the arguments should take precedence over the label
                     // in the attributes or not.
                     $labelIsExpression = true;
                 }
             } else {
                 // All other functions than "label" expect the variables
                 // in the second argument
                 $label = null;
                 $variables = $arguments[1];
                 $labelIsExpression = false;
             }
             if (null !== $variables || $labelIsExpression) {
                 $compiler->raw(', ');
                 if (null !== $variables) {
                     $compiler->subcompile($variables);
                 }
                 if ($labelIsExpression) {
                     if (null !== $variables) {
                         $compiler->raw(' + ');
                     }
                     // Check at runtime whether the label is empty.
                     // If not, add it to the array at runtime.
                     $compiler->raw('(twig_test_empty($_label_ = ');
                     $compiler->subcompile($label);
                     $compiler->raw(') ? array() : array("label" => $_label_))');
                 }
             }
         }
     }
     $compiler->raw(")");
 }
Example #21
0
 /**
  * @covers Twig_Node_Expression_Array::__construct
  */
 public function testConstructor()
 {
     $elements = array(new Twig_Node_Expression_Constant('foo', 1), $foo = new Twig_Node_Expression_Constant('bar', 1));
     $node = new Twig_Node_Expression_Array($elements, 1);
     $this->assertEquals($foo, $node->getNode(1));
 }
Example #22
0
 private function createArrayFromArguments(Twig_Node $arguments, $line = null)
 {
     $line = null === $line ? $arguments->getLine() : $line;
     $array = new Twig_Node_Expression_Array(array(), $line);
     foreach ($arguments as $key => $value) {
         $array->addElement($value, new Twig_Node_Expression_Constant($key, $value->getLine()));
     }
     return $array;
 }
Example #23
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);
 }
 public function parseHashExpression()
 {
     $stream = $this->parser->getStream();
     $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
     $node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
     $first = true;
     while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
         if (!$first) {
             $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
             // trailing ,?
             if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
                 break;
             }
         }
         $first = false;
         // a hash key can be:
         //
         //  * a number -- 12
         //  * a string -- 'a'
         //  * a name, which is equivalent to a string -- a
         //  * an expression, which must be enclosed in parentheses -- (1 + 2)
         if (($token = $stream->nextIf(Twig_Token::STRING_TYPE)) || ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) || ($token = $stream->nextIf(Twig_Token::NUMBER_TYPE))) {
             $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
         } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
             $key = $this->parseExpression();
         } else {
             $current = $stream->getCurrent();
             throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $this->parser->getFilename());
         }
         $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
         $value = $this->parseExpression();
         $node->addElement($value, $key);
     }
     $stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
     return $node;
 }
 /**
  * @param ArrayNode $node
  * @return array
  */
 private function collectConstantValues(ArrayNode $node)
 {
     $values = array();
     foreach ($node->getKeyValuePairs() as $pair) {
         if (!$pair['key'] instanceof ConstantNode) {
             continue;
         }
         $value = null;
         if ($pair['value'] instanceof ConstantNode) {
             $value = $pair['value']->getAttribute('value');
         } elseif ($pair['value'] instanceof ArrayNode) {
             $value = $this->collectConstantValues($pair['value']);
         }
         $values[$pair['key']->getAttribute('value')] = $value;
     }
     return $values;
 }