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 ()
 
 compile (Twig_Compiler $compiler)
 Compiles the node to PHP. More...
 
 getLine ()
 
 getNodeTag ()
 
- 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.

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
string($value)
Adds a quoted string to the compiled code.
Definition: Compiler.php:157
subcompile(Twig_NodeInterface $node, $raw=true)
Definition: Compiler.php:94
getArguments($callable, $arguments)
Definition: Call.php:102
hasAttribute($name)
Definition: Node.php:144
hasNode($name)
Definition: Node.php:178
getAttribute($name)
Definition: Node.php:152
getNode($name)
Definition: Node.php:186

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().

+ 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.

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 }
reflectCallable($callable)
Definition: Call.php:258
compileArguments(Twig_Compiler $compiler)
Definition: Call.php:48
compile(Twig_Compiler $compiler)
Compiles the node to PHP.
Definition: Node.php:114
$r
Definition: example_031.php:79
Interface implemented by extension classes.
$type

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

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

+ 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

Reimplemented in Twig_Tests_Node_Expression_Call.

Definition at line 102 of file Call.php.

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 }
Exception thrown when a syntax error occurs during lexing or parsing of a template.
Definition: Syntax.php:19
getCallableParameters($callable, $isVariadic)
Definition: Call.php:219
Represents a node in the AST.
Definition: Node.php:19
count()
Definition: Node.php:209
$key
Definition: croninfo.php:18
catch(Exception $e) $message

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

Referenced by compileArguments().

+ 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.

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 }

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

Referenced by getArguments().

+ 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.

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 }

References Twig_Node\$name.

Referenced by getArguments().

+ Here is the caller graph for this function:

◆ reflectCallable()

Twig_Node_Expression_Call::reflectCallable (   $callable)
private

Definition at line 258 of file Call.php.

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 }

References $r, and $reflector.

Referenced by compileCallable(), and getCallableParameters().

+ 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: