Dotclear

source: inc/libs/Twig/Node/Expression/Call.php @ 1149:1657e862089c

Revision 1149:1657e862089c, 5.8 KB checked in by dsls, 12 years ago (diff)

Fixed unix case-sensitive twig directory

Line 
1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) 2012 Fabien Potencier
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
12{
13    protected function compileCallable(Twig_Compiler $compiler)
14    {
15        $callable = $this->getAttribute('callable');
16
17        $closingParenthesis = false;
18        if ($callable) {
19            if (is_string($callable)) {
20                $compiler->raw($callable);
21            } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
22                $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1]));
23            } else {
24                $type = ucfirst($this->getAttribute('type'));
25                $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
26                $closingParenthesis = true;
27            }
28        } else {
29            $compiler->raw($this->getAttribute('thing')->compile());
30        }
31
32        $this->compileArguments($compiler);
33
34        if ($closingParenthesis) {
35            $compiler->raw(')');
36        }
37    }
38
39    protected function compileArguments(Twig_Compiler $compiler)
40    {
41        $compiler->raw('(');
42
43        $first = true;
44
45        if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
46            $compiler->raw('$this->env');
47            $first = false;
48        }
49
50        if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
51            if (!$first) {
52                $compiler->raw(', ');
53            }
54            $compiler->raw('$context');
55            $first = false;
56        }
57
58        if ($this->hasAttribute('arguments')) {
59            foreach ($this->getAttribute('arguments') as $argument) {
60                if (!$first) {
61                    $compiler->raw(', ');
62                }
63                $compiler->string($argument);
64                $first = false;
65            }
66        }
67
68        if ($this->hasNode('node')) {
69            if (!$first) {
70                $compiler->raw(', ');
71            }
72            $compiler->subcompile($this->getNode('node'));
73            $first = false;
74        }
75
76        if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) {
77            $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
78
79            $arguments = $this->getArguments($callable, $this->getNode('arguments'));
80
81            foreach ($arguments as $node) {
82                if (!$first) {
83                    $compiler->raw(', ');
84                }
85                $compiler->subcompile($node);
86                $first = false;
87            }
88        }
89
90        $compiler->raw(')');
91    }
92
93    protected function getArguments($callable, $arguments)
94    {
95        $parameters = array();
96        $named = false;
97        foreach ($arguments as $name => $node) {
98            if (!is_int($name)) {
99                $named = true;
100                $name = $this->normalizeName($name);
101            }
102            $parameters[$name] = $node;
103        }
104
105        if (!$named) {
106            return $parameters;
107        }
108
109        if (!$callable) {
110            throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name')));
111        }
112
113        // manage named arguments
114        if (is_array($callable)) {
115            $r = new ReflectionMethod($callable[0], $callable[1]);
116        } elseif (is_object($callable) && !$callable instanceof Closure) {
117            $r = new ReflectionObject($callable);
118            $r = $r->getMethod('__invoke');
119        } else {
120            $r = new ReflectionFunction($callable);
121        }
122
123        $definition = $r->getParameters();
124        if ($this->hasNode('node')) {
125            array_shift($definition);
126        }
127        if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
128            array_shift($definition);
129        }
130        if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
131            array_shift($definition);
132        }
133        if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
134            foreach ($this->getAttribute('arguments') as $argument) {
135                array_shift($definition);
136            }
137        }
138
139        $arguments = array();
140        $pos = 0;
141        foreach ($definition as $param) {
142            $name = $this->normalizeName($param->name);
143
144            if (array_key_exists($name, $parameters)) {
145                $arguments[] = $parameters[$name];
146                unset($parameters[$name]);
147            } elseif (array_key_exists($pos, $parameters)) {
148                $arguments[] = $parameters[$pos];
149                unset($parameters[$pos]);
150                ++$pos;
151            } elseif ($param->isDefaultValueAvailable()) {
152                $arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
153            } elseif ($param->isOptional()) {
154                break;
155            } else {
156                throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
157            }
158        }
159
160        foreach (array_keys($parameters) as $name) {
161            throw new Twig_Error_Syntax(sprintf('Unknown argument "%s" for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
162        }
163
164        return $arguments;
165    }
166
167    protected function normalizeName($name)
168    {
169        return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
170    }
171}
Note: See TracBrowser for help on using the repository browser.

Sites map