17        $closingParenthesis = 
false;
 
   19            if (is_string($callable) && 
false === strpos($callable, 
'::')) {
 
   20                $compiler->
raw($callable);
 
   23                if (
$r instanceof ReflectionMethod && is_string($callable[0])) {
 
   25                        $compiler->
raw(sprintf(
'%s::%s', $callable[0], $callable[1]));
 
   27                        $compiler->
raw(sprintf(
'$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
 
   30                    $compiler->
raw(sprintf(
'$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1]));
 
   33                    $compiler->
raw(sprintf(
'call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', 
$type, $this->
getAttribute(
'name')));
 
   34                    $closingParenthesis = 
true;
 
   43        if ($closingParenthesis) {
 
   55            $compiler->
raw(
'$this->env');
 
   63            $compiler->
raw(
'$context');
 
   68            foreach ($this->
getAttribute(
'arguments') as $argument) {
 
   72                $compiler->
string($argument);
 
   85        if ($this->
hasNode(
'arguments')) {
 
   90            foreach ($arguments as $node) {
 
  107        $parameters = array();
 
  109        foreach ($arguments as 
$name => $node) {
 
  110            if (!is_int(
$name)) {
 
  114                throw new Twig_Error_Syntax(sprintf(
'Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
 
  117            $parameters[
$name] = $node;
 
  121        if (!$named && !$isVariadic) {
 
  127                $message = sprintf(
'Named arguments are not supported for %s "%s".', $callType, $callName);
 
  129                $message = sprintf(
'Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
 
  136        $arguments = array();
 
  138        $missingArguments = array();
 
  139        $optionalArguments = array();
 
  141        foreach ($callableParameters as $callableParameter) {
 
  144            if (array_key_exists(
$name, $parameters)) {
 
  145                if (array_key_exists($pos, $parameters)) {
 
  146                    throw new Twig_Error_Syntax(sprintf(
'Argument "%s" is defined twice for %s "%s".', 
$name, $callType, $callName));
 
  149                if (
count($missingArguments)) {
 
  151                        '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".',
 
  152                        $name, $callType, $callName, implode(
', ', $names), 
count($missingArguments) > 1 ? 
's' : 
'', implode(
'", "', $missingArguments))
 
  156                $arguments = array_merge($arguments, $optionalArguments);
 
  157                $arguments[] = $parameters[
$name];
 
  158                unset($parameters[
$name]);
 
  159                $optionalArguments = array();
 
  160            } elseif (array_key_exists($pos, $parameters)) {
 
  161                $arguments = array_merge($arguments, $optionalArguments);
 
  162                $arguments[] = $parameters[$pos];
 
  163                unset($parameters[$pos]);
 
  164                $optionalArguments = array();
 
  166            } elseif ($callableParameter->isDefaultValueAvailable()) {
 
  168            } elseif ($callableParameter->isOptional()) {
 
  169                if (empty($parameters)) {
 
  172                    $missingArguments[] = 
$name;
 
  175                throw new Twig_Error_Syntax(sprintf(
'Value for argument "%s" is required for %s "%s".', 
$name, $callType, $callName));
 
  181            foreach ($parameters as 
$key => $value) {
 
  183                    $arbitraryArguments->addElement($value);
 
  187                unset($parameters[
$key]);
 
  190            if ($arbitraryArguments->count()) {
 
  191                $arguments = array_merge($arguments, $optionalArguments);
 
  192                $arguments[] = $arbitraryArguments;
 
  196        if (!empty($parameters)) {
 
  197            $unknownParameter = 
null;
 
  198            foreach ($parameters as $parameter) {
 
  200                    $unknownParameter = $parameter;
 
  206                'Unknown argument%s "%s" for %s "%s(%s)".',
 
  207                count($parameters) > 1 ? 
's' : 
'', implode(
'", "', array_keys($parameters)), $callType, $callName, implode(
', ', $names)
 
  208            ), $unknownParameter ? $unknownParameter->getTemplateLine() : -1);
 
  216        return strtolower(preg_replace(array(
'/([A-Z]+)([A-Z][a-z])/', 
'/([a-z\d])([A-Z])/'), array(
'\\1_\\2', 
'\\1_\\2'), 
$name));
 
  226        $parameters = 
$r->getParameters();
 
  228            array_shift($parameters);
 
  231            array_shift($parameters);
 
  234            array_shift($parameters);
 
  237            foreach ($this->
getAttribute(
'arguments') as $argument) {
 
  238                array_shift($parameters);
 
  242            $argument = end($parameters);
 
  243            if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
 
  244                array_pop($parameters);
 
  246                $callableName = 
$r->name;
 
  247                if (
$r instanceof ReflectionMethod) {
 
  248                    $callableName = 
$r->getDeclaringClass()->name.
'::'.$callableName;
 
  251                throw new LogicException(sprintf(
'The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = array()".', $callableName, $this->
getAttribute(
'type'), $this->
getAttribute(
'name')));
 
  260        if (
null !== $this->reflector) {
 
  264        if (is_array($callable)) {
 
  265            if (!method_exists($callable[0], $callable[1])) {
 
  267                return array(
null, array());
 
  269            $r = 
new ReflectionMethod($callable[0], $callable[1]);
 
  270        } elseif (is_object($callable) && !$callable instanceof Closure) {
 
  271            $r = 
new ReflectionObject($callable);
 
  272            $r = 
$r->getMethod(
'__invoke');
 
  273            $callable = array($callable, 
'__invoke');
 
  274        } elseif (is_string($callable) && 
false !== $pos = strpos($callable, 
'::')) {
 
  275            $class = substr($callable, 0, $pos);
 
  276            $method = substr($callable, $pos + 2);
 
  277            if (!method_exists($class, $method)) {
 
  279                return array(
null, array());
 
  281            $r = 
new ReflectionMethod($callable);
 
  282            $callable = array($class, $method);
 
  284            $r = 
new ReflectionFunction($callable);
 
  287        return $this->reflector = array(
$r, $callable);
 
  291class_alias(
'Twig_Node_Expression_Call', 
'Twig\Node\Expression\CallExpression', 
false);
 
An exception for terminatinating execution or to throw for unit testing.
Compiles a node to PHP code.
raw($string)
Adds a raw string to the compiled code.
string($value)
Adds a quoted string to the compiled code.
subcompile(Twig_NodeInterface $node, $raw=true)
Exception thrown when a syntax error occurs during lexing or parsing of a template.
compileCallable(Twig_Compiler $compiler)
getCallableParameters($callable, $isVariadic)
reflectCallable($callable)
compileArguments(Twig_Compiler $compiler)
getArguments($callable, $arguments)
Abstract class for all nodes that represents an expression.
Represents a node in the AST.
compile(Twig_Compiler $compiler)
Compiles the node to PHP.
Interface implemented by extension classes.
catch(Exception $e) $message