ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Twig_Node_Expression_Call Class Reference
+ Inheritance diagram for Twig_Node_Expression_Call:
+ Collaboration diagram for Twig_Node_Expression_Call:

Protected Member Functions

 compileCallable (Twig_Compiler $compiler)
 
 compileArguments (Twig_Compiler $compiler)
 
 getArguments ($callable, $arguments)
 
 normalizeName ($name)
 

Private Member Functions

 getCallableParameters ($callable, $isVariadic)
 
 reflectCallable ($callable)
 

Private Attributes

 $reflector
 

Additional Inherited Members

- Public Member Functions inherited from Twig_Node
 __construct (array $nodes=array(), array $attributes=array(), $lineno=0, $tag=null)
 Constructor. More...
 
 __toString ()
 
 toXml ($asDom=false)
 
 compile (Twig_Compiler $compiler)
 Compiles the node to PHP. More...
 
 getTemplateLine ()
 
 getLine ()
 
 getNodeTag ()
 
 hasAttribute ($name)
 
 getAttribute ($name)
 
 setAttribute ($name, $value)
 
 removeAttribute ($name)
 
 hasNode ($name)
 
 getNode ($name)
 
 setNode ($name, $node=null)
 
 removeNode ($name)
 
 count ()
 
 getIterator ()
 
 setTemplateName ($name)
 
 getTemplateName ()
 
 setFilename ($name)
 
 getFilename ()
 
- Protected Attributes inherited from Twig_Node
 $nodes
 
 $attributes
 
 $lineno
 
 $tag
 

Detailed Description

Definition at line 11 of file Call.php.

Member Function Documentation

◆ compileArguments()

Twig_Node_Expression_Call::compileArguments ( Twig_Compiler  $compiler)
protected

Definition at line 48 of file Call.php.

References getArguments(), Twig_Node\getAttribute(), Twig_Node\getNode(), Twig_Node\hasAttribute(), Twig_Node\hasNode(), Twig_Compiler\raw(), Twig_Compiler\string(), and Twig_Compiler\subcompile().

Referenced by compileCallable().

49  {
50  $compiler->raw('(');
51 
52  $first = true;
53 
54  if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
55  $compiler->raw('$this->env');
56  $first = false;
57  }
58 
59  if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
60  if (!$first) {
61  $compiler->raw(', ');
62  }
63  $compiler->raw('$context');
64  $first = false;
65  }
66 
67  if ($this->hasAttribute('arguments')) {
68  foreach ($this->getAttribute('arguments') as $argument) {
69  if (!$first) {
70  $compiler->raw(', ');
71  }
72  $compiler->string($argument);
73  $first = false;
74  }
75  }
76 
77  if ($this->hasNode('node')) {
78  if (!$first) {
79  $compiler->raw(', ');
80  }
81  $compiler->subcompile($this->getNode('node'));
82  $first = false;
83  }
84 
85  if ($this->hasNode('arguments')) {
86  $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
87 
88  $arguments = $this->getArguments($callable, $this->getNode('arguments'));
89 
90  foreach ($arguments as $node) {
91  if (!$first) {
92  $compiler->raw(', ');
93  }
94  $compiler->subcompile($node);
95  $first = false;
96  }
97  }
98 
99  $compiler->raw(')');
100  }
raw($string)
Adds a raw string to the compiled code.
Definition: Compiler.php:112
subcompile(Twig_NodeInterface $node, $raw=true)
Definition: Compiler.php:94
string($value)
Adds a quoted string to the compiled code.
Definition: Compiler.php:157
hasAttribute($name)
Definition: Node.php:144
getAttribute($name)
Definition: Node.php:152
hasNode($name)
Definition: Node.php:178
getNode($name)
Definition: Node.php:186
getArguments($callable, $arguments)
Definition: Call.php:102
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compileCallable()

Twig_Node_Expression_Call::compileCallable ( Twig_Compiler  $compiler)
protected

Definition at line 15 of file Call.php.

References $r, $type, Twig_Node\compile(), compileArguments(), Twig_Node\getAttribute(), Twig_Node\hasAttribute(), Twig_Compiler\raw(), and reflectCallable().

Referenced by Twig_Node_Expression_Function\compile(), Twig_Node_Expression_Filter\compile(), and Twig_Node_Expression_Test\compile().

16  {
17  $closingParenthesis = false;
18  if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
19  if (is_string($callable) && false === strpos($callable, '::')) {
20  $compiler->raw($callable);
21  } else {
22  list($r, $callable) = $this->reflectCallable($callable);
23  if ($r instanceof ReflectionMethod && is_string($callable[0])) {
24  if ($r->isStatic()) {
25  $compiler->raw(sprintf('%s::%s', $callable[0], $callable[1]));
26  } else {
27  $compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
28  }
29  } elseif ($r instanceof ReflectionMethod && $callable[0] instanceof Twig_ExtensionInterface) {
30  $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', get_class($callable[0]), $callable[1]));
31  } else {
32  $type = ucfirst($this->getAttribute('type'));
33  $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
34  $closingParenthesis = true;
35  }
36  }
37  } else {
38  $compiler->raw($this->getAttribute('thing')->compile());
39  }
40 
41  $this->compileArguments($compiler);
42 
43  if ($closingParenthesis) {
44  $compiler->raw(')');
45  }
46  }
raw($string)
Adds a raw string to the compiled code.
Definition: Compiler.php:112
Interface implemented by extension classes.
$type
reflectCallable($callable)
Definition: Call.php:258
hasAttribute($name)
Definition: Node.php:144
compileArguments(Twig_Compiler $compiler)
Definition: Call.php:48
$r
Definition: example_031.php:79
compile(Twig_Compiler $compiler)
Compiles the node to PHP.
Definition: Node.php:114
getAttribute($name)
Definition: Node.php:152
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getArguments()

Twig_Node_Expression_Call::getArguments (   $callable,
  $arguments 
)
protected

Definition at line 102 of file Call.php.

References $key, $message, Twig_Node\$name, Twig_Node\count(), Twig_Node\getAttribute(), getCallableParameters(), Twig_Node\hasAttribute(), and normalizeName().

Referenced by compileArguments().

103  {
104  $callType = $this->getAttribute('type');
105  $callName = $this->getAttribute('name');
106 
107  $parameters = array();
108  $named = false;
109  foreach ($arguments as $name => $node) {
110  if (!is_int($name)) {
111  $named = true;
112  $name = $this->normalizeName($name);
113  } elseif ($named) {
114  throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
115  }
116 
117  $parameters[$name] = $node;
118  }
119 
120  $isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
121  if (!$named && !$isVariadic) {
122  return $parameters;
123  }
124 
125  if (!$callable) {
126  if ($named) {
127  $message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
128  } else {
129  $message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
130  }
131 
132  throw new LogicException($message);
133  }
134 
135  $callableParameters = $this->getCallableParameters($callable, $isVariadic);
136  $arguments = array();
137  $names = array();
138  $missingArguments = array();
139  $optionalArguments = array();
140  $pos = 0;
141  foreach ($callableParameters as $callableParameter) {
142  $names[] = $name = $this->normalizeName($callableParameter->name);
143 
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));
147  }
148 
149  if (count($missingArguments)) {
150  throw new Twig_Error_Syntax(sprintf(
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))
153  );
154  }
155 
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();
165  ++$pos;
166  } elseif ($callableParameter->isDefaultValueAvailable()) {
167  $optionalArguments[] = new Twig_Node_Expression_Constant($callableParameter->getDefaultValue(), -1);
168  } elseif ($callableParameter->isOptional()) {
169  if (empty($parameters)) {
170  break;
171  } else {
172  $missingArguments[] = $name;
173  }
174  } else {
175  throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName));
176  }
177  }
178 
179  if ($isVariadic) {
180  $arbitraryArguments = new Twig_Node_Expression_Array(array(), -1);
181  foreach ($parameters as $key => $value) {
182  if (is_int($key)) {
183  $arbitraryArguments->addElement($value);
184  } else {
185  $arbitraryArguments->addElement($value, new Twig_Node_Expression_Constant($key, -1));
186  }
187  unset($parameters[$key]);
188  }
189 
190  if ($arbitraryArguments->count()) {
191  $arguments = array_merge($arguments, $optionalArguments);
192  $arguments[] = $arbitraryArguments;
193  }
194  }
195 
196  if (!empty($parameters)) {
197  $unknownParameter = null;
198  foreach ($parameters as $parameter) {
199  if ($parameter instanceof Twig_Node) {
200  $unknownParameter = $parameter;
201  break;
202  }
203  }
204 
205  throw new Twig_Error_Syntax(sprintf(
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);
209  }
210 
211  return $arguments;
212  }
Represents a node in the AST.
Definition: Node.php:18
hasAttribute($name)
Definition: Node.php:144
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:18
catch(Exception $e) $message
getAttribute($name)
Definition: Node.php:152
getCallableParameters($callable, $isVariadic)
Definition: Call.php:219
count()
Definition: Node.php:209
$key
Definition: croninfo.php:18
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCallableParameters()

Twig_Node_Expression_Call::getCallableParameters (   $callable,
  $isVariadic 
)
private

Definition at line 219 of file Call.php.

References $r, Twig_Node\getAttribute(), Twig_Node\hasAttribute(), Twig_Node\hasNode(), and reflectCallable().

Referenced by getArguments().

220  {
221  list($r) = $this->reflectCallable($callable);
222  if (null === $r) {
223  return array();
224  }
225 
226  $parameters = $r->getParameters();
227  if ($this->hasNode('node')) {
228  array_shift($parameters);
229  }
230  if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
231  array_shift($parameters);
232  }
233  if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
234  array_shift($parameters);
235  }
236  if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
237  foreach ($this->getAttribute('arguments') as $argument) {
238  array_shift($parameters);
239  }
240  }
241  if ($isVariadic) {
242  $argument = end($parameters);
243  if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
244  array_pop($parameters);
245  } else {
246  $callableName = $r->name;
247  if ($r instanceof ReflectionMethod) {
248  $callableName = $r->getDeclaringClass()->name.'::'.$callableName;
249  }
250 
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')));
252  }
253  }
254 
255  return $parameters;
256  }
reflectCallable($callable)
Definition: Call.php:258
hasAttribute($name)
Definition: Node.php:144
$r
Definition: example_031.php:79
getAttribute($name)
Definition: Node.php:152
hasNode($name)
Definition: Node.php:178
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ normalizeName()

Twig_Node_Expression_Call::normalizeName (   $name)
protected

Definition at line 214 of file Call.php.

References Twig_Node\$name.

Referenced by getArguments().

215  {
216  return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
217  }
+ Here is the caller graph for this function:

◆ reflectCallable()

Twig_Node_Expression_Call::reflectCallable (   $callable)
private

Definition at line 258 of file Call.php.

References $r, and $reflector.

Referenced by compileCallable(), and getCallableParameters().

259  {
260  if (null !== $this->reflector) {
261  return $this->reflector;
262  }
263 
264  if (is_array($callable)) {
265  if (!method_exists($callable[0], $callable[1])) {
266  // __call()
267  return array(null, array());
268  }
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)) {
278  // __staticCall()
279  return array(null, array());
280  }
281  $r = new ReflectionMethod($callable);
282  $callable = array($class, $method);
283  } else {
284  $r = new ReflectionFunction($callable);
285  }
286 
287  return $this->reflector = array($r, $callable);
288  }
$r
Definition: example_031.php:79
+ Here is the caller graph for this function:

Field Documentation

◆ $reflector

Twig_Node_Expression_Call::$reflector
private

Definition at line 13 of file Call.php.

Referenced by reflectCallable().


The documentation for this class was generated from the following file: