@@ -46,7 +46,7 @@ |
||
46 | 46 | /** |
47 | 47 | * Dwoo_Adapters_ZendFramework_PluginProxy's constructor. |
48 | 48 | * |
49 | - * @param Zend_View_Interface $view |
|
49 | + * @param Dwoo_Adapters_ZendFramework_View $view |
|
50 | 50 | */ |
51 | 51 | public function __construct(Zend_View_Interface $view) |
52 | 52 | { |
@@ -36,88 +36,88 @@ |
||
36 | 36 | */ |
37 | 37 | class Dwoo_Adapters_ZendFramework_PluginProxy implements IPluginProxy |
38 | 38 | { |
39 | - /** |
|
40 | - * reference to the zend view owning this proxy. |
|
41 | - * |
|
42 | - * @var Zend_View_Interface |
|
43 | - */ |
|
44 | - public $view; |
|
39 | + /** |
|
40 | + * reference to the zend view owning this proxy. |
|
41 | + * |
|
42 | + * @var Zend_View_Interface |
|
43 | + */ |
|
44 | + public $view; |
|
45 | 45 | |
46 | - /** |
|
47 | - * Dwoo_Adapters_ZendFramework_PluginProxy's constructor. |
|
48 | - * |
|
49 | - * @param Zend_View_Interface $view |
|
50 | - */ |
|
51 | - public function __construct(Zend_View_Interface $view) |
|
52 | - { |
|
53 | - $this->view = $view; |
|
54 | - } |
|
46 | + /** |
|
47 | + * Dwoo_Adapters_ZendFramework_PluginProxy's constructor. |
|
48 | + * |
|
49 | + * @param Zend_View_Interface $view |
|
50 | + */ |
|
51 | + public function __construct(Zend_View_Interface $view) |
|
52 | + { |
|
53 | + $this->view = $view; |
|
54 | + } |
|
55 | 55 | |
56 | - /** |
|
57 | - * Called from Dwoo_Compiler to check if the requested plugin is available. |
|
58 | - * |
|
59 | - * @param string $name |
|
60 | - * |
|
61 | - * @return bool |
|
62 | - */ |
|
63 | - public function handles($name) |
|
64 | - { |
|
65 | - try { |
|
66 | - $this->view->getHelper($name); |
|
67 | - } catch (Zend_Loader_PluginLoader_Exception $e) { |
|
68 | - return false; |
|
69 | - } |
|
56 | + /** |
|
57 | + * Called from Dwoo_Compiler to check if the requested plugin is available. |
|
58 | + * |
|
59 | + * @param string $name |
|
60 | + * |
|
61 | + * @return bool |
|
62 | + */ |
|
63 | + public function handles($name) |
|
64 | + { |
|
65 | + try { |
|
66 | + $this->view->getHelper($name); |
|
67 | + } catch (Zend_Loader_PluginLoader_Exception $e) { |
|
68 | + return false; |
|
69 | + } |
|
70 | 70 | |
71 | - return true; |
|
72 | - } |
|
71 | + return true; |
|
72 | + } |
|
73 | 73 | |
74 | - /** |
|
75 | - * returns the code (as a string) to call the plugin |
|
76 | - * (this will be executed at runtime inside the Dwoo class). |
|
77 | - * |
|
78 | - * @param string $name the plugin name |
|
79 | - * @param array $params a parameter array, array key "*" is the rest array |
|
80 | - * |
|
81 | - * @return string |
|
82 | - */ |
|
83 | - public function getCode($name, $params) |
|
84 | - { |
|
85 | - return '$this->getPluginProxy()->view->'.$name.'('.Compiler::implode_r($params).')'; |
|
86 | - } |
|
74 | + /** |
|
75 | + * returns the code (as a string) to call the plugin |
|
76 | + * (this will be executed at runtime inside the Dwoo class). |
|
77 | + * |
|
78 | + * @param string $name the plugin name |
|
79 | + * @param array $params a parameter array, array key "*" is the rest array |
|
80 | + * |
|
81 | + * @return string |
|
82 | + */ |
|
83 | + public function getCode($name, $params) |
|
84 | + { |
|
85 | + return '$this->getPluginProxy()->view->'.$name.'('.Compiler::implode_r($params).')'; |
|
86 | + } |
|
87 | 87 | |
88 | - /** |
|
89 | - * returns a callback to the plugin, this is used with the reflection API to |
|
90 | - * find out about the plugin's parameter names etc. |
|
91 | - * |
|
92 | - * should you need a rest array (i.e. for ZendFramework helpers) without the |
|
93 | - * possibility to edit the plugin's code, you can provide a callback to some |
|
94 | - * other function with the correct parameter signature, i.e. : |
|
95 | - * <code> |
|
96 | - * return array($this, "callbackHelper"); |
|
97 | - * // and callbackHelper would be as such: |
|
98 | - * public function callbackHelper(array $rest=array()){} |
|
99 | - * </code> |
|
100 | - * |
|
101 | - * @param string $name the plugin name |
|
102 | - * |
|
103 | - * @return callback |
|
104 | - */ |
|
105 | - public function getCallback($name) |
|
106 | - { |
|
107 | - return array($this->view->getHelper($name), $name); |
|
108 | - } |
|
88 | + /** |
|
89 | + * returns a callback to the plugin, this is used with the reflection API to |
|
90 | + * find out about the plugin's parameter names etc. |
|
91 | + * |
|
92 | + * should you need a rest array (i.e. for ZendFramework helpers) without the |
|
93 | + * possibility to edit the plugin's code, you can provide a callback to some |
|
94 | + * other function with the correct parameter signature, i.e. : |
|
95 | + * <code> |
|
96 | + * return array($this, "callbackHelper"); |
|
97 | + * // and callbackHelper would be as such: |
|
98 | + * public function callbackHelper(array $rest=array()){} |
|
99 | + * </code> |
|
100 | + * |
|
101 | + * @param string $name the plugin name |
|
102 | + * |
|
103 | + * @return callback |
|
104 | + */ |
|
105 | + public function getCallback($name) |
|
106 | + { |
|
107 | + return array($this->view->getHelper($name), $name); |
|
108 | + } |
|
109 | 109 | |
110 | - /** |
|
111 | - * returns some code that will check if the plugin is loaded and if not load it |
|
112 | - * this is optional, if your plugins are autoloaded or whatever, just return an |
|
113 | - * empty string. |
|
114 | - * |
|
115 | - * @param string $name the plugin name |
|
116 | - * |
|
117 | - * @return string |
|
118 | - */ |
|
119 | - public function getLoader($name) |
|
120 | - { |
|
121 | - return ''; |
|
122 | - } |
|
110 | + /** |
|
111 | + * returns some code that will check if the plugin is loaded and if not load it |
|
112 | + * this is optional, if your plugins are autoloaded or whatever, just return an |
|
113 | + * empty string. |
|
114 | + * |
|
115 | + * @param string $name the plugin name |
|
116 | + * |
|
117 | + * @return string |
|
118 | + */ |
|
119 | + public function getLoader($name) |
|
120 | + { |
|
121 | + return ''; |
|
122 | + } |
|
123 | 123 | } |
@@ -83,7 +83,6 @@ discard block |
||
83 | 83 | * - type class name or object for engine, dataProvider or compiler |
84 | 84 | * - any set* method (compileDir for setCompileDir ...) |
85 | 85 | * |
86 | - * @param array $options |
|
87 | 86 | * |
88 | 87 | * @return Dwoo_Adapters_ZendFramework_View |
89 | 88 | */ |
@@ -437,7 +436,6 @@ discard block |
||
437 | 436 | * Processes a view script and outputs it. Output is then |
438 | 437 | * passed through filters. |
439 | 438 | * |
440 | - * @param string $name The script script name to process |
|
441 | 439 | * |
442 | 440 | * @return string The script output |
443 | 441 | */ |
@@ -16,507 +16,507 @@ |
||
16 | 16 | */ |
17 | 17 | class Dwoo_Adapters_ZendFramework_View extends Zend_View_Abstract |
18 | 18 | { |
19 | - /** |
|
20 | - * @var Core |
|
21 | - */ |
|
22 | - protected $_engine = null; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var Dwoo_Data |
|
26 | - */ |
|
27 | - protected $_dataProvider = null; |
|
28 | - |
|
29 | - /** |
|
30 | - * @var Dwoo_Compiler |
|
31 | - */ |
|
32 | - protected $_compiler = null; |
|
33 | - |
|
34 | - /** |
|
35 | - * Changing Filter's scope to play nicely. |
|
36 | - * |
|
37 | - * @var array |
|
38 | - */ |
|
39 | - protected $_filter = array(); |
|
40 | - |
|
41 | - /** |
|
42 | - * @var string |
|
43 | - */ |
|
44 | - protected $_templateFileClass = 'Dwoo_Template_File'; |
|
45 | - |
|
46 | - /** |
|
47 | - * @var array |
|
48 | - */ |
|
49 | - protected $_templateFileSettings = array(); |
|
50 | - |
|
51 | - /** |
|
52 | - * @var Dwoo_IPluginProxy |
|
53 | - */ |
|
54 | - protected $_pluginProxy = null; |
|
55 | - |
|
56 | - /** |
|
57 | - * Constructor method. |
|
58 | - * See setOptions for $opt details. |
|
59 | - * |
|
60 | - * @see setOptions |
|
61 | - * |
|
62 | - * @param array|Zend_Config List of options or Zend_Config instance |
|
63 | - */ |
|
64 | - public function __construct($opt = array()) |
|
65 | - { |
|
66 | - if (is_array($opt)) { |
|
67 | - $this->setOptions($opt); |
|
68 | - } elseif ($opt instanceof Zend_Config) { |
|
69 | - $this->setConfig($opt); |
|
70 | - } |
|
71 | - |
|
72 | - $this->init(); |
|
73 | - } |
|
74 | - |
|
75 | - /** |
|
76 | - * Set object state from options array |
|
77 | - * - engine = engine class name|engine object|array of options for engine |
|
78 | - * - dataProvider = data provider class name|data provider object|array of options for data provider |
|
79 | - * - compiler = compiler class name|compiler object|array of options for compiler |
|
80 | - * - templateFile =. |
|
81 | - * |
|
82 | - * Array of options: |
|
83 | - * - type class name or object for engine, dataProvider or compiler |
|
84 | - * - any set* method (compileDir for setCompileDir ...) |
|
85 | - * |
|
86 | - * @param array $options |
|
87 | - * |
|
88 | - * @return Dwoo_Adapters_ZendFramework_View |
|
89 | - */ |
|
90 | - public function setOptions(array $opt = array()) |
|
91 | - { |
|
92 | - // Making sure that everything is loaded. |
|
93 | - $classes = array('engine', 'dataProvider', 'compiler'); |
|
94 | - |
|
95 | - // Setting options to Dwoo objects... |
|
96 | - foreach ($opt as $type => $settings) { |
|
97 | - if (!method_exists($this, 'set'.$type)) { |
|
98 | - throw new Dwoo_Exception("Unknown type $type"); |
|
99 | - } |
|
100 | - |
|
101 | - if (is_string($settings) || is_object($settings)) { |
|
102 | - call_user_func(array($this, 'set'.$type), $settings); |
|
103 | - } elseif (is_array($settings)) { |
|
104 | - // Set requested class |
|
105 | - if (array_key_exists('type', $settings)) { |
|
106 | - call_user_func(array($this, 'set'.$type), $settings['type']); |
|
107 | - } |
|
108 | - |
|
109 | - if (in_array($type, $classes)) { |
|
110 | - // Call get so that the class is initialized |
|
111 | - $rel = call_user_func(array($this, 'get'.$type)); |
|
112 | - |
|
113 | - // Call set*() methods so that all the settings are set. |
|
114 | - foreach ($settings as $method => $value) { |
|
115 | - if (method_exists($rel, 'set'.$method)) { |
|
116 | - call_user_func(array($rel, 'set'.$method), $value); |
|
117 | - } |
|
118 | - } |
|
119 | - } elseif ('templateFile' == $type) { |
|
120 | - // Remember the settings for the templateFile |
|
121 | - $this->_templateFileSettings = $settings; |
|
122 | - } |
|
123 | - } |
|
124 | - } |
|
125 | - } |
|
126 | - |
|
127 | - /** |
|
128 | - * Set object state from Zend_Config object. |
|
129 | - * |
|
130 | - * @param Zend_Config $config |
|
131 | - * |
|
132 | - * @return Dwoo_Adapters_ZendFramework_View |
|
133 | - */ |
|
134 | - public function setConfig(Zend_Config $config) |
|
135 | - { |
|
136 | - return $this->setOptions($config->toArray()); |
|
137 | - } |
|
138 | - |
|
139 | - /** |
|
140 | - * Called before template rendering. |
|
141 | - * |
|
142 | - * Binds plugin proxy to the Dwoo. |
|
143 | - * |
|
144 | - * @see Dwoo_Adapters_ZendFramework_View::getPluginProxy(); |
|
145 | - * @see Dwoo_Core::setPluginProxy(); |
|
146 | - */ |
|
147 | - protected function preRender() |
|
148 | - { |
|
149 | - $this->getEngine()->setPluginProxy($this->getPluginProxy()); |
|
150 | - } |
|
151 | - |
|
152 | - /** |
|
153 | - * Wraper for Dwoo_Data::__set() |
|
154 | - * allows to assign variables using the object syntax. |
|
155 | - * |
|
156 | - * @see Dwoo_Data::__set() |
|
157 | - * |
|
158 | - * @param string $name the variable name |
|
159 | - * @param string $value the value to assign to it |
|
160 | - */ |
|
161 | - public function __set($name, $value) |
|
162 | - { |
|
163 | - $this->getDataProvider()->__set($name, $value); |
|
164 | - } |
|
165 | - |
|
166 | - /** |
|
167 | - * Sraper for Dwoo_Data::__get() allows to read variables using the object |
|
168 | - * syntax. |
|
169 | - * |
|
170 | - * @see Dwoo_Data::__get() |
|
171 | - * |
|
172 | - * @param string $name the variable name |
|
173 | - * |
|
174 | - * @return mixed |
|
175 | - */ |
|
176 | - public function __get($name) |
|
177 | - { |
|
178 | - return $this->getDataProvider()->__get($name); |
|
179 | - } |
|
180 | - |
|
181 | - /** |
|
182 | - * Wraper for Dwoo_Data::__isset() |
|
183 | - * supports calls to isset($dwooData->var). |
|
184 | - * |
|
185 | - * @see Dwoo_Data::__isset() |
|
186 | - * |
|
187 | - * @param string $name the variable name |
|
188 | - */ |
|
189 | - public function __isset($name) |
|
190 | - { |
|
191 | - return $this->getDataProvider()->__isset($name); |
|
192 | - } |
|
193 | - |
|
194 | - /** |
|
195 | - * Wraper for Dwoo_Data::_unset() |
|
196 | - * supports unsetting variables using the object syntax. |
|
197 | - * |
|
198 | - * @see Dwoo_Data::__unset() |
|
199 | - * |
|
200 | - * @param string $name the variable name |
|
201 | - */ |
|
202 | - public function __unset($name) |
|
203 | - { |
|
204 | - $this->getDataProvider()->__unset($name); |
|
205 | - } |
|
206 | - |
|
207 | - /** |
|
208 | - * Catches clone request and clones data provider. |
|
209 | - */ |
|
210 | - public function __clone() |
|
211 | - { |
|
212 | - $this->setDataProvider(clone $this->getDataProvider()); |
|
213 | - } |
|
214 | - |
|
215 | - /** |
|
216 | - * Returns plugin proxy interface. |
|
217 | - * |
|
218 | - * @return Dwoo_IPluginProxy |
|
219 | - */ |
|
220 | - public function getPluginProxy() |
|
221 | - { |
|
222 | - if (!$this->_pluginProxy) { |
|
223 | - $this->_pluginProxy = new Dwoo_Adapters_ZendFramework_PluginProxy($this); |
|
224 | - } |
|
225 | - |
|
226 | - return $this->_pluginProxy; |
|
227 | - } |
|
228 | - |
|
229 | - /** |
|
230 | - * Sets plugin proxy. |
|
231 | - * |
|
232 | - * @param Dwoo_IPluginProxy |
|
233 | - * |
|
234 | - * @return Dwoo_Adapters_ZendFramework_View |
|
235 | - */ |
|
236 | - public function setPluginProxy(Dwoo_IPluginProxy $pluginProxy) |
|
237 | - { |
|
238 | - $this->_pluginProxy = $pluginProxy; |
|
239 | - |
|
240 | - return $this; |
|
241 | - } |
|
242 | - |
|
243 | - /** |
|
244 | - * Sets template engine. |
|
245 | - * |
|
246 | - * @param string|Dwoo Object or name of the class |
|
247 | - */ |
|
248 | - public function setEngine($engine) |
|
249 | - { |
|
250 | - // if param given as an object |
|
251 | - if ($engine instanceof Dwoo_Core) { |
|
252 | - $this->_engine = $engine; |
|
253 | - } elseif (is_subclass_of($engine, 'Dwoo') || 'Dwoo' === $engine) { |
|
254 | - $this->_engine = new $engine(); |
|
255 | - } else { |
|
256 | - throw new Dwoo_Exception('Custom engine must be a subclass of Dwoo'); |
|
257 | - } |
|
258 | - } |
|
259 | - |
|
260 | - /** |
|
261 | - * Return the Dwoo template engine object. |
|
262 | - * |
|
263 | - * @return Dwoo |
|
264 | - */ |
|
265 | - public function getEngine() |
|
266 | - { |
|
267 | - if (null === $this->_engine) { |
|
268 | - $this->_engine = new Dwoo_Adapters_ZendFramework_Dwoo(); |
|
269 | - } |
|
270 | - |
|
271 | - return $this->_engine; |
|
272 | - } |
|
273 | - |
|
274 | - /** |
|
275 | - * Sets Dwoo data object. |
|
276 | - * |
|
277 | - * @param string|Dwoo_Data Object or name of the class |
|
278 | - */ |
|
279 | - public function setDataProvider($data) |
|
280 | - { |
|
281 | - if ($data instanceof Dwoo_IDataProvider) { |
|
282 | - $this->_dataProvider = $data; |
|
283 | - } elseif (is_subclass_of($data, 'Dwoo_Data') || 'Dwoo_Data' == $data) { |
|
284 | - $this->_dataProvider = new $data(); |
|
285 | - } else { |
|
286 | - throw new Dwoo_Exception('Custom data provider must be a subclass of Dwoo_Data or instance of Dwoo_IDataProvider'); |
|
287 | - } |
|
288 | - } |
|
289 | - |
|
290 | - /** |
|
291 | - * Return the Dwoo data object. |
|
292 | - * |
|
293 | - * @return Dwoo_Data |
|
294 | - */ |
|
295 | - public function getDataProvider() |
|
296 | - { |
|
297 | - if (null === $this->_dataProvider) { |
|
298 | - $this->_dataProvider = new Dwoo_Data(); |
|
299 | - |
|
300 | - // Satisfy Zend_View_Abstract wishes to access this unexisting property |
|
301 | - // by setting it to empty array (see Zend_View_Abstract::_filter) |
|
302 | - $this->_dataProvider->_filter = array(); |
|
303 | - } |
|
304 | - |
|
305 | - return $this->_dataProvider; |
|
306 | - } |
|
307 | - |
|
308 | - /** |
|
309 | - * Sets Dwoo compiler. |
|
310 | - * |
|
311 | - * @param string|Dwoo_Compiler Object or name of the class |
|
312 | - */ |
|
313 | - public function setCompiler($compiler) |
|
314 | - { |
|
315 | - |
|
316 | - // if param given as an object |
|
317 | - if ($compiler instanceof Dwoo_ICompiler) { |
|
318 | - $this->_compiler = $compiler; |
|
319 | - } |
|
320 | - // if param given as a string |
|
321 | - elseif (is_subclass_of($compiler, 'Dwoo_Compiler') || 'Dwoo_Compiler' == $compiler) { |
|
322 | - $this->_compiler = new $compiler(); |
|
323 | - } else { |
|
324 | - throw new Dwoo_Exception('Custom compiler must be a subclass of Dwoo_Compiler or instance of Dwoo_ICompiler'); |
|
325 | - } |
|
326 | - } |
|
327 | - |
|
328 | - /** |
|
329 | - * Return the Dwoo compiler object. |
|
330 | - * |
|
331 | - * @return Dwoo_Compiler |
|
332 | - */ |
|
333 | - public function getCompiler() |
|
334 | - { |
|
335 | - if (null === $this->_compiler) { |
|
336 | - $this->_compiler = Dwoo_Compiler::compilerFactory(); |
|
337 | - } |
|
338 | - |
|
339 | - return $this->_compiler; |
|
340 | - } |
|
341 | - |
|
342 | - /** |
|
343 | - * Initializes Dwoo_ITemplate type of class and sets properties from _templateFileSettings. |
|
344 | - * |
|
345 | - * @param string Dwoo_ITemplate $template |
|
346 | - * |
|
347 | - * @return Dwoo_ITemplate |
|
348 | - */ |
|
349 | - public function getTemplateFile($template) |
|
350 | - { |
|
351 | - $templateFileClass = $this->_templateFileClass; |
|
352 | - |
|
353 | - $dwooTemplateFile = new $templateFileClass($template); |
|
354 | - |
|
355 | - if (!($dwooTemplateFile instanceof Dwoo_ITemplate)) { |
|
356 | - throw new Dwoo_Exception('Custom templateFile class must be a subclass of Dwoo_ITemplate'); |
|
357 | - } |
|
358 | - |
|
359 | - foreach ($this->_templateFileSettings as $method => $value) { |
|
360 | - if (method_exists($dwooTemplateFile, 'set'.$method)) { |
|
361 | - call_user_func(array($dwooTemplateFile, 'set'.$method), $value); |
|
362 | - } |
|
363 | - } |
|
364 | - |
|
365 | - return $dwooTemplateFile; |
|
366 | - } |
|
367 | - |
|
368 | - /** |
|
369 | - * Dwoo_ITemplate type of class. |
|
370 | - * |
|
371 | - * @param string Name of the class |
|
372 | - */ |
|
373 | - public function setTemplateFile($tempateFileClass) |
|
374 | - { |
|
375 | - $this->_templateFileClass = $tempateFileClass; |
|
376 | - } |
|
377 | - |
|
378 | - /** |
|
379 | - * Passes data to Dwoo_Data object. |
|
380 | - * |
|
381 | - * @see Dwoo_Data::assign() |
|
382 | - * |
|
383 | - * @param array|string $name |
|
384 | - * @param mixed $val |
|
385 | - * |
|
386 | - * @return Dwoo_Adapters_ZendFramework_View |
|
387 | - */ |
|
388 | - public function assign($name, $val = null) |
|
389 | - { |
|
390 | - $this->getDataProvider()->assign($name, $val); |
|
391 | - |
|
392 | - return $this; |
|
393 | - } |
|
394 | - |
|
395 | - /** |
|
396 | - * Return list of all assigned variables. |
|
397 | - * |
|
398 | - * @return array |
|
399 | - */ |
|
400 | - public function getVars() |
|
401 | - { |
|
402 | - return $this->getDataProvider()->getData(); |
|
403 | - } |
|
404 | - |
|
405 | - /** |
|
406 | - * Clear all assigned variables. |
|
407 | - * |
|
408 | - * Clears all variables assigned to Zend_View either via {@link assign()} or |
|
409 | - * property overloading ({@link __get()}/{@link __set()}). |
|
410 | - * |
|
411 | - * @return Dwoo_Adapters_ZendFramework_View |
|
412 | - */ |
|
413 | - public function clearVars() |
|
414 | - { |
|
415 | - $this->getDataProvider()->clear(); |
|
416 | - |
|
417 | - return $this; |
|
418 | - } |
|
419 | - |
|
420 | - /** |
|
421 | - * Wraper for parent's render method so preRender method |
|
422 | - * can be called (that will bind the plugin proxy to the |
|
423 | - * engine. |
|
424 | - * |
|
425 | - * @see Zend_View_Abstract::render |
|
426 | - * |
|
427 | - * @return string The script output |
|
428 | - */ |
|
429 | - public function render($name) |
|
430 | - { |
|
431 | - $this->preRender(); |
|
432 | - |
|
433 | - return parent::render($name); |
|
434 | - } |
|
435 | - |
|
436 | - /** |
|
437 | - * Processes a view script and outputs it. Output is then |
|
438 | - * passed through filters. |
|
439 | - * |
|
440 | - * @param string $name The script script name to process |
|
441 | - * |
|
442 | - * @return string The script output |
|
443 | - */ |
|
444 | - public function _run() |
|
445 | - { |
|
446 | - echo $this->_engine->get( |
|
447 | - $this->getTemplateFile(func_get_arg(0)), |
|
448 | - $this->getDataProvider(), |
|
449 | - $this->getCompiler() |
|
450 | - ); |
|
451 | - } |
|
452 | - |
|
453 | - /** |
|
454 | - * Add plugin path. |
|
455 | - * |
|
456 | - * @param string $dir Directory |
|
457 | - * |
|
458 | - * @return Dwoo_Adapters_ZendFramework_View |
|
459 | - */ |
|
460 | - public function addPluginDir($dir) |
|
461 | - { |
|
462 | - $this->getEngine()->getLoader()->addDirectory($dir); |
|
463 | - |
|
464 | - return $this; |
|
465 | - } |
|
466 | - |
|
467 | - /** |
|
468 | - * Set compile path. |
|
469 | - * |
|
470 | - * @param string $dir Directory |
|
471 | - * |
|
472 | - * @return Dwoo_Adapters_ZendFramework_View |
|
473 | - */ |
|
474 | - public function setCompileDir($dir) |
|
475 | - { |
|
476 | - $this->getEngine()->setCompileDir($dir); |
|
477 | - |
|
478 | - return $this; |
|
479 | - } |
|
480 | - |
|
481 | - /** |
|
482 | - * Set cache path. |
|
483 | - * |
|
484 | - * @param string $dir Directory |
|
485 | - * |
|
486 | - * @return Dwoo_Adapters_ZendFramework_View |
|
487 | - */ |
|
488 | - public function setCacheDir($dir) |
|
489 | - { |
|
490 | - $this->getEngine()->setCacheDir($dir); |
|
491 | - |
|
492 | - return $this; |
|
493 | - } |
|
494 | - |
|
495 | - /** |
|
496 | - * Set cache lifetime. |
|
497 | - * |
|
498 | - * @param string $seconds Lifetime in seconds |
|
499 | - * |
|
500 | - * @return Dwoo_Adapters_ZendFramework_View |
|
501 | - */ |
|
502 | - public function setCacheLifetime($seconds) |
|
503 | - { |
|
504 | - $this->getEngine()->setCacheTime($seconds); |
|
505 | - |
|
506 | - return $this; |
|
507 | - } |
|
508 | - |
|
509 | - /** |
|
510 | - * Set charset. |
|
511 | - * |
|
512 | - * @param string $charset |
|
513 | - * |
|
514 | - * @return Dwoo_Adapters_ZendFramework_View |
|
515 | - */ |
|
516 | - public function setCharset($charset) |
|
517 | - { |
|
518 | - $this->_engine->setCharset($charset); |
|
519 | - |
|
520 | - return $this; |
|
521 | - } |
|
19 | + /** |
|
20 | + * @var Core |
|
21 | + */ |
|
22 | + protected $_engine = null; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var Dwoo_Data |
|
26 | + */ |
|
27 | + protected $_dataProvider = null; |
|
28 | + |
|
29 | + /** |
|
30 | + * @var Dwoo_Compiler |
|
31 | + */ |
|
32 | + protected $_compiler = null; |
|
33 | + |
|
34 | + /** |
|
35 | + * Changing Filter's scope to play nicely. |
|
36 | + * |
|
37 | + * @var array |
|
38 | + */ |
|
39 | + protected $_filter = array(); |
|
40 | + |
|
41 | + /** |
|
42 | + * @var string |
|
43 | + */ |
|
44 | + protected $_templateFileClass = 'Dwoo_Template_File'; |
|
45 | + |
|
46 | + /** |
|
47 | + * @var array |
|
48 | + */ |
|
49 | + protected $_templateFileSettings = array(); |
|
50 | + |
|
51 | + /** |
|
52 | + * @var Dwoo_IPluginProxy |
|
53 | + */ |
|
54 | + protected $_pluginProxy = null; |
|
55 | + |
|
56 | + /** |
|
57 | + * Constructor method. |
|
58 | + * See setOptions for $opt details. |
|
59 | + * |
|
60 | + * @see setOptions |
|
61 | + * |
|
62 | + * @param array|Zend_Config List of options or Zend_Config instance |
|
63 | + */ |
|
64 | + public function __construct($opt = array()) |
|
65 | + { |
|
66 | + if (is_array($opt)) { |
|
67 | + $this->setOptions($opt); |
|
68 | + } elseif ($opt instanceof Zend_Config) { |
|
69 | + $this->setConfig($opt); |
|
70 | + } |
|
71 | + |
|
72 | + $this->init(); |
|
73 | + } |
|
74 | + |
|
75 | + /** |
|
76 | + * Set object state from options array |
|
77 | + * - engine = engine class name|engine object|array of options for engine |
|
78 | + * - dataProvider = data provider class name|data provider object|array of options for data provider |
|
79 | + * - compiler = compiler class name|compiler object|array of options for compiler |
|
80 | + * - templateFile =. |
|
81 | + * |
|
82 | + * Array of options: |
|
83 | + * - type class name or object for engine, dataProvider or compiler |
|
84 | + * - any set* method (compileDir for setCompileDir ...) |
|
85 | + * |
|
86 | + * @param array $options |
|
87 | + * |
|
88 | + * @return Dwoo_Adapters_ZendFramework_View |
|
89 | + */ |
|
90 | + public function setOptions(array $opt = array()) |
|
91 | + { |
|
92 | + // Making sure that everything is loaded. |
|
93 | + $classes = array('engine', 'dataProvider', 'compiler'); |
|
94 | + |
|
95 | + // Setting options to Dwoo objects... |
|
96 | + foreach ($opt as $type => $settings) { |
|
97 | + if (!method_exists($this, 'set'.$type)) { |
|
98 | + throw new Dwoo_Exception("Unknown type $type"); |
|
99 | + } |
|
100 | + |
|
101 | + if (is_string($settings) || is_object($settings)) { |
|
102 | + call_user_func(array($this, 'set'.$type), $settings); |
|
103 | + } elseif (is_array($settings)) { |
|
104 | + // Set requested class |
|
105 | + if (array_key_exists('type', $settings)) { |
|
106 | + call_user_func(array($this, 'set'.$type), $settings['type']); |
|
107 | + } |
|
108 | + |
|
109 | + if (in_array($type, $classes)) { |
|
110 | + // Call get so that the class is initialized |
|
111 | + $rel = call_user_func(array($this, 'get'.$type)); |
|
112 | + |
|
113 | + // Call set*() methods so that all the settings are set. |
|
114 | + foreach ($settings as $method => $value) { |
|
115 | + if (method_exists($rel, 'set'.$method)) { |
|
116 | + call_user_func(array($rel, 'set'.$method), $value); |
|
117 | + } |
|
118 | + } |
|
119 | + } elseif ('templateFile' == $type) { |
|
120 | + // Remember the settings for the templateFile |
|
121 | + $this->_templateFileSettings = $settings; |
|
122 | + } |
|
123 | + } |
|
124 | + } |
|
125 | + } |
|
126 | + |
|
127 | + /** |
|
128 | + * Set object state from Zend_Config object. |
|
129 | + * |
|
130 | + * @param Zend_Config $config |
|
131 | + * |
|
132 | + * @return Dwoo_Adapters_ZendFramework_View |
|
133 | + */ |
|
134 | + public function setConfig(Zend_Config $config) |
|
135 | + { |
|
136 | + return $this->setOptions($config->toArray()); |
|
137 | + } |
|
138 | + |
|
139 | + /** |
|
140 | + * Called before template rendering. |
|
141 | + * |
|
142 | + * Binds plugin proxy to the Dwoo. |
|
143 | + * |
|
144 | + * @see Dwoo_Adapters_ZendFramework_View::getPluginProxy(); |
|
145 | + * @see Dwoo_Core::setPluginProxy(); |
|
146 | + */ |
|
147 | + protected function preRender() |
|
148 | + { |
|
149 | + $this->getEngine()->setPluginProxy($this->getPluginProxy()); |
|
150 | + } |
|
151 | + |
|
152 | + /** |
|
153 | + * Wraper for Dwoo_Data::__set() |
|
154 | + * allows to assign variables using the object syntax. |
|
155 | + * |
|
156 | + * @see Dwoo_Data::__set() |
|
157 | + * |
|
158 | + * @param string $name the variable name |
|
159 | + * @param string $value the value to assign to it |
|
160 | + */ |
|
161 | + public function __set($name, $value) |
|
162 | + { |
|
163 | + $this->getDataProvider()->__set($name, $value); |
|
164 | + } |
|
165 | + |
|
166 | + /** |
|
167 | + * Sraper for Dwoo_Data::__get() allows to read variables using the object |
|
168 | + * syntax. |
|
169 | + * |
|
170 | + * @see Dwoo_Data::__get() |
|
171 | + * |
|
172 | + * @param string $name the variable name |
|
173 | + * |
|
174 | + * @return mixed |
|
175 | + */ |
|
176 | + public function __get($name) |
|
177 | + { |
|
178 | + return $this->getDataProvider()->__get($name); |
|
179 | + } |
|
180 | + |
|
181 | + /** |
|
182 | + * Wraper for Dwoo_Data::__isset() |
|
183 | + * supports calls to isset($dwooData->var). |
|
184 | + * |
|
185 | + * @see Dwoo_Data::__isset() |
|
186 | + * |
|
187 | + * @param string $name the variable name |
|
188 | + */ |
|
189 | + public function __isset($name) |
|
190 | + { |
|
191 | + return $this->getDataProvider()->__isset($name); |
|
192 | + } |
|
193 | + |
|
194 | + /** |
|
195 | + * Wraper for Dwoo_Data::_unset() |
|
196 | + * supports unsetting variables using the object syntax. |
|
197 | + * |
|
198 | + * @see Dwoo_Data::__unset() |
|
199 | + * |
|
200 | + * @param string $name the variable name |
|
201 | + */ |
|
202 | + public function __unset($name) |
|
203 | + { |
|
204 | + $this->getDataProvider()->__unset($name); |
|
205 | + } |
|
206 | + |
|
207 | + /** |
|
208 | + * Catches clone request and clones data provider. |
|
209 | + */ |
|
210 | + public function __clone() |
|
211 | + { |
|
212 | + $this->setDataProvider(clone $this->getDataProvider()); |
|
213 | + } |
|
214 | + |
|
215 | + /** |
|
216 | + * Returns plugin proxy interface. |
|
217 | + * |
|
218 | + * @return Dwoo_IPluginProxy |
|
219 | + */ |
|
220 | + public function getPluginProxy() |
|
221 | + { |
|
222 | + if (!$this->_pluginProxy) { |
|
223 | + $this->_pluginProxy = new Dwoo_Adapters_ZendFramework_PluginProxy($this); |
|
224 | + } |
|
225 | + |
|
226 | + return $this->_pluginProxy; |
|
227 | + } |
|
228 | + |
|
229 | + /** |
|
230 | + * Sets plugin proxy. |
|
231 | + * |
|
232 | + * @param Dwoo_IPluginProxy |
|
233 | + * |
|
234 | + * @return Dwoo_Adapters_ZendFramework_View |
|
235 | + */ |
|
236 | + public function setPluginProxy(Dwoo_IPluginProxy $pluginProxy) |
|
237 | + { |
|
238 | + $this->_pluginProxy = $pluginProxy; |
|
239 | + |
|
240 | + return $this; |
|
241 | + } |
|
242 | + |
|
243 | + /** |
|
244 | + * Sets template engine. |
|
245 | + * |
|
246 | + * @param string|Dwoo Object or name of the class |
|
247 | + */ |
|
248 | + public function setEngine($engine) |
|
249 | + { |
|
250 | + // if param given as an object |
|
251 | + if ($engine instanceof Dwoo_Core) { |
|
252 | + $this->_engine = $engine; |
|
253 | + } elseif (is_subclass_of($engine, 'Dwoo') || 'Dwoo' === $engine) { |
|
254 | + $this->_engine = new $engine(); |
|
255 | + } else { |
|
256 | + throw new Dwoo_Exception('Custom engine must be a subclass of Dwoo'); |
|
257 | + } |
|
258 | + } |
|
259 | + |
|
260 | + /** |
|
261 | + * Return the Dwoo template engine object. |
|
262 | + * |
|
263 | + * @return Dwoo |
|
264 | + */ |
|
265 | + public function getEngine() |
|
266 | + { |
|
267 | + if (null === $this->_engine) { |
|
268 | + $this->_engine = new Dwoo_Adapters_ZendFramework_Dwoo(); |
|
269 | + } |
|
270 | + |
|
271 | + return $this->_engine; |
|
272 | + } |
|
273 | + |
|
274 | + /** |
|
275 | + * Sets Dwoo data object. |
|
276 | + * |
|
277 | + * @param string|Dwoo_Data Object or name of the class |
|
278 | + */ |
|
279 | + public function setDataProvider($data) |
|
280 | + { |
|
281 | + if ($data instanceof Dwoo_IDataProvider) { |
|
282 | + $this->_dataProvider = $data; |
|
283 | + } elseif (is_subclass_of($data, 'Dwoo_Data') || 'Dwoo_Data' == $data) { |
|
284 | + $this->_dataProvider = new $data(); |
|
285 | + } else { |
|
286 | + throw new Dwoo_Exception('Custom data provider must be a subclass of Dwoo_Data or instance of Dwoo_IDataProvider'); |
|
287 | + } |
|
288 | + } |
|
289 | + |
|
290 | + /** |
|
291 | + * Return the Dwoo data object. |
|
292 | + * |
|
293 | + * @return Dwoo_Data |
|
294 | + */ |
|
295 | + public function getDataProvider() |
|
296 | + { |
|
297 | + if (null === $this->_dataProvider) { |
|
298 | + $this->_dataProvider = new Dwoo_Data(); |
|
299 | + |
|
300 | + // Satisfy Zend_View_Abstract wishes to access this unexisting property |
|
301 | + // by setting it to empty array (see Zend_View_Abstract::_filter) |
|
302 | + $this->_dataProvider->_filter = array(); |
|
303 | + } |
|
304 | + |
|
305 | + return $this->_dataProvider; |
|
306 | + } |
|
307 | + |
|
308 | + /** |
|
309 | + * Sets Dwoo compiler. |
|
310 | + * |
|
311 | + * @param string|Dwoo_Compiler Object or name of the class |
|
312 | + */ |
|
313 | + public function setCompiler($compiler) |
|
314 | + { |
|
315 | + |
|
316 | + // if param given as an object |
|
317 | + if ($compiler instanceof Dwoo_ICompiler) { |
|
318 | + $this->_compiler = $compiler; |
|
319 | + } |
|
320 | + // if param given as a string |
|
321 | + elseif (is_subclass_of($compiler, 'Dwoo_Compiler') || 'Dwoo_Compiler' == $compiler) { |
|
322 | + $this->_compiler = new $compiler(); |
|
323 | + } else { |
|
324 | + throw new Dwoo_Exception('Custom compiler must be a subclass of Dwoo_Compiler or instance of Dwoo_ICompiler'); |
|
325 | + } |
|
326 | + } |
|
327 | + |
|
328 | + /** |
|
329 | + * Return the Dwoo compiler object. |
|
330 | + * |
|
331 | + * @return Dwoo_Compiler |
|
332 | + */ |
|
333 | + public function getCompiler() |
|
334 | + { |
|
335 | + if (null === $this->_compiler) { |
|
336 | + $this->_compiler = Dwoo_Compiler::compilerFactory(); |
|
337 | + } |
|
338 | + |
|
339 | + return $this->_compiler; |
|
340 | + } |
|
341 | + |
|
342 | + /** |
|
343 | + * Initializes Dwoo_ITemplate type of class and sets properties from _templateFileSettings. |
|
344 | + * |
|
345 | + * @param string Dwoo_ITemplate $template |
|
346 | + * |
|
347 | + * @return Dwoo_ITemplate |
|
348 | + */ |
|
349 | + public function getTemplateFile($template) |
|
350 | + { |
|
351 | + $templateFileClass = $this->_templateFileClass; |
|
352 | + |
|
353 | + $dwooTemplateFile = new $templateFileClass($template); |
|
354 | + |
|
355 | + if (!($dwooTemplateFile instanceof Dwoo_ITemplate)) { |
|
356 | + throw new Dwoo_Exception('Custom templateFile class must be a subclass of Dwoo_ITemplate'); |
|
357 | + } |
|
358 | + |
|
359 | + foreach ($this->_templateFileSettings as $method => $value) { |
|
360 | + if (method_exists($dwooTemplateFile, 'set'.$method)) { |
|
361 | + call_user_func(array($dwooTemplateFile, 'set'.$method), $value); |
|
362 | + } |
|
363 | + } |
|
364 | + |
|
365 | + return $dwooTemplateFile; |
|
366 | + } |
|
367 | + |
|
368 | + /** |
|
369 | + * Dwoo_ITemplate type of class. |
|
370 | + * |
|
371 | + * @param string Name of the class |
|
372 | + */ |
|
373 | + public function setTemplateFile($tempateFileClass) |
|
374 | + { |
|
375 | + $this->_templateFileClass = $tempateFileClass; |
|
376 | + } |
|
377 | + |
|
378 | + /** |
|
379 | + * Passes data to Dwoo_Data object. |
|
380 | + * |
|
381 | + * @see Dwoo_Data::assign() |
|
382 | + * |
|
383 | + * @param array|string $name |
|
384 | + * @param mixed $val |
|
385 | + * |
|
386 | + * @return Dwoo_Adapters_ZendFramework_View |
|
387 | + */ |
|
388 | + public function assign($name, $val = null) |
|
389 | + { |
|
390 | + $this->getDataProvider()->assign($name, $val); |
|
391 | + |
|
392 | + return $this; |
|
393 | + } |
|
394 | + |
|
395 | + /** |
|
396 | + * Return list of all assigned variables. |
|
397 | + * |
|
398 | + * @return array |
|
399 | + */ |
|
400 | + public function getVars() |
|
401 | + { |
|
402 | + return $this->getDataProvider()->getData(); |
|
403 | + } |
|
404 | + |
|
405 | + /** |
|
406 | + * Clear all assigned variables. |
|
407 | + * |
|
408 | + * Clears all variables assigned to Zend_View either via {@link assign()} or |
|
409 | + * property overloading ({@link __get()}/{@link __set()}). |
|
410 | + * |
|
411 | + * @return Dwoo_Adapters_ZendFramework_View |
|
412 | + */ |
|
413 | + public function clearVars() |
|
414 | + { |
|
415 | + $this->getDataProvider()->clear(); |
|
416 | + |
|
417 | + return $this; |
|
418 | + } |
|
419 | + |
|
420 | + /** |
|
421 | + * Wraper for parent's render method so preRender method |
|
422 | + * can be called (that will bind the plugin proxy to the |
|
423 | + * engine. |
|
424 | + * |
|
425 | + * @see Zend_View_Abstract::render |
|
426 | + * |
|
427 | + * @return string The script output |
|
428 | + */ |
|
429 | + public function render($name) |
|
430 | + { |
|
431 | + $this->preRender(); |
|
432 | + |
|
433 | + return parent::render($name); |
|
434 | + } |
|
435 | + |
|
436 | + /** |
|
437 | + * Processes a view script and outputs it. Output is then |
|
438 | + * passed through filters. |
|
439 | + * |
|
440 | + * @param string $name The script script name to process |
|
441 | + * |
|
442 | + * @return string The script output |
|
443 | + */ |
|
444 | + public function _run() |
|
445 | + { |
|
446 | + echo $this->_engine->get( |
|
447 | + $this->getTemplateFile(func_get_arg(0)), |
|
448 | + $this->getDataProvider(), |
|
449 | + $this->getCompiler() |
|
450 | + ); |
|
451 | + } |
|
452 | + |
|
453 | + /** |
|
454 | + * Add plugin path. |
|
455 | + * |
|
456 | + * @param string $dir Directory |
|
457 | + * |
|
458 | + * @return Dwoo_Adapters_ZendFramework_View |
|
459 | + */ |
|
460 | + public function addPluginDir($dir) |
|
461 | + { |
|
462 | + $this->getEngine()->getLoader()->addDirectory($dir); |
|
463 | + |
|
464 | + return $this; |
|
465 | + } |
|
466 | + |
|
467 | + /** |
|
468 | + * Set compile path. |
|
469 | + * |
|
470 | + * @param string $dir Directory |
|
471 | + * |
|
472 | + * @return Dwoo_Adapters_ZendFramework_View |
|
473 | + */ |
|
474 | + public function setCompileDir($dir) |
|
475 | + { |
|
476 | + $this->getEngine()->setCompileDir($dir); |
|
477 | + |
|
478 | + return $this; |
|
479 | + } |
|
480 | + |
|
481 | + /** |
|
482 | + * Set cache path. |
|
483 | + * |
|
484 | + * @param string $dir Directory |
|
485 | + * |
|
486 | + * @return Dwoo_Adapters_ZendFramework_View |
|
487 | + */ |
|
488 | + public function setCacheDir($dir) |
|
489 | + { |
|
490 | + $this->getEngine()->setCacheDir($dir); |
|
491 | + |
|
492 | + return $this; |
|
493 | + } |
|
494 | + |
|
495 | + /** |
|
496 | + * Set cache lifetime. |
|
497 | + * |
|
498 | + * @param string $seconds Lifetime in seconds |
|
499 | + * |
|
500 | + * @return Dwoo_Adapters_ZendFramework_View |
|
501 | + */ |
|
502 | + public function setCacheLifetime($seconds) |
|
503 | + { |
|
504 | + $this->getEngine()->setCacheTime($seconds); |
|
505 | + |
|
506 | + return $this; |
|
507 | + } |
|
508 | + |
|
509 | + /** |
|
510 | + * Set charset. |
|
511 | + * |
|
512 | + * @param string $charset |
|
513 | + * |
|
514 | + * @return Dwoo_Adapters_ZendFramework_View |
|
515 | + */ |
|
516 | + public function setCharset($charset) |
|
517 | + { |
|
518 | + $this->_engine->setCharset($charset); |
|
519 | + |
|
520 | + return $this; |
|
521 | + } |
|
522 | 522 | } |
@@ -277,7 +277,7 @@ discard block |
||
277 | 277 | /** |
278 | 278 | * Returns the left and right template delimiters. |
279 | 279 | * |
280 | - * @return array containing the left and the right delimiters |
|
280 | + * @return string[] containing the left and the right delimiters |
|
281 | 281 | */ |
282 | 282 | public function getDelimiters() |
283 | 283 | { |
@@ -362,7 +362,7 @@ discard block |
||
362 | 362 | * Adds a preprocessor to the compiler, it will be called |
363 | 363 | * before the template is compiled. |
364 | 364 | * |
365 | - * @param mixed $callback either a valid callback to the preprocessor or a simple name if the autoload is set to |
|
365 | + * @param string $callback either a valid callback to the preprocessor or a simple name if the autoload is set to |
|
366 | 366 | * true |
367 | 367 | * @param bool $autoload if set to true, the preprocessor is auto-loaded from one of the plugin directories, else |
368 | 368 | * you must provide a valid callback |
@@ -1321,7 +1321,7 @@ discard block |
||
1321 | 1321 | * |
1322 | 1322 | * @param array $params parameter array |
1323 | 1323 | * |
1324 | - * @return array tokens |
|
1324 | + * @return Compiler tokens |
|
1325 | 1325 | */ |
1326 | 1326 | public function getParamTokens(array $params) |
1327 | 1327 | { |
@@ -31,3596 +31,3596 @@ |
||
31 | 31 | */ |
32 | 32 | class Compiler implements ICompiler |
33 | 33 | { |
34 | - /** |
|
35 | - * Constant that represents a php opening tag. |
|
36 | - * use it in case it needs to be adjusted |
|
37 | - * |
|
38 | - * @var string |
|
39 | - */ |
|
40 | - const PHP_OPEN = '<?php '; |
|
41 | - |
|
42 | - /** |
|
43 | - * Constant that represents a php closing tag. |
|
44 | - * use it in case it needs to be adjusted |
|
45 | - * |
|
46 | - * @var string |
|
47 | - */ |
|
48 | - const PHP_CLOSE = '?>'; |
|
49 | - |
|
50 | - /** |
|
51 | - * Boolean flag to enable or disable debugging output. |
|
52 | - * |
|
53 | - * @var bool |
|
54 | - */ |
|
55 | - public $debug = false; |
|
56 | - |
|
57 | - /** |
|
58 | - * Left script delimiter. |
|
59 | - * |
|
60 | - * @var string |
|
61 | - */ |
|
62 | - protected $ld = '{'; |
|
63 | - |
|
64 | - /** |
|
65 | - * Left script delimiter with escaped regex meta characters. |
|
66 | - * |
|
67 | - * @var string |
|
68 | - */ |
|
69 | - protected $ldr = '\\{'; |
|
70 | - |
|
71 | - /** |
|
72 | - * Right script delimiter. |
|
73 | - * |
|
74 | - * @var string |
|
75 | - */ |
|
76 | - protected $rd = '}'; |
|
77 | - |
|
78 | - /** |
|
79 | - * Right script delimiter with escaped regex meta characters. |
|
80 | - * |
|
81 | - * @var string |
|
82 | - */ |
|
83 | - protected $rdr = '\\}'; |
|
84 | - |
|
85 | - /** |
|
86 | - * Defines whether the nested comments should be parsed as nested or not. |
|
87 | - * defaults to false (classic block comment parsing as in all languages) |
|
88 | - * |
|
89 | - * @var bool |
|
90 | - */ |
|
91 | - protected $allowNestedComments = false; |
|
92 | - |
|
93 | - /** |
|
94 | - * Defines whether opening and closing tags can contain spaces before valid data or not. |
|
95 | - * turn to true if you want to be sloppy with the syntax, but when set to false it allows |
|
96 | - * to skip javascript and css tags as long as they are in the form "{ something", which is |
|
97 | - * nice. default is false. |
|
98 | - * |
|
99 | - * @var bool |
|
100 | - */ |
|
101 | - protected $allowLooseOpenings = false; |
|
102 | - |
|
103 | - /** |
|
104 | - * Defines whether the compiler will automatically html-escape variables or not. |
|
105 | - * default is false |
|
106 | - * |
|
107 | - * @var bool |
|
108 | - */ |
|
109 | - protected $autoEscape = false; |
|
110 | - |
|
111 | - /** |
|
112 | - * Security policy object. |
|
113 | - * |
|
114 | - * @var SecurityPolicy |
|
115 | - */ |
|
116 | - protected $securityPolicy; |
|
117 | - |
|
118 | - /** |
|
119 | - * Stores the custom plugins registered with this compiler. |
|
120 | - * |
|
121 | - * @var array |
|
122 | - */ |
|
123 | - protected $customPlugins = array(); |
|
124 | - |
|
125 | - /** |
|
126 | - * Stores the template plugins registered with this compiler. |
|
127 | - * |
|
128 | - * @var array |
|
129 | - */ |
|
130 | - protected $templatePlugins = array(); |
|
131 | - |
|
132 | - /** |
|
133 | - * Stores the pre- and post-processors callbacks. |
|
134 | - * |
|
135 | - * @var array |
|
136 | - */ |
|
137 | - protected $processors = array('pre' => array(), 'post' => array()); |
|
138 | - |
|
139 | - /** |
|
140 | - * Stores a list of plugins that are used in the currently compiled |
|
141 | - * template, and that are not compilable. these plugins will be loaded |
|
142 | - * during the template's runtime if required. |
|
143 | - * it is a 1D array formatted as key:pluginName value:pluginType |
|
144 | - * |
|
145 | - * @var array |
|
146 | - */ |
|
147 | - protected $usedPlugins; |
|
148 | - |
|
149 | - /** |
|
150 | - * Stores the template undergoing compilation. |
|
151 | - * |
|
152 | - * @var string |
|
153 | - */ |
|
154 | - protected $template; |
|
155 | - |
|
156 | - /** |
|
157 | - * Stores the current pointer position inside the template. |
|
158 | - * |
|
159 | - * @var int |
|
160 | - */ |
|
161 | - protected $pointer; |
|
162 | - |
|
163 | - /** |
|
164 | - * Stores the current line count inside the template for debugging purposes. |
|
165 | - * |
|
166 | - * @var int |
|
167 | - */ |
|
168 | - protected $line; |
|
169 | - |
|
170 | - /** |
|
171 | - * Stores the current template source while compiling it. |
|
172 | - * |
|
173 | - * @var string |
|
174 | - */ |
|
175 | - protected $templateSource; |
|
176 | - |
|
177 | - /** |
|
178 | - * Stores the data within which the scope moves. |
|
179 | - * |
|
180 | - * @var array |
|
181 | - */ |
|
182 | - protected $data; |
|
183 | - |
|
184 | - /** |
|
185 | - * Variable scope of the compiler, set to null if |
|
186 | - * it can not be resolved to a static string (i.e. if some |
|
187 | - * plugin defines a new scope based on a variable array key). |
|
188 | - * |
|
189 | - * @var mixed |
|
190 | - */ |
|
191 | - protected $scope; |
|
192 | - |
|
193 | - /** |
|
194 | - * Variable scope tree, that allows to rebuild the current |
|
195 | - * scope if required, i.e. when going to a parent level. |
|
196 | - * |
|
197 | - * @var array |
|
198 | - */ |
|
199 | - protected $scopeTree; |
|
200 | - |
|
201 | - /** |
|
202 | - * Block plugins stack, accessible through some methods. |
|
203 | - * |
|
204 | - * @see findBlock |
|
205 | - * @see getCurrentBlock |
|
206 | - * @see addBlock |
|
207 | - * @see addCustomBlock |
|
208 | - * @see injectBlock |
|
209 | - * @see removeBlock |
|
210 | - * @see removeTopBlock |
|
211 | - * @var array |
|
212 | - */ |
|
213 | - protected $stack = array(); |
|
214 | - |
|
215 | - /** |
|
216 | - * Current block at the top of the block plugins stack, |
|
217 | - * accessible through getCurrentBlock. |
|
218 | - * |
|
219 | - * @see getCurrentBlock |
|
220 | - * @var array |
|
221 | - */ |
|
222 | - protected $curBlock; |
|
223 | - |
|
224 | - /** |
|
225 | - * Current dwoo object that uses this compiler, or null. |
|
226 | - * |
|
227 | - * @var Core |
|
228 | - */ |
|
229 | - public $dwoo; |
|
230 | - |
|
231 | - /** |
|
232 | - * Holds an instance of this class, used by getInstance when you don't |
|
233 | - * provide a custom compiler in order to save resources. |
|
234 | - * |
|
235 | - * @var Compiler |
|
236 | - */ |
|
237 | - protected static $instance; |
|
238 | - |
|
239 | - /** |
|
240 | - * Token types. |
|
241 | - * |
|
242 | - * @var int |
|
243 | - */ |
|
244 | - const T_UNQUOTED_STRING = 1; |
|
245 | - const T_NUMERIC = 2; |
|
246 | - const T_NULL = 4; |
|
247 | - const T_BOOL = 8; |
|
248 | - const T_MATH = 16; |
|
249 | - const T_BREAKCHAR = 32; |
|
250 | - |
|
251 | - /** |
|
252 | - * Compiler constructor. |
|
253 | - * saves the created instance so that child templates get the same one |
|
254 | - */ |
|
255 | - public function __construct() |
|
256 | - { |
|
257 | - self::$instance = $this; |
|
258 | - } |
|
259 | - |
|
260 | - /** |
|
261 | - * Sets the delimiters to use in the templates. |
|
262 | - * delimiters can be multi-character strings but should not be one of those as they will |
|
263 | - * make it very hard to work with templates or might even break the compiler entirely : "\", "$", "|", ":" and |
|
264 | - * finally "#" only if you intend to use config-vars with the #var# syntax. |
|
265 | - * |
|
266 | - * @param string $left left delimiter |
|
267 | - * @param string $right right delimiter |
|
268 | - */ |
|
269 | - public function setDelimiters($left, $right) |
|
270 | - { |
|
271 | - $this->ld = $left; |
|
272 | - $this->rd = $right; |
|
273 | - $this->ldr = preg_quote($left, '/'); |
|
274 | - $this->rdr = preg_quote($right, '/'); |
|
275 | - } |
|
276 | - |
|
277 | - /** |
|
278 | - * Returns the left and right template delimiters. |
|
279 | - * |
|
280 | - * @return array containing the left and the right delimiters |
|
281 | - */ |
|
282 | - public function getDelimiters() |
|
283 | - { |
|
284 | - return array($this->ld, $this->rd); |
|
285 | - } |
|
286 | - |
|
287 | - /** |
|
288 | - * Sets the way to handle nested comments, if set to true |
|
289 | - * {* foo {* some other *} comment *} will be stripped correctly. |
|
290 | - * if false it will remove {* foo {* some other *} and leave "comment *}" alone, |
|
291 | - * this is the default behavior |
|
292 | - * |
|
293 | - * @param bool $allow allow nested comments or not, defaults to true (but the default internal value is false) |
|
294 | - */ |
|
295 | - public function setNestedCommentsHandling($allow = true) |
|
296 | - { |
|
297 | - $this->allowNestedComments = (bool)$allow; |
|
298 | - } |
|
299 | - |
|
300 | - /** |
|
301 | - * Returns the nested comments handling setting. |
|
302 | - * |
|
303 | - * @see setNestedCommentsHandling |
|
304 | - * @return bool true if nested comments are allowed |
|
305 | - */ |
|
306 | - public function getNestedCommentsHandling() |
|
307 | - { |
|
308 | - return $this->allowNestedComments; |
|
309 | - } |
|
310 | - |
|
311 | - /** |
|
312 | - * Sets the tag openings handling strictness, if set to true, template tags can |
|
313 | - * contain spaces before the first function/string/variable such as { $foo} is valid. |
|
314 | - * if set to false (default setting), { $foo} is invalid but that is however a good thing |
|
315 | - * as it allows css (i.e. #foo { color:red; }) to be parsed silently without triggering |
|
316 | - * an error, same goes for javascript. |
|
317 | - * |
|
318 | - * @param bool $allow true to allow loose handling, false to restore default setting |
|
319 | - */ |
|
320 | - public function setLooseOpeningHandling($allow = false) |
|
321 | - { |
|
322 | - $this->allowLooseOpenings = (bool)$allow; |
|
323 | - } |
|
324 | - |
|
325 | - /** |
|
326 | - * Returns the tag openings handling strictness setting. |
|
327 | - * |
|
328 | - * @see setLooseOpeningHandling |
|
329 | - * @return bool true if loose tags are allowed |
|
330 | - */ |
|
331 | - public function getLooseOpeningHandling() |
|
332 | - { |
|
333 | - return $this->allowLooseOpenings; |
|
334 | - } |
|
335 | - |
|
336 | - /** |
|
337 | - * Changes the auto escape setting. |
|
338 | - * if enabled, the compiler will automatically html-escape variables, |
|
339 | - * unless they are passed through the safe function such as {$var|safe} |
|
340 | - * or {safe $var} |
|
341 | - * default setting is disabled/false |
|
342 | - * |
|
343 | - * @param bool $enabled set to true to enable, false to disable |
|
344 | - */ |
|
345 | - public function setAutoEscape($enabled) |
|
346 | - { |
|
347 | - $this->autoEscape = (bool)$enabled; |
|
348 | - } |
|
349 | - |
|
350 | - /** |
|
351 | - * Returns the auto escape setting. |
|
352 | - * default setting is disabled/false |
|
353 | - * |
|
354 | - * @return bool |
|
355 | - */ |
|
356 | - public function getAutoEscape() |
|
357 | - { |
|
358 | - return $this->autoEscape; |
|
359 | - } |
|
360 | - |
|
361 | - /** |
|
362 | - * Adds a preprocessor to the compiler, it will be called |
|
363 | - * before the template is compiled. |
|
364 | - * |
|
365 | - * @param mixed $callback either a valid callback to the preprocessor or a simple name if the autoload is set to |
|
366 | - * true |
|
367 | - * @param bool $autoload if set to true, the preprocessor is auto-loaded from one of the plugin directories, else |
|
368 | - * you must provide a valid callback |
|
369 | - */ |
|
370 | - public function addPreProcessor($callback, $autoload = false) |
|
371 | - { |
|
372 | - if ($autoload) { |
|
373 | - $name = str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', Core::toCamelCase($callback)); |
|
374 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . $name; |
|
375 | - |
|
376 | - if (class_exists($class)) { |
|
377 | - $callback = array(new $class($this), 'process'); |
|
378 | - } elseif (function_exists($class)) { |
|
379 | - $callback = $class; |
|
380 | - } else { |
|
381 | - $callback = array('autoload' => true, 'class' => $class, 'name' => $name); |
|
382 | - } |
|
383 | - |
|
384 | - $this->processors['pre'][] = $callback; |
|
385 | - } else { |
|
386 | - $this->processors['pre'][] = $callback; |
|
387 | - } |
|
388 | - } |
|
389 | - |
|
390 | - /** |
|
391 | - * Removes a preprocessor from the compiler. |
|
392 | - * |
|
393 | - * @param mixed $callback either a valid callback to the preprocessor or a simple name if it was autoloaded |
|
394 | - */ |
|
395 | - public function removePreProcessor($callback) |
|
396 | - { |
|
397 | - if (($index = array_search($callback, $this->processors['pre'], true)) !== false) { |
|
398 | - unset($this->processors['pre'][$index]); |
|
399 | - } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
400 | - $callback), |
|
401 | - $this->processors['pre'], true)) !== false) { |
|
402 | - unset($this->processors['pre'][$index]); |
|
403 | - } else { |
|
404 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
405 | - foreach ($this->processors['pre'] as $index => $proc) { |
|
406 | - if (is_array($proc) && ($proc[0] instanceof $class) || (isset($proc['class']) && $proc['class'] == $class)) { |
|
407 | - unset($this->processors['pre'][$index]); |
|
408 | - break; |
|
409 | - } |
|
410 | - } |
|
411 | - } |
|
412 | - } |
|
413 | - |
|
414 | - /** |
|
415 | - * Adds a postprocessor to the compiler, it will be called |
|
416 | - * before the template is compiled. |
|
417 | - * |
|
418 | - * @param mixed $callback either a valid callback to the postprocessor or a simple name if the autoload is set to |
|
419 | - * true |
|
420 | - * @param bool $autoload if set to true, the postprocessor is auto-loaded from one of the plugin directories, else |
|
421 | - * you must provide a valid callback |
|
422 | - */ |
|
423 | - public function addPostProcessor($callback, $autoload = false) |
|
424 | - { |
|
425 | - if ($autoload) { |
|
426 | - $name = str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
427 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . Core::toCamelCase($name); |
|
428 | - |
|
429 | - if (class_exists($class)) { |
|
430 | - $callback = array(new $class($this), 'process'); |
|
431 | - } elseif (function_exists($class)) { |
|
432 | - $callback = $class; |
|
433 | - } else { |
|
434 | - $callback = array('autoload' => true, 'class' => $class, 'name' => $name); |
|
435 | - } |
|
436 | - |
|
437 | - $this->processors['post'][] = $callback; |
|
438 | - } else { |
|
439 | - $this->processors['post'][] = $callback; |
|
440 | - } |
|
441 | - } |
|
442 | - |
|
443 | - /** |
|
444 | - * Removes a postprocessor from the compiler. |
|
445 | - * |
|
446 | - * @param mixed $callback either a valid callback to the postprocessor or a simple name if it was autoloaded |
|
447 | - */ |
|
448 | - public function removePostProcessor($callback) |
|
449 | - { |
|
450 | - if (($index = array_search($callback, $this->processors['post'], true)) !== false) { |
|
451 | - unset($this->processors['post'][$index]); |
|
452 | - } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
453 | - $callback), |
|
454 | - $this->processors['post'], true)) !== false) { |
|
455 | - unset($this->processors['post'][$index]); |
|
456 | - } else { |
|
457 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
458 | - foreach ($this->processors['post'] as $index => $proc) { |
|
459 | - if (is_array($proc) && ($proc[0] instanceof $class) || (isset($proc['class']) && $proc['class'] == $class)) { |
|
460 | - unset($this->processors['post'][$index]); |
|
461 | - break; |
|
462 | - } |
|
463 | - } |
|
464 | - } |
|
465 | - } |
|
466 | - |
|
467 | - /** |
|
468 | - * Internal function to autoload processors at runtime if required. |
|
469 | - * |
|
470 | - * @param string $class the class/function name |
|
471 | - * @param string $name the plugin name (without Dwoo_Plugin_ prefix) |
|
472 | - * |
|
473 | - * @return array|string |
|
474 | - * @throws Exception |
|
475 | - */ |
|
476 | - protected function loadProcessor($class, $name) |
|
477 | - { |
|
478 | - if (!class_exists($class) && !function_exists($class)) { |
|
479 | - try { |
|
480 | - $this->getDwoo()->getLoader()->loadPlugin($name); |
|
481 | - } |
|
482 | - catch (Exception $e) { |
|
483 | - throw new Exception('Processor ' . $name . ' could not be found in your plugin directories, please ensure it is in a file named ' . $name . '.php in the plugin directory'); |
|
484 | - } |
|
485 | - } |
|
486 | - |
|
487 | - if (class_exists($class)) { |
|
488 | - return array(new $class($this), 'process'); |
|
489 | - } |
|
490 | - |
|
491 | - if (function_exists($class)) { |
|
492 | - return $class; |
|
493 | - } |
|
494 | - |
|
495 | - throw new Exception('Wrong processor name, when using autoload the processor must be in one of your plugin dir as "name.php" containg a class or function named "Dwoo_Processor_name"'); |
|
496 | - } |
|
497 | - |
|
498 | - /** |
|
499 | - * Adds an used plugin, this is reserved for use by the {template} plugin. |
|
500 | - * this is required so that plugin loading bubbles up from loaded |
|
501 | - * template files to the current one |
|
502 | - * |
|
503 | - * @private |
|
504 | - * |
|
505 | - * @param string $name function name |
|
506 | - * @param int $type plugin type (Core::*_PLUGIN) |
|
507 | - */ |
|
508 | - public function addUsedPlugin($name, $type) |
|
509 | - { |
|
510 | - $this->usedPlugins[$name] = $type; |
|
511 | - } |
|
512 | - |
|
513 | - /** |
|
514 | - * Returns all the plugins this template uses. |
|
515 | - * |
|
516 | - * @private |
|
517 | - * @return array the list of used plugins in the parsed template |
|
518 | - */ |
|
519 | - public function getUsedPlugins() |
|
520 | - { |
|
521 | - return $this->usedPlugins; |
|
522 | - } |
|
523 | - |
|
524 | - /** |
|
525 | - * Adds a template plugin, this is reserved for use by the {template} plugin. |
|
526 | - * this is required because the template functions are not declared yet |
|
527 | - * during compilation, so we must have a way of validating their argument |
|
528 | - * signature without using the reflection api |
|
529 | - * |
|
530 | - * @private |
|
531 | - * |
|
532 | - * @param string $name function name |
|
533 | - * @param array $params parameter array to help validate the function call |
|
534 | - * @param string $uuid unique id of the function |
|
535 | - * @param string $body function php code |
|
536 | - */ |
|
537 | - public function addTemplatePlugin($name, array $params, $uuid, $body = null) |
|
538 | - { |
|
539 | - $this->templatePlugins[$name] = array('params' => $params, 'body' => $body, 'uuid' => $uuid); |
|
540 | - } |
|
541 | - |
|
542 | - /** |
|
543 | - * Returns all the parsed sub-templates. |
|
544 | - * |
|
545 | - * @private |
|
546 | - * @return array the parsed sub-templates |
|
547 | - */ |
|
548 | - public function getTemplatePlugins() |
|
549 | - { |
|
550 | - return $this->templatePlugins; |
|
551 | - } |
|
552 | - |
|
553 | - /** |
|
554 | - * Marks a template plugin as being called, which means its source must be included in the compiled template. |
|
555 | - * |
|
556 | - * @param string $name function name |
|
557 | - */ |
|
558 | - public function useTemplatePlugin($name) |
|
559 | - { |
|
560 | - $this->templatePlugins[$name]['called'] = true; |
|
561 | - } |
|
562 | - |
|
563 | - /** |
|
564 | - * Adds the custom plugins loaded into Dwoo to the compiler so it can load them. |
|
565 | - * |
|
566 | - * @see Core::addPlugin |
|
567 | - * |
|
568 | - * @param array $customPlugins an array of custom plugins |
|
569 | - */ |
|
570 | - public function setCustomPlugins(array $customPlugins) |
|
571 | - { |
|
572 | - $this->customPlugins = $customPlugins; |
|
573 | - } |
|
574 | - |
|
575 | - /** |
|
576 | - * Sets the security policy object to enforce some php security settings. |
|
577 | - * use this if untrusted persons can modify templates, |
|
578 | - * set it on the Dwoo object as it will be passed onto the compiler automatically |
|
579 | - * |
|
580 | - * @param SecurityPolicy $policy the security policy object |
|
581 | - */ |
|
582 | - public function setSecurityPolicy(SecurityPolicy $policy = null) |
|
583 | - { |
|
584 | - $this->securityPolicy = $policy; |
|
585 | - } |
|
586 | - |
|
587 | - /** |
|
588 | - * Returns the current security policy object or null by default. |
|
589 | - * |
|
590 | - * @return SecurityPolicy|null the security policy object if any |
|
591 | - */ |
|
592 | - public function getSecurityPolicy() |
|
593 | - { |
|
594 | - return $this->securityPolicy; |
|
595 | - } |
|
596 | - |
|
597 | - /** |
|
598 | - * Sets the pointer position. |
|
599 | - * |
|
600 | - * @param int $position the new pointer position |
|
601 | - * @param bool $isOffset if set to true, the position acts as an offset and not an absolute position |
|
602 | - */ |
|
603 | - public function setPointer($position, $isOffset = false) |
|
604 | - { |
|
605 | - if ($isOffset) { |
|
606 | - $this->pointer += $position; |
|
607 | - } else { |
|
608 | - $this->pointer = $position; |
|
609 | - } |
|
610 | - } |
|
611 | - |
|
612 | - /** |
|
613 | - * Returns the current pointer position, only available during compilation of a template. |
|
614 | - * |
|
615 | - * @return int |
|
616 | - */ |
|
617 | - public function getPointer() |
|
618 | - { |
|
619 | - return $this->pointer; |
|
620 | - } |
|
621 | - |
|
622 | - /** |
|
623 | - * Sets the line number. |
|
624 | - * |
|
625 | - * @param int $number the new line number |
|
626 | - * @param bool $isOffset if set to true, the position acts as an offset and not an absolute position |
|
627 | - */ |
|
628 | - public function setLine($number, $isOffset = false) |
|
629 | - { |
|
630 | - if ($isOffset) { |
|
631 | - $this->line += $number; |
|
632 | - } else { |
|
633 | - $this->line = $number; |
|
634 | - } |
|
635 | - } |
|
636 | - |
|
637 | - /** |
|
638 | - * Returns the current line number, only available during compilation of a template. |
|
639 | - * |
|
640 | - * @return int |
|
641 | - */ |
|
642 | - public function getLine() |
|
643 | - { |
|
644 | - return $this->line; |
|
645 | - } |
|
646 | - |
|
647 | - /** |
|
648 | - * Returns the dwoo object that initiated this template compilation, only available during compilation of a |
|
649 | - * template. |
|
650 | - * |
|
651 | - * @return Core |
|
652 | - */ |
|
653 | - public function getDwoo() |
|
654 | - { |
|
655 | - return $this->dwoo; |
|
656 | - } |
|
657 | - |
|
658 | - /** |
|
659 | - * Overwrites the template that is being compiled. |
|
660 | - * |
|
661 | - * @param string $newSource the template source that must replace the current one |
|
662 | - * @param bool $fromPointer if set to true, only the source from the current pointer position is replaced |
|
663 | - * |
|
664 | - * @return void |
|
665 | - */ |
|
666 | - public function setTemplateSource($newSource, $fromPointer = false) |
|
667 | - { |
|
668 | - if ($fromPointer === true) { |
|
669 | - $this->templateSource = substr($this->templateSource, 0, $this->pointer) . $newSource; |
|
670 | - } else { |
|
671 | - $this->templateSource = $newSource; |
|
672 | - } |
|
673 | - } |
|
674 | - |
|
675 | - /** |
|
676 | - * Returns the template that is being compiled. |
|
677 | - * |
|
678 | - * @param mixed $fromPointer if set to true, only the source from the current pointer |
|
679 | - * position is returned, if a number is given it overrides the current pointer |
|
680 | - * |
|
681 | - * @return string the template or partial template |
|
682 | - */ |
|
683 | - public function getTemplateSource($fromPointer = false) |
|
684 | - { |
|
685 | - if ($fromPointer === true) { |
|
686 | - return substr($this->templateSource, $this->pointer); |
|
687 | - } elseif (is_numeric($fromPointer)) { |
|
688 | - return substr($this->templateSource, $fromPointer); |
|
689 | - } else { |
|
690 | - return $this->templateSource; |
|
691 | - } |
|
692 | - } |
|
693 | - |
|
694 | - /** |
|
695 | - * Resets the compilation pointer, effectively restarting the compilation process. |
|
696 | - * this is useful if a plugin modifies the template source since it might need to be recompiled |
|
697 | - */ |
|
698 | - public function recompile() |
|
699 | - { |
|
700 | - $this->setPointer(0); |
|
701 | - } |
|
702 | - |
|
703 | - /** |
|
704 | - * Compiles the provided string down to php code. |
|
705 | - * |
|
706 | - * @param Core $dwoo |
|
707 | - * @param ITemplate $template the template to compile |
|
708 | - * |
|
709 | - * @return string a compiled php string |
|
710 | - * @throws CompilationException |
|
711 | - */ |
|
712 | - public function compile(Core $dwoo, ITemplate $template) |
|
713 | - { |
|
714 | - // init vars |
|
715 | - // $compiled = ''; |
|
716 | - $tpl = $template->getSource(); |
|
717 | - $ptr = 0; |
|
718 | - $this->dwoo = $dwoo; |
|
719 | - $this->template = $template; |
|
720 | - $this->templateSource = &$tpl; |
|
721 | - $this->pointer = &$ptr; |
|
722 | - |
|
723 | - while (true) { |
|
724 | - // if pointer is at the beginning, reset everything, that allows a plugin to externally reset the compiler if everything must be reparsed |
|
725 | - if ($ptr === 0) { |
|
726 | - // resets variables |
|
727 | - $this->usedPlugins = array(); |
|
728 | - $this->data = array(); |
|
729 | - $this->scope = &$this->data; |
|
730 | - $this->scopeTree = array(); |
|
731 | - $this->stack = array(); |
|
732 | - $this->line = 1; |
|
733 | - $this->templatePlugins = array(); |
|
734 | - // add top level block |
|
735 | - $compiled = $this->addBlock('TopLevelBlock', array(), 0); |
|
736 | - $this->stack[0]['buffer'] = ''; |
|
737 | - |
|
738 | - if ($this->debug) { |
|
739 | - echo "\n"; |
|
740 | - echo 'COMPILER INIT' . "\n"; |
|
741 | - } |
|
742 | - |
|
743 | - if ($this->debug) { |
|
744 | - echo 'PROCESSING PREPROCESSORS (' . count($this->processors['pre']) . ')' . "\n"; |
|
745 | - } |
|
746 | - |
|
747 | - // runs preprocessors |
|
748 | - foreach ($this->processors['pre'] as $preProc) { |
|
749 | - if (is_array($preProc) && isset($preProc['autoload'])) { |
|
750 | - $preProc = $this->loadProcessor($preProc['class'], $preProc['name']); |
|
751 | - } |
|
752 | - if (is_array($preProc) && $preProc[0] instanceof Processor) { |
|
753 | - $tpl = call_user_func($preProc, $tpl); |
|
754 | - } else { |
|
755 | - $tpl = call_user_func($preProc, $this, $tpl); |
|
756 | - } |
|
757 | - } |
|
758 | - unset($preProc); |
|
759 | - |
|
760 | - // show template source if debug |
|
761 | - if ($this->debug) { |
|
762 | - echo '<pre>'.print_r(htmlentities($tpl), true).'</pre>'."\n"; |
|
763 | - } |
|
764 | - |
|
765 | - // strips php tags if required by the security policy |
|
766 | - if ($this->securityPolicy !== null) { |
|
767 | - $search = array('{<\?php.*?\?>}'); |
|
768 | - if (ini_get('short_open_tags')) { |
|
769 | - $search = array('{<\?.*?\?>}', '{<%.*?%>}'); |
|
770 | - } |
|
771 | - switch ($this->securityPolicy->getPhpHandling()) { |
|
772 | - case SecurityPolicy::PHP_ALLOW: |
|
773 | - break; |
|
774 | - case SecurityPolicy::PHP_ENCODE: |
|
775 | - $tpl = preg_replace_callback($search, array($this, 'phpTagEncodingHelper'), $tpl); |
|
776 | - break; |
|
777 | - case SecurityPolicy::PHP_REMOVE: |
|
778 | - $tpl = preg_replace($search, '', $tpl); |
|
779 | - } |
|
780 | - } |
|
781 | - } |
|
782 | - |
|
783 | - $pos = strpos($tpl, $this->ld, $ptr); |
|
784 | - |
|
785 | - if ($pos === false) { |
|
786 | - $this->push(substr($tpl, $ptr), 0); |
|
787 | - break; |
|
788 | - } elseif (substr($tpl, $pos - 1, 1) === '\\' && substr($tpl, $pos - 2, 1) !== '\\') { |
|
789 | - $this->push(substr($tpl, $ptr, $pos - $ptr - 1) . $this->ld); |
|
790 | - $ptr = $pos + strlen($this->ld); |
|
791 | - } elseif (preg_match('/^' . $this->ldr . ($this->allowLooseOpenings ? '\s*' : '') . 'literal' . ($this->allowLooseOpenings ? '\s*' : '') . $this->rdr . '/s', substr($tpl, $pos), $litOpen)) { |
|
792 | - if (!preg_match('/' . $this->ldr . ($this->allowLooseOpenings ? '\s*' : '') . '\/literal' . ($this->allowLooseOpenings ? '\s*' : '') . $this->rdr . '/s', $tpl, $litClose, PREG_OFFSET_CAPTURE, $pos)) { |
|
793 | - throw new CompilationException($this, 'The {literal} blocks must be closed explicitly with {/literal}'); |
|
794 | - } |
|
795 | - $endpos = $litClose[0][1]; |
|
796 | - $this->push(substr($tpl, $ptr, $pos - $ptr) . substr($tpl, $pos + strlen($litOpen[0]), $endpos - $pos - strlen($litOpen[0]))); |
|
797 | - $ptr = $endpos + strlen($litClose[0][0]); |
|
798 | - } else { |
|
799 | - if (substr($tpl, $pos - 2, 1) === '\\' && substr($tpl, $pos - 1, 1) === '\\') { |
|
800 | - $this->push(substr($tpl, $ptr, $pos - $ptr - 1)); |
|
801 | - $ptr = $pos; |
|
802 | - } |
|
803 | - |
|
804 | - $this->push(substr($tpl, $ptr, $pos - $ptr)); |
|
805 | - $ptr = $pos; |
|
806 | - |
|
807 | - $pos += strlen($this->ld); |
|
808 | - if ($this->allowLooseOpenings) { |
|
809 | - while (substr($tpl, $pos, 1) === ' ') { |
|
810 | - $pos += 1; |
|
811 | - } |
|
812 | - } else { |
|
813 | - if (substr($tpl, $pos, 1) === ' ' || substr($tpl, $pos, 1) === "\r" || substr($tpl, $pos, 1) === "\n" || substr($tpl, $pos, 1) === "\t") { |
|
814 | - $ptr = $pos; |
|
815 | - $this->push($this->ld); |
|
816 | - continue; |
|
817 | - } |
|
818 | - } |
|
819 | - |
|
820 | - // check that there is an end tag present |
|
821 | - if (strpos($tpl, $this->rd, $pos) === false) { |
|
822 | - throw new CompilationException($this, 'A template tag was not closed, started with "' . substr($tpl, $ptr, 30) . '"'); |
|
823 | - } |
|
824 | - |
|
825 | - $ptr += strlen($this->ld); |
|
826 | - $subptr = $ptr; |
|
827 | - |
|
828 | - while (true) { |
|
829 | - $parsed = $this->parse($tpl, $subptr, null, false, 'root', $subptr); |
|
830 | - |
|
831 | - // reload loop if the compiler was reset |
|
832 | - if ($ptr === 0) { |
|
833 | - continue 2; |
|
834 | - } |
|
835 | - |
|
836 | - $len = $subptr - $ptr; |
|
837 | - $this->push($parsed, substr_count(substr($tpl, $ptr, $len), "\n")); |
|
838 | - $ptr += $len; |
|
839 | - |
|
840 | - if ($parsed === false) { |
|
841 | - break; |
|
842 | - } |
|
843 | - } |
|
844 | - } |
|
845 | - } |
|
846 | - |
|
847 | - $compiled .= $this->removeBlock('TopLevelBlock'); |
|
848 | - |
|
849 | - if ($this->debug) { |
|
850 | - echo 'PROCESSING POSTPROCESSORS' . "\n"; |
|
851 | - } |
|
852 | - |
|
853 | - foreach ($this->processors['post'] as $postProc) { |
|
854 | - if (is_array($postProc) && isset($postProc['autoload'])) { |
|
855 | - $postProc = $this->loadProcessor($postProc['class'], $postProc['name']); |
|
856 | - } |
|
857 | - if (is_array($postProc) && $postProc[0] instanceof Processor) { |
|
858 | - $compiled = call_user_func($postProc, $compiled); |
|
859 | - } else { |
|
860 | - $compiled = call_user_func($postProc, $this, $compiled); |
|
861 | - } |
|
862 | - } |
|
863 | - unset($postProc); |
|
864 | - |
|
865 | - if ($this->debug) { |
|
866 | - echo 'COMPILATION COMPLETE : MEM USAGE : ' . memory_get_usage() . "\n"; |
|
867 | - } |
|
868 | - |
|
869 | - $output = "<?php\n/* template head */\n"; |
|
870 | - |
|
871 | - // build plugin preloader |
|
872 | - foreach ($this->getUsedPlugins() as $plugin => $type) { |
|
873 | - if ($type & Core::CUSTOM_PLUGIN) { |
|
874 | - continue; |
|
875 | - } |
|
876 | - |
|
877 | - switch ($type) { |
|
878 | - case Core::BLOCK_PLUGIN: |
|
879 | - case Core::CLASS_PLUGIN: |
|
880 | - if (class_exists('Plugin' . $plugin) !== false) { |
|
881 | - $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)". |
|
882 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
883 | - } else { |
|
884 | - $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_BLOCKS . "Plugin" . $plugin . "')===false)". |
|
885 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
886 | - } |
|
887 | - break; |
|
888 | - case Core::FUNC_PLUGIN: |
|
889 | - if (function_exists('Plugin' . $plugin) !== false) { |
|
890 | - $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)". |
|
891 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
892 | - } else { |
|
893 | - $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)". |
|
894 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
895 | - } |
|
896 | - break; |
|
897 | - case Core::SMARTY_MODIFIER: |
|
898 | - $output .= "if (function_exists('smarty_modifier_$plugin')===false)". |
|
899 | - "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
900 | - break; |
|
901 | - case Core::SMARTY_FUNCTION: |
|
902 | - $output .= "if (function_exists('smarty_function_$plugin')===false)". |
|
903 | - "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
904 | - break; |
|
905 | - case Core::SMARTY_BLOCK: |
|
906 | - $output .= "if (function_exists('smarty_block_$plugin')===false)". |
|
907 | - "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
908 | - break; |
|
909 | - case Core::PROXY_PLUGIN: |
|
910 | - $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin); |
|
911 | - break; |
|
912 | - default: |
|
913 | - throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type); |
|
914 | - } |
|
915 | - } |
|
916 | - |
|
917 | - foreach ($this->templatePlugins as $function => $attr) { |
|
918 | - if (isset($attr['called']) && $attr['called'] === true && !isset($attr['checked'])) { |
|
919 | - $this->resolveSubTemplateDependencies($function); |
|
920 | - } |
|
921 | - } |
|
922 | - foreach ($this->templatePlugins as $function) { |
|
923 | - if (isset($function['called']) && $function['called'] === true) { |
|
924 | - $output .= $function['body'] . PHP_EOL; |
|
925 | - } |
|
926 | - } |
|
927 | - |
|
928 | - $output .= $compiled . "\n?>"; |
|
929 | - |
|
930 | - $output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*' . preg_quote(self::PHP_CLOSE, '/') . preg_quote(self::PHP_OPEN, '/') . ')/', ";\n", $output); |
|
931 | - $output = str_replace(self::PHP_CLOSE . self::PHP_OPEN, "\n", $output); |
|
932 | - |
|
933 | - // handle <?xml tag at the beginning |
|
934 | - $output = preg_replace('#(/\* template body \*/ \?>\s*)<\?xml#is', '$1<?php echo \'<?xml\'; ?>', $output); |
|
935 | - |
|
936 | - // add another line break after PHP closing tags that have a line break following, |
|
937 | - // as we do not know whether it's intended, and PHP will strip it otherwise |
|
938 | - $output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0' . "\n", $output); |
|
939 | - |
|
940 | - if ($this->debug) { |
|
941 | - echo '=============================================================================================' . "\n"; |
|
942 | - $lines = preg_split('{\r\n|\n|<br />}', $output); |
|
943 | - array_shift($lines); |
|
944 | - foreach ($lines as $i => $line) { |
|
945 | - echo ($i + 1) . '. ' . $line . "\r\n"; |
|
946 | - } |
|
947 | - echo '=============================================================================================' . "\n"; |
|
948 | - } |
|
949 | - |
|
950 | - $this->template = $this->dwoo = null; |
|
951 | - $tpl = null; |
|
952 | - |
|
953 | - return $output; |
|
954 | - } |
|
955 | - |
|
956 | - /** |
|
957 | - * Checks what sub-templates are used in every sub-template so that we're sure they are all compiled. |
|
958 | - * |
|
959 | - * @param string $function the sub-template name |
|
960 | - */ |
|
961 | - protected function resolveSubTemplateDependencies($function) |
|
962 | - { |
|
963 | - if ($this->debug) { |
|
964 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
965 | - } |
|
966 | - |
|
967 | - $body = $this->templatePlugins[$function]['body']; |
|
968 | - foreach ($this->templatePlugins as $func => $attr) { |
|
969 | - if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS . |
|
970 | - 'Plugin' . Core::toCamelCase($func)) !== false) { |
|
971 | - $this->templatePlugins[$func]['called'] = true; |
|
972 | - $this->resolveSubTemplateDependencies($func); |
|
973 | - } |
|
974 | - } |
|
975 | - $this->templatePlugins[$function]['checked'] = true; |
|
976 | - } |
|
977 | - |
|
978 | - /** |
|
979 | - * Adds compiled content to the current block. |
|
980 | - * |
|
981 | - * @param string $content the content to push |
|
982 | - * @param int $lineCount newlines count in content, optional |
|
983 | - * |
|
984 | - * @throws CompilationException |
|
985 | - */ |
|
986 | - public function push($content, $lineCount = null) |
|
987 | - { |
|
988 | - if ($lineCount === null) { |
|
989 | - $lineCount = substr_count($content, "\n"); |
|
990 | - } |
|
991 | - |
|
992 | - if ($this->curBlock['buffer'] === null && count($this->stack) > 1) { |
|
993 | - // buffer is not initialized yet (the block has just been created) |
|
994 | - $this->stack[count($this->stack) - 2]['buffer'] .= (string)$content; |
|
995 | - $this->curBlock['buffer'] = ''; |
|
996 | - } else { |
|
997 | - if (!isset($this->curBlock['buffer'])) { |
|
998 | - throw new CompilationException($this, 'The template has been closed too early, you probably have an extra block-closing tag somewhere'); |
|
999 | - } |
|
1000 | - // append current content to current block's buffer |
|
1001 | - $this->curBlock['buffer'] .= (string)$content; |
|
1002 | - } |
|
1003 | - $this->line += $lineCount; |
|
1004 | - } |
|
1005 | - |
|
1006 | - /** |
|
1007 | - * Sets the scope. |
|
1008 | - * set to null if the scope becomes "unstable" (i.e. too variable or unknown) so that |
|
1009 | - * variables are compiled in a more evaluative way than just $this->scope['key'] |
|
1010 | - * |
|
1011 | - * @param mixed $scope a string i.e. "level1.level2" or an array i.e. array("level1", "level2") |
|
1012 | - * @param bool $absolute if true, the scope is set from the top level scope and not from the current scope |
|
1013 | - * |
|
1014 | - * @return array the current scope tree |
|
1015 | - */ |
|
1016 | - public function setScope($scope, $absolute = false) |
|
1017 | - { |
|
1018 | - $old = $this->scopeTree; |
|
1019 | - |
|
1020 | - if ($scope === null) { |
|
1021 | - unset($this->scope); |
|
1022 | - $this->scope = null; |
|
1023 | - } |
|
1024 | - |
|
1025 | - if (is_array($scope) === false) { |
|
1026 | - $scope = explode('.', $scope); |
|
1027 | - } |
|
1028 | - |
|
1029 | - if ($absolute === true) { |
|
1030 | - $this->scope = &$this->data; |
|
1031 | - $this->scopeTree = array(); |
|
1032 | - } |
|
1033 | - |
|
1034 | - while (($bit = array_shift($scope)) !== null) { |
|
1035 | - if ($bit === '_parent' || $bit === '_') { |
|
1036 | - array_pop($this->scopeTree); |
|
1037 | - reset($this->scopeTree); |
|
1038 | - $this->scope = &$this->data; |
|
1039 | - $cnt = count($this->scopeTree); |
|
1040 | - for ($i = 0; $i < $cnt; ++ $i) { |
|
1041 | - $this->scope = &$this->scope[$this->scopeTree[$i]]; |
|
1042 | - } |
|
1043 | - } elseif ($bit === '_root' || $bit === '__') { |
|
1044 | - $this->scope = &$this->data; |
|
1045 | - $this->scopeTree = array(); |
|
1046 | - } elseif (isset($this->scope[$bit])) { |
|
1047 | - $this->scope = &$this->scope[$bit]; |
|
1048 | - $this->scopeTree[] = $bit; |
|
1049 | - } else { |
|
1050 | - $this->scope[$bit] = array(); |
|
1051 | - $this->scope = &$this->scope[$bit]; |
|
1052 | - $this->scopeTree[] = $bit; |
|
1053 | - } |
|
1054 | - } |
|
1055 | - |
|
1056 | - return $old; |
|
1057 | - } |
|
1058 | - |
|
1059 | - /** |
|
1060 | - * Adds a block to the top of the block stack. |
|
1061 | - * |
|
1062 | - * @param string $type block type (name) |
|
1063 | - * @param array $params the parameters array |
|
1064 | - * @param int $paramtype the parameters type (see mapParams), 0, 1 or 2 |
|
1065 | - * |
|
1066 | - * @return string the preProcessing() method's output |
|
1067 | - */ |
|
1068 | - public function addBlock($type, array $params, $paramtype) |
|
1069 | - { |
|
1070 | - if ($this->debug) { |
|
1071 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1072 | - } |
|
1073 | - |
|
1074 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type); |
|
1075 | - if (class_exists($class) === false) { |
|
1076 | - $this->getDwoo()->getLoader()->loadPlugin($type); |
|
1077 | - } |
|
1078 | - $params = $this->mapParams($params, array($class, 'init'), $paramtype); |
|
1079 | - |
|
1080 | - $this->stack[] = array( |
|
1081 | - 'type' => $type, |
|
1082 | - 'params' => $params, |
|
1083 | - 'custom' => false, |
|
1084 | - 'class' => $class, |
|
1085 | - 'buffer' => null |
|
1086 | - ); |
|
1087 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1088 | - |
|
1089 | - return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type); |
|
1090 | - } |
|
1091 | - |
|
1092 | - /** |
|
1093 | - * Adds a custom block to the top of the block stack. |
|
1094 | - * |
|
1095 | - * @param string $type block type (name) |
|
1096 | - * @param array $params the parameters array |
|
1097 | - * @param int $paramtype the parameters type (see mapParams), 0, 1 or 2 |
|
1098 | - * |
|
1099 | - * @return string the preProcessing() method's output |
|
1100 | - */ |
|
1101 | - public function addCustomBlock($type, array $params, $paramtype) |
|
1102 | - { |
|
1103 | - $callback = $this->customPlugins[$type]['callback']; |
|
1104 | - if (is_array($callback)) { |
|
1105 | - $class = is_object($callback[0]) ? get_class($callback[0]) : $callback[0]; |
|
1106 | - } else { |
|
1107 | - $class = $callback; |
|
1108 | - } |
|
1109 | - |
|
1110 | - $params = $this->mapParams($params, array($class, 'init'), $paramtype); |
|
1111 | - |
|
1112 | - $this->stack[] = array( |
|
1113 | - 'type' => $type, |
|
1114 | - 'params' => $params, |
|
1115 | - 'custom' => true, |
|
1116 | - 'class' => $class, |
|
1117 | - 'buffer' => null |
|
1118 | - ); |
|
1119 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1120 | - |
|
1121 | - return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type); |
|
1122 | - } |
|
1123 | - |
|
1124 | - /** |
|
1125 | - * Injects a block at the top of the plugin stack without calling its preProcessing method. |
|
1126 | - * used by {else} blocks to re-add themselves after having closed everything up to their parent |
|
1127 | - * |
|
1128 | - * @param string $type block type (name) |
|
1129 | - * @param array $params parameters array |
|
1130 | - */ |
|
1131 | - public function injectBlock($type, array $params) |
|
1132 | - { |
|
1133 | - if ($this->debug) { |
|
1134 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1135 | - } |
|
1136 | - |
|
1137 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type); |
|
1138 | - if (class_exists($class) === false) { |
|
1139 | - $this->getDwoo()->getLoader()->loadPlugin($type); |
|
1140 | - } |
|
1141 | - $this->stack[] = array( |
|
1142 | - 'type' => $type, |
|
1143 | - 'params' => $params, |
|
1144 | - 'custom' => false, |
|
1145 | - 'class' => $class, |
|
1146 | - 'buffer' => null |
|
1147 | - ); |
|
1148 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1149 | - } |
|
1150 | - |
|
1151 | - /** |
|
1152 | - * Removes the closest-to-top block of the given type and all other |
|
1153 | - * blocks encountered while going down the block stack. |
|
1154 | - * |
|
1155 | - * @param string $type block type (name) |
|
1156 | - * |
|
1157 | - * @return string the output of all postProcessing() method's return values of the closed blocks |
|
1158 | - * @throws CompilationException |
|
1159 | - */ |
|
1160 | - public function removeBlock($type) |
|
1161 | - { |
|
1162 | - if ($this->debug) { |
|
1163 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1164 | - } |
|
1165 | - |
|
1166 | - $output = ''; |
|
1167 | - |
|
1168 | - $pluginType = $this->getPluginType($type); |
|
1169 | - if ($pluginType & Core::SMARTY_BLOCK) { |
|
1170 | - $type = 'Smartyinterface'; |
|
1171 | - } |
|
1172 | - while (true) { |
|
1173 | - while ($top = array_pop($this->stack)) { |
|
1174 | - if ($top['custom']) { |
|
1175 | - $class = $top['class']; |
|
1176 | - } else { |
|
1177 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($top['type']); |
|
1178 | - } |
|
1179 | - if (count($this->stack)) { |
|
1180 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1181 | - $this->push(call_user_func(array( |
|
1182 | - $class, |
|
1183 | - 'postProcessing' |
|
1184 | - ), $this, $top['params'], '', '', $top['buffer']), 0); |
|
1185 | - } else { |
|
1186 | - $null = null; |
|
1187 | - $this->curBlock = &$null; |
|
1188 | - $output = call_user_func( |
|
1189 | - array( |
|
1190 | - $class, |
|
1191 | - 'postProcessing' |
|
1192 | - ), $this, $top['params'], '', '', $top['buffer'] |
|
1193 | - ); |
|
1194 | - } |
|
1195 | - |
|
1196 | - if ($top['type'] === $type) { |
|
1197 | - break 2; |
|
1198 | - } |
|
1199 | - } |
|
1200 | - |
|
1201 | - throw new CompilationException($this, 'Syntax malformation, a block of type "' . $type . '" was closed but was not opened'); |
|
1202 | - break; |
|
1203 | - } |
|
1204 | - |
|
1205 | - return $output; |
|
1206 | - } |
|
1207 | - |
|
1208 | - /** |
|
1209 | - * Returns a reference to the first block of the given type encountered and |
|
1210 | - * optionally closes all blocks until it finds it |
|
1211 | - * this is mainly used by {else} plugins to close everything that was opened |
|
1212 | - * between their parent and themselves. |
|
1213 | - * |
|
1214 | - * @param string $type the block type (name) |
|
1215 | - * @param bool $closeAlong whether to close all blocks encountered while going down the block stack or not |
|
1216 | - * |
|
1217 | - * @return mixed &array the array is as such: array('type'=>pluginName, 'params'=>parameter array, |
|
1218 | - * 'custom'=>bool defining whether it's a custom plugin or not, for internal use) |
|
1219 | - * @throws CompilationException |
|
1220 | - */ |
|
1221 | - public function &findBlock($type, $closeAlong = false) |
|
1222 | - { |
|
1223 | - if ($closeAlong === true) { |
|
1224 | - while ($b = end($this->stack)) { |
|
1225 | - if ($b['type'] === $type) { |
|
1226 | - return $this->stack[key($this->stack)]; |
|
1227 | - } |
|
1228 | - $this->push($this->removeTopBlock(), 0); |
|
1229 | - } |
|
1230 | - } else { |
|
1231 | - end($this->stack); |
|
1232 | - while ($b = current($this->stack)) { |
|
1233 | - if ($b['type'] === $type) { |
|
1234 | - return $this->stack[key($this->stack)]; |
|
1235 | - } |
|
1236 | - prev($this->stack); |
|
1237 | - } |
|
1238 | - } |
|
1239 | - |
|
1240 | - throw new CompilationException($this, 'A parent block of type "' . $type . '" is required and can not be found'); |
|
1241 | - } |
|
1242 | - |
|
1243 | - /** |
|
1244 | - * Returns a reference to the current block array. |
|
1245 | - * |
|
1246 | - * @return array the array is as such: array('type'=>pluginName, 'params'=>parameter array, |
|
1247 | - * 'custom'=>bool defining whether it's a custom plugin or not, for internal use) |
|
1248 | - */ |
|
1249 | - public function &getCurrentBlock() |
|
1250 | - { |
|
1251 | - return $this->curBlock; |
|
1252 | - } |
|
1253 | - |
|
1254 | - /** |
|
1255 | - * Removes the block at the top of the stack and calls its postProcessing() method. |
|
1256 | - * |
|
1257 | - * @return string the postProcessing() method's output |
|
1258 | - * @throws CompilationException |
|
1259 | - */ |
|
1260 | - public function removeTopBlock() |
|
1261 | - { |
|
1262 | - if ($this->debug) { |
|
1263 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1264 | - } |
|
1265 | - |
|
1266 | - $o = array_pop($this->stack); |
|
1267 | - if ($o === null) { |
|
1268 | - throw new CompilationException($this, 'Syntax malformation, a block of unknown type was closed but was not opened.'); |
|
1269 | - } |
|
1270 | - if ($o['custom']) { |
|
1271 | - $class = $o['class']; |
|
1272 | - } else { |
|
1273 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($o['type']); |
|
1274 | - } |
|
1275 | - |
|
1276 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1277 | - |
|
1278 | - return call_user_func(array($class, 'postProcessing'), $this, $o['params'], '', '', $o['buffer']); |
|
1279 | - } |
|
1280 | - |
|
1281 | - /** |
|
1282 | - * Returns the compiled parameters (for example a variable's compiled parameter will be "$this->scope['key']") out |
|
1283 | - * of the given parameter array. |
|
1284 | - * |
|
1285 | - * @param array $params parameter array |
|
1286 | - * |
|
1287 | - * @return array filtered parameters |
|
1288 | - */ |
|
1289 | - public function getCompiledParams(array $params) |
|
1290 | - { |
|
1291 | - foreach ($params as $k => $p) { |
|
1292 | - if (is_array($p)) { |
|
1293 | - $params[$k] = $p[0]; |
|
1294 | - } |
|
1295 | - } |
|
1296 | - |
|
1297 | - return $params; |
|
1298 | - } |
|
1299 | - |
|
1300 | - /** |
|
1301 | - * Returns the real parameters (for example a variable's real parameter will be its key, etc) out of the given |
|
1302 | - * parameter array. |
|
1303 | - * |
|
1304 | - * @param array $params parameter array |
|
1305 | - * |
|
1306 | - * @return array filtered parameters |
|
1307 | - */ |
|
1308 | - public function getRealParams(array $params) |
|
1309 | - { |
|
1310 | - foreach ($params as $k => $p) { |
|
1311 | - if (is_array($p)) { |
|
1312 | - $params[$k] = $p[1]; |
|
1313 | - } |
|
1314 | - } |
|
1315 | - |
|
1316 | - return $params; |
|
1317 | - } |
|
1318 | - |
|
1319 | - /** |
|
1320 | - * Returns the token of each parameter out of the given parameter array. |
|
1321 | - * |
|
1322 | - * @param array $params parameter array |
|
1323 | - * |
|
1324 | - * @return array tokens |
|
1325 | - */ |
|
1326 | - public function getParamTokens(array $params) |
|
1327 | - { |
|
1328 | - foreach ($params as $k => $p) { |
|
1329 | - if (is_array($p)) { |
|
1330 | - $params[$k] = isset($p[2]) ? $p[2] : 0; |
|
1331 | - } |
|
1332 | - } |
|
1333 | - |
|
1334 | - return $params; |
|
1335 | - } |
|
1336 | - |
|
1337 | - /** |
|
1338 | - * Entry point of the parser, it redirects calls to other parse* functions. |
|
1339 | - * |
|
1340 | - * @param string $in the string within which we must parse something |
|
1341 | - * @param int $from the starting offset of the parsed area |
|
1342 | - * @param int $to the ending offset of the parsed area |
|
1343 | - * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
1344 | - * default |
|
1345 | - * @param string $curBlock the current parser-block being processed |
|
1346 | - * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
1347 | - * or null by default |
|
1348 | - * |
|
1349 | - * @return string parsed values |
|
1350 | - * @throws CompilationException |
|
1351 | - */ |
|
1352 | - protected function parse($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
1353 | - { |
|
1354 | - if ($this->debug) { |
|
1355 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1356 | - } |
|
1357 | - |
|
1358 | - if ($to === null) { |
|
1359 | - $to = strlen($in); |
|
1360 | - } |
|
1361 | - $first = substr($in, $from, 1); |
|
1362 | - |
|
1363 | - if ($first === false) { |
|
1364 | - throw new CompilationException($this, 'Unexpected EOF, a template tag was not closed'); |
|
1365 | - } |
|
1366 | - |
|
1367 | - while ($first === ' ' || $first === "\n" || $first === "\t" || $first === "\r") { |
|
1368 | - if ($curBlock === 'root' && substr($in, $from, strlen($this->rd)) === $this->rd) { |
|
1369 | - // end template tag |
|
1370 | - $pointer += strlen($this->rd); |
|
1371 | - if ($this->debug) { |
|
1372 | - echo 'TEMPLATE PARSING ENDED' . "\n"; |
|
1373 | - } |
|
1374 | - |
|
1375 | - return false; |
|
1376 | - } |
|
1377 | - ++ $from; |
|
1378 | - if ($pointer !== null) { |
|
1379 | - ++ $pointer; |
|
1380 | - } |
|
1381 | - if ($from >= $to) { |
|
1382 | - if (is_array($parsingParams)) { |
|
1383 | - return $parsingParams; |
|
1384 | - } else { |
|
1385 | - return ''; |
|
1386 | - } |
|
1387 | - } |
|
1388 | - $first = $in[$from]; |
|
1389 | - } |
|
1390 | - |
|
1391 | - $substr = substr($in, $from, $to - $from); |
|
1392 | - |
|
1393 | - if ($this->debug) { |
|
1394 | - echo 'PARSE CALL : PARSING "<b>' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . '</b>" @ ' . $from . ':' . $to . ' in ' . $curBlock . ' : pointer=' . $pointer . "\n"; |
|
1395 | - } |
|
1396 | - $parsed = ''; |
|
1397 | - |
|
1398 | - if ($curBlock === 'root' && $first === '*') { |
|
1399 | - $src = $this->getTemplateSource(); |
|
1400 | - $startpos = $this->getPointer() - strlen($this->ld); |
|
1401 | - if (substr($src, $startpos, strlen($this->ld)) === $this->ld) { |
|
1402 | - if ($startpos > 0) { |
|
1403 | - do { |
|
1404 | - $char = substr($src, -- $startpos, 1); |
|
1405 | - if ($char == "\n") { |
|
1406 | - ++ $startpos; |
|
1407 | - $whitespaceStart = true; |
|
1408 | - break; |
|
1409 | - } |
|
1410 | - } |
|
1411 | - while ($startpos > 0 && ($char == ' ' || $char == "\t")); |
|
1412 | - } |
|
1413 | - |
|
1414 | - if (!isset($whitespaceStart)) { |
|
1415 | - $startpos = $this->getPointer(); |
|
1416 | - } else { |
|
1417 | - $pointer -= $this->getPointer() - $startpos; |
|
1418 | - } |
|
1419 | - |
|
1420 | - if ($this->allowNestedComments && strpos($src, $this->ld . '*', $this->getPointer()) !== false) { |
|
1421 | - $comOpen = $this->ld . '*'; |
|
1422 | - $comClose = '*' . $this->rd; |
|
1423 | - $level = 1; |
|
1424 | - $ptr = $this->getPointer(); |
|
1425 | - |
|
1426 | - while ($level > 0 && $ptr < strlen($src)) { |
|
1427 | - $open = strpos($src, $comOpen, $ptr); |
|
1428 | - $close = strpos($src, $comClose, $ptr); |
|
1429 | - |
|
1430 | - if ($open !== false && $close !== false) { |
|
1431 | - if ($open < $close) { |
|
1432 | - $ptr = $open + strlen($comOpen); |
|
1433 | - ++ $level; |
|
1434 | - } else { |
|
1435 | - $ptr = $close + strlen($comClose); |
|
1436 | - -- $level; |
|
1437 | - } |
|
1438 | - } elseif ($open !== false) { |
|
1439 | - $ptr = $open + strlen($comOpen); |
|
1440 | - ++ $level; |
|
1441 | - } elseif ($close !== false) { |
|
1442 | - $ptr = $close + strlen($comClose); |
|
1443 | - -- $level; |
|
1444 | - } else { |
|
1445 | - $ptr = strlen($src); |
|
1446 | - } |
|
1447 | - } |
|
1448 | - $endpos = $ptr - strlen('*' . $this->rd); |
|
1449 | - } else { |
|
1450 | - $endpos = strpos($src, '*' . $this->rd, $startpos); |
|
1451 | - if ($endpos == false) { |
|
1452 | - throw new CompilationException($this, 'Un-ended comment'); |
|
1453 | - } |
|
1454 | - } |
|
1455 | - $pointer += $endpos - $startpos + strlen('*' . $this->rd); |
|
1456 | - if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos + strlen('*' . $this->rd)), $m)) { |
|
1457 | - $pointer += strlen($m[0]); |
|
1458 | - $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer']) - ($this->getPointer() - $startpos - strlen($this->ld))); |
|
1459 | - } |
|
1460 | - |
|
1461 | - return false; |
|
1462 | - } |
|
1463 | - } |
|
1464 | - |
|
1465 | - if ($first === '$') { |
|
1466 | - // var |
|
1467 | - $out = $this->parseVar($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1468 | - $parsed = 'var'; |
|
1469 | - } elseif ($first === '%' && preg_match('#^%[a-z_\\\\]#i', $substr)) { |
|
1470 | - // Short constant |
|
1471 | - $out = $this->parseConst($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1472 | - } elseif (($first === '"' || $first === "'") && !(is_array($parsingParams) && preg_match('#^([\'"])[a-z0-9_]+\1\s*=>?(?:\s+|[^=])#i', $substr))) { |
|
1473 | - // string |
|
1474 | - $out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1475 | - } elseif (preg_match('/^\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?(' . (is_array($parsingParams) || $curBlock != 'root' ? '' : '\s+[^(]|') . '\s*\(|\s*' . $this->rdr . '|\s*;)/i', $substr)) { |
|
1476 | - // func |
|
1477 | - $out = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1478 | - $parsed = 'func'; |
|
1479 | - } elseif ($first === ';') { |
|
1480 | - // instruction end |
|
1481 | - if ($this->debug) { |
|
1482 | - echo 'END OF INSTRUCTION' . "\n"; |
|
1483 | - } |
|
1484 | - if ($pointer !== null) { |
|
1485 | - ++ $pointer; |
|
1486 | - } |
|
1487 | - |
|
1488 | - return $this->parse($in, $from + 1, $to, false, 'root', $pointer); |
|
1489 | - } elseif ($curBlock === 'root' && preg_match('#^/([a-z_][a-z0-9_]*)?#i', $substr, $match)) { |
|
1490 | - // close block |
|
1491 | - if (!empty($match[1]) && $match[1] == 'else') { |
|
1492 | - throw new CompilationException($this, 'Else blocks must not be closed explicitly, they are automatically closed when their parent block is closed'); |
|
1493 | - } |
|
1494 | - if (!empty($match[1]) && $match[1] == 'elseif') { |
|
1495 | - throw new CompilationException($this, 'Elseif blocks must not be closed explicitly, they are automatically closed when their parent block is closed or a new else/elseif block is declared after them'); |
|
1496 | - } |
|
1497 | - if ($pointer !== null) { |
|
1498 | - $pointer += strlen($match[0]); |
|
1499 | - } |
|
1500 | - if (empty($match[1])) { |
|
1501 | - if ($this->curBlock['type'] == 'else' || $this->curBlock['type'] == 'elseif') { |
|
1502 | - $pointer -= strlen($match[0]); |
|
1503 | - } |
|
1504 | - if ($this->debug) { |
|
1505 | - echo 'TOP BLOCK CLOSED' . "\n"; |
|
1506 | - } |
|
1507 | - |
|
1508 | - return $this->removeTopBlock(); |
|
1509 | - } else { |
|
1510 | - if ($this->debug) { |
|
1511 | - echo 'BLOCK OF TYPE ' . $match[1] . ' CLOSED' . "\n"; |
|
1512 | - } |
|
1513 | - |
|
1514 | - return $this->removeBlock($match[1]); |
|
1515 | - } |
|
1516 | - } elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) { |
|
1517 | - // end template tag |
|
1518 | - if ($this->debug) { |
|
1519 | - echo 'TAG PARSING ENDED' . "\n"; |
|
1520 | - } |
|
1521 | - $pointer += strlen($this->rd); |
|
1522 | - |
|
1523 | - return false; |
|
1524 | - } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*=' . ($curBlock === 'array' ? '>?' : '') . ')(?:\s+|[^=]).*#i', $substr, $match)) { |
|
1525 | - // named parameter |
|
1526 | - if ($this->debug) { |
|
1527 | - echo 'NAMED PARAM FOUND' . "\n"; |
|
1528 | - } |
|
1529 | - $len = strlen($match[1]); |
|
1530 | - while (substr($in, $from + $len, 1) === ' ') { |
|
1531 | - ++ $len; |
|
1532 | - } |
|
1533 | - if ($pointer !== null) { |
|
1534 | - $pointer += $len; |
|
1535 | - } |
|
1536 | - |
|
1537 | - $output = array( |
|
1538 | - trim($match[1], " \t\r\n=>'\""), |
|
1539 | - $this->parse($in, $from + $len, $to, false, 'namedparam', $pointer) |
|
1540 | - ); |
|
1541 | - |
|
1542 | - $parsingParams[] = $output; |
|
1543 | - |
|
1544 | - return $parsingParams; |
|
1545 | - } elseif (preg_match('#^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*::\$[a-z0-9_]+)#i', $substr, $match)) { |
|
1546 | - // static member access |
|
1547 | - $parsed = 'var'; |
|
1548 | - if (is_array($parsingParams)) { |
|
1549 | - $parsingParams[] = array($match[1], $match[1]); |
|
1550 | - $out = $parsingParams; |
|
1551 | - } else { |
|
1552 | - $out = $match[1]; |
|
1553 | - } |
|
1554 | - $pointer += strlen($match[1]); |
|
1555 | - } elseif ($substr !== '' && (is_array($parsingParams) || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'expression')) { |
|
1556 | - // unquoted string, bool or number |
|
1557 | - $out = $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1558 | - } else { |
|
1559 | - // parse error |
|
1560 | - throw new CompilationException($this, 'Parse error in "' . substr($in, $from, $to - $from) . '"'); |
|
1561 | - } |
|
1562 | - |
|
1563 | - if (empty($out)) { |
|
1564 | - return ''; |
|
1565 | - } |
|
1566 | - |
|
1567 | - $substr = substr($in, $pointer, $to - $pointer); |
|
1568 | - |
|
1569 | - // var parsed, check if any var-extension applies |
|
1570 | - if ($parsed === 'var') { |
|
1571 | - if (preg_match('#^\s*([/%+*-])\s*([a-z0-9]|\$)#i', $substr, $match)) { |
|
1572 | - if ($this->debug) { |
|
1573 | - echo 'PARSING POST-VAR EXPRESSION ' . $substr . "\n"; |
|
1574 | - } |
|
1575 | - // parse expressions |
|
1576 | - $pointer += strlen($match[0]) - 1; |
|
1577 | - if (is_array($parsingParams)) { |
|
1578 | - if ($match[2] == '$') { |
|
1579 | - $expr = $this->parseVar($in, $pointer, $to, array(), $curBlock, $pointer); |
|
1580 | - } else { |
|
1581 | - $expr = $this->parse($in, $pointer, $to, array(), 'expression', $pointer); |
|
1582 | - } |
|
1583 | - $out[count($out) - 1][0] .= $match[1] . $expr[0][0]; |
|
1584 | - $out[count($out) - 1][1] .= $match[1] . $expr[0][1]; |
|
1585 | - } else { |
|
1586 | - if ($match[2] == '$') { |
|
1587 | - $expr = $this->parseVar($in, $pointer, $to, false, $curBlock, $pointer); |
|
1588 | - } else { |
|
1589 | - $expr = $this->parse($in, $pointer, $to, false, 'expression', $pointer); |
|
1590 | - } |
|
1591 | - if (is_array($out) && is_array($expr)) { |
|
1592 | - $out[0] .= $match[1] . $expr[0]; |
|
1593 | - $out[1] .= $match[1] . $expr[1]; |
|
1594 | - } elseif (is_array($out)) { |
|
1595 | - $out[0] .= $match[1] . $expr; |
|
1596 | - $out[1] .= $match[1] . $expr; |
|
1597 | - } elseif (is_array($expr)) { |
|
1598 | - $out .= $match[1] . $expr[0]; |
|
1599 | - } else { |
|
1600 | - $out .= $match[1] . $expr; |
|
1601 | - } |
|
1602 | - } |
|
1603 | - } elseif ($curBlock === 'root' && preg_match('#^(\s*(?:[+/*%-.]=|=|\+\+|--)\s*)(.*)#s', $substr, $match)) { |
|
1604 | - if ($this->debug) { |
|
1605 | - echo 'PARSING POST-VAR ASSIGNMENT ' . $substr . "\n"; |
|
1606 | - } |
|
1607 | - // parse assignment |
|
1608 | - $value = $match[2]; |
|
1609 | - $operator = trim($match[1]); |
|
1610 | - if (substr($value, 0, 1) == '=') { |
|
1611 | - throw new CompilationException($this, 'Unexpected "=" in <em>' . $substr . '</em>'); |
|
1612 | - } |
|
1613 | - |
|
1614 | - if ($pointer !== null) { |
|
1615 | - $pointer += strlen($match[1]); |
|
1616 | - } |
|
1617 | - |
|
1618 | - if ($operator !== '++' && $operator !== '--') { |
|
1619 | - $parts = array(); |
|
1620 | - $ptr = 0; |
|
1621 | - $parts = $this->parse($value, 0, strlen($value), $parts, 'condition', $ptr); |
|
1622 | - $pointer += $ptr; |
|
1623 | - |
|
1624 | - // load if plugin |
|
1625 | - try { |
|
1626 | - $this->getPluginType('if'); |
|
1627 | - } |
|
1628 | - catch (Exception $e) { |
|
1629 | - throw new CompilationException($this, 'Assignments require the "if" plugin to be accessible'); |
|
1630 | - } |
|
1631 | - |
|
1632 | - $parts = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS . 'PluginIf', 'init'), 1); |
|
1633 | - $tokens = $this->getParamTokens($parts); |
|
1634 | - $parts = $this->getCompiledParams($parts); |
|
1635 | - |
|
1636 | - $value = PluginIf::replaceKeywords($parts['*'], $tokens['*'], $this); |
|
1637 | - $echo = ''; |
|
1638 | - } else { |
|
1639 | - $value = array(); |
|
1640 | - $echo = 'echo '; |
|
1641 | - } |
|
1642 | - |
|
1643 | - if ($this->autoEscape) { |
|
1644 | - $out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out); |
|
1645 | - } |
|
1646 | - $out = self::PHP_OPEN . $echo . $out . $operator . implode(' ', $value) . self::PHP_CLOSE; |
|
1647 | - } elseif ($curBlock === 'array' && is_array($parsingParams) && preg_match('#^(\s*=>?\s*)#', $substr, $match)) { |
|
1648 | - // parse namedparam with var as name (only for array) |
|
1649 | - if ($this->debug) { |
|
1650 | - echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND' . "\n"; |
|
1651 | - } |
|
1652 | - $len = strlen($match[1]); |
|
1653 | - $var = $out[count($out) - 1]; |
|
1654 | - $pointer += $len; |
|
1655 | - |
|
1656 | - $output = array($var[0], $this->parse($substr, $len, null, false, 'namedparam', $pointer)); |
|
1657 | - |
|
1658 | - $parsingParams[] = $output; |
|
1659 | - |
|
1660 | - return $parsingParams; |
|
1661 | - } |
|
1662 | - } |
|
1663 | - |
|
1664 | - if ($curBlock !== 'modifier' && ($parsed === 'func' || $parsed === 'var') && preg_match('#^(\|@?[a-z0-9_]+(:.*)?)+#i', $substr, $match)) { |
|
1665 | - // parse modifier on funcs or vars |
|
1666 | - $srcPointer = $pointer; |
|
1667 | - if (is_array($parsingParams)) { |
|
1668 | - $tmp = $this->replaceModifiers( |
|
1669 | - array( |
|
1670 | - null, |
|
1671 | - null, |
|
1672 | - $out[count($out) - 1][0], |
|
1673 | - $match[0] |
|
1674 | - ), $curBlock, $pointer |
|
1675 | - ); |
|
1676 | - $out[count($out) - 1][0] = $tmp; |
|
1677 | - $out[count($out) - 1][1] .= substr($substr, $srcPointer, $srcPointer - $pointer); |
|
1678 | - } else { |
|
1679 | - $out = $this->replaceModifiers(array(null, null, $out, $match[0]), $curBlock, $pointer); |
|
1680 | - } |
|
1681 | - } |
|
1682 | - |
|
1683 | - // func parsed, check if any func-extension applies |
|
1684 | - if ($parsed === 'func' && preg_match('#^->[a-z0-9_]+(\s*\(.+|->[a-z_].*)?#is', $substr, $match)) { |
|
1685 | - // parse method call or property read |
|
1686 | - $ptr = 0; |
|
1687 | - |
|
1688 | - if (is_array($parsingParams)) { |
|
1689 | - $output = $this->parseMethodCall($out[count($out) - 1][1], $match[0], $curBlock, $ptr); |
|
1690 | - |
|
1691 | - $out[count($out) - 1][0] = $output; |
|
1692 | - $out[count($out) - 1][1] .= substr($match[0], 0, $ptr); |
|
1693 | - } else { |
|
1694 | - $out = $this->parseMethodCall($out, $match[0], $curBlock, $ptr); |
|
1695 | - } |
|
1696 | - |
|
1697 | - $pointer += $ptr; |
|
1698 | - } |
|
1699 | - |
|
1700 | - if ($curBlock === 'root' && substr($out, 0, strlen(self::PHP_OPEN)) !== self::PHP_OPEN) { |
|
1701 | - return self::PHP_OPEN . 'echo ' . $out . ';' . self::PHP_CLOSE; |
|
1702 | - } else { |
|
1703 | - return $out; |
|
1704 | - } |
|
1705 | - } |
|
1706 | - |
|
1707 | - /** |
|
1708 | - * Parses a function call. |
|
1709 | - * |
|
1710 | - * @param string $in the string within which we must parse something |
|
1711 | - * @param int $from the starting offset of the parsed area |
|
1712 | - * @param int $to the ending offset of the parsed area |
|
1713 | - * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
1714 | - * default |
|
1715 | - * @param string $curBlock the current parser-block being processed |
|
1716 | - * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
1717 | - * or null by default |
|
1718 | - * |
|
1719 | - * @return string parsed values |
|
1720 | - * @throws CompilationException |
|
1721 | - * @throws Exception |
|
1722 | - * @throws SecurityException |
|
1723 | - */ |
|
1724 | - protected function parseFunction($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
1725 | - { |
|
1726 | - $output = ''; |
|
1727 | - $cmdstr = substr($in, $from, $to - $from); |
|
1728 | - preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*' . $this->rdr . '|\s*;)?/i', $cmdstr, $match); |
|
1729 | - |
|
1730 | - if (empty($match[1])) { |
|
1731 | - throw new CompilationException($this, 'Parse error, invalid function name : ' . substr($cmdstr, 0, 15)); |
|
1732 | - } |
|
1733 | - |
|
1734 | - $func = $match[1]; |
|
1735 | - |
|
1736 | - if (!empty($match[2])) { |
|
1737 | - $cmdstr = $match[1]; |
|
1738 | - } |
|
1739 | - |
|
1740 | - if ($this->debug) { |
|
1741 | - echo 'FUNC FOUND (' . $func . ')' . "\n"; |
|
1742 | - } |
|
1743 | - |
|
1744 | - $paramsep = ''; |
|
1745 | - |
|
1746 | - if (is_array($parsingParams) || $curBlock != 'root') { |
|
1747 | - $paramspos = strpos($cmdstr, '('); |
|
1748 | - $paramsep = ')'; |
|
1749 | - } elseif (preg_match_all('#^\s*[\\\\:a-z0-9_]+(\s*\(|\s+[^(])#i', $cmdstr, $match, PREG_OFFSET_CAPTURE)) { |
|
1750 | - $paramspos = $match[1][0][1]; |
|
1751 | - $paramsep = substr($match[1][0][0], - 1) === '(' ? ')' : ''; |
|
1752 | - if ($paramsep === ')') { |
|
1753 | - $paramspos += strlen($match[1][0][0]) - 1; |
|
1754 | - if (substr($cmdstr, 0, 2) === 'if' || substr($cmdstr, 0, 6) === 'elseif') { |
|
1755 | - $paramsep = ''; |
|
1756 | - if (strlen($match[1][0][0]) > 1) { |
|
1757 | - -- $paramspos; |
|
1758 | - } |
|
1759 | - } |
|
1760 | - } |
|
1761 | - } else { |
|
1762 | - $paramspos = false; |
|
1763 | - } |
|
1764 | - |
|
1765 | - $state = 0; |
|
1766 | - |
|
1767 | - if ($paramspos === false) { |
|
1768 | - $params = array(); |
|
1769 | - |
|
1770 | - if ($curBlock !== 'root') { |
|
1771 | - return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1772 | - } |
|
1773 | - } else { |
|
1774 | - if ($curBlock === 'condition') { |
|
1775 | - // load if plugin |
|
1776 | - $this->getPluginType('if'); |
|
1777 | - |
|
1778 | - if (PluginIf::replaceKeywords(array($func), array(self::T_UNQUOTED_STRING), $this) !== array($func)) { |
|
1779 | - return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1780 | - } |
|
1781 | - } |
|
1782 | - $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos - strlen($func))); |
|
1783 | - $paramstr = substr($cmdstr, $paramspos + 1); |
|
1784 | - if (substr($paramstr, - 1, 1) === $paramsep) { |
|
1785 | - $paramstr = substr($paramstr, 0, - 1); |
|
1786 | - } |
|
1787 | - |
|
1788 | - if (strlen($paramstr) === 0) { |
|
1789 | - $params = array(); |
|
1790 | - $paramstr = ''; |
|
1791 | - } else { |
|
1792 | - $ptr = 0; |
|
1793 | - $params = array(); |
|
1794 | - if ($func === 'empty') { |
|
1795 | - $params = $this->parseVar($paramstr, $ptr, strlen($paramstr), $params, 'root', $ptr); |
|
1796 | - } else { |
|
1797 | - while ($ptr < strlen($paramstr)) { |
|
1798 | - while (true) { |
|
1799 | - if ($ptr >= strlen($paramstr)) { |
|
1800 | - break 2; |
|
1801 | - } |
|
1802 | - |
|
1803 | - if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') { |
|
1804 | - if ($this->debug) { |
|
1805 | - echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1806 | - } |
|
1807 | - break 2; |
|
1808 | - } elseif ($paramstr[$ptr] === ';') { |
|
1809 | - ++ $ptr; |
|
1810 | - if ($this->debug) { |
|
1811 | - echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1812 | - } |
|
1813 | - break 2; |
|
1814 | - } elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') { |
|
1815 | - if ($this->debug) { |
|
1816 | - echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1817 | - } |
|
1818 | - break 2; |
|
1819 | - } elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) { |
|
1820 | - if ($this->debug) { |
|
1821 | - echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT ' . $ptr . "\n"; |
|
1822 | - } |
|
1823 | - break 2; |
|
1824 | - } |
|
1825 | - |
|
1826 | - if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") { |
|
1827 | - ++ $ptr; |
|
1828 | - } else { |
|
1829 | - break; |
|
1830 | - } |
|
1831 | - } |
|
1832 | - |
|
1833 | - if ($this->debug) { |
|
1834 | - echo 'FUNC START PARAM PARSING WITH POINTER AT ' . $ptr . "\n"; |
|
1835 | - } |
|
1836 | - |
|
1837 | - if ($func === 'if' || $func === 'elseif' || $func === 'tif') { |
|
1838 | - $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'condition', $ptr); |
|
1839 | - } elseif ($func === 'array') { |
|
1840 | - $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'array', $ptr); |
|
1841 | - } else { |
|
1842 | - $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'function', $ptr); |
|
1843 | - } |
|
1844 | - |
|
1845 | - if ($this->debug) { |
|
1846 | - echo 'PARAM PARSED, POINTER AT ' . $ptr . ' (' . substr($paramstr, $ptr - 1, 3) . ')' . "\n"; |
|
1847 | - } |
|
1848 | - } |
|
1849 | - } |
|
1850 | - $paramstr = substr($paramstr, 0, $ptr); |
|
1851 | - $state = 0; |
|
1852 | - foreach ($params as $k => $p) { |
|
1853 | - if (is_array($p) && is_array($p[1])) { |
|
1854 | - $state |= 2; |
|
1855 | - } else { |
|
1856 | - if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m) && $func !== 'array') { |
|
1857 | - $params[$k] = array($m[2], array('true', 'true')); |
|
1858 | - } else { |
|
1859 | - if ($state & 2 && $func !== 'array') { |
|
1860 | - throw new CompilationException($this, 'You can not use an unnamed parameter after a named one'); |
|
1861 | - } |
|
1862 | - $state |= 1; |
|
1863 | - } |
|
1864 | - } |
|
1865 | - } |
|
1866 | - } |
|
1867 | - } |
|
1868 | - |
|
1869 | - if ($pointer !== null) { |
|
1870 | - $pointer += (isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func) + (isset($whitespace) ? $whitespace : 0); |
|
1871 | - if ($this->debug) { |
|
1872 | - echo 'FUNC ADDS ' . ((isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func)) . ' TO POINTER' . "\n"; |
|
1873 | - } |
|
1874 | - } |
|
1875 | - |
|
1876 | - if ($curBlock === 'method' || $func === 'do' || strstr($func, '::') !== false) { |
|
1877 | - // handle static method calls with security policy |
|
1878 | - if (strstr($func, '::') !== false && $this->securityPolicy !== null && $this->securityPolicy->isMethodAllowed(explode('::', strtolower($func))) !== true) { |
|
1879 | - throw new SecurityException('Call to a disallowed php function : ' . $func); |
|
1880 | - } |
|
1881 | - $pluginType = Core::NATIVE_PLUGIN; |
|
1882 | - } else { |
|
1883 | - $pluginType = $this->getPluginType($func); |
|
1884 | - } |
|
1885 | - |
|
1886 | - // Blocks plugin |
|
1887 | - if ($pluginType & Core::BLOCK_PLUGIN) { |
|
1888 | - if ($curBlock !== 'root' || is_array($parsingParams)) { |
|
1889 | - throw new CompilationException($this, 'Block plugins can not be used as other plugin\'s arguments'); |
|
1890 | - } |
|
1891 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
1892 | - return $this->addCustomBlock($func, $params, $state); |
|
1893 | - } else { |
|
1894 | - return $this->addBlock($func, $params, $state); |
|
1895 | - } |
|
1896 | - } elseif ($pluginType & Core::SMARTY_BLOCK) { |
|
1897 | - if ($curBlock !== 'root' || is_array($parsingParams)) { |
|
1898 | - throw new CompilationException($this, 'Block plugins can not be used as other plugin\'s arguments'); |
|
1899 | - } |
|
1900 | - |
|
1901 | - if ($state & 2) { |
|
1902 | - array_unshift($params, array('__functype', array($pluginType, $pluginType))); |
|
1903 | - array_unshift($params, array('__funcname', array($func, $func))); |
|
1904 | - } else { |
|
1905 | - array_unshift($params, array($pluginType, $pluginType)); |
|
1906 | - array_unshift($params, array($func, $func)); |
|
1907 | - } |
|
1908 | - |
|
1909 | - return $this->addBlock('smartyinterface', $params, $state); |
|
1910 | - } |
|
1911 | - |
|
1912 | - // Functions plugin |
|
1913 | - if ($pluginType & Core::NATIVE_PLUGIN || $pluginType & Core::SMARTY_FUNCTION || $pluginType & Core::SMARTY_BLOCK) { |
|
1914 | - $params = $this->mapParams($params, null, $state); |
|
1915 | - } elseif ($pluginType & Core::CLASS_PLUGIN) { |
|
1916 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
1917 | - $params = $this->mapParams( |
|
1918 | - $params, array( |
|
1919 | - $this->customPlugins[$func]['class'], |
|
1920 | - $this->customPlugins[$func]['function'] |
|
1921 | - ), $state); |
|
1922 | - } else { |
|
1923 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
1924 | - $params = $this->mapParams($params, array( |
|
1925 | - 'Plugin' . Core::toCamelCase($func), |
|
1926 | - ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process' |
|
1927 | - ), $state); |
|
1928 | - } else { |
|
1929 | - $params = $this->mapParams($params, array( |
|
1930 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
1931 | - ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process' |
|
1932 | - ), $state); |
|
1933 | - } |
|
1934 | - } |
|
1935 | - } elseif ($pluginType & Core::FUNC_PLUGIN) { |
|
1936 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
1937 | - $params = $this->mapParams($params, $this->customPlugins[$func]['callback'], $state); |
|
1938 | - } else { |
|
1939 | - // Custom plugin |
|
1940 | - if (function_exists('Plugin' . Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? |
|
1941 | - 'Compile' : '')) !== false) { |
|
1942 | - $params = $this->mapParams($params, 'Plugin' . Core::toCamelCase($func) . (($pluginType & |
|
1943 | - Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1944 | - } // Builtin helper plugin |
|
1945 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . ( |
|
1946 | - ($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) !== false) { |
|
1947 | - $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase |
|
1948 | - ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1949 | - } // Builtin function plugin |
|
1950 | - else { |
|
1951 | - $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase |
|
1952 | - ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1953 | - } |
|
1954 | - } |
|
1955 | - } elseif ($pluginType & Core::SMARTY_MODIFIER) { |
|
1956 | - $output = 'smarty_modifier_' . $func . '(' . implode(', ', $params) . ')'; |
|
1957 | - } elseif ($pluginType & Core::PROXY_PLUGIN) { |
|
1958 | - $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state); |
|
1959 | - } elseif ($pluginType & Core::TEMPLATE_PLUGIN) { |
|
1960 | - // transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values)) |
|
1961 | - $map = array(); |
|
1962 | - foreach ($this->templatePlugins[$func]['params'] as $param => $defValue) { |
|
1963 | - if ($param == 'rest') { |
|
1964 | - $param = '*'; |
|
1965 | - } |
|
1966 | - $hasDefault = $defValue !== null; |
|
1967 | - if ($defValue === 'null') { |
|
1968 | - $defValue = null; |
|
1969 | - } elseif ($defValue === 'false') { |
|
1970 | - $defValue = false; |
|
1971 | - } elseif ($defValue === 'true') { |
|
1972 | - $defValue = true; |
|
1973 | - } elseif (preg_match('#^([\'"]).*?\1$#', $defValue)) { |
|
1974 | - $defValue = substr($defValue, 1, - 1); |
|
1975 | - } |
|
1976 | - $map[] = array($param, $hasDefault, $defValue); |
|
1977 | - } |
|
1978 | - |
|
1979 | - $params = $this->mapParams($params, null, $state, $map); |
|
1980 | - } |
|
1981 | - |
|
1982 | - // only keep php-syntax-safe values for non-block plugins |
|
1983 | - $tokens = array(); |
|
1984 | - foreach ($params as $k => $p) { |
|
1985 | - $tokens[$k] = isset($p[2]) ? $p[2] : 0; |
|
1986 | - $params[$k] = $p[0]; |
|
1987 | - } |
|
1988 | - if ($pluginType & Core::NATIVE_PLUGIN) { |
|
1989 | - if ($func === 'do') { |
|
1990 | - if (isset($params['*'])) { |
|
1991 | - $output = implode(';', $params['*']) . ';'; |
|
1992 | - } else { |
|
1993 | - $output = ''; |
|
1994 | - } |
|
1995 | - |
|
1996 | - if (is_array($parsingParams) || $curBlock !== 'root') { |
|
1997 | - throw new CompilationException($this, 'Do can not be used inside another function or block'); |
|
1998 | - } else { |
|
1999 | - return self::PHP_OPEN . $output . self::PHP_CLOSE; |
|
2000 | - } |
|
2001 | - } else { |
|
2002 | - if (isset($params['*'])) { |
|
2003 | - $output = $func . '(' . implode(', ', $params['*']) . ')'; |
|
2004 | - } else { |
|
2005 | - $output = $func . '()'; |
|
2006 | - } |
|
2007 | - } |
|
2008 | - } elseif ($pluginType & Core::FUNC_PLUGIN) { |
|
2009 | - if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
2010 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2011 | - $funcCompiler = $this->customPlugins[$func]['callback']; |
|
2012 | - } else { |
|
2013 | - // Custom plugin |
|
2014 | - if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) { |
|
2015 | - $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile'; |
|
2016 | - } // Builtin helper plugin |
|
2017 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . |
|
2018 | - 'Compile') !== false) { |
|
2019 | - $funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . |
|
2020 | - 'Compile'; |
|
2021 | - } // Builtin function plugin |
|
2022 | - else { |
|
2023 | - $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . |
|
2024 | - 'Compile'; |
|
2025 | - } |
|
2026 | - } |
|
2027 | - array_unshift($params, $this); |
|
2028 | - if ($func === 'tif') { |
|
2029 | - $params[] = $tokens; |
|
2030 | - } |
|
2031 | - $output = call_user_func_array($funcCompiler, $params); |
|
2032 | - } else { |
|
2033 | - array_unshift($params, '$this'); |
|
2034 | - $params = self::implode_r($params); |
|
2035 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2036 | - $callback = $this->customPlugins[$func]['callback']; |
|
2037 | - if ($callback instanceof Closure) { |
|
2038 | - $output = 'call_user_func($this->getCustomPlugin(\'' . $func . '\'), ' . $params . ')'; |
|
2039 | - } else { |
|
2040 | - $output = 'call_user_func(\'' . $callback . '\', ' . $params . ')'; |
|
2041 | - } |
|
2042 | - } else { |
|
2043 | - // Custom plugin |
|
2044 | - if (function_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2045 | - $output = 'Plugin' . Core::toCamelCase($func) . '(' . $params . |
|
2046 | - ')'; |
|
2047 | - } // Builtin helper plugin |
|
2048 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== |
|
2049 | - false) { |
|
2050 | - $output = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . '(' . |
|
2051 | - $params . ')'; |
|
2052 | - } // Builtin function plugin |
|
2053 | - else { |
|
2054 | - $output = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '(' . |
|
2055 | - $params . ')'; |
|
2056 | - } |
|
2057 | - } |
|
2058 | - } |
|
2059 | - } elseif ($pluginType & Core::CLASS_PLUGIN) { |
|
2060 | - if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
2061 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2062 | - $callback = $this->customPlugins[$func]['callback']; |
|
2063 | - if (!is_array($callback)) { |
|
2064 | - if (!method_exists($callback, 'compile')) { |
|
2065 | - throw new Exception('Custom plugin ' . $func . ' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
2066 | - } |
|
2067 | - if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) { |
|
2068 | - $funcCompiler = array($callback, 'compile'); |
|
2069 | - } else { |
|
2070 | - $funcCompiler = array(new $callback(), 'compile'); |
|
2071 | - } |
|
2072 | - } else { |
|
2073 | - $funcCompiler = $callback; |
|
2074 | - } |
|
2075 | - } else { |
|
2076 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2077 | - $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile'); |
|
2078 | - } else { |
|
2079 | - $funcCompiler = array( |
|
2080 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
2081 | - 'compile' |
|
2082 | - ); |
|
2083 | - } |
|
2084 | - array_unshift($params, $this); |
|
2085 | - } |
|
2086 | - $output = call_user_func_array($funcCompiler, $params); |
|
2087 | - } else { |
|
2088 | - $params = self::implode_r($params); |
|
2089 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2090 | - $callback = $this->customPlugins[$func]['callback']; |
|
2091 | - if (!is_array($callback)) { |
|
2092 | - if (!method_exists($callback, 'process')) { |
|
2093 | - throw new Exception('Custom plugin ' . $func . ' must implement the "process" method to be usable, or you should provide a full callback to the method to use'); |
|
2094 | - } |
|
2095 | - if (($ref = new ReflectionMethod($callback, 'process')) && $ref->isStatic()) { |
|
2096 | - $output = 'call_user_func(array(\'' . $callback . '\', \'process\'), ' . $params . ')'; |
|
2097 | - } else { |
|
2098 | - $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback . '\'), \'process\'), ' . $params . ')'; |
|
2099 | - } |
|
2100 | - } elseif (is_object($callback[0])) { |
|
2101 | - $output = 'call_user_func(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2102 | - } elseif (($ref = new ReflectionMethod($callback[0], $callback[1])) && $ref->isStatic()) { |
|
2103 | - $output = 'call_user_func(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2104 | - } else { |
|
2105 | - $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback[0] . '\'), \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2106 | - } |
|
2107 | - if (empty($params)) { |
|
2108 | - $output = substr($output, 0, - 3) . ')'; |
|
2109 | - } |
|
2110 | - } else { |
|
2111 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2112 | - $output = '$this->classCall(\'Plugin' . $func . '\', array(' . $params . '))'; |
|
2113 | - } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== |
|
2114 | - false) { |
|
2115 | - $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', |
|
34 | + /** |
|
35 | + * Constant that represents a php opening tag. |
|
36 | + * use it in case it needs to be adjusted |
|
37 | + * |
|
38 | + * @var string |
|
39 | + */ |
|
40 | + const PHP_OPEN = '<?php '; |
|
41 | + |
|
42 | + /** |
|
43 | + * Constant that represents a php closing tag. |
|
44 | + * use it in case it needs to be adjusted |
|
45 | + * |
|
46 | + * @var string |
|
47 | + */ |
|
48 | + const PHP_CLOSE = '?>'; |
|
49 | + |
|
50 | + /** |
|
51 | + * Boolean flag to enable or disable debugging output. |
|
52 | + * |
|
53 | + * @var bool |
|
54 | + */ |
|
55 | + public $debug = false; |
|
56 | + |
|
57 | + /** |
|
58 | + * Left script delimiter. |
|
59 | + * |
|
60 | + * @var string |
|
61 | + */ |
|
62 | + protected $ld = '{'; |
|
63 | + |
|
64 | + /** |
|
65 | + * Left script delimiter with escaped regex meta characters. |
|
66 | + * |
|
67 | + * @var string |
|
68 | + */ |
|
69 | + protected $ldr = '\\{'; |
|
70 | + |
|
71 | + /** |
|
72 | + * Right script delimiter. |
|
73 | + * |
|
74 | + * @var string |
|
75 | + */ |
|
76 | + protected $rd = '}'; |
|
77 | + |
|
78 | + /** |
|
79 | + * Right script delimiter with escaped regex meta characters. |
|
80 | + * |
|
81 | + * @var string |
|
82 | + */ |
|
83 | + protected $rdr = '\\}'; |
|
84 | + |
|
85 | + /** |
|
86 | + * Defines whether the nested comments should be parsed as nested or not. |
|
87 | + * defaults to false (classic block comment parsing as in all languages) |
|
88 | + * |
|
89 | + * @var bool |
|
90 | + */ |
|
91 | + protected $allowNestedComments = false; |
|
92 | + |
|
93 | + /** |
|
94 | + * Defines whether opening and closing tags can contain spaces before valid data or not. |
|
95 | + * turn to true if you want to be sloppy with the syntax, but when set to false it allows |
|
96 | + * to skip javascript and css tags as long as they are in the form "{ something", which is |
|
97 | + * nice. default is false. |
|
98 | + * |
|
99 | + * @var bool |
|
100 | + */ |
|
101 | + protected $allowLooseOpenings = false; |
|
102 | + |
|
103 | + /** |
|
104 | + * Defines whether the compiler will automatically html-escape variables or not. |
|
105 | + * default is false |
|
106 | + * |
|
107 | + * @var bool |
|
108 | + */ |
|
109 | + protected $autoEscape = false; |
|
110 | + |
|
111 | + /** |
|
112 | + * Security policy object. |
|
113 | + * |
|
114 | + * @var SecurityPolicy |
|
115 | + */ |
|
116 | + protected $securityPolicy; |
|
117 | + |
|
118 | + /** |
|
119 | + * Stores the custom plugins registered with this compiler. |
|
120 | + * |
|
121 | + * @var array |
|
122 | + */ |
|
123 | + protected $customPlugins = array(); |
|
124 | + |
|
125 | + /** |
|
126 | + * Stores the template plugins registered with this compiler. |
|
127 | + * |
|
128 | + * @var array |
|
129 | + */ |
|
130 | + protected $templatePlugins = array(); |
|
131 | + |
|
132 | + /** |
|
133 | + * Stores the pre- and post-processors callbacks. |
|
134 | + * |
|
135 | + * @var array |
|
136 | + */ |
|
137 | + protected $processors = array('pre' => array(), 'post' => array()); |
|
138 | + |
|
139 | + /** |
|
140 | + * Stores a list of plugins that are used in the currently compiled |
|
141 | + * template, and that are not compilable. these plugins will be loaded |
|
142 | + * during the template's runtime if required. |
|
143 | + * it is a 1D array formatted as key:pluginName value:pluginType |
|
144 | + * |
|
145 | + * @var array |
|
146 | + */ |
|
147 | + protected $usedPlugins; |
|
148 | + |
|
149 | + /** |
|
150 | + * Stores the template undergoing compilation. |
|
151 | + * |
|
152 | + * @var string |
|
153 | + */ |
|
154 | + protected $template; |
|
155 | + |
|
156 | + /** |
|
157 | + * Stores the current pointer position inside the template. |
|
158 | + * |
|
159 | + * @var int |
|
160 | + */ |
|
161 | + protected $pointer; |
|
162 | + |
|
163 | + /** |
|
164 | + * Stores the current line count inside the template for debugging purposes. |
|
165 | + * |
|
166 | + * @var int |
|
167 | + */ |
|
168 | + protected $line; |
|
169 | + |
|
170 | + /** |
|
171 | + * Stores the current template source while compiling it. |
|
172 | + * |
|
173 | + * @var string |
|
174 | + */ |
|
175 | + protected $templateSource; |
|
176 | + |
|
177 | + /** |
|
178 | + * Stores the data within which the scope moves. |
|
179 | + * |
|
180 | + * @var array |
|
181 | + */ |
|
182 | + protected $data; |
|
183 | + |
|
184 | + /** |
|
185 | + * Variable scope of the compiler, set to null if |
|
186 | + * it can not be resolved to a static string (i.e. if some |
|
187 | + * plugin defines a new scope based on a variable array key). |
|
188 | + * |
|
189 | + * @var mixed |
|
190 | + */ |
|
191 | + protected $scope; |
|
192 | + |
|
193 | + /** |
|
194 | + * Variable scope tree, that allows to rebuild the current |
|
195 | + * scope if required, i.e. when going to a parent level. |
|
196 | + * |
|
197 | + * @var array |
|
198 | + */ |
|
199 | + protected $scopeTree; |
|
200 | + |
|
201 | + /** |
|
202 | + * Block plugins stack, accessible through some methods. |
|
203 | + * |
|
204 | + * @see findBlock |
|
205 | + * @see getCurrentBlock |
|
206 | + * @see addBlock |
|
207 | + * @see addCustomBlock |
|
208 | + * @see injectBlock |
|
209 | + * @see removeBlock |
|
210 | + * @see removeTopBlock |
|
211 | + * @var array |
|
212 | + */ |
|
213 | + protected $stack = array(); |
|
214 | + |
|
215 | + /** |
|
216 | + * Current block at the top of the block plugins stack, |
|
217 | + * accessible through getCurrentBlock. |
|
218 | + * |
|
219 | + * @see getCurrentBlock |
|
220 | + * @var array |
|
221 | + */ |
|
222 | + protected $curBlock; |
|
223 | + |
|
224 | + /** |
|
225 | + * Current dwoo object that uses this compiler, or null. |
|
226 | + * |
|
227 | + * @var Core |
|
228 | + */ |
|
229 | + public $dwoo; |
|
230 | + |
|
231 | + /** |
|
232 | + * Holds an instance of this class, used by getInstance when you don't |
|
233 | + * provide a custom compiler in order to save resources. |
|
234 | + * |
|
235 | + * @var Compiler |
|
236 | + */ |
|
237 | + protected static $instance; |
|
238 | + |
|
239 | + /** |
|
240 | + * Token types. |
|
241 | + * |
|
242 | + * @var int |
|
243 | + */ |
|
244 | + const T_UNQUOTED_STRING = 1; |
|
245 | + const T_NUMERIC = 2; |
|
246 | + const T_NULL = 4; |
|
247 | + const T_BOOL = 8; |
|
248 | + const T_MATH = 16; |
|
249 | + const T_BREAKCHAR = 32; |
|
250 | + |
|
251 | + /** |
|
252 | + * Compiler constructor. |
|
253 | + * saves the created instance so that child templates get the same one |
|
254 | + */ |
|
255 | + public function __construct() |
|
256 | + { |
|
257 | + self::$instance = $this; |
|
258 | + } |
|
259 | + |
|
260 | + /** |
|
261 | + * Sets the delimiters to use in the templates. |
|
262 | + * delimiters can be multi-character strings but should not be one of those as they will |
|
263 | + * make it very hard to work with templates or might even break the compiler entirely : "\", "$", "|", ":" and |
|
264 | + * finally "#" only if you intend to use config-vars with the #var# syntax. |
|
265 | + * |
|
266 | + * @param string $left left delimiter |
|
267 | + * @param string $right right delimiter |
|
268 | + */ |
|
269 | + public function setDelimiters($left, $right) |
|
270 | + { |
|
271 | + $this->ld = $left; |
|
272 | + $this->rd = $right; |
|
273 | + $this->ldr = preg_quote($left, '/'); |
|
274 | + $this->rdr = preg_quote($right, '/'); |
|
275 | + } |
|
276 | + |
|
277 | + /** |
|
278 | + * Returns the left and right template delimiters. |
|
279 | + * |
|
280 | + * @return array containing the left and the right delimiters |
|
281 | + */ |
|
282 | + public function getDelimiters() |
|
283 | + { |
|
284 | + return array($this->ld, $this->rd); |
|
285 | + } |
|
286 | + |
|
287 | + /** |
|
288 | + * Sets the way to handle nested comments, if set to true |
|
289 | + * {* foo {* some other *} comment *} will be stripped correctly. |
|
290 | + * if false it will remove {* foo {* some other *} and leave "comment *}" alone, |
|
291 | + * this is the default behavior |
|
292 | + * |
|
293 | + * @param bool $allow allow nested comments or not, defaults to true (but the default internal value is false) |
|
294 | + */ |
|
295 | + public function setNestedCommentsHandling($allow = true) |
|
296 | + { |
|
297 | + $this->allowNestedComments = (bool)$allow; |
|
298 | + } |
|
299 | + |
|
300 | + /** |
|
301 | + * Returns the nested comments handling setting. |
|
302 | + * |
|
303 | + * @see setNestedCommentsHandling |
|
304 | + * @return bool true if nested comments are allowed |
|
305 | + */ |
|
306 | + public function getNestedCommentsHandling() |
|
307 | + { |
|
308 | + return $this->allowNestedComments; |
|
309 | + } |
|
310 | + |
|
311 | + /** |
|
312 | + * Sets the tag openings handling strictness, if set to true, template tags can |
|
313 | + * contain spaces before the first function/string/variable such as { $foo} is valid. |
|
314 | + * if set to false (default setting), { $foo} is invalid but that is however a good thing |
|
315 | + * as it allows css (i.e. #foo { color:red; }) to be parsed silently without triggering |
|
316 | + * an error, same goes for javascript. |
|
317 | + * |
|
318 | + * @param bool $allow true to allow loose handling, false to restore default setting |
|
319 | + */ |
|
320 | + public function setLooseOpeningHandling($allow = false) |
|
321 | + { |
|
322 | + $this->allowLooseOpenings = (bool)$allow; |
|
323 | + } |
|
324 | + |
|
325 | + /** |
|
326 | + * Returns the tag openings handling strictness setting. |
|
327 | + * |
|
328 | + * @see setLooseOpeningHandling |
|
329 | + * @return bool true if loose tags are allowed |
|
330 | + */ |
|
331 | + public function getLooseOpeningHandling() |
|
332 | + { |
|
333 | + return $this->allowLooseOpenings; |
|
334 | + } |
|
335 | + |
|
336 | + /** |
|
337 | + * Changes the auto escape setting. |
|
338 | + * if enabled, the compiler will automatically html-escape variables, |
|
339 | + * unless they are passed through the safe function such as {$var|safe} |
|
340 | + * or {safe $var} |
|
341 | + * default setting is disabled/false |
|
342 | + * |
|
343 | + * @param bool $enabled set to true to enable, false to disable |
|
344 | + */ |
|
345 | + public function setAutoEscape($enabled) |
|
346 | + { |
|
347 | + $this->autoEscape = (bool)$enabled; |
|
348 | + } |
|
349 | + |
|
350 | + /** |
|
351 | + * Returns the auto escape setting. |
|
352 | + * default setting is disabled/false |
|
353 | + * |
|
354 | + * @return bool |
|
355 | + */ |
|
356 | + public function getAutoEscape() |
|
357 | + { |
|
358 | + return $this->autoEscape; |
|
359 | + } |
|
360 | + |
|
361 | + /** |
|
362 | + * Adds a preprocessor to the compiler, it will be called |
|
363 | + * before the template is compiled. |
|
364 | + * |
|
365 | + * @param mixed $callback either a valid callback to the preprocessor or a simple name if the autoload is set to |
|
366 | + * true |
|
367 | + * @param bool $autoload if set to true, the preprocessor is auto-loaded from one of the plugin directories, else |
|
368 | + * you must provide a valid callback |
|
369 | + */ |
|
370 | + public function addPreProcessor($callback, $autoload = false) |
|
371 | + { |
|
372 | + if ($autoload) { |
|
373 | + $name = str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', Core::toCamelCase($callback)); |
|
374 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS . $name; |
|
375 | + |
|
376 | + if (class_exists($class)) { |
|
377 | + $callback = array(new $class($this), 'process'); |
|
378 | + } elseif (function_exists($class)) { |
|
379 | + $callback = $class; |
|
380 | + } else { |
|
381 | + $callback = array('autoload' => true, 'class' => $class, 'name' => $name); |
|
382 | + } |
|
383 | + |
|
384 | + $this->processors['pre'][] = $callback; |
|
385 | + } else { |
|
386 | + $this->processors['pre'][] = $callback; |
|
387 | + } |
|
388 | + } |
|
389 | + |
|
390 | + /** |
|
391 | + * Removes a preprocessor from the compiler. |
|
392 | + * |
|
393 | + * @param mixed $callback either a valid callback to the preprocessor or a simple name if it was autoloaded |
|
394 | + */ |
|
395 | + public function removePreProcessor($callback) |
|
396 | + { |
|
397 | + if (($index = array_search($callback, $this->processors['pre'], true)) !== false) { |
|
398 | + unset($this->processors['pre'][$index]); |
|
399 | + } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
400 | + $callback), |
|
401 | + $this->processors['pre'], true)) !== false) { |
|
402 | + unset($this->processors['pre'][$index]); |
|
403 | + } else { |
|
404 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
405 | + foreach ($this->processors['pre'] as $index => $proc) { |
|
406 | + if (is_array($proc) && ($proc[0] instanceof $class) || (isset($proc['class']) && $proc['class'] == $class)) { |
|
407 | + unset($this->processors['pre'][$index]); |
|
408 | + break; |
|
409 | + } |
|
410 | + } |
|
411 | + } |
|
412 | + } |
|
413 | + |
|
414 | + /** |
|
415 | + * Adds a postprocessor to the compiler, it will be called |
|
416 | + * before the template is compiled. |
|
417 | + * |
|
418 | + * @param mixed $callback either a valid callback to the postprocessor or a simple name if the autoload is set to |
|
419 | + * true |
|
420 | + * @param bool $autoload if set to true, the postprocessor is auto-loaded from one of the plugin directories, else |
|
421 | + * you must provide a valid callback |
|
422 | + */ |
|
423 | + public function addPostProcessor($callback, $autoload = false) |
|
424 | + { |
|
425 | + if ($autoload) { |
|
426 | + $name = str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
427 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS . Core::toCamelCase($name); |
|
428 | + |
|
429 | + if (class_exists($class)) { |
|
430 | + $callback = array(new $class($this), 'process'); |
|
431 | + } elseif (function_exists($class)) { |
|
432 | + $callback = $class; |
|
433 | + } else { |
|
434 | + $callback = array('autoload' => true, 'class' => $class, 'name' => $name); |
|
435 | + } |
|
436 | + |
|
437 | + $this->processors['post'][] = $callback; |
|
438 | + } else { |
|
439 | + $this->processors['post'][] = $callback; |
|
440 | + } |
|
441 | + } |
|
442 | + |
|
443 | + /** |
|
444 | + * Removes a postprocessor from the compiler. |
|
445 | + * |
|
446 | + * @param mixed $callback either a valid callback to the postprocessor or a simple name if it was autoloaded |
|
447 | + */ |
|
448 | + public function removePostProcessor($callback) |
|
449 | + { |
|
450 | + if (($index = array_search($callback, $this->processors['post'], true)) !== false) { |
|
451 | + unset($this->processors['post'][$index]); |
|
452 | + } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
453 | + $callback), |
|
454 | + $this->processors['post'], true)) !== false) { |
|
455 | + unset($this->processors['post'][$index]); |
|
456 | + } else { |
|
457 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
458 | + foreach ($this->processors['post'] as $index => $proc) { |
|
459 | + if (is_array($proc) && ($proc[0] instanceof $class) || (isset($proc['class']) && $proc['class'] == $class)) { |
|
460 | + unset($this->processors['post'][$index]); |
|
461 | + break; |
|
462 | + } |
|
463 | + } |
|
464 | + } |
|
465 | + } |
|
466 | + |
|
467 | + /** |
|
468 | + * Internal function to autoload processors at runtime if required. |
|
469 | + * |
|
470 | + * @param string $class the class/function name |
|
471 | + * @param string $name the plugin name (without Dwoo_Plugin_ prefix) |
|
472 | + * |
|
473 | + * @return array|string |
|
474 | + * @throws Exception |
|
475 | + */ |
|
476 | + protected function loadProcessor($class, $name) |
|
477 | + { |
|
478 | + if (!class_exists($class) && !function_exists($class)) { |
|
479 | + try { |
|
480 | + $this->getDwoo()->getLoader()->loadPlugin($name); |
|
481 | + } |
|
482 | + catch (Exception $e) { |
|
483 | + throw new Exception('Processor ' . $name . ' could not be found in your plugin directories, please ensure it is in a file named ' . $name . '.php in the plugin directory'); |
|
484 | + } |
|
485 | + } |
|
486 | + |
|
487 | + if (class_exists($class)) { |
|
488 | + return array(new $class($this), 'process'); |
|
489 | + } |
|
490 | + |
|
491 | + if (function_exists($class)) { |
|
492 | + return $class; |
|
493 | + } |
|
494 | + |
|
495 | + throw new Exception('Wrong processor name, when using autoload the processor must be in one of your plugin dir as "name.php" containg a class or function named "Dwoo_Processor_name"'); |
|
496 | + } |
|
497 | + |
|
498 | + /** |
|
499 | + * Adds an used plugin, this is reserved for use by the {template} plugin. |
|
500 | + * this is required so that plugin loading bubbles up from loaded |
|
501 | + * template files to the current one |
|
502 | + * |
|
503 | + * @private |
|
504 | + * |
|
505 | + * @param string $name function name |
|
506 | + * @param int $type plugin type (Core::*_PLUGIN) |
|
507 | + */ |
|
508 | + public function addUsedPlugin($name, $type) |
|
509 | + { |
|
510 | + $this->usedPlugins[$name] = $type; |
|
511 | + } |
|
512 | + |
|
513 | + /** |
|
514 | + * Returns all the plugins this template uses. |
|
515 | + * |
|
516 | + * @private |
|
517 | + * @return array the list of used plugins in the parsed template |
|
518 | + */ |
|
519 | + public function getUsedPlugins() |
|
520 | + { |
|
521 | + return $this->usedPlugins; |
|
522 | + } |
|
523 | + |
|
524 | + /** |
|
525 | + * Adds a template plugin, this is reserved for use by the {template} plugin. |
|
526 | + * this is required because the template functions are not declared yet |
|
527 | + * during compilation, so we must have a way of validating their argument |
|
528 | + * signature without using the reflection api |
|
529 | + * |
|
530 | + * @private |
|
531 | + * |
|
532 | + * @param string $name function name |
|
533 | + * @param array $params parameter array to help validate the function call |
|
534 | + * @param string $uuid unique id of the function |
|
535 | + * @param string $body function php code |
|
536 | + */ |
|
537 | + public function addTemplatePlugin($name, array $params, $uuid, $body = null) |
|
538 | + { |
|
539 | + $this->templatePlugins[$name] = array('params' => $params, 'body' => $body, 'uuid' => $uuid); |
|
540 | + } |
|
541 | + |
|
542 | + /** |
|
543 | + * Returns all the parsed sub-templates. |
|
544 | + * |
|
545 | + * @private |
|
546 | + * @return array the parsed sub-templates |
|
547 | + */ |
|
548 | + public function getTemplatePlugins() |
|
549 | + { |
|
550 | + return $this->templatePlugins; |
|
551 | + } |
|
552 | + |
|
553 | + /** |
|
554 | + * Marks a template plugin as being called, which means its source must be included in the compiled template. |
|
555 | + * |
|
556 | + * @param string $name function name |
|
557 | + */ |
|
558 | + public function useTemplatePlugin($name) |
|
559 | + { |
|
560 | + $this->templatePlugins[$name]['called'] = true; |
|
561 | + } |
|
562 | + |
|
563 | + /** |
|
564 | + * Adds the custom plugins loaded into Dwoo to the compiler so it can load them. |
|
565 | + * |
|
566 | + * @see Core::addPlugin |
|
567 | + * |
|
568 | + * @param array $customPlugins an array of custom plugins |
|
569 | + */ |
|
570 | + public function setCustomPlugins(array $customPlugins) |
|
571 | + { |
|
572 | + $this->customPlugins = $customPlugins; |
|
573 | + } |
|
574 | + |
|
575 | + /** |
|
576 | + * Sets the security policy object to enforce some php security settings. |
|
577 | + * use this if untrusted persons can modify templates, |
|
578 | + * set it on the Dwoo object as it will be passed onto the compiler automatically |
|
579 | + * |
|
580 | + * @param SecurityPolicy $policy the security policy object |
|
581 | + */ |
|
582 | + public function setSecurityPolicy(SecurityPolicy $policy = null) |
|
583 | + { |
|
584 | + $this->securityPolicy = $policy; |
|
585 | + } |
|
586 | + |
|
587 | + /** |
|
588 | + * Returns the current security policy object or null by default. |
|
589 | + * |
|
590 | + * @return SecurityPolicy|null the security policy object if any |
|
591 | + */ |
|
592 | + public function getSecurityPolicy() |
|
593 | + { |
|
594 | + return $this->securityPolicy; |
|
595 | + } |
|
596 | + |
|
597 | + /** |
|
598 | + * Sets the pointer position. |
|
599 | + * |
|
600 | + * @param int $position the new pointer position |
|
601 | + * @param bool $isOffset if set to true, the position acts as an offset and not an absolute position |
|
602 | + */ |
|
603 | + public function setPointer($position, $isOffset = false) |
|
604 | + { |
|
605 | + if ($isOffset) { |
|
606 | + $this->pointer += $position; |
|
607 | + } else { |
|
608 | + $this->pointer = $position; |
|
609 | + } |
|
610 | + } |
|
611 | + |
|
612 | + /** |
|
613 | + * Returns the current pointer position, only available during compilation of a template. |
|
614 | + * |
|
615 | + * @return int |
|
616 | + */ |
|
617 | + public function getPointer() |
|
618 | + { |
|
619 | + return $this->pointer; |
|
620 | + } |
|
621 | + |
|
622 | + /** |
|
623 | + * Sets the line number. |
|
624 | + * |
|
625 | + * @param int $number the new line number |
|
626 | + * @param bool $isOffset if set to true, the position acts as an offset and not an absolute position |
|
627 | + */ |
|
628 | + public function setLine($number, $isOffset = false) |
|
629 | + { |
|
630 | + if ($isOffset) { |
|
631 | + $this->line += $number; |
|
632 | + } else { |
|
633 | + $this->line = $number; |
|
634 | + } |
|
635 | + } |
|
636 | + |
|
637 | + /** |
|
638 | + * Returns the current line number, only available during compilation of a template. |
|
639 | + * |
|
640 | + * @return int |
|
641 | + */ |
|
642 | + public function getLine() |
|
643 | + { |
|
644 | + return $this->line; |
|
645 | + } |
|
646 | + |
|
647 | + /** |
|
648 | + * Returns the dwoo object that initiated this template compilation, only available during compilation of a |
|
649 | + * template. |
|
650 | + * |
|
651 | + * @return Core |
|
652 | + */ |
|
653 | + public function getDwoo() |
|
654 | + { |
|
655 | + return $this->dwoo; |
|
656 | + } |
|
657 | + |
|
658 | + /** |
|
659 | + * Overwrites the template that is being compiled. |
|
660 | + * |
|
661 | + * @param string $newSource the template source that must replace the current one |
|
662 | + * @param bool $fromPointer if set to true, only the source from the current pointer position is replaced |
|
663 | + * |
|
664 | + * @return void |
|
665 | + */ |
|
666 | + public function setTemplateSource($newSource, $fromPointer = false) |
|
667 | + { |
|
668 | + if ($fromPointer === true) { |
|
669 | + $this->templateSource = substr($this->templateSource, 0, $this->pointer) . $newSource; |
|
670 | + } else { |
|
671 | + $this->templateSource = $newSource; |
|
672 | + } |
|
673 | + } |
|
674 | + |
|
675 | + /** |
|
676 | + * Returns the template that is being compiled. |
|
677 | + * |
|
678 | + * @param mixed $fromPointer if set to true, only the source from the current pointer |
|
679 | + * position is returned, if a number is given it overrides the current pointer |
|
680 | + * |
|
681 | + * @return string the template or partial template |
|
682 | + */ |
|
683 | + public function getTemplateSource($fromPointer = false) |
|
684 | + { |
|
685 | + if ($fromPointer === true) { |
|
686 | + return substr($this->templateSource, $this->pointer); |
|
687 | + } elseif (is_numeric($fromPointer)) { |
|
688 | + return substr($this->templateSource, $fromPointer); |
|
689 | + } else { |
|
690 | + return $this->templateSource; |
|
691 | + } |
|
692 | + } |
|
693 | + |
|
694 | + /** |
|
695 | + * Resets the compilation pointer, effectively restarting the compilation process. |
|
696 | + * this is useful if a plugin modifies the template source since it might need to be recompiled |
|
697 | + */ |
|
698 | + public function recompile() |
|
699 | + { |
|
700 | + $this->setPointer(0); |
|
701 | + } |
|
702 | + |
|
703 | + /** |
|
704 | + * Compiles the provided string down to php code. |
|
705 | + * |
|
706 | + * @param Core $dwoo |
|
707 | + * @param ITemplate $template the template to compile |
|
708 | + * |
|
709 | + * @return string a compiled php string |
|
710 | + * @throws CompilationException |
|
711 | + */ |
|
712 | + public function compile(Core $dwoo, ITemplate $template) |
|
713 | + { |
|
714 | + // init vars |
|
715 | + // $compiled = ''; |
|
716 | + $tpl = $template->getSource(); |
|
717 | + $ptr = 0; |
|
718 | + $this->dwoo = $dwoo; |
|
719 | + $this->template = $template; |
|
720 | + $this->templateSource = &$tpl; |
|
721 | + $this->pointer = &$ptr; |
|
722 | + |
|
723 | + while (true) { |
|
724 | + // if pointer is at the beginning, reset everything, that allows a plugin to externally reset the compiler if everything must be reparsed |
|
725 | + if ($ptr === 0) { |
|
726 | + // resets variables |
|
727 | + $this->usedPlugins = array(); |
|
728 | + $this->data = array(); |
|
729 | + $this->scope = &$this->data; |
|
730 | + $this->scopeTree = array(); |
|
731 | + $this->stack = array(); |
|
732 | + $this->line = 1; |
|
733 | + $this->templatePlugins = array(); |
|
734 | + // add top level block |
|
735 | + $compiled = $this->addBlock('TopLevelBlock', array(), 0); |
|
736 | + $this->stack[0]['buffer'] = ''; |
|
737 | + |
|
738 | + if ($this->debug) { |
|
739 | + echo "\n"; |
|
740 | + echo 'COMPILER INIT' . "\n"; |
|
741 | + } |
|
742 | + |
|
743 | + if ($this->debug) { |
|
744 | + echo 'PROCESSING PREPROCESSORS (' . count($this->processors['pre']) . ')' . "\n"; |
|
745 | + } |
|
746 | + |
|
747 | + // runs preprocessors |
|
748 | + foreach ($this->processors['pre'] as $preProc) { |
|
749 | + if (is_array($preProc) && isset($preProc['autoload'])) { |
|
750 | + $preProc = $this->loadProcessor($preProc['class'], $preProc['name']); |
|
751 | + } |
|
752 | + if (is_array($preProc) && $preProc[0] instanceof Processor) { |
|
753 | + $tpl = call_user_func($preProc, $tpl); |
|
754 | + } else { |
|
755 | + $tpl = call_user_func($preProc, $this, $tpl); |
|
756 | + } |
|
757 | + } |
|
758 | + unset($preProc); |
|
759 | + |
|
760 | + // show template source if debug |
|
761 | + if ($this->debug) { |
|
762 | + echo '<pre>'.print_r(htmlentities($tpl), true).'</pre>'."\n"; |
|
763 | + } |
|
764 | + |
|
765 | + // strips php tags if required by the security policy |
|
766 | + if ($this->securityPolicy !== null) { |
|
767 | + $search = array('{<\?php.*?\?>}'); |
|
768 | + if (ini_get('short_open_tags')) { |
|
769 | + $search = array('{<\?.*?\?>}', '{<%.*?%>}'); |
|
770 | + } |
|
771 | + switch ($this->securityPolicy->getPhpHandling()) { |
|
772 | + case SecurityPolicy::PHP_ALLOW: |
|
773 | + break; |
|
774 | + case SecurityPolicy::PHP_ENCODE: |
|
775 | + $tpl = preg_replace_callback($search, array($this, 'phpTagEncodingHelper'), $tpl); |
|
776 | + break; |
|
777 | + case SecurityPolicy::PHP_REMOVE: |
|
778 | + $tpl = preg_replace($search, '', $tpl); |
|
779 | + } |
|
780 | + } |
|
781 | + } |
|
782 | + |
|
783 | + $pos = strpos($tpl, $this->ld, $ptr); |
|
784 | + |
|
785 | + if ($pos === false) { |
|
786 | + $this->push(substr($tpl, $ptr), 0); |
|
787 | + break; |
|
788 | + } elseif (substr($tpl, $pos - 1, 1) === '\\' && substr($tpl, $pos - 2, 1) !== '\\') { |
|
789 | + $this->push(substr($tpl, $ptr, $pos - $ptr - 1) . $this->ld); |
|
790 | + $ptr = $pos + strlen($this->ld); |
|
791 | + } elseif (preg_match('/^' . $this->ldr . ($this->allowLooseOpenings ? '\s*' : '') . 'literal' . ($this->allowLooseOpenings ? '\s*' : '') . $this->rdr . '/s', substr($tpl, $pos), $litOpen)) { |
|
792 | + if (!preg_match('/' . $this->ldr . ($this->allowLooseOpenings ? '\s*' : '') . '\/literal' . ($this->allowLooseOpenings ? '\s*' : '') . $this->rdr . '/s', $tpl, $litClose, PREG_OFFSET_CAPTURE, $pos)) { |
|
793 | + throw new CompilationException($this, 'The {literal} blocks must be closed explicitly with {/literal}'); |
|
794 | + } |
|
795 | + $endpos = $litClose[0][1]; |
|
796 | + $this->push(substr($tpl, $ptr, $pos - $ptr) . substr($tpl, $pos + strlen($litOpen[0]), $endpos - $pos - strlen($litOpen[0]))); |
|
797 | + $ptr = $endpos + strlen($litClose[0][0]); |
|
798 | + } else { |
|
799 | + if (substr($tpl, $pos - 2, 1) === '\\' && substr($tpl, $pos - 1, 1) === '\\') { |
|
800 | + $this->push(substr($tpl, $ptr, $pos - $ptr - 1)); |
|
801 | + $ptr = $pos; |
|
802 | + } |
|
803 | + |
|
804 | + $this->push(substr($tpl, $ptr, $pos - $ptr)); |
|
805 | + $ptr = $pos; |
|
806 | + |
|
807 | + $pos += strlen($this->ld); |
|
808 | + if ($this->allowLooseOpenings) { |
|
809 | + while (substr($tpl, $pos, 1) === ' ') { |
|
810 | + $pos += 1; |
|
811 | + } |
|
812 | + } else { |
|
813 | + if (substr($tpl, $pos, 1) === ' ' || substr($tpl, $pos, 1) === "\r" || substr($tpl, $pos, 1) === "\n" || substr($tpl, $pos, 1) === "\t") { |
|
814 | + $ptr = $pos; |
|
815 | + $this->push($this->ld); |
|
816 | + continue; |
|
817 | + } |
|
818 | + } |
|
819 | + |
|
820 | + // check that there is an end tag present |
|
821 | + if (strpos($tpl, $this->rd, $pos) === false) { |
|
822 | + throw new CompilationException($this, 'A template tag was not closed, started with "' . substr($tpl, $ptr, 30) . '"'); |
|
823 | + } |
|
824 | + |
|
825 | + $ptr += strlen($this->ld); |
|
826 | + $subptr = $ptr; |
|
827 | + |
|
828 | + while (true) { |
|
829 | + $parsed = $this->parse($tpl, $subptr, null, false, 'root', $subptr); |
|
830 | + |
|
831 | + // reload loop if the compiler was reset |
|
832 | + if ($ptr === 0) { |
|
833 | + continue 2; |
|
834 | + } |
|
835 | + |
|
836 | + $len = $subptr - $ptr; |
|
837 | + $this->push($parsed, substr_count(substr($tpl, $ptr, $len), "\n")); |
|
838 | + $ptr += $len; |
|
839 | + |
|
840 | + if ($parsed === false) { |
|
841 | + break; |
|
842 | + } |
|
843 | + } |
|
844 | + } |
|
845 | + } |
|
846 | + |
|
847 | + $compiled .= $this->removeBlock('TopLevelBlock'); |
|
848 | + |
|
849 | + if ($this->debug) { |
|
850 | + echo 'PROCESSING POSTPROCESSORS' . "\n"; |
|
851 | + } |
|
852 | + |
|
853 | + foreach ($this->processors['post'] as $postProc) { |
|
854 | + if (is_array($postProc) && isset($postProc['autoload'])) { |
|
855 | + $postProc = $this->loadProcessor($postProc['class'], $postProc['name']); |
|
856 | + } |
|
857 | + if (is_array($postProc) && $postProc[0] instanceof Processor) { |
|
858 | + $compiled = call_user_func($postProc, $compiled); |
|
859 | + } else { |
|
860 | + $compiled = call_user_func($postProc, $this, $compiled); |
|
861 | + } |
|
862 | + } |
|
863 | + unset($postProc); |
|
864 | + |
|
865 | + if ($this->debug) { |
|
866 | + echo 'COMPILATION COMPLETE : MEM USAGE : ' . memory_get_usage() . "\n"; |
|
867 | + } |
|
868 | + |
|
869 | + $output = "<?php\n/* template head */\n"; |
|
870 | + |
|
871 | + // build plugin preloader |
|
872 | + foreach ($this->getUsedPlugins() as $plugin => $type) { |
|
873 | + if ($type & Core::CUSTOM_PLUGIN) { |
|
874 | + continue; |
|
875 | + } |
|
876 | + |
|
877 | + switch ($type) { |
|
878 | + case Core::BLOCK_PLUGIN: |
|
879 | + case Core::CLASS_PLUGIN: |
|
880 | + if (class_exists('Plugin' . $plugin) !== false) { |
|
881 | + $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)". |
|
882 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
883 | + } else { |
|
884 | + $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_BLOCKS . "Plugin" . $plugin . "')===false)". |
|
885 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
886 | + } |
|
887 | + break; |
|
888 | + case Core::FUNC_PLUGIN: |
|
889 | + if (function_exists('Plugin' . $plugin) !== false) { |
|
890 | + $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)". |
|
891 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
892 | + } else { |
|
893 | + $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)". |
|
894 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
895 | + } |
|
896 | + break; |
|
897 | + case Core::SMARTY_MODIFIER: |
|
898 | + $output .= "if (function_exists('smarty_modifier_$plugin')===false)". |
|
899 | + "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
900 | + break; |
|
901 | + case Core::SMARTY_FUNCTION: |
|
902 | + $output .= "if (function_exists('smarty_function_$plugin')===false)". |
|
903 | + "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
904 | + break; |
|
905 | + case Core::SMARTY_BLOCK: |
|
906 | + $output .= "if (function_exists('smarty_block_$plugin')===false)". |
|
907 | + "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
908 | + break; |
|
909 | + case Core::PROXY_PLUGIN: |
|
910 | + $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin); |
|
911 | + break; |
|
912 | + default: |
|
913 | + throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type); |
|
914 | + } |
|
915 | + } |
|
916 | + |
|
917 | + foreach ($this->templatePlugins as $function => $attr) { |
|
918 | + if (isset($attr['called']) && $attr['called'] === true && !isset($attr['checked'])) { |
|
919 | + $this->resolveSubTemplateDependencies($function); |
|
920 | + } |
|
921 | + } |
|
922 | + foreach ($this->templatePlugins as $function) { |
|
923 | + if (isset($function['called']) && $function['called'] === true) { |
|
924 | + $output .= $function['body'] . PHP_EOL; |
|
925 | + } |
|
926 | + } |
|
927 | + |
|
928 | + $output .= $compiled . "\n?>"; |
|
929 | + |
|
930 | + $output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*' . preg_quote(self::PHP_CLOSE, '/') . preg_quote(self::PHP_OPEN, '/') . ')/', ";\n", $output); |
|
931 | + $output = str_replace(self::PHP_CLOSE . self::PHP_OPEN, "\n", $output); |
|
932 | + |
|
933 | + // handle <?xml tag at the beginning |
|
934 | + $output = preg_replace('#(/\* template body \*/ \?>\s*)<\?xml#is', '$1<?php echo \'<?xml\'; ?>', $output); |
|
935 | + |
|
936 | + // add another line break after PHP closing tags that have a line break following, |
|
937 | + // as we do not know whether it's intended, and PHP will strip it otherwise |
|
938 | + $output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0' . "\n", $output); |
|
939 | + |
|
940 | + if ($this->debug) { |
|
941 | + echo '=============================================================================================' . "\n"; |
|
942 | + $lines = preg_split('{\r\n|\n|<br />}', $output); |
|
943 | + array_shift($lines); |
|
944 | + foreach ($lines as $i => $line) { |
|
945 | + echo ($i + 1) . '. ' . $line . "\r\n"; |
|
946 | + } |
|
947 | + echo '=============================================================================================' . "\n"; |
|
948 | + } |
|
949 | + |
|
950 | + $this->template = $this->dwoo = null; |
|
951 | + $tpl = null; |
|
952 | + |
|
953 | + return $output; |
|
954 | + } |
|
955 | + |
|
956 | + /** |
|
957 | + * Checks what sub-templates are used in every sub-template so that we're sure they are all compiled. |
|
958 | + * |
|
959 | + * @param string $function the sub-template name |
|
960 | + */ |
|
961 | + protected function resolveSubTemplateDependencies($function) |
|
962 | + { |
|
963 | + if ($this->debug) { |
|
964 | + echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
965 | + } |
|
966 | + |
|
967 | + $body = $this->templatePlugins[$function]['body']; |
|
968 | + foreach ($this->templatePlugins as $func => $attr) { |
|
969 | + if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS . |
|
970 | + 'Plugin' . Core::toCamelCase($func)) !== false) { |
|
971 | + $this->templatePlugins[$func]['called'] = true; |
|
972 | + $this->resolveSubTemplateDependencies($func); |
|
973 | + } |
|
974 | + } |
|
975 | + $this->templatePlugins[$function]['checked'] = true; |
|
976 | + } |
|
977 | + |
|
978 | + /** |
|
979 | + * Adds compiled content to the current block. |
|
980 | + * |
|
981 | + * @param string $content the content to push |
|
982 | + * @param int $lineCount newlines count in content, optional |
|
983 | + * |
|
984 | + * @throws CompilationException |
|
985 | + */ |
|
986 | + public function push($content, $lineCount = null) |
|
987 | + { |
|
988 | + if ($lineCount === null) { |
|
989 | + $lineCount = substr_count($content, "\n"); |
|
990 | + } |
|
991 | + |
|
992 | + if ($this->curBlock['buffer'] === null && count($this->stack) > 1) { |
|
993 | + // buffer is not initialized yet (the block has just been created) |
|
994 | + $this->stack[count($this->stack) - 2]['buffer'] .= (string)$content; |
|
995 | + $this->curBlock['buffer'] = ''; |
|
996 | + } else { |
|
997 | + if (!isset($this->curBlock['buffer'])) { |
|
998 | + throw new CompilationException($this, 'The template has been closed too early, you probably have an extra block-closing tag somewhere'); |
|
999 | + } |
|
1000 | + // append current content to current block's buffer |
|
1001 | + $this->curBlock['buffer'] .= (string)$content; |
|
1002 | + } |
|
1003 | + $this->line += $lineCount; |
|
1004 | + } |
|
1005 | + |
|
1006 | + /** |
|
1007 | + * Sets the scope. |
|
1008 | + * set to null if the scope becomes "unstable" (i.e. too variable or unknown) so that |
|
1009 | + * variables are compiled in a more evaluative way than just $this->scope['key'] |
|
1010 | + * |
|
1011 | + * @param mixed $scope a string i.e. "level1.level2" or an array i.e. array("level1", "level2") |
|
1012 | + * @param bool $absolute if true, the scope is set from the top level scope and not from the current scope |
|
1013 | + * |
|
1014 | + * @return array the current scope tree |
|
1015 | + */ |
|
1016 | + public function setScope($scope, $absolute = false) |
|
1017 | + { |
|
1018 | + $old = $this->scopeTree; |
|
1019 | + |
|
1020 | + if ($scope === null) { |
|
1021 | + unset($this->scope); |
|
1022 | + $this->scope = null; |
|
1023 | + } |
|
1024 | + |
|
1025 | + if (is_array($scope) === false) { |
|
1026 | + $scope = explode('.', $scope); |
|
1027 | + } |
|
1028 | + |
|
1029 | + if ($absolute === true) { |
|
1030 | + $this->scope = &$this->data; |
|
1031 | + $this->scopeTree = array(); |
|
1032 | + } |
|
1033 | + |
|
1034 | + while (($bit = array_shift($scope)) !== null) { |
|
1035 | + if ($bit === '_parent' || $bit === '_') { |
|
1036 | + array_pop($this->scopeTree); |
|
1037 | + reset($this->scopeTree); |
|
1038 | + $this->scope = &$this->data; |
|
1039 | + $cnt = count($this->scopeTree); |
|
1040 | + for ($i = 0; $i < $cnt; ++ $i) { |
|
1041 | + $this->scope = &$this->scope[$this->scopeTree[$i]]; |
|
1042 | + } |
|
1043 | + } elseif ($bit === '_root' || $bit === '__') { |
|
1044 | + $this->scope = &$this->data; |
|
1045 | + $this->scopeTree = array(); |
|
1046 | + } elseif (isset($this->scope[$bit])) { |
|
1047 | + $this->scope = &$this->scope[$bit]; |
|
1048 | + $this->scopeTree[] = $bit; |
|
1049 | + } else { |
|
1050 | + $this->scope[$bit] = array(); |
|
1051 | + $this->scope = &$this->scope[$bit]; |
|
1052 | + $this->scopeTree[] = $bit; |
|
1053 | + } |
|
1054 | + } |
|
1055 | + |
|
1056 | + return $old; |
|
1057 | + } |
|
1058 | + |
|
1059 | + /** |
|
1060 | + * Adds a block to the top of the block stack. |
|
1061 | + * |
|
1062 | + * @param string $type block type (name) |
|
1063 | + * @param array $params the parameters array |
|
1064 | + * @param int $paramtype the parameters type (see mapParams), 0, 1 or 2 |
|
1065 | + * |
|
1066 | + * @return string the preProcessing() method's output |
|
1067 | + */ |
|
1068 | + public function addBlock($type, array $params, $paramtype) |
|
1069 | + { |
|
1070 | + if ($this->debug) { |
|
1071 | + echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1072 | + } |
|
1073 | + |
|
1074 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type); |
|
1075 | + if (class_exists($class) === false) { |
|
1076 | + $this->getDwoo()->getLoader()->loadPlugin($type); |
|
1077 | + } |
|
1078 | + $params = $this->mapParams($params, array($class, 'init'), $paramtype); |
|
1079 | + |
|
1080 | + $this->stack[] = array( |
|
1081 | + 'type' => $type, |
|
1082 | + 'params' => $params, |
|
1083 | + 'custom' => false, |
|
1084 | + 'class' => $class, |
|
1085 | + 'buffer' => null |
|
1086 | + ); |
|
1087 | + $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1088 | + |
|
1089 | + return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type); |
|
1090 | + } |
|
1091 | + |
|
1092 | + /** |
|
1093 | + * Adds a custom block to the top of the block stack. |
|
1094 | + * |
|
1095 | + * @param string $type block type (name) |
|
1096 | + * @param array $params the parameters array |
|
1097 | + * @param int $paramtype the parameters type (see mapParams), 0, 1 or 2 |
|
1098 | + * |
|
1099 | + * @return string the preProcessing() method's output |
|
1100 | + */ |
|
1101 | + public function addCustomBlock($type, array $params, $paramtype) |
|
1102 | + { |
|
1103 | + $callback = $this->customPlugins[$type]['callback']; |
|
1104 | + if (is_array($callback)) { |
|
1105 | + $class = is_object($callback[0]) ? get_class($callback[0]) : $callback[0]; |
|
1106 | + } else { |
|
1107 | + $class = $callback; |
|
1108 | + } |
|
1109 | + |
|
1110 | + $params = $this->mapParams($params, array($class, 'init'), $paramtype); |
|
1111 | + |
|
1112 | + $this->stack[] = array( |
|
1113 | + 'type' => $type, |
|
1114 | + 'params' => $params, |
|
1115 | + 'custom' => true, |
|
1116 | + 'class' => $class, |
|
1117 | + 'buffer' => null |
|
1118 | + ); |
|
1119 | + $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1120 | + |
|
1121 | + return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type); |
|
1122 | + } |
|
1123 | + |
|
1124 | + /** |
|
1125 | + * Injects a block at the top of the plugin stack without calling its preProcessing method. |
|
1126 | + * used by {else} blocks to re-add themselves after having closed everything up to their parent |
|
1127 | + * |
|
1128 | + * @param string $type block type (name) |
|
1129 | + * @param array $params parameters array |
|
1130 | + */ |
|
1131 | + public function injectBlock($type, array $params) |
|
1132 | + { |
|
1133 | + if ($this->debug) { |
|
1134 | + echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1135 | + } |
|
1136 | + |
|
1137 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type); |
|
1138 | + if (class_exists($class) === false) { |
|
1139 | + $this->getDwoo()->getLoader()->loadPlugin($type); |
|
1140 | + } |
|
1141 | + $this->stack[] = array( |
|
1142 | + 'type' => $type, |
|
1143 | + 'params' => $params, |
|
1144 | + 'custom' => false, |
|
1145 | + 'class' => $class, |
|
1146 | + 'buffer' => null |
|
1147 | + ); |
|
1148 | + $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1149 | + } |
|
1150 | + |
|
1151 | + /** |
|
1152 | + * Removes the closest-to-top block of the given type and all other |
|
1153 | + * blocks encountered while going down the block stack. |
|
1154 | + * |
|
1155 | + * @param string $type block type (name) |
|
1156 | + * |
|
1157 | + * @return string the output of all postProcessing() method's return values of the closed blocks |
|
1158 | + * @throws CompilationException |
|
1159 | + */ |
|
1160 | + public function removeBlock($type) |
|
1161 | + { |
|
1162 | + if ($this->debug) { |
|
1163 | + echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1164 | + } |
|
1165 | + |
|
1166 | + $output = ''; |
|
1167 | + |
|
1168 | + $pluginType = $this->getPluginType($type); |
|
1169 | + if ($pluginType & Core::SMARTY_BLOCK) { |
|
1170 | + $type = 'Smartyinterface'; |
|
1171 | + } |
|
1172 | + while (true) { |
|
1173 | + while ($top = array_pop($this->stack)) { |
|
1174 | + if ($top['custom']) { |
|
1175 | + $class = $top['class']; |
|
1176 | + } else { |
|
1177 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($top['type']); |
|
1178 | + } |
|
1179 | + if (count($this->stack)) { |
|
1180 | + $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1181 | + $this->push(call_user_func(array( |
|
1182 | + $class, |
|
1183 | + 'postProcessing' |
|
1184 | + ), $this, $top['params'], '', '', $top['buffer']), 0); |
|
1185 | + } else { |
|
1186 | + $null = null; |
|
1187 | + $this->curBlock = &$null; |
|
1188 | + $output = call_user_func( |
|
1189 | + array( |
|
1190 | + $class, |
|
1191 | + 'postProcessing' |
|
1192 | + ), $this, $top['params'], '', '', $top['buffer'] |
|
1193 | + ); |
|
1194 | + } |
|
1195 | + |
|
1196 | + if ($top['type'] === $type) { |
|
1197 | + break 2; |
|
1198 | + } |
|
1199 | + } |
|
1200 | + |
|
1201 | + throw new CompilationException($this, 'Syntax malformation, a block of type "' . $type . '" was closed but was not opened'); |
|
1202 | + break; |
|
1203 | + } |
|
1204 | + |
|
1205 | + return $output; |
|
1206 | + } |
|
1207 | + |
|
1208 | + /** |
|
1209 | + * Returns a reference to the first block of the given type encountered and |
|
1210 | + * optionally closes all blocks until it finds it |
|
1211 | + * this is mainly used by {else} plugins to close everything that was opened |
|
1212 | + * between their parent and themselves. |
|
1213 | + * |
|
1214 | + * @param string $type the block type (name) |
|
1215 | + * @param bool $closeAlong whether to close all blocks encountered while going down the block stack or not |
|
1216 | + * |
|
1217 | + * @return mixed &array the array is as such: array('type'=>pluginName, 'params'=>parameter array, |
|
1218 | + * 'custom'=>bool defining whether it's a custom plugin or not, for internal use) |
|
1219 | + * @throws CompilationException |
|
1220 | + */ |
|
1221 | + public function &findBlock($type, $closeAlong = false) |
|
1222 | + { |
|
1223 | + if ($closeAlong === true) { |
|
1224 | + while ($b = end($this->stack)) { |
|
1225 | + if ($b['type'] === $type) { |
|
1226 | + return $this->stack[key($this->stack)]; |
|
1227 | + } |
|
1228 | + $this->push($this->removeTopBlock(), 0); |
|
1229 | + } |
|
1230 | + } else { |
|
1231 | + end($this->stack); |
|
1232 | + while ($b = current($this->stack)) { |
|
1233 | + if ($b['type'] === $type) { |
|
1234 | + return $this->stack[key($this->stack)]; |
|
1235 | + } |
|
1236 | + prev($this->stack); |
|
1237 | + } |
|
1238 | + } |
|
1239 | + |
|
1240 | + throw new CompilationException($this, 'A parent block of type "' . $type . '" is required and can not be found'); |
|
1241 | + } |
|
1242 | + |
|
1243 | + /** |
|
1244 | + * Returns a reference to the current block array. |
|
1245 | + * |
|
1246 | + * @return array the array is as such: array('type'=>pluginName, 'params'=>parameter array, |
|
1247 | + * 'custom'=>bool defining whether it's a custom plugin or not, for internal use) |
|
1248 | + */ |
|
1249 | + public function &getCurrentBlock() |
|
1250 | + { |
|
1251 | + return $this->curBlock; |
|
1252 | + } |
|
1253 | + |
|
1254 | + /** |
|
1255 | + * Removes the block at the top of the stack and calls its postProcessing() method. |
|
1256 | + * |
|
1257 | + * @return string the postProcessing() method's output |
|
1258 | + * @throws CompilationException |
|
1259 | + */ |
|
1260 | + public function removeTopBlock() |
|
1261 | + { |
|
1262 | + if ($this->debug) { |
|
1263 | + echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1264 | + } |
|
1265 | + |
|
1266 | + $o = array_pop($this->stack); |
|
1267 | + if ($o === null) { |
|
1268 | + throw new CompilationException($this, 'Syntax malformation, a block of unknown type was closed but was not opened.'); |
|
1269 | + } |
|
1270 | + if ($o['custom']) { |
|
1271 | + $class = $o['class']; |
|
1272 | + } else { |
|
1273 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($o['type']); |
|
1274 | + } |
|
1275 | + |
|
1276 | + $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1277 | + |
|
1278 | + return call_user_func(array($class, 'postProcessing'), $this, $o['params'], '', '', $o['buffer']); |
|
1279 | + } |
|
1280 | + |
|
1281 | + /** |
|
1282 | + * Returns the compiled parameters (for example a variable's compiled parameter will be "$this->scope['key']") out |
|
1283 | + * of the given parameter array. |
|
1284 | + * |
|
1285 | + * @param array $params parameter array |
|
1286 | + * |
|
1287 | + * @return array filtered parameters |
|
1288 | + */ |
|
1289 | + public function getCompiledParams(array $params) |
|
1290 | + { |
|
1291 | + foreach ($params as $k => $p) { |
|
1292 | + if (is_array($p)) { |
|
1293 | + $params[$k] = $p[0]; |
|
1294 | + } |
|
1295 | + } |
|
1296 | + |
|
1297 | + return $params; |
|
1298 | + } |
|
1299 | + |
|
1300 | + /** |
|
1301 | + * Returns the real parameters (for example a variable's real parameter will be its key, etc) out of the given |
|
1302 | + * parameter array. |
|
1303 | + * |
|
1304 | + * @param array $params parameter array |
|
1305 | + * |
|
1306 | + * @return array filtered parameters |
|
1307 | + */ |
|
1308 | + public function getRealParams(array $params) |
|
1309 | + { |
|
1310 | + foreach ($params as $k => $p) { |
|
1311 | + if (is_array($p)) { |
|
1312 | + $params[$k] = $p[1]; |
|
1313 | + } |
|
1314 | + } |
|
1315 | + |
|
1316 | + return $params; |
|
1317 | + } |
|
1318 | + |
|
1319 | + /** |
|
1320 | + * Returns the token of each parameter out of the given parameter array. |
|
1321 | + * |
|
1322 | + * @param array $params parameter array |
|
1323 | + * |
|
1324 | + * @return array tokens |
|
1325 | + */ |
|
1326 | + public function getParamTokens(array $params) |
|
1327 | + { |
|
1328 | + foreach ($params as $k => $p) { |
|
1329 | + if (is_array($p)) { |
|
1330 | + $params[$k] = isset($p[2]) ? $p[2] : 0; |
|
1331 | + } |
|
1332 | + } |
|
1333 | + |
|
1334 | + return $params; |
|
1335 | + } |
|
1336 | + |
|
1337 | + /** |
|
1338 | + * Entry point of the parser, it redirects calls to other parse* functions. |
|
1339 | + * |
|
1340 | + * @param string $in the string within which we must parse something |
|
1341 | + * @param int $from the starting offset of the parsed area |
|
1342 | + * @param int $to the ending offset of the parsed area |
|
1343 | + * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
1344 | + * default |
|
1345 | + * @param string $curBlock the current parser-block being processed |
|
1346 | + * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
1347 | + * or null by default |
|
1348 | + * |
|
1349 | + * @return string parsed values |
|
1350 | + * @throws CompilationException |
|
1351 | + */ |
|
1352 | + protected function parse($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
1353 | + { |
|
1354 | + if ($this->debug) { |
|
1355 | + echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1356 | + } |
|
1357 | + |
|
1358 | + if ($to === null) { |
|
1359 | + $to = strlen($in); |
|
1360 | + } |
|
1361 | + $first = substr($in, $from, 1); |
|
1362 | + |
|
1363 | + if ($first === false) { |
|
1364 | + throw new CompilationException($this, 'Unexpected EOF, a template tag was not closed'); |
|
1365 | + } |
|
1366 | + |
|
1367 | + while ($first === ' ' || $first === "\n" || $first === "\t" || $first === "\r") { |
|
1368 | + if ($curBlock === 'root' && substr($in, $from, strlen($this->rd)) === $this->rd) { |
|
1369 | + // end template tag |
|
1370 | + $pointer += strlen($this->rd); |
|
1371 | + if ($this->debug) { |
|
1372 | + echo 'TEMPLATE PARSING ENDED' . "\n"; |
|
1373 | + } |
|
1374 | + |
|
1375 | + return false; |
|
1376 | + } |
|
1377 | + ++ $from; |
|
1378 | + if ($pointer !== null) { |
|
1379 | + ++ $pointer; |
|
1380 | + } |
|
1381 | + if ($from >= $to) { |
|
1382 | + if (is_array($parsingParams)) { |
|
1383 | + return $parsingParams; |
|
1384 | + } else { |
|
1385 | + return ''; |
|
1386 | + } |
|
1387 | + } |
|
1388 | + $first = $in[$from]; |
|
1389 | + } |
|
1390 | + |
|
1391 | + $substr = substr($in, $from, $to - $from); |
|
1392 | + |
|
1393 | + if ($this->debug) { |
|
1394 | + echo 'PARSE CALL : PARSING "<b>' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . '</b>" @ ' . $from . ':' . $to . ' in ' . $curBlock . ' : pointer=' . $pointer . "\n"; |
|
1395 | + } |
|
1396 | + $parsed = ''; |
|
1397 | + |
|
1398 | + if ($curBlock === 'root' && $first === '*') { |
|
1399 | + $src = $this->getTemplateSource(); |
|
1400 | + $startpos = $this->getPointer() - strlen($this->ld); |
|
1401 | + if (substr($src, $startpos, strlen($this->ld)) === $this->ld) { |
|
1402 | + if ($startpos > 0) { |
|
1403 | + do { |
|
1404 | + $char = substr($src, -- $startpos, 1); |
|
1405 | + if ($char == "\n") { |
|
1406 | + ++ $startpos; |
|
1407 | + $whitespaceStart = true; |
|
1408 | + break; |
|
1409 | + } |
|
1410 | + } |
|
1411 | + while ($startpos > 0 && ($char == ' ' || $char == "\t")); |
|
1412 | + } |
|
1413 | + |
|
1414 | + if (!isset($whitespaceStart)) { |
|
1415 | + $startpos = $this->getPointer(); |
|
1416 | + } else { |
|
1417 | + $pointer -= $this->getPointer() - $startpos; |
|
1418 | + } |
|
1419 | + |
|
1420 | + if ($this->allowNestedComments && strpos($src, $this->ld . '*', $this->getPointer()) !== false) { |
|
1421 | + $comOpen = $this->ld . '*'; |
|
1422 | + $comClose = '*' . $this->rd; |
|
1423 | + $level = 1; |
|
1424 | + $ptr = $this->getPointer(); |
|
1425 | + |
|
1426 | + while ($level > 0 && $ptr < strlen($src)) { |
|
1427 | + $open = strpos($src, $comOpen, $ptr); |
|
1428 | + $close = strpos($src, $comClose, $ptr); |
|
1429 | + |
|
1430 | + if ($open !== false && $close !== false) { |
|
1431 | + if ($open < $close) { |
|
1432 | + $ptr = $open + strlen($comOpen); |
|
1433 | + ++ $level; |
|
1434 | + } else { |
|
1435 | + $ptr = $close + strlen($comClose); |
|
1436 | + -- $level; |
|
1437 | + } |
|
1438 | + } elseif ($open !== false) { |
|
1439 | + $ptr = $open + strlen($comOpen); |
|
1440 | + ++ $level; |
|
1441 | + } elseif ($close !== false) { |
|
1442 | + $ptr = $close + strlen($comClose); |
|
1443 | + -- $level; |
|
1444 | + } else { |
|
1445 | + $ptr = strlen($src); |
|
1446 | + } |
|
1447 | + } |
|
1448 | + $endpos = $ptr - strlen('*' . $this->rd); |
|
1449 | + } else { |
|
1450 | + $endpos = strpos($src, '*' . $this->rd, $startpos); |
|
1451 | + if ($endpos == false) { |
|
1452 | + throw new CompilationException($this, 'Un-ended comment'); |
|
1453 | + } |
|
1454 | + } |
|
1455 | + $pointer += $endpos - $startpos + strlen('*' . $this->rd); |
|
1456 | + if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos + strlen('*' . $this->rd)), $m)) { |
|
1457 | + $pointer += strlen($m[0]); |
|
1458 | + $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer']) - ($this->getPointer() - $startpos - strlen($this->ld))); |
|
1459 | + } |
|
1460 | + |
|
1461 | + return false; |
|
1462 | + } |
|
1463 | + } |
|
1464 | + |
|
1465 | + if ($first === '$') { |
|
1466 | + // var |
|
1467 | + $out = $this->parseVar($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1468 | + $parsed = 'var'; |
|
1469 | + } elseif ($first === '%' && preg_match('#^%[a-z_\\\\]#i', $substr)) { |
|
1470 | + // Short constant |
|
1471 | + $out = $this->parseConst($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1472 | + } elseif (($first === '"' || $first === "'") && !(is_array($parsingParams) && preg_match('#^([\'"])[a-z0-9_]+\1\s*=>?(?:\s+|[^=])#i', $substr))) { |
|
1473 | + // string |
|
1474 | + $out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1475 | + } elseif (preg_match('/^\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?(' . (is_array($parsingParams) || $curBlock != 'root' ? '' : '\s+[^(]|') . '\s*\(|\s*' . $this->rdr . '|\s*;)/i', $substr)) { |
|
1476 | + // func |
|
1477 | + $out = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1478 | + $parsed = 'func'; |
|
1479 | + } elseif ($first === ';') { |
|
1480 | + // instruction end |
|
1481 | + if ($this->debug) { |
|
1482 | + echo 'END OF INSTRUCTION' . "\n"; |
|
1483 | + } |
|
1484 | + if ($pointer !== null) { |
|
1485 | + ++ $pointer; |
|
1486 | + } |
|
1487 | + |
|
1488 | + return $this->parse($in, $from + 1, $to, false, 'root', $pointer); |
|
1489 | + } elseif ($curBlock === 'root' && preg_match('#^/([a-z_][a-z0-9_]*)?#i', $substr, $match)) { |
|
1490 | + // close block |
|
1491 | + if (!empty($match[1]) && $match[1] == 'else') { |
|
1492 | + throw new CompilationException($this, 'Else blocks must not be closed explicitly, they are automatically closed when their parent block is closed'); |
|
1493 | + } |
|
1494 | + if (!empty($match[1]) && $match[1] == 'elseif') { |
|
1495 | + throw new CompilationException($this, 'Elseif blocks must not be closed explicitly, they are automatically closed when their parent block is closed or a new else/elseif block is declared after them'); |
|
1496 | + } |
|
1497 | + if ($pointer !== null) { |
|
1498 | + $pointer += strlen($match[0]); |
|
1499 | + } |
|
1500 | + if (empty($match[1])) { |
|
1501 | + if ($this->curBlock['type'] == 'else' || $this->curBlock['type'] == 'elseif') { |
|
1502 | + $pointer -= strlen($match[0]); |
|
1503 | + } |
|
1504 | + if ($this->debug) { |
|
1505 | + echo 'TOP BLOCK CLOSED' . "\n"; |
|
1506 | + } |
|
1507 | + |
|
1508 | + return $this->removeTopBlock(); |
|
1509 | + } else { |
|
1510 | + if ($this->debug) { |
|
1511 | + echo 'BLOCK OF TYPE ' . $match[1] . ' CLOSED' . "\n"; |
|
1512 | + } |
|
1513 | + |
|
1514 | + return $this->removeBlock($match[1]); |
|
1515 | + } |
|
1516 | + } elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) { |
|
1517 | + // end template tag |
|
1518 | + if ($this->debug) { |
|
1519 | + echo 'TAG PARSING ENDED' . "\n"; |
|
1520 | + } |
|
1521 | + $pointer += strlen($this->rd); |
|
1522 | + |
|
1523 | + return false; |
|
1524 | + } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*=' . ($curBlock === 'array' ? '>?' : '') . ')(?:\s+|[^=]).*#i', $substr, $match)) { |
|
1525 | + // named parameter |
|
1526 | + if ($this->debug) { |
|
1527 | + echo 'NAMED PARAM FOUND' . "\n"; |
|
1528 | + } |
|
1529 | + $len = strlen($match[1]); |
|
1530 | + while (substr($in, $from + $len, 1) === ' ') { |
|
1531 | + ++ $len; |
|
1532 | + } |
|
1533 | + if ($pointer !== null) { |
|
1534 | + $pointer += $len; |
|
1535 | + } |
|
1536 | + |
|
1537 | + $output = array( |
|
1538 | + trim($match[1], " \t\r\n=>'\""), |
|
1539 | + $this->parse($in, $from + $len, $to, false, 'namedparam', $pointer) |
|
1540 | + ); |
|
1541 | + |
|
1542 | + $parsingParams[] = $output; |
|
1543 | + |
|
1544 | + return $parsingParams; |
|
1545 | + } elseif (preg_match('#^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*::\$[a-z0-9_]+)#i', $substr, $match)) { |
|
1546 | + // static member access |
|
1547 | + $parsed = 'var'; |
|
1548 | + if (is_array($parsingParams)) { |
|
1549 | + $parsingParams[] = array($match[1], $match[1]); |
|
1550 | + $out = $parsingParams; |
|
1551 | + } else { |
|
1552 | + $out = $match[1]; |
|
1553 | + } |
|
1554 | + $pointer += strlen($match[1]); |
|
1555 | + } elseif ($substr !== '' && (is_array($parsingParams) || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'expression')) { |
|
1556 | + // unquoted string, bool or number |
|
1557 | + $out = $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1558 | + } else { |
|
1559 | + // parse error |
|
1560 | + throw new CompilationException($this, 'Parse error in "' . substr($in, $from, $to - $from) . '"'); |
|
1561 | + } |
|
1562 | + |
|
1563 | + if (empty($out)) { |
|
1564 | + return ''; |
|
1565 | + } |
|
1566 | + |
|
1567 | + $substr = substr($in, $pointer, $to - $pointer); |
|
1568 | + |
|
1569 | + // var parsed, check if any var-extension applies |
|
1570 | + if ($parsed === 'var') { |
|
1571 | + if (preg_match('#^\s*([/%+*-])\s*([a-z0-9]|\$)#i', $substr, $match)) { |
|
1572 | + if ($this->debug) { |
|
1573 | + echo 'PARSING POST-VAR EXPRESSION ' . $substr . "\n"; |
|
1574 | + } |
|
1575 | + // parse expressions |
|
1576 | + $pointer += strlen($match[0]) - 1; |
|
1577 | + if (is_array($parsingParams)) { |
|
1578 | + if ($match[2] == '$') { |
|
1579 | + $expr = $this->parseVar($in, $pointer, $to, array(), $curBlock, $pointer); |
|
1580 | + } else { |
|
1581 | + $expr = $this->parse($in, $pointer, $to, array(), 'expression', $pointer); |
|
1582 | + } |
|
1583 | + $out[count($out) - 1][0] .= $match[1] . $expr[0][0]; |
|
1584 | + $out[count($out) - 1][1] .= $match[1] . $expr[0][1]; |
|
1585 | + } else { |
|
1586 | + if ($match[2] == '$') { |
|
1587 | + $expr = $this->parseVar($in, $pointer, $to, false, $curBlock, $pointer); |
|
1588 | + } else { |
|
1589 | + $expr = $this->parse($in, $pointer, $to, false, 'expression', $pointer); |
|
1590 | + } |
|
1591 | + if (is_array($out) && is_array($expr)) { |
|
1592 | + $out[0] .= $match[1] . $expr[0]; |
|
1593 | + $out[1] .= $match[1] . $expr[1]; |
|
1594 | + } elseif (is_array($out)) { |
|
1595 | + $out[0] .= $match[1] . $expr; |
|
1596 | + $out[1] .= $match[1] . $expr; |
|
1597 | + } elseif (is_array($expr)) { |
|
1598 | + $out .= $match[1] . $expr[0]; |
|
1599 | + } else { |
|
1600 | + $out .= $match[1] . $expr; |
|
1601 | + } |
|
1602 | + } |
|
1603 | + } elseif ($curBlock === 'root' && preg_match('#^(\s*(?:[+/*%-.]=|=|\+\+|--)\s*)(.*)#s', $substr, $match)) { |
|
1604 | + if ($this->debug) { |
|
1605 | + echo 'PARSING POST-VAR ASSIGNMENT ' . $substr . "\n"; |
|
1606 | + } |
|
1607 | + // parse assignment |
|
1608 | + $value = $match[2]; |
|
1609 | + $operator = trim($match[1]); |
|
1610 | + if (substr($value, 0, 1) == '=') { |
|
1611 | + throw new CompilationException($this, 'Unexpected "=" in <em>' . $substr . '</em>'); |
|
1612 | + } |
|
1613 | + |
|
1614 | + if ($pointer !== null) { |
|
1615 | + $pointer += strlen($match[1]); |
|
1616 | + } |
|
1617 | + |
|
1618 | + if ($operator !== '++' && $operator !== '--') { |
|
1619 | + $parts = array(); |
|
1620 | + $ptr = 0; |
|
1621 | + $parts = $this->parse($value, 0, strlen($value), $parts, 'condition', $ptr); |
|
1622 | + $pointer += $ptr; |
|
1623 | + |
|
1624 | + // load if plugin |
|
1625 | + try { |
|
1626 | + $this->getPluginType('if'); |
|
1627 | + } |
|
1628 | + catch (Exception $e) { |
|
1629 | + throw new CompilationException($this, 'Assignments require the "if" plugin to be accessible'); |
|
1630 | + } |
|
1631 | + |
|
1632 | + $parts = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS . 'PluginIf', 'init'), 1); |
|
1633 | + $tokens = $this->getParamTokens($parts); |
|
1634 | + $parts = $this->getCompiledParams($parts); |
|
1635 | + |
|
1636 | + $value = PluginIf::replaceKeywords($parts['*'], $tokens['*'], $this); |
|
1637 | + $echo = ''; |
|
1638 | + } else { |
|
1639 | + $value = array(); |
|
1640 | + $echo = 'echo '; |
|
1641 | + } |
|
1642 | + |
|
1643 | + if ($this->autoEscape) { |
|
1644 | + $out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out); |
|
1645 | + } |
|
1646 | + $out = self::PHP_OPEN . $echo . $out . $operator . implode(' ', $value) . self::PHP_CLOSE; |
|
1647 | + } elseif ($curBlock === 'array' && is_array($parsingParams) && preg_match('#^(\s*=>?\s*)#', $substr, $match)) { |
|
1648 | + // parse namedparam with var as name (only for array) |
|
1649 | + if ($this->debug) { |
|
1650 | + echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND' . "\n"; |
|
1651 | + } |
|
1652 | + $len = strlen($match[1]); |
|
1653 | + $var = $out[count($out) - 1]; |
|
1654 | + $pointer += $len; |
|
1655 | + |
|
1656 | + $output = array($var[0], $this->parse($substr, $len, null, false, 'namedparam', $pointer)); |
|
1657 | + |
|
1658 | + $parsingParams[] = $output; |
|
1659 | + |
|
1660 | + return $parsingParams; |
|
1661 | + } |
|
1662 | + } |
|
1663 | + |
|
1664 | + if ($curBlock !== 'modifier' && ($parsed === 'func' || $parsed === 'var') && preg_match('#^(\|@?[a-z0-9_]+(:.*)?)+#i', $substr, $match)) { |
|
1665 | + // parse modifier on funcs or vars |
|
1666 | + $srcPointer = $pointer; |
|
1667 | + if (is_array($parsingParams)) { |
|
1668 | + $tmp = $this->replaceModifiers( |
|
1669 | + array( |
|
1670 | + null, |
|
1671 | + null, |
|
1672 | + $out[count($out) - 1][0], |
|
1673 | + $match[0] |
|
1674 | + ), $curBlock, $pointer |
|
1675 | + ); |
|
1676 | + $out[count($out) - 1][0] = $tmp; |
|
1677 | + $out[count($out) - 1][1] .= substr($substr, $srcPointer, $srcPointer - $pointer); |
|
1678 | + } else { |
|
1679 | + $out = $this->replaceModifiers(array(null, null, $out, $match[0]), $curBlock, $pointer); |
|
1680 | + } |
|
1681 | + } |
|
1682 | + |
|
1683 | + // func parsed, check if any func-extension applies |
|
1684 | + if ($parsed === 'func' && preg_match('#^->[a-z0-9_]+(\s*\(.+|->[a-z_].*)?#is', $substr, $match)) { |
|
1685 | + // parse method call or property read |
|
1686 | + $ptr = 0; |
|
1687 | + |
|
1688 | + if (is_array($parsingParams)) { |
|
1689 | + $output = $this->parseMethodCall($out[count($out) - 1][1], $match[0], $curBlock, $ptr); |
|
1690 | + |
|
1691 | + $out[count($out) - 1][0] = $output; |
|
1692 | + $out[count($out) - 1][1] .= substr($match[0], 0, $ptr); |
|
1693 | + } else { |
|
1694 | + $out = $this->parseMethodCall($out, $match[0], $curBlock, $ptr); |
|
1695 | + } |
|
1696 | + |
|
1697 | + $pointer += $ptr; |
|
1698 | + } |
|
1699 | + |
|
1700 | + if ($curBlock === 'root' && substr($out, 0, strlen(self::PHP_OPEN)) !== self::PHP_OPEN) { |
|
1701 | + return self::PHP_OPEN . 'echo ' . $out . ';' . self::PHP_CLOSE; |
|
1702 | + } else { |
|
1703 | + return $out; |
|
1704 | + } |
|
1705 | + } |
|
1706 | + |
|
1707 | + /** |
|
1708 | + * Parses a function call. |
|
1709 | + * |
|
1710 | + * @param string $in the string within which we must parse something |
|
1711 | + * @param int $from the starting offset of the parsed area |
|
1712 | + * @param int $to the ending offset of the parsed area |
|
1713 | + * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
1714 | + * default |
|
1715 | + * @param string $curBlock the current parser-block being processed |
|
1716 | + * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
1717 | + * or null by default |
|
1718 | + * |
|
1719 | + * @return string parsed values |
|
1720 | + * @throws CompilationException |
|
1721 | + * @throws Exception |
|
1722 | + * @throws SecurityException |
|
1723 | + */ |
|
1724 | + protected function parseFunction($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
1725 | + { |
|
1726 | + $output = ''; |
|
1727 | + $cmdstr = substr($in, $from, $to - $from); |
|
1728 | + preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*' . $this->rdr . '|\s*;)?/i', $cmdstr, $match); |
|
1729 | + |
|
1730 | + if (empty($match[1])) { |
|
1731 | + throw new CompilationException($this, 'Parse error, invalid function name : ' . substr($cmdstr, 0, 15)); |
|
1732 | + } |
|
1733 | + |
|
1734 | + $func = $match[1]; |
|
1735 | + |
|
1736 | + if (!empty($match[2])) { |
|
1737 | + $cmdstr = $match[1]; |
|
1738 | + } |
|
1739 | + |
|
1740 | + if ($this->debug) { |
|
1741 | + echo 'FUNC FOUND (' . $func . ')' . "\n"; |
|
1742 | + } |
|
1743 | + |
|
1744 | + $paramsep = ''; |
|
1745 | + |
|
1746 | + if (is_array($parsingParams) || $curBlock != 'root') { |
|
1747 | + $paramspos = strpos($cmdstr, '('); |
|
1748 | + $paramsep = ')'; |
|
1749 | + } elseif (preg_match_all('#^\s*[\\\\:a-z0-9_]+(\s*\(|\s+[^(])#i', $cmdstr, $match, PREG_OFFSET_CAPTURE)) { |
|
1750 | + $paramspos = $match[1][0][1]; |
|
1751 | + $paramsep = substr($match[1][0][0], - 1) === '(' ? ')' : ''; |
|
1752 | + if ($paramsep === ')') { |
|
1753 | + $paramspos += strlen($match[1][0][0]) - 1; |
|
1754 | + if (substr($cmdstr, 0, 2) === 'if' || substr($cmdstr, 0, 6) === 'elseif') { |
|
1755 | + $paramsep = ''; |
|
1756 | + if (strlen($match[1][0][0]) > 1) { |
|
1757 | + -- $paramspos; |
|
1758 | + } |
|
1759 | + } |
|
1760 | + } |
|
1761 | + } else { |
|
1762 | + $paramspos = false; |
|
1763 | + } |
|
1764 | + |
|
1765 | + $state = 0; |
|
1766 | + |
|
1767 | + if ($paramspos === false) { |
|
1768 | + $params = array(); |
|
1769 | + |
|
1770 | + if ($curBlock !== 'root') { |
|
1771 | + return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1772 | + } |
|
1773 | + } else { |
|
1774 | + if ($curBlock === 'condition') { |
|
1775 | + // load if plugin |
|
1776 | + $this->getPluginType('if'); |
|
1777 | + |
|
1778 | + if (PluginIf::replaceKeywords(array($func), array(self::T_UNQUOTED_STRING), $this) !== array($func)) { |
|
1779 | + return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
|
1780 | + } |
|
1781 | + } |
|
1782 | + $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos - strlen($func))); |
|
1783 | + $paramstr = substr($cmdstr, $paramspos + 1); |
|
1784 | + if (substr($paramstr, - 1, 1) === $paramsep) { |
|
1785 | + $paramstr = substr($paramstr, 0, - 1); |
|
1786 | + } |
|
1787 | + |
|
1788 | + if (strlen($paramstr) === 0) { |
|
1789 | + $params = array(); |
|
1790 | + $paramstr = ''; |
|
1791 | + } else { |
|
1792 | + $ptr = 0; |
|
1793 | + $params = array(); |
|
1794 | + if ($func === 'empty') { |
|
1795 | + $params = $this->parseVar($paramstr, $ptr, strlen($paramstr), $params, 'root', $ptr); |
|
1796 | + } else { |
|
1797 | + while ($ptr < strlen($paramstr)) { |
|
1798 | + while (true) { |
|
1799 | + if ($ptr >= strlen($paramstr)) { |
|
1800 | + break 2; |
|
1801 | + } |
|
1802 | + |
|
1803 | + if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') { |
|
1804 | + if ($this->debug) { |
|
1805 | + echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1806 | + } |
|
1807 | + break 2; |
|
1808 | + } elseif ($paramstr[$ptr] === ';') { |
|
1809 | + ++ $ptr; |
|
1810 | + if ($this->debug) { |
|
1811 | + echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1812 | + } |
|
1813 | + break 2; |
|
1814 | + } elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') { |
|
1815 | + if ($this->debug) { |
|
1816 | + echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1817 | + } |
|
1818 | + break 2; |
|
1819 | + } elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) { |
|
1820 | + if ($this->debug) { |
|
1821 | + echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT ' . $ptr . "\n"; |
|
1822 | + } |
|
1823 | + break 2; |
|
1824 | + } |
|
1825 | + |
|
1826 | + if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") { |
|
1827 | + ++ $ptr; |
|
1828 | + } else { |
|
1829 | + break; |
|
1830 | + } |
|
1831 | + } |
|
1832 | + |
|
1833 | + if ($this->debug) { |
|
1834 | + echo 'FUNC START PARAM PARSING WITH POINTER AT ' . $ptr . "\n"; |
|
1835 | + } |
|
1836 | + |
|
1837 | + if ($func === 'if' || $func === 'elseif' || $func === 'tif') { |
|
1838 | + $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'condition', $ptr); |
|
1839 | + } elseif ($func === 'array') { |
|
1840 | + $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'array', $ptr); |
|
1841 | + } else { |
|
1842 | + $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'function', $ptr); |
|
1843 | + } |
|
1844 | + |
|
1845 | + if ($this->debug) { |
|
1846 | + echo 'PARAM PARSED, POINTER AT ' . $ptr . ' (' . substr($paramstr, $ptr - 1, 3) . ')' . "\n"; |
|
1847 | + } |
|
1848 | + } |
|
1849 | + } |
|
1850 | + $paramstr = substr($paramstr, 0, $ptr); |
|
1851 | + $state = 0; |
|
1852 | + foreach ($params as $k => $p) { |
|
1853 | + if (is_array($p) && is_array($p[1])) { |
|
1854 | + $state |= 2; |
|
1855 | + } else { |
|
1856 | + if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m) && $func !== 'array') { |
|
1857 | + $params[$k] = array($m[2], array('true', 'true')); |
|
1858 | + } else { |
|
1859 | + if ($state & 2 && $func !== 'array') { |
|
1860 | + throw new CompilationException($this, 'You can not use an unnamed parameter after a named one'); |
|
1861 | + } |
|
1862 | + $state |= 1; |
|
1863 | + } |
|
1864 | + } |
|
1865 | + } |
|
1866 | + } |
|
1867 | + } |
|
1868 | + |
|
1869 | + if ($pointer !== null) { |
|
1870 | + $pointer += (isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func) + (isset($whitespace) ? $whitespace : 0); |
|
1871 | + if ($this->debug) { |
|
1872 | + echo 'FUNC ADDS ' . ((isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func)) . ' TO POINTER' . "\n"; |
|
1873 | + } |
|
1874 | + } |
|
1875 | + |
|
1876 | + if ($curBlock === 'method' || $func === 'do' || strstr($func, '::') !== false) { |
|
1877 | + // handle static method calls with security policy |
|
1878 | + if (strstr($func, '::') !== false && $this->securityPolicy !== null && $this->securityPolicy->isMethodAllowed(explode('::', strtolower($func))) !== true) { |
|
1879 | + throw new SecurityException('Call to a disallowed php function : ' . $func); |
|
1880 | + } |
|
1881 | + $pluginType = Core::NATIVE_PLUGIN; |
|
1882 | + } else { |
|
1883 | + $pluginType = $this->getPluginType($func); |
|
1884 | + } |
|
1885 | + |
|
1886 | + // Blocks plugin |
|
1887 | + if ($pluginType & Core::BLOCK_PLUGIN) { |
|
1888 | + if ($curBlock !== 'root' || is_array($parsingParams)) { |
|
1889 | + throw new CompilationException($this, 'Block plugins can not be used as other plugin\'s arguments'); |
|
1890 | + } |
|
1891 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
1892 | + return $this->addCustomBlock($func, $params, $state); |
|
1893 | + } else { |
|
1894 | + return $this->addBlock($func, $params, $state); |
|
1895 | + } |
|
1896 | + } elseif ($pluginType & Core::SMARTY_BLOCK) { |
|
1897 | + if ($curBlock !== 'root' || is_array($parsingParams)) { |
|
1898 | + throw new CompilationException($this, 'Block plugins can not be used as other plugin\'s arguments'); |
|
1899 | + } |
|
1900 | + |
|
1901 | + if ($state & 2) { |
|
1902 | + array_unshift($params, array('__functype', array($pluginType, $pluginType))); |
|
1903 | + array_unshift($params, array('__funcname', array($func, $func))); |
|
1904 | + } else { |
|
1905 | + array_unshift($params, array($pluginType, $pluginType)); |
|
1906 | + array_unshift($params, array($func, $func)); |
|
1907 | + } |
|
1908 | + |
|
1909 | + return $this->addBlock('smartyinterface', $params, $state); |
|
1910 | + } |
|
1911 | + |
|
1912 | + // Functions plugin |
|
1913 | + if ($pluginType & Core::NATIVE_PLUGIN || $pluginType & Core::SMARTY_FUNCTION || $pluginType & Core::SMARTY_BLOCK) { |
|
1914 | + $params = $this->mapParams($params, null, $state); |
|
1915 | + } elseif ($pluginType & Core::CLASS_PLUGIN) { |
|
1916 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
1917 | + $params = $this->mapParams( |
|
1918 | + $params, array( |
|
1919 | + $this->customPlugins[$func]['class'], |
|
1920 | + $this->customPlugins[$func]['function'] |
|
1921 | + ), $state); |
|
1922 | + } else { |
|
1923 | + if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
1924 | + $params = $this->mapParams($params, array( |
|
1925 | + 'Plugin' . Core::toCamelCase($func), |
|
1926 | + ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process' |
|
1927 | + ), $state); |
|
1928 | + } else { |
|
1929 | + $params = $this->mapParams($params, array( |
|
1930 | + Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
1931 | + ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process' |
|
1932 | + ), $state); |
|
1933 | + } |
|
1934 | + } |
|
1935 | + } elseif ($pluginType & Core::FUNC_PLUGIN) { |
|
1936 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
1937 | + $params = $this->mapParams($params, $this->customPlugins[$func]['callback'], $state); |
|
1938 | + } else { |
|
1939 | + // Custom plugin |
|
1940 | + if (function_exists('Plugin' . Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? |
|
1941 | + 'Compile' : '')) !== false) { |
|
1942 | + $params = $this->mapParams($params, 'Plugin' . Core::toCamelCase($func) . (($pluginType & |
|
1943 | + Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1944 | + } // Builtin helper plugin |
|
1945 | + elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . ( |
|
1946 | + ($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) !== false) { |
|
1947 | + $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase |
|
1948 | + ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1949 | + } // Builtin function plugin |
|
1950 | + else { |
|
1951 | + $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase |
|
1952 | + ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1953 | + } |
|
1954 | + } |
|
1955 | + } elseif ($pluginType & Core::SMARTY_MODIFIER) { |
|
1956 | + $output = 'smarty_modifier_' . $func . '(' . implode(', ', $params) . ')'; |
|
1957 | + } elseif ($pluginType & Core::PROXY_PLUGIN) { |
|
1958 | + $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state); |
|
1959 | + } elseif ($pluginType & Core::TEMPLATE_PLUGIN) { |
|
1960 | + // transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values)) |
|
1961 | + $map = array(); |
|
1962 | + foreach ($this->templatePlugins[$func]['params'] as $param => $defValue) { |
|
1963 | + if ($param == 'rest') { |
|
1964 | + $param = '*'; |
|
1965 | + } |
|
1966 | + $hasDefault = $defValue !== null; |
|
1967 | + if ($defValue === 'null') { |
|
1968 | + $defValue = null; |
|
1969 | + } elseif ($defValue === 'false') { |
|
1970 | + $defValue = false; |
|
1971 | + } elseif ($defValue === 'true') { |
|
1972 | + $defValue = true; |
|
1973 | + } elseif (preg_match('#^([\'"]).*?\1$#', $defValue)) { |
|
1974 | + $defValue = substr($defValue, 1, - 1); |
|
1975 | + } |
|
1976 | + $map[] = array($param, $hasDefault, $defValue); |
|
1977 | + } |
|
1978 | + |
|
1979 | + $params = $this->mapParams($params, null, $state, $map); |
|
1980 | + } |
|
1981 | + |
|
1982 | + // only keep php-syntax-safe values for non-block plugins |
|
1983 | + $tokens = array(); |
|
1984 | + foreach ($params as $k => $p) { |
|
1985 | + $tokens[$k] = isset($p[2]) ? $p[2] : 0; |
|
1986 | + $params[$k] = $p[0]; |
|
1987 | + } |
|
1988 | + if ($pluginType & Core::NATIVE_PLUGIN) { |
|
1989 | + if ($func === 'do') { |
|
1990 | + if (isset($params['*'])) { |
|
1991 | + $output = implode(';', $params['*']) . ';'; |
|
1992 | + } else { |
|
1993 | + $output = ''; |
|
1994 | + } |
|
1995 | + |
|
1996 | + if (is_array($parsingParams) || $curBlock !== 'root') { |
|
1997 | + throw new CompilationException($this, 'Do can not be used inside another function or block'); |
|
1998 | + } else { |
|
1999 | + return self::PHP_OPEN . $output . self::PHP_CLOSE; |
|
2000 | + } |
|
2001 | + } else { |
|
2002 | + if (isset($params['*'])) { |
|
2003 | + $output = $func . '(' . implode(', ', $params['*']) . ')'; |
|
2004 | + } else { |
|
2005 | + $output = $func . '()'; |
|
2006 | + } |
|
2007 | + } |
|
2008 | + } elseif ($pluginType & Core::FUNC_PLUGIN) { |
|
2009 | + if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
2010 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2011 | + $funcCompiler = $this->customPlugins[$func]['callback']; |
|
2012 | + } else { |
|
2013 | + // Custom plugin |
|
2014 | + if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) { |
|
2015 | + $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile'; |
|
2016 | + } // Builtin helper plugin |
|
2017 | + elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . |
|
2018 | + 'Compile') !== false) { |
|
2019 | + $funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . |
|
2020 | + 'Compile'; |
|
2021 | + } // Builtin function plugin |
|
2022 | + else { |
|
2023 | + $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . |
|
2024 | + 'Compile'; |
|
2025 | + } |
|
2026 | + } |
|
2027 | + array_unshift($params, $this); |
|
2028 | + if ($func === 'tif') { |
|
2029 | + $params[] = $tokens; |
|
2030 | + } |
|
2031 | + $output = call_user_func_array($funcCompiler, $params); |
|
2032 | + } else { |
|
2033 | + array_unshift($params, '$this'); |
|
2034 | + $params = self::implode_r($params); |
|
2035 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2036 | + $callback = $this->customPlugins[$func]['callback']; |
|
2037 | + if ($callback instanceof Closure) { |
|
2038 | + $output = 'call_user_func($this->getCustomPlugin(\'' . $func . '\'), ' . $params . ')'; |
|
2039 | + } else { |
|
2040 | + $output = 'call_user_func(\'' . $callback . '\', ' . $params . ')'; |
|
2041 | + } |
|
2042 | + } else { |
|
2043 | + // Custom plugin |
|
2044 | + if (function_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2045 | + $output = 'Plugin' . Core::toCamelCase($func) . '(' . $params . |
|
2046 | + ')'; |
|
2047 | + } // Builtin helper plugin |
|
2048 | + elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== |
|
2049 | + false) { |
|
2050 | + $output = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . '(' . |
|
2051 | + $params . ')'; |
|
2052 | + } // Builtin function plugin |
|
2053 | + else { |
|
2054 | + $output = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '(' . |
|
2055 | + $params . ')'; |
|
2056 | + } |
|
2057 | + } |
|
2058 | + } |
|
2059 | + } elseif ($pluginType & Core::CLASS_PLUGIN) { |
|
2060 | + if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
2061 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2062 | + $callback = $this->customPlugins[$func]['callback']; |
|
2063 | + if (!is_array($callback)) { |
|
2064 | + if (!method_exists($callback, 'compile')) { |
|
2065 | + throw new Exception('Custom plugin ' . $func . ' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
2066 | + } |
|
2067 | + if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) { |
|
2068 | + $funcCompiler = array($callback, 'compile'); |
|
2069 | + } else { |
|
2070 | + $funcCompiler = array(new $callback(), 'compile'); |
|
2071 | + } |
|
2072 | + } else { |
|
2073 | + $funcCompiler = $callback; |
|
2074 | + } |
|
2075 | + } else { |
|
2076 | + if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2077 | + $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile'); |
|
2078 | + } else { |
|
2079 | + $funcCompiler = array( |
|
2080 | + Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
2081 | + 'compile' |
|
2082 | + ); |
|
2083 | + } |
|
2084 | + array_unshift($params, $this); |
|
2085 | + } |
|
2086 | + $output = call_user_func_array($funcCompiler, $params); |
|
2087 | + } else { |
|
2088 | + $params = self::implode_r($params); |
|
2089 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2090 | + $callback = $this->customPlugins[$func]['callback']; |
|
2091 | + if (!is_array($callback)) { |
|
2092 | + if (!method_exists($callback, 'process')) { |
|
2093 | + throw new Exception('Custom plugin ' . $func . ' must implement the "process" method to be usable, or you should provide a full callback to the method to use'); |
|
2094 | + } |
|
2095 | + if (($ref = new ReflectionMethod($callback, 'process')) && $ref->isStatic()) { |
|
2096 | + $output = 'call_user_func(array(\'' . $callback . '\', \'process\'), ' . $params . ')'; |
|
2097 | + } else { |
|
2098 | + $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback . '\'), \'process\'), ' . $params . ')'; |
|
2099 | + } |
|
2100 | + } elseif (is_object($callback[0])) { |
|
2101 | + $output = 'call_user_func(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2102 | + } elseif (($ref = new ReflectionMethod($callback[0], $callback[1])) && $ref->isStatic()) { |
|
2103 | + $output = 'call_user_func(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2104 | + } else { |
|
2105 | + $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback[0] . '\'), \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2106 | + } |
|
2107 | + if (empty($params)) { |
|
2108 | + $output = substr($output, 0, - 3) . ')'; |
|
2109 | + } |
|
2110 | + } else { |
|
2111 | + if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2112 | + $output = '$this->classCall(\'Plugin' . $func . '\', array(' . $params . '))'; |
|
2113 | + } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== |
|
2114 | + false) { |
|
2115 | + $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', |
|
2116 | 2116 | array(' . $params . '))'; |
2117 | - } else{ |
|
2118 | - $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))'; |
|
2119 | - } |
|
2120 | - } |
|
2121 | - } |
|
2122 | - } elseif ($pluginType & Core::PROXY_PLUGIN) { |
|
2123 | - $output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params); |
|
2124 | - } elseif ($pluginType & Core::SMARTY_FUNCTION) { |
|
2125 | - if (isset($params['*'])) { |
|
2126 | - $params = self::implode_r($params['*'], true); |
|
2127 | - } else { |
|
2128 | - $params = ''; |
|
2129 | - } |
|
2130 | - |
|
2131 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2132 | - $callback = $this->customPlugins[$func]['callback']; |
|
2133 | - if (is_array($callback)) { |
|
2134 | - if (is_object($callback[0])) { |
|
2135 | - $output = 'call_user_func_array(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(array(' . $params . '), $this))'; |
|
2136 | - } else { |
|
2137 | - $output = 'call_user_func_array(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(array(' . $params . '), $this))'; |
|
2138 | - } |
|
2139 | - } else { |
|
2140 | - $output = $callback . '(array(' . $params . '), $this)'; |
|
2141 | - } |
|
2142 | - } else { |
|
2143 | - $output = 'smarty_function_' . $func . '(array(' . $params . '), $this)'; |
|
2144 | - } |
|
2145 | - } elseif ($pluginType & Core::TEMPLATE_PLUGIN) { |
|
2146 | - array_unshift($params, '$this'); |
|
2147 | - $params = self::implode_r($params); |
|
2148 | - $output = 'Plugin' . Core::toCamelCase($func) . |
|
2149 | - $this->templatePlugins[$func]['uuid'] . '(' . $params . ')'; |
|
2150 | - $this->templatePlugins[$func]['called'] = true; |
|
2151 | - } |
|
2152 | - |
|
2153 | - if (is_array($parsingParams)) { |
|
2154 | - $parsingParams[] = array($output, $output); |
|
2155 | - |
|
2156 | - return $parsingParams; |
|
2157 | - } elseif ($curBlock === 'namedparam') { |
|
2158 | - return array($output, $output); |
|
2159 | - } else { |
|
2160 | - return $output; |
|
2161 | - } |
|
2162 | - } |
|
2163 | - |
|
2164 | - /** |
|
2165 | - * Parses a string. |
|
2166 | - * |
|
2167 | - * @param string $in the string within which we must parse something |
|
2168 | - * @param int $from the starting offset of the parsed area |
|
2169 | - * @param int $to the ending offset of the parsed area |
|
2170 | - * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2171 | - * default |
|
2172 | - * @param string $curBlock the current parser-block being processed |
|
2173 | - * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2174 | - * or null by default |
|
2175 | - * |
|
2176 | - * @return string parsed values |
|
2177 | - * @throws CompilationException |
|
2178 | - */ |
|
2179 | - protected function parseString($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2180 | - { |
|
2181 | - $substr = substr($in, $from, $to - $from); |
|
2182 | - $first = $substr[0]; |
|
2183 | - |
|
2184 | - if ($this->debug) { |
|
2185 | - echo 'STRING FOUND (in ' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . ')' . "\n"; |
|
2186 | - } |
|
2187 | - $strend = false; |
|
2188 | - $o = $from + 1; |
|
2189 | - while ($strend === false) { |
|
2190 | - $strend = strpos($in, $first, $o); |
|
2191 | - if ($strend === false) { |
|
2192 | - throw new CompilationException($this, 'Unfinished string, started with ' . substr($in, $from, $to - $from)); |
|
2193 | - } |
|
2194 | - if (substr($in, $strend - 1, 1) === '\\') { |
|
2195 | - $o = $strend + 1; |
|
2196 | - $strend = false; |
|
2197 | - } |
|
2198 | - } |
|
2199 | - if ($this->debug) { |
|
2200 | - echo 'STRING DELIMITED: ' . substr($in, $from, $strend + 1 - $from) . "\n"; |
|
2201 | - } |
|
2202 | - |
|
2203 | - $srcOutput = substr($in, $from, $strend + 1 - $from); |
|
2204 | - |
|
2205 | - if ($pointer !== null) { |
|
2206 | - $pointer += strlen($srcOutput); |
|
2207 | - } |
|
2208 | - |
|
2209 | - $output = $this->replaceStringVars($srcOutput, $first); |
|
2210 | - |
|
2211 | - // handle modifiers |
|
2212 | - if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend + 1 - $from), $match)) { |
|
2213 | - $modstr = $match[1]; |
|
2214 | - |
|
2215 | - if ($curBlock === 'root' && substr($modstr, - 1) === '}') { |
|
2216 | - $modstr = substr($modstr, 0, - 1); |
|
2217 | - } |
|
2218 | - $modstr = str_replace('\\' . $first, $first, $modstr); |
|
2219 | - $ptr = 0; |
|
2220 | - $output = $this->replaceModifiers(array(null, null, $output, $modstr), 'string', $ptr); |
|
2221 | - |
|
2222 | - $strend += $ptr; |
|
2223 | - if ($pointer !== null) { |
|
2224 | - $pointer += $ptr; |
|
2225 | - } |
|
2226 | - $srcOutput .= substr($substr, $strend + 1 - $from, $ptr); |
|
2227 | - } |
|
2228 | - |
|
2229 | - if (is_array($parsingParams)) { |
|
2230 | - $parsingParams[] = array($output, substr($srcOutput, 1, - 1)); |
|
2231 | - |
|
2232 | - return $parsingParams; |
|
2233 | - } elseif ($curBlock === 'namedparam') { |
|
2234 | - return array($output, substr($srcOutput, 1, - 1)); |
|
2235 | - } else { |
|
2236 | - return $output; |
|
2237 | - } |
|
2238 | - } |
|
2239 | - |
|
2240 | - /** |
|
2241 | - * Parses a constant. |
|
2242 | - * |
|
2243 | - * @param string $in the string within which we must parse something |
|
2244 | - * @param int $from the starting offset of the parsed area |
|
2245 | - * @param int $to the ending offset of the parsed area |
|
2246 | - * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2247 | - * default |
|
2248 | - * @param string $curBlock the current parser-block being processed |
|
2249 | - * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2250 | - * or null by default |
|
2251 | - * |
|
2252 | - * @return string parsed values |
|
2253 | - * @throws CompilationException |
|
2254 | - */ |
|
2255 | - protected function parseConst($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2256 | - { |
|
2257 | - $substr = substr($in, $from, $to - $from); |
|
2258 | - |
|
2259 | - if ($this->debug) { |
|
2260 | - echo 'CONST FOUND : ' . $substr . "\n"; |
|
2261 | - } |
|
2262 | - |
|
2263 | - if (!preg_match('#^%([\\\\a-z0-9_:]+)#i', $substr, $m)) { |
|
2264 | - throw new CompilationException($this, 'Invalid constant'); |
|
2265 | - } |
|
2266 | - |
|
2267 | - if ($pointer !== null) { |
|
2268 | - $pointer += strlen($m[0]); |
|
2269 | - } |
|
2270 | - |
|
2271 | - $output = $this->parseConstKey($m[1], $curBlock); |
|
2272 | - |
|
2273 | - if (is_array($parsingParams)) { |
|
2274 | - $parsingParams[] = array($output, $m[1]); |
|
2275 | - |
|
2276 | - return $parsingParams; |
|
2277 | - } elseif ($curBlock === 'namedparam') { |
|
2278 | - return array($output, $m[1]); |
|
2279 | - } else { |
|
2280 | - return $output; |
|
2281 | - } |
|
2282 | - } |
|
2283 | - |
|
2284 | - /** |
|
2285 | - * Parses a constant. |
|
2286 | - * |
|
2287 | - * @param string $key the constant to parse |
|
2288 | - * @param string $curBlock the current parser-block being processed |
|
2289 | - * |
|
2290 | - * @return string parsed constant |
|
2291 | - */ |
|
2292 | - protected function parseConstKey($key, $curBlock) |
|
2293 | - { |
|
2294 | - if ($this->securityPolicy !== null && $this->securityPolicy->getConstantHandling() === SecurityPolicy::CONST_DISALLOW) { |
|
2295 | - return 'null'; |
|
2296 | - } |
|
2297 | - |
|
2298 | - if ($curBlock !== 'root') { |
|
2299 | - $output = '(defined("' . $key . '") ? ' . $key . ' : null)'; |
|
2300 | - } else { |
|
2301 | - $output = $key; |
|
2302 | - } |
|
2303 | - |
|
2304 | - return $output; |
|
2305 | - } |
|
2306 | - |
|
2307 | - /** |
|
2308 | - * Parses a variable. |
|
2309 | - * |
|
2310 | - * @param string $in the string within which we must parse something |
|
2311 | - * @param int $from the starting offset of the parsed area |
|
2312 | - * @param int $to the ending offset of the parsed area |
|
2313 | - * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2314 | - * default |
|
2315 | - * @param string $curBlock the current parser-block being processed |
|
2316 | - * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2317 | - * or null by default |
|
2318 | - * |
|
2319 | - * @return string parsed values |
|
2320 | - * @throws CompilationException |
|
2321 | - */ |
|
2322 | - protected function parseVar($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2323 | - { |
|
2324 | - $methodCall = ''; |
|
2325 | - $substr = substr($in, $from, $to - $from); |
|
2326 | - |
|
2327 | - if (preg_match( |
|
2328 | - '#(\$?\.?[a-z0-9_:]*(?:(?:(?:\.|->)(?:[a-z0-9_:]+|(?R))|\[(?:[a-z0-9_:]+|(?R)|(["\'])[^\2]*?\2)\]))*)' . // var key |
|
2329 | - ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'expression' || $curBlock === 'delimited_string' ? '(\(.*)?' : '()') . // method call |
|
2330 | - ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'delimited_string' ? '((?:(?:[+/*%=-])(?:(?<!=)=?-?[$%][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9.,]*|[+-]))*)' : '()') . // simple math expressions |
|
2331 | - ($curBlock !== 'modifier' ? '((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').*?\5|:[^`]*))*))+)?' : '(())') . // modifiers |
|
2332 | - '#i', $substr, $match |
|
2333 | - )) { |
|
2334 | - $key = substr($match[1], 1); |
|
2335 | - |
|
2336 | - $matchedLength = strlen($match[0]); |
|
2337 | - $hasModifiers = !empty($match[5]); |
|
2338 | - $hasExpression = !empty($match[4]); |
|
2339 | - $hasMethodCall = !empty($match[3]); |
|
2340 | - |
|
2341 | - if (substr($key, - 1) == '.') { |
|
2342 | - $key = substr($key, 0, - 1); |
|
2343 | - -- $matchedLength; |
|
2344 | - } |
|
2345 | - |
|
2346 | - if ($hasMethodCall) { |
|
2347 | - $matchedLength -= strlen($match[3]) + strlen(substr($match[1], strrpos($match[1], '->'))); |
|
2348 | - $key = substr($match[1], 1, strrpos($match[1], '->') - 1); |
|
2349 | - $methodCall = substr($match[1], strrpos($match[1], '->')) . $match[3]; |
|
2350 | - } |
|
2351 | - |
|
2352 | - if ($hasModifiers) { |
|
2353 | - $matchedLength -= strlen($match[5]); |
|
2354 | - } |
|
2355 | - |
|
2356 | - if ($pointer !== null) { |
|
2357 | - $pointer += $matchedLength; |
|
2358 | - } |
|
2359 | - |
|
2360 | - // replace useless brackets by dot accessed vars and strip enclosing quotes if present |
|
2361 | - $key = preg_replace('#\[(["\']?)([^$%\[.>-]+)\1\]#', '.$2', $key); |
|
2362 | - |
|
2363 | - if ($this->debug) { |
|
2364 | - if ($hasMethodCall) { |
|
2365 | - echo 'METHOD CALL FOUND : $' . $key . substr($methodCall, 0, 30) . "\n"; |
|
2366 | - } else { |
|
2367 | - echo 'VAR FOUND : $' . $key . "\n"; |
|
2368 | - } |
|
2369 | - } |
|
2370 | - |
|
2371 | - $key = str_replace('"', '\\"', $key); |
|
2372 | - |
|
2373 | - $cnt = substr_count($key, '$'); |
|
2374 | - if ($cnt > 0) { |
|
2375 | - $uid = 0; |
|
2376 | - $parsed = array($uid => ''); |
|
2377 | - $current = &$parsed; |
|
2378 | - $curTxt = &$parsed[$uid ++]; |
|
2379 | - $tree = array(); |
|
2380 | - $chars = str_split($key, 1); |
|
2381 | - $inSplittedVar = false; |
|
2382 | - $bracketCount = 0; |
|
2383 | - |
|
2384 | - while (($char = array_shift($chars)) !== null) { |
|
2385 | - if ($char === '[') { |
|
2386 | - if (count($tree) > 0) { |
|
2387 | - ++ $bracketCount; |
|
2388 | - } else { |
|
2389 | - $tree[] = &$current; |
|
2390 | - $current[$uid] = array($uid + 1 => ''); |
|
2391 | - $current = &$current[$uid ++]; |
|
2392 | - $curTxt = &$current[$uid ++]; |
|
2393 | - continue; |
|
2394 | - } |
|
2395 | - } elseif ($char === ']') { |
|
2396 | - if ($bracketCount > 0) { |
|
2397 | - -- $bracketCount; |
|
2398 | - } else { |
|
2399 | - $current = &$tree[count($tree) - 1]; |
|
2400 | - array_pop($tree); |
|
2401 | - if (current($chars) !== '[' && current($chars) !== false && current($chars) !== ']') { |
|
2402 | - $current[$uid] = ''; |
|
2403 | - $curTxt = &$current[$uid ++]; |
|
2404 | - } |
|
2405 | - continue; |
|
2406 | - } |
|
2407 | - } elseif ($char === '$') { |
|
2408 | - if (count($tree) == 0) { |
|
2409 | - $curTxt = &$current[$uid ++]; |
|
2410 | - $inSplittedVar = true; |
|
2411 | - } |
|
2412 | - } elseif (($char === '.' || $char === '-') && count($tree) == 0 && $inSplittedVar) { |
|
2413 | - $curTxt = &$current[$uid ++]; |
|
2414 | - $inSplittedVar = false; |
|
2415 | - } |
|
2416 | - |
|
2417 | - $curTxt .= $char; |
|
2418 | - } |
|
2419 | - unset($uid, $current, $curTxt, $tree, $chars); |
|
2420 | - |
|
2421 | - if ($this->debug) { |
|
2422 | - echo 'RECURSIVE VAR REPLACEMENT : ' . $key . "\n"; |
|
2423 | - } |
|
2424 | - |
|
2425 | - $key = $this->flattenVarTree($parsed); |
|
2426 | - |
|
2427 | - if ($this->debug) { |
|
2428 | - echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n"; |
|
2429 | - } |
|
2430 | - |
|
2431 | - $output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("' . $key . '")'); |
|
2432 | - } else { |
|
2433 | - $output = $this->parseVarKey($key, $hasModifiers ? 'modifier' : $curBlock); |
|
2434 | - } |
|
2435 | - |
|
2436 | - // methods |
|
2437 | - if ($hasMethodCall) { |
|
2438 | - $ptr = 0; |
|
2439 | - |
|
2440 | - $output = $this->parseMethodCall($output, $methodCall, $curBlock, $ptr); |
|
2441 | - |
|
2442 | - if ($pointer !== null) { |
|
2443 | - $pointer += $ptr; |
|
2444 | - } |
|
2445 | - $matchedLength += $ptr; |
|
2446 | - } |
|
2447 | - |
|
2448 | - if ($hasExpression) { |
|
2449 | - // expressions |
|
2450 | - preg_match_all('#(?:([+/*%=-])(=?-?[%$][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|=?-?[0-9.,]+|\1))#i', $match[4], $expMatch); |
|
2451 | - |
|
2452 | - foreach ($expMatch[1] as $k => $operator) { |
|
2453 | - if (substr($expMatch[2][$k], 0, 1) === '=') { |
|
2454 | - $assign = true; |
|
2455 | - if ($operator === '=') { |
|
2456 | - throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, can not use "==" in expressions'); |
|
2457 | - } |
|
2458 | - if ($curBlock !== 'root') { |
|
2459 | - throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}'); |
|
2460 | - } |
|
2461 | - $operator .= '='; |
|
2462 | - $expMatch[2][$k] = substr($expMatch[2][$k], 1); |
|
2463 | - } |
|
2464 | - |
|
2465 | - if (substr($expMatch[2][$k], 0, 1) === '-' && strlen($expMatch[2][$k]) > 1) { |
|
2466 | - $operator .= '-'; |
|
2467 | - $expMatch[2][$k] = substr($expMatch[2][$k], 1); |
|
2468 | - } |
|
2469 | - if (($operator === '+' || $operator === '-') && $expMatch[2][$k] === $operator) { |
|
2470 | - $output = '(' . $output . $operator . $operator . ')'; |
|
2471 | - break; |
|
2472 | - } elseif (substr($expMatch[2][$k], 0, 1) === '$') { |
|
2473 | - $output = '(' . $output . ' ' . $operator . ' ' . $this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')'; |
|
2474 | - } elseif (substr($expMatch[2][$k], 0, 1) === '%') { |
|
2475 | - $output = '(' . $output . ' ' . $operator . ' ' . $this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')'; |
|
2476 | - } elseif (!empty($expMatch[2][$k])) { |
|
2477 | - $output = '(' . $output . ' ' . $operator . ' ' . str_replace(',', '.', $expMatch[2][$k]) . ')'; |
|
2478 | - } else { |
|
2479 | - throw new CompilationException($this, 'Unfinished expression <em>' . $substr . '</em>, missing var or number after math operator'); |
|
2480 | - } |
|
2481 | - } |
|
2482 | - } |
|
2483 | - |
|
2484 | - if ($this->autoEscape === true && $curBlock !== 'condition') { |
|
2485 | - $output = '(is_string($tmp=' . $output . ') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)'; |
|
2486 | - } |
|
2487 | - |
|
2488 | - // handle modifiers |
|
2489 | - if ($curBlock !== 'modifier' && $hasModifiers) { |
|
2490 | - $ptr = 0; |
|
2491 | - $output = $this->replaceModifiers(array(null, null, $output, $match[5]), 'var', $ptr); |
|
2492 | - if ($pointer !== null) { |
|
2493 | - $pointer += $ptr; |
|
2494 | - } |
|
2495 | - $matchedLength += $ptr; |
|
2496 | - } |
|
2497 | - |
|
2498 | - if (is_array($parsingParams)) { |
|
2499 | - $parsingParams[] = array($output, $key); |
|
2500 | - |
|
2501 | - return $parsingParams; |
|
2502 | - } elseif ($curBlock === 'namedparam') { |
|
2503 | - return array($output, $key); |
|
2504 | - } elseif ($curBlock === 'string' || $curBlock === 'delimited_string') { |
|
2505 | - return array($matchedLength, $output); |
|
2506 | - } elseif ($curBlock === 'expression' || $curBlock === 'variable') { |
|
2507 | - return $output; |
|
2508 | - } elseif (isset($assign)) { |
|
2509 | - return self::PHP_OPEN . $output . ';' . self::PHP_CLOSE; |
|
2510 | - } else { |
|
2511 | - return $output; |
|
2512 | - } |
|
2513 | - } else { |
|
2514 | - if ($curBlock === 'string' || $curBlock === 'delimited_string') { |
|
2515 | - return array(0, ''); |
|
2516 | - } else { |
|
2517 | - throw new CompilationException($this, 'Invalid variable name <em>' . $substr . '</em>'); |
|
2518 | - } |
|
2519 | - } |
|
2520 | - } |
|
2521 | - |
|
2522 | - /** |
|
2523 | - * Parses any number of chained method calls/property reads. |
|
2524 | - * |
|
2525 | - * @param string $output the variable or whatever upon which the method are called |
|
2526 | - * @param string $methodCall method call source, starting at "->" |
|
2527 | - * @param string $curBlock the current parser-block being processed |
|
2528 | - * @param int $pointer a reference to a pointer that will be increased by the amount of characters parsed |
|
2529 | - * |
|
2530 | - * @return string parsed call(s)/read(s) |
|
2531 | - */ |
|
2532 | - protected function parseMethodCall($output, $methodCall, $curBlock, &$pointer) |
|
2533 | - { |
|
2534 | - $ptr = 0; |
|
2535 | - $len = strlen($methodCall); |
|
2536 | - |
|
2537 | - while ($ptr < $len) { |
|
2538 | - if (strpos($methodCall, '->', $ptr) === $ptr) { |
|
2539 | - $ptr += 2; |
|
2540 | - } |
|
2541 | - |
|
2542 | - if (in_array( |
|
2543 | - $methodCall[$ptr], array( |
|
2544 | - ';', |
|
2545 | - ',', |
|
2546 | - '/', |
|
2547 | - ' ', |
|
2548 | - "\t", |
|
2549 | - "\r", |
|
2550 | - "\n", |
|
2551 | - ')', |
|
2552 | - '+', |
|
2553 | - '*', |
|
2554 | - '%', |
|
2555 | - '=', |
|
2556 | - '-', |
|
2557 | - '|' |
|
2558 | - ) |
|
2559 | - ) || substr($methodCall, $ptr, strlen($this->rd)) === $this->rd |
|
2560 | - ) { |
|
2561 | - // break char found |
|
2562 | - break; |
|
2563 | - } |
|
2564 | - |
|
2565 | - if (!preg_match('/^([a-z0-9_]+)(\(.*?\))?/i', substr($methodCall, $ptr), $methMatch)) { |
|
2566 | - break; |
|
2567 | - } |
|
2568 | - |
|
2569 | - if (empty($methMatch[2])) { |
|
2570 | - // property |
|
2571 | - if ($curBlock === 'root') { |
|
2572 | - $output .= '->' . $methMatch[1]; |
|
2573 | - } else { |
|
2574 | - $output = '(($tmp = ' . $output . ') ? $tmp->' . $methMatch[1] . ' : null)'; |
|
2575 | - } |
|
2576 | - $ptr += strlen($methMatch[1]); |
|
2577 | - } else { |
|
2578 | - // method |
|
2579 | - if (substr($methMatch[2], 0, 2) === '()') { |
|
2580 | - $parsedCall = $methMatch[1] . '()'; |
|
2581 | - $ptr += strlen($methMatch[1]) + 2; |
|
2582 | - } else { |
|
2583 | - $parsedCall = $this->parseFunction($methodCall, $ptr, strlen($methodCall), false, 'method', $ptr); |
|
2584 | - } |
|
2585 | - if ($this->securityPolicy !== null) { |
|
2586 | - $argPos = strpos($parsedCall, '('); |
|
2587 | - $method = strtolower(substr($parsedCall, 0, $argPos)); |
|
2588 | - $args = substr($parsedCall, $argPos); |
|
2589 | - if ($curBlock === 'root') { |
|
2590 | - $output = '$this->getSecurityPolicy()->callMethod($this, ' . $output . ', ' . var_export($method, true) . ', array' . $args . ')'; |
|
2591 | - } else { |
|
2592 | - $output = '(($tmp = ' . $output . ') ? $this->getSecurityPolicy()->callMethod($this, $tmp, ' . var_export($method, true) . ', array' . $args . ') : null)'; |
|
2593 | - } |
|
2594 | - } else { |
|
2595 | - if ($curBlock === 'root') { |
|
2596 | - $output .= '->' . $parsedCall; |
|
2597 | - } else { |
|
2598 | - $output = '(($tmp = ' . $output . ') ? $tmp->' . $parsedCall . ' : null)'; |
|
2599 | - } |
|
2600 | - } |
|
2601 | - } |
|
2602 | - } |
|
2603 | - |
|
2604 | - $pointer += $ptr; |
|
2605 | - |
|
2606 | - return $output; |
|
2607 | - } |
|
2608 | - |
|
2609 | - /** |
|
2610 | - * Parses a constant variable (a variable that doesn't contain another variable) and preprocesses it to save |
|
2611 | - * runtime processing time. |
|
2612 | - * |
|
2613 | - * @param string $key the variable to parse |
|
2614 | - * @param string $curBlock the current parser-block being processed |
|
2615 | - * |
|
2616 | - * @return string parsed variable |
|
2617 | - */ |
|
2618 | - protected function parseVarKey($key, $curBlock) |
|
2619 | - { |
|
2620 | - if ($key === '') { |
|
2621 | - return '$this->scope'; |
|
2622 | - } |
|
2623 | - if (substr($key, 0, 1) === '.') { |
|
2624 | - $key = 'dwoo' . $key; |
|
2625 | - } |
|
2626 | - if (preg_match('#dwoo\.(get|post|server|cookies|session|env|request)((?:\.[a-z0-9_-]+)+)#i', $key, $m)) { |
|
2627 | - $global = strtoupper($m[1]); |
|
2628 | - if ($global === 'COOKIES') { |
|
2629 | - $global = 'COOKIE'; |
|
2630 | - } |
|
2631 | - $key = '$_' . $global; |
|
2632 | - foreach (explode('.', ltrim($m[2], '.')) as $part) { |
|
2633 | - $key .= '[' . var_export($part, true) . ']'; |
|
2634 | - } |
|
2635 | - if ($curBlock === 'root') { |
|
2636 | - $output = $key; |
|
2637 | - } else { |
|
2638 | - $output = '(isset(' . $key . ')?' . $key . ':null)'; |
|
2639 | - } |
|
2640 | - } elseif (preg_match('#dwoo\.const\.([a-z0-9_:]+)#i', $key, $m)) { |
|
2641 | - return $this->parseConstKey($m[1], $curBlock); |
|
2642 | - } elseif ($this->scope !== null) { |
|
2643 | - if (strstr($key, '.') === false && strstr($key, '[') === false && strstr($key, '->') === false) { |
|
2644 | - if ($key === 'dwoo') { |
|
2645 | - $output = '$this->globals'; |
|
2646 | - } elseif ($key === '_root' || $key === '__') { |
|
2647 | - $output = '$this->data'; |
|
2648 | - } elseif ($key === '_parent' || $key === '_') { |
|
2649 | - $output = '$this->readParentVar(1)'; |
|
2650 | - } elseif ($key === '_key') { |
|
2651 | - $output = '$tmp_key'; |
|
2652 | - } else { |
|
2653 | - if ($curBlock === 'root') { |
|
2654 | - $output = '$this->scope["' . $key . '"]'; |
|
2655 | - } else { |
|
2656 | - $output = '(isset($this->scope["' . $key . '"]) ? $this->scope["' . $key . '"] : null)'; |
|
2657 | - } |
|
2658 | - } |
|
2659 | - } else { |
|
2660 | - preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+|(\\\?[\'"])[^\3]*?\3)\]?#i', $key, $m); |
|
2661 | - |
|
2662 | - $i = $m[2][0]; |
|
2663 | - if ($i === '_parent' || $i === '_') { |
|
2664 | - $parentCnt = 0; |
|
2665 | - |
|
2666 | - while (true) { |
|
2667 | - ++ $parentCnt; |
|
2668 | - array_shift($m[2]); |
|
2669 | - array_shift($m[1]); |
|
2670 | - if (current($m[2]) === '_parent') { |
|
2671 | - continue; |
|
2672 | - } |
|
2673 | - break; |
|
2674 | - } |
|
2675 | - |
|
2676 | - $output = '$this->readParentVar(' . $parentCnt . ')'; |
|
2677 | - } else { |
|
2678 | - if ($i === 'dwoo') { |
|
2679 | - $output = '$this->globals'; |
|
2680 | - array_shift($m[2]); |
|
2681 | - array_shift($m[1]); |
|
2682 | - } elseif ($i === '_root' || $i === '__') { |
|
2683 | - $output = '$this->data'; |
|
2684 | - array_shift($m[2]); |
|
2685 | - array_shift($m[1]); |
|
2686 | - } elseif ($i === '_key') { |
|
2687 | - $output = '$tmp_key'; |
|
2688 | - } else { |
|
2689 | - $output = '$this->scope'; |
|
2690 | - } |
|
2691 | - |
|
2692 | - while (count($m[1]) && $m[1][0] !== '->') { |
|
2693 | - $m[2][0] = preg_replace('/(^\\\([\'"])|\\\([\'"])$)/x', '$2$3', $m[2][0]); |
|
2694 | - if (substr($m[2][0], 0, 1) == '"' || substr($m[2][0], 0, 1) == "'") { |
|
2695 | - $output .= '[' . $m[2][0] . ']'; |
|
2696 | - } else { |
|
2697 | - $output .= '["' . $m[2][0] . '"]'; |
|
2698 | - } |
|
2699 | - array_shift($m[2]); |
|
2700 | - array_shift($m[1]); |
|
2701 | - } |
|
2702 | - |
|
2703 | - if ($curBlock !== 'root') { |
|
2704 | - $output = '(isset(' . $output . ') ? ' . $output . ':null)'; |
|
2705 | - } |
|
2706 | - } |
|
2707 | - |
|
2708 | - if (count($m[2])) { |
|
2709 | - unset($m[0]); |
|
2710 | - $output = '$this->readVarInto(' . str_replace("\n", '', var_export($m, true)) . ', ' . $output . ', ' . ($curBlock == 'root' ? 'false' : 'true') . ')'; |
|
2711 | - } |
|
2712 | - } |
|
2713 | - } else { |
|
2714 | - preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+)\]?#i', $key, $m); |
|
2715 | - unset($m[0]); |
|
2716 | - $output = '$this->readVar(' . str_replace("\n", '', var_export($m, true)) . ')'; |
|
2717 | - } |
|
2718 | - |
|
2719 | - return $output; |
|
2720 | - } |
|
2721 | - |
|
2722 | - /** |
|
2723 | - * Flattens a variable tree, this helps in parsing very complex variables such as $var.foo[$foo.bar->baz].baz, |
|
2724 | - * it computes the contents of the brackets first and works out from there. |
|
2725 | - * |
|
2726 | - * @param array $tree the variable tree parsed by he parseVar() method that must be flattened |
|
2727 | - * @param bool $recursed leave that to false by default, it is only for internal use |
|
2728 | - * |
|
2729 | - * @return string flattened tree |
|
2730 | - */ |
|
2731 | - protected function flattenVarTree(array $tree, $recursed = false) |
|
2732 | - { |
|
2733 | - $out = $recursed ? '".$this->readVarInto(' : ''; |
|
2734 | - foreach ($tree as $bit) { |
|
2735 | - if (is_array($bit)) { |
|
2736 | - $out .= '.' . $this->flattenVarTree($bit, false); |
|
2737 | - } else { |
|
2738 | - $key = str_replace('"', '\\"', $bit); |
|
2739 | - |
|
2740 | - if (substr($key, 0, 1) === '$') { |
|
2741 | - $out .= '".' . $this->parseVar($key, 0, strlen($key), false, 'variable') . '."'; |
|
2742 | - } else { |
|
2743 | - $cnt = substr_count($key, '$'); |
|
2744 | - |
|
2745 | - if ($this->debug) { |
|
2746 | - echo 'PARSING SUBVARS IN : ' . $key . "\n"; |
|
2747 | - } |
|
2748 | - if ($cnt > 0) { |
|
2749 | - while (-- $cnt >= 0) { |
|
2750 | - if (isset($last)) { |
|
2751 | - $last = strrpos($key, '$', - (strlen($key) - $last + 1)); |
|
2752 | - } else { |
|
2753 | - $last = strrpos($key, '$'); |
|
2754 | - } |
|
2755 | - preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch); |
|
2756 | - |
|
2757 | - $len = strlen($submatch[0]); |
|
2758 | - $key = substr_replace( |
|
2759 | - $key, preg_replace_callback( |
|
2760 | - '#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array( |
|
2761 | - $this, |
|
2762 | - 'replaceVarKeyHelper' |
|
2763 | - ), substr($key, $last, $len) |
|
2764 | - ), $last, $len |
|
2765 | - ); |
|
2766 | - if ($this->debug) { |
|
2767 | - echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n"; |
|
2768 | - } |
|
2769 | - } |
|
2770 | - unset($last); |
|
2771 | - |
|
2772 | - $out .= $key; |
|
2773 | - } else { |
|
2774 | - $out .= $key; |
|
2775 | - } |
|
2776 | - } |
|
2777 | - } |
|
2778 | - } |
|
2779 | - $out .= $recursed ? ', true)."' : ''; |
|
2780 | - |
|
2781 | - return $out; |
|
2782 | - } |
|
2783 | - |
|
2784 | - /** |
|
2785 | - * Helper function that parses a variable. |
|
2786 | - * |
|
2787 | - * @param array $match the matched variable, array(1=>"string match") |
|
2788 | - * |
|
2789 | - * @return string parsed variable |
|
2790 | - */ |
|
2791 | - protected function replaceVarKeyHelper($match) |
|
2792 | - { |
|
2793 | - return '".' . $this->parseVar($match[0], 0, strlen($match[0]), false, 'variable') . '."'; |
|
2794 | - } |
|
2795 | - |
|
2796 | - /** |
|
2797 | - * Parses various constants, operators or non-quoted strings. |
|
2798 | - * |
|
2799 | - * @param string $in the string within which we must parse something |
|
2800 | - * @param int $from the starting offset of the parsed area |
|
2801 | - * @param int $to the ending offset of the parsed area |
|
2802 | - * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2803 | - * default |
|
2804 | - * @param string $curBlock the current parser-block being processed |
|
2805 | - * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2806 | - * or null by default |
|
2807 | - * |
|
2808 | - * @return string parsed values |
|
2809 | - * @throws Exception |
|
2810 | - */ |
|
2811 | - protected function parseOthers($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2812 | - { |
|
2813 | - $substr = substr($in, $from, $to - $from); |
|
2814 | - |
|
2815 | - $end = strlen($substr); |
|
2816 | - |
|
2817 | - if ($curBlock === 'condition') { |
|
2818 | - $breakChars = array( |
|
2819 | - '(', |
|
2820 | - ')', |
|
2821 | - ' ', |
|
2822 | - '||', |
|
2823 | - '&&', |
|
2824 | - '|', |
|
2825 | - '&', |
|
2826 | - '>=', |
|
2827 | - '<=', |
|
2828 | - '===', |
|
2829 | - '==', |
|
2830 | - '=', |
|
2831 | - '!==', |
|
2832 | - '!=', |
|
2833 | - '<<', |
|
2834 | - '<', |
|
2835 | - '>>', |
|
2836 | - '>', |
|
2837 | - '^', |
|
2838 | - '~', |
|
2839 | - ',', |
|
2840 | - '+', |
|
2841 | - '-', |
|
2842 | - '*', |
|
2843 | - '/', |
|
2844 | - '%', |
|
2845 | - '!', |
|
2846 | - '?', |
|
2847 | - ':', |
|
2848 | - $this->rd, |
|
2849 | - ';' |
|
2850 | - ); |
|
2851 | - } elseif ($curBlock === 'modifier') { |
|
2852 | - $breakChars = array(' ', ',', ')', ':', '|', "\r", "\n", "\t", ';', $this->rd); |
|
2853 | - } elseif ($curBlock === 'expression') { |
|
2854 | - $breakChars = array('/', '%', '+', '-', '*', ' ', ',', ')', "\r", "\n", "\t", ';', $this->rd); |
|
2855 | - } else { |
|
2856 | - $breakChars = array(' ', ',', ')', "\r", "\n", "\t", ';', $this->rd); |
|
2857 | - } |
|
2858 | - |
|
2859 | - $breaker = false; |
|
2860 | - while (list($k, $char) = each($breakChars)) { |
|
2861 | - $test = strpos($substr, $char); |
|
2862 | - if ($test !== false && $test < $end) { |
|
2863 | - $end = $test; |
|
2864 | - $breaker = $k; |
|
2865 | - } |
|
2866 | - } |
|
2867 | - |
|
2868 | - if ($curBlock === 'condition') { |
|
2869 | - if ($end === 0 && $breaker !== false) { |
|
2870 | - $end = strlen($breakChars[$breaker]); |
|
2871 | - } |
|
2872 | - } |
|
2873 | - |
|
2874 | - if ($end !== false) { |
|
2875 | - $substr = substr($substr, 0, $end); |
|
2876 | - } |
|
2877 | - |
|
2878 | - if ($pointer !== null) { |
|
2879 | - $pointer += strlen($substr); |
|
2880 | - } |
|
2881 | - |
|
2882 | - $src = $substr; |
|
2883 | - $substr = trim($substr); |
|
2884 | - |
|
2885 | - if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') { |
|
2886 | - if ($this->debug) { |
|
2887 | - echo 'BOOLEAN(FALSE) PARSED' . "\n"; |
|
2888 | - } |
|
2889 | - $substr = 'false'; |
|
2890 | - $type = self::T_BOOL; |
|
2891 | - } elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') { |
|
2892 | - if ($this->debug) { |
|
2893 | - echo 'BOOLEAN(TRUE) PARSED' . "\n"; |
|
2894 | - } |
|
2895 | - $substr = 'true'; |
|
2896 | - $type = self::T_BOOL; |
|
2897 | - } elseif ($substr === 'null' || $substr === 'NULL') { |
|
2898 | - if ($this->debug) { |
|
2899 | - echo 'NULL PARSED' . "\n"; |
|
2900 | - } |
|
2901 | - $substr = 'null'; |
|
2902 | - $type = self::T_NULL; |
|
2903 | - } elseif (is_numeric($substr)) { |
|
2904 | - $substr = (float)$substr; |
|
2905 | - if ((int)$substr == $substr) { |
|
2906 | - $substr = (int)$substr; |
|
2907 | - } |
|
2908 | - $type = self::T_NUMERIC; |
|
2909 | - if ($this->debug) { |
|
2910 | - echo 'NUMBER (' . $substr . ') PARSED' . "\n"; |
|
2911 | - } |
|
2912 | - } elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) { |
|
2913 | - if ($this->debug) { |
|
2914 | - echo 'SIMPLE MATH PARSED . "\n"'; |
|
2915 | - } |
|
2916 | - $type = self::T_MATH; |
|
2917 | - $substr = '(' . $substr . ')'; |
|
2918 | - } elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) { |
|
2919 | - if ($this->debug) { |
|
2920 | - echo 'BREAKCHAR (' . $substr . ') PARSED' . "\n"; |
|
2921 | - } |
|
2922 | - $type = self::T_BREAKCHAR; |
|
2923 | - //$substr = '"'.$substr.'"'; |
|
2924 | - } else { |
|
2925 | - $substr = $this->replaceStringVars('\'' . str_replace('\'', '\\\'', $substr) . '\'', '\'', $curBlock); |
|
2926 | - $type = self::T_UNQUOTED_STRING; |
|
2927 | - if ($this->debug) { |
|
2928 | - echo 'BLABBER (' . $substr . ') CASTED AS STRING' . "\n"; |
|
2929 | - } |
|
2930 | - } |
|
2931 | - |
|
2932 | - if (is_array($parsingParams)) { |
|
2933 | - $parsingParams[] = array($substr, $src, $type); |
|
2934 | - |
|
2935 | - return $parsingParams; |
|
2936 | - } elseif ($curBlock === 'namedparam') { |
|
2937 | - return array($substr, $src, $type); |
|
2938 | - } elseif ($curBlock === 'expression') { |
|
2939 | - return $substr; |
|
2940 | - } else { |
|
2941 | - throw new Exception('Something went wrong'); |
|
2942 | - } |
|
2943 | - } |
|
2944 | - |
|
2945 | - /** |
|
2946 | - * Replaces variables within a parsed string. |
|
2947 | - * |
|
2948 | - * @param string $string the parsed string |
|
2949 | - * @param string $first the first character parsed in the string, which is the string delimiter (' or ") |
|
2950 | - * @param string $curBlock the current parser-block being processed |
|
2951 | - * |
|
2952 | - * @return string the original string with variables replaced |
|
2953 | - */ |
|
2954 | - protected function replaceStringVars($string, $first, $curBlock = '') |
|
2955 | - { |
|
2956 | - $pos = 0; |
|
2957 | - if ($this->debug) { |
|
2958 | - echo 'STRING VAR REPLACEMENT : ' . $string . "\n"; |
|
2959 | - } |
|
2960 | - // replace vars |
|
2961 | - while (($pos = strpos($string, '$', $pos)) !== false) { |
|
2962 | - $prev = substr($string, $pos - 1, 1); |
|
2963 | - if ($prev === '\\') { |
|
2964 | - ++ $pos; |
|
2965 | - continue; |
|
2966 | - } |
|
2967 | - |
|
2968 | - $var = $this->parse($string, $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string'))); |
|
2969 | - $len = $var[0]; |
|
2970 | - $var = $this->parse(str_replace('\\' . $first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string'))); |
|
2971 | - |
|
2972 | - if ($prev === '`' && substr($string, $pos + $len, 1) === '`') { |
|
2973 | - $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos - 1, $len + 2); |
|
2974 | - } else { |
|
2975 | - $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos, $len); |
|
2976 | - } |
|
2977 | - $pos += strlen($var[1]) + 2; |
|
2978 | - if ($this->debug) { |
|
2979 | - echo 'STRING VAR REPLACEMENT DONE : ' . $string . "\n"; |
|
2980 | - } |
|
2981 | - } |
|
2982 | - |
|
2983 | - // handle modifiers |
|
2984 | - // TODO Obsolete? |
|
2985 | - $string = preg_replace_callback( |
|
2986 | - '#("|\')\.(.+?)\.\1((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').+?\4|:[^`]*))*))+)#i', array( |
|
2987 | - $this, |
|
2988 | - 'replaceModifiers' |
|
2989 | - ), $string |
|
2990 | - ); |
|
2991 | - |
|
2992 | - // replace escaped dollar operators by unescaped ones if required |
|
2993 | - if ($first === "'") { |
|
2994 | - $string = str_replace('\\$', '$', $string); |
|
2995 | - } |
|
2996 | - |
|
2997 | - return $string; |
|
2998 | - } |
|
2999 | - |
|
3000 | - /** |
|
3001 | - * Replaces the modifiers applied to a string or a variable. |
|
3002 | - * |
|
3003 | - * @param array $m the regex matches that must be array(1=>"double or single quotes enclosing a string, |
|
3004 | - * when applicable", 2=>"the string or var", 3=>"the modifiers matched") |
|
3005 | - * @param string $curBlock the current parser-block being processed |
|
3006 | - * @param null $pointer |
|
3007 | - * |
|
3008 | - * @return string the input enclosed with various function calls according to the modifiers found |
|
3009 | - * @throws CompilationException |
|
3010 | - * @throws Exception |
|
3011 | - */ |
|
3012 | - protected function replaceModifiers(array $m, $curBlock = null, &$pointer = null) |
|
3013 | - { |
|
3014 | - if ($this->debug) { |
|
3015 | - echo 'PARSING MODIFIERS : ' . $m[3] . "\n"; |
|
3016 | - } |
|
3017 | - |
|
3018 | - if ($pointer !== null) { |
|
3019 | - $pointer += strlen($m[3]); |
|
3020 | - } |
|
3021 | - // remove first pipe |
|
3022 | - $cmdstrsrc = substr($m[3], 1); |
|
3023 | - // remove last quote if present |
|
3024 | - if (substr($cmdstrsrc, - 1, 1) === $m[1]) { |
|
3025 | - $cmdstrsrc = substr($cmdstrsrc, 0, - 1); |
|
3026 | - $add = $m[1]; |
|
3027 | - } |
|
3028 | - |
|
3029 | - $output = $m[2]; |
|
3030 | - |
|
3031 | - $continue = true; |
|
3032 | - while (strlen($cmdstrsrc) > 0 && $continue) { |
|
3033 | - if ($cmdstrsrc[0] === '|') { |
|
3034 | - $cmdstrsrc = substr($cmdstrsrc, 1); |
|
3035 | - continue; |
|
3036 | - } |
|
3037 | - if ($cmdstrsrc[0] === ' ' || $cmdstrsrc[0] === ';' || substr($cmdstrsrc, 0, strlen($this->rd)) === $this->rd) { |
|
3038 | - if ($this->debug) { |
|
3039 | - echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND' . "\n"; |
|
3040 | - } |
|
3041 | - $continue = false; |
|
3042 | - if ($pointer !== null) { |
|
3043 | - $pointer -= strlen($cmdstrsrc); |
|
3044 | - } |
|
3045 | - break; |
|
3046 | - } |
|
3047 | - $cmdstr = $cmdstrsrc; |
|
3048 | - $paramsep = ':'; |
|
3049 | - if (!preg_match('/^(@{0,2}[a-z_][a-z0-9_]*)(:)?/i', $cmdstr, $match)) { |
|
3050 | - throw new CompilationException($this, 'Invalid modifier name, started with : ' . substr($cmdstr, 0, 10)); |
|
3051 | - } |
|
3052 | - $paramspos = !empty($match[2]) ? strlen($match[1]) : false; |
|
3053 | - $func = $match[1]; |
|
3054 | - |
|
3055 | - $state = 0; |
|
3056 | - if ($paramspos === false) { |
|
3057 | - $cmdstrsrc = substr($cmdstrsrc, strlen($func)); |
|
3058 | - $params = array(); |
|
3059 | - if ($this->debug) { |
|
3060 | - echo 'MODIFIER (' . $func . ') CALLED WITH NO PARAMS' . "\n"; |
|
3061 | - } |
|
3062 | - } else { |
|
3063 | - $paramstr = substr($cmdstr, $paramspos + 1); |
|
3064 | - if (substr($paramstr, - 1, 1) === $paramsep) { |
|
3065 | - $paramstr = substr($paramstr, 0, - 1); |
|
3066 | - } |
|
3067 | - |
|
3068 | - $ptr = 0; |
|
3069 | - $params = array(); |
|
3070 | - while ($ptr < strlen($paramstr)) { |
|
3071 | - if ($this->debug) { |
|
3072 | - echo 'MODIFIER (' . $func . ') START PARAM PARSING WITH POINTER AT ' . $ptr . "\n"; |
|
3073 | - } |
|
3074 | - if ($this->debug) { |
|
3075 | - echo $paramstr . '--' . $ptr . '--' . strlen($paramstr) . '--modifier' . "\n"; |
|
3076 | - } |
|
3077 | - $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'modifier', $ptr); |
|
3078 | - if ($this->debug) { |
|
3079 | - echo 'PARAM PARSED, POINTER AT ' . $ptr . "\n"; |
|
3080 | - } |
|
3081 | - |
|
3082 | - if ($ptr >= strlen($paramstr)) { |
|
3083 | - if ($this->debug) { |
|
3084 | - echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED' . "\n"; |
|
3085 | - } |
|
3086 | - break; |
|
3087 | - } |
|
3088 | - |
|
3089 | - if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === '|' || $paramstr[$ptr] === ';' || substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) { |
|
3090 | - if ($this->debug) { |
|
3091 | - echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT ' . $ptr . "\n"; |
|
3092 | - } |
|
3093 | - if ($paramstr[$ptr] !== '|') { |
|
3094 | - $continue = false; |
|
3095 | - if ($pointer !== null) { |
|
3096 | - $pointer -= strlen($paramstr) - $ptr; |
|
3097 | - } |
|
3098 | - } |
|
3099 | - ++ $ptr; |
|
3100 | - break; |
|
3101 | - } |
|
3102 | - if ($ptr < strlen($paramstr) && $paramstr[$ptr] === ':') { |
|
3103 | - ++ $ptr; |
|
3104 | - } |
|
3105 | - } |
|
3106 | - $cmdstrsrc = substr($cmdstrsrc, strlen($func) + 1 + $ptr); |
|
3107 | - foreach ($params as $k => $p) { |
|
3108 | - if (is_array($p) && is_array($p[1])) { |
|
3109 | - $state |= 2; |
|
3110 | - } else { |
|
3111 | - if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m)) { |
|
3112 | - $params[$k] = array($m[2], array('true', 'true')); |
|
3113 | - } else { |
|
3114 | - if ($state & 2) { |
|
3115 | - throw new CompilationException($this, 'You can not use an unnamed parameter after a named one'); |
|
3116 | - } |
|
3117 | - $state |= 1; |
|
3118 | - } |
|
3119 | - } |
|
3120 | - } |
|
3121 | - } |
|
3122 | - |
|
3123 | - // check if we must use array_map with this plugin or not |
|
3124 | - $mapped = false; |
|
3125 | - if (substr($func, 0, 1) === '@') { |
|
3126 | - $func = substr($func, 1); |
|
3127 | - $mapped = true; |
|
3128 | - } |
|
3129 | - |
|
3130 | - $pluginType = $this->getPluginType($func); |
|
3131 | - |
|
3132 | - if ($state & 2) { |
|
3133 | - array_unshift($params, array('value', is_array($output) ? $output : array($output, $output))); |
|
3134 | - } else { |
|
3135 | - array_unshift($params, is_array($output) ? $output : array($output, $output)); |
|
3136 | - } |
|
3137 | - |
|
3138 | - if ($pluginType & Core::NATIVE_PLUGIN) { |
|
3139 | - $params = $this->mapParams($params, null, $state); |
|
3140 | - |
|
3141 | - $params = $params['*'][0]; |
|
3142 | - |
|
3143 | - $params = self::implode_r($params); |
|
3144 | - |
|
3145 | - if ($mapped) { |
|
3146 | - $output = '$this->arrayMap(\'' . $func . '\', array(' . $params . '))'; |
|
3147 | - } else { |
|
3148 | - $output = $func . '(' . $params . ')'; |
|
3149 | - } |
|
3150 | - } elseif ($pluginType & Core::PROXY_PLUGIN) { |
|
3151 | - $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state); |
|
3152 | - foreach ($params as &$p) { |
|
3153 | - $p = $p[0]; |
|
3154 | - } |
|
3155 | - $output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params); |
|
3156 | - } elseif ($pluginType & Core::SMARTY_MODIFIER) { |
|
3157 | - $params = $this->mapParams($params, null, $state); |
|
3158 | - $params = $params['*'][0]; |
|
3159 | - |
|
3160 | - $params = self::implode_r($params); |
|
3161 | - |
|
3162 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3163 | - $callback = $this->customPlugins[$func]['callback']; |
|
3164 | - if (is_array($callback)) { |
|
3165 | - if (is_object($callback[0])) { |
|
3166 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3167 | - } else { |
|
3168 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3169 | - } |
|
3170 | - } elseif ($mapped) { |
|
3171 | - $output = '$this->arrayMap(\'' . $callback . '\', array(' . $params . '))'; |
|
3172 | - } else { |
|
3173 | - $output = $callback . '(' . $params . ')'; |
|
3174 | - } |
|
3175 | - } elseif ($mapped) { |
|
3176 | - $output = '$this->arrayMap(\'smarty_modifier_' . $func . '\', array(' . $params . '))'; |
|
3177 | - } else { |
|
3178 | - $output = 'smarty_modifier_' . $func . '(' . $params . ')'; |
|
3179 | - } |
|
3180 | - } else { |
|
3181 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3182 | - $callback = $this->customPlugins[$func]['callback']; |
|
3183 | - $pluginName = $callback; |
|
3184 | - } else { |
|
3185 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false || function_exists('Plugin' . |
|
3186 | - Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) |
|
3187 | - !== false) { |
|
3188 | - $pluginName = 'Plugin' . Core::toCamelCase($func); |
|
3189 | - } else { |
|
3190 | - $pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func); |
|
3191 | - } |
|
3192 | - if ($pluginType & Core::CLASS_PLUGIN) { |
|
3193 | - $callback = array($pluginName, ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'); |
|
3194 | - } else { |
|
3195 | - $callback = $pluginName . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''); |
|
3196 | - } |
|
3197 | - } |
|
3198 | - $params = $this->mapParams($params, $callback, $state); |
|
3199 | - |
|
3200 | - foreach ($params as &$p) { |
|
3201 | - $p = $p[0]; |
|
3202 | - } |
|
3203 | - |
|
3204 | - if ($pluginType & Core::FUNC_PLUGIN) { |
|
3205 | - if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
3206 | - if ($mapped) { |
|
3207 | - throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.'); |
|
3208 | - } |
|
3209 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3210 | - $funcCompiler = $this->customPlugins[$func]['callback']; |
|
3211 | - } else { |
|
3212 | - if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) { |
|
3213 | - $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile'; |
|
3214 | - } else { |
|
3215 | - $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . |
|
3216 | - 'Compile'; |
|
3217 | - } |
|
3218 | - } |
|
3219 | - array_unshift($params, $this); |
|
3220 | - $output = call_user_func_array($funcCompiler, $params); |
|
3221 | - } else { |
|
3222 | - array_unshift($params, '$this'); |
|
3223 | - |
|
3224 | - $params = self::implode_r($params); |
|
3225 | - if ($mapped) { |
|
3226 | - $output = '$this->arrayMap(\'' . $pluginName . '\', array(' . $params . '))'; |
|
3227 | - } else { |
|
3228 | - $output = $pluginName . '(' . $params . ')'; |
|
3229 | - } |
|
3230 | - } |
|
3231 | - } else { |
|
3232 | - if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
3233 | - if ($mapped) { |
|
3234 | - throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.'); |
|
3235 | - } |
|
3236 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3237 | - $callback = $this->customPlugins[$func]['callback']; |
|
3238 | - if (!is_array($callback)) { |
|
3239 | - if (!method_exists($callback, 'compile')) { |
|
3240 | - throw new Exception('Custom plugin ' . $func . ' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
3241 | - } |
|
3242 | - if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) { |
|
3243 | - $funcCompiler = array($callback, 'compile'); |
|
3244 | - } else { |
|
3245 | - $funcCompiler = array(new $callback(), 'compile'); |
|
3246 | - } |
|
3247 | - } else { |
|
3248 | - $funcCompiler = $callback; |
|
3249 | - } |
|
3250 | - } else { |
|
3251 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
3252 | - $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile'); |
|
3253 | - } else { |
|
3254 | - $funcCompiler = array( |
|
3255 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
3256 | - 'compile' |
|
3257 | - ); |
|
3258 | - } |
|
3259 | - array_unshift($params, $this); |
|
3260 | - } |
|
3261 | - $output = call_user_func_array($funcCompiler, $params); |
|
3262 | - } else { |
|
3263 | - $params = self::implode_r($params); |
|
3264 | - |
|
3265 | - if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3266 | - if (is_object($callback[0])) { |
|
3267 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3268 | - } else { |
|
3269 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3270 | - } |
|
3271 | - } elseif ($mapped) { |
|
3272 | - $output = '$this->arrayMap(array($this->getObjectPlugin(\''. |
|
3273 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '\'), |
|
2117 | + } else{ |
|
2118 | + $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))'; |
|
2119 | + } |
|
2120 | + } |
|
2121 | + } |
|
2122 | + } elseif ($pluginType & Core::PROXY_PLUGIN) { |
|
2123 | + $output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params); |
|
2124 | + } elseif ($pluginType & Core::SMARTY_FUNCTION) { |
|
2125 | + if (isset($params['*'])) { |
|
2126 | + $params = self::implode_r($params['*'], true); |
|
2127 | + } else { |
|
2128 | + $params = ''; |
|
2129 | + } |
|
2130 | + |
|
2131 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
2132 | + $callback = $this->customPlugins[$func]['callback']; |
|
2133 | + if (is_array($callback)) { |
|
2134 | + if (is_object($callback[0])) { |
|
2135 | + $output = 'call_user_func_array(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(array(' . $params . '), $this))'; |
|
2136 | + } else { |
|
2137 | + $output = 'call_user_func_array(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(array(' . $params . '), $this))'; |
|
2138 | + } |
|
2139 | + } else { |
|
2140 | + $output = $callback . '(array(' . $params . '), $this)'; |
|
2141 | + } |
|
2142 | + } else { |
|
2143 | + $output = 'smarty_function_' . $func . '(array(' . $params . '), $this)'; |
|
2144 | + } |
|
2145 | + } elseif ($pluginType & Core::TEMPLATE_PLUGIN) { |
|
2146 | + array_unshift($params, '$this'); |
|
2147 | + $params = self::implode_r($params); |
|
2148 | + $output = 'Plugin' . Core::toCamelCase($func) . |
|
2149 | + $this->templatePlugins[$func]['uuid'] . '(' . $params . ')'; |
|
2150 | + $this->templatePlugins[$func]['called'] = true; |
|
2151 | + } |
|
2152 | + |
|
2153 | + if (is_array($parsingParams)) { |
|
2154 | + $parsingParams[] = array($output, $output); |
|
2155 | + |
|
2156 | + return $parsingParams; |
|
2157 | + } elseif ($curBlock === 'namedparam') { |
|
2158 | + return array($output, $output); |
|
2159 | + } else { |
|
2160 | + return $output; |
|
2161 | + } |
|
2162 | + } |
|
2163 | + |
|
2164 | + /** |
|
2165 | + * Parses a string. |
|
2166 | + * |
|
2167 | + * @param string $in the string within which we must parse something |
|
2168 | + * @param int $from the starting offset of the parsed area |
|
2169 | + * @param int $to the ending offset of the parsed area |
|
2170 | + * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2171 | + * default |
|
2172 | + * @param string $curBlock the current parser-block being processed |
|
2173 | + * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2174 | + * or null by default |
|
2175 | + * |
|
2176 | + * @return string parsed values |
|
2177 | + * @throws CompilationException |
|
2178 | + */ |
|
2179 | + protected function parseString($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2180 | + { |
|
2181 | + $substr = substr($in, $from, $to - $from); |
|
2182 | + $first = $substr[0]; |
|
2183 | + |
|
2184 | + if ($this->debug) { |
|
2185 | + echo 'STRING FOUND (in ' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . ')' . "\n"; |
|
2186 | + } |
|
2187 | + $strend = false; |
|
2188 | + $o = $from + 1; |
|
2189 | + while ($strend === false) { |
|
2190 | + $strend = strpos($in, $first, $o); |
|
2191 | + if ($strend === false) { |
|
2192 | + throw new CompilationException($this, 'Unfinished string, started with ' . substr($in, $from, $to - $from)); |
|
2193 | + } |
|
2194 | + if (substr($in, $strend - 1, 1) === '\\') { |
|
2195 | + $o = $strend + 1; |
|
2196 | + $strend = false; |
|
2197 | + } |
|
2198 | + } |
|
2199 | + if ($this->debug) { |
|
2200 | + echo 'STRING DELIMITED: ' . substr($in, $from, $strend + 1 - $from) . "\n"; |
|
2201 | + } |
|
2202 | + |
|
2203 | + $srcOutput = substr($in, $from, $strend + 1 - $from); |
|
2204 | + |
|
2205 | + if ($pointer !== null) { |
|
2206 | + $pointer += strlen($srcOutput); |
|
2207 | + } |
|
2208 | + |
|
2209 | + $output = $this->replaceStringVars($srcOutput, $first); |
|
2210 | + |
|
2211 | + // handle modifiers |
|
2212 | + if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend + 1 - $from), $match)) { |
|
2213 | + $modstr = $match[1]; |
|
2214 | + |
|
2215 | + if ($curBlock === 'root' && substr($modstr, - 1) === '}') { |
|
2216 | + $modstr = substr($modstr, 0, - 1); |
|
2217 | + } |
|
2218 | + $modstr = str_replace('\\' . $first, $first, $modstr); |
|
2219 | + $ptr = 0; |
|
2220 | + $output = $this->replaceModifiers(array(null, null, $output, $modstr), 'string', $ptr); |
|
2221 | + |
|
2222 | + $strend += $ptr; |
|
2223 | + if ($pointer !== null) { |
|
2224 | + $pointer += $ptr; |
|
2225 | + } |
|
2226 | + $srcOutput .= substr($substr, $strend + 1 - $from, $ptr); |
|
2227 | + } |
|
2228 | + |
|
2229 | + if (is_array($parsingParams)) { |
|
2230 | + $parsingParams[] = array($output, substr($srcOutput, 1, - 1)); |
|
2231 | + |
|
2232 | + return $parsingParams; |
|
2233 | + } elseif ($curBlock === 'namedparam') { |
|
2234 | + return array($output, substr($srcOutput, 1, - 1)); |
|
2235 | + } else { |
|
2236 | + return $output; |
|
2237 | + } |
|
2238 | + } |
|
2239 | + |
|
2240 | + /** |
|
2241 | + * Parses a constant. |
|
2242 | + * |
|
2243 | + * @param string $in the string within which we must parse something |
|
2244 | + * @param int $from the starting offset of the parsed area |
|
2245 | + * @param int $to the ending offset of the parsed area |
|
2246 | + * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2247 | + * default |
|
2248 | + * @param string $curBlock the current parser-block being processed |
|
2249 | + * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2250 | + * or null by default |
|
2251 | + * |
|
2252 | + * @return string parsed values |
|
2253 | + * @throws CompilationException |
|
2254 | + */ |
|
2255 | + protected function parseConst($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2256 | + { |
|
2257 | + $substr = substr($in, $from, $to - $from); |
|
2258 | + |
|
2259 | + if ($this->debug) { |
|
2260 | + echo 'CONST FOUND : ' . $substr . "\n"; |
|
2261 | + } |
|
2262 | + |
|
2263 | + if (!preg_match('#^%([\\\\a-z0-9_:]+)#i', $substr, $m)) { |
|
2264 | + throw new CompilationException($this, 'Invalid constant'); |
|
2265 | + } |
|
2266 | + |
|
2267 | + if ($pointer !== null) { |
|
2268 | + $pointer += strlen($m[0]); |
|
2269 | + } |
|
2270 | + |
|
2271 | + $output = $this->parseConstKey($m[1], $curBlock); |
|
2272 | + |
|
2273 | + if (is_array($parsingParams)) { |
|
2274 | + $parsingParams[] = array($output, $m[1]); |
|
2275 | + |
|
2276 | + return $parsingParams; |
|
2277 | + } elseif ($curBlock === 'namedparam') { |
|
2278 | + return array($output, $m[1]); |
|
2279 | + } else { |
|
2280 | + return $output; |
|
2281 | + } |
|
2282 | + } |
|
2283 | + |
|
2284 | + /** |
|
2285 | + * Parses a constant. |
|
2286 | + * |
|
2287 | + * @param string $key the constant to parse |
|
2288 | + * @param string $curBlock the current parser-block being processed |
|
2289 | + * |
|
2290 | + * @return string parsed constant |
|
2291 | + */ |
|
2292 | + protected function parseConstKey($key, $curBlock) |
|
2293 | + { |
|
2294 | + if ($this->securityPolicy !== null && $this->securityPolicy->getConstantHandling() === SecurityPolicy::CONST_DISALLOW) { |
|
2295 | + return 'null'; |
|
2296 | + } |
|
2297 | + |
|
2298 | + if ($curBlock !== 'root') { |
|
2299 | + $output = '(defined("' . $key . '") ? ' . $key . ' : null)'; |
|
2300 | + } else { |
|
2301 | + $output = $key; |
|
2302 | + } |
|
2303 | + |
|
2304 | + return $output; |
|
2305 | + } |
|
2306 | + |
|
2307 | + /** |
|
2308 | + * Parses a variable. |
|
2309 | + * |
|
2310 | + * @param string $in the string within which we must parse something |
|
2311 | + * @param int $from the starting offset of the parsed area |
|
2312 | + * @param int $to the ending offset of the parsed area |
|
2313 | + * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2314 | + * default |
|
2315 | + * @param string $curBlock the current parser-block being processed |
|
2316 | + * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2317 | + * or null by default |
|
2318 | + * |
|
2319 | + * @return string parsed values |
|
2320 | + * @throws CompilationException |
|
2321 | + */ |
|
2322 | + protected function parseVar($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2323 | + { |
|
2324 | + $methodCall = ''; |
|
2325 | + $substr = substr($in, $from, $to - $from); |
|
2326 | + |
|
2327 | + if (preg_match( |
|
2328 | + '#(\$?\.?[a-z0-9_:]*(?:(?:(?:\.|->)(?:[a-z0-9_:]+|(?R))|\[(?:[a-z0-9_:]+|(?R)|(["\'])[^\2]*?\2)\]))*)' . // var key |
|
2329 | + ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'expression' || $curBlock === 'delimited_string' ? '(\(.*)?' : '()') . // method call |
|
2330 | + ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'delimited_string' ? '((?:(?:[+/*%=-])(?:(?<!=)=?-?[$%][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9.,]*|[+-]))*)' : '()') . // simple math expressions |
|
2331 | + ($curBlock !== 'modifier' ? '((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').*?\5|:[^`]*))*))+)?' : '(())') . // modifiers |
|
2332 | + '#i', $substr, $match |
|
2333 | + )) { |
|
2334 | + $key = substr($match[1], 1); |
|
2335 | + |
|
2336 | + $matchedLength = strlen($match[0]); |
|
2337 | + $hasModifiers = !empty($match[5]); |
|
2338 | + $hasExpression = !empty($match[4]); |
|
2339 | + $hasMethodCall = !empty($match[3]); |
|
2340 | + |
|
2341 | + if (substr($key, - 1) == '.') { |
|
2342 | + $key = substr($key, 0, - 1); |
|
2343 | + -- $matchedLength; |
|
2344 | + } |
|
2345 | + |
|
2346 | + if ($hasMethodCall) { |
|
2347 | + $matchedLength -= strlen($match[3]) + strlen(substr($match[1], strrpos($match[1], '->'))); |
|
2348 | + $key = substr($match[1], 1, strrpos($match[1], '->') - 1); |
|
2349 | + $methodCall = substr($match[1], strrpos($match[1], '->')) . $match[3]; |
|
2350 | + } |
|
2351 | + |
|
2352 | + if ($hasModifiers) { |
|
2353 | + $matchedLength -= strlen($match[5]); |
|
2354 | + } |
|
2355 | + |
|
2356 | + if ($pointer !== null) { |
|
2357 | + $pointer += $matchedLength; |
|
2358 | + } |
|
2359 | + |
|
2360 | + // replace useless brackets by dot accessed vars and strip enclosing quotes if present |
|
2361 | + $key = preg_replace('#\[(["\']?)([^$%\[.>-]+)\1\]#', '.$2', $key); |
|
2362 | + |
|
2363 | + if ($this->debug) { |
|
2364 | + if ($hasMethodCall) { |
|
2365 | + echo 'METHOD CALL FOUND : $' . $key . substr($methodCall, 0, 30) . "\n"; |
|
2366 | + } else { |
|
2367 | + echo 'VAR FOUND : $' . $key . "\n"; |
|
2368 | + } |
|
2369 | + } |
|
2370 | + |
|
2371 | + $key = str_replace('"', '\\"', $key); |
|
2372 | + |
|
2373 | + $cnt = substr_count($key, '$'); |
|
2374 | + if ($cnt > 0) { |
|
2375 | + $uid = 0; |
|
2376 | + $parsed = array($uid => ''); |
|
2377 | + $current = &$parsed; |
|
2378 | + $curTxt = &$parsed[$uid ++]; |
|
2379 | + $tree = array(); |
|
2380 | + $chars = str_split($key, 1); |
|
2381 | + $inSplittedVar = false; |
|
2382 | + $bracketCount = 0; |
|
2383 | + |
|
2384 | + while (($char = array_shift($chars)) !== null) { |
|
2385 | + if ($char === '[') { |
|
2386 | + if (count($tree) > 0) { |
|
2387 | + ++ $bracketCount; |
|
2388 | + } else { |
|
2389 | + $tree[] = &$current; |
|
2390 | + $current[$uid] = array($uid + 1 => ''); |
|
2391 | + $current = &$current[$uid ++]; |
|
2392 | + $curTxt = &$current[$uid ++]; |
|
2393 | + continue; |
|
2394 | + } |
|
2395 | + } elseif ($char === ']') { |
|
2396 | + if ($bracketCount > 0) { |
|
2397 | + -- $bracketCount; |
|
2398 | + } else { |
|
2399 | + $current = &$tree[count($tree) - 1]; |
|
2400 | + array_pop($tree); |
|
2401 | + if (current($chars) !== '[' && current($chars) !== false && current($chars) !== ']') { |
|
2402 | + $current[$uid] = ''; |
|
2403 | + $curTxt = &$current[$uid ++]; |
|
2404 | + } |
|
2405 | + continue; |
|
2406 | + } |
|
2407 | + } elseif ($char === '$') { |
|
2408 | + if (count($tree) == 0) { |
|
2409 | + $curTxt = &$current[$uid ++]; |
|
2410 | + $inSplittedVar = true; |
|
2411 | + } |
|
2412 | + } elseif (($char === '.' || $char === '-') && count($tree) == 0 && $inSplittedVar) { |
|
2413 | + $curTxt = &$current[$uid ++]; |
|
2414 | + $inSplittedVar = false; |
|
2415 | + } |
|
2416 | + |
|
2417 | + $curTxt .= $char; |
|
2418 | + } |
|
2419 | + unset($uid, $current, $curTxt, $tree, $chars); |
|
2420 | + |
|
2421 | + if ($this->debug) { |
|
2422 | + echo 'RECURSIVE VAR REPLACEMENT : ' . $key . "\n"; |
|
2423 | + } |
|
2424 | + |
|
2425 | + $key = $this->flattenVarTree($parsed); |
|
2426 | + |
|
2427 | + if ($this->debug) { |
|
2428 | + echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n"; |
|
2429 | + } |
|
2430 | + |
|
2431 | + $output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("' . $key . '")'); |
|
2432 | + } else { |
|
2433 | + $output = $this->parseVarKey($key, $hasModifiers ? 'modifier' : $curBlock); |
|
2434 | + } |
|
2435 | + |
|
2436 | + // methods |
|
2437 | + if ($hasMethodCall) { |
|
2438 | + $ptr = 0; |
|
2439 | + |
|
2440 | + $output = $this->parseMethodCall($output, $methodCall, $curBlock, $ptr); |
|
2441 | + |
|
2442 | + if ($pointer !== null) { |
|
2443 | + $pointer += $ptr; |
|
2444 | + } |
|
2445 | + $matchedLength += $ptr; |
|
2446 | + } |
|
2447 | + |
|
2448 | + if ($hasExpression) { |
|
2449 | + // expressions |
|
2450 | + preg_match_all('#(?:([+/*%=-])(=?-?[%$][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|=?-?[0-9.,]+|\1))#i', $match[4], $expMatch); |
|
2451 | + |
|
2452 | + foreach ($expMatch[1] as $k => $operator) { |
|
2453 | + if (substr($expMatch[2][$k], 0, 1) === '=') { |
|
2454 | + $assign = true; |
|
2455 | + if ($operator === '=') { |
|
2456 | + throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, can not use "==" in expressions'); |
|
2457 | + } |
|
2458 | + if ($curBlock !== 'root') { |
|
2459 | + throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}'); |
|
2460 | + } |
|
2461 | + $operator .= '='; |
|
2462 | + $expMatch[2][$k] = substr($expMatch[2][$k], 1); |
|
2463 | + } |
|
2464 | + |
|
2465 | + if (substr($expMatch[2][$k], 0, 1) === '-' && strlen($expMatch[2][$k]) > 1) { |
|
2466 | + $operator .= '-'; |
|
2467 | + $expMatch[2][$k] = substr($expMatch[2][$k], 1); |
|
2468 | + } |
|
2469 | + if (($operator === '+' || $operator === '-') && $expMatch[2][$k] === $operator) { |
|
2470 | + $output = '(' . $output . $operator . $operator . ')'; |
|
2471 | + break; |
|
2472 | + } elseif (substr($expMatch[2][$k], 0, 1) === '$') { |
|
2473 | + $output = '(' . $output . ' ' . $operator . ' ' . $this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')'; |
|
2474 | + } elseif (substr($expMatch[2][$k], 0, 1) === '%') { |
|
2475 | + $output = '(' . $output . ' ' . $operator . ' ' . $this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')'; |
|
2476 | + } elseif (!empty($expMatch[2][$k])) { |
|
2477 | + $output = '(' . $output . ' ' . $operator . ' ' . str_replace(',', '.', $expMatch[2][$k]) . ')'; |
|
2478 | + } else { |
|
2479 | + throw new CompilationException($this, 'Unfinished expression <em>' . $substr . '</em>, missing var or number after math operator'); |
|
2480 | + } |
|
2481 | + } |
|
2482 | + } |
|
2483 | + |
|
2484 | + if ($this->autoEscape === true && $curBlock !== 'condition') { |
|
2485 | + $output = '(is_string($tmp=' . $output . ') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)'; |
|
2486 | + } |
|
2487 | + |
|
2488 | + // handle modifiers |
|
2489 | + if ($curBlock !== 'modifier' && $hasModifiers) { |
|
2490 | + $ptr = 0; |
|
2491 | + $output = $this->replaceModifiers(array(null, null, $output, $match[5]), 'var', $ptr); |
|
2492 | + if ($pointer !== null) { |
|
2493 | + $pointer += $ptr; |
|
2494 | + } |
|
2495 | + $matchedLength += $ptr; |
|
2496 | + } |
|
2497 | + |
|
2498 | + if (is_array($parsingParams)) { |
|
2499 | + $parsingParams[] = array($output, $key); |
|
2500 | + |
|
2501 | + return $parsingParams; |
|
2502 | + } elseif ($curBlock === 'namedparam') { |
|
2503 | + return array($output, $key); |
|
2504 | + } elseif ($curBlock === 'string' || $curBlock === 'delimited_string') { |
|
2505 | + return array($matchedLength, $output); |
|
2506 | + } elseif ($curBlock === 'expression' || $curBlock === 'variable') { |
|
2507 | + return $output; |
|
2508 | + } elseif (isset($assign)) { |
|
2509 | + return self::PHP_OPEN . $output . ';' . self::PHP_CLOSE; |
|
2510 | + } else { |
|
2511 | + return $output; |
|
2512 | + } |
|
2513 | + } else { |
|
2514 | + if ($curBlock === 'string' || $curBlock === 'delimited_string') { |
|
2515 | + return array(0, ''); |
|
2516 | + } else { |
|
2517 | + throw new CompilationException($this, 'Invalid variable name <em>' . $substr . '</em>'); |
|
2518 | + } |
|
2519 | + } |
|
2520 | + } |
|
2521 | + |
|
2522 | + /** |
|
2523 | + * Parses any number of chained method calls/property reads. |
|
2524 | + * |
|
2525 | + * @param string $output the variable or whatever upon which the method are called |
|
2526 | + * @param string $methodCall method call source, starting at "->" |
|
2527 | + * @param string $curBlock the current parser-block being processed |
|
2528 | + * @param int $pointer a reference to a pointer that will be increased by the amount of characters parsed |
|
2529 | + * |
|
2530 | + * @return string parsed call(s)/read(s) |
|
2531 | + */ |
|
2532 | + protected function parseMethodCall($output, $methodCall, $curBlock, &$pointer) |
|
2533 | + { |
|
2534 | + $ptr = 0; |
|
2535 | + $len = strlen($methodCall); |
|
2536 | + |
|
2537 | + while ($ptr < $len) { |
|
2538 | + if (strpos($methodCall, '->', $ptr) === $ptr) { |
|
2539 | + $ptr += 2; |
|
2540 | + } |
|
2541 | + |
|
2542 | + if (in_array( |
|
2543 | + $methodCall[$ptr], array( |
|
2544 | + ';', |
|
2545 | + ',', |
|
2546 | + '/', |
|
2547 | + ' ', |
|
2548 | + "\t", |
|
2549 | + "\r", |
|
2550 | + "\n", |
|
2551 | + ')', |
|
2552 | + '+', |
|
2553 | + '*', |
|
2554 | + '%', |
|
2555 | + '=', |
|
2556 | + '-', |
|
2557 | + '|' |
|
2558 | + ) |
|
2559 | + ) || substr($methodCall, $ptr, strlen($this->rd)) === $this->rd |
|
2560 | + ) { |
|
2561 | + // break char found |
|
2562 | + break; |
|
2563 | + } |
|
2564 | + |
|
2565 | + if (!preg_match('/^([a-z0-9_]+)(\(.*?\))?/i', substr($methodCall, $ptr), $methMatch)) { |
|
2566 | + break; |
|
2567 | + } |
|
2568 | + |
|
2569 | + if (empty($methMatch[2])) { |
|
2570 | + // property |
|
2571 | + if ($curBlock === 'root') { |
|
2572 | + $output .= '->' . $methMatch[1]; |
|
2573 | + } else { |
|
2574 | + $output = '(($tmp = ' . $output . ') ? $tmp->' . $methMatch[1] . ' : null)'; |
|
2575 | + } |
|
2576 | + $ptr += strlen($methMatch[1]); |
|
2577 | + } else { |
|
2578 | + // method |
|
2579 | + if (substr($methMatch[2], 0, 2) === '()') { |
|
2580 | + $parsedCall = $methMatch[1] . '()'; |
|
2581 | + $ptr += strlen($methMatch[1]) + 2; |
|
2582 | + } else { |
|
2583 | + $parsedCall = $this->parseFunction($methodCall, $ptr, strlen($methodCall), false, 'method', $ptr); |
|
2584 | + } |
|
2585 | + if ($this->securityPolicy !== null) { |
|
2586 | + $argPos = strpos($parsedCall, '('); |
|
2587 | + $method = strtolower(substr($parsedCall, 0, $argPos)); |
|
2588 | + $args = substr($parsedCall, $argPos); |
|
2589 | + if ($curBlock === 'root') { |
|
2590 | + $output = '$this->getSecurityPolicy()->callMethod($this, ' . $output . ', ' . var_export($method, true) . ', array' . $args . ')'; |
|
2591 | + } else { |
|
2592 | + $output = '(($tmp = ' . $output . ') ? $this->getSecurityPolicy()->callMethod($this, $tmp, ' . var_export($method, true) . ', array' . $args . ') : null)'; |
|
2593 | + } |
|
2594 | + } else { |
|
2595 | + if ($curBlock === 'root') { |
|
2596 | + $output .= '->' . $parsedCall; |
|
2597 | + } else { |
|
2598 | + $output = '(($tmp = ' . $output . ') ? $tmp->' . $parsedCall . ' : null)'; |
|
2599 | + } |
|
2600 | + } |
|
2601 | + } |
|
2602 | + } |
|
2603 | + |
|
2604 | + $pointer += $ptr; |
|
2605 | + |
|
2606 | + return $output; |
|
2607 | + } |
|
2608 | + |
|
2609 | + /** |
|
2610 | + * Parses a constant variable (a variable that doesn't contain another variable) and preprocesses it to save |
|
2611 | + * runtime processing time. |
|
2612 | + * |
|
2613 | + * @param string $key the variable to parse |
|
2614 | + * @param string $curBlock the current parser-block being processed |
|
2615 | + * |
|
2616 | + * @return string parsed variable |
|
2617 | + */ |
|
2618 | + protected function parseVarKey($key, $curBlock) |
|
2619 | + { |
|
2620 | + if ($key === '') { |
|
2621 | + return '$this->scope'; |
|
2622 | + } |
|
2623 | + if (substr($key, 0, 1) === '.') { |
|
2624 | + $key = 'dwoo' . $key; |
|
2625 | + } |
|
2626 | + if (preg_match('#dwoo\.(get|post|server|cookies|session|env|request)((?:\.[a-z0-9_-]+)+)#i', $key, $m)) { |
|
2627 | + $global = strtoupper($m[1]); |
|
2628 | + if ($global === 'COOKIES') { |
|
2629 | + $global = 'COOKIE'; |
|
2630 | + } |
|
2631 | + $key = '$_' . $global; |
|
2632 | + foreach (explode('.', ltrim($m[2], '.')) as $part) { |
|
2633 | + $key .= '[' . var_export($part, true) . ']'; |
|
2634 | + } |
|
2635 | + if ($curBlock === 'root') { |
|
2636 | + $output = $key; |
|
2637 | + } else { |
|
2638 | + $output = '(isset(' . $key . ')?' . $key . ':null)'; |
|
2639 | + } |
|
2640 | + } elseif (preg_match('#dwoo\.const\.([a-z0-9_:]+)#i', $key, $m)) { |
|
2641 | + return $this->parseConstKey($m[1], $curBlock); |
|
2642 | + } elseif ($this->scope !== null) { |
|
2643 | + if (strstr($key, '.') === false && strstr($key, '[') === false && strstr($key, '->') === false) { |
|
2644 | + if ($key === 'dwoo') { |
|
2645 | + $output = '$this->globals'; |
|
2646 | + } elseif ($key === '_root' || $key === '__') { |
|
2647 | + $output = '$this->data'; |
|
2648 | + } elseif ($key === '_parent' || $key === '_') { |
|
2649 | + $output = '$this->readParentVar(1)'; |
|
2650 | + } elseif ($key === '_key') { |
|
2651 | + $output = '$tmp_key'; |
|
2652 | + } else { |
|
2653 | + if ($curBlock === 'root') { |
|
2654 | + $output = '$this->scope["' . $key . '"]'; |
|
2655 | + } else { |
|
2656 | + $output = '(isset($this->scope["' . $key . '"]) ? $this->scope["' . $key . '"] : null)'; |
|
2657 | + } |
|
2658 | + } |
|
2659 | + } else { |
|
2660 | + preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+|(\\\?[\'"])[^\3]*?\3)\]?#i', $key, $m); |
|
2661 | + |
|
2662 | + $i = $m[2][0]; |
|
2663 | + if ($i === '_parent' || $i === '_') { |
|
2664 | + $parentCnt = 0; |
|
2665 | + |
|
2666 | + while (true) { |
|
2667 | + ++ $parentCnt; |
|
2668 | + array_shift($m[2]); |
|
2669 | + array_shift($m[1]); |
|
2670 | + if (current($m[2]) === '_parent') { |
|
2671 | + continue; |
|
2672 | + } |
|
2673 | + break; |
|
2674 | + } |
|
2675 | + |
|
2676 | + $output = '$this->readParentVar(' . $parentCnt . ')'; |
|
2677 | + } else { |
|
2678 | + if ($i === 'dwoo') { |
|
2679 | + $output = '$this->globals'; |
|
2680 | + array_shift($m[2]); |
|
2681 | + array_shift($m[1]); |
|
2682 | + } elseif ($i === '_root' || $i === '__') { |
|
2683 | + $output = '$this->data'; |
|
2684 | + array_shift($m[2]); |
|
2685 | + array_shift($m[1]); |
|
2686 | + } elseif ($i === '_key') { |
|
2687 | + $output = '$tmp_key'; |
|
2688 | + } else { |
|
2689 | + $output = '$this->scope'; |
|
2690 | + } |
|
2691 | + |
|
2692 | + while (count($m[1]) && $m[1][0] !== '->') { |
|
2693 | + $m[2][0] = preg_replace('/(^\\\([\'"])|\\\([\'"])$)/x', '$2$3', $m[2][0]); |
|
2694 | + if (substr($m[2][0], 0, 1) == '"' || substr($m[2][0], 0, 1) == "'") { |
|
2695 | + $output .= '[' . $m[2][0] . ']'; |
|
2696 | + } else { |
|
2697 | + $output .= '["' . $m[2][0] . '"]'; |
|
2698 | + } |
|
2699 | + array_shift($m[2]); |
|
2700 | + array_shift($m[1]); |
|
2701 | + } |
|
2702 | + |
|
2703 | + if ($curBlock !== 'root') { |
|
2704 | + $output = '(isset(' . $output . ') ? ' . $output . ':null)'; |
|
2705 | + } |
|
2706 | + } |
|
2707 | + |
|
2708 | + if (count($m[2])) { |
|
2709 | + unset($m[0]); |
|
2710 | + $output = '$this->readVarInto(' . str_replace("\n", '', var_export($m, true)) . ', ' . $output . ', ' . ($curBlock == 'root' ? 'false' : 'true') . ')'; |
|
2711 | + } |
|
2712 | + } |
|
2713 | + } else { |
|
2714 | + preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+)\]?#i', $key, $m); |
|
2715 | + unset($m[0]); |
|
2716 | + $output = '$this->readVar(' . str_replace("\n", '', var_export($m, true)) . ')'; |
|
2717 | + } |
|
2718 | + |
|
2719 | + return $output; |
|
2720 | + } |
|
2721 | + |
|
2722 | + /** |
|
2723 | + * Flattens a variable tree, this helps in parsing very complex variables such as $var.foo[$foo.bar->baz].baz, |
|
2724 | + * it computes the contents of the brackets first and works out from there. |
|
2725 | + * |
|
2726 | + * @param array $tree the variable tree parsed by he parseVar() method that must be flattened |
|
2727 | + * @param bool $recursed leave that to false by default, it is only for internal use |
|
2728 | + * |
|
2729 | + * @return string flattened tree |
|
2730 | + */ |
|
2731 | + protected function flattenVarTree(array $tree, $recursed = false) |
|
2732 | + { |
|
2733 | + $out = $recursed ? '".$this->readVarInto(' : ''; |
|
2734 | + foreach ($tree as $bit) { |
|
2735 | + if (is_array($bit)) { |
|
2736 | + $out .= '.' . $this->flattenVarTree($bit, false); |
|
2737 | + } else { |
|
2738 | + $key = str_replace('"', '\\"', $bit); |
|
2739 | + |
|
2740 | + if (substr($key, 0, 1) === '$') { |
|
2741 | + $out .= '".' . $this->parseVar($key, 0, strlen($key), false, 'variable') . '."'; |
|
2742 | + } else { |
|
2743 | + $cnt = substr_count($key, '$'); |
|
2744 | + |
|
2745 | + if ($this->debug) { |
|
2746 | + echo 'PARSING SUBVARS IN : ' . $key . "\n"; |
|
2747 | + } |
|
2748 | + if ($cnt > 0) { |
|
2749 | + while (-- $cnt >= 0) { |
|
2750 | + if (isset($last)) { |
|
2751 | + $last = strrpos($key, '$', - (strlen($key) - $last + 1)); |
|
2752 | + } else { |
|
2753 | + $last = strrpos($key, '$'); |
|
2754 | + } |
|
2755 | + preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch); |
|
2756 | + |
|
2757 | + $len = strlen($submatch[0]); |
|
2758 | + $key = substr_replace( |
|
2759 | + $key, preg_replace_callback( |
|
2760 | + '#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array( |
|
2761 | + $this, |
|
2762 | + 'replaceVarKeyHelper' |
|
2763 | + ), substr($key, $last, $len) |
|
2764 | + ), $last, $len |
|
2765 | + ); |
|
2766 | + if ($this->debug) { |
|
2767 | + echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n"; |
|
2768 | + } |
|
2769 | + } |
|
2770 | + unset($last); |
|
2771 | + |
|
2772 | + $out .= $key; |
|
2773 | + } else { |
|
2774 | + $out .= $key; |
|
2775 | + } |
|
2776 | + } |
|
2777 | + } |
|
2778 | + } |
|
2779 | + $out .= $recursed ? ', true)."' : ''; |
|
2780 | + |
|
2781 | + return $out; |
|
2782 | + } |
|
2783 | + |
|
2784 | + /** |
|
2785 | + * Helper function that parses a variable. |
|
2786 | + * |
|
2787 | + * @param array $match the matched variable, array(1=>"string match") |
|
2788 | + * |
|
2789 | + * @return string parsed variable |
|
2790 | + */ |
|
2791 | + protected function replaceVarKeyHelper($match) |
|
2792 | + { |
|
2793 | + return '".' . $this->parseVar($match[0], 0, strlen($match[0]), false, 'variable') . '."'; |
|
2794 | + } |
|
2795 | + |
|
2796 | + /** |
|
2797 | + * Parses various constants, operators or non-quoted strings. |
|
2798 | + * |
|
2799 | + * @param string $in the string within which we must parse something |
|
2800 | + * @param int $from the starting offset of the parsed area |
|
2801 | + * @param int $to the ending offset of the parsed area |
|
2802 | + * @param mixed $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by |
|
2803 | + * default |
|
2804 | + * @param string $curBlock the current parser-block being processed |
|
2805 | + * @param mixed $pointer a reference to a pointer that will be increased by the amount of characters parsed, |
|
2806 | + * or null by default |
|
2807 | + * |
|
2808 | + * @return string parsed values |
|
2809 | + * @throws Exception |
|
2810 | + */ |
|
2811 | + protected function parseOthers($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
|
2812 | + { |
|
2813 | + $substr = substr($in, $from, $to - $from); |
|
2814 | + |
|
2815 | + $end = strlen($substr); |
|
2816 | + |
|
2817 | + if ($curBlock === 'condition') { |
|
2818 | + $breakChars = array( |
|
2819 | + '(', |
|
2820 | + ')', |
|
2821 | + ' ', |
|
2822 | + '||', |
|
2823 | + '&&', |
|
2824 | + '|', |
|
2825 | + '&', |
|
2826 | + '>=', |
|
2827 | + '<=', |
|
2828 | + '===', |
|
2829 | + '==', |
|
2830 | + '=', |
|
2831 | + '!==', |
|
2832 | + '!=', |
|
2833 | + '<<', |
|
2834 | + '<', |
|
2835 | + '>>', |
|
2836 | + '>', |
|
2837 | + '^', |
|
2838 | + '~', |
|
2839 | + ',', |
|
2840 | + '+', |
|
2841 | + '-', |
|
2842 | + '*', |
|
2843 | + '/', |
|
2844 | + '%', |
|
2845 | + '!', |
|
2846 | + '?', |
|
2847 | + ':', |
|
2848 | + $this->rd, |
|
2849 | + ';' |
|
2850 | + ); |
|
2851 | + } elseif ($curBlock === 'modifier') { |
|
2852 | + $breakChars = array(' ', ',', ')', ':', '|', "\r", "\n", "\t", ';', $this->rd); |
|
2853 | + } elseif ($curBlock === 'expression') { |
|
2854 | + $breakChars = array('/', '%', '+', '-', '*', ' ', ',', ')', "\r", "\n", "\t", ';', $this->rd); |
|
2855 | + } else { |
|
2856 | + $breakChars = array(' ', ',', ')', "\r", "\n", "\t", ';', $this->rd); |
|
2857 | + } |
|
2858 | + |
|
2859 | + $breaker = false; |
|
2860 | + while (list($k, $char) = each($breakChars)) { |
|
2861 | + $test = strpos($substr, $char); |
|
2862 | + if ($test !== false && $test < $end) { |
|
2863 | + $end = $test; |
|
2864 | + $breaker = $k; |
|
2865 | + } |
|
2866 | + } |
|
2867 | + |
|
2868 | + if ($curBlock === 'condition') { |
|
2869 | + if ($end === 0 && $breaker !== false) { |
|
2870 | + $end = strlen($breakChars[$breaker]); |
|
2871 | + } |
|
2872 | + } |
|
2873 | + |
|
2874 | + if ($end !== false) { |
|
2875 | + $substr = substr($substr, 0, $end); |
|
2876 | + } |
|
2877 | + |
|
2878 | + if ($pointer !== null) { |
|
2879 | + $pointer += strlen($substr); |
|
2880 | + } |
|
2881 | + |
|
2882 | + $src = $substr; |
|
2883 | + $substr = trim($substr); |
|
2884 | + |
|
2885 | + if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') { |
|
2886 | + if ($this->debug) { |
|
2887 | + echo 'BOOLEAN(FALSE) PARSED' . "\n"; |
|
2888 | + } |
|
2889 | + $substr = 'false'; |
|
2890 | + $type = self::T_BOOL; |
|
2891 | + } elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') { |
|
2892 | + if ($this->debug) { |
|
2893 | + echo 'BOOLEAN(TRUE) PARSED' . "\n"; |
|
2894 | + } |
|
2895 | + $substr = 'true'; |
|
2896 | + $type = self::T_BOOL; |
|
2897 | + } elseif ($substr === 'null' || $substr === 'NULL') { |
|
2898 | + if ($this->debug) { |
|
2899 | + echo 'NULL PARSED' . "\n"; |
|
2900 | + } |
|
2901 | + $substr = 'null'; |
|
2902 | + $type = self::T_NULL; |
|
2903 | + } elseif (is_numeric($substr)) { |
|
2904 | + $substr = (float)$substr; |
|
2905 | + if ((int)$substr == $substr) { |
|
2906 | + $substr = (int)$substr; |
|
2907 | + } |
|
2908 | + $type = self::T_NUMERIC; |
|
2909 | + if ($this->debug) { |
|
2910 | + echo 'NUMBER (' . $substr . ') PARSED' . "\n"; |
|
2911 | + } |
|
2912 | + } elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) { |
|
2913 | + if ($this->debug) { |
|
2914 | + echo 'SIMPLE MATH PARSED . "\n"'; |
|
2915 | + } |
|
2916 | + $type = self::T_MATH; |
|
2917 | + $substr = '(' . $substr . ')'; |
|
2918 | + } elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) { |
|
2919 | + if ($this->debug) { |
|
2920 | + echo 'BREAKCHAR (' . $substr . ') PARSED' . "\n"; |
|
2921 | + } |
|
2922 | + $type = self::T_BREAKCHAR; |
|
2923 | + //$substr = '"'.$substr.'"'; |
|
2924 | + } else { |
|
2925 | + $substr = $this->replaceStringVars('\'' . str_replace('\'', '\\\'', $substr) . '\'', '\'', $curBlock); |
|
2926 | + $type = self::T_UNQUOTED_STRING; |
|
2927 | + if ($this->debug) { |
|
2928 | + echo 'BLABBER (' . $substr . ') CASTED AS STRING' . "\n"; |
|
2929 | + } |
|
2930 | + } |
|
2931 | + |
|
2932 | + if (is_array($parsingParams)) { |
|
2933 | + $parsingParams[] = array($substr, $src, $type); |
|
2934 | + |
|
2935 | + return $parsingParams; |
|
2936 | + } elseif ($curBlock === 'namedparam') { |
|
2937 | + return array($substr, $src, $type); |
|
2938 | + } elseif ($curBlock === 'expression') { |
|
2939 | + return $substr; |
|
2940 | + } else { |
|
2941 | + throw new Exception('Something went wrong'); |
|
2942 | + } |
|
2943 | + } |
|
2944 | + |
|
2945 | + /** |
|
2946 | + * Replaces variables within a parsed string. |
|
2947 | + * |
|
2948 | + * @param string $string the parsed string |
|
2949 | + * @param string $first the first character parsed in the string, which is the string delimiter (' or ") |
|
2950 | + * @param string $curBlock the current parser-block being processed |
|
2951 | + * |
|
2952 | + * @return string the original string with variables replaced |
|
2953 | + */ |
|
2954 | + protected function replaceStringVars($string, $first, $curBlock = '') |
|
2955 | + { |
|
2956 | + $pos = 0; |
|
2957 | + if ($this->debug) { |
|
2958 | + echo 'STRING VAR REPLACEMENT : ' . $string . "\n"; |
|
2959 | + } |
|
2960 | + // replace vars |
|
2961 | + while (($pos = strpos($string, '$', $pos)) !== false) { |
|
2962 | + $prev = substr($string, $pos - 1, 1); |
|
2963 | + if ($prev === '\\') { |
|
2964 | + ++ $pos; |
|
2965 | + continue; |
|
2966 | + } |
|
2967 | + |
|
2968 | + $var = $this->parse($string, $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string'))); |
|
2969 | + $len = $var[0]; |
|
2970 | + $var = $this->parse(str_replace('\\' . $first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string'))); |
|
2971 | + |
|
2972 | + if ($prev === '`' && substr($string, $pos + $len, 1) === '`') { |
|
2973 | + $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos - 1, $len + 2); |
|
2974 | + } else { |
|
2975 | + $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos, $len); |
|
2976 | + } |
|
2977 | + $pos += strlen($var[1]) + 2; |
|
2978 | + if ($this->debug) { |
|
2979 | + echo 'STRING VAR REPLACEMENT DONE : ' . $string . "\n"; |
|
2980 | + } |
|
2981 | + } |
|
2982 | + |
|
2983 | + // handle modifiers |
|
2984 | + // TODO Obsolete? |
|
2985 | + $string = preg_replace_callback( |
|
2986 | + '#("|\')\.(.+?)\.\1((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').+?\4|:[^`]*))*))+)#i', array( |
|
2987 | + $this, |
|
2988 | + 'replaceModifiers' |
|
2989 | + ), $string |
|
2990 | + ); |
|
2991 | + |
|
2992 | + // replace escaped dollar operators by unescaped ones if required |
|
2993 | + if ($first === "'") { |
|
2994 | + $string = str_replace('\\$', '$', $string); |
|
2995 | + } |
|
2996 | + |
|
2997 | + return $string; |
|
2998 | + } |
|
2999 | + |
|
3000 | + /** |
|
3001 | + * Replaces the modifiers applied to a string or a variable. |
|
3002 | + * |
|
3003 | + * @param array $m the regex matches that must be array(1=>"double or single quotes enclosing a string, |
|
3004 | + * when applicable", 2=>"the string or var", 3=>"the modifiers matched") |
|
3005 | + * @param string $curBlock the current parser-block being processed |
|
3006 | + * @param null $pointer |
|
3007 | + * |
|
3008 | + * @return string the input enclosed with various function calls according to the modifiers found |
|
3009 | + * @throws CompilationException |
|
3010 | + * @throws Exception |
|
3011 | + */ |
|
3012 | + protected function replaceModifiers(array $m, $curBlock = null, &$pointer = null) |
|
3013 | + { |
|
3014 | + if ($this->debug) { |
|
3015 | + echo 'PARSING MODIFIERS : ' . $m[3] . "\n"; |
|
3016 | + } |
|
3017 | + |
|
3018 | + if ($pointer !== null) { |
|
3019 | + $pointer += strlen($m[3]); |
|
3020 | + } |
|
3021 | + // remove first pipe |
|
3022 | + $cmdstrsrc = substr($m[3], 1); |
|
3023 | + // remove last quote if present |
|
3024 | + if (substr($cmdstrsrc, - 1, 1) === $m[1]) { |
|
3025 | + $cmdstrsrc = substr($cmdstrsrc, 0, - 1); |
|
3026 | + $add = $m[1]; |
|
3027 | + } |
|
3028 | + |
|
3029 | + $output = $m[2]; |
|
3030 | + |
|
3031 | + $continue = true; |
|
3032 | + while (strlen($cmdstrsrc) > 0 && $continue) { |
|
3033 | + if ($cmdstrsrc[0] === '|') { |
|
3034 | + $cmdstrsrc = substr($cmdstrsrc, 1); |
|
3035 | + continue; |
|
3036 | + } |
|
3037 | + if ($cmdstrsrc[0] === ' ' || $cmdstrsrc[0] === ';' || substr($cmdstrsrc, 0, strlen($this->rd)) === $this->rd) { |
|
3038 | + if ($this->debug) { |
|
3039 | + echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND' . "\n"; |
|
3040 | + } |
|
3041 | + $continue = false; |
|
3042 | + if ($pointer !== null) { |
|
3043 | + $pointer -= strlen($cmdstrsrc); |
|
3044 | + } |
|
3045 | + break; |
|
3046 | + } |
|
3047 | + $cmdstr = $cmdstrsrc; |
|
3048 | + $paramsep = ':'; |
|
3049 | + if (!preg_match('/^(@{0,2}[a-z_][a-z0-9_]*)(:)?/i', $cmdstr, $match)) { |
|
3050 | + throw new CompilationException($this, 'Invalid modifier name, started with : ' . substr($cmdstr, 0, 10)); |
|
3051 | + } |
|
3052 | + $paramspos = !empty($match[2]) ? strlen($match[1]) : false; |
|
3053 | + $func = $match[1]; |
|
3054 | + |
|
3055 | + $state = 0; |
|
3056 | + if ($paramspos === false) { |
|
3057 | + $cmdstrsrc = substr($cmdstrsrc, strlen($func)); |
|
3058 | + $params = array(); |
|
3059 | + if ($this->debug) { |
|
3060 | + echo 'MODIFIER (' . $func . ') CALLED WITH NO PARAMS' . "\n"; |
|
3061 | + } |
|
3062 | + } else { |
|
3063 | + $paramstr = substr($cmdstr, $paramspos + 1); |
|
3064 | + if (substr($paramstr, - 1, 1) === $paramsep) { |
|
3065 | + $paramstr = substr($paramstr, 0, - 1); |
|
3066 | + } |
|
3067 | + |
|
3068 | + $ptr = 0; |
|
3069 | + $params = array(); |
|
3070 | + while ($ptr < strlen($paramstr)) { |
|
3071 | + if ($this->debug) { |
|
3072 | + echo 'MODIFIER (' . $func . ') START PARAM PARSING WITH POINTER AT ' . $ptr . "\n"; |
|
3073 | + } |
|
3074 | + if ($this->debug) { |
|
3075 | + echo $paramstr . '--' . $ptr . '--' . strlen($paramstr) . '--modifier' . "\n"; |
|
3076 | + } |
|
3077 | + $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'modifier', $ptr); |
|
3078 | + if ($this->debug) { |
|
3079 | + echo 'PARAM PARSED, POINTER AT ' . $ptr . "\n"; |
|
3080 | + } |
|
3081 | + |
|
3082 | + if ($ptr >= strlen($paramstr)) { |
|
3083 | + if ($this->debug) { |
|
3084 | + echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED' . "\n"; |
|
3085 | + } |
|
3086 | + break; |
|
3087 | + } |
|
3088 | + |
|
3089 | + if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === '|' || $paramstr[$ptr] === ';' || substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) { |
|
3090 | + if ($this->debug) { |
|
3091 | + echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT ' . $ptr . "\n"; |
|
3092 | + } |
|
3093 | + if ($paramstr[$ptr] !== '|') { |
|
3094 | + $continue = false; |
|
3095 | + if ($pointer !== null) { |
|
3096 | + $pointer -= strlen($paramstr) - $ptr; |
|
3097 | + } |
|
3098 | + } |
|
3099 | + ++ $ptr; |
|
3100 | + break; |
|
3101 | + } |
|
3102 | + if ($ptr < strlen($paramstr) && $paramstr[$ptr] === ':') { |
|
3103 | + ++ $ptr; |
|
3104 | + } |
|
3105 | + } |
|
3106 | + $cmdstrsrc = substr($cmdstrsrc, strlen($func) + 1 + $ptr); |
|
3107 | + foreach ($params as $k => $p) { |
|
3108 | + if (is_array($p) && is_array($p[1])) { |
|
3109 | + $state |= 2; |
|
3110 | + } else { |
|
3111 | + if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m)) { |
|
3112 | + $params[$k] = array($m[2], array('true', 'true')); |
|
3113 | + } else { |
|
3114 | + if ($state & 2) { |
|
3115 | + throw new CompilationException($this, 'You can not use an unnamed parameter after a named one'); |
|
3116 | + } |
|
3117 | + $state |= 1; |
|
3118 | + } |
|
3119 | + } |
|
3120 | + } |
|
3121 | + } |
|
3122 | + |
|
3123 | + // check if we must use array_map with this plugin or not |
|
3124 | + $mapped = false; |
|
3125 | + if (substr($func, 0, 1) === '@') { |
|
3126 | + $func = substr($func, 1); |
|
3127 | + $mapped = true; |
|
3128 | + } |
|
3129 | + |
|
3130 | + $pluginType = $this->getPluginType($func); |
|
3131 | + |
|
3132 | + if ($state & 2) { |
|
3133 | + array_unshift($params, array('value', is_array($output) ? $output : array($output, $output))); |
|
3134 | + } else { |
|
3135 | + array_unshift($params, is_array($output) ? $output : array($output, $output)); |
|
3136 | + } |
|
3137 | + |
|
3138 | + if ($pluginType & Core::NATIVE_PLUGIN) { |
|
3139 | + $params = $this->mapParams($params, null, $state); |
|
3140 | + |
|
3141 | + $params = $params['*'][0]; |
|
3142 | + |
|
3143 | + $params = self::implode_r($params); |
|
3144 | + |
|
3145 | + if ($mapped) { |
|
3146 | + $output = '$this->arrayMap(\'' . $func . '\', array(' . $params . '))'; |
|
3147 | + } else { |
|
3148 | + $output = $func . '(' . $params . ')'; |
|
3149 | + } |
|
3150 | + } elseif ($pluginType & Core::PROXY_PLUGIN) { |
|
3151 | + $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state); |
|
3152 | + foreach ($params as &$p) { |
|
3153 | + $p = $p[0]; |
|
3154 | + } |
|
3155 | + $output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params); |
|
3156 | + } elseif ($pluginType & Core::SMARTY_MODIFIER) { |
|
3157 | + $params = $this->mapParams($params, null, $state); |
|
3158 | + $params = $params['*'][0]; |
|
3159 | + |
|
3160 | + $params = self::implode_r($params); |
|
3161 | + |
|
3162 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3163 | + $callback = $this->customPlugins[$func]['callback']; |
|
3164 | + if (is_array($callback)) { |
|
3165 | + if (is_object($callback[0])) { |
|
3166 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3167 | + } else { |
|
3168 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3169 | + } |
|
3170 | + } elseif ($mapped) { |
|
3171 | + $output = '$this->arrayMap(\'' . $callback . '\', array(' . $params . '))'; |
|
3172 | + } else { |
|
3173 | + $output = $callback . '(' . $params . ')'; |
|
3174 | + } |
|
3175 | + } elseif ($mapped) { |
|
3176 | + $output = '$this->arrayMap(\'smarty_modifier_' . $func . '\', array(' . $params . '))'; |
|
3177 | + } else { |
|
3178 | + $output = 'smarty_modifier_' . $func . '(' . $params . ')'; |
|
3179 | + } |
|
3180 | + } else { |
|
3181 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3182 | + $callback = $this->customPlugins[$func]['callback']; |
|
3183 | + $pluginName = $callback; |
|
3184 | + } else { |
|
3185 | + if (class_exists('Plugin' . Core::toCamelCase($func)) !== false || function_exists('Plugin' . |
|
3186 | + Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) |
|
3187 | + !== false) { |
|
3188 | + $pluginName = 'Plugin' . Core::toCamelCase($func); |
|
3189 | + } else { |
|
3190 | + $pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func); |
|
3191 | + } |
|
3192 | + if ($pluginType & Core::CLASS_PLUGIN) { |
|
3193 | + $callback = array($pluginName, ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'); |
|
3194 | + } else { |
|
3195 | + $callback = $pluginName . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''); |
|
3196 | + } |
|
3197 | + } |
|
3198 | + $params = $this->mapParams($params, $callback, $state); |
|
3199 | + |
|
3200 | + foreach ($params as &$p) { |
|
3201 | + $p = $p[0]; |
|
3202 | + } |
|
3203 | + |
|
3204 | + if ($pluginType & Core::FUNC_PLUGIN) { |
|
3205 | + if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
3206 | + if ($mapped) { |
|
3207 | + throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.'); |
|
3208 | + } |
|
3209 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3210 | + $funcCompiler = $this->customPlugins[$func]['callback']; |
|
3211 | + } else { |
|
3212 | + if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) { |
|
3213 | + $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile'; |
|
3214 | + } else { |
|
3215 | + $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . |
|
3216 | + 'Compile'; |
|
3217 | + } |
|
3218 | + } |
|
3219 | + array_unshift($params, $this); |
|
3220 | + $output = call_user_func_array($funcCompiler, $params); |
|
3221 | + } else { |
|
3222 | + array_unshift($params, '$this'); |
|
3223 | + |
|
3224 | + $params = self::implode_r($params); |
|
3225 | + if ($mapped) { |
|
3226 | + $output = '$this->arrayMap(\'' . $pluginName . '\', array(' . $params . '))'; |
|
3227 | + } else { |
|
3228 | + $output = $pluginName . '(' . $params . ')'; |
|
3229 | + } |
|
3230 | + } |
|
3231 | + } else { |
|
3232 | + if ($pluginType & Core::COMPILABLE_PLUGIN) { |
|
3233 | + if ($mapped) { |
|
3234 | + throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.'); |
|
3235 | + } |
|
3236 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3237 | + $callback = $this->customPlugins[$func]['callback']; |
|
3238 | + if (!is_array($callback)) { |
|
3239 | + if (!method_exists($callback, 'compile')) { |
|
3240 | + throw new Exception('Custom plugin ' . $func . ' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
3241 | + } |
|
3242 | + if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) { |
|
3243 | + $funcCompiler = array($callback, 'compile'); |
|
3244 | + } else { |
|
3245 | + $funcCompiler = array(new $callback(), 'compile'); |
|
3246 | + } |
|
3247 | + } else { |
|
3248 | + $funcCompiler = $callback; |
|
3249 | + } |
|
3250 | + } else { |
|
3251 | + if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
3252 | + $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile'); |
|
3253 | + } else { |
|
3254 | + $funcCompiler = array( |
|
3255 | + Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
3256 | + 'compile' |
|
3257 | + ); |
|
3258 | + } |
|
3259 | + array_unshift($params, $this); |
|
3260 | + } |
|
3261 | + $output = call_user_func_array($funcCompiler, $params); |
|
3262 | + } else { |
|
3263 | + $params = self::implode_r($params); |
|
3264 | + |
|
3265 | + if ($pluginType & Core::CUSTOM_PLUGIN) { |
|
3266 | + if (is_object($callback[0])) { |
|
3267 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3268 | + } else { |
|
3269 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3270 | + } |
|
3271 | + } elseif ($mapped) { |
|
3272 | + $output = '$this->arrayMap(array($this->getObjectPlugin(\''. |
|
3273 | + Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '\'), |
|
3274 | 3274 | \'process\'), array(' . $params . '))'; |
3275 | - } else { |
|
3276 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
3277 | - $output = '$this->classCall(\'Plugin' . Core::toCamelCase($func) . '\', array(' . $params . '))'; |
|
3278 | - } else { |
|
3279 | - $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))'; |
|
3280 | - } |
|
3281 | - } |
|
3282 | - } |
|
3283 | - } |
|
3284 | - } |
|
3285 | - } |
|
3286 | - |
|
3287 | - if ($curBlock === 'namedparam') { |
|
3288 | - return array($output, $output); |
|
3289 | - } elseif ($curBlock === 'var' || $m[1] === null) { |
|
3290 | - return $output; |
|
3291 | - } elseif ($curBlock === 'string' || $curBlock === 'root') { |
|
3292 | - return $m[1] . '.' . $output . '.' . $m[1] . (isset($add) ? $add : null); |
|
3293 | - } |
|
3294 | - |
|
3295 | - return ''; |
|
3296 | - } |
|
3297 | - |
|
3298 | - /** |
|
3299 | - * Recursively implodes an array in a similar manner as var_export() does but with some tweaks |
|
3300 | - * to handle pre-compiled values and the fact that we do not need to enclose everything with |
|
3301 | - * "array" and do not require top-level keys to be displayed. |
|
3302 | - * |
|
3303 | - * @param array $params the array to implode |
|
3304 | - * @param bool $recursiveCall if set to true, the function outputs key names for the top level |
|
3305 | - * |
|
3306 | - * @return string the imploded array |
|
3307 | - */ |
|
3308 | - public static function implode_r(array $params, $recursiveCall = false) |
|
3309 | - { |
|
3310 | - $out = ''; |
|
3311 | - foreach ($params as $k => $p) { |
|
3312 | - if (is_array($p)) { |
|
3313 | - $out2 = 'array('; |
|
3314 | - foreach ($p as $k2 => $v) { |
|
3315 | - $out2 .= var_export($k2, true) . ' => ' . (is_array($v) ? 'array(' . self::implode_r($v, true) . ')' : $v) . ', '; |
|
3316 | - } |
|
3317 | - $p = rtrim($out2, ', ') . ')'; |
|
3318 | - } |
|
3319 | - if ($recursiveCall) { |
|
3320 | - $out .= var_export($k, true) . ' => ' . $p . ', '; |
|
3321 | - } else { |
|
3322 | - $out .= $p . ', '; |
|
3323 | - } |
|
3324 | - } |
|
3325 | - |
|
3326 | - return rtrim($out, ', '); |
|
3327 | - } |
|
3328 | - |
|
3329 | - /** |
|
3330 | - * Returns the plugin type of a plugin and adds it to the used plugins array if required. |
|
3331 | - * |
|
3332 | - * @param string $name plugin name, as found in the template |
|
3333 | - * |
|
3334 | - * @return int type as a multi bit flag composed of the Dwoo plugin types constants |
|
3335 | - * @throws Exception |
|
3336 | - * @throws SecurityException |
|
3337 | - * @throws Exception |
|
3338 | - */ |
|
3339 | - protected function getPluginType($name) |
|
3340 | - { |
|
3341 | - $pluginType = - 1; |
|
3342 | - |
|
3343 | - if (($this->securityPolicy === null && (function_exists($name) || strtolower($name) === 'isset' || strtolower($name) === 'empty')) || ($this->securityPolicy !== null && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) !== false)) { |
|
3344 | - $phpFunc = true; |
|
3345 | - } elseif ($this->securityPolicy !== null && function_exists($name) && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) === false) { |
|
3346 | - throw new SecurityException('Call to a disallowed php function : ' . $name); |
|
3347 | - } |
|
3348 | - |
|
3349 | - while ($pluginType <= 0) { |
|
3350 | - // Template plugin compilable |
|
3351 | - if (isset($this->templatePlugins[$name])) { |
|
3352 | - $pluginType = Core::TEMPLATE_PLUGIN | Core::COMPILABLE_PLUGIN; |
|
3353 | - } // Custom plugin |
|
3354 | - elseif (isset($this->customPlugins[$name])) { |
|
3355 | - $pluginType = $this->customPlugins[$name]['type'] | Core::CUSTOM_PLUGIN; |
|
3356 | - } // Class blocks plugin |
|
3357 | - elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), false) !== |
|
3358 | - false) { |
|
3359 | - if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), 'Dwoo\Block\Plugin')) { |
|
3360 | - $pluginType = Core::BLOCK_PLUGIN; |
|
3361 | - } else { |
|
3362 | - $pluginType = Core::CLASS_PLUGIN; |
|
3363 | - } |
|
3364 | - $interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name)); |
|
3365 | - if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
|
3366 | - $pluginType |= Core::COMPILABLE_PLUGIN; |
|
3367 | - } |
|
3368 | - } // Class functions plugin |
|
3369 | - elseif(class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name), false) !== |
|
3370 | - false) { |
|
3371 | - $pluginType = Core::CLASS_PLUGIN; |
|
3372 | - $interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name)); |
|
3373 | - if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
|
3374 | - $pluginType |= Core::COMPILABLE_PLUGIN; |
|
3375 | - } |
|
3376 | - } // Class without namespace |
|
3377 | - elseif(class_exists('Plugin' . Core::toCamelCase($name), false) !== false) { |
|
3378 | - $pluginType = Core::CLASS_PLUGIN; |
|
3379 | - $interfaces = class_implements('Plugin' . Core::toCamelCase($name)); |
|
3380 | - if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
|
3381 | - $pluginType |= Core::COMPILABLE_PLUGIN; |
|
3382 | - } |
|
3383 | - } // Function plugin (with/without namespaces) |
|
3384 | - elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase |
|
3385 | - ($name)) !== |
|
3386 | - false || function_exists('Plugin' . Core::toCamelCase($name)) !== false) { |
|
3387 | - $pluginType = Core::FUNC_PLUGIN; |
|
3388 | - } // Function plugin compile (with/without namespaces) |
|
3389 | - elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name) . |
|
3390 | - 'Compile') !== false || function_exists('Plugin' . Core::toCamelCase($name) . 'Compile') !== |
|
3391 | - false) { |
|
3392 | - $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN; |
|
3393 | - } // Helper plugin compile |
|
3394 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name) . 'Compile') |
|
3395 | - !== false) { |
|
3396 | - $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN; |
|
3397 | - } // Smarty modifier |
|
3398 | - elseif (function_exists('smarty_modifier_' . $name) !== false) { |
|
3399 | - $pluginType = Core::SMARTY_MODIFIER; |
|
3400 | - } // Smarty function |
|
3401 | - elseif (function_exists('smarty_function_' . $name) !== false) { |
|
3402 | - $pluginType = Core::SMARTY_FUNCTION; |
|
3403 | - } // Smarty block |
|
3404 | - elseif (function_exists('smarty_block_' . $name) !== false) { |
|
3405 | - $pluginType = Core::SMARTY_BLOCK; |
|
3406 | - } // Everything else |
|
3407 | - else { |
|
3408 | - if ($pluginType === - 1) { |
|
3409 | - try { |
|
3410 | - $this->getDwoo()->getLoader()->loadPlugin( |
|
3411 | - 'Plugin' . Core::toCamelCase($name)); |
|
3412 | - } |
|
3413 | - catch (Exception $e) { |
|
3414 | - if (isset($phpFunc)) { |
|
3415 | - $pluginType = Core::NATIVE_PLUGIN; |
|
3416 | - } elseif (is_object($this->getDwoo()->getPluginProxy()) && $this->getDwoo()->getPluginProxy()->handles($name)) { |
|
3417 | - $pluginType = Core::PROXY_PLUGIN; |
|
3418 | - break; |
|
3419 | - } else { |
|
3420 | - throw $e; |
|
3421 | - } |
|
3422 | - } |
|
3423 | - } else { |
|
3424 | - throw new Exception('Plugin "' . $name . '" could not be found, type:' . $pluginType); |
|
3425 | - } |
|
3426 | - ++ $pluginType; |
|
3427 | - } |
|
3428 | - } |
|
3429 | - |
|
3430 | - if (($pluginType & Core::COMPILABLE_PLUGIN) === 0 && ($pluginType & Core::NATIVE_PLUGIN) === 0 && ($pluginType & Core::PROXY_PLUGIN) === 0) { |
|
3431 | - $this->addUsedPlugin(Core::toCamelCase($name), $pluginType); |
|
3432 | - } |
|
3433 | - |
|
3434 | - return $pluginType; |
|
3435 | - } |
|
3436 | - |
|
3437 | - /** |
|
3438 | - * Allows a plugin to load another one at compile time, this will also mark |
|
3439 | - * it as used by this template so it will be loaded at runtime (which can be |
|
3440 | - * useful for compiled plugins that rely on another plugin when their compiled |
|
3441 | - * code runs). |
|
3442 | - * |
|
3443 | - * @param string $name the plugin name |
|
3444 | - * |
|
3445 | - * @return void |
|
3446 | - */ |
|
3447 | - public function loadPlugin($name) |
|
3448 | - { |
|
3449 | - $this->getPluginType($name); |
|
3450 | - } |
|
3451 | - |
|
3452 | - /** |
|
3453 | - * Runs htmlentities over the matched <?php ?> blocks when the security policy enforces that. |
|
3454 | - * |
|
3455 | - * @param array $match matched php block |
|
3456 | - * |
|
3457 | - * @return string the htmlentities-converted string |
|
3458 | - */ |
|
3459 | - protected function phpTagEncodingHelper($match) |
|
3460 | - { |
|
3461 | - return htmlspecialchars($match[0]); |
|
3462 | - } |
|
3463 | - |
|
3464 | - /** |
|
3465 | - * Maps the parameters received from the template onto the parameters required by the given callback. |
|
3466 | - * |
|
3467 | - * @param array $params the array of parameters |
|
3468 | - * @param callback $callback the function or method to reflect on to find out the required parameters |
|
3469 | - * @param int $callType the type of call in the template, 0 = no params, 1 = php-style call, 2 = named |
|
3470 | - * parameters call |
|
3471 | - * @param array $map the parameter map to use, if not provided it will be built from the callback |
|
3472 | - * |
|
3473 | - * @return array parameters sorted in the correct order with missing optional parameters filled |
|
3474 | - * @throws CompilationException |
|
3475 | - */ |
|
3476 | - protected function mapParams(array $params, $callback, $callType = 2, $map = null) |
|
3477 | - { |
|
3478 | - if (!$map) { |
|
3479 | - $map = $this->getParamMap($callback); |
|
3480 | - } |
|
3481 | - |
|
3482 | - $paramlist = array(); |
|
3483 | - |
|
3484 | - // transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values)) |
|
3485 | - $ps = array(); |
|
3486 | - foreach ($params as $p) { |
|
3487 | - if (is_array($p[1])) { |
|
3488 | - $ps[$p[0]] = $p[1]; |
|
3489 | - } else { |
|
3490 | - $ps[] = $p; |
|
3491 | - } |
|
3492 | - } |
|
3493 | - |
|
3494 | - // loops over the param map and assigns values from the template or default value for unset optional params |
|
3495 | - while (list($k, $v) = each($map)) { |
|
3496 | - if ($v[0] === '*') { |
|
3497 | - // "rest" array parameter, fill every remaining params in it and then break |
|
3498 | - if (count($ps) === 0) { |
|
3499 | - if ($v[1] === false) { |
|
3500 | - throw new CompilationException( |
|
3501 | - $this, 'Rest argument missing for ' . str_replace( |
|
3502 | - array( |
|
3503 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin', |
|
3504 | - 'Compile' |
|
3505 | - ), '', (is_array($callback) ? $callback[0] : $callback) |
|
3506 | - ) |
|
3507 | - ); |
|
3508 | - } else { |
|
3509 | - break; |
|
3510 | - } |
|
3511 | - } |
|
3512 | - $tmp = array(); |
|
3513 | - $tmp2 = array(); |
|
3514 | - $tmp3 = array(); |
|
3515 | - foreach ($ps as $i => $p) { |
|
3516 | - $tmp[$i] = $p[0]; |
|
3517 | - $tmp2[$i] = $p[1]; |
|
3518 | - $tmp3[$i] = isset($p[2]) ? $p[2] : 0; |
|
3519 | - unset($ps[$i]); |
|
3520 | - } |
|
3521 | - $paramlist[$v[0]] = array($tmp, $tmp2, $tmp3); |
|
3522 | - unset($tmp, $tmp2, $i, $p); |
|
3523 | - break; |
|
3524 | - } elseif (isset($ps[$v[0]])) { |
|
3525 | - // parameter is defined as named param |
|
3526 | - $paramlist[$v[0]] = $ps[$v[0]]; |
|
3527 | - unset($ps[$v[0]]); |
|
3528 | - } elseif (isset($ps[$k])) { |
|
3529 | - // parameter is defined as ordered param |
|
3530 | - $paramlist[$v[0]] = $ps[$k]; |
|
3531 | - unset($ps[$k]); |
|
3532 | - } elseif ($v[1] === false) { |
|
3533 | - // parameter is not defined and not optional, throw error |
|
3534 | - if (is_array($callback)) { |
|
3535 | - if (is_object($callback[0])) { |
|
3536 | - $name = get_class($callback[0]) . '::' . $callback[1]; |
|
3537 | - } else { |
|
3538 | - $name = $callback[0]; |
|
3539 | - } |
|
3540 | - } else { |
|
3541 | - $name = $callback; |
|
3542 | - } |
|
3543 | - |
|
3544 | - throw new CompilationException( |
|
3545 | - $this, 'Argument ' . $k . '/' . $v[0] . ' missing for ' . str_replace( |
|
3546 | - array( |
|
3547 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin', |
|
3548 | - 'Compile' |
|
3549 | - ), '', $name |
|
3550 | - ) |
|
3551 | - ); |
|
3552 | - } elseif ($v[2] === null) { |
|
3553 | - // enforce lowercased null if default value is null (php outputs NULL with var export) |
|
3554 | - $paramlist[$v[0]] = array('null', null, self::T_NULL); |
|
3555 | - } else { |
|
3556 | - // outputs default value with var_export |
|
3557 | - $paramlist[$v[0]] = array(var_export($v[2], true), $v[2]); |
|
3558 | - } |
|
3559 | - } |
|
3560 | - |
|
3561 | - if (count($ps)) { |
|
3562 | - foreach ($ps as $i => $p) { |
|
3563 | - array_push($paramlist, $p); |
|
3564 | - } |
|
3565 | - } |
|
3566 | - |
|
3567 | - return $paramlist; |
|
3568 | - } |
|
3569 | - |
|
3570 | - /** |
|
3571 | - * Returns the parameter map of the given callback, it filters out entries typed as Dwoo and Compiler and turns the |
|
3572 | - * rest parameter into a "*". |
|
3573 | - * |
|
3574 | - * @param callback $callback the function/method to reflect on |
|
3575 | - * |
|
3576 | - * @return array processed parameter map |
|
3577 | - */ |
|
3578 | - protected function getParamMap($callback) |
|
3579 | - { |
|
3580 | - if (is_null($callback)) { |
|
3581 | - return array(array('*', true)); |
|
3582 | - } |
|
3583 | - if (is_array($callback)) { |
|
3584 | - $ref = new ReflectionMethod($callback[0], $callback[1]); |
|
3585 | - } else { |
|
3586 | - $ref = new ReflectionFunction($callback); |
|
3587 | - } |
|
3588 | - |
|
3589 | - $out = array(); |
|
3590 | - foreach ($ref->getParameters() as $param) { |
|
3591 | - if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Core') { |
|
3592 | - continue; |
|
3593 | - } |
|
3594 | - if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Compiler') { |
|
3595 | - continue; |
|
3596 | - } |
|
3597 | - if ($param->getName() === 'rest' && $param->isArray() === true) { |
|
3598 | - $out[] = array('*', $param->isOptional(), null); |
|
3599 | - continue; |
|
3600 | - } |
|
3601 | - $out[] = array( |
|
3602 | - $param->getName(), |
|
3603 | - $param->isOptional(), |
|
3604 | - $param->isOptional() ? $param->getDefaultValue() : null |
|
3605 | - ); |
|
3606 | - } |
|
3607 | - |
|
3608 | - return $out; |
|
3609 | - } |
|
3610 | - |
|
3611 | - /** |
|
3612 | - * Returns a default instance of this compiler, used by default by all Dwoo templates that do not have a |
|
3613 | - * specific compiler assigned and when you do not override the default compiler factory function. |
|
3614 | - * |
|
3615 | - * @see Core::setDefaultCompilerFactory() |
|
3616 | - * @return Compiler |
|
3617 | - */ |
|
3618 | - public static function compilerFactory() |
|
3619 | - { |
|
3620 | - if (self::$instance === null) { |
|
3621 | - self::$instance = new self(); |
|
3622 | - } |
|
3623 | - |
|
3624 | - return self::$instance; |
|
3625 | - } |
|
3275 | + } else { |
|
3276 | + if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
3277 | + $output = '$this->classCall(\'Plugin' . Core::toCamelCase($func) . '\', array(' . $params . '))'; |
|
3278 | + } else { |
|
3279 | + $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))'; |
|
3280 | + } |
|
3281 | + } |
|
3282 | + } |
|
3283 | + } |
|
3284 | + } |
|
3285 | + } |
|
3286 | + |
|
3287 | + if ($curBlock === 'namedparam') { |
|
3288 | + return array($output, $output); |
|
3289 | + } elseif ($curBlock === 'var' || $m[1] === null) { |
|
3290 | + return $output; |
|
3291 | + } elseif ($curBlock === 'string' || $curBlock === 'root') { |
|
3292 | + return $m[1] . '.' . $output . '.' . $m[1] . (isset($add) ? $add : null); |
|
3293 | + } |
|
3294 | + |
|
3295 | + return ''; |
|
3296 | + } |
|
3297 | + |
|
3298 | + /** |
|
3299 | + * Recursively implodes an array in a similar manner as var_export() does but with some tweaks |
|
3300 | + * to handle pre-compiled values and the fact that we do not need to enclose everything with |
|
3301 | + * "array" and do not require top-level keys to be displayed. |
|
3302 | + * |
|
3303 | + * @param array $params the array to implode |
|
3304 | + * @param bool $recursiveCall if set to true, the function outputs key names for the top level |
|
3305 | + * |
|
3306 | + * @return string the imploded array |
|
3307 | + */ |
|
3308 | + public static function implode_r(array $params, $recursiveCall = false) |
|
3309 | + { |
|
3310 | + $out = ''; |
|
3311 | + foreach ($params as $k => $p) { |
|
3312 | + if (is_array($p)) { |
|
3313 | + $out2 = 'array('; |
|
3314 | + foreach ($p as $k2 => $v) { |
|
3315 | + $out2 .= var_export($k2, true) . ' => ' . (is_array($v) ? 'array(' . self::implode_r($v, true) . ')' : $v) . ', '; |
|
3316 | + } |
|
3317 | + $p = rtrim($out2, ', ') . ')'; |
|
3318 | + } |
|
3319 | + if ($recursiveCall) { |
|
3320 | + $out .= var_export($k, true) . ' => ' . $p . ', '; |
|
3321 | + } else { |
|
3322 | + $out .= $p . ', '; |
|
3323 | + } |
|
3324 | + } |
|
3325 | + |
|
3326 | + return rtrim($out, ', '); |
|
3327 | + } |
|
3328 | + |
|
3329 | + /** |
|
3330 | + * Returns the plugin type of a plugin and adds it to the used plugins array if required. |
|
3331 | + * |
|
3332 | + * @param string $name plugin name, as found in the template |
|
3333 | + * |
|
3334 | + * @return int type as a multi bit flag composed of the Dwoo plugin types constants |
|
3335 | + * @throws Exception |
|
3336 | + * @throws SecurityException |
|
3337 | + * @throws Exception |
|
3338 | + */ |
|
3339 | + protected function getPluginType($name) |
|
3340 | + { |
|
3341 | + $pluginType = - 1; |
|
3342 | + |
|
3343 | + if (($this->securityPolicy === null && (function_exists($name) || strtolower($name) === 'isset' || strtolower($name) === 'empty')) || ($this->securityPolicy !== null && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) !== false)) { |
|
3344 | + $phpFunc = true; |
|
3345 | + } elseif ($this->securityPolicy !== null && function_exists($name) && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) === false) { |
|
3346 | + throw new SecurityException('Call to a disallowed php function : ' . $name); |
|
3347 | + } |
|
3348 | + |
|
3349 | + while ($pluginType <= 0) { |
|
3350 | + // Template plugin compilable |
|
3351 | + if (isset($this->templatePlugins[$name])) { |
|
3352 | + $pluginType = Core::TEMPLATE_PLUGIN | Core::COMPILABLE_PLUGIN; |
|
3353 | + } // Custom plugin |
|
3354 | + elseif (isset($this->customPlugins[$name])) { |
|
3355 | + $pluginType = $this->customPlugins[$name]['type'] | Core::CUSTOM_PLUGIN; |
|
3356 | + } // Class blocks plugin |
|
3357 | + elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), false) !== |
|
3358 | + false) { |
|
3359 | + if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), 'Dwoo\Block\Plugin')) { |
|
3360 | + $pluginType = Core::BLOCK_PLUGIN; |
|
3361 | + } else { |
|
3362 | + $pluginType = Core::CLASS_PLUGIN; |
|
3363 | + } |
|
3364 | + $interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name)); |
|
3365 | + if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
|
3366 | + $pluginType |= Core::COMPILABLE_PLUGIN; |
|
3367 | + } |
|
3368 | + } // Class functions plugin |
|
3369 | + elseif(class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name), false) !== |
|
3370 | + false) { |
|
3371 | + $pluginType = Core::CLASS_PLUGIN; |
|
3372 | + $interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name)); |
|
3373 | + if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
|
3374 | + $pluginType |= Core::COMPILABLE_PLUGIN; |
|
3375 | + } |
|
3376 | + } // Class without namespace |
|
3377 | + elseif(class_exists('Plugin' . Core::toCamelCase($name), false) !== false) { |
|
3378 | + $pluginType = Core::CLASS_PLUGIN; |
|
3379 | + $interfaces = class_implements('Plugin' . Core::toCamelCase($name)); |
|
3380 | + if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
|
3381 | + $pluginType |= Core::COMPILABLE_PLUGIN; |
|
3382 | + } |
|
3383 | + } // Function plugin (with/without namespaces) |
|
3384 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase |
|
3385 | + ($name)) !== |
|
3386 | + false || function_exists('Plugin' . Core::toCamelCase($name)) !== false) { |
|
3387 | + $pluginType = Core::FUNC_PLUGIN; |
|
3388 | + } // Function plugin compile (with/without namespaces) |
|
3389 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name) . |
|
3390 | + 'Compile') !== false || function_exists('Plugin' . Core::toCamelCase($name) . 'Compile') !== |
|
3391 | + false) { |
|
3392 | + $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN; |
|
3393 | + } // Helper plugin compile |
|
3394 | + elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name) . 'Compile') |
|
3395 | + !== false) { |
|
3396 | + $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN; |
|
3397 | + } // Smarty modifier |
|
3398 | + elseif (function_exists('smarty_modifier_' . $name) !== false) { |
|
3399 | + $pluginType = Core::SMARTY_MODIFIER; |
|
3400 | + } // Smarty function |
|
3401 | + elseif (function_exists('smarty_function_' . $name) !== false) { |
|
3402 | + $pluginType = Core::SMARTY_FUNCTION; |
|
3403 | + } // Smarty block |
|
3404 | + elseif (function_exists('smarty_block_' . $name) !== false) { |
|
3405 | + $pluginType = Core::SMARTY_BLOCK; |
|
3406 | + } // Everything else |
|
3407 | + else { |
|
3408 | + if ($pluginType === - 1) { |
|
3409 | + try { |
|
3410 | + $this->getDwoo()->getLoader()->loadPlugin( |
|
3411 | + 'Plugin' . Core::toCamelCase($name)); |
|
3412 | + } |
|
3413 | + catch (Exception $e) { |
|
3414 | + if (isset($phpFunc)) { |
|
3415 | + $pluginType = Core::NATIVE_PLUGIN; |
|
3416 | + } elseif (is_object($this->getDwoo()->getPluginProxy()) && $this->getDwoo()->getPluginProxy()->handles($name)) { |
|
3417 | + $pluginType = Core::PROXY_PLUGIN; |
|
3418 | + break; |
|
3419 | + } else { |
|
3420 | + throw $e; |
|
3421 | + } |
|
3422 | + } |
|
3423 | + } else { |
|
3424 | + throw new Exception('Plugin "' . $name . '" could not be found, type:' . $pluginType); |
|
3425 | + } |
|
3426 | + ++ $pluginType; |
|
3427 | + } |
|
3428 | + } |
|
3429 | + |
|
3430 | + if (($pluginType & Core::COMPILABLE_PLUGIN) === 0 && ($pluginType & Core::NATIVE_PLUGIN) === 0 && ($pluginType & Core::PROXY_PLUGIN) === 0) { |
|
3431 | + $this->addUsedPlugin(Core::toCamelCase($name), $pluginType); |
|
3432 | + } |
|
3433 | + |
|
3434 | + return $pluginType; |
|
3435 | + } |
|
3436 | + |
|
3437 | + /** |
|
3438 | + * Allows a plugin to load another one at compile time, this will also mark |
|
3439 | + * it as used by this template so it will be loaded at runtime (which can be |
|
3440 | + * useful for compiled plugins that rely on another plugin when their compiled |
|
3441 | + * code runs). |
|
3442 | + * |
|
3443 | + * @param string $name the plugin name |
|
3444 | + * |
|
3445 | + * @return void |
|
3446 | + */ |
|
3447 | + public function loadPlugin($name) |
|
3448 | + { |
|
3449 | + $this->getPluginType($name); |
|
3450 | + } |
|
3451 | + |
|
3452 | + /** |
|
3453 | + * Runs htmlentities over the matched <?php ?> blocks when the security policy enforces that. |
|
3454 | + * |
|
3455 | + * @param array $match matched php block |
|
3456 | + * |
|
3457 | + * @return string the htmlentities-converted string |
|
3458 | + */ |
|
3459 | + protected function phpTagEncodingHelper($match) |
|
3460 | + { |
|
3461 | + return htmlspecialchars($match[0]); |
|
3462 | + } |
|
3463 | + |
|
3464 | + /** |
|
3465 | + * Maps the parameters received from the template onto the parameters required by the given callback. |
|
3466 | + * |
|
3467 | + * @param array $params the array of parameters |
|
3468 | + * @param callback $callback the function or method to reflect on to find out the required parameters |
|
3469 | + * @param int $callType the type of call in the template, 0 = no params, 1 = php-style call, 2 = named |
|
3470 | + * parameters call |
|
3471 | + * @param array $map the parameter map to use, if not provided it will be built from the callback |
|
3472 | + * |
|
3473 | + * @return array parameters sorted in the correct order with missing optional parameters filled |
|
3474 | + * @throws CompilationException |
|
3475 | + */ |
|
3476 | + protected function mapParams(array $params, $callback, $callType = 2, $map = null) |
|
3477 | + { |
|
3478 | + if (!$map) { |
|
3479 | + $map = $this->getParamMap($callback); |
|
3480 | + } |
|
3481 | + |
|
3482 | + $paramlist = array(); |
|
3483 | + |
|
3484 | + // transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values)) |
|
3485 | + $ps = array(); |
|
3486 | + foreach ($params as $p) { |
|
3487 | + if (is_array($p[1])) { |
|
3488 | + $ps[$p[0]] = $p[1]; |
|
3489 | + } else { |
|
3490 | + $ps[] = $p; |
|
3491 | + } |
|
3492 | + } |
|
3493 | + |
|
3494 | + // loops over the param map and assigns values from the template or default value for unset optional params |
|
3495 | + while (list($k, $v) = each($map)) { |
|
3496 | + if ($v[0] === '*') { |
|
3497 | + // "rest" array parameter, fill every remaining params in it and then break |
|
3498 | + if (count($ps) === 0) { |
|
3499 | + if ($v[1] === false) { |
|
3500 | + throw new CompilationException( |
|
3501 | + $this, 'Rest argument missing for ' . str_replace( |
|
3502 | + array( |
|
3503 | + Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin', |
|
3504 | + 'Compile' |
|
3505 | + ), '', (is_array($callback) ? $callback[0] : $callback) |
|
3506 | + ) |
|
3507 | + ); |
|
3508 | + } else { |
|
3509 | + break; |
|
3510 | + } |
|
3511 | + } |
|
3512 | + $tmp = array(); |
|
3513 | + $tmp2 = array(); |
|
3514 | + $tmp3 = array(); |
|
3515 | + foreach ($ps as $i => $p) { |
|
3516 | + $tmp[$i] = $p[0]; |
|
3517 | + $tmp2[$i] = $p[1]; |
|
3518 | + $tmp3[$i] = isset($p[2]) ? $p[2] : 0; |
|
3519 | + unset($ps[$i]); |
|
3520 | + } |
|
3521 | + $paramlist[$v[0]] = array($tmp, $tmp2, $tmp3); |
|
3522 | + unset($tmp, $tmp2, $i, $p); |
|
3523 | + break; |
|
3524 | + } elseif (isset($ps[$v[0]])) { |
|
3525 | + // parameter is defined as named param |
|
3526 | + $paramlist[$v[0]] = $ps[$v[0]]; |
|
3527 | + unset($ps[$v[0]]); |
|
3528 | + } elseif (isset($ps[$k])) { |
|
3529 | + // parameter is defined as ordered param |
|
3530 | + $paramlist[$v[0]] = $ps[$k]; |
|
3531 | + unset($ps[$k]); |
|
3532 | + } elseif ($v[1] === false) { |
|
3533 | + // parameter is not defined and not optional, throw error |
|
3534 | + if (is_array($callback)) { |
|
3535 | + if (is_object($callback[0])) { |
|
3536 | + $name = get_class($callback[0]) . '::' . $callback[1]; |
|
3537 | + } else { |
|
3538 | + $name = $callback[0]; |
|
3539 | + } |
|
3540 | + } else { |
|
3541 | + $name = $callback; |
|
3542 | + } |
|
3543 | + |
|
3544 | + throw new CompilationException( |
|
3545 | + $this, 'Argument ' . $k . '/' . $v[0] . ' missing for ' . str_replace( |
|
3546 | + array( |
|
3547 | + Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin', |
|
3548 | + 'Compile' |
|
3549 | + ), '', $name |
|
3550 | + ) |
|
3551 | + ); |
|
3552 | + } elseif ($v[2] === null) { |
|
3553 | + // enforce lowercased null if default value is null (php outputs NULL with var export) |
|
3554 | + $paramlist[$v[0]] = array('null', null, self::T_NULL); |
|
3555 | + } else { |
|
3556 | + // outputs default value with var_export |
|
3557 | + $paramlist[$v[0]] = array(var_export($v[2], true), $v[2]); |
|
3558 | + } |
|
3559 | + } |
|
3560 | + |
|
3561 | + if (count($ps)) { |
|
3562 | + foreach ($ps as $i => $p) { |
|
3563 | + array_push($paramlist, $p); |
|
3564 | + } |
|
3565 | + } |
|
3566 | + |
|
3567 | + return $paramlist; |
|
3568 | + } |
|
3569 | + |
|
3570 | + /** |
|
3571 | + * Returns the parameter map of the given callback, it filters out entries typed as Dwoo and Compiler and turns the |
|
3572 | + * rest parameter into a "*". |
|
3573 | + * |
|
3574 | + * @param callback $callback the function/method to reflect on |
|
3575 | + * |
|
3576 | + * @return array processed parameter map |
|
3577 | + */ |
|
3578 | + protected function getParamMap($callback) |
|
3579 | + { |
|
3580 | + if (is_null($callback)) { |
|
3581 | + return array(array('*', true)); |
|
3582 | + } |
|
3583 | + if (is_array($callback)) { |
|
3584 | + $ref = new ReflectionMethod($callback[0], $callback[1]); |
|
3585 | + } else { |
|
3586 | + $ref = new ReflectionFunction($callback); |
|
3587 | + } |
|
3588 | + |
|
3589 | + $out = array(); |
|
3590 | + foreach ($ref->getParameters() as $param) { |
|
3591 | + if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Core') { |
|
3592 | + continue; |
|
3593 | + } |
|
3594 | + if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Compiler') { |
|
3595 | + continue; |
|
3596 | + } |
|
3597 | + if ($param->getName() === 'rest' && $param->isArray() === true) { |
|
3598 | + $out[] = array('*', $param->isOptional(), null); |
|
3599 | + continue; |
|
3600 | + } |
|
3601 | + $out[] = array( |
|
3602 | + $param->getName(), |
|
3603 | + $param->isOptional(), |
|
3604 | + $param->isOptional() ? $param->getDefaultValue() : null |
|
3605 | + ); |
|
3606 | + } |
|
3607 | + |
|
3608 | + return $out; |
|
3609 | + } |
|
3610 | + |
|
3611 | + /** |
|
3612 | + * Returns a default instance of this compiler, used by default by all Dwoo templates that do not have a |
|
3613 | + * specific compiler assigned and when you do not override the default compiler factory function. |
|
3614 | + * |
|
3615 | + * @see Core::setDefaultCompilerFactory() |
|
3616 | + * @return Compiler |
|
3617 | + */ |
|
3618 | + public static function compilerFactory() |
|
3619 | + { |
|
3620 | + if (self::$instance === null) { |
|
3621 | + self::$instance = new self(); |
|
3622 | + } |
|
3623 | + |
|
3624 | + return self::$instance; |
|
3625 | + } |
|
3626 | 3626 | } |
@@ -769,13 +769,13 @@ discard block |
||
769 | 769 | $search = array('{<\?.*?\?>}', '{<%.*?%>}'); |
770 | 770 | } |
771 | 771 | switch ($this->securityPolicy->getPhpHandling()) { |
772 | - case SecurityPolicy::PHP_ALLOW: |
|
773 | - break; |
|
774 | - case SecurityPolicy::PHP_ENCODE: |
|
775 | - $tpl = preg_replace_callback($search, array($this, 'phpTagEncodingHelper'), $tpl); |
|
776 | - break; |
|
777 | - case SecurityPolicy::PHP_REMOVE: |
|
778 | - $tpl = preg_replace($search, '', $tpl); |
|
772 | + case SecurityPolicy::PHP_ALLOW: |
|
773 | + break; |
|
774 | + case SecurityPolicy::PHP_ENCODE: |
|
775 | + $tpl = preg_replace_callback($search, array($this, 'phpTagEncodingHelper'), $tpl); |
|
776 | + break; |
|
777 | + case SecurityPolicy::PHP_REMOVE: |
|
778 | + $tpl = preg_replace($search, '', $tpl); |
|
779 | 779 | } |
780 | 780 | } |
781 | 781 | } |
@@ -875,42 +875,42 @@ discard block |
||
875 | 875 | } |
876 | 876 | |
877 | 877 | switch ($type) { |
878 | - case Core::BLOCK_PLUGIN: |
|
879 | - case Core::CLASS_PLUGIN: |
|
880 | - if (class_exists('Plugin' . $plugin) !== false) { |
|
881 | - $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)". |
|
882 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
883 | - } else { |
|
884 | - $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_BLOCKS . "Plugin" . $plugin . "')===false)". |
|
885 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
886 | - } |
|
887 | - break; |
|
888 | - case Core::FUNC_PLUGIN: |
|
889 | - if (function_exists('Plugin' . $plugin) !== false) { |
|
890 | - $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)". |
|
891 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
892 | - } else { |
|
893 | - $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)". |
|
894 | - "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
895 | - } |
|
896 | - break; |
|
897 | - case Core::SMARTY_MODIFIER: |
|
898 | - $output .= "if (function_exists('smarty_modifier_$plugin')===false)". |
|
899 | - "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
900 | - break; |
|
901 | - case Core::SMARTY_FUNCTION: |
|
902 | - $output .= "if (function_exists('smarty_function_$plugin')===false)". |
|
903 | - "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
904 | - break; |
|
905 | - case Core::SMARTY_BLOCK: |
|
906 | - $output .= "if (function_exists('smarty_block_$plugin')===false)". |
|
907 | - "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
908 | - break; |
|
909 | - case Core::PROXY_PLUGIN: |
|
910 | - $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin); |
|
911 | - break; |
|
912 | - default: |
|
913 | - throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type); |
|
878 | + case Core::BLOCK_PLUGIN: |
|
879 | + case Core::CLASS_PLUGIN: |
|
880 | + if (class_exists('Plugin' . $plugin) !== false) { |
|
881 | + $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)". |
|
882 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
883 | + } else { |
|
884 | + $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_BLOCKS . "Plugin" . $plugin . "')===false)". |
|
885 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
886 | + } |
|
887 | + break; |
|
888 | + case Core::FUNC_PLUGIN: |
|
889 | + if (function_exists('Plugin' . $plugin) !== false) { |
|
890 | + $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)". |
|
891 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
892 | + } else { |
|
893 | + $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)". |
|
894 | + "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
|
895 | + } |
|
896 | + break; |
|
897 | + case Core::SMARTY_MODIFIER: |
|
898 | + $output .= "if (function_exists('smarty_modifier_$plugin')===false)". |
|
899 | + "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
900 | + break; |
|
901 | + case Core::SMARTY_FUNCTION: |
|
902 | + $output .= "if (function_exists('smarty_function_$plugin')===false)". |
|
903 | + "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
904 | + break; |
|
905 | + case Core::SMARTY_BLOCK: |
|
906 | + $output .= "if (function_exists('smarty_block_$plugin')===false)". |
|
907 | + "\n\t\$this->getLoader()->loadPlugin('$plugin');\n"; |
|
908 | + break; |
|
909 | + case Core::PROXY_PLUGIN: |
|
910 | + $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin); |
|
911 | + break; |
|
912 | + default: |
|
913 | + throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type); |
|
914 | 914 | } |
915 | 915 | } |
916 | 916 |
@@ -294,7 +294,7 @@ discard block |
||
294 | 294 | */ |
295 | 295 | public function setNestedCommentsHandling($allow = true) |
296 | 296 | { |
297 | - $this->allowNestedComments = (bool)$allow; |
|
297 | + $this->allowNestedComments = (bool) $allow; |
|
298 | 298 | } |
299 | 299 | |
300 | 300 | /** |
@@ -319,7 +319,7 @@ discard block |
||
319 | 319 | */ |
320 | 320 | public function setLooseOpeningHandling($allow = false) |
321 | 321 | { |
322 | - $this->allowLooseOpenings = (bool)$allow; |
|
322 | + $this->allowLooseOpenings = (bool) $allow; |
|
323 | 323 | } |
324 | 324 | |
325 | 325 | /** |
@@ -344,7 +344,7 @@ discard block |
||
344 | 344 | */ |
345 | 345 | public function setAutoEscape($enabled) |
346 | 346 | { |
347 | - $this->autoEscape = (bool)$enabled; |
|
347 | + $this->autoEscape = (bool) $enabled; |
|
348 | 348 | } |
349 | 349 | |
350 | 350 | /** |
@@ -371,7 +371,7 @@ discard block |
||
371 | 371 | { |
372 | 372 | if ($autoload) { |
373 | 373 | $name = str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', Core::toCamelCase($callback)); |
374 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . $name; |
|
374 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS.$name; |
|
375 | 375 | |
376 | 376 | if (class_exists($class)) { |
377 | 377 | $callback = array(new $class($this), 'process'); |
@@ -396,12 +396,12 @@ discard block |
||
396 | 396 | { |
397 | 397 | if (($index = array_search($callback, $this->processors['pre'], true)) !== false) { |
398 | 398 | unset($this->processors['pre'][$index]); |
399 | - } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
399 | + } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS.str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
400 | 400 | $callback), |
401 | 401 | $this->processors['pre'], true)) !== false) { |
402 | 402 | unset($this->processors['pre'][$index]); |
403 | 403 | } else { |
404 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
404 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS.str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
405 | 405 | foreach ($this->processors['pre'] as $index => $proc) { |
406 | 406 | if (is_array($proc) && ($proc[0] instanceof $class) || (isset($proc['class']) && $proc['class'] == $class)) { |
407 | 407 | unset($this->processors['pre'][$index]); |
@@ -424,7 +424,7 @@ discard block |
||
424 | 424 | { |
425 | 425 | if ($autoload) { |
426 | 426 | $name = str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
427 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . Core::toCamelCase($name); |
|
427 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS.Core::toCamelCase($name); |
|
428 | 428 | |
429 | 429 | if (class_exists($class)) { |
430 | 430 | $callback = array(new $class($this), 'process'); |
@@ -449,12 +449,12 @@ discard block |
||
449 | 449 | { |
450 | 450 | if (($index = array_search($callback, $this->processors['post'], true)) !== false) { |
451 | 451 | unset($this->processors['post'][$index]); |
452 | - } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
452 | + } elseif (($index = array_search(Core::NAMESPACE_PLUGINS_PROCESSORS.str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', |
|
453 | 453 | $callback), |
454 | 454 | $this->processors['post'], true)) !== false) { |
455 | 455 | unset($this->processors['post'][$index]); |
456 | 456 | } else { |
457 | - $class = Core::NAMESPACE_PLUGINS_PROCESSORS . str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
457 | + $class = Core::NAMESPACE_PLUGINS_PROCESSORS.str_replace(Core::NAMESPACE_PLUGINS_PROCESSORS, '', $callback); |
|
458 | 458 | foreach ($this->processors['post'] as $index => $proc) { |
459 | 459 | if (is_array($proc) && ($proc[0] instanceof $class) || (isset($proc['class']) && $proc['class'] == $class)) { |
460 | 460 | unset($this->processors['post'][$index]); |
@@ -480,7 +480,7 @@ discard block |
||
480 | 480 | $this->getDwoo()->getLoader()->loadPlugin($name); |
481 | 481 | } |
482 | 482 | catch (Exception $e) { |
483 | - throw new Exception('Processor ' . $name . ' could not be found in your plugin directories, please ensure it is in a file named ' . $name . '.php in the plugin directory'); |
|
483 | + throw new Exception('Processor '.$name.' could not be found in your plugin directories, please ensure it is in a file named '.$name.'.php in the plugin directory'); |
|
484 | 484 | } |
485 | 485 | } |
486 | 486 | |
@@ -666,7 +666,7 @@ discard block |
||
666 | 666 | public function setTemplateSource($newSource, $fromPointer = false) |
667 | 667 | { |
668 | 668 | if ($fromPointer === true) { |
669 | - $this->templateSource = substr($this->templateSource, 0, $this->pointer) . $newSource; |
|
669 | + $this->templateSource = substr($this->templateSource, 0, $this->pointer).$newSource; |
|
670 | 670 | } else { |
671 | 671 | $this->templateSource = $newSource; |
672 | 672 | } |
@@ -737,11 +737,11 @@ discard block |
||
737 | 737 | |
738 | 738 | if ($this->debug) { |
739 | 739 | echo "\n"; |
740 | - echo 'COMPILER INIT' . "\n"; |
|
740 | + echo 'COMPILER INIT'."\n"; |
|
741 | 741 | } |
742 | 742 | |
743 | 743 | if ($this->debug) { |
744 | - echo 'PROCESSING PREPROCESSORS (' . count($this->processors['pre']) . ')' . "\n"; |
|
744 | + echo 'PROCESSING PREPROCESSORS ('.count($this->processors['pre']).')'."\n"; |
|
745 | 745 | } |
746 | 746 | |
747 | 747 | // runs preprocessors |
@@ -785,23 +785,23 @@ discard block |
||
785 | 785 | if ($pos === false) { |
786 | 786 | $this->push(substr($tpl, $ptr), 0); |
787 | 787 | break; |
788 | - } elseif (substr($tpl, $pos - 1, 1) === '\\' && substr($tpl, $pos - 2, 1) !== '\\') { |
|
789 | - $this->push(substr($tpl, $ptr, $pos - $ptr - 1) . $this->ld); |
|
790 | - $ptr = $pos + strlen($this->ld); |
|
791 | - } elseif (preg_match('/^' . $this->ldr . ($this->allowLooseOpenings ? '\s*' : '') . 'literal' . ($this->allowLooseOpenings ? '\s*' : '') . $this->rdr . '/s', substr($tpl, $pos), $litOpen)) { |
|
792 | - if (!preg_match('/' . $this->ldr . ($this->allowLooseOpenings ? '\s*' : '') . '\/literal' . ($this->allowLooseOpenings ? '\s*' : '') . $this->rdr . '/s', $tpl, $litClose, PREG_OFFSET_CAPTURE, $pos)) { |
|
788 | + } elseif (substr($tpl, $pos-1, 1) === '\\' && substr($tpl, $pos-2, 1) !== '\\') { |
|
789 | + $this->push(substr($tpl, $ptr, $pos-$ptr-1).$this->ld); |
|
790 | + $ptr = $pos+strlen($this->ld); |
|
791 | + } elseif (preg_match('/^'.$this->ldr.($this->allowLooseOpenings ? '\s*' : '').'literal'.($this->allowLooseOpenings ? '\s*' : '').$this->rdr.'/s', substr($tpl, $pos), $litOpen)) { |
|
792 | + if (!preg_match('/'.$this->ldr.($this->allowLooseOpenings ? '\s*' : '').'\/literal'.($this->allowLooseOpenings ? '\s*' : '').$this->rdr.'/s', $tpl, $litClose, PREG_OFFSET_CAPTURE, $pos)) { |
|
793 | 793 | throw new CompilationException($this, 'The {literal} blocks must be closed explicitly with {/literal}'); |
794 | 794 | } |
795 | 795 | $endpos = $litClose[0][1]; |
796 | - $this->push(substr($tpl, $ptr, $pos - $ptr) . substr($tpl, $pos + strlen($litOpen[0]), $endpos - $pos - strlen($litOpen[0]))); |
|
797 | - $ptr = $endpos + strlen($litClose[0][0]); |
|
796 | + $this->push(substr($tpl, $ptr, $pos-$ptr).substr($tpl, $pos+strlen($litOpen[0]), $endpos-$pos-strlen($litOpen[0]))); |
|
797 | + $ptr = $endpos+strlen($litClose[0][0]); |
|
798 | 798 | } else { |
799 | - if (substr($tpl, $pos - 2, 1) === '\\' && substr($tpl, $pos - 1, 1) === '\\') { |
|
800 | - $this->push(substr($tpl, $ptr, $pos - $ptr - 1)); |
|
799 | + if (substr($tpl, $pos-2, 1) === '\\' && substr($tpl, $pos-1, 1) === '\\') { |
|
800 | + $this->push(substr($tpl, $ptr, $pos-$ptr-1)); |
|
801 | 801 | $ptr = $pos; |
802 | 802 | } |
803 | 803 | |
804 | - $this->push(substr($tpl, $ptr, $pos - $ptr)); |
|
804 | + $this->push(substr($tpl, $ptr, $pos-$ptr)); |
|
805 | 805 | $ptr = $pos; |
806 | 806 | |
807 | 807 | $pos += strlen($this->ld); |
@@ -819,7 +819,7 @@ discard block |
||
819 | 819 | |
820 | 820 | // check that there is an end tag present |
821 | 821 | if (strpos($tpl, $this->rd, $pos) === false) { |
822 | - throw new CompilationException($this, 'A template tag was not closed, started with "' . substr($tpl, $ptr, 30) . '"'); |
|
822 | + throw new CompilationException($this, 'A template tag was not closed, started with "'.substr($tpl, $ptr, 30).'"'); |
|
823 | 823 | } |
824 | 824 | |
825 | 825 | $ptr += strlen($this->ld); |
@@ -833,7 +833,7 @@ discard block |
||
833 | 833 | continue 2; |
834 | 834 | } |
835 | 835 | |
836 | - $len = $subptr - $ptr; |
|
836 | + $len = $subptr-$ptr; |
|
837 | 837 | $this->push($parsed, substr_count(substr($tpl, $ptr, $len), "\n")); |
838 | 838 | $ptr += $len; |
839 | 839 | |
@@ -847,7 +847,7 @@ discard block |
||
847 | 847 | $compiled .= $this->removeBlock('TopLevelBlock'); |
848 | 848 | |
849 | 849 | if ($this->debug) { |
850 | - echo 'PROCESSING POSTPROCESSORS' . "\n"; |
|
850 | + echo 'PROCESSING POSTPROCESSORS'."\n"; |
|
851 | 851 | } |
852 | 852 | |
853 | 853 | foreach ($this->processors['post'] as $postProc) { |
@@ -863,7 +863,7 @@ discard block |
||
863 | 863 | unset($postProc); |
864 | 864 | |
865 | 865 | if ($this->debug) { |
866 | - echo 'COMPILATION COMPLETE : MEM USAGE : ' . memory_get_usage() . "\n"; |
|
866 | + echo 'COMPILATION COMPLETE : MEM USAGE : '.memory_get_usage()."\n"; |
|
867 | 867 | } |
868 | 868 | |
869 | 869 | $output = "<?php\n/* template head */\n"; |
@@ -877,20 +877,20 @@ discard block |
||
877 | 877 | switch ($type) { |
878 | 878 | case Core::BLOCK_PLUGIN: |
879 | 879 | case Core::CLASS_PLUGIN: |
880 | - if (class_exists('Plugin' . $plugin) !== false) { |
|
881 | - $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)". |
|
880 | + if (class_exists('Plugin'.$plugin) !== false) { |
|
881 | + $output .= "if (class_exists('"."Plugin".$plugin."')===false)". |
|
882 | 882 | "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
883 | 883 | } else { |
884 | - $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_BLOCKS . "Plugin" . $plugin . "')===false)". |
|
884 | + $output .= "if (class_exists('".Core::NAMESPACE_PLUGINS_BLOCKS."Plugin".$plugin."')===false)". |
|
885 | 885 | "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
886 | 886 | } |
887 | 887 | break; |
888 | 888 | case Core::FUNC_PLUGIN: |
889 | - if (function_exists('Plugin' . $plugin) !== false) { |
|
890 | - $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)". |
|
889 | + if (function_exists('Plugin'.$plugin) !== false) { |
|
890 | + $output .= "if (function_exists('"."Plugin".$plugin."')===false)". |
|
891 | 891 | "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
892 | 892 | } else { |
893 | - $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)". |
|
893 | + $output .= "if (function_exists('".Core::NAMESPACE_PLUGINS_FUNCTIONS."Plugin".$plugin."')===false)". |
|
894 | 894 | "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n"; |
895 | 895 | } |
896 | 896 | break; |
@@ -910,7 +910,7 @@ discard block |
||
910 | 910 | $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin); |
911 | 911 | break; |
912 | 912 | default: |
913 | - throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type); |
|
913 | + throw new CompilationException($this, 'Type error for '.$plugin.' with type'.$type); |
|
914 | 914 | } |
915 | 915 | } |
916 | 916 | |
@@ -921,30 +921,30 @@ discard block |
||
921 | 921 | } |
922 | 922 | foreach ($this->templatePlugins as $function) { |
923 | 923 | if (isset($function['called']) && $function['called'] === true) { |
924 | - $output .= $function['body'] . PHP_EOL; |
|
924 | + $output .= $function['body'].PHP_EOL; |
|
925 | 925 | } |
926 | 926 | } |
927 | 927 | |
928 | - $output .= $compiled . "\n?>"; |
|
928 | + $output .= $compiled."\n?>"; |
|
929 | 929 | |
930 | - $output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*' . preg_quote(self::PHP_CLOSE, '/') . preg_quote(self::PHP_OPEN, '/') . ')/', ";\n", $output); |
|
931 | - $output = str_replace(self::PHP_CLOSE . self::PHP_OPEN, "\n", $output); |
|
930 | + $output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*'.preg_quote(self::PHP_CLOSE, '/').preg_quote(self::PHP_OPEN, '/').')/', ";\n", $output); |
|
931 | + $output = str_replace(self::PHP_CLOSE.self::PHP_OPEN, "\n", $output); |
|
932 | 932 | |
933 | 933 | // handle <?xml tag at the beginning |
934 | 934 | $output = preg_replace('#(/\* template body \*/ \?>\s*)<\?xml#is', '$1<?php echo \'<?xml\'; ?>', $output); |
935 | 935 | |
936 | 936 | // add another line break after PHP closing tags that have a line break following, |
937 | 937 | // as we do not know whether it's intended, and PHP will strip it otherwise |
938 | - $output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0' . "\n", $output); |
|
938 | + $output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0'."\n", $output); |
|
939 | 939 | |
940 | 940 | if ($this->debug) { |
941 | - echo '=============================================================================================' . "\n"; |
|
941 | + echo '============================================================================================='."\n"; |
|
942 | 942 | $lines = preg_split('{\r\n|\n|<br />}', $output); |
943 | 943 | array_shift($lines); |
944 | 944 | foreach ($lines as $i => $line) { |
945 | - echo ($i + 1) . '. ' . $line . "\r\n"; |
|
945 | + echo ($i+1).'. '.$line."\r\n"; |
|
946 | 946 | } |
947 | - echo '=============================================================================================' . "\n"; |
|
947 | + echo '============================================================================================='."\n"; |
|
948 | 948 | } |
949 | 949 | |
950 | 950 | $this->template = $this->dwoo = null; |
@@ -961,13 +961,13 @@ discard block |
||
961 | 961 | protected function resolveSubTemplateDependencies($function) |
962 | 962 | { |
963 | 963 | if ($this->debug) { |
964 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
964 | + echo 'Compiler::'.__FUNCTION__."\n"; |
|
965 | 965 | } |
966 | 966 | |
967 | 967 | $body = $this->templatePlugins[$function]['body']; |
968 | 968 | foreach ($this->templatePlugins as $func => $attr) { |
969 | - if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS . |
|
970 | - 'Plugin' . Core::toCamelCase($func)) !== false) { |
|
969 | + if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS. |
|
970 | + 'Plugin'.Core::toCamelCase($func)) !== false) { |
|
971 | 971 | $this->templatePlugins[$func]['called'] = true; |
972 | 972 | $this->resolveSubTemplateDependencies($func); |
973 | 973 | } |
@@ -991,14 +991,14 @@ discard block |
||
991 | 991 | |
992 | 992 | if ($this->curBlock['buffer'] === null && count($this->stack) > 1) { |
993 | 993 | // buffer is not initialized yet (the block has just been created) |
994 | - $this->stack[count($this->stack) - 2]['buffer'] .= (string)$content; |
|
994 | + $this->stack[count($this->stack)-2]['buffer'] .= (string) $content; |
|
995 | 995 | $this->curBlock['buffer'] = ''; |
996 | 996 | } else { |
997 | 997 | if (!isset($this->curBlock['buffer'])) { |
998 | 998 | throw new CompilationException($this, 'The template has been closed too early, you probably have an extra block-closing tag somewhere'); |
999 | 999 | } |
1000 | 1000 | // append current content to current block's buffer |
1001 | - $this->curBlock['buffer'] .= (string)$content; |
|
1001 | + $this->curBlock['buffer'] .= (string) $content; |
|
1002 | 1002 | } |
1003 | 1003 | $this->line += $lineCount; |
1004 | 1004 | } |
@@ -1068,23 +1068,23 @@ discard block |
||
1068 | 1068 | public function addBlock($type, array $params, $paramtype) |
1069 | 1069 | { |
1070 | 1070 | if ($this->debug) { |
1071 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1071 | + echo 'Compiler::'.__FUNCTION__."\n"; |
|
1072 | 1072 | } |
1073 | 1073 | |
1074 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type); |
|
1074 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($type); |
|
1075 | 1075 | if (class_exists($class) === false) { |
1076 | 1076 | $this->getDwoo()->getLoader()->loadPlugin($type); |
1077 | 1077 | } |
1078 | 1078 | $params = $this->mapParams($params, array($class, 'init'), $paramtype); |
1079 | 1079 | |
1080 | - $this->stack[] = array( |
|
1080 | + $this->stack[] = array( |
|
1081 | 1081 | 'type' => $type, |
1082 | 1082 | 'params' => $params, |
1083 | 1083 | 'custom' => false, |
1084 | 1084 | 'class' => $class, |
1085 | 1085 | 'buffer' => null |
1086 | 1086 | ); |
1087 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1087 | + $this->curBlock = &$this->stack[count($this->stack)-1]; |
|
1088 | 1088 | |
1089 | 1089 | return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type); |
1090 | 1090 | } |
@@ -1109,14 +1109,14 @@ discard block |
||
1109 | 1109 | |
1110 | 1110 | $params = $this->mapParams($params, array($class, 'init'), $paramtype); |
1111 | 1111 | |
1112 | - $this->stack[] = array( |
|
1112 | + $this->stack[] = array( |
|
1113 | 1113 | 'type' => $type, |
1114 | 1114 | 'params' => $params, |
1115 | 1115 | 'custom' => true, |
1116 | 1116 | 'class' => $class, |
1117 | 1117 | 'buffer' => null |
1118 | 1118 | ); |
1119 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1119 | + $this->curBlock = &$this->stack[count($this->stack)-1]; |
|
1120 | 1120 | |
1121 | 1121 | return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type); |
1122 | 1122 | } |
@@ -1131,21 +1131,21 @@ discard block |
||
1131 | 1131 | public function injectBlock($type, array $params) |
1132 | 1132 | { |
1133 | 1133 | if ($this->debug) { |
1134 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1134 | + echo 'Compiler::'.__FUNCTION__."\n"; |
|
1135 | 1135 | } |
1136 | 1136 | |
1137 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type); |
|
1137 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($type); |
|
1138 | 1138 | if (class_exists($class) === false) { |
1139 | 1139 | $this->getDwoo()->getLoader()->loadPlugin($type); |
1140 | 1140 | } |
1141 | - $this->stack[] = array( |
|
1141 | + $this->stack[] = array( |
|
1142 | 1142 | 'type' => $type, |
1143 | 1143 | 'params' => $params, |
1144 | 1144 | 'custom' => false, |
1145 | 1145 | 'class' => $class, |
1146 | 1146 | 'buffer' => null |
1147 | 1147 | ); |
1148 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1148 | + $this->curBlock = &$this->stack[count($this->stack)-1]; |
|
1149 | 1149 | } |
1150 | 1150 | |
1151 | 1151 | /** |
@@ -1160,7 +1160,7 @@ discard block |
||
1160 | 1160 | public function removeBlock($type) |
1161 | 1161 | { |
1162 | 1162 | if ($this->debug) { |
1163 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1163 | + echo 'Compiler::'.__FUNCTION__."\n"; |
|
1164 | 1164 | } |
1165 | 1165 | |
1166 | 1166 | $output = ''; |
@@ -1174,10 +1174,10 @@ discard block |
||
1174 | 1174 | if ($top['custom']) { |
1175 | 1175 | $class = $top['class']; |
1176 | 1176 | } else { |
1177 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($top['type']); |
|
1177 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($top['type']); |
|
1178 | 1178 | } |
1179 | 1179 | if (count($this->stack)) { |
1180 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1180 | + $this->curBlock = &$this->stack[count($this->stack)-1]; |
|
1181 | 1181 | $this->push(call_user_func(array( |
1182 | 1182 | $class, |
1183 | 1183 | 'postProcessing' |
@@ -1198,7 +1198,7 @@ discard block |
||
1198 | 1198 | } |
1199 | 1199 | } |
1200 | 1200 | |
1201 | - throw new CompilationException($this, 'Syntax malformation, a block of type "' . $type . '" was closed but was not opened'); |
|
1201 | + throw new CompilationException($this, 'Syntax malformation, a block of type "'.$type.'" was closed but was not opened'); |
|
1202 | 1202 | break; |
1203 | 1203 | } |
1204 | 1204 | |
@@ -1237,7 +1237,7 @@ discard block |
||
1237 | 1237 | } |
1238 | 1238 | } |
1239 | 1239 | |
1240 | - throw new CompilationException($this, 'A parent block of type "' . $type . '" is required and can not be found'); |
|
1240 | + throw new CompilationException($this, 'A parent block of type "'.$type.'" is required and can not be found'); |
|
1241 | 1241 | } |
1242 | 1242 | |
1243 | 1243 | /** |
@@ -1260,7 +1260,7 @@ discard block |
||
1260 | 1260 | public function removeTopBlock() |
1261 | 1261 | { |
1262 | 1262 | if ($this->debug) { |
1263 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1263 | + echo 'Compiler::'.__FUNCTION__."\n"; |
|
1264 | 1264 | } |
1265 | 1265 | |
1266 | 1266 | $o = array_pop($this->stack); |
@@ -1270,10 +1270,10 @@ discard block |
||
1270 | 1270 | if ($o['custom']) { |
1271 | 1271 | $class = $o['class']; |
1272 | 1272 | } else { |
1273 | - $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($o['type']); |
|
1273 | + $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($o['type']); |
|
1274 | 1274 | } |
1275 | 1275 | |
1276 | - $this->curBlock = &$this->stack[count($this->stack) - 1]; |
|
1276 | + $this->curBlock = &$this->stack[count($this->stack)-1]; |
|
1277 | 1277 | |
1278 | 1278 | return call_user_func(array($class, 'postProcessing'), $this, $o['params'], '', '', $o['buffer']); |
1279 | 1279 | } |
@@ -1352,7 +1352,7 @@ discard block |
||
1352 | 1352 | protected function parse($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
1353 | 1353 | { |
1354 | 1354 | if ($this->debug) { |
1355 | - echo 'Compiler::' . __FUNCTION__ . "\n"; |
|
1355 | + echo 'Compiler::'.__FUNCTION__."\n"; |
|
1356 | 1356 | } |
1357 | 1357 | |
1358 | 1358 | if ($to === null) { |
@@ -1369,14 +1369,14 @@ discard block |
||
1369 | 1369 | // end template tag |
1370 | 1370 | $pointer += strlen($this->rd); |
1371 | 1371 | if ($this->debug) { |
1372 | - echo 'TEMPLATE PARSING ENDED' . "\n"; |
|
1372 | + echo 'TEMPLATE PARSING ENDED'."\n"; |
|
1373 | 1373 | } |
1374 | 1374 | |
1375 | 1375 | return false; |
1376 | 1376 | } |
1377 | - ++ $from; |
|
1377 | + ++$from; |
|
1378 | 1378 | if ($pointer !== null) { |
1379 | - ++ $pointer; |
|
1379 | + ++$pointer; |
|
1380 | 1380 | } |
1381 | 1381 | if ($from >= $to) { |
1382 | 1382 | if (is_array($parsingParams)) { |
@@ -1388,22 +1388,22 @@ discard block |
||
1388 | 1388 | $first = $in[$from]; |
1389 | 1389 | } |
1390 | 1390 | |
1391 | - $substr = substr($in, $from, $to - $from); |
|
1391 | + $substr = substr($in, $from, $to-$from); |
|
1392 | 1392 | |
1393 | 1393 | if ($this->debug) { |
1394 | - echo 'PARSE CALL : PARSING "<b>' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . '</b>" @ ' . $from . ':' . $to . ' in ' . $curBlock . ' : pointer=' . $pointer . "\n"; |
|
1394 | + echo 'PARSE CALL : PARSING "<b>'.htmlentities(substr($in, $from, min($to-$from, 50))).(($to-$from) > 50 ? '...' : '').'</b>" @ '.$from.':'.$to.' in '.$curBlock.' : pointer='.$pointer."\n"; |
|
1395 | 1395 | } |
1396 | 1396 | $parsed = ''; |
1397 | 1397 | |
1398 | 1398 | if ($curBlock === 'root' && $first === '*') { |
1399 | 1399 | $src = $this->getTemplateSource(); |
1400 | - $startpos = $this->getPointer() - strlen($this->ld); |
|
1400 | + $startpos = $this->getPointer()-strlen($this->ld); |
|
1401 | 1401 | if (substr($src, $startpos, strlen($this->ld)) === $this->ld) { |
1402 | 1402 | if ($startpos > 0) { |
1403 | 1403 | do { |
1404 | 1404 | $char = substr($src, -- $startpos, 1); |
1405 | 1405 | if ($char == "\n") { |
1406 | - ++ $startpos; |
|
1406 | + ++$startpos; |
|
1407 | 1407 | $whitespaceStart = true; |
1408 | 1408 | break; |
1409 | 1409 | } |
@@ -1414,12 +1414,12 @@ discard block |
||
1414 | 1414 | if (!isset($whitespaceStart)) { |
1415 | 1415 | $startpos = $this->getPointer(); |
1416 | 1416 | } else { |
1417 | - $pointer -= $this->getPointer() - $startpos; |
|
1417 | + $pointer -= $this->getPointer()-$startpos; |
|
1418 | 1418 | } |
1419 | 1419 | |
1420 | - if ($this->allowNestedComments && strpos($src, $this->ld . '*', $this->getPointer()) !== false) { |
|
1421 | - $comOpen = $this->ld . '*'; |
|
1422 | - $comClose = '*' . $this->rd; |
|
1420 | + if ($this->allowNestedComments && strpos($src, $this->ld.'*', $this->getPointer()) !== false) { |
|
1421 | + $comOpen = $this->ld.'*'; |
|
1422 | + $comClose = '*'.$this->rd; |
|
1423 | 1423 | $level = 1; |
1424 | 1424 | $ptr = $this->getPointer(); |
1425 | 1425 | |
@@ -1429,33 +1429,33 @@ discard block |
||
1429 | 1429 | |
1430 | 1430 | if ($open !== false && $close !== false) { |
1431 | 1431 | if ($open < $close) { |
1432 | - $ptr = $open + strlen($comOpen); |
|
1433 | - ++ $level; |
|
1432 | + $ptr = $open+strlen($comOpen); |
|
1433 | + ++$level; |
|
1434 | 1434 | } else { |
1435 | - $ptr = $close + strlen($comClose); |
|
1436 | - -- $level; |
|
1435 | + $ptr = $close+strlen($comClose); |
|
1436 | + --$level; |
|
1437 | 1437 | } |
1438 | 1438 | } elseif ($open !== false) { |
1439 | - $ptr = $open + strlen($comOpen); |
|
1440 | - ++ $level; |
|
1439 | + $ptr = $open+strlen($comOpen); |
|
1440 | + ++$level; |
|
1441 | 1441 | } elseif ($close !== false) { |
1442 | - $ptr = $close + strlen($comClose); |
|
1443 | - -- $level; |
|
1442 | + $ptr = $close+strlen($comClose); |
|
1443 | + --$level; |
|
1444 | 1444 | } else { |
1445 | 1445 | $ptr = strlen($src); |
1446 | 1446 | } |
1447 | 1447 | } |
1448 | - $endpos = $ptr - strlen('*' . $this->rd); |
|
1448 | + $endpos = $ptr-strlen('*'.$this->rd); |
|
1449 | 1449 | } else { |
1450 | - $endpos = strpos($src, '*' . $this->rd, $startpos); |
|
1450 | + $endpos = strpos($src, '*'.$this->rd, $startpos); |
|
1451 | 1451 | if ($endpos == false) { |
1452 | 1452 | throw new CompilationException($this, 'Un-ended comment'); |
1453 | 1453 | } |
1454 | 1454 | } |
1455 | - $pointer += $endpos - $startpos + strlen('*' . $this->rd); |
|
1456 | - if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos + strlen('*' . $this->rd)), $m)) { |
|
1455 | + $pointer += $endpos-$startpos+strlen('*'.$this->rd); |
|
1456 | + if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos+strlen('*'.$this->rd)), $m)) { |
|
1457 | 1457 | $pointer += strlen($m[0]); |
1458 | - $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer']) - ($this->getPointer() - $startpos - strlen($this->ld))); |
|
1458 | + $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer'])-($this->getPointer()-$startpos-strlen($this->ld))); |
|
1459 | 1459 | } |
1460 | 1460 | |
1461 | 1461 | return false; |
@@ -1472,20 +1472,20 @@ discard block |
||
1472 | 1472 | } elseif (($first === '"' || $first === "'") && !(is_array($parsingParams) && preg_match('#^([\'"])[a-z0-9_]+\1\s*=>?(?:\s+|[^=])#i', $substr))) { |
1473 | 1473 | // string |
1474 | 1474 | $out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer); |
1475 | - } elseif (preg_match('/^\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?(' . (is_array($parsingParams) || $curBlock != 'root' ? '' : '\s+[^(]|') . '\s*\(|\s*' . $this->rdr . '|\s*;)/i', $substr)) { |
|
1475 | + } elseif (preg_match('/^\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?('.(is_array($parsingParams) || $curBlock != 'root' ? '' : '\s+[^(]|').'\s*\(|\s*'.$this->rdr.'|\s*;)/i', $substr)) { |
|
1476 | 1476 | // func |
1477 | 1477 | $out = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer); |
1478 | 1478 | $parsed = 'func'; |
1479 | 1479 | } elseif ($first === ';') { |
1480 | 1480 | // instruction end |
1481 | 1481 | if ($this->debug) { |
1482 | - echo 'END OF INSTRUCTION' . "\n"; |
|
1482 | + echo 'END OF INSTRUCTION'."\n"; |
|
1483 | 1483 | } |
1484 | 1484 | if ($pointer !== null) { |
1485 | - ++ $pointer; |
|
1485 | + ++$pointer; |
|
1486 | 1486 | } |
1487 | 1487 | |
1488 | - return $this->parse($in, $from + 1, $to, false, 'root', $pointer); |
|
1488 | + return $this->parse($in, $from+1, $to, false, 'root', $pointer); |
|
1489 | 1489 | } elseif ($curBlock === 'root' && preg_match('#^/([a-z_][a-z0-9_]*)?#i', $substr, $match)) { |
1490 | 1490 | // close block |
1491 | 1491 | if (!empty($match[1]) && $match[1] == 'else') { |
@@ -1502,13 +1502,13 @@ discard block |
||
1502 | 1502 | $pointer -= strlen($match[0]); |
1503 | 1503 | } |
1504 | 1504 | if ($this->debug) { |
1505 | - echo 'TOP BLOCK CLOSED' . "\n"; |
|
1505 | + echo 'TOP BLOCK CLOSED'."\n"; |
|
1506 | 1506 | } |
1507 | 1507 | |
1508 | 1508 | return $this->removeTopBlock(); |
1509 | 1509 | } else { |
1510 | 1510 | if ($this->debug) { |
1511 | - echo 'BLOCK OF TYPE ' . $match[1] . ' CLOSED' . "\n"; |
|
1511 | + echo 'BLOCK OF TYPE '.$match[1].' CLOSED'."\n"; |
|
1512 | 1512 | } |
1513 | 1513 | |
1514 | 1514 | return $this->removeBlock($match[1]); |
@@ -1516,19 +1516,19 @@ discard block |
||
1516 | 1516 | } elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) { |
1517 | 1517 | // end template tag |
1518 | 1518 | if ($this->debug) { |
1519 | - echo 'TAG PARSING ENDED' . "\n"; |
|
1519 | + echo 'TAG PARSING ENDED'."\n"; |
|
1520 | 1520 | } |
1521 | 1521 | $pointer += strlen($this->rd); |
1522 | 1522 | |
1523 | 1523 | return false; |
1524 | - } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*=' . ($curBlock === 'array' ? '>?' : '') . ')(?:\s+|[^=]).*#i', $substr, $match)) { |
|
1524 | + } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*='.($curBlock === 'array' ? '>?' : '').')(?:\s+|[^=]).*#i', $substr, $match)) { |
|
1525 | 1525 | // named parameter |
1526 | 1526 | if ($this->debug) { |
1527 | - echo 'NAMED PARAM FOUND' . "\n"; |
|
1527 | + echo 'NAMED PARAM FOUND'."\n"; |
|
1528 | 1528 | } |
1529 | 1529 | $len = strlen($match[1]); |
1530 | - while (substr($in, $from + $len, 1) === ' ') { |
|
1531 | - ++ $len; |
|
1530 | + while (substr($in, $from+$len, 1) === ' ') { |
|
1531 | + ++$len; |
|
1532 | 1532 | } |
1533 | 1533 | if ($pointer !== null) { |
1534 | 1534 | $pointer += $len; |
@@ -1536,7 +1536,7 @@ discard block |
||
1536 | 1536 | |
1537 | 1537 | $output = array( |
1538 | 1538 | trim($match[1], " \t\r\n=>'\""), |
1539 | - $this->parse($in, $from + $len, $to, false, 'namedparam', $pointer) |
|
1539 | + $this->parse($in, $from+$len, $to, false, 'namedparam', $pointer) |
|
1540 | 1540 | ); |
1541 | 1541 | |
1542 | 1542 | $parsingParams[] = $output; |
@@ -1557,31 +1557,31 @@ discard block |
||
1557 | 1557 | $out = $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
1558 | 1558 | } else { |
1559 | 1559 | // parse error |
1560 | - throw new CompilationException($this, 'Parse error in "' . substr($in, $from, $to - $from) . '"'); |
|
1560 | + throw new CompilationException($this, 'Parse error in "'.substr($in, $from, $to-$from).'"'); |
|
1561 | 1561 | } |
1562 | 1562 | |
1563 | 1563 | if (empty($out)) { |
1564 | 1564 | return ''; |
1565 | 1565 | } |
1566 | 1566 | |
1567 | - $substr = substr($in, $pointer, $to - $pointer); |
|
1567 | + $substr = substr($in, $pointer, $to-$pointer); |
|
1568 | 1568 | |
1569 | 1569 | // var parsed, check if any var-extension applies |
1570 | 1570 | if ($parsed === 'var') { |
1571 | 1571 | if (preg_match('#^\s*([/%+*-])\s*([a-z0-9]|\$)#i', $substr, $match)) { |
1572 | 1572 | if ($this->debug) { |
1573 | - echo 'PARSING POST-VAR EXPRESSION ' . $substr . "\n"; |
|
1573 | + echo 'PARSING POST-VAR EXPRESSION '.$substr."\n"; |
|
1574 | 1574 | } |
1575 | 1575 | // parse expressions |
1576 | - $pointer += strlen($match[0]) - 1; |
|
1576 | + $pointer += strlen($match[0])-1; |
|
1577 | 1577 | if (is_array($parsingParams)) { |
1578 | 1578 | if ($match[2] == '$') { |
1579 | 1579 | $expr = $this->parseVar($in, $pointer, $to, array(), $curBlock, $pointer); |
1580 | 1580 | } else { |
1581 | 1581 | $expr = $this->parse($in, $pointer, $to, array(), 'expression', $pointer); |
1582 | 1582 | } |
1583 | - $out[count($out) - 1][0] .= $match[1] . $expr[0][0]; |
|
1584 | - $out[count($out) - 1][1] .= $match[1] . $expr[0][1]; |
|
1583 | + $out[count($out)-1][0] .= $match[1].$expr[0][0]; |
|
1584 | + $out[count($out)-1][1] .= $match[1].$expr[0][1]; |
|
1585 | 1585 | } else { |
1586 | 1586 | if ($match[2] == '$') { |
1587 | 1587 | $expr = $this->parseVar($in, $pointer, $to, false, $curBlock, $pointer); |
@@ -1589,26 +1589,26 @@ discard block |
||
1589 | 1589 | $expr = $this->parse($in, $pointer, $to, false, 'expression', $pointer); |
1590 | 1590 | } |
1591 | 1591 | if (is_array($out) && is_array($expr)) { |
1592 | - $out[0] .= $match[1] . $expr[0]; |
|
1593 | - $out[1] .= $match[1] . $expr[1]; |
|
1592 | + $out[0] .= $match[1].$expr[0]; |
|
1593 | + $out[1] .= $match[1].$expr[1]; |
|
1594 | 1594 | } elseif (is_array($out)) { |
1595 | - $out[0] .= $match[1] . $expr; |
|
1596 | - $out[1] .= $match[1] . $expr; |
|
1595 | + $out[0] .= $match[1].$expr; |
|
1596 | + $out[1] .= $match[1].$expr; |
|
1597 | 1597 | } elseif (is_array($expr)) { |
1598 | - $out .= $match[1] . $expr[0]; |
|
1598 | + $out .= $match[1].$expr[0]; |
|
1599 | 1599 | } else { |
1600 | - $out .= $match[1] . $expr; |
|
1600 | + $out .= $match[1].$expr; |
|
1601 | 1601 | } |
1602 | 1602 | } |
1603 | 1603 | } elseif ($curBlock === 'root' && preg_match('#^(\s*(?:[+/*%-.]=|=|\+\+|--)\s*)(.*)#s', $substr, $match)) { |
1604 | 1604 | if ($this->debug) { |
1605 | - echo 'PARSING POST-VAR ASSIGNMENT ' . $substr . "\n"; |
|
1605 | + echo 'PARSING POST-VAR ASSIGNMENT '.$substr."\n"; |
|
1606 | 1606 | } |
1607 | 1607 | // parse assignment |
1608 | 1608 | $value = $match[2]; |
1609 | 1609 | $operator = trim($match[1]); |
1610 | 1610 | if (substr($value, 0, 1) == '=') { |
1611 | - throw new CompilationException($this, 'Unexpected "=" in <em>' . $substr . '</em>'); |
|
1611 | + throw new CompilationException($this, 'Unexpected "=" in <em>'.$substr.'</em>'); |
|
1612 | 1612 | } |
1613 | 1613 | |
1614 | 1614 | if ($pointer !== null) { |
@@ -1629,7 +1629,7 @@ discard block |
||
1629 | 1629 | throw new CompilationException($this, 'Assignments require the "if" plugin to be accessible'); |
1630 | 1630 | } |
1631 | 1631 | |
1632 | - $parts = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS . 'PluginIf', 'init'), 1); |
|
1632 | + $parts = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS.'PluginIf', 'init'), 1); |
|
1633 | 1633 | $tokens = $this->getParamTokens($parts); |
1634 | 1634 | $parts = $this->getCompiledParams($parts); |
1635 | 1635 | |
@@ -1643,14 +1643,14 @@ discard block |
||
1643 | 1643 | if ($this->autoEscape) { |
1644 | 1644 | $out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out); |
1645 | 1645 | } |
1646 | - $out = self::PHP_OPEN . $echo . $out . $operator . implode(' ', $value) . self::PHP_CLOSE; |
|
1646 | + $out = self::PHP_OPEN.$echo.$out.$operator.implode(' ', $value).self::PHP_CLOSE; |
|
1647 | 1647 | } elseif ($curBlock === 'array' && is_array($parsingParams) && preg_match('#^(\s*=>?\s*)#', $substr, $match)) { |
1648 | 1648 | // parse namedparam with var as name (only for array) |
1649 | 1649 | if ($this->debug) { |
1650 | - echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND' . "\n"; |
|
1650 | + echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND'."\n"; |
|
1651 | 1651 | } |
1652 | 1652 | $len = strlen($match[1]); |
1653 | - $var = $out[count($out) - 1]; |
|
1653 | + $var = $out[count($out)-1]; |
|
1654 | 1654 | $pointer += $len; |
1655 | 1655 | |
1656 | 1656 | $output = array($var[0], $this->parse($substr, $len, null, false, 'namedparam', $pointer)); |
@@ -1665,16 +1665,16 @@ discard block |
||
1665 | 1665 | // parse modifier on funcs or vars |
1666 | 1666 | $srcPointer = $pointer; |
1667 | 1667 | if (is_array($parsingParams)) { |
1668 | - $tmp = $this->replaceModifiers( |
|
1668 | + $tmp = $this->replaceModifiers( |
|
1669 | 1669 | array( |
1670 | 1670 | null, |
1671 | 1671 | null, |
1672 | - $out[count($out) - 1][0], |
|
1672 | + $out[count($out)-1][0], |
|
1673 | 1673 | $match[0] |
1674 | 1674 | ), $curBlock, $pointer |
1675 | 1675 | ); |
1676 | - $out[count($out) - 1][0] = $tmp; |
|
1677 | - $out[count($out) - 1][1] .= substr($substr, $srcPointer, $srcPointer - $pointer); |
|
1676 | + $out[count($out)-1][0] = $tmp; |
|
1677 | + $out[count($out)-1][1] .= substr($substr, $srcPointer, $srcPointer-$pointer); |
|
1678 | 1678 | } else { |
1679 | 1679 | $out = $this->replaceModifiers(array(null, null, $out, $match[0]), $curBlock, $pointer); |
1680 | 1680 | } |
@@ -1686,10 +1686,10 @@ discard block |
||
1686 | 1686 | $ptr = 0; |
1687 | 1687 | |
1688 | 1688 | if (is_array($parsingParams)) { |
1689 | - $output = $this->parseMethodCall($out[count($out) - 1][1], $match[0], $curBlock, $ptr); |
|
1689 | + $output = $this->parseMethodCall($out[count($out)-1][1], $match[0], $curBlock, $ptr); |
|
1690 | 1690 | |
1691 | - $out[count($out) - 1][0] = $output; |
|
1692 | - $out[count($out) - 1][1] .= substr($match[0], 0, $ptr); |
|
1691 | + $out[count($out)-1][0] = $output; |
|
1692 | + $out[count($out)-1][1] .= substr($match[0], 0, $ptr); |
|
1693 | 1693 | } else { |
1694 | 1694 | $out = $this->parseMethodCall($out, $match[0], $curBlock, $ptr); |
1695 | 1695 | } |
@@ -1698,7 +1698,7 @@ discard block |
||
1698 | 1698 | } |
1699 | 1699 | |
1700 | 1700 | if ($curBlock === 'root' && substr($out, 0, strlen(self::PHP_OPEN)) !== self::PHP_OPEN) { |
1701 | - return self::PHP_OPEN . 'echo ' . $out . ';' . self::PHP_CLOSE; |
|
1701 | + return self::PHP_OPEN.'echo '.$out.';'.self::PHP_CLOSE; |
|
1702 | 1702 | } else { |
1703 | 1703 | return $out; |
1704 | 1704 | } |
@@ -1724,11 +1724,11 @@ discard block |
||
1724 | 1724 | protected function parseFunction($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
1725 | 1725 | { |
1726 | 1726 | $output = ''; |
1727 | - $cmdstr = substr($in, $from, $to - $from); |
|
1728 | - preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*' . $this->rdr . '|\s*;)?/i', $cmdstr, $match); |
|
1727 | + $cmdstr = substr($in, $from, $to-$from); |
|
1728 | + preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*'.$this->rdr.'|\s*;)?/i', $cmdstr, $match); |
|
1729 | 1729 | |
1730 | 1730 | if (empty($match[1])) { |
1731 | - throw new CompilationException($this, 'Parse error, invalid function name : ' . substr($cmdstr, 0, 15)); |
|
1731 | + throw new CompilationException($this, 'Parse error, invalid function name : '.substr($cmdstr, 0, 15)); |
|
1732 | 1732 | } |
1733 | 1733 | |
1734 | 1734 | $func = $match[1]; |
@@ -1738,7 +1738,7 @@ discard block |
||
1738 | 1738 | } |
1739 | 1739 | |
1740 | 1740 | if ($this->debug) { |
1741 | - echo 'FUNC FOUND (' . $func . ')' . "\n"; |
|
1741 | + echo 'FUNC FOUND ('.$func.')'."\n"; |
|
1742 | 1742 | } |
1743 | 1743 | |
1744 | 1744 | $paramsep = ''; |
@@ -1750,11 +1750,11 @@ discard block |
||
1750 | 1750 | $paramspos = $match[1][0][1]; |
1751 | 1751 | $paramsep = substr($match[1][0][0], - 1) === '(' ? ')' : ''; |
1752 | 1752 | if ($paramsep === ')') { |
1753 | - $paramspos += strlen($match[1][0][0]) - 1; |
|
1753 | + $paramspos += strlen($match[1][0][0])-1; |
|
1754 | 1754 | if (substr($cmdstr, 0, 2) === 'if' || substr($cmdstr, 0, 6) === 'elseif') { |
1755 | 1755 | $paramsep = ''; |
1756 | 1756 | if (strlen($match[1][0][0]) > 1) { |
1757 | - -- $paramspos; |
|
1757 | + --$paramspos; |
|
1758 | 1758 | } |
1759 | 1759 | } |
1760 | 1760 | } |
@@ -1779,8 +1779,8 @@ discard block |
||
1779 | 1779 | return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer); |
1780 | 1780 | } |
1781 | 1781 | } |
1782 | - $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos - strlen($func))); |
|
1783 | - $paramstr = substr($cmdstr, $paramspos + 1); |
|
1782 | + $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos-strlen($func))); |
|
1783 | + $paramstr = substr($cmdstr, $paramspos+1); |
|
1784 | 1784 | if (substr($paramstr, - 1, 1) === $paramsep) { |
1785 | 1785 | $paramstr = substr($paramstr, 0, - 1); |
1786 | 1786 | } |
@@ -1802,36 +1802,36 @@ discard block |
||
1802 | 1802 | |
1803 | 1803 | if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') { |
1804 | 1804 | if ($this->debug) { |
1805 | - echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1805 | + echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT '.$ptr."\n"; |
|
1806 | 1806 | } |
1807 | 1807 | break 2; |
1808 | 1808 | } elseif ($paramstr[$ptr] === ';') { |
1809 | - ++ $ptr; |
|
1809 | + ++$ptr; |
|
1810 | 1810 | if ($this->debug) { |
1811 | - echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1811 | + echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT '.$ptr."\n"; |
|
1812 | 1812 | } |
1813 | 1813 | break 2; |
1814 | 1814 | } elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') { |
1815 | 1815 | if ($this->debug) { |
1816 | - echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT ' . $ptr . "\n"; |
|
1816 | + echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT '.$ptr."\n"; |
|
1817 | 1817 | } |
1818 | 1818 | break 2; |
1819 | 1819 | } elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) { |
1820 | 1820 | if ($this->debug) { |
1821 | - echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT ' . $ptr . "\n"; |
|
1821 | + echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT '.$ptr."\n"; |
|
1822 | 1822 | } |
1823 | 1823 | break 2; |
1824 | 1824 | } |
1825 | 1825 | |
1826 | 1826 | if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") { |
1827 | - ++ $ptr; |
|
1827 | + ++$ptr; |
|
1828 | 1828 | } else { |
1829 | 1829 | break; |
1830 | 1830 | } |
1831 | 1831 | } |
1832 | 1832 | |
1833 | 1833 | if ($this->debug) { |
1834 | - echo 'FUNC START PARAM PARSING WITH POINTER AT ' . $ptr . "\n"; |
|
1834 | + echo 'FUNC START PARAM PARSING WITH POINTER AT '.$ptr."\n"; |
|
1835 | 1835 | } |
1836 | 1836 | |
1837 | 1837 | if ($func === 'if' || $func === 'elseif' || $func === 'tif') { |
@@ -1843,7 +1843,7 @@ discard block |
||
1843 | 1843 | } |
1844 | 1844 | |
1845 | 1845 | if ($this->debug) { |
1846 | - echo 'PARAM PARSED, POINTER AT ' . $ptr . ' (' . substr($paramstr, $ptr - 1, 3) . ')' . "\n"; |
|
1846 | + echo 'PARAM PARSED, POINTER AT '.$ptr.' ('.substr($paramstr, $ptr-1, 3).')'."\n"; |
|
1847 | 1847 | } |
1848 | 1848 | } |
1849 | 1849 | } |
@@ -1867,16 +1867,16 @@ discard block |
||
1867 | 1867 | } |
1868 | 1868 | |
1869 | 1869 | if ($pointer !== null) { |
1870 | - $pointer += (isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func) + (isset($whitespace) ? $whitespace : 0); |
|
1870 | + $pointer += (isset($paramstr) ? strlen($paramstr) : 0)+(')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1))+strlen($func)+(isset($whitespace) ? $whitespace : 0); |
|
1871 | 1871 | if ($this->debug) { |
1872 | - echo 'FUNC ADDS ' . ((isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func)) . ' TO POINTER' . "\n"; |
|
1872 | + echo 'FUNC ADDS '.((isset($paramstr) ? strlen($paramstr) : 0)+(')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1))+strlen($func)).' TO POINTER'."\n"; |
|
1873 | 1873 | } |
1874 | 1874 | } |
1875 | 1875 | |
1876 | 1876 | if ($curBlock === 'method' || $func === 'do' || strstr($func, '::') !== false) { |
1877 | 1877 | // handle static method calls with security policy |
1878 | 1878 | if (strstr($func, '::') !== false && $this->securityPolicy !== null && $this->securityPolicy->isMethodAllowed(explode('::', strtolower($func))) !== true) { |
1879 | - throw new SecurityException('Call to a disallowed php function : ' . $func); |
|
1879 | + throw new SecurityException('Call to a disallowed php function : '.$func); |
|
1880 | 1880 | } |
1881 | 1881 | $pluginType = Core::NATIVE_PLUGIN; |
1882 | 1882 | } else { |
@@ -1920,14 +1920,14 @@ discard block |
||
1920 | 1920 | $this->customPlugins[$func]['function'] |
1921 | 1921 | ), $state); |
1922 | 1922 | } else { |
1923 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
1923 | + if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) { |
|
1924 | 1924 | $params = $this->mapParams($params, array( |
1925 | - 'Plugin' . Core::toCamelCase($func), |
|
1925 | + 'Plugin'.Core::toCamelCase($func), |
|
1926 | 1926 | ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process' |
1927 | 1927 | ), $state); |
1928 | 1928 | } else { |
1929 | 1929 | $params = $this->mapParams($params, array( |
1930 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
1930 | + Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func), |
|
1931 | 1931 | ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process' |
1932 | 1932 | ), $state); |
1933 | 1933 | } |
@@ -1937,23 +1937,21 @@ discard block |
||
1937 | 1937 | $params = $this->mapParams($params, $this->customPlugins[$func]['callback'], $state); |
1938 | 1938 | } else { |
1939 | 1939 | // Custom plugin |
1940 | - if (function_exists('Plugin' . Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? |
|
1940 | + if (function_exists('Plugin'.Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ? |
|
1941 | 1941 | 'Compile' : '')) !== false) { |
1942 | - $params = $this->mapParams($params, 'Plugin' . Core::toCamelCase($func) . (($pluginType & |
|
1942 | + $params = $this->mapParams($params, 'Plugin'.Core::toCamelCase($func).(($pluginType & |
|
1943 | 1943 | Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
1944 | 1944 | } // Builtin helper plugin |
1945 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . ( |
|
1945 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).( |
|
1946 | 1946 | ($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) !== false) { |
1947 | - $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase |
|
1948 | - ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1947 | + $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1949 | 1948 | } // Builtin function plugin |
1950 | 1949 | else { |
1951 | - $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase |
|
1952 | - ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1950 | + $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state); |
|
1953 | 1951 | } |
1954 | 1952 | } |
1955 | 1953 | } elseif ($pluginType & Core::SMARTY_MODIFIER) { |
1956 | - $output = 'smarty_modifier_' . $func . '(' . implode(', ', $params) . ')'; |
|
1954 | + $output = 'smarty_modifier_'.$func.'('.implode(', ', $params).')'; |
|
1957 | 1955 | } elseif ($pluginType & Core::PROXY_PLUGIN) { |
1958 | 1956 | $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state); |
1959 | 1957 | } elseif ($pluginType & Core::TEMPLATE_PLUGIN) { |
@@ -1988,7 +1986,7 @@ discard block |
||
1988 | 1986 | if ($pluginType & Core::NATIVE_PLUGIN) { |
1989 | 1987 | if ($func === 'do') { |
1990 | 1988 | if (isset($params['*'])) { |
1991 | - $output = implode(';', $params['*']) . ';'; |
|
1989 | + $output = implode(';', $params['*']).';'; |
|
1992 | 1990 | } else { |
1993 | 1991 | $output = ''; |
1994 | 1992 | } |
@@ -1996,13 +1994,13 @@ discard block |
||
1996 | 1994 | if (is_array($parsingParams) || $curBlock !== 'root') { |
1997 | 1995 | throw new CompilationException($this, 'Do can not be used inside another function or block'); |
1998 | 1996 | } else { |
1999 | - return self::PHP_OPEN . $output . self::PHP_CLOSE; |
|
1997 | + return self::PHP_OPEN.$output.self::PHP_CLOSE; |
|
2000 | 1998 | } |
2001 | 1999 | } else { |
2002 | 2000 | if (isset($params['*'])) { |
2003 | - $output = $func . '(' . implode(', ', $params['*']) . ')'; |
|
2001 | + $output = $func.'('.implode(', ', $params['*']).')'; |
|
2004 | 2002 | } else { |
2005 | - $output = $func . '()'; |
|
2003 | + $output = $func.'()'; |
|
2006 | 2004 | } |
2007 | 2005 | } |
2008 | 2006 | } elseif ($pluginType & Core::FUNC_PLUGIN) { |
@@ -2011,16 +2009,16 @@ discard block |
||
2011 | 2009 | $funcCompiler = $this->customPlugins[$func]['callback']; |
2012 | 2010 | } else { |
2013 | 2011 | // Custom plugin |
2014 | - if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) { |
|
2015 | - $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile'; |
|
2012 | + if (function_exists('Plugin'.Core::toCamelCase($func).'Compile') !== false) { |
|
2013 | + $funcCompiler = 'Plugin'.Core::toCamelCase($func).'Compile'; |
|
2016 | 2014 | } // Builtin helper plugin |
2017 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . |
|
2015 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func). |
|
2018 | 2016 | 'Compile') !== false) { |
2019 | - $funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . |
|
2017 | + $funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func). |
|
2020 | 2018 | 'Compile'; |
2021 | 2019 | } // Builtin function plugin |
2022 | 2020 | else { |
2023 | - $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . |
|
2021 | + $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func). |
|
2024 | 2022 | 'Compile'; |
2025 | 2023 | } |
2026 | 2024 | } |
@@ -2035,24 +2033,24 @@ discard block |
||
2035 | 2033 | if ($pluginType & Core::CUSTOM_PLUGIN) { |
2036 | 2034 | $callback = $this->customPlugins[$func]['callback']; |
2037 | 2035 | if ($callback instanceof Closure) { |
2038 | - $output = 'call_user_func($this->getCustomPlugin(\'' . $func . '\'), ' . $params . ')'; |
|
2036 | + $output = 'call_user_func($this->getCustomPlugin(\''.$func.'\'), '.$params.')'; |
|
2039 | 2037 | } else { |
2040 | - $output = 'call_user_func(\'' . $callback . '\', ' . $params . ')'; |
|
2038 | + $output = 'call_user_func(\''.$callback.'\', '.$params.')'; |
|
2041 | 2039 | } |
2042 | 2040 | } else { |
2043 | 2041 | // Custom plugin |
2044 | - if (function_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2045 | - $output = 'Plugin' . Core::toCamelCase($func) . '(' . $params . |
|
2042 | + if (function_exists('Plugin'.Core::toCamelCase($func)) !== false) { |
|
2043 | + $output = 'Plugin'.Core::toCamelCase($func).'('.$params. |
|
2046 | 2044 | ')'; |
2047 | 2045 | } // Builtin helper plugin |
2048 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== |
|
2046 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func)) !== |
|
2049 | 2047 | false) { |
2050 | - $output = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . '(' . |
|
2051 | - $params . ')'; |
|
2048 | + $output = Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).'('. |
|
2049 | + $params.')'; |
|
2052 | 2050 | } // Builtin function plugin |
2053 | 2051 | else { |
2054 | - $output = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '(' . |
|
2055 | - $params . ')'; |
|
2052 | + $output = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).'('. |
|
2053 | + $params.')'; |
|
2056 | 2054 | } |
2057 | 2055 | } |
2058 | 2056 | } |
@@ -2062,7 +2060,7 @@ discard block |
||
2062 | 2060 | $callback = $this->customPlugins[$func]['callback']; |
2063 | 2061 | if (!is_array($callback)) { |
2064 | 2062 | if (!method_exists($callback, 'compile')) { |
2065 | - throw new Exception('Custom plugin ' . $func . ' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
2063 | + throw new Exception('Custom plugin '.$func.' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
2066 | 2064 | } |
2067 | 2065 | if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) { |
2068 | 2066 | $funcCompiler = array($callback, 'compile'); |
@@ -2073,11 +2071,11 @@ discard block |
||
2073 | 2071 | $funcCompiler = $callback; |
2074 | 2072 | } |
2075 | 2073 | } else { |
2076 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2077 | - $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile'); |
|
2074 | + if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) { |
|
2075 | + $funcCompiler = array('Plugin'.Core::toCamelCase($func), 'compile'); |
|
2078 | 2076 | } else { |
2079 | 2077 | $funcCompiler = array( |
2080 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
2078 | + Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func), |
|
2081 | 2079 | 'compile' |
2082 | 2080 | ); |
2083 | 2081 | } |
@@ -2090,32 +2088,32 @@ discard block |
||
2090 | 2088 | $callback = $this->customPlugins[$func]['callback']; |
2091 | 2089 | if (!is_array($callback)) { |
2092 | 2090 | if (!method_exists($callback, 'process')) { |
2093 | - throw new Exception('Custom plugin ' . $func . ' must implement the "process" method to be usable, or you should provide a full callback to the method to use'); |
|
2091 | + throw new Exception('Custom plugin '.$func.' must implement the "process" method to be usable, or you should provide a full callback to the method to use'); |
|
2094 | 2092 | } |
2095 | 2093 | if (($ref = new ReflectionMethod($callback, 'process')) && $ref->isStatic()) { |
2096 | - $output = 'call_user_func(array(\'' . $callback . '\', \'process\'), ' . $params . ')'; |
|
2094 | + $output = 'call_user_func(array(\''.$callback.'\', \'process\'), '.$params.')'; |
|
2097 | 2095 | } else { |
2098 | - $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback . '\'), \'process\'), ' . $params . ')'; |
|
2096 | + $output = 'call_user_func(array($this->getObjectPlugin(\''.$callback.'\'), \'process\'), '.$params.')'; |
|
2099 | 2097 | } |
2100 | 2098 | } elseif (is_object($callback[0])) { |
2101 | - $output = 'call_user_func(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2099 | + $output = 'call_user_func(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), '.$params.')'; |
|
2102 | 2100 | } elseif (($ref = new ReflectionMethod($callback[0], $callback[1])) && $ref->isStatic()) { |
2103 | - $output = 'call_user_func(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2101 | + $output = 'call_user_func(array(\''.$callback[0].'\', \''.$callback[1].'\'), '.$params.')'; |
|
2104 | 2102 | } else { |
2105 | - $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback[0] . '\'), \'' . $callback[1] . '\'), ' . $params . ')'; |
|
2103 | + $output = 'call_user_func(array($this->getObjectPlugin(\''.$callback[0].'\'), \''.$callback[1].'\'), '.$params.')'; |
|
2106 | 2104 | } |
2107 | 2105 | if (empty($params)) { |
2108 | - $output = substr($output, 0, - 3) . ')'; |
|
2106 | + $output = substr($output, 0, - 3).')'; |
|
2109 | 2107 | } |
2110 | 2108 | } else { |
2111 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
2112 | - $output = '$this->classCall(\'Plugin' . $func . '\', array(' . $params . '))'; |
|
2113 | - } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== |
|
2109 | + if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) { |
|
2110 | + $output = '$this->classCall(\'Plugin'.$func.'\', array('.$params.'))'; |
|
2111 | + } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func)) !== |
|
2114 | 2112 | false) { |
2115 | - $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', |
|
2116 | - array(' . $params . '))'; |
|
2117 | - } else{ |
|
2118 | - $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))'; |
|
2113 | + $output = '$this->classCall(\''.Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.$func.'\', |
|
2114 | + array(' . $params.'))'; |
|
2115 | + } else { |
|
2116 | + $output = '$this->classCall(\''.$func.'\', array('.$params.'))'; |
|
2119 | 2117 | } |
2120 | 2118 | } |
2121 | 2119 | } |
@@ -2132,21 +2130,21 @@ discard block |
||
2132 | 2130 | $callback = $this->customPlugins[$func]['callback']; |
2133 | 2131 | if (is_array($callback)) { |
2134 | 2132 | if (is_object($callback[0])) { |
2135 | - $output = 'call_user_func_array(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(array(' . $params . '), $this))'; |
|
2133 | + $output = 'call_user_func_array(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), array(array('.$params.'), $this))'; |
|
2136 | 2134 | } else { |
2137 | - $output = 'call_user_func_array(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(array(' . $params . '), $this))'; |
|
2135 | + $output = 'call_user_func_array(array(\''.$callback[0].'\', \''.$callback[1].'\'), array(array('.$params.'), $this))'; |
|
2138 | 2136 | } |
2139 | 2137 | } else { |
2140 | - $output = $callback . '(array(' . $params . '), $this)'; |
|
2138 | + $output = $callback.'(array('.$params.'), $this)'; |
|
2141 | 2139 | } |
2142 | 2140 | } else { |
2143 | - $output = 'smarty_function_' . $func . '(array(' . $params . '), $this)'; |
|
2141 | + $output = 'smarty_function_'.$func.'(array('.$params.'), $this)'; |
|
2144 | 2142 | } |
2145 | 2143 | } elseif ($pluginType & Core::TEMPLATE_PLUGIN) { |
2146 | 2144 | array_unshift($params, '$this'); |
2147 | 2145 | $params = self::implode_r($params); |
2148 | - $output = 'Plugin' . Core::toCamelCase($func) . |
|
2149 | - $this->templatePlugins[$func]['uuid'] . '(' . $params . ')'; |
|
2146 | + $output = 'Plugin'.Core::toCamelCase($func). |
|
2147 | + $this->templatePlugins[$func]['uuid'].'('.$params.')'; |
|
2150 | 2148 | $this->templatePlugins[$func]['called'] = true; |
2151 | 2149 | } |
2152 | 2150 | |
@@ -2178,29 +2176,29 @@ discard block |
||
2178 | 2176 | */ |
2179 | 2177 | protected function parseString($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
2180 | 2178 | { |
2181 | - $substr = substr($in, $from, $to - $from); |
|
2179 | + $substr = substr($in, $from, $to-$from); |
|
2182 | 2180 | $first = $substr[0]; |
2183 | 2181 | |
2184 | 2182 | if ($this->debug) { |
2185 | - echo 'STRING FOUND (in ' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . ')' . "\n"; |
|
2183 | + echo 'STRING FOUND (in '.htmlentities(substr($in, $from, min($to-$from, 50))).(($to-$from) > 50 ? '...' : '').')'."\n"; |
|
2186 | 2184 | } |
2187 | 2185 | $strend = false; |
2188 | - $o = $from + 1; |
|
2186 | + $o = $from+1; |
|
2189 | 2187 | while ($strend === false) { |
2190 | 2188 | $strend = strpos($in, $first, $o); |
2191 | 2189 | if ($strend === false) { |
2192 | - throw new CompilationException($this, 'Unfinished string, started with ' . substr($in, $from, $to - $from)); |
|
2190 | + throw new CompilationException($this, 'Unfinished string, started with '.substr($in, $from, $to-$from)); |
|
2193 | 2191 | } |
2194 | - if (substr($in, $strend - 1, 1) === '\\') { |
|
2195 | - $o = $strend + 1; |
|
2192 | + if (substr($in, $strend-1, 1) === '\\') { |
|
2193 | + $o = $strend+1; |
|
2196 | 2194 | $strend = false; |
2197 | 2195 | } |
2198 | 2196 | } |
2199 | 2197 | if ($this->debug) { |
2200 | - echo 'STRING DELIMITED: ' . substr($in, $from, $strend + 1 - $from) . "\n"; |
|
2198 | + echo 'STRING DELIMITED: '.substr($in, $from, $strend+1-$from)."\n"; |
|
2201 | 2199 | } |
2202 | 2200 | |
2203 | - $srcOutput = substr($in, $from, $strend + 1 - $from); |
|
2201 | + $srcOutput = substr($in, $from, $strend+1-$from); |
|
2204 | 2202 | |
2205 | 2203 | if ($pointer !== null) { |
2206 | 2204 | $pointer += strlen($srcOutput); |
@@ -2209,13 +2207,13 @@ discard block |
||
2209 | 2207 | $output = $this->replaceStringVars($srcOutput, $first); |
2210 | 2208 | |
2211 | 2209 | // handle modifiers |
2212 | - if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend + 1 - $from), $match)) { |
|
2210 | + if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend+1-$from), $match)) { |
|
2213 | 2211 | $modstr = $match[1]; |
2214 | 2212 | |
2215 | 2213 | if ($curBlock === 'root' && substr($modstr, - 1) === '}') { |
2216 | 2214 | $modstr = substr($modstr, 0, - 1); |
2217 | 2215 | } |
2218 | - $modstr = str_replace('\\' . $first, $first, $modstr); |
|
2216 | + $modstr = str_replace('\\'.$first, $first, $modstr); |
|
2219 | 2217 | $ptr = 0; |
2220 | 2218 | $output = $this->replaceModifiers(array(null, null, $output, $modstr), 'string', $ptr); |
2221 | 2219 | |
@@ -2223,7 +2221,7 @@ discard block |
||
2223 | 2221 | if ($pointer !== null) { |
2224 | 2222 | $pointer += $ptr; |
2225 | 2223 | } |
2226 | - $srcOutput .= substr($substr, $strend + 1 - $from, $ptr); |
|
2224 | + $srcOutput .= substr($substr, $strend+1-$from, $ptr); |
|
2227 | 2225 | } |
2228 | 2226 | |
2229 | 2227 | if (is_array($parsingParams)) { |
@@ -2254,10 +2252,10 @@ discard block |
||
2254 | 2252 | */ |
2255 | 2253 | protected function parseConst($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
2256 | 2254 | { |
2257 | - $substr = substr($in, $from, $to - $from); |
|
2255 | + $substr = substr($in, $from, $to-$from); |
|
2258 | 2256 | |
2259 | 2257 | if ($this->debug) { |
2260 | - echo 'CONST FOUND : ' . $substr . "\n"; |
|
2258 | + echo 'CONST FOUND : '.$substr."\n"; |
|
2261 | 2259 | } |
2262 | 2260 | |
2263 | 2261 | if (!preg_match('#^%([\\\\a-z0-9_:]+)#i', $substr, $m)) { |
@@ -2296,7 +2294,7 @@ discard block |
||
2296 | 2294 | } |
2297 | 2295 | |
2298 | 2296 | if ($curBlock !== 'root') { |
2299 | - $output = '(defined("' . $key . '") ? ' . $key . ' : null)'; |
|
2297 | + $output = '(defined("'.$key.'") ? '.$key.' : null)'; |
|
2300 | 2298 | } else { |
2301 | 2299 | $output = $key; |
2302 | 2300 | } |
@@ -2322,13 +2320,13 @@ discard block |
||
2322 | 2320 | protected function parseVar($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
2323 | 2321 | { |
2324 | 2322 | $methodCall = ''; |
2325 | - $substr = substr($in, $from, $to - $from); |
|
2323 | + $substr = substr($in, $from, $to-$from); |
|
2326 | 2324 | |
2327 | 2325 | if (preg_match( |
2328 | - '#(\$?\.?[a-z0-9_:]*(?:(?:(?:\.|->)(?:[a-z0-9_:]+|(?R))|\[(?:[a-z0-9_:]+|(?R)|(["\'])[^\2]*?\2)\]))*)' . // var key |
|
2329 | - ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'expression' || $curBlock === 'delimited_string' ? '(\(.*)?' : '()') . // method call |
|
2330 | - ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'delimited_string' ? '((?:(?:[+/*%=-])(?:(?<!=)=?-?[$%][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9.,]*|[+-]))*)' : '()') . // simple math expressions |
|
2331 | - ($curBlock !== 'modifier' ? '((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').*?\5|:[^`]*))*))+)?' : '(())') . // modifiers |
|
2326 | + '#(\$?\.?[a-z0-9_:]*(?:(?:(?:\.|->)(?:[a-z0-9_:]+|(?R))|\[(?:[a-z0-9_:]+|(?R)|(["\'])[^\2]*?\2)\]))*)'.// var key |
|
2327 | + ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'expression' || $curBlock === 'delimited_string' ? '(\(.*)?' : '()').// method call |
|
2328 | + ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'delimited_string' ? '((?:(?:[+/*%=-])(?:(?<!=)=?-?[$%][a-z0-9.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9.,]*|[+-]))*)' : '()').// simple math expressions |
|
2329 | + ($curBlock !== 'modifier' ? '((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').*?\5|:[^`]*))*))+)?' : '(())').// modifiers |
|
2332 | 2330 | '#i', $substr, $match |
2333 | 2331 | )) { |
2334 | 2332 | $key = substr($match[1], 1); |
@@ -2340,13 +2338,13 @@ discard block |
||
2340 | 2338 | |
2341 | 2339 | if (substr($key, - 1) == '.') { |
2342 | 2340 | $key = substr($key, 0, - 1); |
2343 | - -- $matchedLength; |
|
2341 | + --$matchedLength; |
|
2344 | 2342 | } |
2345 | 2343 | |
2346 | 2344 | if ($hasMethodCall) { |
2347 | - $matchedLength -= strlen($match[3]) + strlen(substr($match[1], strrpos($match[1], '->'))); |
|
2348 | - $key = substr($match[1], 1, strrpos($match[1], '->') - 1); |
|
2349 | - $methodCall = substr($match[1], strrpos($match[1], '->')) . $match[3]; |
|
2345 | + $matchedLength -= strlen($match[3])+strlen(substr($match[1], strrpos($match[1], '->'))); |
|
2346 | + $key = substr($match[1], 1, strrpos($match[1], '->')-1); |
|
2347 | + $methodCall = substr($match[1], strrpos($match[1], '->')).$match[3]; |
|
2350 | 2348 | } |
2351 | 2349 | |
2352 | 2350 | if ($hasModifiers) { |
@@ -2362,9 +2360,9 @@ discard block |
||
2362 | 2360 | |
2363 | 2361 | if ($this->debug) { |
2364 | 2362 | if ($hasMethodCall) { |
2365 | - echo 'METHOD CALL FOUND : $' . $key . substr($methodCall, 0, 30) . "\n"; |
|
2363 | + echo 'METHOD CALL FOUND : $'.$key.substr($methodCall, 0, 30)."\n"; |
|
2366 | 2364 | } else { |
2367 | - echo 'VAR FOUND : $' . $key . "\n"; |
|
2365 | + echo 'VAR FOUND : $'.$key."\n"; |
|
2368 | 2366 | } |
2369 | 2367 | } |
2370 | 2368 | |
@@ -2375,7 +2373,7 @@ discard block |
||
2375 | 2373 | $uid = 0; |
2376 | 2374 | $parsed = array($uid => ''); |
2377 | 2375 | $current = &$parsed; |
2378 | - $curTxt = &$parsed[$uid ++]; |
|
2376 | + $curTxt = &$parsed[$uid++]; |
|
2379 | 2377 | $tree = array(); |
2380 | 2378 | $chars = str_split($key, 1); |
2381 | 2379 | $inSplittedVar = false; |
@@ -2384,33 +2382,33 @@ discard block |
||
2384 | 2382 | while (($char = array_shift($chars)) !== null) { |
2385 | 2383 | if ($char === '[') { |
2386 | 2384 | if (count($tree) > 0) { |
2387 | - ++ $bracketCount; |
|
2385 | + ++$bracketCount; |
|
2388 | 2386 | } else { |
2389 | 2387 | $tree[] = &$current; |
2390 | - $current[$uid] = array($uid + 1 => ''); |
|
2391 | - $current = &$current[$uid ++]; |
|
2392 | - $curTxt = &$current[$uid ++]; |
|
2388 | + $current[$uid] = array($uid+1 => ''); |
|
2389 | + $current = &$current[$uid++]; |
|
2390 | + $curTxt = &$current[$uid++]; |
|
2393 | 2391 | continue; |
2394 | 2392 | } |
2395 | 2393 | } elseif ($char === ']') { |
2396 | 2394 | if ($bracketCount > 0) { |
2397 | - -- $bracketCount; |
|
2395 | + --$bracketCount; |
|
2398 | 2396 | } else { |
2399 | - $current = &$tree[count($tree) - 1]; |
|
2397 | + $current = &$tree[count($tree)-1]; |
|
2400 | 2398 | array_pop($tree); |
2401 | 2399 | if (current($chars) !== '[' && current($chars) !== false && current($chars) !== ']') { |
2402 | 2400 | $current[$uid] = ''; |
2403 | - $curTxt = &$current[$uid ++]; |
|
2401 | + $curTxt = &$current[$uid++]; |
|
2404 | 2402 | } |
2405 | 2403 | continue; |
2406 | 2404 | } |
2407 | 2405 | } elseif ($char === '$') { |
2408 | 2406 | if (count($tree) == 0) { |
2409 | - $curTxt = &$current[$uid ++]; |
|
2407 | + $curTxt = &$current[$uid++]; |
|
2410 | 2408 | $inSplittedVar = true; |
2411 | 2409 | } |
2412 | 2410 | } elseif (($char === '.' || $char === '-') && count($tree) == 0 && $inSplittedVar) { |
2413 | - $curTxt = &$current[$uid ++]; |
|
2411 | + $curTxt = &$current[$uid++]; |
|
2414 | 2412 | $inSplittedVar = false; |
2415 | 2413 | } |
2416 | 2414 | |
@@ -2419,16 +2417,16 @@ discard block |
||
2419 | 2417 | unset($uid, $current, $curTxt, $tree, $chars); |
2420 | 2418 | |
2421 | 2419 | if ($this->debug) { |
2422 | - echo 'RECURSIVE VAR REPLACEMENT : ' . $key . "\n"; |
|
2420 | + echo 'RECURSIVE VAR REPLACEMENT : '.$key."\n"; |
|
2423 | 2421 | } |
2424 | 2422 | |
2425 | 2423 | $key = $this->flattenVarTree($parsed); |
2426 | 2424 | |
2427 | 2425 | if ($this->debug) { |
2428 | - echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n"; |
|
2426 | + echo 'RECURSIVE VAR REPLACEMENT DONE : '.$key."\n"; |
|
2429 | 2427 | } |
2430 | 2428 | |
2431 | - $output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("' . $key . '")'); |
|
2429 | + $output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("'.$key.'")'); |
|
2432 | 2430 | } else { |
2433 | 2431 | $output = $this->parseVarKey($key, $hasModifiers ? 'modifier' : $curBlock); |
2434 | 2432 | } |
@@ -2453,10 +2451,10 @@ discard block |
||
2453 | 2451 | if (substr($expMatch[2][$k], 0, 1) === '=') { |
2454 | 2452 | $assign = true; |
2455 | 2453 | if ($operator === '=') { |
2456 | - throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, can not use "==" in expressions'); |
|
2454 | + throw new CompilationException($this, 'Invalid expression <em>'.$substr.'</em>, can not use "==" in expressions'); |
|
2457 | 2455 | } |
2458 | 2456 | if ($curBlock !== 'root') { |
2459 | - throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}'); |
|
2457 | + throw new CompilationException($this, 'Invalid expression <em>'.$substr.'</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}'); |
|
2460 | 2458 | } |
2461 | 2459 | $operator .= '='; |
2462 | 2460 | $expMatch[2][$k] = substr($expMatch[2][$k], 1); |
@@ -2467,22 +2465,22 @@ discard block |
||
2467 | 2465 | $expMatch[2][$k] = substr($expMatch[2][$k], 1); |
2468 | 2466 | } |
2469 | 2467 | if (($operator === '+' || $operator === '-') && $expMatch[2][$k] === $operator) { |
2470 | - $output = '(' . $output . $operator . $operator . ')'; |
|
2468 | + $output = '('.$output.$operator.$operator.')'; |
|
2471 | 2469 | break; |
2472 | 2470 | } elseif (substr($expMatch[2][$k], 0, 1) === '$') { |
2473 | - $output = '(' . $output . ' ' . $operator . ' ' . $this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')'; |
|
2471 | + $output = '('.$output.' '.$operator.' '.$this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression').')'; |
|
2474 | 2472 | } elseif (substr($expMatch[2][$k], 0, 1) === '%') { |
2475 | - $output = '(' . $output . ' ' . $operator . ' ' . $this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')'; |
|
2473 | + $output = '('.$output.' '.$operator.' '.$this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression').')'; |
|
2476 | 2474 | } elseif (!empty($expMatch[2][$k])) { |
2477 | - $output = '(' . $output . ' ' . $operator . ' ' . str_replace(',', '.', $expMatch[2][$k]) . ')'; |
|
2475 | + $output = '('.$output.' '.$operator.' '.str_replace(',', '.', $expMatch[2][$k]).')'; |
|
2478 | 2476 | } else { |
2479 | - throw new CompilationException($this, 'Unfinished expression <em>' . $substr . '</em>, missing var or number after math operator'); |
|
2477 | + throw new CompilationException($this, 'Unfinished expression <em>'.$substr.'</em>, missing var or number after math operator'); |
|
2480 | 2478 | } |
2481 | 2479 | } |
2482 | 2480 | } |
2483 | 2481 | |
2484 | 2482 | if ($this->autoEscape === true && $curBlock !== 'condition') { |
2485 | - $output = '(is_string($tmp=' . $output . ') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)'; |
|
2483 | + $output = '(is_string($tmp='.$output.') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)'; |
|
2486 | 2484 | } |
2487 | 2485 | |
2488 | 2486 | // handle modifiers |
@@ -2506,7 +2504,7 @@ discard block |
||
2506 | 2504 | } elseif ($curBlock === 'expression' || $curBlock === 'variable') { |
2507 | 2505 | return $output; |
2508 | 2506 | } elseif (isset($assign)) { |
2509 | - return self::PHP_OPEN . $output . ';' . self::PHP_CLOSE; |
|
2507 | + return self::PHP_OPEN.$output.';'.self::PHP_CLOSE; |
|
2510 | 2508 | } else { |
2511 | 2509 | return $output; |
2512 | 2510 | } |
@@ -2514,7 +2512,7 @@ discard block |
||
2514 | 2512 | if ($curBlock === 'string' || $curBlock === 'delimited_string') { |
2515 | 2513 | return array(0, ''); |
2516 | 2514 | } else { |
2517 | - throw new CompilationException($this, 'Invalid variable name <em>' . $substr . '</em>'); |
|
2515 | + throw new CompilationException($this, 'Invalid variable name <em>'.$substr.'</em>'); |
|
2518 | 2516 | } |
2519 | 2517 | } |
2520 | 2518 | } |
@@ -2569,16 +2567,16 @@ discard block |
||
2569 | 2567 | if (empty($methMatch[2])) { |
2570 | 2568 | // property |
2571 | 2569 | if ($curBlock === 'root') { |
2572 | - $output .= '->' . $methMatch[1]; |
|
2570 | + $output .= '->'.$methMatch[1]; |
|
2573 | 2571 | } else { |
2574 | - $output = '(($tmp = ' . $output . ') ? $tmp->' . $methMatch[1] . ' : null)'; |
|
2572 | + $output = '(($tmp = '.$output.') ? $tmp->'.$methMatch[1].' : null)'; |
|
2575 | 2573 | } |
2576 | 2574 | $ptr += strlen($methMatch[1]); |
2577 | 2575 | } else { |
2578 | 2576 | // method |
2579 | 2577 | if (substr($methMatch[2], 0, 2) === '()') { |
2580 | - $parsedCall = $methMatch[1] . '()'; |
|
2581 | - $ptr += strlen($methMatch[1]) + 2; |
|
2578 | + $parsedCall = $methMatch[1].'()'; |
|
2579 | + $ptr += strlen($methMatch[1])+2; |
|
2582 | 2580 | } else { |
2583 | 2581 | $parsedCall = $this->parseFunction($methodCall, $ptr, strlen($methodCall), false, 'method', $ptr); |
2584 | 2582 | } |
@@ -2587,15 +2585,15 @@ discard block |
||
2587 | 2585 | $method = strtolower(substr($parsedCall, 0, $argPos)); |
2588 | 2586 | $args = substr($parsedCall, $argPos); |
2589 | 2587 | if ($curBlock === 'root') { |
2590 | - $output = '$this->getSecurityPolicy()->callMethod($this, ' . $output . ', ' . var_export($method, true) . ', array' . $args . ')'; |
|
2588 | + $output = '$this->getSecurityPolicy()->callMethod($this, '.$output.', '.var_export($method, true).', array'.$args.')'; |
|
2591 | 2589 | } else { |
2592 | - $output = '(($tmp = ' . $output . ') ? $this->getSecurityPolicy()->callMethod($this, $tmp, ' . var_export($method, true) . ', array' . $args . ') : null)'; |
|
2590 | + $output = '(($tmp = '.$output.') ? $this->getSecurityPolicy()->callMethod($this, $tmp, '.var_export($method, true).', array'.$args.') : null)'; |
|
2593 | 2591 | } |
2594 | 2592 | } else { |
2595 | 2593 | if ($curBlock === 'root') { |
2596 | - $output .= '->' . $parsedCall; |
|
2594 | + $output .= '->'.$parsedCall; |
|
2597 | 2595 | } else { |
2598 | - $output = '(($tmp = ' . $output . ') ? $tmp->' . $parsedCall . ' : null)'; |
|
2596 | + $output = '(($tmp = '.$output.') ? $tmp->'.$parsedCall.' : null)'; |
|
2599 | 2597 | } |
2600 | 2598 | } |
2601 | 2599 | } |
@@ -2621,21 +2619,21 @@ discard block |
||
2621 | 2619 | return '$this->scope'; |
2622 | 2620 | } |
2623 | 2621 | if (substr($key, 0, 1) === '.') { |
2624 | - $key = 'dwoo' . $key; |
|
2622 | + $key = 'dwoo'.$key; |
|
2625 | 2623 | } |
2626 | 2624 | if (preg_match('#dwoo\.(get|post|server|cookies|session|env|request)((?:\.[a-z0-9_-]+)+)#i', $key, $m)) { |
2627 | 2625 | $global = strtoupper($m[1]); |
2628 | 2626 | if ($global === 'COOKIES') { |
2629 | 2627 | $global = 'COOKIE'; |
2630 | 2628 | } |
2631 | - $key = '$_' . $global; |
|
2629 | + $key = '$_'.$global; |
|
2632 | 2630 | foreach (explode('.', ltrim($m[2], '.')) as $part) { |
2633 | - $key .= '[' . var_export($part, true) . ']'; |
|
2631 | + $key .= '['.var_export($part, true).']'; |
|
2634 | 2632 | } |
2635 | 2633 | if ($curBlock === 'root') { |
2636 | 2634 | $output = $key; |
2637 | 2635 | } else { |
2638 | - $output = '(isset(' . $key . ')?' . $key . ':null)'; |
|
2636 | + $output = '(isset('.$key.')?'.$key.':null)'; |
|
2639 | 2637 | } |
2640 | 2638 | } elseif (preg_match('#dwoo\.const\.([a-z0-9_:]+)#i', $key, $m)) { |
2641 | 2639 | return $this->parseConstKey($m[1], $curBlock); |
@@ -2651,9 +2649,9 @@ discard block |
||
2651 | 2649 | $output = '$tmp_key'; |
2652 | 2650 | } else { |
2653 | 2651 | if ($curBlock === 'root') { |
2654 | - $output = '$this->scope["' . $key . '"]'; |
|
2652 | + $output = '$this->scope["'.$key.'"]'; |
|
2655 | 2653 | } else { |
2656 | - $output = '(isset($this->scope["' . $key . '"]) ? $this->scope["' . $key . '"] : null)'; |
|
2654 | + $output = '(isset($this->scope["'.$key.'"]) ? $this->scope["'.$key.'"] : null)'; |
|
2657 | 2655 | } |
2658 | 2656 | } |
2659 | 2657 | } else { |
@@ -2664,7 +2662,7 @@ discard block |
||
2664 | 2662 | $parentCnt = 0; |
2665 | 2663 | |
2666 | 2664 | while (true) { |
2667 | - ++ $parentCnt; |
|
2665 | + ++$parentCnt; |
|
2668 | 2666 | array_shift($m[2]); |
2669 | 2667 | array_shift($m[1]); |
2670 | 2668 | if (current($m[2]) === '_parent') { |
@@ -2673,7 +2671,7 @@ discard block |
||
2673 | 2671 | break; |
2674 | 2672 | } |
2675 | 2673 | |
2676 | - $output = '$this->readParentVar(' . $parentCnt . ')'; |
|
2674 | + $output = '$this->readParentVar('.$parentCnt.')'; |
|
2677 | 2675 | } else { |
2678 | 2676 | if ($i === 'dwoo') { |
2679 | 2677 | $output = '$this->globals'; |
@@ -2692,28 +2690,28 @@ discard block |
||
2692 | 2690 | while (count($m[1]) && $m[1][0] !== '->') { |
2693 | 2691 | $m[2][0] = preg_replace('/(^\\\([\'"])|\\\([\'"])$)/x', '$2$3', $m[2][0]); |
2694 | 2692 | if (substr($m[2][0], 0, 1) == '"' || substr($m[2][0], 0, 1) == "'") { |
2695 | - $output .= '[' . $m[2][0] . ']'; |
|
2693 | + $output .= '['.$m[2][0].']'; |
|
2696 | 2694 | } else { |
2697 | - $output .= '["' . $m[2][0] . '"]'; |
|
2695 | + $output .= '["'.$m[2][0].'"]'; |
|
2698 | 2696 | } |
2699 | 2697 | array_shift($m[2]); |
2700 | 2698 | array_shift($m[1]); |
2701 | 2699 | } |
2702 | 2700 | |
2703 | 2701 | if ($curBlock !== 'root') { |
2704 | - $output = '(isset(' . $output . ') ? ' . $output . ':null)'; |
|
2702 | + $output = '(isset('.$output.') ? '.$output.':null)'; |
|
2705 | 2703 | } |
2706 | 2704 | } |
2707 | 2705 | |
2708 | 2706 | if (count($m[2])) { |
2709 | 2707 | unset($m[0]); |
2710 | - $output = '$this->readVarInto(' . str_replace("\n", '', var_export($m, true)) . ', ' . $output . ', ' . ($curBlock == 'root' ? 'false' : 'true') . ')'; |
|
2708 | + $output = '$this->readVarInto('.str_replace("\n", '', var_export($m, true)).', '.$output.', '.($curBlock == 'root' ? 'false' : 'true').')'; |
|
2711 | 2709 | } |
2712 | 2710 | } |
2713 | 2711 | } else { |
2714 | 2712 | preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+)\]?#i', $key, $m); |
2715 | 2713 | unset($m[0]); |
2716 | - $output = '$this->readVar(' . str_replace("\n", '', var_export($m, true)) . ')'; |
|
2714 | + $output = '$this->readVar('.str_replace("\n", '', var_export($m, true)).')'; |
|
2717 | 2715 | } |
2718 | 2716 | |
2719 | 2717 | return $output; |
@@ -2733,38 +2731,38 @@ discard block |
||
2733 | 2731 | $out = $recursed ? '".$this->readVarInto(' : ''; |
2734 | 2732 | foreach ($tree as $bit) { |
2735 | 2733 | if (is_array($bit)) { |
2736 | - $out .= '.' . $this->flattenVarTree($bit, false); |
|
2734 | + $out .= '.'.$this->flattenVarTree($bit, false); |
|
2737 | 2735 | } else { |
2738 | 2736 | $key = str_replace('"', '\\"', $bit); |
2739 | 2737 | |
2740 | 2738 | if (substr($key, 0, 1) === '$') { |
2741 | - $out .= '".' . $this->parseVar($key, 0, strlen($key), false, 'variable') . '."'; |
|
2739 | + $out .= '".'.$this->parseVar($key, 0, strlen($key), false, 'variable').'."'; |
|
2742 | 2740 | } else { |
2743 | 2741 | $cnt = substr_count($key, '$'); |
2744 | 2742 | |
2745 | 2743 | if ($this->debug) { |
2746 | - echo 'PARSING SUBVARS IN : ' . $key . "\n"; |
|
2744 | + echo 'PARSING SUBVARS IN : '.$key."\n"; |
|
2747 | 2745 | } |
2748 | 2746 | if ($cnt > 0) { |
2749 | - while (-- $cnt >= 0) { |
|
2747 | + while (--$cnt >= 0) { |
|
2750 | 2748 | if (isset($last)) { |
2751 | - $last = strrpos($key, '$', - (strlen($key) - $last + 1)); |
|
2749 | + $last = strrpos($key, '$', - (strlen($key)-$last+1)); |
|
2752 | 2750 | } else { |
2753 | 2751 | $last = strrpos($key, '$'); |
2754 | 2752 | } |
2755 | - preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch); |
|
2753 | + preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*'.'((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch); |
|
2756 | 2754 | |
2757 | 2755 | $len = strlen($submatch[0]); |
2758 | 2756 | $key = substr_replace( |
2759 | 2757 | $key, preg_replace_callback( |
2760 | - '#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array( |
|
2758 | + '#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)'.'((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array( |
|
2761 | 2759 | $this, |
2762 | 2760 | 'replaceVarKeyHelper' |
2763 | 2761 | ), substr($key, $last, $len) |
2764 | 2762 | ), $last, $len |
2765 | 2763 | ); |
2766 | 2764 | if ($this->debug) { |
2767 | - echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n"; |
|
2765 | + echo 'RECURSIVE VAR REPLACEMENT DONE : '.$key."\n"; |
|
2768 | 2766 | } |
2769 | 2767 | } |
2770 | 2768 | unset($last); |
@@ -2790,7 +2788,7 @@ discard block |
||
2790 | 2788 | */ |
2791 | 2789 | protected function replaceVarKeyHelper($match) |
2792 | 2790 | { |
2793 | - return '".' . $this->parseVar($match[0], 0, strlen($match[0]), false, 'variable') . '."'; |
|
2791 | + return '".'.$this->parseVar($match[0], 0, strlen($match[0]), false, 'variable').'."'; |
|
2794 | 2792 | } |
2795 | 2793 | |
2796 | 2794 | /** |
@@ -2810,7 +2808,7 @@ discard block |
||
2810 | 2808 | */ |
2811 | 2809 | protected function parseOthers($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null) |
2812 | 2810 | { |
2813 | - $substr = substr($in, $from, $to - $from); |
|
2811 | + $substr = substr($in, $from, $to-$from); |
|
2814 | 2812 | |
2815 | 2813 | $end = strlen($substr); |
2816 | 2814 | |
@@ -2884,48 +2882,48 @@ discard block |
||
2884 | 2882 | |
2885 | 2883 | if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') { |
2886 | 2884 | if ($this->debug) { |
2887 | - echo 'BOOLEAN(FALSE) PARSED' . "\n"; |
|
2885 | + echo 'BOOLEAN(FALSE) PARSED'."\n"; |
|
2888 | 2886 | } |
2889 | 2887 | $substr = 'false'; |
2890 | 2888 | $type = self::T_BOOL; |
2891 | 2889 | } elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') { |
2892 | 2890 | if ($this->debug) { |
2893 | - echo 'BOOLEAN(TRUE) PARSED' . "\n"; |
|
2891 | + echo 'BOOLEAN(TRUE) PARSED'."\n"; |
|
2894 | 2892 | } |
2895 | 2893 | $substr = 'true'; |
2896 | 2894 | $type = self::T_BOOL; |
2897 | 2895 | } elseif ($substr === 'null' || $substr === 'NULL') { |
2898 | 2896 | if ($this->debug) { |
2899 | - echo 'NULL PARSED' . "\n"; |
|
2897 | + echo 'NULL PARSED'."\n"; |
|
2900 | 2898 | } |
2901 | 2899 | $substr = 'null'; |
2902 | 2900 | $type = self::T_NULL; |
2903 | 2901 | } elseif (is_numeric($substr)) { |
2904 | - $substr = (float)$substr; |
|
2905 | - if ((int)$substr == $substr) { |
|
2906 | - $substr = (int)$substr; |
|
2902 | + $substr = (float) $substr; |
|
2903 | + if ((int) $substr == $substr) { |
|
2904 | + $substr = (int) $substr; |
|
2907 | 2905 | } |
2908 | 2906 | $type = self::T_NUMERIC; |
2909 | 2907 | if ($this->debug) { |
2910 | - echo 'NUMBER (' . $substr . ') PARSED' . "\n"; |
|
2908 | + echo 'NUMBER ('.$substr.') PARSED'."\n"; |
|
2911 | 2909 | } |
2912 | 2910 | } elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) { |
2913 | 2911 | if ($this->debug) { |
2914 | 2912 | echo 'SIMPLE MATH PARSED . "\n"'; |
2915 | 2913 | } |
2916 | 2914 | $type = self::T_MATH; |
2917 | - $substr = '(' . $substr . ')'; |
|
2915 | + $substr = '('.$substr.')'; |
|
2918 | 2916 | } elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) { |
2919 | 2917 | if ($this->debug) { |
2920 | - echo 'BREAKCHAR (' . $substr . ') PARSED' . "\n"; |
|
2918 | + echo 'BREAKCHAR ('.$substr.') PARSED'."\n"; |
|
2921 | 2919 | } |
2922 | 2920 | $type = self::T_BREAKCHAR; |
2923 | 2921 | //$substr = '"'.$substr.'"'; |
2924 | 2922 | } else { |
2925 | - $substr = $this->replaceStringVars('\'' . str_replace('\'', '\\\'', $substr) . '\'', '\'', $curBlock); |
|
2923 | + $substr = $this->replaceStringVars('\''.str_replace('\'', '\\\'', $substr).'\'', '\'', $curBlock); |
|
2926 | 2924 | $type = self::T_UNQUOTED_STRING; |
2927 | 2925 | if ($this->debug) { |
2928 | - echo 'BLABBER (' . $substr . ') CASTED AS STRING' . "\n"; |
|
2926 | + echo 'BLABBER ('.$substr.') CASTED AS STRING'."\n"; |
|
2929 | 2927 | } |
2930 | 2928 | } |
2931 | 2929 | |
@@ -2955,28 +2953,28 @@ discard block |
||
2955 | 2953 | { |
2956 | 2954 | $pos = 0; |
2957 | 2955 | if ($this->debug) { |
2958 | - echo 'STRING VAR REPLACEMENT : ' . $string . "\n"; |
|
2956 | + echo 'STRING VAR REPLACEMENT : '.$string."\n"; |
|
2959 | 2957 | } |
2960 | 2958 | // replace vars |
2961 | 2959 | while (($pos = strpos($string, '$', $pos)) !== false) { |
2962 | - $prev = substr($string, $pos - 1, 1); |
|
2960 | + $prev = substr($string, $pos-1, 1); |
|
2963 | 2961 | if ($prev === '\\') { |
2964 | - ++ $pos; |
|
2962 | + ++$pos; |
|
2965 | 2963 | continue; |
2966 | 2964 | } |
2967 | 2965 | |
2968 | 2966 | $var = $this->parse($string, $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string'))); |
2969 | 2967 | $len = $var[0]; |
2970 | - $var = $this->parse(str_replace('\\' . $first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string'))); |
|
2968 | + $var = $this->parse(str_replace('\\'.$first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string'))); |
|
2971 | 2969 | |
2972 | - if ($prev === '`' && substr($string, $pos + $len, 1) === '`') { |
|
2973 | - $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos - 1, $len + 2); |
|
2970 | + if ($prev === '`' && substr($string, $pos+$len, 1) === '`') { |
|
2971 | + $string = substr_replace($string, $first.'.'.$var[1].'.'.$first, $pos-1, $len+2); |
|
2974 | 2972 | } else { |
2975 | - $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos, $len); |
|
2973 | + $string = substr_replace($string, $first.'.'.$var[1].'.'.$first, $pos, $len); |
|
2976 | 2974 | } |
2977 | - $pos += strlen($var[1]) + 2; |
|
2975 | + $pos += strlen($var[1])+2; |
|
2978 | 2976 | if ($this->debug) { |
2979 | - echo 'STRING VAR REPLACEMENT DONE : ' . $string . "\n"; |
|
2977 | + echo 'STRING VAR REPLACEMENT DONE : '.$string."\n"; |
|
2980 | 2978 | } |
2981 | 2979 | } |
2982 | 2980 | |
@@ -3012,7 +3010,7 @@ discard block |
||
3012 | 3010 | protected function replaceModifiers(array $m, $curBlock = null, &$pointer = null) |
3013 | 3011 | { |
3014 | 3012 | if ($this->debug) { |
3015 | - echo 'PARSING MODIFIERS : ' . $m[3] . "\n"; |
|
3013 | + echo 'PARSING MODIFIERS : '.$m[3]."\n"; |
|
3016 | 3014 | } |
3017 | 3015 | |
3018 | 3016 | if ($pointer !== null) { |
@@ -3036,7 +3034,7 @@ discard block |
||
3036 | 3034 | } |
3037 | 3035 | if ($cmdstrsrc[0] === ' ' || $cmdstrsrc[0] === ';' || substr($cmdstrsrc, 0, strlen($this->rd)) === $this->rd) { |
3038 | 3036 | if ($this->debug) { |
3039 | - echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND' . "\n"; |
|
3037 | + echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND'."\n"; |
|
3040 | 3038 | } |
3041 | 3039 | $continue = false; |
3042 | 3040 | if ($pointer !== null) { |
@@ -3047,7 +3045,7 @@ discard block |
||
3047 | 3045 | $cmdstr = $cmdstrsrc; |
3048 | 3046 | $paramsep = ':'; |
3049 | 3047 | if (!preg_match('/^(@{0,2}[a-z_][a-z0-9_]*)(:)?/i', $cmdstr, $match)) { |
3050 | - throw new CompilationException($this, 'Invalid modifier name, started with : ' . substr($cmdstr, 0, 10)); |
|
3048 | + throw new CompilationException($this, 'Invalid modifier name, started with : '.substr($cmdstr, 0, 10)); |
|
3051 | 3049 | } |
3052 | 3050 | $paramspos = !empty($match[2]) ? strlen($match[1]) : false; |
3053 | 3051 | $func = $match[1]; |
@@ -3057,10 +3055,10 @@ discard block |
||
3057 | 3055 | $cmdstrsrc = substr($cmdstrsrc, strlen($func)); |
3058 | 3056 | $params = array(); |
3059 | 3057 | if ($this->debug) { |
3060 | - echo 'MODIFIER (' . $func . ') CALLED WITH NO PARAMS' . "\n"; |
|
3058 | + echo 'MODIFIER ('.$func.') CALLED WITH NO PARAMS'."\n"; |
|
3061 | 3059 | } |
3062 | 3060 | } else { |
3063 | - $paramstr = substr($cmdstr, $paramspos + 1); |
|
3061 | + $paramstr = substr($cmdstr, $paramspos+1); |
|
3064 | 3062 | if (substr($paramstr, - 1, 1) === $paramsep) { |
3065 | 3063 | $paramstr = substr($paramstr, 0, - 1); |
3066 | 3064 | } |
@@ -3069,41 +3067,41 @@ discard block |
||
3069 | 3067 | $params = array(); |
3070 | 3068 | while ($ptr < strlen($paramstr)) { |
3071 | 3069 | if ($this->debug) { |
3072 | - echo 'MODIFIER (' . $func . ') START PARAM PARSING WITH POINTER AT ' . $ptr . "\n"; |
|
3070 | + echo 'MODIFIER ('.$func.') START PARAM PARSING WITH POINTER AT '.$ptr."\n"; |
|
3073 | 3071 | } |
3074 | 3072 | if ($this->debug) { |
3075 | - echo $paramstr . '--' . $ptr . '--' . strlen($paramstr) . '--modifier' . "\n"; |
|
3073 | + echo $paramstr.'--'.$ptr.'--'.strlen($paramstr).'--modifier'."\n"; |
|
3076 | 3074 | } |
3077 | 3075 | $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'modifier', $ptr); |
3078 | 3076 | if ($this->debug) { |
3079 | - echo 'PARAM PARSED, POINTER AT ' . $ptr . "\n"; |
|
3077 | + echo 'PARAM PARSED, POINTER AT '.$ptr."\n"; |
|
3080 | 3078 | } |
3081 | 3079 | |
3082 | 3080 | if ($ptr >= strlen($paramstr)) { |
3083 | 3081 | if ($this->debug) { |
3084 | - echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED' . "\n"; |
|
3082 | + echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED'."\n"; |
|
3085 | 3083 | } |
3086 | 3084 | break; |
3087 | 3085 | } |
3088 | 3086 | |
3089 | 3087 | if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === '|' || $paramstr[$ptr] === ';' || substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) { |
3090 | 3088 | if ($this->debug) { |
3091 | - echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT ' . $ptr . "\n"; |
|
3089 | + echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT '.$ptr."\n"; |
|
3092 | 3090 | } |
3093 | 3091 | if ($paramstr[$ptr] !== '|') { |
3094 | 3092 | $continue = false; |
3095 | 3093 | if ($pointer !== null) { |
3096 | - $pointer -= strlen($paramstr) - $ptr; |
|
3094 | + $pointer -= strlen($paramstr)-$ptr; |
|
3097 | 3095 | } |
3098 | 3096 | } |
3099 | - ++ $ptr; |
|
3097 | + ++$ptr; |
|
3100 | 3098 | break; |
3101 | 3099 | } |
3102 | 3100 | if ($ptr < strlen($paramstr) && $paramstr[$ptr] === ':') { |
3103 | - ++ $ptr; |
|
3101 | + ++$ptr; |
|
3104 | 3102 | } |
3105 | 3103 | } |
3106 | - $cmdstrsrc = substr($cmdstrsrc, strlen($func) + 1 + $ptr); |
|
3104 | + $cmdstrsrc = substr($cmdstrsrc, strlen($func)+1+$ptr); |
|
3107 | 3105 | foreach ($params as $k => $p) { |
3108 | 3106 | if (is_array($p) && is_array($p[1])) { |
3109 | 3107 | $state |= 2; |
@@ -3143,9 +3141,9 @@ discard block |
||
3143 | 3141 | $params = self::implode_r($params); |
3144 | 3142 | |
3145 | 3143 | if ($mapped) { |
3146 | - $output = '$this->arrayMap(\'' . $func . '\', array(' . $params . '))'; |
|
3144 | + $output = '$this->arrayMap(\''.$func.'\', array('.$params.'))'; |
|
3147 | 3145 | } else { |
3148 | - $output = $func . '(' . $params . ')'; |
|
3146 | + $output = $func.'('.$params.')'; |
|
3149 | 3147 | } |
3150 | 3148 | } elseif ($pluginType & Core::PROXY_PLUGIN) { |
3151 | 3149 | $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state); |
@@ -3163,36 +3161,36 @@ discard block |
||
3163 | 3161 | $callback = $this->customPlugins[$func]['callback']; |
3164 | 3162 | if (is_array($callback)) { |
3165 | 3163 | if (is_object($callback[0])) { |
3166 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3164 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), array('.$params.'))'; |
|
3167 | 3165 | } else { |
3168 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3166 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array(\''.$callback[0].'\', \''.$callback[1].'\'), array('.$params.'))'; |
|
3169 | 3167 | } |
3170 | 3168 | } elseif ($mapped) { |
3171 | - $output = '$this->arrayMap(\'' . $callback . '\', array(' . $params . '))'; |
|
3169 | + $output = '$this->arrayMap(\''.$callback.'\', array('.$params.'))'; |
|
3172 | 3170 | } else { |
3173 | - $output = $callback . '(' . $params . ')'; |
|
3171 | + $output = $callback.'('.$params.')'; |
|
3174 | 3172 | } |
3175 | 3173 | } elseif ($mapped) { |
3176 | - $output = '$this->arrayMap(\'smarty_modifier_' . $func . '\', array(' . $params . '))'; |
|
3174 | + $output = '$this->arrayMap(\'smarty_modifier_'.$func.'\', array('.$params.'))'; |
|
3177 | 3175 | } else { |
3178 | - $output = 'smarty_modifier_' . $func . '(' . $params . ')'; |
|
3176 | + $output = 'smarty_modifier_'.$func.'('.$params.')'; |
|
3179 | 3177 | } |
3180 | 3178 | } else { |
3181 | 3179 | if ($pluginType & Core::CUSTOM_PLUGIN) { |
3182 | 3180 | $callback = $this->customPlugins[$func]['callback']; |
3183 | 3181 | $pluginName = $callback; |
3184 | 3182 | } else { |
3185 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false || function_exists('Plugin' . |
|
3186 | - Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) |
|
3183 | + if (class_exists('Plugin'.Core::toCamelCase($func)) !== false || function_exists('Plugin'. |
|
3184 | + Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) |
|
3187 | 3185 | !== false) { |
3188 | - $pluginName = 'Plugin' . Core::toCamelCase($func); |
|
3186 | + $pluginName = 'Plugin'.Core::toCamelCase($func); |
|
3189 | 3187 | } else { |
3190 | - $pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func); |
|
3188 | + $pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func); |
|
3191 | 3189 | } |
3192 | 3190 | if ($pluginType & Core::CLASS_PLUGIN) { |
3193 | 3191 | $callback = array($pluginName, ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'); |
3194 | 3192 | } else { |
3195 | - $callback = $pluginName . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''); |
|
3193 | + $callback = $pluginName.(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''); |
|
3196 | 3194 | } |
3197 | 3195 | } |
3198 | 3196 | $params = $this->mapParams($params, $callback, $state); |
@@ -3209,10 +3207,10 @@ discard block |
||
3209 | 3207 | if ($pluginType & Core::CUSTOM_PLUGIN) { |
3210 | 3208 | $funcCompiler = $this->customPlugins[$func]['callback']; |
3211 | 3209 | } else { |
3212 | - if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) { |
|
3213 | - $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile'; |
|
3210 | + if (function_exists('Plugin'.Core::toCamelCase($func).'Compile') !== false) { |
|
3211 | + $funcCompiler = 'Plugin'.Core::toCamelCase($func).'Compile'; |
|
3214 | 3212 | } else { |
3215 | - $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . |
|
3213 | + $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func). |
|
3216 | 3214 | 'Compile'; |
3217 | 3215 | } |
3218 | 3216 | } |
@@ -3223,9 +3221,9 @@ discard block |
||
3223 | 3221 | |
3224 | 3222 | $params = self::implode_r($params); |
3225 | 3223 | if ($mapped) { |
3226 | - $output = '$this->arrayMap(\'' . $pluginName . '\', array(' . $params . '))'; |
|
3224 | + $output = '$this->arrayMap(\''.$pluginName.'\', array('.$params.'))'; |
|
3227 | 3225 | } else { |
3228 | - $output = $pluginName . '(' . $params . ')'; |
|
3226 | + $output = $pluginName.'('.$params.')'; |
|
3229 | 3227 | } |
3230 | 3228 | } |
3231 | 3229 | } else { |
@@ -3237,7 +3235,7 @@ discard block |
||
3237 | 3235 | $callback = $this->customPlugins[$func]['callback']; |
3238 | 3236 | if (!is_array($callback)) { |
3239 | 3237 | if (!method_exists($callback, 'compile')) { |
3240 | - throw new Exception('Custom plugin ' . $func . ' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
3238 | + throw new Exception('Custom plugin '.$func.' must implement the "compile" method to be compilable, or you should provide a full callback to the method to use'); |
|
3241 | 3239 | } |
3242 | 3240 | if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) { |
3243 | 3241 | $funcCompiler = array($callback, 'compile'); |
@@ -3248,11 +3246,11 @@ discard block |
||
3248 | 3246 | $funcCompiler = $callback; |
3249 | 3247 | } |
3250 | 3248 | } else { |
3251 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
3252 | - $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile'); |
|
3249 | + if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) { |
|
3250 | + $funcCompiler = array('Plugin'.Core::toCamelCase($func), 'compile'); |
|
3253 | 3251 | } else { |
3254 | 3252 | $funcCompiler = array( |
3255 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func), |
|
3253 | + Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func), |
|
3256 | 3254 | 'compile' |
3257 | 3255 | ); |
3258 | 3256 | } |
@@ -3264,19 +3262,19 @@ discard block |
||
3264 | 3262 | |
3265 | 3263 | if ($pluginType & Core::CUSTOM_PLUGIN) { |
3266 | 3264 | if (is_object($callback[0])) { |
3267 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3265 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), array('.$params.'))'; |
|
3268 | 3266 | } else { |
3269 | - $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))'; |
|
3267 | + $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array(\''.$callback[0].'\', \''.$callback[1].'\'), array('.$params.'))'; |
|
3270 | 3268 | } |
3271 | 3269 | } elseif ($mapped) { |
3272 | 3270 | $output = '$this->arrayMap(array($this->getObjectPlugin(\''. |
3273 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '\'), |
|
3274 | - \'process\'), array(' . $params . '))'; |
|
3271 | + Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).'\'), |
|
3272 | + \'process\'), array(' . $params.'))'; |
|
3275 | 3273 | } else { |
3276 | - if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) { |
|
3277 | - $output = '$this->classCall(\'Plugin' . Core::toCamelCase($func) . '\', array(' . $params . '))'; |
|
3274 | + if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) { |
|
3275 | + $output = '$this->classCall(\'Plugin'.Core::toCamelCase($func).'\', array('.$params.'))'; |
|
3278 | 3276 | } else { |
3279 | - $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))'; |
|
3277 | + $output = '$this->classCall(\''.$func.'\', array('.$params.'))'; |
|
3280 | 3278 | } |
3281 | 3279 | } |
3282 | 3280 | } |
@@ -3289,7 +3287,7 @@ discard block |
||
3289 | 3287 | } elseif ($curBlock === 'var' || $m[1] === null) { |
3290 | 3288 | return $output; |
3291 | 3289 | } elseif ($curBlock === 'string' || $curBlock === 'root') { |
3292 | - return $m[1] . '.' . $output . '.' . $m[1] . (isset($add) ? $add : null); |
|
3290 | + return $m[1].'.'.$output.'.'.$m[1].(isset($add) ? $add : null); |
|
3293 | 3291 | } |
3294 | 3292 | |
3295 | 3293 | return ''; |
@@ -3312,14 +3310,14 @@ discard block |
||
3312 | 3310 | if (is_array($p)) { |
3313 | 3311 | $out2 = 'array('; |
3314 | 3312 | foreach ($p as $k2 => $v) { |
3315 | - $out2 .= var_export($k2, true) . ' => ' . (is_array($v) ? 'array(' . self::implode_r($v, true) . ')' : $v) . ', '; |
|
3313 | + $out2 .= var_export($k2, true).' => '.(is_array($v) ? 'array('.self::implode_r($v, true).')' : $v).', '; |
|
3316 | 3314 | } |
3317 | - $p = rtrim($out2, ', ') . ')'; |
|
3315 | + $p = rtrim($out2, ', ').')'; |
|
3318 | 3316 | } |
3319 | 3317 | if ($recursiveCall) { |
3320 | - $out .= var_export($k, true) . ' => ' . $p . ', '; |
|
3318 | + $out .= var_export($k, true).' => '.$p.', '; |
|
3321 | 3319 | } else { |
3322 | - $out .= $p . ', '; |
|
3320 | + $out .= $p.', '; |
|
3323 | 3321 | } |
3324 | 3322 | } |
3325 | 3323 | |
@@ -3343,7 +3341,7 @@ discard block |
||
3343 | 3341 | if (($this->securityPolicy === null && (function_exists($name) || strtolower($name) === 'isset' || strtolower($name) === 'empty')) || ($this->securityPolicy !== null && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) !== false)) { |
3344 | 3342 | $phpFunc = true; |
3345 | 3343 | } elseif ($this->securityPolicy !== null && function_exists($name) && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) === false) { |
3346 | - throw new SecurityException('Call to a disallowed php function : ' . $name); |
|
3344 | + throw new SecurityException('Call to a disallowed php function : '.$name); |
|
3347 | 3345 | } |
3348 | 3346 | |
3349 | 3347 | while ($pluginType <= 0) { |
@@ -3354,61 +3352,60 @@ discard block |
||
3354 | 3352 | elseif (isset($this->customPlugins[$name])) { |
3355 | 3353 | $pluginType = $this->customPlugins[$name]['type'] | Core::CUSTOM_PLUGIN; |
3356 | 3354 | } // Class blocks plugin |
3357 | - elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), false) !== |
|
3355 | + elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($name), false) !== |
|
3358 | 3356 | false) { |
3359 | - if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), 'Dwoo\Block\Plugin')) { |
|
3357 | + if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($name), 'Dwoo\Block\Plugin')) { |
|
3360 | 3358 | $pluginType = Core::BLOCK_PLUGIN; |
3361 | 3359 | } else { |
3362 | 3360 | $pluginType = Core::CLASS_PLUGIN; |
3363 | 3361 | } |
3364 | - $interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name)); |
|
3362 | + $interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($name)); |
|
3365 | 3363 | if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
3366 | 3364 | $pluginType |= Core::COMPILABLE_PLUGIN; |
3367 | 3365 | } |
3368 | 3366 | } // Class functions plugin |
3369 | - elseif(class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name), false) !== |
|
3367 | + elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name), false) !== |
|
3370 | 3368 | false) { |
3371 | 3369 | $pluginType = Core::CLASS_PLUGIN; |
3372 | - $interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name)); |
|
3370 | + $interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name)); |
|
3373 | 3371 | if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
3374 | 3372 | $pluginType |= Core::COMPILABLE_PLUGIN; |
3375 | 3373 | } |
3376 | 3374 | } // Class without namespace |
3377 | - elseif(class_exists('Plugin' . Core::toCamelCase($name), false) !== false) { |
|
3375 | + elseif (class_exists('Plugin'.Core::toCamelCase($name), false) !== false) { |
|
3378 | 3376 | $pluginType = Core::CLASS_PLUGIN; |
3379 | - $interfaces = class_implements('Plugin' . Core::toCamelCase($name)); |
|
3377 | + $interfaces = class_implements('Plugin'.Core::toCamelCase($name)); |
|
3380 | 3378 | if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) { |
3381 | 3379 | $pluginType |= Core::COMPILABLE_PLUGIN; |
3382 | 3380 | } |
3383 | 3381 | } // Function plugin (with/without namespaces) |
3384 | - elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase |
|
3385 | - ($name)) !== |
|
3386 | - false || function_exists('Plugin' . Core::toCamelCase($name)) !== false) { |
|
3382 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name)) !== |
|
3383 | + false || function_exists('Plugin'.Core::toCamelCase($name)) !== false) { |
|
3387 | 3384 | $pluginType = Core::FUNC_PLUGIN; |
3388 | 3385 | } // Function plugin compile (with/without namespaces) |
3389 | - elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name) . |
|
3390 | - 'Compile') !== false || function_exists('Plugin' . Core::toCamelCase($name) . 'Compile') !== |
|
3386 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name). |
|
3387 | + 'Compile') !== false || function_exists('Plugin'.Core::toCamelCase($name).'Compile') !== |
|
3391 | 3388 | false) { |
3392 | 3389 | $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN; |
3393 | 3390 | } // Helper plugin compile |
3394 | - elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name) . 'Compile') |
|
3391 | + elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($name).'Compile') |
|
3395 | 3392 | !== false) { |
3396 | 3393 | $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN; |
3397 | 3394 | } // Smarty modifier |
3398 | - elseif (function_exists('smarty_modifier_' . $name) !== false) { |
|
3395 | + elseif (function_exists('smarty_modifier_'.$name) !== false) { |
|
3399 | 3396 | $pluginType = Core::SMARTY_MODIFIER; |
3400 | 3397 | } // Smarty function |
3401 | - elseif (function_exists('smarty_function_' . $name) !== false) { |
|
3398 | + elseif (function_exists('smarty_function_'.$name) !== false) { |
|
3402 | 3399 | $pluginType = Core::SMARTY_FUNCTION; |
3403 | 3400 | } // Smarty block |
3404 | - elseif (function_exists('smarty_block_' . $name) !== false) { |
|
3401 | + elseif (function_exists('smarty_block_'.$name) !== false) { |
|
3405 | 3402 | $pluginType = Core::SMARTY_BLOCK; |
3406 | 3403 | } // Everything else |
3407 | 3404 | else { |
3408 | 3405 | if ($pluginType === - 1) { |
3409 | 3406 | try { |
3410 | 3407 | $this->getDwoo()->getLoader()->loadPlugin( |
3411 | - 'Plugin' . Core::toCamelCase($name)); |
|
3408 | + 'Plugin'.Core::toCamelCase($name)); |
|
3412 | 3409 | } |
3413 | 3410 | catch (Exception $e) { |
3414 | 3411 | if (isset($phpFunc)) { |
@@ -3421,9 +3418,9 @@ discard block |
||
3421 | 3418 | } |
3422 | 3419 | } |
3423 | 3420 | } else { |
3424 | - throw new Exception('Plugin "' . $name . '" could not be found, type:' . $pluginType); |
|
3421 | + throw new Exception('Plugin "'.$name.'" could not be found, type:'.$pluginType); |
|
3425 | 3422 | } |
3426 | - ++ $pluginType; |
|
3423 | + ++$pluginType; |
|
3427 | 3424 | } |
3428 | 3425 | } |
3429 | 3426 | |
@@ -3498,9 +3495,9 @@ discard block |
||
3498 | 3495 | if (count($ps) === 0) { |
3499 | 3496 | if ($v[1] === false) { |
3500 | 3497 | throw new CompilationException( |
3501 | - $this, 'Rest argument missing for ' . str_replace( |
|
3498 | + $this, 'Rest argument missing for '.str_replace( |
|
3502 | 3499 | array( |
3503 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin', |
|
3500 | + Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin', |
|
3504 | 3501 | 'Compile' |
3505 | 3502 | ), '', (is_array($callback) ? $callback[0] : $callback) |
3506 | 3503 | ) |
@@ -3533,7 +3530,7 @@ discard block |
||
3533 | 3530 | // parameter is not defined and not optional, throw error |
3534 | 3531 | if (is_array($callback)) { |
3535 | 3532 | if (is_object($callback[0])) { |
3536 | - $name = get_class($callback[0]) . '::' . $callback[1]; |
|
3533 | + $name = get_class($callback[0]).'::'.$callback[1]; |
|
3537 | 3534 | } else { |
3538 | 3535 | $name = $callback[0]; |
3539 | 3536 | } |
@@ -3542,9 +3539,9 @@ discard block |
||
3542 | 3539 | } |
3543 | 3540 | |
3544 | 3541 | throw new CompilationException( |
3545 | - $this, 'Argument ' . $k . '/' . $v[0] . ' missing for ' . str_replace( |
|
3542 | + $this, 'Argument '.$k.'/'.$v[0].' missing for '.str_replace( |
|
3546 | 3543 | array( |
3547 | - Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin', |
|
3544 | + Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin', |
|
3548 | 3545 | 'Compile' |
3549 | 3546 | ), '', $name |
3550 | 3547 | ) |
@@ -478,8 +478,7 @@ discard block |
||
478 | 478 | if (!class_exists($class) && !function_exists($class)) { |
479 | 479 | try { |
480 | 480 | $this->getDwoo()->getLoader()->loadPlugin($name); |
481 | - } |
|
482 | - catch (Exception $e) { |
|
481 | + } catch (Exception $e) { |
|
483 | 482 | throw new Exception('Processor ' . $name . ' could not be found in your plugin directories, please ensure it is in a file named ' . $name . '.php in the plugin directory'); |
484 | 483 | } |
485 | 484 | } |
@@ -1624,8 +1623,7 @@ discard block |
||
1624 | 1623 | // load if plugin |
1625 | 1624 | try { |
1626 | 1625 | $this->getPluginType('if'); |
1627 | - } |
|
1628 | - catch (Exception $e) { |
|
1626 | + } catch (Exception $e) { |
|
1629 | 1627 | throw new CompilationException($this, 'Assignments require the "if" plugin to be accessible'); |
1630 | 1628 | } |
1631 | 1629 | |
@@ -3409,8 +3407,7 @@ discard block |
||
3409 | 3407 | try { |
3410 | 3408 | $this->getDwoo()->getLoader()->loadPlugin( |
3411 | 3409 | 'Plugin' . Core::toCamelCase($name)); |
3412 | - } |
|
3413 | - catch (Exception $e) { |
|
3410 | + } catch (Exception $e) { |
|
3414 | 3411 | if (isset($phpFunc)) { |
3415 | 3412 | $pluginType = Core::NATIVE_PLUGIN; |
3416 | 3413 | } elseif (is_object($this->getDwoo()->getPluginProxy()) && $this->getDwoo()->getPluginProxy()->handles($name)) { |
@@ -536,7 +536,7 @@ discard block |
||
536 | 536 | * Adds a filter to this Dwoo instance, it will be used to filter the output of all the templates rendered by this |
537 | 537 | * instance. |
538 | 538 | * |
539 | - * @param mixed $callback a callback or a filter name if it is autoloaded from a plugin directory |
|
539 | + * @param Smarty\Filter\Adapter $callback a callback or a filter name if it is autoloaded from a plugin directory |
|
540 | 540 | * @param bool $autoload if true, the first parameter must be a filter name from one of the plugin directories |
541 | 541 | * |
542 | 542 | * @return void |
@@ -1547,7 +1547,7 @@ discard block |
||
1547 | 1547 | * @param mixed $value the value to assign |
1548 | 1548 | * @param string $scope the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property") |
1549 | 1549 | * |
1550 | - * @return bool true if assigned correctly or false if a problem occured while parsing the var string |
|
1550 | + * @return null|false true if assigned correctly or false if a problem occured while parsing the var string |
|
1551 | 1551 | */ |
1552 | 1552 | public function assignInScope($value, $scope) |
1553 | 1553 | { |
@@ -44,1683 +44,1683 @@ |
||
44 | 44 | */ |
45 | 45 | class Core |
46 | 46 | { |
47 | - /** |
|
48 | - * Current version number. |
|
49 | - * |
|
50 | - * @var string |
|
51 | - */ |
|
52 | - const VERSION = '1.3.0'; |
|
53 | - |
|
54 | - /** |
|
55 | - * Unique number of this dwoo release, based on version number. |
|
56 | - * this can be used by templates classes to check whether the compiled template |
|
57 | - * has been compiled before this release or not, so that old templates are |
|
58 | - * recompiled automatically when Dwoo is updated |
|
59 | - */ |
|
60 | - const RELEASE_TAG = 130; |
|
61 | - |
|
62 | - /** |
|
63 | - * Constants that represents all plugin types |
|
64 | - * these are bitwise-operation-safe values to allow multiple types |
|
65 | - * on a single plugin |
|
66 | - * |
|
67 | - * @var int |
|
68 | - */ |
|
69 | - const CLASS_PLUGIN = 1; |
|
70 | - const FUNC_PLUGIN = 2; |
|
71 | - const NATIVE_PLUGIN = 4; |
|
72 | - const BLOCK_PLUGIN = 8; |
|
73 | - const COMPILABLE_PLUGIN = 16; |
|
74 | - const CUSTOM_PLUGIN = 32; |
|
75 | - const SMARTY_MODIFIER = 64; |
|
76 | - const SMARTY_BLOCK = 128; |
|
77 | - const SMARTY_FUNCTION = 256; |
|
78 | - const PROXY_PLUGIN = 512; |
|
79 | - const TEMPLATE_PLUGIN = 1024; |
|
80 | - |
|
81 | - /** |
|
82 | - * Constant to default namespaces of builtin plugins |
|
83 | - * |
|
84 | - * @var string |
|
85 | - */ |
|
86 | - const NAMESPACE_PLUGINS_BLOCKS = 'Dwoo\Plugins\Blocks\\'; |
|
87 | - const NAMESPACE_PLUGINS_FILTERS = 'Dwoo\Plugins\Filters\\'; |
|
88 | - const NAMESPACE_PLUGINS_FUNCTIONS = 'Dwoo\Plugins\Functions\\'; |
|
89 | - const NAMESPACE_PLUGINS_HELPERS = 'Dwoo\Plugins\Helpers\\'; |
|
90 | - const NAMESPACE_PLUGINS_PROCESSORS = 'Dwoo\Plugins\Processors\\'; |
|
91 | - |
|
92 | - /** |
|
93 | - * Character set of the template, used by string manipulation plugins. |
|
94 | - * it must be lowercase, but setCharset() will take care of that |
|
95 | - * |
|
96 | - * @see setCharset |
|
97 | - * @see getCharset |
|
98 | - * @var string |
|
99 | - */ |
|
100 | - protected $charset = 'UTF-8'; |
|
101 | - |
|
102 | - /** |
|
103 | - * Global variables that are accessible through $dwoo.* in the templates. |
|
104 | - * default values include: |
|
105 | - * $dwoo.version - current version number |
|
106 | - * $dwoo.ad - a Powered by Dwoo link pointing to dwoo.org |
|
107 | - * $dwoo.now - the current time |
|
108 | - * $dwoo.template - the current template filename |
|
109 | - * $dwoo.charset - the character set used by the template |
|
110 | - * on top of that, foreach and other plugins can store special values in there, |
|
111 | - * see their documentation for more details. |
|
112 | - * |
|
113 | - * @var array |
|
114 | - */ |
|
115 | - public $globals; |
|
116 | - |
|
117 | - /** |
|
118 | - * Directory where the compiled templates are stored. |
|
119 | - * defaults to DWOO_COMPILEDIR (= dwoo_dir/compiled by default) |
|
120 | - * |
|
121 | - * @var string |
|
122 | - */ |
|
123 | - protected $compileDir; |
|
124 | - |
|
125 | - /** |
|
126 | - * Directory where the cached templates are stored. |
|
127 | - * defaults to DWOO_CACHEDIR (= dwoo_dir/cache by default) |
|
128 | - * |
|
129 | - * @var string |
|
130 | - */ |
|
131 | - protected $cacheDir; |
|
132 | - |
|
133 | - /** |
|
134 | - * Defines how long (in seconds) the cached files must remain valid. |
|
135 | - * can be overriden on a per-template basis |
|
136 | - * -1 = never delete |
|
137 | - * 0 = disabled |
|
138 | - * >0 = duration in seconds |
|
139 | - * |
|
140 | - * @var int |
|
141 | - */ |
|
142 | - protected $cacheTime = 0; |
|
143 | - |
|
144 | - /** |
|
145 | - * Security policy object. |
|
146 | - * |
|
147 | - * @var SecurityPolicy |
|
148 | - */ |
|
149 | - protected $securityPolicy = null; |
|
150 | - |
|
151 | - /** |
|
152 | - * Stores the custom plugins callbacks. |
|
153 | - * |
|
154 | - * @see addPlugin |
|
155 | - * @see removePlugin |
|
156 | - * @var array |
|
157 | - */ |
|
158 | - protected $plugins = array(); |
|
159 | - |
|
160 | - /** |
|
161 | - * Stores the filter callbacks. |
|
162 | - * |
|
163 | - * @see addFilter |
|
164 | - * @see removeFilter |
|
165 | - * @var array |
|
166 | - */ |
|
167 | - protected $filters = array(); |
|
168 | - |
|
169 | - /** |
|
170 | - * Stores the resource types and associated |
|
171 | - * classes / compiler classes. |
|
172 | - * |
|
173 | - * @var array |
|
174 | - */ |
|
175 | - protected $resources = array( |
|
176 | - 'file' => array( |
|
177 | - 'class' => 'Dwoo\Template\File', |
|
178 | - 'compiler' => null, |
|
179 | - ), |
|
180 | - 'string' => array( |
|
181 | - 'class' => 'Dwoo\Template\String', |
|
182 | - 'compiler' => null, |
|
183 | - ), |
|
184 | - ); |
|
185 | - |
|
186 | - /** |
|
187 | - * The dwoo loader object used to load plugins by this dwoo instance. |
|
188 | - * |
|
189 | - * @var ILoader |
|
190 | - */ |
|
191 | - protected $loader = null; |
|
192 | - |
|
193 | - /** |
|
194 | - * Currently rendered template, set to null when not-rendering. |
|
195 | - * |
|
196 | - * @var ITemplate |
|
197 | - */ |
|
198 | - protected $template = null; |
|
199 | - |
|
200 | - /** |
|
201 | - * Stores the instances of the class plugins during template runtime. |
|
202 | - * |
|
203 | - * @var array |
|
204 | - */ |
|
205 | - protected $runtimePlugins; |
|
206 | - |
|
207 | - /** |
|
208 | - * Stores the returned values during template runtime. |
|
209 | - * |
|
210 | - * @var array |
|
211 | - */ |
|
212 | - protected $returnData; |
|
213 | - |
|
214 | - /** |
|
215 | - * Stores the data during template runtime. |
|
216 | - * |
|
217 | - * @var array |
|
218 | - */ |
|
219 | - public $data; |
|
220 | - |
|
221 | - /** |
|
222 | - * Stores the current scope during template runtime. |
|
223 | - * this should ideally not be accessed directly from outside template code |
|
224 | - * |
|
225 | - * @var mixed |
|
226 | - */ |
|
227 | - public $scope; |
|
228 | - |
|
229 | - /** |
|
230 | - * Stores the scope tree during template runtime. |
|
231 | - * |
|
232 | - * @var array |
|
233 | - */ |
|
234 | - protected $scopeTree; |
|
235 | - |
|
236 | - /** |
|
237 | - * Stores the block plugins stack during template runtime. |
|
238 | - * |
|
239 | - * @var array |
|
240 | - */ |
|
241 | - protected $stack; |
|
242 | - |
|
243 | - /** |
|
244 | - * Stores the current block plugin at the top of the stack during template runtime. |
|
245 | - * |
|
246 | - * @var BlockPlugin |
|
247 | - */ |
|
248 | - protected $curBlock; |
|
249 | - |
|
250 | - /** |
|
251 | - * Stores the output buffer during template runtime. |
|
252 | - * |
|
253 | - * @var string |
|
254 | - */ |
|
255 | - protected $buffer; |
|
256 | - |
|
257 | - /** |
|
258 | - * Stores plugin proxy. |
|
259 | - * |
|
260 | - * @var IPluginProxy |
|
261 | - */ |
|
262 | - protected $pluginProxy; |
|
263 | - |
|
264 | - /** |
|
265 | - * Constructor, sets the cache and compile dir to the default values if not provided. |
|
266 | - * |
|
267 | - * @param string $compileDir path to the compiled directory, defaults to lib/compiled |
|
268 | - * @param string $cacheDir path to the cache directory, defaults to lib/cache |
|
269 | - */ |
|
270 | - public function __construct($compileDir = null, $cacheDir = null) |
|
271 | - { |
|
272 | - if ($compileDir !== null) { |
|
273 | - $this->setCompileDir($compileDir); |
|
274 | - } |
|
275 | - if ($cacheDir !== null) { |
|
276 | - $this->setCacheDir($cacheDir); |
|
277 | - } |
|
278 | - $this->initGlobals(); |
|
279 | - } |
|
280 | - |
|
281 | - /** |
|
282 | - * Resets some runtime variables to allow a cloned object to be used to render sub-templates. |
|
283 | - * |
|
284 | - * @return void |
|
285 | - */ |
|
286 | - public function __clone() |
|
287 | - { |
|
288 | - $this->template = null; |
|
289 | - unset($this->data); |
|
290 | - unset($this->returnData); |
|
291 | - } |
|
292 | - |
|
293 | - /** |
|
294 | - * Returns the given template rendered using the provided data and optional compiler. |
|
295 | - * |
|
296 | - * @param mixed $_tpl template, can either be a ITemplate object (i.e. TemplateFile), a |
|
297 | - * valid path to a template, or a template as a string it is recommended to |
|
298 | - * provide a ITemplate as it will probably make things faster, especially if |
|
299 | - * you render a template multiple times |
|
300 | - * @param mixed $data the data to use, can either be a IDataProvider object (i.e. Data) or |
|
301 | - * an associative array. if you're rendering the template from cache, it can be |
|
302 | - * left null |
|
303 | - * @param ICompiler $_compiler the compiler that must be used to compile the template, if left empty a default |
|
304 | - * Compiler will be used |
|
305 | - * |
|
306 | - * @return string|void or the template output if $output is false |
|
307 | - * @throws Exception |
|
308 | - */ |
|
309 | - public function get($_tpl, $data = array(), $_compiler = null) |
|
310 | - { |
|
311 | - // a render call came from within a template, so we need a new dwoo instance in order to avoid breaking this one |
|
312 | - if ($this->template instanceof ITemplate) { |
|
313 | - $clone = clone $this; |
|
314 | - |
|
315 | - return $clone->get($_tpl, $data, $_compiler); |
|
316 | - } |
|
317 | - |
|
318 | - // auto-create template if required |
|
319 | - if ($_tpl instanceof ITemplate) { |
|
320 | - // valid, skip |
|
321 | - } elseif (is_string($_tpl) && file_exists($_tpl)) { |
|
322 | - $_tpl = new TemplateFile($_tpl); |
|
323 | - } else { |
|
324 | - throw new Exception( |
|
325 | - 'Dwoo->get\'s first argument must be a ITemplate (i.e. TemplateFile) or |
|
47 | + /** |
|
48 | + * Current version number. |
|
49 | + * |
|
50 | + * @var string |
|
51 | + */ |
|
52 | + const VERSION = '1.3.0'; |
|
53 | + |
|
54 | + /** |
|
55 | + * Unique number of this dwoo release, based on version number. |
|
56 | + * this can be used by templates classes to check whether the compiled template |
|
57 | + * has been compiled before this release or not, so that old templates are |
|
58 | + * recompiled automatically when Dwoo is updated |
|
59 | + */ |
|
60 | + const RELEASE_TAG = 130; |
|
61 | + |
|
62 | + /** |
|
63 | + * Constants that represents all plugin types |
|
64 | + * these are bitwise-operation-safe values to allow multiple types |
|
65 | + * on a single plugin |
|
66 | + * |
|
67 | + * @var int |
|
68 | + */ |
|
69 | + const CLASS_PLUGIN = 1; |
|
70 | + const FUNC_PLUGIN = 2; |
|
71 | + const NATIVE_PLUGIN = 4; |
|
72 | + const BLOCK_PLUGIN = 8; |
|
73 | + const COMPILABLE_PLUGIN = 16; |
|
74 | + const CUSTOM_PLUGIN = 32; |
|
75 | + const SMARTY_MODIFIER = 64; |
|
76 | + const SMARTY_BLOCK = 128; |
|
77 | + const SMARTY_FUNCTION = 256; |
|
78 | + const PROXY_PLUGIN = 512; |
|
79 | + const TEMPLATE_PLUGIN = 1024; |
|
80 | + |
|
81 | + /** |
|
82 | + * Constant to default namespaces of builtin plugins |
|
83 | + * |
|
84 | + * @var string |
|
85 | + */ |
|
86 | + const NAMESPACE_PLUGINS_BLOCKS = 'Dwoo\Plugins\Blocks\\'; |
|
87 | + const NAMESPACE_PLUGINS_FILTERS = 'Dwoo\Plugins\Filters\\'; |
|
88 | + const NAMESPACE_PLUGINS_FUNCTIONS = 'Dwoo\Plugins\Functions\\'; |
|
89 | + const NAMESPACE_PLUGINS_HELPERS = 'Dwoo\Plugins\Helpers\\'; |
|
90 | + const NAMESPACE_PLUGINS_PROCESSORS = 'Dwoo\Plugins\Processors\\'; |
|
91 | + |
|
92 | + /** |
|
93 | + * Character set of the template, used by string manipulation plugins. |
|
94 | + * it must be lowercase, but setCharset() will take care of that |
|
95 | + * |
|
96 | + * @see setCharset |
|
97 | + * @see getCharset |
|
98 | + * @var string |
|
99 | + */ |
|
100 | + protected $charset = 'UTF-8'; |
|
101 | + |
|
102 | + /** |
|
103 | + * Global variables that are accessible through $dwoo.* in the templates. |
|
104 | + * default values include: |
|
105 | + * $dwoo.version - current version number |
|
106 | + * $dwoo.ad - a Powered by Dwoo link pointing to dwoo.org |
|
107 | + * $dwoo.now - the current time |
|
108 | + * $dwoo.template - the current template filename |
|
109 | + * $dwoo.charset - the character set used by the template |
|
110 | + * on top of that, foreach and other plugins can store special values in there, |
|
111 | + * see their documentation for more details. |
|
112 | + * |
|
113 | + * @var array |
|
114 | + */ |
|
115 | + public $globals; |
|
116 | + |
|
117 | + /** |
|
118 | + * Directory where the compiled templates are stored. |
|
119 | + * defaults to DWOO_COMPILEDIR (= dwoo_dir/compiled by default) |
|
120 | + * |
|
121 | + * @var string |
|
122 | + */ |
|
123 | + protected $compileDir; |
|
124 | + |
|
125 | + /** |
|
126 | + * Directory where the cached templates are stored. |
|
127 | + * defaults to DWOO_CACHEDIR (= dwoo_dir/cache by default) |
|
128 | + * |
|
129 | + * @var string |
|
130 | + */ |
|
131 | + protected $cacheDir; |
|
132 | + |
|
133 | + /** |
|
134 | + * Defines how long (in seconds) the cached files must remain valid. |
|
135 | + * can be overriden on a per-template basis |
|
136 | + * -1 = never delete |
|
137 | + * 0 = disabled |
|
138 | + * >0 = duration in seconds |
|
139 | + * |
|
140 | + * @var int |
|
141 | + */ |
|
142 | + protected $cacheTime = 0; |
|
143 | + |
|
144 | + /** |
|
145 | + * Security policy object. |
|
146 | + * |
|
147 | + * @var SecurityPolicy |
|
148 | + */ |
|
149 | + protected $securityPolicy = null; |
|
150 | + |
|
151 | + /** |
|
152 | + * Stores the custom plugins callbacks. |
|
153 | + * |
|
154 | + * @see addPlugin |
|
155 | + * @see removePlugin |
|
156 | + * @var array |
|
157 | + */ |
|
158 | + protected $plugins = array(); |
|
159 | + |
|
160 | + /** |
|
161 | + * Stores the filter callbacks. |
|
162 | + * |
|
163 | + * @see addFilter |
|
164 | + * @see removeFilter |
|
165 | + * @var array |
|
166 | + */ |
|
167 | + protected $filters = array(); |
|
168 | + |
|
169 | + /** |
|
170 | + * Stores the resource types and associated |
|
171 | + * classes / compiler classes. |
|
172 | + * |
|
173 | + * @var array |
|
174 | + */ |
|
175 | + protected $resources = array( |
|
176 | + 'file' => array( |
|
177 | + 'class' => 'Dwoo\Template\File', |
|
178 | + 'compiler' => null, |
|
179 | + ), |
|
180 | + 'string' => array( |
|
181 | + 'class' => 'Dwoo\Template\String', |
|
182 | + 'compiler' => null, |
|
183 | + ), |
|
184 | + ); |
|
185 | + |
|
186 | + /** |
|
187 | + * The dwoo loader object used to load plugins by this dwoo instance. |
|
188 | + * |
|
189 | + * @var ILoader |
|
190 | + */ |
|
191 | + protected $loader = null; |
|
192 | + |
|
193 | + /** |
|
194 | + * Currently rendered template, set to null when not-rendering. |
|
195 | + * |
|
196 | + * @var ITemplate |
|
197 | + */ |
|
198 | + protected $template = null; |
|
199 | + |
|
200 | + /** |
|
201 | + * Stores the instances of the class plugins during template runtime. |
|
202 | + * |
|
203 | + * @var array |
|
204 | + */ |
|
205 | + protected $runtimePlugins; |
|
206 | + |
|
207 | + /** |
|
208 | + * Stores the returned values during template runtime. |
|
209 | + * |
|
210 | + * @var array |
|
211 | + */ |
|
212 | + protected $returnData; |
|
213 | + |
|
214 | + /** |
|
215 | + * Stores the data during template runtime. |
|
216 | + * |
|
217 | + * @var array |
|
218 | + */ |
|
219 | + public $data; |
|
220 | + |
|
221 | + /** |
|
222 | + * Stores the current scope during template runtime. |
|
223 | + * this should ideally not be accessed directly from outside template code |
|
224 | + * |
|
225 | + * @var mixed |
|
226 | + */ |
|
227 | + public $scope; |
|
228 | + |
|
229 | + /** |
|
230 | + * Stores the scope tree during template runtime. |
|
231 | + * |
|
232 | + * @var array |
|
233 | + */ |
|
234 | + protected $scopeTree; |
|
235 | + |
|
236 | + /** |
|
237 | + * Stores the block plugins stack during template runtime. |
|
238 | + * |
|
239 | + * @var array |
|
240 | + */ |
|
241 | + protected $stack; |
|
242 | + |
|
243 | + /** |
|
244 | + * Stores the current block plugin at the top of the stack during template runtime. |
|
245 | + * |
|
246 | + * @var BlockPlugin |
|
247 | + */ |
|
248 | + protected $curBlock; |
|
249 | + |
|
250 | + /** |
|
251 | + * Stores the output buffer during template runtime. |
|
252 | + * |
|
253 | + * @var string |
|
254 | + */ |
|
255 | + protected $buffer; |
|
256 | + |
|
257 | + /** |
|
258 | + * Stores plugin proxy. |
|
259 | + * |
|
260 | + * @var IPluginProxy |
|
261 | + */ |
|
262 | + protected $pluginProxy; |
|
263 | + |
|
264 | + /** |
|
265 | + * Constructor, sets the cache and compile dir to the default values if not provided. |
|
266 | + * |
|
267 | + * @param string $compileDir path to the compiled directory, defaults to lib/compiled |
|
268 | + * @param string $cacheDir path to the cache directory, defaults to lib/cache |
|
269 | + */ |
|
270 | + public function __construct($compileDir = null, $cacheDir = null) |
|
271 | + { |
|
272 | + if ($compileDir !== null) { |
|
273 | + $this->setCompileDir($compileDir); |
|
274 | + } |
|
275 | + if ($cacheDir !== null) { |
|
276 | + $this->setCacheDir($cacheDir); |
|
277 | + } |
|
278 | + $this->initGlobals(); |
|
279 | + } |
|
280 | + |
|
281 | + /** |
|
282 | + * Resets some runtime variables to allow a cloned object to be used to render sub-templates. |
|
283 | + * |
|
284 | + * @return void |
|
285 | + */ |
|
286 | + public function __clone() |
|
287 | + { |
|
288 | + $this->template = null; |
|
289 | + unset($this->data); |
|
290 | + unset($this->returnData); |
|
291 | + } |
|
292 | + |
|
293 | + /** |
|
294 | + * Returns the given template rendered using the provided data and optional compiler. |
|
295 | + * |
|
296 | + * @param mixed $_tpl template, can either be a ITemplate object (i.e. TemplateFile), a |
|
297 | + * valid path to a template, or a template as a string it is recommended to |
|
298 | + * provide a ITemplate as it will probably make things faster, especially if |
|
299 | + * you render a template multiple times |
|
300 | + * @param mixed $data the data to use, can either be a IDataProvider object (i.e. Data) or |
|
301 | + * an associative array. if you're rendering the template from cache, it can be |
|
302 | + * left null |
|
303 | + * @param ICompiler $_compiler the compiler that must be used to compile the template, if left empty a default |
|
304 | + * Compiler will be used |
|
305 | + * |
|
306 | + * @return string|void or the template output if $output is false |
|
307 | + * @throws Exception |
|
308 | + */ |
|
309 | + public function get($_tpl, $data = array(), $_compiler = null) |
|
310 | + { |
|
311 | + // a render call came from within a template, so we need a new dwoo instance in order to avoid breaking this one |
|
312 | + if ($this->template instanceof ITemplate) { |
|
313 | + $clone = clone $this; |
|
314 | + |
|
315 | + return $clone->get($_tpl, $data, $_compiler); |
|
316 | + } |
|
317 | + |
|
318 | + // auto-create template if required |
|
319 | + if ($_tpl instanceof ITemplate) { |
|
320 | + // valid, skip |
|
321 | + } elseif (is_string($_tpl) && file_exists($_tpl)) { |
|
322 | + $_tpl = new TemplateFile($_tpl); |
|
323 | + } else { |
|
324 | + throw new Exception( |
|
325 | + 'Dwoo->get\'s first argument must be a ITemplate (i.e. TemplateFile) or |
|
326 | 326 | a valid path to a template file', E_USER_NOTICE |
327 | - ); |
|
328 | - } |
|
329 | - |
|
330 | - // save the current template, enters render mode at the same time |
|
331 | - // if another rendering is requested it will be proxied to a new Core(instance |
|
332 | - $this->template = $_tpl; |
|
333 | - |
|
334 | - // load data |
|
335 | - if ($data instanceof IDataProvider) { |
|
336 | - $this->data = $data->getData(); |
|
337 | - } elseif (is_array($data)) { |
|
338 | - $this->data = $data; |
|
339 | - } elseif ($data instanceof ArrayAccess) { |
|
340 | - $this->data = $data; |
|
341 | - } else { |
|
342 | - throw new Exception( |
|
343 | - 'Dwoo->get/Dwoo->output\'s data argument must be a IDataProvider object (i.e. Data) or |
|
327 | + ); |
|
328 | + } |
|
329 | + |
|
330 | + // save the current template, enters render mode at the same time |
|
331 | + // if another rendering is requested it will be proxied to a new Core(instance |
|
332 | + $this->template = $_tpl; |
|
333 | + |
|
334 | + // load data |
|
335 | + if ($data instanceof IDataProvider) { |
|
336 | + $this->data = $data->getData(); |
|
337 | + } elseif (is_array($data)) { |
|
338 | + $this->data = $data; |
|
339 | + } elseif ($data instanceof ArrayAccess) { |
|
340 | + $this->data = $data; |
|
341 | + } else { |
|
342 | + throw new Exception( |
|
343 | + 'Dwoo->get/Dwoo->output\'s data argument must be a IDataProvider object (i.e. Data) or |
|
344 | 344 | an associative array', E_USER_NOTICE |
345 | - ); |
|
346 | - } |
|
347 | - |
|
348 | - $this->globals['template'] = $_tpl->getName(); |
|
349 | - $this->initRuntimeVars($_tpl); |
|
350 | - |
|
351 | - // try to get cached template |
|
352 | - $file = $_tpl->getCachedTemplate($this); |
|
353 | - $doCache = $file === true; |
|
354 | - $cacheLoaded = is_string($file); |
|
355 | - |
|
356 | - if ($cacheLoaded === true) { |
|
357 | - // cache is present, run it |
|
358 | - ob_start(); |
|
359 | - include $file; |
|
360 | - $this->template = null; |
|
361 | - |
|
362 | - return ob_get_clean(); |
|
363 | - } else { |
|
364 | - $dynamicId = uniqid(); |
|
365 | - |
|
366 | - // render template |
|
367 | - $compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler); |
|
368 | - $out = include $compiledTemplate; |
|
369 | - |
|
370 | - // template returned false so it needs to be recompiled |
|
371 | - if ($out === false) { |
|
372 | - $_tpl->forceCompilation(); |
|
373 | - $compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler); |
|
374 | - $out = include $compiledTemplate; |
|
375 | - } |
|
376 | - |
|
377 | - if ($doCache === true) { |
|
378 | - $out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*' . $dynamicId . '*/ echo \'$1\'; ?>', $out); |
|
379 | - if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS . 'PluginDynamic')) { |
|
380 | - $this->getLoader()->loadPlugin('PluginDynamic'); |
|
381 | - } |
|
382 | - $out = PluginDynamic::unescape($out, $dynamicId, $compiledTemplate); |
|
383 | - } |
|
384 | - |
|
385 | - // process filters |
|
386 | - foreach ($this->filters as $filter) { |
|
387 | - if (is_array($filter) && $filter[0] instanceof Filter) { |
|
388 | - $out = call_user_func($filter, $out); |
|
389 | - } else { |
|
390 | - $out = call_user_func($filter, $this, $out); |
|
391 | - } |
|
392 | - } |
|
393 | - |
|
394 | - if ($doCache === true) { |
|
395 | - // building cache |
|
396 | - $file = $_tpl->cache($this, $out); |
|
397 | - |
|
398 | - // run it from the cache to be sure dynamics are rendered |
|
399 | - ob_start(); |
|
400 | - include $file; |
|
401 | - // exit render mode |
|
402 | - $this->template = null; |
|
403 | - |
|
404 | - return ob_get_clean(); |
|
405 | - } else { |
|
406 | - // no need to build cache |
|
407 | - // exit render mode |
|
408 | - $this->template = null; |
|
409 | - |
|
410 | - return $out; |
|
411 | - } |
|
412 | - } |
|
413 | - } |
|
414 | - |
|
415 | - /** |
|
416 | - * Re-initializes the globals array before each template run. |
|
417 | - * this method is only callede once when the Dwoo object is created |
|
418 | - * |
|
419 | - * @return void |
|
420 | - */ |
|
421 | - protected function initGlobals() |
|
422 | - { |
|
423 | - $this->globals = array( |
|
424 | - 'version' => self::VERSION, |
|
425 | - 'ad' => '<a href="http://dwoo.org/">Powered by Dwoo</a>', |
|
426 | - 'now' => $_SERVER['REQUEST_TIME'], |
|
427 | - 'charset' => $this->charset, |
|
428 | - ); |
|
429 | - } |
|
430 | - |
|
431 | - /** |
|
432 | - * Re-initializes the runtime variables before each template run. |
|
433 | - * override this method to inject data in the globals array if needed, this |
|
434 | - * method is called before each template execution |
|
435 | - * |
|
436 | - * @param ITemplate $tpl the template that is going to be rendered |
|
437 | - * |
|
438 | - * @return void |
|
439 | - */ |
|
440 | - protected function initRuntimeVars(ITemplate $tpl) |
|
441 | - { |
|
442 | - $this->runtimePlugins = array(); |
|
443 | - $this->scope = &$this->data; |
|
444 | - $this->scopeTree = array(); |
|
445 | - $this->stack = array(); |
|
446 | - $this->curBlock = null; |
|
447 | - $this->buffer = ''; |
|
448 | - $this->returnData = array(); |
|
449 | - } |
|
450 | - |
|
451 | - /** |
|
452 | - * Adds a custom plugin that is not in one of the plugin directories. |
|
453 | - * |
|
454 | - * @param string $name the plugin name to be used in the templates |
|
455 | - * @param callback $callback the plugin callback, either a function name, |
|
456 | - * a class name or an array containing an object |
|
457 | - * or class name and a method name |
|
458 | - * @param bool $compilable if set to true, the plugin is assumed to be compilable |
|
459 | - * |
|
460 | - * @return void |
|
461 | - * @throws Exception |
|
462 | - */ |
|
463 | - public function addPlugin($name, $callback, $compilable = false) |
|
464 | - { |
|
465 | - $compilable = $compilable ? self::COMPILABLE_PLUGIN : 0; |
|
466 | - if (is_array($callback)) { |
|
467 | - if (is_subclass_of(is_object($callback[0]) ? get_class($callback[0]) : $callback[0], 'Dwoo\Block\Plugin')) { |
|
468 | - $this->plugins[$name] = array( |
|
469 | - 'type' => self::BLOCK_PLUGIN | $compilable, |
|
470 | - 'callback' => $callback, |
|
471 | - 'class' => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0]) |
|
472 | - ); |
|
473 | - } else { |
|
474 | - $this->plugins[$name] = array( |
|
475 | - 'type' => self::CLASS_PLUGIN | $compilable, |
|
476 | - 'callback' => $callback, |
|
477 | - 'class' => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0]), |
|
478 | - 'function' => $callback[1] |
|
479 | - ); |
|
480 | - } |
|
481 | - } elseif (is_string($callback)) { |
|
482 | - if (class_exists($callback)) { |
|
483 | - if (is_subclass_of($callback, 'Dwoo\Block\Plugin')) { |
|
484 | - $this->plugins[$name] = array( |
|
485 | - 'type' => self::BLOCK_PLUGIN | $compilable, |
|
486 | - 'callback' => $callback, |
|
487 | - 'class' => $callback |
|
488 | - ); |
|
489 | - } else { |
|
490 | - $this->plugins[$name] = array( |
|
491 | - 'type' => self::CLASS_PLUGIN | $compilable, |
|
492 | - 'callback' => $callback, |
|
493 | - 'class' => $callback, |
|
494 | - 'function' => ($compilable ? 'compile' : 'process') |
|
495 | - ); |
|
496 | - } |
|
497 | - } elseif (function_exists($callback)) { |
|
498 | - $this->plugins[$name] = array( |
|
499 | - 'type' => self::FUNC_PLUGIN | $compilable, |
|
500 | - 'callback' => $callback |
|
501 | - ); |
|
502 | - } else { |
|
503 | - throw new Exception( |
|
504 | - 'Callback could not be processed correctly, please check that the function/class |
|
345 | + ); |
|
346 | + } |
|
347 | + |
|
348 | + $this->globals['template'] = $_tpl->getName(); |
|
349 | + $this->initRuntimeVars($_tpl); |
|
350 | + |
|
351 | + // try to get cached template |
|
352 | + $file = $_tpl->getCachedTemplate($this); |
|
353 | + $doCache = $file === true; |
|
354 | + $cacheLoaded = is_string($file); |
|
355 | + |
|
356 | + if ($cacheLoaded === true) { |
|
357 | + // cache is present, run it |
|
358 | + ob_start(); |
|
359 | + include $file; |
|
360 | + $this->template = null; |
|
361 | + |
|
362 | + return ob_get_clean(); |
|
363 | + } else { |
|
364 | + $dynamicId = uniqid(); |
|
365 | + |
|
366 | + // render template |
|
367 | + $compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler); |
|
368 | + $out = include $compiledTemplate; |
|
369 | + |
|
370 | + // template returned false so it needs to be recompiled |
|
371 | + if ($out === false) { |
|
372 | + $_tpl->forceCompilation(); |
|
373 | + $compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler); |
|
374 | + $out = include $compiledTemplate; |
|
375 | + } |
|
376 | + |
|
377 | + if ($doCache === true) { |
|
378 | + $out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*' . $dynamicId . '*/ echo \'$1\'; ?>', $out); |
|
379 | + if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS . 'PluginDynamic')) { |
|
380 | + $this->getLoader()->loadPlugin('PluginDynamic'); |
|
381 | + } |
|
382 | + $out = PluginDynamic::unescape($out, $dynamicId, $compiledTemplate); |
|
383 | + } |
|
384 | + |
|
385 | + // process filters |
|
386 | + foreach ($this->filters as $filter) { |
|
387 | + if (is_array($filter) && $filter[0] instanceof Filter) { |
|
388 | + $out = call_user_func($filter, $out); |
|
389 | + } else { |
|
390 | + $out = call_user_func($filter, $this, $out); |
|
391 | + } |
|
392 | + } |
|
393 | + |
|
394 | + if ($doCache === true) { |
|
395 | + // building cache |
|
396 | + $file = $_tpl->cache($this, $out); |
|
397 | + |
|
398 | + // run it from the cache to be sure dynamics are rendered |
|
399 | + ob_start(); |
|
400 | + include $file; |
|
401 | + // exit render mode |
|
402 | + $this->template = null; |
|
403 | + |
|
404 | + return ob_get_clean(); |
|
405 | + } else { |
|
406 | + // no need to build cache |
|
407 | + // exit render mode |
|
408 | + $this->template = null; |
|
409 | + |
|
410 | + return $out; |
|
411 | + } |
|
412 | + } |
|
413 | + } |
|
414 | + |
|
415 | + /** |
|
416 | + * Re-initializes the globals array before each template run. |
|
417 | + * this method is only callede once when the Dwoo object is created |
|
418 | + * |
|
419 | + * @return void |
|
420 | + */ |
|
421 | + protected function initGlobals() |
|
422 | + { |
|
423 | + $this->globals = array( |
|
424 | + 'version' => self::VERSION, |
|
425 | + 'ad' => '<a href="http://dwoo.org/">Powered by Dwoo</a>', |
|
426 | + 'now' => $_SERVER['REQUEST_TIME'], |
|
427 | + 'charset' => $this->charset, |
|
428 | + ); |
|
429 | + } |
|
430 | + |
|
431 | + /** |
|
432 | + * Re-initializes the runtime variables before each template run. |
|
433 | + * override this method to inject data in the globals array if needed, this |
|
434 | + * method is called before each template execution |
|
435 | + * |
|
436 | + * @param ITemplate $tpl the template that is going to be rendered |
|
437 | + * |
|
438 | + * @return void |
|
439 | + */ |
|
440 | + protected function initRuntimeVars(ITemplate $tpl) |
|
441 | + { |
|
442 | + $this->runtimePlugins = array(); |
|
443 | + $this->scope = &$this->data; |
|
444 | + $this->scopeTree = array(); |
|
445 | + $this->stack = array(); |
|
446 | + $this->curBlock = null; |
|
447 | + $this->buffer = ''; |
|
448 | + $this->returnData = array(); |
|
449 | + } |
|
450 | + |
|
451 | + /** |
|
452 | + * Adds a custom plugin that is not in one of the plugin directories. |
|
453 | + * |
|
454 | + * @param string $name the plugin name to be used in the templates |
|
455 | + * @param callback $callback the plugin callback, either a function name, |
|
456 | + * a class name or an array containing an object |
|
457 | + * or class name and a method name |
|
458 | + * @param bool $compilable if set to true, the plugin is assumed to be compilable |
|
459 | + * |
|
460 | + * @return void |
|
461 | + * @throws Exception |
|
462 | + */ |
|
463 | + public function addPlugin($name, $callback, $compilable = false) |
|
464 | + { |
|
465 | + $compilable = $compilable ? self::COMPILABLE_PLUGIN : 0; |
|
466 | + if (is_array($callback)) { |
|
467 | + if (is_subclass_of(is_object($callback[0]) ? get_class($callback[0]) : $callback[0], 'Dwoo\Block\Plugin')) { |
|
468 | + $this->plugins[$name] = array( |
|
469 | + 'type' => self::BLOCK_PLUGIN | $compilable, |
|
470 | + 'callback' => $callback, |
|
471 | + 'class' => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0]) |
|
472 | + ); |
|
473 | + } else { |
|
474 | + $this->plugins[$name] = array( |
|
475 | + 'type' => self::CLASS_PLUGIN | $compilable, |
|
476 | + 'callback' => $callback, |
|
477 | + 'class' => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0]), |
|
478 | + 'function' => $callback[1] |
|
479 | + ); |
|
480 | + } |
|
481 | + } elseif (is_string($callback)) { |
|
482 | + if (class_exists($callback)) { |
|
483 | + if (is_subclass_of($callback, 'Dwoo\Block\Plugin')) { |
|
484 | + $this->plugins[$name] = array( |
|
485 | + 'type' => self::BLOCK_PLUGIN | $compilable, |
|
486 | + 'callback' => $callback, |
|
487 | + 'class' => $callback |
|
488 | + ); |
|
489 | + } else { |
|
490 | + $this->plugins[$name] = array( |
|
491 | + 'type' => self::CLASS_PLUGIN | $compilable, |
|
492 | + 'callback' => $callback, |
|
493 | + 'class' => $callback, |
|
494 | + 'function' => ($compilable ? 'compile' : 'process') |
|
495 | + ); |
|
496 | + } |
|
497 | + } elseif (function_exists($callback)) { |
|
498 | + $this->plugins[$name] = array( |
|
499 | + 'type' => self::FUNC_PLUGIN | $compilable, |
|
500 | + 'callback' => $callback |
|
501 | + ); |
|
502 | + } else { |
|
503 | + throw new Exception( |
|
504 | + 'Callback could not be processed correctly, please check that the function/class |
|
505 | 505 | you used exists' |
506 | - ); |
|
507 | - } |
|
508 | - } elseif ($callback instanceof Closure) { |
|
509 | - $this->plugins[$name] = array( |
|
510 | - 'type' => self::FUNC_PLUGIN | $compilable, |
|
511 | - 'callback' => $callback |
|
512 | - ); |
|
513 | - } else { |
|
514 | - throw new Exception( |
|
515 | - 'Callback could not be processed correctly, please check that the function/class you |
|
506 | + ); |
|
507 | + } |
|
508 | + } elseif ($callback instanceof Closure) { |
|
509 | + $this->plugins[$name] = array( |
|
510 | + 'type' => self::FUNC_PLUGIN | $compilable, |
|
511 | + 'callback' => $callback |
|
512 | + ); |
|
513 | + } else { |
|
514 | + throw new Exception( |
|
515 | + 'Callback could not be processed correctly, please check that the function/class you |
|
516 | 516 | used exists' |
517 | - ); |
|
518 | - } |
|
519 | - } |
|
520 | - |
|
521 | - /** |
|
522 | - * Removes a custom plugin. |
|
523 | - * |
|
524 | - * @param string $name the plugin name |
|
525 | - * |
|
526 | - * @return void |
|
527 | - */ |
|
528 | - public function removePlugin($name) |
|
529 | - { |
|
530 | - if (isset($this->plugins[$name])) { |
|
531 | - unset($this->plugins[$name]); |
|
532 | - } |
|
533 | - } |
|
534 | - |
|
535 | - /** |
|
536 | - * Adds a filter to this Dwoo instance, it will be used to filter the output of all the templates rendered by this |
|
537 | - * instance. |
|
538 | - * |
|
539 | - * @param mixed $callback a callback or a filter name if it is autoloaded from a plugin directory |
|
540 | - * @param bool $autoload if true, the first parameter must be a filter name from one of the plugin directories |
|
541 | - * |
|
542 | - * @return void |
|
543 | - * @throws Exception |
|
544 | - */ |
|
545 | - public function addFilter($callback, $autoload = false) |
|
546 | - { |
|
547 | - if ($autoload) { |
|
548 | - $class = self::NAMESPACE_PLUGINS_FILTERS . self::toCamelCase($callback); |
|
549 | - if (!class_exists($class) && !function_exists($class)) { |
|
550 | - try { |
|
551 | - $this->getLoader()->loadPlugin($callback); |
|
552 | - } |
|
553 | - catch (Exception $e) { |
|
554 | - if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) { |
|
555 | - throw new Exception( |
|
556 | - 'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should |
|
517 | + ); |
|
518 | + } |
|
519 | + } |
|
520 | + |
|
521 | + /** |
|
522 | + * Removes a custom plugin. |
|
523 | + * |
|
524 | + * @param string $name the plugin name |
|
525 | + * |
|
526 | + * @return void |
|
527 | + */ |
|
528 | + public function removePlugin($name) |
|
529 | + { |
|
530 | + if (isset($this->plugins[$name])) { |
|
531 | + unset($this->plugins[$name]); |
|
532 | + } |
|
533 | + } |
|
534 | + |
|
535 | + /** |
|
536 | + * Adds a filter to this Dwoo instance, it will be used to filter the output of all the templates rendered by this |
|
537 | + * instance. |
|
538 | + * |
|
539 | + * @param mixed $callback a callback or a filter name if it is autoloaded from a plugin directory |
|
540 | + * @param bool $autoload if true, the first parameter must be a filter name from one of the plugin directories |
|
541 | + * |
|
542 | + * @return void |
|
543 | + * @throws Exception |
|
544 | + */ |
|
545 | + public function addFilter($callback, $autoload = false) |
|
546 | + { |
|
547 | + if ($autoload) { |
|
548 | + $class = self::NAMESPACE_PLUGINS_FILTERS . self::toCamelCase($callback); |
|
549 | + if (!class_exists($class) && !function_exists($class)) { |
|
550 | + try { |
|
551 | + $this->getLoader()->loadPlugin($callback); |
|
552 | + } |
|
553 | + catch (Exception $e) { |
|
554 | + if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) { |
|
555 | + throw new Exception( |
|
556 | + 'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should |
|
557 | 557 | not be used, please only use "' . str_replace('Dwoo_Filter_', '', $callback) . '"' |
558 | - ); |
|
559 | - } else { |
|
560 | - throw new Exception( |
|
561 | - 'Wrong filter name : ' . $callback . ', when using autoload the filter must |
|
558 | + ); |
|
559 | + } else { |
|
560 | + throw new Exception( |
|
561 | + 'Wrong filter name : ' . $callback . ', when using autoload the filter must |
|
562 | 562 | be in one of your plugin dir as "name.php" containig a class or function named |
563 | 563 | "Dwoo_Filter_name"' |
564 | - ); |
|
565 | - } |
|
566 | - } |
|
567 | - } |
|
568 | - |
|
569 | - if (class_exists($class)) { |
|
570 | - $callback = array(new $class($this), 'process'); |
|
571 | - } elseif (function_exists($class)) { |
|
572 | - $callback = $class; |
|
573 | - } else { |
|
574 | - throw new Exception( |
|
575 | - 'Wrong filter name : ' . $callback . ', when using autoload the filter must be in |
|
564 | + ); |
|
565 | + } |
|
566 | + } |
|
567 | + } |
|
568 | + |
|
569 | + if (class_exists($class)) { |
|
570 | + $callback = array(new $class($this), 'process'); |
|
571 | + } elseif (function_exists($class)) { |
|
572 | + $callback = $class; |
|
573 | + } else { |
|
574 | + throw new Exception( |
|
575 | + 'Wrong filter name : ' . $callback . ', when using autoload the filter must be in |
|
576 | 576 | one of your plugin dir as "name.php" containig a class or function named "Dwoo_Filter_name"' |
577 | - ); |
|
578 | - } |
|
579 | - |
|
580 | - $this->filters[] = $callback; |
|
581 | - } else { |
|
582 | - $this->filters[] = $callback; |
|
583 | - } |
|
584 | - } |
|
585 | - |
|
586 | - /** |
|
587 | - * Removes a filter. |
|
588 | - * |
|
589 | - * @param mixed $callback callback or filter name if it was autoloaded |
|
590 | - * |
|
591 | - * @return void |
|
592 | - */ |
|
593 | - public function removeFilter($callback) |
|
594 | - { |
|
595 | - if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS. 'Filter' . self::toCamelCase($callback), $this->filters, |
|
596 | - true)) !== |
|
597 | - false) { |
|
598 | - unset($this->filters[$index]); |
|
599 | - } elseif (($index = array_search($callback, $this->filters, true)) !== false) { |
|
600 | - unset($this->filters[$index]); |
|
601 | - } else { |
|
602 | - $class = self::NAMESPACE_PLUGINS_FILTERS . 'Filter' . $callback; |
|
603 | - foreach ($this->filters as $index => $filter) { |
|
604 | - if (is_array($filter) && $filter[0] instanceof $class) { |
|
605 | - unset($this->filters[$index]); |
|
606 | - break; |
|
607 | - } |
|
608 | - } |
|
609 | - } |
|
610 | - } |
|
611 | - |
|
612 | - /** |
|
613 | - * Adds a resource or overrides a default one. |
|
614 | - * |
|
615 | - * @param string $name the resource name |
|
616 | - * @param string $class the resource class (which must implement ITemplate) |
|
617 | - * @param callback $compilerFactory the compiler factory callback, a function that must return a compiler instance |
|
618 | - * used to compile this resource, if none is provided. by default it will produce |
|
619 | - * a Compiler object |
|
620 | - * |
|
621 | - * @return void |
|
622 | - * @throws Exception |
|
623 | - */ |
|
624 | - public function addResource($name, $class, $compilerFactory = null) |
|
625 | - { |
|
626 | - if (strlen($name) < 2) { |
|
627 | - throw new Exception('Resource names must be at least two-character long to avoid conflicts with Windows paths'); |
|
628 | - } |
|
629 | - |
|
630 | - if (!class_exists($class)) { |
|
631 | - throw new Exception('Resource class does not exist'); |
|
632 | - } |
|
633 | - |
|
634 | - $interfaces = class_implements($class); |
|
635 | - if (in_array('Dwoo\ITemplate', $interfaces) === false) { |
|
636 | - throw new Exception('Resource class must implement ITemplate'); |
|
637 | - } |
|
638 | - |
|
639 | - $this->resources[$name] = array( |
|
640 | - 'class' => $class, |
|
641 | - 'compiler' => $compilerFactory |
|
642 | - ); |
|
643 | - } |
|
644 | - |
|
645 | - /** |
|
646 | - * Removes a custom resource. |
|
647 | - * |
|
648 | - * @param string $name the resource name |
|
649 | - * |
|
650 | - * @return void |
|
651 | - */ |
|
652 | - public function removeResource($name) |
|
653 | - { |
|
654 | - unset($this->resources[$name]); |
|
655 | - if ($name === 'file') { |
|
656 | - $this->resources['file'] = array( |
|
657 | - 'class' => 'Dwoo\Template\File', |
|
658 | - 'compiler' => null |
|
659 | - ); |
|
660 | - } |
|
661 | - } |
|
662 | - |
|
663 | - /** |
|
664 | - * Sets the loader object to use to load plugins. |
|
665 | - * |
|
666 | - * @param ILoader $loader loader |
|
667 | - * |
|
668 | - * @return void |
|
669 | - */ |
|
670 | - public function setLoader(ILoader $loader) |
|
671 | - { |
|
672 | - $this->loader = $loader; |
|
673 | - } |
|
674 | - |
|
675 | - /** |
|
676 | - * Returns the current loader object or a default one if none is currently found. |
|
677 | - * |
|
678 | - * @return ILoader|Loader |
|
679 | - */ |
|
680 | - public function getLoader() |
|
681 | - { |
|
682 | - if ($this->loader === null) { |
|
683 | - $this->loader = new Loader($this->getCompileDir()); |
|
684 | - } |
|
685 | - |
|
686 | - return $this->loader; |
|
687 | - } |
|
688 | - |
|
689 | - /** |
|
690 | - * Returns the custom plugins loaded. |
|
691 | - * Used by the ITemplate classes to pass the custom plugins to their ICompiler instance. |
|
692 | - * |
|
693 | - * @return array |
|
694 | - */ |
|
695 | - public function getCustomPlugins() |
|
696 | - { |
|
697 | - return $this->plugins; |
|
698 | - } |
|
699 | - |
|
700 | - /** |
|
701 | - * Return a specified custom plugin loaded by his name. |
|
702 | - * Used by the compiler, for executing a Closure. |
|
703 | - * |
|
704 | - * @param string $name |
|
705 | - * |
|
706 | - * @return mixed|null |
|
707 | - */ |
|
708 | - public function getCustomPlugin($name) |
|
709 | - { |
|
710 | - if (isset($this->plugins[$name])) { |
|
711 | - return $this->plugins[$name]['callback']; |
|
712 | - } |
|
713 | - |
|
714 | - return null; |
|
715 | - } |
|
716 | - |
|
717 | - /** |
|
718 | - * Returns the cache directory with a trailing DIRECTORY_SEPARATOR. |
|
719 | - * |
|
720 | - * @return string |
|
721 | - */ |
|
722 | - public function getCacheDir() |
|
723 | - { |
|
724 | - if ($this->cacheDir === null) { |
|
725 | - $this->setCacheDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR); |
|
726 | - } |
|
727 | - |
|
728 | - return $this->cacheDir; |
|
729 | - } |
|
730 | - |
|
731 | - /** |
|
732 | - * Sets the cache directory and automatically appends a DIRECTORY_SEPARATOR. |
|
733 | - * |
|
734 | - * @param string $dir the cache directory |
|
735 | - * |
|
736 | - * @return void |
|
737 | - * @throws Exception |
|
738 | - */ |
|
739 | - public function setCacheDir($dir) |
|
740 | - { |
|
741 | - $this->cacheDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR; |
|
742 | - if (is_writable($this->cacheDir) === false) { |
|
743 | - throw new Exception('The cache directory must be writable, chmod "' . $this->cacheDir . '" to make it writable'); |
|
744 | - } |
|
745 | - } |
|
746 | - |
|
747 | - /** |
|
748 | - * Returns the compile directory with a trailing DIRECTORY_SEPARATOR. |
|
749 | - * |
|
750 | - * @return string |
|
751 | - */ |
|
752 | - public function getCompileDir() |
|
753 | - { |
|
754 | - if ($this->compileDir === null) { |
|
755 | - $this->setCompileDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'compiled' . DIRECTORY_SEPARATOR); |
|
756 | - } |
|
757 | - |
|
758 | - return $this->compileDir; |
|
759 | - } |
|
760 | - |
|
761 | - /** |
|
762 | - * Sets the compile directory and automatically appends a DIRECTORY_SEPARATOR. |
|
763 | - * |
|
764 | - * @param string $dir the compile directory |
|
765 | - * |
|
766 | - * @return void |
|
767 | - * @throws Exception |
|
768 | - */ |
|
769 | - public function setCompileDir($dir) |
|
770 | - { |
|
771 | - $this->compileDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR; |
|
772 | - if (is_writable($this->compileDir) === false) { |
|
773 | - throw new Exception('The compile directory must be writable, chmod "' . $this->compileDir . '" to make it writable'); |
|
774 | - } |
|
775 | - } |
|
776 | - |
|
777 | - /** |
|
778 | - * Returns the default cache time that is used with templates that do not have a cache time set. |
|
779 | - * |
|
780 | - * @return int the duration in seconds |
|
781 | - */ |
|
782 | - public function getCacheTime() |
|
783 | - { |
|
784 | - return $this->cacheTime; |
|
785 | - } |
|
786 | - |
|
787 | - /** |
|
788 | - * Sets the default cache time to use with templates that do not have a cache time set. |
|
789 | - * |
|
790 | - * @param int $seconds the duration in seconds |
|
791 | - * |
|
792 | - * @return void |
|
793 | - */ |
|
794 | - public function setCacheTime($seconds) |
|
795 | - { |
|
796 | - $this->cacheTime = (int)$seconds; |
|
797 | - } |
|
798 | - |
|
799 | - /** |
|
800 | - * Returns the character set used by the string manipulation plugins. |
|
801 | - * the charset is automatically lowercased |
|
802 | - * |
|
803 | - * @return string |
|
804 | - */ |
|
805 | - public function getCharset() |
|
806 | - { |
|
807 | - return $this->charset; |
|
808 | - } |
|
809 | - |
|
810 | - /** |
|
811 | - * Sets the character set used by the string manipulation plugins. |
|
812 | - * the charset will be automatically lowercased |
|
813 | - * |
|
814 | - * @param string $charset the character set |
|
815 | - * |
|
816 | - * @return void |
|
817 | - */ |
|
818 | - public function setCharset($charset) |
|
819 | - { |
|
820 | - $this->charset = strtolower((string)$charset); |
|
821 | - } |
|
822 | - |
|
823 | - /** |
|
824 | - * Returns the current template being rendered, when applicable, or null. |
|
825 | - * |
|
826 | - * @return ITemplate|null |
|
827 | - */ |
|
828 | - public function getTemplate() |
|
829 | - { |
|
830 | - return $this->template; |
|
831 | - } |
|
832 | - |
|
833 | - /** |
|
834 | - * Sets the current template being rendered. |
|
835 | - * |
|
836 | - * @param ITemplate $tpl template object |
|
837 | - * |
|
838 | - * @return void |
|
839 | - */ |
|
840 | - public function setTemplate(ITemplate $tpl) |
|
841 | - { |
|
842 | - $this->template = $tpl; |
|
843 | - } |
|
844 | - |
|
845 | - /** |
|
846 | - * Sets the default compiler factory function for the given resource name. |
|
847 | - * a compiler factory must return a ICompiler object pre-configured to fit your needs |
|
848 | - * |
|
849 | - * @param string $resourceName the resource name (i.e. file, string) |
|
850 | - * @param callback $compilerFactory the compiler factory callback |
|
851 | - * |
|
852 | - * @return void |
|
853 | - */ |
|
854 | - public function setDefaultCompilerFactory($resourceName, $compilerFactory) |
|
855 | - { |
|
856 | - $this->resources[$resourceName]['compiler'] = $compilerFactory; |
|
857 | - } |
|
858 | - |
|
859 | - /** |
|
860 | - * Returns the default compiler factory function for the given resource name. |
|
861 | - * |
|
862 | - * @param string $resourceName the resource name |
|
863 | - * |
|
864 | - * @return callback the compiler factory callback |
|
865 | - */ |
|
866 | - public function getDefaultCompilerFactory($resourceName) |
|
867 | - { |
|
868 | - return $this->resources[$resourceName]['compiler']; |
|
869 | - } |
|
870 | - |
|
871 | - /** |
|
872 | - * Sets the security policy object to enforce some php security settings. |
|
873 | - * use this if untrusted persons can modify templates |
|
874 | - * |
|
875 | - * @param SecurityPolicy $policy the security policy object |
|
876 | - * |
|
877 | - * @return void |
|
878 | - */ |
|
879 | - public function setSecurityPolicy(SecurityPolicy $policy = null) |
|
880 | - { |
|
881 | - $this->securityPolicy = $policy; |
|
882 | - } |
|
883 | - |
|
884 | - /** |
|
885 | - * Returns the current security policy object or null by default. |
|
886 | - * |
|
887 | - * @return SecurityPolicy|null the security policy object if any |
|
888 | - */ |
|
889 | - public function getSecurityPolicy() |
|
890 | - { |
|
891 | - return $this->securityPolicy; |
|
892 | - } |
|
893 | - |
|
894 | - /** |
|
895 | - * Sets the object that must be used as a plugin proxy when plugin can't be found |
|
896 | - * by dwoo's loader. |
|
897 | - * |
|
898 | - * @param IPluginProxy $pluginProxy the proxy object |
|
899 | - * |
|
900 | - * @return void |
|
901 | - */ |
|
902 | - public function setPluginProxy(IPluginProxy $pluginProxy) |
|
903 | - { |
|
904 | - $this->pluginProxy = $pluginProxy; |
|
905 | - } |
|
906 | - |
|
907 | - /** |
|
908 | - * Returns the current plugin proxy object or null by default. |
|
909 | - * |
|
910 | - * @return IPluginProxy |
|
911 | - */ |
|
912 | - public function getPluginProxy() |
|
913 | - { |
|
914 | - return $this->pluginProxy; |
|
915 | - } |
|
916 | - |
|
917 | - /** |
|
918 | - * Checks whether the given template is cached or not. |
|
919 | - * |
|
920 | - * @param ITemplate $tpl the template object |
|
921 | - * |
|
922 | - * @return bool |
|
923 | - */ |
|
924 | - public function isCached(ITemplate $tpl) |
|
925 | - { |
|
926 | - return is_string($tpl->getCachedTemplate($this)); |
|
927 | - } |
|
928 | - |
|
929 | - /** |
|
930 | - * Clear templates inside the compiled directory. |
|
931 | - * |
|
932 | - * @return int |
|
933 | - */ |
|
934 | - public function clearCompiled() |
|
935 | - { |
|
936 | - $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCompileDir()), \RecursiveIteratorIterator::SELF_FIRST); |
|
937 | - $count = 0; |
|
938 | - foreach ($iterator as $file) { |
|
939 | - if ($file->isFile()) { |
|
940 | - $count += unlink($file->__toString()) ? 1 : 0; |
|
941 | - } |
|
942 | - } |
|
943 | - |
|
944 | - return $count; |
|
945 | - } |
|
946 | - |
|
947 | - /** |
|
948 | - * Clears the cached templates if they are older than the given time. |
|
949 | - * |
|
950 | - * @param int $olderThan minimum time (in seconds) required for a cached template to be cleared |
|
951 | - * |
|
952 | - * @return int the amount of templates cleared |
|
953 | - */ |
|
954 | - public function clearCache($olderThan = - 1) |
|
955 | - { |
|
956 | - $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCacheDir()), \RecursiveIteratorIterator::SELF_FIRST); |
|
957 | - $expired = time() - $olderThan; |
|
958 | - $count = 0; |
|
959 | - foreach ($iterator as $file) { |
|
960 | - if ($file->isFile() && $file->getCTime() < $expired) { |
|
961 | - $count += unlink((string)$file) ? 1 : 0; |
|
962 | - } |
|
963 | - } |
|
964 | - |
|
965 | - return $count; |
|
966 | - } |
|
967 | - |
|
968 | - /** |
|
969 | - * Fetches a template object of the given resource. |
|
970 | - * |
|
971 | - * @param string $resourceName the resource name (i.e. file, string) |
|
972 | - * @param string $resourceId the resource identifier (i.e. file path) |
|
973 | - * @param int $cacheTime the cache time setting for this resource |
|
974 | - * @param string $cacheId the unique cache identifier |
|
975 | - * @param string $compileId the unique compiler identifier |
|
976 | - * @param ITemplate $parentTemplate the parent template |
|
977 | - * |
|
978 | - * @return ITemplate |
|
979 | - * @throws Exception |
|
980 | - */ |
|
981 | - public function templateFactory($resourceName, $resourceId, $cacheTime = null, $cacheId = null, $compileId = null, ITemplate $parentTemplate = null) |
|
982 | - { |
|
983 | - if (isset($this->resources[$resourceName])) { |
|
984 | - /** |
|
985 | - * Interface ITemplate |
|
986 | - * |
|
987 | - * @var ITemplate $class |
|
988 | - */ |
|
989 | - $class = $this->resources[$resourceName]['class']; |
|
990 | - |
|
991 | - return $class::templateFactory($this, $resourceId, $cacheTime, $cacheId, $compileId, $parentTemplate); |
|
992 | - } |
|
993 | - |
|
994 | - throw new Exception('Unknown resource type : ' . $resourceName); |
|
995 | - } |
|
996 | - |
|
997 | - /** |
|
998 | - * Checks if the input is an array or arrayaccess object, optionally it can also check if it's |
|
999 | - * empty. |
|
1000 | - * |
|
1001 | - * @param mixed $value the variable to check |
|
1002 | - * @param bool $checkIsEmpty if true, the function will also check if the array|arrayaccess is empty, |
|
1003 | - * and return true only if it's not empty |
|
1004 | - * |
|
1005 | - * @return int|bool true if it's an array|arrayaccess (or the item count if $checkIsEmpty is true) or false if it's |
|
1006 | - * not an array|arrayaccess (or 0 if $checkIsEmpty is true) |
|
1007 | - */ |
|
1008 | - public function isArray($value, $checkIsEmpty = false) |
|
1009 | - { |
|
1010 | - if (is_array($value) === true || $value instanceof ArrayAccess) { |
|
1011 | - if ($checkIsEmpty === false) { |
|
1012 | - return true; |
|
1013 | - } |
|
1014 | - |
|
1015 | - return $this->count($value); |
|
1016 | - } |
|
1017 | - |
|
1018 | - return false; |
|
1019 | - } |
|
1020 | - |
|
1021 | - /** |
|
1022 | - * Checks if the input is an array or a traversable object, optionally it can also check if it's |
|
1023 | - * empty. |
|
1024 | - * |
|
1025 | - * @param mixed $value the variable to check |
|
1026 | - * @param bool $checkIsEmpty if true, the function will also check if the array|traversable is empty, |
|
1027 | - * and return true only if it's not empty |
|
1028 | - * |
|
1029 | - * @return int|bool true if it's an array|traversable (or the item count if $checkIsEmpty is true) or false if it's |
|
1030 | - * not an array|traversable (or 0 if $checkIsEmpty is true) |
|
1031 | - */ |
|
1032 | - public function isTraversable($value, $checkIsEmpty = false) |
|
1033 | - { |
|
1034 | - if (is_array($value) === true) { |
|
1035 | - if ($checkIsEmpty === false) { |
|
1036 | - return true; |
|
1037 | - } else { |
|
1038 | - return count($value) > 0; |
|
1039 | - } |
|
1040 | - } elseif ($value instanceof Traversable) { |
|
1041 | - if ($checkIsEmpty === false) { |
|
1042 | - return true; |
|
1043 | - } else { |
|
1044 | - return $this->count($value); |
|
1045 | - } |
|
1046 | - } |
|
1047 | - |
|
1048 | - return false; |
|
1049 | - } |
|
1050 | - |
|
1051 | - /** |
|
1052 | - * Counts an array or arrayaccess/traversable object. |
|
1053 | - * |
|
1054 | - * @param mixed $value the value to count |
|
1055 | - * |
|
1056 | - * @return int|bool the count for arrays and objects that implement countable, true for other objects that don't, |
|
1057 | - * and 0 for empty elements |
|
1058 | - */ |
|
1059 | - public function count($value) |
|
1060 | - { |
|
1061 | - if (is_array($value) === true || $value instanceof Countable) { |
|
1062 | - return count($value); |
|
1063 | - } elseif ($value instanceof ArrayAccess) { |
|
1064 | - if ($value->offsetExists(0)) { |
|
1065 | - return true; |
|
1066 | - } |
|
1067 | - } elseif ($value instanceof Iterator) { |
|
1068 | - $value->rewind(); |
|
1069 | - if ($value->valid()) { |
|
1070 | - return true; |
|
1071 | - } |
|
1072 | - } elseif ($value instanceof Traversable) { |
|
1073 | - foreach ($value as $dummy) { |
|
1074 | - return true; |
|
1075 | - } |
|
1076 | - } |
|
1077 | - |
|
1078 | - return 0; |
|
1079 | - } |
|
1080 | - |
|
1081 | - /** |
|
1082 | - * Triggers a dwoo error. |
|
1083 | - * |
|
1084 | - * @param string $message the error message |
|
1085 | - * @param int $level the error level, one of the PHP's E_* constants |
|
1086 | - * |
|
1087 | - * @return void |
|
1088 | - */ |
|
1089 | - public function triggerError($message, $level = E_USER_NOTICE) |
|
1090 | - { |
|
1091 | - if (!($tplIdentifier = $this->template->getResourceIdentifier())) { |
|
1092 | - $tplIdentifier = $this->template->getResourceName(); |
|
1093 | - } |
|
1094 | - trigger_error('Dwoo error (in ' . $tplIdentifier . ') : ' . $message, $level); |
|
1095 | - } |
|
1096 | - |
|
1097 | - /** |
|
1098 | - * Adds a block to the block stack. |
|
1099 | - * |
|
1100 | - * @param string $blockName the block name (without Dwoo_Plugin_ prefix) |
|
1101 | - * @param array $args the arguments to be passed to the block's init() function |
|
1102 | - * |
|
1103 | - * @return BlockPlugin the newly created block |
|
1104 | - */ |
|
1105 | - public function addStack($blockName, array $args = array()) |
|
1106 | - { |
|
1107 | - if (isset($this->plugins[$blockName])) { |
|
1108 | - $class = $this->plugins[$blockName]['class']; |
|
1109 | - } else { |
|
1110 | - $class = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . self::toCamelCase($blockName); |
|
1111 | - } |
|
1112 | - |
|
1113 | - if ($this->curBlock !== null) { |
|
1114 | - $this->curBlock->buffer(ob_get_contents()); |
|
1115 | - ob_clean(); |
|
1116 | - } else { |
|
1117 | - $this->buffer .= ob_get_contents(); |
|
1118 | - ob_clean(); |
|
1119 | - } |
|
1120 | - |
|
1121 | - $block = new $class($this); |
|
1122 | - |
|
1123 | - call_user_func_array(array($block, 'init'), $args); |
|
1124 | - |
|
1125 | - $this->stack[] = $this->curBlock = $block; |
|
1126 | - |
|
1127 | - return $block; |
|
1128 | - } |
|
1129 | - |
|
1130 | - /** |
|
1131 | - * Removes the plugin at the top of the block stack. |
|
1132 | - * Calls the block buffer() function, followed by a call to end() and finally a call to process() |
|
1133 | - * |
|
1134 | - * @return void |
|
1135 | - */ |
|
1136 | - public function delStack() |
|
1137 | - { |
|
1138 | - $args = func_get_args(); |
|
1139 | - |
|
1140 | - $this->curBlock->buffer(ob_get_contents()); |
|
1141 | - ob_clean(); |
|
1142 | - |
|
1143 | - call_user_func_array(array($this->curBlock, 'end'), $args); |
|
1144 | - |
|
1145 | - $tmp = array_pop($this->stack); |
|
1146 | - |
|
1147 | - if (count($this->stack) > 0) { |
|
1148 | - $this->curBlock = end($this->stack); |
|
1149 | - $this->curBlock->buffer($tmp->process()); |
|
1150 | - } else { |
|
1151 | - if ($this->buffer !== '') { |
|
1152 | - echo $this->buffer; |
|
1153 | - $this->buffer = ''; |
|
1154 | - } |
|
1155 | - $this->curBlock = null; |
|
1156 | - echo $tmp->process(); |
|
1157 | - } |
|
1158 | - |
|
1159 | - unset($tmp); |
|
1160 | - } |
|
1161 | - |
|
1162 | - /** |
|
1163 | - * Returns the parent block of the given block. |
|
1164 | - * |
|
1165 | - * @param BlockPlugin $block the block class plugin |
|
1166 | - * |
|
1167 | - * @return BlockPlugin|false if the given block isn't in the stack |
|
1168 | - */ |
|
1169 | - public function getParentBlock(BlockPlugin $block) |
|
1170 | - { |
|
1171 | - $index = array_search($block, $this->stack, true); |
|
1172 | - if ($index !== false && $index > 0) { |
|
1173 | - return $this->stack[$index - 1]; |
|
1174 | - } |
|
1175 | - |
|
1176 | - return false; |
|
1177 | - } |
|
1178 | - |
|
1179 | - /** |
|
1180 | - * Finds the closest block of the given type, starting at the top of the stack. |
|
1181 | - * |
|
1182 | - * @param string $type the type of plugin you want to find |
|
1183 | - * |
|
1184 | - * @return BlockPlugin|false if no plugin of such type is in the stack |
|
1185 | - */ |
|
1186 | - public function findBlock($type) |
|
1187 | - { |
|
1188 | - if (isset($this->plugins[$type])) { |
|
1189 | - $type = $this->plugins[$type]['class']; |
|
1190 | - } else { |
|
1191 | - $type = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin_' . str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin', |
|
1192 | - '', $type); |
|
1193 | - } |
|
1194 | - |
|
1195 | - $keys = array_keys($this->stack); |
|
1196 | - while (($key = array_pop($keys)) !== false) { |
|
1197 | - if ($this->stack[$key] instanceof $type) { |
|
1198 | - return $this->stack[$key]; |
|
1199 | - } |
|
1200 | - } |
|
1201 | - |
|
1202 | - return false; |
|
1203 | - } |
|
1204 | - |
|
1205 | - /** |
|
1206 | - * Returns a Plugin of the given class. |
|
1207 | - * this is so a single instance of every class plugin is created at each template run, |
|
1208 | - * allowing class plugins to have "per-template-run" static variables |
|
1209 | - * |
|
1210 | - * @param string $class the class name |
|
1211 | - * |
|
1212 | - * @return mixed an object of the given class |
|
1213 | - */ |
|
1214 | - public function getObjectPlugin($class) |
|
1215 | - { |
|
1216 | - if (isset($this->runtimePlugins[$class])) { |
|
1217 | - return $this->runtimePlugins[$class]; |
|
1218 | - } |
|
1219 | - |
|
1220 | - return $this->runtimePlugins[$class] = new $class($this); |
|
1221 | - } |
|
1222 | - |
|
1223 | - /** |
|
1224 | - * Calls the process() method of the given class-plugin name. |
|
1225 | - * |
|
1226 | - * @param string $plugName the class plugin name (without Dwoo_Plugin_ prefix) |
|
1227 | - * @param array $params an array of parameters to send to the process() method |
|
1228 | - * |
|
1229 | - * @return string the process() return value |
|
1230 | - */ |
|
1231 | - public function classCall($plugName, array $params = array()) |
|
1232 | - { |
|
1233 | - $class = self::toCamelCase($plugName); |
|
1234 | - $plugin = $this->getObjectPlugin($class); |
|
1235 | - |
|
1236 | - return call_user_func_array(array($plugin, 'process'), $params); |
|
1237 | - } |
|
1238 | - |
|
1239 | - /** |
|
1240 | - * Calls a php function. |
|
1241 | - * |
|
1242 | - * @param string $callback the function to call |
|
1243 | - * @param array $params an array of parameters to send to the function |
|
1244 | - * |
|
1245 | - * @return mixed the return value of the called function |
|
1246 | - */ |
|
1247 | - public function arrayMap($callback, array $params) |
|
1248 | - { |
|
1249 | - if ($params[0] === $this) { |
|
1250 | - $addThis = true; |
|
1251 | - array_shift($params); |
|
1252 | - } |
|
1253 | - if ((is_array($params[0]) || ($params[0] instanceof Iterator && $params[0] instanceof ArrayAccess))) { |
|
1254 | - if (empty($params[0])) { |
|
1255 | - return $params[0]; |
|
1256 | - } |
|
1257 | - |
|
1258 | - // array map |
|
1259 | - $out = array(); |
|
1260 | - $cnt = count($params); |
|
1261 | - |
|
1262 | - if (isset($addThis)) { |
|
1263 | - array_unshift($params, $this); |
|
1264 | - $items = $params[1]; |
|
1265 | - $keys = array_keys($items); |
|
1266 | - |
|
1267 | - if (is_string($callback) === false) { |
|
1268 | - while (($i = array_shift($keys)) !== null) { |
|
1269 | - $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params); |
|
1270 | - } |
|
1271 | - } elseif ($cnt === 1) { |
|
1272 | - while (($i = array_shift($keys)) !== null) { |
|
1273 | - $out[] = $callback($this, $items[$i]); |
|
1274 | - } |
|
1275 | - } elseif ($cnt === 2) { |
|
1276 | - while (($i = array_shift($keys)) !== null) { |
|
1277 | - $out[] = $callback($this, $items[$i], $params[2]); |
|
1278 | - } |
|
1279 | - } elseif ($cnt === 3) { |
|
1280 | - while (($i = array_shift($keys)) !== null) { |
|
1281 | - $out[] = $callback($this, $items[$i], $params[2], $params[3]); |
|
1282 | - } |
|
1283 | - } else { |
|
1284 | - while (($i = array_shift($keys)) !== null) { |
|
1285 | - $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params); |
|
1286 | - } |
|
1287 | - } |
|
1288 | - } else { |
|
1289 | - $items = $params[0]; |
|
1290 | - $keys = array_keys($items); |
|
1291 | - |
|
1292 | - if (is_string($callback) === false) { |
|
1293 | - while (($i = array_shift($keys)) !== null) { |
|
1294 | - $out[] = call_user_func_array($callback, array($items[$i]) + $params); |
|
1295 | - } |
|
1296 | - } elseif ($cnt === 1) { |
|
1297 | - while (($i = array_shift($keys)) !== null) { |
|
1298 | - $out[] = $callback($items[$i]); |
|
1299 | - } |
|
1300 | - } elseif ($cnt === 2) { |
|
1301 | - while (($i = array_shift($keys)) !== null) { |
|
1302 | - $out[] = $callback($items[$i], $params[1]); |
|
1303 | - } |
|
1304 | - } elseif ($cnt === 3) { |
|
1305 | - while (($i = array_shift($keys)) !== null) { |
|
1306 | - $out[] = $callback($items[$i], $params[1], $params[2]); |
|
1307 | - } |
|
1308 | - } elseif ($cnt === 4) { |
|
1309 | - while (($i = array_shift($keys)) !== null) { |
|
1310 | - $out[] = $callback($items[$i], $params[1], $params[2], $params[3]); |
|
1311 | - } |
|
1312 | - } else { |
|
1313 | - while (($i = array_shift($keys)) !== null) { |
|
1314 | - $out[] = call_user_func_array($callback, array($items[$i]) + $params); |
|
1315 | - } |
|
1316 | - } |
|
1317 | - } |
|
1318 | - |
|
1319 | - return $out; |
|
1320 | - } else { |
|
1321 | - return $params[0]; |
|
1322 | - } |
|
1323 | - } |
|
1324 | - |
|
1325 | - /** |
|
1326 | - * Reads a variable into the given data array. |
|
1327 | - * |
|
1328 | - * @param string $varstr the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property") |
|
1329 | - * @param mixed $data the data array or object to read from |
|
1330 | - * @param bool $safeRead if true, the function will check whether the index exists to prevent any notices from |
|
1331 | - * being output |
|
1332 | - * |
|
1333 | - * @return mixed |
|
1334 | - */ |
|
1335 | - public function readVarInto($varstr, $data, $safeRead = false) |
|
1336 | - { |
|
1337 | - if ($data === null) { |
|
1338 | - return null; |
|
1339 | - } |
|
1340 | - |
|
1341 | - if (is_array($varstr) === false) { |
|
1342 | - preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m); |
|
1343 | - } else { |
|
1344 | - $m = $varstr; |
|
1345 | - } |
|
1346 | - unset($varstr); |
|
1347 | - |
|
1348 | - while (list($k, $sep) = each($m[1])) { |
|
1349 | - if ($sep === '.' || $sep === '[' || $sep === '') { |
|
1350 | - // strip enclosing quotes if present |
|
1351 | - $m[2][$k] = preg_replace('#^(["\']?)(.*?)\1$#', '$2', $m[2][$k]); |
|
1352 | - |
|
1353 | - if ((is_array($data) || $data instanceof ArrayAccess) && ($safeRead === false || isset($data[$m[2][$k]]))) { |
|
1354 | - $data = $data[$m[2][$k]]; |
|
1355 | - } else { |
|
1356 | - return null; |
|
1357 | - } |
|
1358 | - } else { |
|
1359 | - if (is_object($data) && ($safeRead === false || isset($data->$m[2][$k]))) { |
|
1360 | - $data = $data->$m[2][$k]; |
|
1361 | - } else { |
|
1362 | - return null; |
|
1363 | - } |
|
1364 | - } |
|
1365 | - } |
|
1366 | - |
|
1367 | - return $data; |
|
1368 | - } |
|
1369 | - |
|
1370 | - /** |
|
1371 | - * Reads a variable into the parent scope. |
|
1372 | - * |
|
1373 | - * @param int $parentLevels the amount of parent levels to go from the current scope |
|
1374 | - * @param string $varstr the variable string, using dwoo variable syntax (i.e. |
|
1375 | - * "var.subvar[subsubvar]->property") |
|
1376 | - * |
|
1377 | - * @return mixed |
|
1378 | - */ |
|
1379 | - public function readParentVar($parentLevels, $varstr = null) |
|
1380 | - { |
|
1381 | - $tree = $this->scopeTree; |
|
1382 | - $cur = $this->data; |
|
1383 | - |
|
1384 | - while ($parentLevels -- !== 0) { |
|
1385 | - array_pop($tree); |
|
1386 | - } |
|
1387 | - |
|
1388 | - while (($i = array_shift($tree)) !== null) { |
|
1389 | - if (is_object($cur)) { |
|
1390 | - $cur = $cur->$i; |
|
1391 | - } else { |
|
1392 | - $cur = $cur[$i]; |
|
1393 | - } |
|
1394 | - } |
|
1395 | - |
|
1396 | - if ($varstr !== null) { |
|
1397 | - return $this->readVarInto($varstr, $cur); |
|
1398 | - } else { |
|
1399 | - return $cur; |
|
1400 | - } |
|
1401 | - } |
|
1402 | - |
|
1403 | - /** |
|
1404 | - * Reads a variable into the current scope. |
|
1405 | - * |
|
1406 | - * @param string $varstr the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property") |
|
1407 | - * |
|
1408 | - * @return mixed |
|
1409 | - */ |
|
1410 | - public function readVar($varstr) |
|
1411 | - { |
|
1412 | - if (is_array($varstr) === true) { |
|
1413 | - $m = $varstr; |
|
1414 | - unset($varstr); |
|
1415 | - } else { |
|
1416 | - if (strstr($varstr, '.') === false && strstr($varstr, '[') === false && strstr($varstr, '->') === false) { |
|
1417 | - if ($varstr === 'dwoo') { |
|
1418 | - return $this->globals; |
|
1419 | - } elseif ($varstr === '__' || $varstr === '_root') { |
|
1420 | - return $this->data; |
|
1421 | - } elseif ($varstr === '_' || $varstr === '_parent') { |
|
1422 | - $varstr = '.' . $varstr; |
|
1423 | - $tree = $this->scopeTree; |
|
1424 | - $cur = $this->data; |
|
1425 | - array_pop($tree); |
|
1426 | - |
|
1427 | - while (($i = array_shift($tree)) !== null) { |
|
1428 | - if (is_object($cur)) { |
|
1429 | - $cur = $cur->$i; |
|
1430 | - } else { |
|
1431 | - $cur = $cur[$i]; |
|
1432 | - } |
|
1433 | - } |
|
1434 | - |
|
1435 | - return $cur; |
|
1436 | - } |
|
1437 | - |
|
1438 | - $cur = $this->scope; |
|
1439 | - |
|
1440 | - if (isset($cur[$varstr])) { |
|
1441 | - return $cur[$varstr]; |
|
1442 | - } else { |
|
1443 | - return null; |
|
1444 | - } |
|
1445 | - } |
|
1446 | - |
|
1447 | - if (substr($varstr, 0, 1) === '.') { |
|
1448 | - $varstr = 'dwoo' . $varstr; |
|
1449 | - } |
|
1450 | - |
|
1451 | - preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m); |
|
1452 | - } |
|
1453 | - |
|
1454 | - $i = $m[2][0]; |
|
1455 | - if ($i === 'dwoo') { |
|
1456 | - $cur = $this->globals; |
|
1457 | - array_shift($m[2]); |
|
1458 | - array_shift($m[1]); |
|
1459 | - switch ($m[2][0]) { |
|
1460 | - case 'get': |
|
1461 | - $cur = $_GET; |
|
1462 | - break; |
|
1463 | - case 'post': |
|
1464 | - $cur = $_POST; |
|
1465 | - break; |
|
1466 | - case 'session': |
|
1467 | - $cur = $_SESSION; |
|
1468 | - break; |
|
1469 | - case 'cookies': |
|
1470 | - case 'cookie': |
|
1471 | - $cur = $_COOKIE; |
|
1472 | - break; |
|
1473 | - case 'server': |
|
1474 | - $cur = $_SERVER; |
|
1475 | - break; |
|
1476 | - case 'env': |
|
1477 | - $cur = $_ENV; |
|
1478 | - break; |
|
1479 | - case 'request': |
|
1480 | - $cur = $_REQUEST; |
|
1481 | - break; |
|
1482 | - case 'const': |
|
1483 | - array_shift($m[2]); |
|
1484 | - if (defined($m[2][0])) { |
|
1485 | - return constant($m[2][0]); |
|
1486 | - } else { |
|
1487 | - return null; |
|
1488 | - } |
|
1489 | - } |
|
1490 | - if ($cur !== $this->globals) { |
|
1491 | - array_shift($m[2]); |
|
1492 | - array_shift($m[1]); |
|
1493 | - } |
|
1494 | - } elseif ($i === '__' || $i === '_root') { |
|
1495 | - $cur = $this->data; |
|
1496 | - array_shift($m[2]); |
|
1497 | - array_shift($m[1]); |
|
1498 | - } elseif ($i === '_' || $i === '_parent') { |
|
1499 | - $tree = $this->scopeTree; |
|
1500 | - $cur = $this->data; |
|
1501 | - |
|
1502 | - while (true) { |
|
1503 | - array_pop($tree); |
|
1504 | - array_shift($m[2]); |
|
1505 | - array_shift($m[1]); |
|
1506 | - if (current($m[2]) === '_' || current($m[2]) === '_parent') { |
|
1507 | - continue; |
|
1508 | - } |
|
1509 | - |
|
1510 | - while (($i = array_shift($tree)) !== null) { |
|
1511 | - if (is_object($cur)) { |
|
1512 | - $cur = $cur->$i; |
|
1513 | - } else { |
|
1514 | - $cur = $cur[$i]; |
|
1515 | - } |
|
1516 | - } |
|
1517 | - break; |
|
1518 | - } |
|
1519 | - } else { |
|
1520 | - $cur = $this->scope; |
|
1521 | - } |
|
1522 | - |
|
1523 | - while (list($k, $sep) = each($m[1])) { |
|
1524 | - if ($sep === '.' || $sep === '[' || $sep === '') { |
|
1525 | - if ((is_array($cur) || $cur instanceof ArrayAccess) && isset($cur[$m[2][$k]])) { |
|
1526 | - $cur = $cur[$m[2][$k]]; |
|
1527 | - } else { |
|
1528 | - return null; |
|
1529 | - } |
|
1530 | - } elseif ($sep === '->') { |
|
1531 | - if (is_object($cur)) { |
|
1532 | - $cur = $cur->$m[2][$k]; |
|
1533 | - } else { |
|
1534 | - return null; |
|
1535 | - } |
|
1536 | - } else { |
|
1537 | - return null; |
|
1538 | - } |
|
1539 | - } |
|
1540 | - |
|
1541 | - return $cur; |
|
1542 | - } |
|
1543 | - |
|
1544 | - /** |
|
1545 | - * Assign the value to the given variable. |
|
1546 | - * |
|
1547 | - * @param mixed $value the value to assign |
|
1548 | - * @param string $scope the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property") |
|
1549 | - * |
|
1550 | - * @return bool true if assigned correctly or false if a problem occured while parsing the var string |
|
1551 | - */ |
|
1552 | - public function assignInScope($value, $scope) |
|
1553 | - { |
|
1554 | - if (!is_string($scope)) { |
|
1555 | - $this->triggerError('Assignments must be done into strings, (' . gettype($scope) . ') ' . var_export($scope, true) . ' given', E_USER_ERROR); |
|
1556 | - } |
|
1557 | - if (strstr($scope, '.') === false && strstr($scope, '->') === false) { |
|
1558 | - $this->scope[$scope] = $value; |
|
1559 | - } else { |
|
1560 | - // TODO handle _root/_parent scopes ? |
|
1561 | - preg_match_all('#(\[|->|\.)?([^.[\]-]+)\]?#i', $scope, $m); |
|
1562 | - |
|
1563 | - $cur = &$this->scope; |
|
1564 | - $last = array( |
|
1565 | - array_pop($m[1]), |
|
1566 | - array_pop($m[2]) |
|
1567 | - ); |
|
1568 | - |
|
1569 | - while (list($k, $sep) = each($m[1])) { |
|
1570 | - if ($sep === '.' || $sep === '[' || $sep === '') { |
|
1571 | - if (is_array($cur) === false) { |
|
1572 | - $cur = array(); |
|
1573 | - } |
|
1574 | - $cur = &$cur[$m[2][$k]]; |
|
1575 | - } elseif ($sep === '->') { |
|
1576 | - if (is_object($cur) === false) { |
|
1577 | - $cur = new stdClass(); |
|
1578 | - } |
|
1579 | - $cur = &$cur->$m[2][$k]; |
|
1580 | - } else { |
|
1581 | - return false; |
|
1582 | - } |
|
1583 | - } |
|
1584 | - |
|
1585 | - if ($last[0] === '.' || $last[0] === '[' || $last[0] === '') { |
|
1586 | - if (is_array($cur) === false) { |
|
1587 | - $cur = array(); |
|
1588 | - } |
|
1589 | - $cur[$last[1]] = $value; |
|
1590 | - } elseif ($last[0] === '->') { |
|
1591 | - if (is_object($cur) === false) { |
|
1592 | - $cur = new stdClass(); |
|
1593 | - } |
|
1594 | - $cur->$last[1] = $value; |
|
1595 | - } else { |
|
1596 | - return false; |
|
1597 | - } |
|
1598 | - } |
|
1599 | - } |
|
1600 | - |
|
1601 | - /** |
|
1602 | - * Sets the scope to the given scope string or array. |
|
1603 | - * |
|
1604 | - * @param mixed $scope a string i.e. "level1.level2" or an array i.e. array("level1", "level2") |
|
1605 | - * @param bool $absolute if true, the scope is set from the top level scope and not from the current scope |
|
1606 | - * |
|
1607 | - * @return array the current scope tree |
|
1608 | - */ |
|
1609 | - public function setScope($scope, $absolute = false) |
|
1610 | - { |
|
1611 | - $old = $this->scopeTree; |
|
1612 | - |
|
1613 | - if (is_string($scope) === true) { |
|
1614 | - $scope = explode('.', $scope); |
|
1615 | - } |
|
1616 | - |
|
1617 | - if ($absolute === true) { |
|
1618 | - $this->scope = &$this->data; |
|
1619 | - $this->scopeTree = array(); |
|
1620 | - } |
|
1621 | - |
|
1622 | - while (($bit = array_shift($scope)) !== null) { |
|
1623 | - if ($bit === '_' || $bit === '_parent') { |
|
1624 | - array_pop($this->scopeTree); |
|
1625 | - $this->scope = &$this->data; |
|
1626 | - $cnt = count($this->scopeTree); |
|
1627 | - for ($i = 0; $i < $cnt; ++ $i) { |
|
1628 | - $this->scope = &$this->scope[$this->scopeTree[$i]]; |
|
1629 | - } |
|
1630 | - } elseif ($bit === '__' || $bit === '_root') { |
|
1631 | - $this->scope = &$this->data; |
|
1632 | - $this->scopeTree = array(); |
|
1633 | - } elseif (isset($this->scope[$bit])) { |
|
1634 | - if ($this->scope instanceof ArrayAccess) { |
|
1635 | - $tmp = $this->scope[$bit]; |
|
1636 | - $this->scope = &$tmp; |
|
1637 | - } else { |
|
1638 | - $this->scope = &$this->scope[$bit]; |
|
1639 | - } |
|
1640 | - $this->scopeTree[] = $bit; |
|
1641 | - } else { |
|
1642 | - unset($this->scope); |
|
1643 | - $this->scope = null; |
|
1644 | - } |
|
1645 | - } |
|
1646 | - |
|
1647 | - return $old; |
|
1648 | - } |
|
1649 | - |
|
1650 | - /** |
|
1651 | - * Returns the entire data array. |
|
1652 | - * |
|
1653 | - * @return array |
|
1654 | - */ |
|
1655 | - public function getData() |
|
1656 | - { |
|
1657 | - return $this->data; |
|
1658 | - } |
|
1659 | - |
|
1660 | - /** |
|
1661 | - * Sets a return value for the currently running template. |
|
1662 | - * |
|
1663 | - * @param string $name var name |
|
1664 | - * @param mixed $value var value |
|
1665 | - * |
|
1666 | - * @return void |
|
1667 | - */ |
|
1668 | - public function setReturnValue($name, $value) |
|
1669 | - { |
|
1670 | - $this->returnData[$name] = $value; |
|
1671 | - } |
|
1672 | - |
|
1673 | - /** |
|
1674 | - * Retrieves the return values set by the template. |
|
1675 | - * |
|
1676 | - * @return array |
|
1677 | - */ |
|
1678 | - public function getReturnValues() |
|
1679 | - { |
|
1680 | - return $this->returnData; |
|
1681 | - } |
|
1682 | - |
|
1683 | - /** |
|
1684 | - * Returns a reference to the current scope. |
|
1685 | - * |
|
1686 | - * @return mixed |
|
1687 | - */ |
|
1688 | - public function &getScope() |
|
1689 | - { |
|
1690 | - return $this->scope; |
|
1691 | - } |
|
1692 | - |
|
1693 | - /** |
|
1694 | - * Redirects all calls to unexisting to plugin proxy. |
|
1695 | - * |
|
1696 | - * @param string $method the method name |
|
1697 | - * @param array $args array of arguments |
|
1698 | - * |
|
1699 | - * @return mixed |
|
1700 | - * @throws Exception |
|
1701 | - */ |
|
1702 | - public function __call($method, $args) |
|
1703 | - { |
|
1704 | - $proxy = $this->getPluginProxy(); |
|
1705 | - if (!$proxy) { |
|
1706 | - throw new Exception('Call to undefined method ' . __CLASS__ . '::' . $method . '()'); |
|
1707 | - } |
|
1708 | - |
|
1709 | - return call_user_func_array($proxy->getCallback($method), $args); |
|
1710 | - } |
|
1711 | - |
|
1712 | - /** |
|
1713 | - * Convert plugin name from `auto_escape` to `AutoEscape`. |
|
1714 | - * @param string $input |
|
1715 | - * @param string $separator |
|
1716 | - * |
|
1717 | - * @return mixed |
|
1718 | - */ |
|
1719 | - public static function toCamelCase($input, $separator = '_') |
|
1720 | - { |
|
1721 | - return join(array_map('ucfirst', explode($separator, $input))); |
|
1722 | - |
|
1723 | - // TODO >= PHP5.4.32 |
|
1724 | - //return str_replace($separator, '', ucwords($input, $separator)); |
|
1725 | - } |
|
577 | + ); |
|
578 | + } |
|
579 | + |
|
580 | + $this->filters[] = $callback; |
|
581 | + } else { |
|
582 | + $this->filters[] = $callback; |
|
583 | + } |
|
584 | + } |
|
585 | + |
|
586 | + /** |
|
587 | + * Removes a filter. |
|
588 | + * |
|
589 | + * @param mixed $callback callback or filter name if it was autoloaded |
|
590 | + * |
|
591 | + * @return void |
|
592 | + */ |
|
593 | + public function removeFilter($callback) |
|
594 | + { |
|
595 | + if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS. 'Filter' . self::toCamelCase($callback), $this->filters, |
|
596 | + true)) !== |
|
597 | + false) { |
|
598 | + unset($this->filters[$index]); |
|
599 | + } elseif (($index = array_search($callback, $this->filters, true)) !== false) { |
|
600 | + unset($this->filters[$index]); |
|
601 | + } else { |
|
602 | + $class = self::NAMESPACE_PLUGINS_FILTERS . 'Filter' . $callback; |
|
603 | + foreach ($this->filters as $index => $filter) { |
|
604 | + if (is_array($filter) && $filter[0] instanceof $class) { |
|
605 | + unset($this->filters[$index]); |
|
606 | + break; |
|
607 | + } |
|
608 | + } |
|
609 | + } |
|
610 | + } |
|
611 | + |
|
612 | + /** |
|
613 | + * Adds a resource or overrides a default one. |
|
614 | + * |
|
615 | + * @param string $name the resource name |
|
616 | + * @param string $class the resource class (which must implement ITemplate) |
|
617 | + * @param callback $compilerFactory the compiler factory callback, a function that must return a compiler instance |
|
618 | + * used to compile this resource, if none is provided. by default it will produce |
|
619 | + * a Compiler object |
|
620 | + * |
|
621 | + * @return void |
|
622 | + * @throws Exception |
|
623 | + */ |
|
624 | + public function addResource($name, $class, $compilerFactory = null) |
|
625 | + { |
|
626 | + if (strlen($name) < 2) { |
|
627 | + throw new Exception('Resource names must be at least two-character long to avoid conflicts with Windows paths'); |
|
628 | + } |
|
629 | + |
|
630 | + if (!class_exists($class)) { |
|
631 | + throw new Exception('Resource class does not exist'); |
|
632 | + } |
|
633 | + |
|
634 | + $interfaces = class_implements($class); |
|
635 | + if (in_array('Dwoo\ITemplate', $interfaces) === false) { |
|
636 | + throw new Exception('Resource class must implement ITemplate'); |
|
637 | + } |
|
638 | + |
|
639 | + $this->resources[$name] = array( |
|
640 | + 'class' => $class, |
|
641 | + 'compiler' => $compilerFactory |
|
642 | + ); |
|
643 | + } |
|
644 | + |
|
645 | + /** |
|
646 | + * Removes a custom resource. |
|
647 | + * |
|
648 | + * @param string $name the resource name |
|
649 | + * |
|
650 | + * @return void |
|
651 | + */ |
|
652 | + public function removeResource($name) |
|
653 | + { |
|
654 | + unset($this->resources[$name]); |
|
655 | + if ($name === 'file') { |
|
656 | + $this->resources['file'] = array( |
|
657 | + 'class' => 'Dwoo\Template\File', |
|
658 | + 'compiler' => null |
|
659 | + ); |
|
660 | + } |
|
661 | + } |
|
662 | + |
|
663 | + /** |
|
664 | + * Sets the loader object to use to load plugins. |
|
665 | + * |
|
666 | + * @param ILoader $loader loader |
|
667 | + * |
|
668 | + * @return void |
|
669 | + */ |
|
670 | + public function setLoader(ILoader $loader) |
|
671 | + { |
|
672 | + $this->loader = $loader; |
|
673 | + } |
|
674 | + |
|
675 | + /** |
|
676 | + * Returns the current loader object or a default one if none is currently found. |
|
677 | + * |
|
678 | + * @return ILoader|Loader |
|
679 | + */ |
|
680 | + public function getLoader() |
|
681 | + { |
|
682 | + if ($this->loader === null) { |
|
683 | + $this->loader = new Loader($this->getCompileDir()); |
|
684 | + } |
|
685 | + |
|
686 | + return $this->loader; |
|
687 | + } |
|
688 | + |
|
689 | + /** |
|
690 | + * Returns the custom plugins loaded. |
|
691 | + * Used by the ITemplate classes to pass the custom plugins to their ICompiler instance. |
|
692 | + * |
|
693 | + * @return array |
|
694 | + */ |
|
695 | + public function getCustomPlugins() |
|
696 | + { |
|
697 | + return $this->plugins; |
|
698 | + } |
|
699 | + |
|
700 | + /** |
|
701 | + * Return a specified custom plugin loaded by his name. |
|
702 | + * Used by the compiler, for executing a Closure. |
|
703 | + * |
|
704 | + * @param string $name |
|
705 | + * |
|
706 | + * @return mixed|null |
|
707 | + */ |
|
708 | + public function getCustomPlugin($name) |
|
709 | + { |
|
710 | + if (isset($this->plugins[$name])) { |
|
711 | + return $this->plugins[$name]['callback']; |
|
712 | + } |
|
713 | + |
|
714 | + return null; |
|
715 | + } |
|
716 | + |
|
717 | + /** |
|
718 | + * Returns the cache directory with a trailing DIRECTORY_SEPARATOR. |
|
719 | + * |
|
720 | + * @return string |
|
721 | + */ |
|
722 | + public function getCacheDir() |
|
723 | + { |
|
724 | + if ($this->cacheDir === null) { |
|
725 | + $this->setCacheDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR); |
|
726 | + } |
|
727 | + |
|
728 | + return $this->cacheDir; |
|
729 | + } |
|
730 | + |
|
731 | + /** |
|
732 | + * Sets the cache directory and automatically appends a DIRECTORY_SEPARATOR. |
|
733 | + * |
|
734 | + * @param string $dir the cache directory |
|
735 | + * |
|
736 | + * @return void |
|
737 | + * @throws Exception |
|
738 | + */ |
|
739 | + public function setCacheDir($dir) |
|
740 | + { |
|
741 | + $this->cacheDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR; |
|
742 | + if (is_writable($this->cacheDir) === false) { |
|
743 | + throw new Exception('The cache directory must be writable, chmod "' . $this->cacheDir . '" to make it writable'); |
|
744 | + } |
|
745 | + } |
|
746 | + |
|
747 | + /** |
|
748 | + * Returns the compile directory with a trailing DIRECTORY_SEPARATOR. |
|
749 | + * |
|
750 | + * @return string |
|
751 | + */ |
|
752 | + public function getCompileDir() |
|
753 | + { |
|
754 | + if ($this->compileDir === null) { |
|
755 | + $this->setCompileDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'compiled' . DIRECTORY_SEPARATOR); |
|
756 | + } |
|
757 | + |
|
758 | + return $this->compileDir; |
|
759 | + } |
|
760 | + |
|
761 | + /** |
|
762 | + * Sets the compile directory and automatically appends a DIRECTORY_SEPARATOR. |
|
763 | + * |
|
764 | + * @param string $dir the compile directory |
|
765 | + * |
|
766 | + * @return void |
|
767 | + * @throws Exception |
|
768 | + */ |
|
769 | + public function setCompileDir($dir) |
|
770 | + { |
|
771 | + $this->compileDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR; |
|
772 | + if (is_writable($this->compileDir) === false) { |
|
773 | + throw new Exception('The compile directory must be writable, chmod "' . $this->compileDir . '" to make it writable'); |
|
774 | + } |
|
775 | + } |
|
776 | + |
|
777 | + /** |
|
778 | + * Returns the default cache time that is used with templates that do not have a cache time set. |
|
779 | + * |
|
780 | + * @return int the duration in seconds |
|
781 | + */ |
|
782 | + public function getCacheTime() |
|
783 | + { |
|
784 | + return $this->cacheTime; |
|
785 | + } |
|
786 | + |
|
787 | + /** |
|
788 | + * Sets the default cache time to use with templates that do not have a cache time set. |
|
789 | + * |
|
790 | + * @param int $seconds the duration in seconds |
|
791 | + * |
|
792 | + * @return void |
|
793 | + */ |
|
794 | + public function setCacheTime($seconds) |
|
795 | + { |
|
796 | + $this->cacheTime = (int)$seconds; |
|
797 | + } |
|
798 | + |
|
799 | + /** |
|
800 | + * Returns the character set used by the string manipulation plugins. |
|
801 | + * the charset is automatically lowercased |
|
802 | + * |
|
803 | + * @return string |
|
804 | + */ |
|
805 | + public function getCharset() |
|
806 | + { |
|
807 | + return $this->charset; |
|
808 | + } |
|
809 | + |
|
810 | + /** |
|
811 | + * Sets the character set used by the string manipulation plugins. |
|
812 | + * the charset will be automatically lowercased |
|
813 | + * |
|
814 | + * @param string $charset the character set |
|
815 | + * |
|
816 | + * @return void |
|
817 | + */ |
|
818 | + public function setCharset($charset) |
|
819 | + { |
|
820 | + $this->charset = strtolower((string)$charset); |
|
821 | + } |
|
822 | + |
|
823 | + /** |
|
824 | + * Returns the current template being rendered, when applicable, or null. |
|
825 | + * |
|
826 | + * @return ITemplate|null |
|
827 | + */ |
|
828 | + public function getTemplate() |
|
829 | + { |
|
830 | + return $this->template; |
|
831 | + } |
|
832 | + |
|
833 | + /** |
|
834 | + * Sets the current template being rendered. |
|
835 | + * |
|
836 | + * @param ITemplate $tpl template object |
|
837 | + * |
|
838 | + * @return void |
|
839 | + */ |
|
840 | + public function setTemplate(ITemplate $tpl) |
|
841 | + { |
|
842 | + $this->template = $tpl; |
|
843 | + } |
|
844 | + |
|
845 | + /** |
|
846 | + * Sets the default compiler factory function for the given resource name. |
|
847 | + * a compiler factory must return a ICompiler object pre-configured to fit your needs |
|
848 | + * |
|
849 | + * @param string $resourceName the resource name (i.e. file, string) |
|
850 | + * @param callback $compilerFactory the compiler factory callback |
|
851 | + * |
|
852 | + * @return void |
|
853 | + */ |
|
854 | + public function setDefaultCompilerFactory($resourceName, $compilerFactory) |
|
855 | + { |
|
856 | + $this->resources[$resourceName]['compiler'] = $compilerFactory; |
|
857 | + } |
|
858 | + |
|
859 | + /** |
|
860 | + * Returns the default compiler factory function for the given resource name. |
|
861 | + * |
|
862 | + * @param string $resourceName the resource name |
|
863 | + * |
|
864 | + * @return callback the compiler factory callback |
|
865 | + */ |
|
866 | + public function getDefaultCompilerFactory($resourceName) |
|
867 | + { |
|
868 | + return $this->resources[$resourceName]['compiler']; |
|
869 | + } |
|
870 | + |
|
871 | + /** |
|
872 | + * Sets the security policy object to enforce some php security settings. |
|
873 | + * use this if untrusted persons can modify templates |
|
874 | + * |
|
875 | + * @param SecurityPolicy $policy the security policy object |
|
876 | + * |
|
877 | + * @return void |
|
878 | + */ |
|
879 | + public function setSecurityPolicy(SecurityPolicy $policy = null) |
|
880 | + { |
|
881 | + $this->securityPolicy = $policy; |
|
882 | + } |
|
883 | + |
|
884 | + /** |
|
885 | + * Returns the current security policy object or null by default. |
|
886 | + * |
|
887 | + * @return SecurityPolicy|null the security policy object if any |
|
888 | + */ |
|
889 | + public function getSecurityPolicy() |
|
890 | + { |
|
891 | + return $this->securityPolicy; |
|
892 | + } |
|
893 | + |
|
894 | + /** |
|
895 | + * Sets the object that must be used as a plugin proxy when plugin can't be found |
|
896 | + * by dwoo's loader. |
|
897 | + * |
|
898 | + * @param IPluginProxy $pluginProxy the proxy object |
|
899 | + * |
|
900 | + * @return void |
|
901 | + */ |
|
902 | + public function setPluginProxy(IPluginProxy $pluginProxy) |
|
903 | + { |
|
904 | + $this->pluginProxy = $pluginProxy; |
|
905 | + } |
|
906 | + |
|
907 | + /** |
|
908 | + * Returns the current plugin proxy object or null by default. |
|
909 | + * |
|
910 | + * @return IPluginProxy |
|
911 | + */ |
|
912 | + public function getPluginProxy() |
|
913 | + { |
|
914 | + return $this->pluginProxy; |
|
915 | + } |
|
916 | + |
|
917 | + /** |
|
918 | + * Checks whether the given template is cached or not. |
|
919 | + * |
|
920 | + * @param ITemplate $tpl the template object |
|
921 | + * |
|
922 | + * @return bool |
|
923 | + */ |
|
924 | + public function isCached(ITemplate $tpl) |
|
925 | + { |
|
926 | + return is_string($tpl->getCachedTemplate($this)); |
|
927 | + } |
|
928 | + |
|
929 | + /** |
|
930 | + * Clear templates inside the compiled directory. |
|
931 | + * |
|
932 | + * @return int |
|
933 | + */ |
|
934 | + public function clearCompiled() |
|
935 | + { |
|
936 | + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCompileDir()), \RecursiveIteratorIterator::SELF_FIRST); |
|
937 | + $count = 0; |
|
938 | + foreach ($iterator as $file) { |
|
939 | + if ($file->isFile()) { |
|
940 | + $count += unlink($file->__toString()) ? 1 : 0; |
|
941 | + } |
|
942 | + } |
|
943 | + |
|
944 | + return $count; |
|
945 | + } |
|
946 | + |
|
947 | + /** |
|
948 | + * Clears the cached templates if they are older than the given time. |
|
949 | + * |
|
950 | + * @param int $olderThan minimum time (in seconds) required for a cached template to be cleared |
|
951 | + * |
|
952 | + * @return int the amount of templates cleared |
|
953 | + */ |
|
954 | + public function clearCache($olderThan = - 1) |
|
955 | + { |
|
956 | + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCacheDir()), \RecursiveIteratorIterator::SELF_FIRST); |
|
957 | + $expired = time() - $olderThan; |
|
958 | + $count = 0; |
|
959 | + foreach ($iterator as $file) { |
|
960 | + if ($file->isFile() && $file->getCTime() < $expired) { |
|
961 | + $count += unlink((string)$file) ? 1 : 0; |
|
962 | + } |
|
963 | + } |
|
964 | + |
|
965 | + return $count; |
|
966 | + } |
|
967 | + |
|
968 | + /** |
|
969 | + * Fetches a template object of the given resource. |
|
970 | + * |
|
971 | + * @param string $resourceName the resource name (i.e. file, string) |
|
972 | + * @param string $resourceId the resource identifier (i.e. file path) |
|
973 | + * @param int $cacheTime the cache time setting for this resource |
|
974 | + * @param string $cacheId the unique cache identifier |
|
975 | + * @param string $compileId the unique compiler identifier |
|
976 | + * @param ITemplate $parentTemplate the parent template |
|
977 | + * |
|
978 | + * @return ITemplate |
|
979 | + * @throws Exception |
|
980 | + */ |
|
981 | + public function templateFactory($resourceName, $resourceId, $cacheTime = null, $cacheId = null, $compileId = null, ITemplate $parentTemplate = null) |
|
982 | + { |
|
983 | + if (isset($this->resources[$resourceName])) { |
|
984 | + /** |
|
985 | + * Interface ITemplate |
|
986 | + * |
|
987 | + * @var ITemplate $class |
|
988 | + */ |
|
989 | + $class = $this->resources[$resourceName]['class']; |
|
990 | + |
|
991 | + return $class::templateFactory($this, $resourceId, $cacheTime, $cacheId, $compileId, $parentTemplate); |
|
992 | + } |
|
993 | + |
|
994 | + throw new Exception('Unknown resource type : ' . $resourceName); |
|
995 | + } |
|
996 | + |
|
997 | + /** |
|
998 | + * Checks if the input is an array or arrayaccess object, optionally it can also check if it's |
|
999 | + * empty. |
|
1000 | + * |
|
1001 | + * @param mixed $value the variable to check |
|
1002 | + * @param bool $checkIsEmpty if true, the function will also check if the array|arrayaccess is empty, |
|
1003 | + * and return true only if it's not empty |
|
1004 | + * |
|
1005 | + * @return int|bool true if it's an array|arrayaccess (or the item count if $checkIsEmpty is true) or false if it's |
|
1006 | + * not an array|arrayaccess (or 0 if $checkIsEmpty is true) |
|
1007 | + */ |
|
1008 | + public function isArray($value, $checkIsEmpty = false) |
|
1009 | + { |
|
1010 | + if (is_array($value) === true || $value instanceof ArrayAccess) { |
|
1011 | + if ($checkIsEmpty === false) { |
|
1012 | + return true; |
|
1013 | + } |
|
1014 | + |
|
1015 | + return $this->count($value); |
|
1016 | + } |
|
1017 | + |
|
1018 | + return false; |
|
1019 | + } |
|
1020 | + |
|
1021 | + /** |
|
1022 | + * Checks if the input is an array or a traversable object, optionally it can also check if it's |
|
1023 | + * empty. |
|
1024 | + * |
|
1025 | + * @param mixed $value the variable to check |
|
1026 | + * @param bool $checkIsEmpty if true, the function will also check if the array|traversable is empty, |
|
1027 | + * and return true only if it's not empty |
|
1028 | + * |
|
1029 | + * @return int|bool true if it's an array|traversable (or the item count if $checkIsEmpty is true) or false if it's |
|
1030 | + * not an array|traversable (or 0 if $checkIsEmpty is true) |
|
1031 | + */ |
|
1032 | + public function isTraversable($value, $checkIsEmpty = false) |
|
1033 | + { |
|
1034 | + if (is_array($value) === true) { |
|
1035 | + if ($checkIsEmpty === false) { |
|
1036 | + return true; |
|
1037 | + } else { |
|
1038 | + return count($value) > 0; |
|
1039 | + } |
|
1040 | + } elseif ($value instanceof Traversable) { |
|
1041 | + if ($checkIsEmpty === false) { |
|
1042 | + return true; |
|
1043 | + } else { |
|
1044 | + return $this->count($value); |
|
1045 | + } |
|
1046 | + } |
|
1047 | + |
|
1048 | + return false; |
|
1049 | + } |
|
1050 | + |
|
1051 | + /** |
|
1052 | + * Counts an array or arrayaccess/traversable object. |
|
1053 | + * |
|
1054 | + * @param mixed $value the value to count |
|
1055 | + * |
|
1056 | + * @return int|bool the count for arrays and objects that implement countable, true for other objects that don't, |
|
1057 | + * and 0 for empty elements |
|
1058 | + */ |
|
1059 | + public function count($value) |
|
1060 | + { |
|
1061 | + if (is_array($value) === true || $value instanceof Countable) { |
|
1062 | + return count($value); |
|
1063 | + } elseif ($value instanceof ArrayAccess) { |
|
1064 | + if ($value->offsetExists(0)) { |
|
1065 | + return true; |
|
1066 | + } |
|
1067 | + } elseif ($value instanceof Iterator) { |
|
1068 | + $value->rewind(); |
|
1069 | + if ($value->valid()) { |
|
1070 | + return true; |
|
1071 | + } |
|
1072 | + } elseif ($value instanceof Traversable) { |
|
1073 | + foreach ($value as $dummy) { |
|
1074 | + return true; |
|
1075 | + } |
|
1076 | + } |
|
1077 | + |
|
1078 | + return 0; |
|
1079 | + } |
|
1080 | + |
|
1081 | + /** |
|
1082 | + * Triggers a dwoo error. |
|
1083 | + * |
|
1084 | + * @param string $message the error message |
|
1085 | + * @param int $level the error level, one of the PHP's E_* constants |
|
1086 | + * |
|
1087 | + * @return void |
|
1088 | + */ |
|
1089 | + public function triggerError($message, $level = E_USER_NOTICE) |
|
1090 | + { |
|
1091 | + if (!($tplIdentifier = $this->template->getResourceIdentifier())) { |
|
1092 | + $tplIdentifier = $this->template->getResourceName(); |
|
1093 | + } |
|
1094 | + trigger_error('Dwoo error (in ' . $tplIdentifier . ') : ' . $message, $level); |
|
1095 | + } |
|
1096 | + |
|
1097 | + /** |
|
1098 | + * Adds a block to the block stack. |
|
1099 | + * |
|
1100 | + * @param string $blockName the block name (without Dwoo_Plugin_ prefix) |
|
1101 | + * @param array $args the arguments to be passed to the block's init() function |
|
1102 | + * |
|
1103 | + * @return BlockPlugin the newly created block |
|
1104 | + */ |
|
1105 | + public function addStack($blockName, array $args = array()) |
|
1106 | + { |
|
1107 | + if (isset($this->plugins[$blockName])) { |
|
1108 | + $class = $this->plugins[$blockName]['class']; |
|
1109 | + } else { |
|
1110 | + $class = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . self::toCamelCase($blockName); |
|
1111 | + } |
|
1112 | + |
|
1113 | + if ($this->curBlock !== null) { |
|
1114 | + $this->curBlock->buffer(ob_get_contents()); |
|
1115 | + ob_clean(); |
|
1116 | + } else { |
|
1117 | + $this->buffer .= ob_get_contents(); |
|
1118 | + ob_clean(); |
|
1119 | + } |
|
1120 | + |
|
1121 | + $block = new $class($this); |
|
1122 | + |
|
1123 | + call_user_func_array(array($block, 'init'), $args); |
|
1124 | + |
|
1125 | + $this->stack[] = $this->curBlock = $block; |
|
1126 | + |
|
1127 | + return $block; |
|
1128 | + } |
|
1129 | + |
|
1130 | + /** |
|
1131 | + * Removes the plugin at the top of the block stack. |
|
1132 | + * Calls the block buffer() function, followed by a call to end() and finally a call to process() |
|
1133 | + * |
|
1134 | + * @return void |
|
1135 | + */ |
|
1136 | + public function delStack() |
|
1137 | + { |
|
1138 | + $args = func_get_args(); |
|
1139 | + |
|
1140 | + $this->curBlock->buffer(ob_get_contents()); |
|
1141 | + ob_clean(); |
|
1142 | + |
|
1143 | + call_user_func_array(array($this->curBlock, 'end'), $args); |
|
1144 | + |
|
1145 | + $tmp = array_pop($this->stack); |
|
1146 | + |
|
1147 | + if (count($this->stack) > 0) { |
|
1148 | + $this->curBlock = end($this->stack); |
|
1149 | + $this->curBlock->buffer($tmp->process()); |
|
1150 | + } else { |
|
1151 | + if ($this->buffer !== '') { |
|
1152 | + echo $this->buffer; |
|
1153 | + $this->buffer = ''; |
|
1154 | + } |
|
1155 | + $this->curBlock = null; |
|
1156 | + echo $tmp->process(); |
|
1157 | + } |
|
1158 | + |
|
1159 | + unset($tmp); |
|
1160 | + } |
|
1161 | + |
|
1162 | + /** |
|
1163 | + * Returns the parent block of the given block. |
|
1164 | + * |
|
1165 | + * @param BlockPlugin $block the block class plugin |
|
1166 | + * |
|
1167 | + * @return BlockPlugin|false if the given block isn't in the stack |
|
1168 | + */ |
|
1169 | + public function getParentBlock(BlockPlugin $block) |
|
1170 | + { |
|
1171 | + $index = array_search($block, $this->stack, true); |
|
1172 | + if ($index !== false && $index > 0) { |
|
1173 | + return $this->stack[$index - 1]; |
|
1174 | + } |
|
1175 | + |
|
1176 | + return false; |
|
1177 | + } |
|
1178 | + |
|
1179 | + /** |
|
1180 | + * Finds the closest block of the given type, starting at the top of the stack. |
|
1181 | + * |
|
1182 | + * @param string $type the type of plugin you want to find |
|
1183 | + * |
|
1184 | + * @return BlockPlugin|false if no plugin of such type is in the stack |
|
1185 | + */ |
|
1186 | + public function findBlock($type) |
|
1187 | + { |
|
1188 | + if (isset($this->plugins[$type])) { |
|
1189 | + $type = $this->plugins[$type]['class']; |
|
1190 | + } else { |
|
1191 | + $type = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin_' . str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin', |
|
1192 | + '', $type); |
|
1193 | + } |
|
1194 | + |
|
1195 | + $keys = array_keys($this->stack); |
|
1196 | + while (($key = array_pop($keys)) !== false) { |
|
1197 | + if ($this->stack[$key] instanceof $type) { |
|
1198 | + return $this->stack[$key]; |
|
1199 | + } |
|
1200 | + } |
|
1201 | + |
|
1202 | + return false; |
|
1203 | + } |
|
1204 | + |
|
1205 | + /** |
|
1206 | + * Returns a Plugin of the given class. |
|
1207 | + * this is so a single instance of every class plugin is created at each template run, |
|
1208 | + * allowing class plugins to have "per-template-run" static variables |
|
1209 | + * |
|
1210 | + * @param string $class the class name |
|
1211 | + * |
|
1212 | + * @return mixed an object of the given class |
|
1213 | + */ |
|
1214 | + public function getObjectPlugin($class) |
|
1215 | + { |
|
1216 | + if (isset($this->runtimePlugins[$class])) { |
|
1217 | + return $this->runtimePlugins[$class]; |
|
1218 | + } |
|
1219 | + |
|
1220 | + return $this->runtimePlugins[$class] = new $class($this); |
|
1221 | + } |
|
1222 | + |
|
1223 | + /** |
|
1224 | + * Calls the process() method of the given class-plugin name. |
|
1225 | + * |
|
1226 | + * @param string $plugName the class plugin name (without Dwoo_Plugin_ prefix) |
|
1227 | + * @param array $params an array of parameters to send to the process() method |
|
1228 | + * |
|
1229 | + * @return string the process() return value |
|
1230 | + */ |
|
1231 | + public function classCall($plugName, array $params = array()) |
|
1232 | + { |
|
1233 | + $class = self::toCamelCase($plugName); |
|
1234 | + $plugin = $this->getObjectPlugin($class); |
|
1235 | + |
|
1236 | + return call_user_func_array(array($plugin, 'process'), $params); |
|
1237 | + } |
|
1238 | + |
|
1239 | + /** |
|
1240 | + * Calls a php function. |
|
1241 | + * |
|
1242 | + * @param string $callback the function to call |
|
1243 | + * @param array $params an array of parameters to send to the function |
|
1244 | + * |
|
1245 | + * @return mixed the return value of the called function |
|
1246 | + */ |
|
1247 | + public function arrayMap($callback, array $params) |
|
1248 | + { |
|
1249 | + if ($params[0] === $this) { |
|
1250 | + $addThis = true; |
|
1251 | + array_shift($params); |
|
1252 | + } |
|
1253 | + if ((is_array($params[0]) || ($params[0] instanceof Iterator && $params[0] instanceof ArrayAccess))) { |
|
1254 | + if (empty($params[0])) { |
|
1255 | + return $params[0]; |
|
1256 | + } |
|
1257 | + |
|
1258 | + // array map |
|
1259 | + $out = array(); |
|
1260 | + $cnt = count($params); |
|
1261 | + |
|
1262 | + if (isset($addThis)) { |
|
1263 | + array_unshift($params, $this); |
|
1264 | + $items = $params[1]; |
|
1265 | + $keys = array_keys($items); |
|
1266 | + |
|
1267 | + if (is_string($callback) === false) { |
|
1268 | + while (($i = array_shift($keys)) !== null) { |
|
1269 | + $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params); |
|
1270 | + } |
|
1271 | + } elseif ($cnt === 1) { |
|
1272 | + while (($i = array_shift($keys)) !== null) { |
|
1273 | + $out[] = $callback($this, $items[$i]); |
|
1274 | + } |
|
1275 | + } elseif ($cnt === 2) { |
|
1276 | + while (($i = array_shift($keys)) !== null) { |
|
1277 | + $out[] = $callback($this, $items[$i], $params[2]); |
|
1278 | + } |
|
1279 | + } elseif ($cnt === 3) { |
|
1280 | + while (($i = array_shift($keys)) !== null) { |
|
1281 | + $out[] = $callback($this, $items[$i], $params[2], $params[3]); |
|
1282 | + } |
|
1283 | + } else { |
|
1284 | + while (($i = array_shift($keys)) !== null) { |
|
1285 | + $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params); |
|
1286 | + } |
|
1287 | + } |
|
1288 | + } else { |
|
1289 | + $items = $params[0]; |
|
1290 | + $keys = array_keys($items); |
|
1291 | + |
|
1292 | + if (is_string($callback) === false) { |
|
1293 | + while (($i = array_shift($keys)) !== null) { |
|
1294 | + $out[] = call_user_func_array($callback, array($items[$i]) + $params); |
|
1295 | + } |
|
1296 | + } elseif ($cnt === 1) { |
|
1297 | + while (($i = array_shift($keys)) !== null) { |
|
1298 | + $out[] = $callback($items[$i]); |
|
1299 | + } |
|
1300 | + } elseif ($cnt === 2) { |
|
1301 | + while (($i = array_shift($keys)) !== null) { |
|
1302 | + $out[] = $callback($items[$i], $params[1]); |
|
1303 | + } |
|
1304 | + } elseif ($cnt === 3) { |
|
1305 | + while (($i = array_shift($keys)) !== null) { |
|
1306 | + $out[] = $callback($items[$i], $params[1], $params[2]); |
|
1307 | + } |
|
1308 | + } elseif ($cnt === 4) { |
|
1309 | + while (($i = array_shift($keys)) !== null) { |
|
1310 | + $out[] = $callback($items[$i], $params[1], $params[2], $params[3]); |
|
1311 | + } |
|
1312 | + } else { |
|
1313 | + while (($i = array_shift($keys)) !== null) { |
|
1314 | + $out[] = call_user_func_array($callback, array($items[$i]) + $params); |
|
1315 | + } |
|
1316 | + } |
|
1317 | + } |
|
1318 | + |
|
1319 | + return $out; |
|
1320 | + } else { |
|
1321 | + return $params[0]; |
|
1322 | + } |
|
1323 | + } |
|
1324 | + |
|
1325 | + /** |
|
1326 | + * Reads a variable into the given data array. |
|
1327 | + * |
|
1328 | + * @param string $varstr the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property") |
|
1329 | + * @param mixed $data the data array or object to read from |
|
1330 | + * @param bool $safeRead if true, the function will check whether the index exists to prevent any notices from |
|
1331 | + * being output |
|
1332 | + * |
|
1333 | + * @return mixed |
|
1334 | + */ |
|
1335 | + public function readVarInto($varstr, $data, $safeRead = false) |
|
1336 | + { |
|
1337 | + if ($data === null) { |
|
1338 | + return null; |
|
1339 | + } |
|
1340 | + |
|
1341 | + if (is_array($varstr) === false) { |
|
1342 | + preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m); |
|
1343 | + } else { |
|
1344 | + $m = $varstr; |
|
1345 | + } |
|
1346 | + unset($varstr); |
|
1347 | + |
|
1348 | + while (list($k, $sep) = each($m[1])) { |
|
1349 | + if ($sep === '.' || $sep === '[' || $sep === '') { |
|
1350 | + // strip enclosing quotes if present |
|
1351 | + $m[2][$k] = preg_replace('#^(["\']?)(.*?)\1$#', '$2', $m[2][$k]); |
|
1352 | + |
|
1353 | + if ((is_array($data) || $data instanceof ArrayAccess) && ($safeRead === false || isset($data[$m[2][$k]]))) { |
|
1354 | + $data = $data[$m[2][$k]]; |
|
1355 | + } else { |
|
1356 | + return null; |
|
1357 | + } |
|
1358 | + } else { |
|
1359 | + if (is_object($data) && ($safeRead === false || isset($data->$m[2][$k]))) { |
|
1360 | + $data = $data->$m[2][$k]; |
|
1361 | + } else { |
|
1362 | + return null; |
|
1363 | + } |
|
1364 | + } |
|
1365 | + } |
|
1366 | + |
|
1367 | + return $data; |
|
1368 | + } |
|
1369 | + |
|
1370 | + /** |
|
1371 | + * Reads a variable into the parent scope. |
|
1372 | + * |
|
1373 | + * @param int $parentLevels the amount of parent levels to go from the current scope |
|
1374 | + * @param string $varstr the variable string, using dwoo variable syntax (i.e. |
|
1375 | + * "var.subvar[subsubvar]->property") |
|
1376 | + * |
|
1377 | + * @return mixed |
|
1378 | + */ |
|
1379 | + public function readParentVar($parentLevels, $varstr = null) |
|
1380 | + { |
|
1381 | + $tree = $this->scopeTree; |
|
1382 | + $cur = $this->data; |
|
1383 | + |
|
1384 | + while ($parentLevels -- !== 0) { |
|
1385 | + array_pop($tree); |
|
1386 | + } |
|
1387 | + |
|
1388 | + while (($i = array_shift($tree)) !== null) { |
|
1389 | + if (is_object($cur)) { |
|
1390 | + $cur = $cur->$i; |
|
1391 | + } else { |
|
1392 | + $cur = $cur[$i]; |
|
1393 | + } |
|
1394 | + } |
|
1395 | + |
|
1396 | + if ($varstr !== null) { |
|
1397 | + return $this->readVarInto($varstr, $cur); |
|
1398 | + } else { |
|
1399 | + return $cur; |
|
1400 | + } |
|
1401 | + } |
|
1402 | + |
|
1403 | + /** |
|
1404 | + * Reads a variable into the current scope. |
|
1405 | + * |
|
1406 | + * @param string $varstr the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property") |
|
1407 | + * |
|
1408 | + * @return mixed |
|
1409 | + */ |
|
1410 | + public function readVar($varstr) |
|
1411 | + { |
|
1412 | + if (is_array($varstr) === true) { |
|
1413 | + $m = $varstr; |
|
1414 | + unset($varstr); |
|
1415 | + } else { |
|
1416 | + if (strstr($varstr, '.') === false && strstr($varstr, '[') === false && strstr($varstr, '->') === false) { |
|
1417 | + if ($varstr === 'dwoo') { |
|
1418 | + return $this->globals; |
|
1419 | + } elseif ($varstr === '__' || $varstr === '_root') { |
|
1420 | + return $this->data; |
|
1421 | + } elseif ($varstr === '_' || $varstr === '_parent') { |
|
1422 | + $varstr = '.' . $varstr; |
|
1423 | + $tree = $this->scopeTree; |
|
1424 | + $cur = $this->data; |
|
1425 | + array_pop($tree); |
|
1426 | + |
|
1427 | + while (($i = array_shift($tree)) !== null) { |
|
1428 | + if (is_object($cur)) { |
|
1429 | + $cur = $cur->$i; |
|
1430 | + } else { |
|
1431 | + $cur = $cur[$i]; |
|
1432 | + } |
|
1433 | + } |
|
1434 | + |
|
1435 | + return $cur; |
|
1436 | + } |
|
1437 | + |
|
1438 | + $cur = $this->scope; |
|
1439 | + |
|
1440 | + if (isset($cur[$varstr])) { |
|
1441 | + return $cur[$varstr]; |
|
1442 | + } else { |
|
1443 | + return null; |
|
1444 | + } |
|
1445 | + } |
|
1446 | + |
|
1447 | + if (substr($varstr, 0, 1) === '.') { |
|
1448 | + $varstr = 'dwoo' . $varstr; |
|
1449 | + } |
|
1450 | + |
|
1451 | + preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m); |
|
1452 | + } |
|
1453 | + |
|
1454 | + $i = $m[2][0]; |
|
1455 | + if ($i === 'dwoo') { |
|
1456 | + $cur = $this->globals; |
|
1457 | + array_shift($m[2]); |
|
1458 | + array_shift($m[1]); |
|
1459 | + switch ($m[2][0]) { |
|
1460 | + case 'get': |
|
1461 | + $cur = $_GET; |
|
1462 | + break; |
|
1463 | + case 'post': |
|
1464 | + $cur = $_POST; |
|
1465 | + break; |
|
1466 | + case 'session': |
|
1467 | + $cur = $_SESSION; |
|
1468 | + break; |
|
1469 | + case 'cookies': |
|
1470 | + case 'cookie': |
|
1471 | + $cur = $_COOKIE; |
|
1472 | + break; |
|
1473 | + case 'server': |
|
1474 | + $cur = $_SERVER; |
|
1475 | + break; |
|
1476 | + case 'env': |
|
1477 | + $cur = $_ENV; |
|
1478 | + break; |
|
1479 | + case 'request': |
|
1480 | + $cur = $_REQUEST; |
|
1481 | + break; |
|
1482 | + case 'const': |
|
1483 | + array_shift($m[2]); |
|
1484 | + if (defined($m[2][0])) { |
|
1485 | + return constant($m[2][0]); |
|
1486 | + } else { |
|
1487 | + return null; |
|
1488 | + } |
|
1489 | + } |
|
1490 | + if ($cur !== $this->globals) { |
|
1491 | + array_shift($m[2]); |
|
1492 | + array_shift($m[1]); |
|
1493 | + } |
|
1494 | + } elseif ($i === '__' || $i === '_root') { |
|
1495 | + $cur = $this->data; |
|
1496 | + array_shift($m[2]); |
|
1497 | + array_shift($m[1]); |
|
1498 | + } elseif ($i === '_' || $i === '_parent') { |
|
1499 | + $tree = $this->scopeTree; |
|
1500 | + $cur = $this->data; |
|
1501 | + |
|
1502 | + while (true) { |
|
1503 | + array_pop($tree); |
|
1504 | + array_shift($m[2]); |
|
1505 | + array_shift($m[1]); |
|
1506 | + if (current($m[2]) === '_' || current($m[2]) === '_parent') { |
|
1507 | + continue; |
|
1508 | + } |
|
1509 | + |
|
1510 | + while (($i = array_shift($tree)) !== null) { |
|
1511 | + if (is_object($cur)) { |
|
1512 | + $cur = $cur->$i; |
|
1513 | + } else { |
|
1514 | + $cur = $cur[$i]; |
|
1515 | + } |
|
1516 | + } |
|
1517 | + break; |
|
1518 | + } |
|
1519 | + } else { |
|
1520 | + $cur = $this->scope; |
|
1521 | + } |
|
1522 | + |
|
1523 | + while (list($k, $sep) = each($m[1])) { |
|
1524 | + if ($sep === '.' || $sep === '[' || $sep === '') { |
|
1525 | + if ((is_array($cur) || $cur instanceof ArrayAccess) && isset($cur[$m[2][$k]])) { |
|
1526 | + $cur = $cur[$m[2][$k]]; |
|
1527 | + } else { |
|
1528 | + return null; |
|
1529 | + } |
|
1530 | + } elseif ($sep === '->') { |
|
1531 | + if (is_object($cur)) { |
|
1532 | + $cur = $cur->$m[2][$k]; |
|
1533 | + } else { |
|
1534 | + return null; |
|
1535 | + } |
|
1536 | + } else { |
|
1537 | + return null; |
|
1538 | + } |
|
1539 | + } |
|
1540 | + |
|
1541 | + return $cur; |
|
1542 | + } |
|
1543 | + |
|
1544 | + /** |
|
1545 | + * Assign the value to the given variable. |
|
1546 | + * |
|
1547 | + * @param mixed $value the value to assign |
|
1548 | + * @param string $scope the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property") |
|
1549 | + * |
|
1550 | + * @return bool true if assigned correctly or false if a problem occured while parsing the var string |
|
1551 | + */ |
|
1552 | + public function assignInScope($value, $scope) |
|
1553 | + { |
|
1554 | + if (!is_string($scope)) { |
|
1555 | + $this->triggerError('Assignments must be done into strings, (' . gettype($scope) . ') ' . var_export($scope, true) . ' given', E_USER_ERROR); |
|
1556 | + } |
|
1557 | + if (strstr($scope, '.') === false && strstr($scope, '->') === false) { |
|
1558 | + $this->scope[$scope] = $value; |
|
1559 | + } else { |
|
1560 | + // TODO handle _root/_parent scopes ? |
|
1561 | + preg_match_all('#(\[|->|\.)?([^.[\]-]+)\]?#i', $scope, $m); |
|
1562 | + |
|
1563 | + $cur = &$this->scope; |
|
1564 | + $last = array( |
|
1565 | + array_pop($m[1]), |
|
1566 | + array_pop($m[2]) |
|
1567 | + ); |
|
1568 | + |
|
1569 | + while (list($k, $sep) = each($m[1])) { |
|
1570 | + if ($sep === '.' || $sep === '[' || $sep === '') { |
|
1571 | + if (is_array($cur) === false) { |
|
1572 | + $cur = array(); |
|
1573 | + } |
|
1574 | + $cur = &$cur[$m[2][$k]]; |
|
1575 | + } elseif ($sep === '->') { |
|
1576 | + if (is_object($cur) === false) { |
|
1577 | + $cur = new stdClass(); |
|
1578 | + } |
|
1579 | + $cur = &$cur->$m[2][$k]; |
|
1580 | + } else { |
|
1581 | + return false; |
|
1582 | + } |
|
1583 | + } |
|
1584 | + |
|
1585 | + if ($last[0] === '.' || $last[0] === '[' || $last[0] === '') { |
|
1586 | + if (is_array($cur) === false) { |
|
1587 | + $cur = array(); |
|
1588 | + } |
|
1589 | + $cur[$last[1]] = $value; |
|
1590 | + } elseif ($last[0] === '->') { |
|
1591 | + if (is_object($cur) === false) { |
|
1592 | + $cur = new stdClass(); |
|
1593 | + } |
|
1594 | + $cur->$last[1] = $value; |
|
1595 | + } else { |
|
1596 | + return false; |
|
1597 | + } |
|
1598 | + } |
|
1599 | + } |
|
1600 | + |
|
1601 | + /** |
|
1602 | + * Sets the scope to the given scope string or array. |
|
1603 | + * |
|
1604 | + * @param mixed $scope a string i.e. "level1.level2" or an array i.e. array("level1", "level2") |
|
1605 | + * @param bool $absolute if true, the scope is set from the top level scope and not from the current scope |
|
1606 | + * |
|
1607 | + * @return array the current scope tree |
|
1608 | + */ |
|
1609 | + public function setScope($scope, $absolute = false) |
|
1610 | + { |
|
1611 | + $old = $this->scopeTree; |
|
1612 | + |
|
1613 | + if (is_string($scope) === true) { |
|
1614 | + $scope = explode('.', $scope); |
|
1615 | + } |
|
1616 | + |
|
1617 | + if ($absolute === true) { |
|
1618 | + $this->scope = &$this->data; |
|
1619 | + $this->scopeTree = array(); |
|
1620 | + } |
|
1621 | + |
|
1622 | + while (($bit = array_shift($scope)) !== null) { |
|
1623 | + if ($bit === '_' || $bit === '_parent') { |
|
1624 | + array_pop($this->scopeTree); |
|
1625 | + $this->scope = &$this->data; |
|
1626 | + $cnt = count($this->scopeTree); |
|
1627 | + for ($i = 0; $i < $cnt; ++ $i) { |
|
1628 | + $this->scope = &$this->scope[$this->scopeTree[$i]]; |
|
1629 | + } |
|
1630 | + } elseif ($bit === '__' || $bit === '_root') { |
|
1631 | + $this->scope = &$this->data; |
|
1632 | + $this->scopeTree = array(); |
|
1633 | + } elseif (isset($this->scope[$bit])) { |
|
1634 | + if ($this->scope instanceof ArrayAccess) { |
|
1635 | + $tmp = $this->scope[$bit]; |
|
1636 | + $this->scope = &$tmp; |
|
1637 | + } else { |
|
1638 | + $this->scope = &$this->scope[$bit]; |
|
1639 | + } |
|
1640 | + $this->scopeTree[] = $bit; |
|
1641 | + } else { |
|
1642 | + unset($this->scope); |
|
1643 | + $this->scope = null; |
|
1644 | + } |
|
1645 | + } |
|
1646 | + |
|
1647 | + return $old; |
|
1648 | + } |
|
1649 | + |
|
1650 | + /** |
|
1651 | + * Returns the entire data array. |
|
1652 | + * |
|
1653 | + * @return array |
|
1654 | + */ |
|
1655 | + public function getData() |
|
1656 | + { |
|
1657 | + return $this->data; |
|
1658 | + } |
|
1659 | + |
|
1660 | + /** |
|
1661 | + * Sets a return value for the currently running template. |
|
1662 | + * |
|
1663 | + * @param string $name var name |
|
1664 | + * @param mixed $value var value |
|
1665 | + * |
|
1666 | + * @return void |
|
1667 | + */ |
|
1668 | + public function setReturnValue($name, $value) |
|
1669 | + { |
|
1670 | + $this->returnData[$name] = $value; |
|
1671 | + } |
|
1672 | + |
|
1673 | + /** |
|
1674 | + * Retrieves the return values set by the template. |
|
1675 | + * |
|
1676 | + * @return array |
|
1677 | + */ |
|
1678 | + public function getReturnValues() |
|
1679 | + { |
|
1680 | + return $this->returnData; |
|
1681 | + } |
|
1682 | + |
|
1683 | + /** |
|
1684 | + * Returns a reference to the current scope. |
|
1685 | + * |
|
1686 | + * @return mixed |
|
1687 | + */ |
|
1688 | + public function &getScope() |
|
1689 | + { |
|
1690 | + return $this->scope; |
|
1691 | + } |
|
1692 | + |
|
1693 | + /** |
|
1694 | + * Redirects all calls to unexisting to plugin proxy. |
|
1695 | + * |
|
1696 | + * @param string $method the method name |
|
1697 | + * @param array $args array of arguments |
|
1698 | + * |
|
1699 | + * @return mixed |
|
1700 | + * @throws Exception |
|
1701 | + */ |
|
1702 | + public function __call($method, $args) |
|
1703 | + { |
|
1704 | + $proxy = $this->getPluginProxy(); |
|
1705 | + if (!$proxy) { |
|
1706 | + throw new Exception('Call to undefined method ' . __CLASS__ . '::' . $method . '()'); |
|
1707 | + } |
|
1708 | + |
|
1709 | + return call_user_func_array($proxy->getCallback($method), $args); |
|
1710 | + } |
|
1711 | + |
|
1712 | + /** |
|
1713 | + * Convert plugin name from `auto_escape` to `AutoEscape`. |
|
1714 | + * @param string $input |
|
1715 | + * @param string $separator |
|
1716 | + * |
|
1717 | + * @return mixed |
|
1718 | + */ |
|
1719 | + public static function toCamelCase($input, $separator = '_') |
|
1720 | + { |
|
1721 | + return join(array_map('ucfirst', explode($separator, $input))); |
|
1722 | + |
|
1723 | + // TODO >= PHP5.4.32 |
|
1724 | + //return str_replace($separator, '', ucwords($input, $separator)); |
|
1725 | + } |
|
1726 | 1726 | } |
@@ -375,8 +375,8 @@ discard block |
||
375 | 375 | } |
376 | 376 | |
377 | 377 | if ($doCache === true) { |
378 | - $out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*' . $dynamicId . '*/ echo \'$1\'; ?>', $out); |
|
379 | - if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS . 'PluginDynamic')) { |
|
378 | + $out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*'.$dynamicId.'*/ echo \'$1\'; ?>', $out); |
|
379 | + if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS.'PluginDynamic')) { |
|
380 | 380 | $this->getLoader()->loadPlugin('PluginDynamic'); |
381 | 381 | } |
382 | 382 | $out = PluginDynamic::unescape($out, $dynamicId, $compiledTemplate); |
@@ -545,7 +545,7 @@ discard block |
||
545 | 545 | public function addFilter($callback, $autoload = false) |
546 | 546 | { |
547 | 547 | if ($autoload) { |
548 | - $class = self::NAMESPACE_PLUGINS_FILTERS . self::toCamelCase($callback); |
|
548 | + $class = self::NAMESPACE_PLUGINS_FILTERS.self::toCamelCase($callback); |
|
549 | 549 | if (!class_exists($class) && !function_exists($class)) { |
550 | 550 | try { |
551 | 551 | $this->getLoader()->loadPlugin($callback); |
@@ -553,12 +553,12 @@ discard block |
||
553 | 553 | catch (Exception $e) { |
554 | 554 | if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) { |
555 | 555 | throw new Exception( |
556 | - 'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should |
|
557 | - not be used, please only use "' . str_replace('Dwoo_Filter_', '', $callback) . '"' |
|
556 | + 'Wrong filter name : '.$callback.', the "Dwoo_Filter_" prefix should |
|
557 | + not be used, please only use "' . str_replace('Dwoo_Filter_', '', $callback).'"' |
|
558 | 558 | ); |
559 | 559 | } else { |
560 | 560 | throw new Exception( |
561 | - 'Wrong filter name : ' . $callback . ', when using autoload the filter must |
|
561 | + 'Wrong filter name : '.$callback.', when using autoload the filter must |
|
562 | 562 | be in one of your plugin dir as "name.php" containig a class or function named |
563 | 563 | "Dwoo_Filter_name"' |
564 | 564 | ); |
@@ -572,7 +572,7 @@ discard block |
||
572 | 572 | $callback = $class; |
573 | 573 | } else { |
574 | 574 | throw new Exception( |
575 | - 'Wrong filter name : ' . $callback . ', when using autoload the filter must be in |
|
575 | + 'Wrong filter name : '.$callback.', when using autoload the filter must be in |
|
576 | 576 | one of your plugin dir as "name.php" containig a class or function named "Dwoo_Filter_name"' |
577 | 577 | ); |
578 | 578 | } |
@@ -592,14 +592,14 @@ discard block |
||
592 | 592 | */ |
593 | 593 | public function removeFilter($callback) |
594 | 594 | { |
595 | - if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS. 'Filter' . self::toCamelCase($callback), $this->filters, |
|
595 | + if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS.'Filter'.self::toCamelCase($callback), $this->filters, |
|
596 | 596 | true)) !== |
597 | 597 | false) { |
598 | 598 | unset($this->filters[$index]); |
599 | 599 | } elseif (($index = array_search($callback, $this->filters, true)) !== false) { |
600 | 600 | unset($this->filters[$index]); |
601 | 601 | } else { |
602 | - $class = self::NAMESPACE_PLUGINS_FILTERS . 'Filter' . $callback; |
|
602 | + $class = self::NAMESPACE_PLUGINS_FILTERS.'Filter'.$callback; |
|
603 | 603 | foreach ($this->filters as $index => $filter) { |
604 | 604 | if (is_array($filter) && $filter[0] instanceof $class) { |
605 | 605 | unset($this->filters[$index]); |
@@ -722,7 +722,7 @@ discard block |
||
722 | 722 | public function getCacheDir() |
723 | 723 | { |
724 | 724 | if ($this->cacheDir === null) { |
725 | - $this->setCacheDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR); |
|
725 | + $this->setCacheDir(dirname(__DIR__).DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR); |
|
726 | 726 | } |
727 | 727 | |
728 | 728 | return $this->cacheDir; |
@@ -738,9 +738,9 @@ discard block |
||
738 | 738 | */ |
739 | 739 | public function setCacheDir($dir) |
740 | 740 | { |
741 | - $this->cacheDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR; |
|
741 | + $this->cacheDir = rtrim($dir, '/\\').DIRECTORY_SEPARATOR; |
|
742 | 742 | if (is_writable($this->cacheDir) === false) { |
743 | - throw new Exception('The cache directory must be writable, chmod "' . $this->cacheDir . '" to make it writable'); |
|
743 | + throw new Exception('The cache directory must be writable, chmod "'.$this->cacheDir.'" to make it writable'); |
|
744 | 744 | } |
745 | 745 | } |
746 | 746 | |
@@ -752,7 +752,7 @@ discard block |
||
752 | 752 | public function getCompileDir() |
753 | 753 | { |
754 | 754 | if ($this->compileDir === null) { |
755 | - $this->setCompileDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'compiled' . DIRECTORY_SEPARATOR); |
|
755 | + $this->setCompileDir(dirname(__DIR__).DIRECTORY_SEPARATOR.'compiled'.DIRECTORY_SEPARATOR); |
|
756 | 756 | } |
757 | 757 | |
758 | 758 | return $this->compileDir; |
@@ -768,9 +768,9 @@ discard block |
||
768 | 768 | */ |
769 | 769 | public function setCompileDir($dir) |
770 | 770 | { |
771 | - $this->compileDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR; |
|
771 | + $this->compileDir = rtrim($dir, '/\\').DIRECTORY_SEPARATOR; |
|
772 | 772 | if (is_writable($this->compileDir) === false) { |
773 | - throw new Exception('The compile directory must be writable, chmod "' . $this->compileDir . '" to make it writable'); |
|
773 | + throw new Exception('The compile directory must be writable, chmod "'.$this->compileDir.'" to make it writable'); |
|
774 | 774 | } |
775 | 775 | } |
776 | 776 | |
@@ -793,7 +793,7 @@ discard block |
||
793 | 793 | */ |
794 | 794 | public function setCacheTime($seconds) |
795 | 795 | { |
796 | - $this->cacheTime = (int)$seconds; |
|
796 | + $this->cacheTime = (int) $seconds; |
|
797 | 797 | } |
798 | 798 | |
799 | 799 | /** |
@@ -817,7 +817,7 @@ discard block |
||
817 | 817 | */ |
818 | 818 | public function setCharset($charset) |
819 | 819 | { |
820 | - $this->charset = strtolower((string)$charset); |
|
820 | + $this->charset = strtolower((string) $charset); |
|
821 | 821 | } |
822 | 822 | |
823 | 823 | /** |
@@ -954,11 +954,11 @@ discard block |
||
954 | 954 | public function clearCache($olderThan = - 1) |
955 | 955 | { |
956 | 956 | $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCacheDir()), \RecursiveIteratorIterator::SELF_FIRST); |
957 | - $expired = time() - $olderThan; |
|
957 | + $expired = time()-$olderThan; |
|
958 | 958 | $count = 0; |
959 | 959 | foreach ($iterator as $file) { |
960 | 960 | if ($file->isFile() && $file->getCTime() < $expired) { |
961 | - $count += unlink((string)$file) ? 1 : 0; |
|
961 | + $count += unlink((string) $file) ? 1 : 0; |
|
962 | 962 | } |
963 | 963 | } |
964 | 964 | |
@@ -991,7 +991,7 @@ discard block |
||
991 | 991 | return $class::templateFactory($this, $resourceId, $cacheTime, $cacheId, $compileId, $parentTemplate); |
992 | 992 | } |
993 | 993 | |
994 | - throw new Exception('Unknown resource type : ' . $resourceName); |
|
994 | + throw new Exception('Unknown resource type : '.$resourceName); |
|
995 | 995 | } |
996 | 996 | |
997 | 997 | /** |
@@ -1091,7 +1091,7 @@ discard block |
||
1091 | 1091 | if (!($tplIdentifier = $this->template->getResourceIdentifier())) { |
1092 | 1092 | $tplIdentifier = $this->template->getResourceName(); |
1093 | 1093 | } |
1094 | - trigger_error('Dwoo error (in ' . $tplIdentifier . ') : ' . $message, $level); |
|
1094 | + trigger_error('Dwoo error (in '.$tplIdentifier.') : '.$message, $level); |
|
1095 | 1095 | } |
1096 | 1096 | |
1097 | 1097 | /** |
@@ -1107,7 +1107,7 @@ discard block |
||
1107 | 1107 | if (isset($this->plugins[$blockName])) { |
1108 | 1108 | $class = $this->plugins[$blockName]['class']; |
1109 | 1109 | } else { |
1110 | - $class = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . self::toCamelCase($blockName); |
|
1110 | + $class = self::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.self::toCamelCase($blockName); |
|
1111 | 1111 | } |
1112 | 1112 | |
1113 | 1113 | if ($this->curBlock !== null) { |
@@ -1170,7 +1170,7 @@ discard block |
||
1170 | 1170 | { |
1171 | 1171 | $index = array_search($block, $this->stack, true); |
1172 | 1172 | if ($index !== false && $index > 0) { |
1173 | - return $this->stack[$index - 1]; |
|
1173 | + return $this->stack[$index-1]; |
|
1174 | 1174 | } |
1175 | 1175 | |
1176 | 1176 | return false; |
@@ -1188,7 +1188,7 @@ discard block |
||
1188 | 1188 | if (isset($this->plugins[$type])) { |
1189 | 1189 | $type = $this->plugins[$type]['class']; |
1190 | 1190 | } else { |
1191 | - $type = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin_' . str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin', |
|
1191 | + $type = self::NAMESPACE_PLUGINS_BLOCKS.'Plugin_'.str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin', |
|
1192 | 1192 | '', $type); |
1193 | 1193 | } |
1194 | 1194 | |
@@ -1266,7 +1266,7 @@ discard block |
||
1266 | 1266 | |
1267 | 1267 | if (is_string($callback) === false) { |
1268 | 1268 | while (($i = array_shift($keys)) !== null) { |
1269 | - $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params); |
|
1269 | + $out[] = call_user_func_array($callback, array(1 => $items[$i])+$params); |
|
1270 | 1270 | } |
1271 | 1271 | } elseif ($cnt === 1) { |
1272 | 1272 | while (($i = array_shift($keys)) !== null) { |
@@ -1282,7 +1282,7 @@ discard block |
||
1282 | 1282 | } |
1283 | 1283 | } else { |
1284 | 1284 | while (($i = array_shift($keys)) !== null) { |
1285 | - $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params); |
|
1285 | + $out[] = call_user_func_array($callback, array(1 => $items[$i])+$params); |
|
1286 | 1286 | } |
1287 | 1287 | } |
1288 | 1288 | } else { |
@@ -1291,7 +1291,7 @@ discard block |
||
1291 | 1291 | |
1292 | 1292 | if (is_string($callback) === false) { |
1293 | 1293 | while (($i = array_shift($keys)) !== null) { |
1294 | - $out[] = call_user_func_array($callback, array($items[$i]) + $params); |
|
1294 | + $out[] = call_user_func_array($callback, array($items[$i])+$params); |
|
1295 | 1295 | } |
1296 | 1296 | } elseif ($cnt === 1) { |
1297 | 1297 | while (($i = array_shift($keys)) !== null) { |
@@ -1311,7 +1311,7 @@ discard block |
||
1311 | 1311 | } |
1312 | 1312 | } else { |
1313 | 1313 | while (($i = array_shift($keys)) !== null) { |
1314 | - $out[] = call_user_func_array($callback, array($items[$i]) + $params); |
|
1314 | + $out[] = call_user_func_array($callback, array($items[$i])+$params); |
|
1315 | 1315 | } |
1316 | 1316 | } |
1317 | 1317 | } |
@@ -1381,7 +1381,7 @@ discard block |
||
1381 | 1381 | $tree = $this->scopeTree; |
1382 | 1382 | $cur = $this->data; |
1383 | 1383 | |
1384 | - while ($parentLevels -- !== 0) { |
|
1384 | + while ($parentLevels-- !== 0) { |
|
1385 | 1385 | array_pop($tree); |
1386 | 1386 | } |
1387 | 1387 | |
@@ -1419,7 +1419,7 @@ discard block |
||
1419 | 1419 | } elseif ($varstr === '__' || $varstr === '_root') { |
1420 | 1420 | return $this->data; |
1421 | 1421 | } elseif ($varstr === '_' || $varstr === '_parent') { |
1422 | - $varstr = '.' . $varstr; |
|
1422 | + $varstr = '.'.$varstr; |
|
1423 | 1423 | $tree = $this->scopeTree; |
1424 | 1424 | $cur = $this->data; |
1425 | 1425 | array_pop($tree); |
@@ -1445,7 +1445,7 @@ discard block |
||
1445 | 1445 | } |
1446 | 1446 | |
1447 | 1447 | if (substr($varstr, 0, 1) === '.') { |
1448 | - $varstr = 'dwoo' . $varstr; |
|
1448 | + $varstr = 'dwoo'.$varstr; |
|
1449 | 1449 | } |
1450 | 1450 | |
1451 | 1451 | preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m); |
@@ -1552,7 +1552,7 @@ discard block |
||
1552 | 1552 | public function assignInScope($value, $scope) |
1553 | 1553 | { |
1554 | 1554 | if (!is_string($scope)) { |
1555 | - $this->triggerError('Assignments must be done into strings, (' . gettype($scope) . ') ' . var_export($scope, true) . ' given', E_USER_ERROR); |
|
1555 | + $this->triggerError('Assignments must be done into strings, ('.gettype($scope).') '.var_export($scope, true).' given', E_USER_ERROR); |
|
1556 | 1556 | } |
1557 | 1557 | if (strstr($scope, '.') === false && strstr($scope, '->') === false) { |
1558 | 1558 | $this->scope[$scope] = $value; |
@@ -1703,7 +1703,7 @@ discard block |
||
1703 | 1703 | { |
1704 | 1704 | $proxy = $this->getPluginProxy(); |
1705 | 1705 | if (!$proxy) { |
1706 | - throw new Exception('Call to undefined method ' . __CLASS__ . '::' . $method . '()'); |
|
1706 | + throw new Exception('Call to undefined method '.__CLASS__.'::'.$method.'()'); |
|
1707 | 1707 | } |
1708 | 1708 | |
1709 | 1709 | return call_user_func_array($proxy->getCallback($method), $args); |
@@ -549,8 +549,7 @@ |
||
549 | 549 | if (!class_exists($class) && !function_exists($class)) { |
550 | 550 | try { |
551 | 551 | $this->getLoader()->loadPlugin($callback); |
552 | - } |
|
553 | - catch (Exception $e) { |
|
552 | + } catch (Exception $e) { |
|
554 | 553 | if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) { |
555 | 554 | throw new Exception( |
556 | 555 | 'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should |
@@ -57,7 +57,7 @@ |
||
57 | 57 | /** |
58 | 58 | * Loader constructor. |
59 | 59 | * |
60 | - * @param $cacheDir |
|
60 | + * @param string $cacheDir |
|
61 | 61 | */ |
62 | 62 | public function __construct($cacheDir) |
63 | 63 | { |
@@ -23,176 +23,176 @@ |
||
23 | 23 | */ |
24 | 24 | class Loader implements ILoader |
25 | 25 | { |
26 | - /** |
|
27 | - * Stores the plugin directories. |
|
28 | - * |
|
29 | - * @see addDirectory |
|
30 | - * @var array |
|
31 | - */ |
|
32 | - protected $paths = array(); |
|
26 | + /** |
|
27 | + * Stores the plugin directories. |
|
28 | + * |
|
29 | + * @see addDirectory |
|
30 | + * @var array |
|
31 | + */ |
|
32 | + protected $paths = array(); |
|
33 | 33 | |
34 | - /** |
|
35 | - * Stores the plugins names/paths relationships |
|
36 | - * don't edit this on your own, use addDirectory. |
|
37 | - * |
|
38 | - * @see addDirectory |
|
39 | - * @var array |
|
40 | - */ |
|
41 | - protected $classPath = array(); |
|
34 | + /** |
|
35 | + * Stores the plugins names/paths relationships |
|
36 | + * don't edit this on your own, use addDirectory. |
|
37 | + * |
|
38 | + * @see addDirectory |
|
39 | + * @var array |
|
40 | + */ |
|
41 | + protected $classPath = array(); |
|
42 | 42 | |
43 | - /** |
|
44 | - * Path where class paths cache files are written. |
|
45 | - * |
|
46 | - * @var string |
|
47 | - */ |
|
48 | - protected $cacheDir; |
|
43 | + /** |
|
44 | + * Path where class paths cache files are written. |
|
45 | + * |
|
46 | + * @var string |
|
47 | + */ |
|
48 | + protected $cacheDir; |
|
49 | 49 | |
50 | - /** |
|
51 | - * Path where builtin plugins are stored. |
|
52 | - * |
|
53 | - * @var string |
|
54 | - */ |
|
55 | - protected $corePluginDir; |
|
50 | + /** |
|
51 | + * Path where builtin plugins are stored. |
|
52 | + * |
|
53 | + * @var string |
|
54 | + */ |
|
55 | + protected $corePluginDir; |
|
56 | 56 | |
57 | - /** |
|
58 | - * Loader constructor. |
|
59 | - * |
|
60 | - * @param $cacheDir |
|
61 | - */ |
|
62 | - public function __construct($cacheDir) |
|
63 | - { |
|
64 | - $this->corePluginDir = __DIR__ . DIRECTORY_SEPARATOR . 'Plugins'; |
|
65 | - $this->cacheDir = rtrim($cacheDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; |
|
57 | + /** |
|
58 | + * Loader constructor. |
|
59 | + * |
|
60 | + * @param $cacheDir |
|
61 | + */ |
|
62 | + public function __construct($cacheDir) |
|
63 | + { |
|
64 | + $this->corePluginDir = __DIR__ . DIRECTORY_SEPARATOR . 'Plugins'; |
|
65 | + $this->cacheDir = rtrim($cacheDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; |
|
66 | 66 | |
67 | - // include class paths or rebuild paths if the cache file isn't there |
|
68 | - $cacheFile = $this->cacheDir . 'classpath.cache.d' . Core::RELEASE_TAG . '.php'; |
|
69 | - if (file_exists($cacheFile)) { |
|
70 | - $classpath = file_get_contents($cacheFile); |
|
71 | - $this->classPath = unserialize($classpath) + $this->classPath; |
|
72 | - } else { |
|
73 | - $this->rebuildClassPathCache($this->corePluginDir, $cacheFile); |
|
74 | - } |
|
75 | - } |
|
67 | + // include class paths or rebuild paths if the cache file isn't there |
|
68 | + $cacheFile = $this->cacheDir . 'classpath.cache.d' . Core::RELEASE_TAG . '.php'; |
|
69 | + if (file_exists($cacheFile)) { |
|
70 | + $classpath = file_get_contents($cacheFile); |
|
71 | + $this->classPath = unserialize($classpath) + $this->classPath; |
|
72 | + } else { |
|
73 | + $this->rebuildClassPathCache($this->corePluginDir, $cacheFile); |
|
74 | + } |
|
75 | + } |
|
76 | 76 | |
77 | - /** |
|
78 | - * Rebuilds class paths, scans the given directory recursively and saves all paths in the given file. |
|
79 | - * |
|
80 | - * @param string $path the plugin path to scan |
|
81 | - * @param string $cacheFile the file where to store the plugin paths cache, it will be overwritten |
|
82 | - * |
|
83 | - * @throws Exception |
|
84 | - */ |
|
85 | - protected function rebuildClassPathCache($path, $cacheFile) |
|
86 | - { |
|
87 | - if ($cacheFile !== false) { |
|
88 | - $tmp = $this->classPath; |
|
89 | - $this->classPath = array(); |
|
90 | - } |
|
77 | + /** |
|
78 | + * Rebuilds class paths, scans the given directory recursively and saves all paths in the given file. |
|
79 | + * |
|
80 | + * @param string $path the plugin path to scan |
|
81 | + * @param string $cacheFile the file where to store the plugin paths cache, it will be overwritten |
|
82 | + * |
|
83 | + * @throws Exception |
|
84 | + */ |
|
85 | + protected function rebuildClassPathCache($path, $cacheFile) |
|
86 | + { |
|
87 | + if ($cacheFile !== false) { |
|
88 | + $tmp = $this->classPath; |
|
89 | + $this->classPath = array(); |
|
90 | + } |
|
91 | 91 | |
92 | - // iterates over all files/folders |
|
93 | - $list = glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*'); |
|
94 | - if (is_array($list)) { |
|
95 | - foreach ($list as $f) { |
|
96 | - if (is_dir($f)) { |
|
97 | - $this->rebuildClassPathCache($f, false); |
|
98 | - } else { |
|
99 | - // TODO: is it still valid now? |
|
100 | - $this->classPath[str_replace(array( |
|
101 | - 'function.', |
|
102 | - 'block.', |
|
103 | - 'modifier.', |
|
104 | - 'outputfilter.', |
|
105 | - 'filter.', |
|
106 | - 'prefilter.', |
|
107 | - 'postfilter.', |
|
108 | - 'pre.', |
|
109 | - 'post.', |
|
110 | - 'output.', |
|
111 | - 'shared.', |
|
112 | - 'helper.' |
|
113 | - ), '', basename($f, '.php'))] = $f; |
|
114 | - } |
|
115 | - } |
|
116 | - } |
|
92 | + // iterates over all files/folders |
|
93 | + $list = glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*'); |
|
94 | + if (is_array($list)) { |
|
95 | + foreach ($list as $f) { |
|
96 | + if (is_dir($f)) { |
|
97 | + $this->rebuildClassPathCache($f, false); |
|
98 | + } else { |
|
99 | + // TODO: is it still valid now? |
|
100 | + $this->classPath[str_replace(array( |
|
101 | + 'function.', |
|
102 | + 'block.', |
|
103 | + 'modifier.', |
|
104 | + 'outputfilter.', |
|
105 | + 'filter.', |
|
106 | + 'prefilter.', |
|
107 | + 'postfilter.', |
|
108 | + 'pre.', |
|
109 | + 'post.', |
|
110 | + 'output.', |
|
111 | + 'shared.', |
|
112 | + 'helper.' |
|
113 | + ), '', basename($f, '.php'))] = $f; |
|
114 | + } |
|
115 | + } |
|
116 | + } |
|
117 | 117 | |
118 | - // save in file if it's the first call (not recursed) |
|
119 | - if ($cacheFile !== false) { |
|
120 | - if (!file_put_contents($cacheFile, serialize($this->classPath))) { |
|
121 | - throw new Exception('Could not write into ' . $cacheFile . |
|
122 | - ', either because the folder is not there (create it) or because of the chmod configuration (please ensure this directory is writable by php), alternatively you can change the directory used with $dwoo->setCompileDir() or provide a custom loader object with $dwoo->setLoader()'); |
|
123 | - } |
|
124 | - $this->classPath += $tmp; |
|
125 | - } |
|
126 | - } |
|
118 | + // save in file if it's the first call (not recursed) |
|
119 | + if ($cacheFile !== false) { |
|
120 | + if (!file_put_contents($cacheFile, serialize($this->classPath))) { |
|
121 | + throw new Exception('Could not write into ' . $cacheFile . |
|
122 | + ', either because the folder is not there (create it) or because of the chmod configuration (please ensure this directory is writable by php), alternatively you can change the directory used with $dwoo->setCompileDir() or provide a custom loader object with $dwoo->setLoader()'); |
|
123 | + } |
|
124 | + $this->classPath += $tmp; |
|
125 | + } |
|
126 | + } |
|
127 | 127 | |
128 | - /** |
|
129 | - * Loads a plugin file. |
|
130 | - * |
|
131 | - * @param string $class the plugin name, without the `Plugin` prefix |
|
132 | - * @param bool $forceRehash if true, the class path caches will be rebuilt if the plugin is not found, in case it |
|
133 | - * has just been added, defaults to true |
|
134 | - * |
|
135 | - * @throws Exception |
|
136 | - */ |
|
137 | - public function loadPlugin($class, $forceRehash = true) |
|
138 | - { |
|
139 | - /** |
|
140 | - * An unknown class was requested (maybe newly added) or the |
|
141 | - * include failed so we rebuild the cache. include() will fail |
|
142 | - * with an uncatchable error if the file doesn't exist, which |
|
143 | - * usually means that the cache is stale and must be rebuilt, |
|
144 | - * so we check for that before trying to include() the plugin. |
|
145 | - */ |
|
146 | - if ((!isset($this->classPath[$class]) || !is_readable($this->classPath[$class])) || (!isset |
|
147 | - ($this->classPath[$class . 'Compile']) || !is_readable($this->classPath[$class . 'Compile']))) { |
|
148 | - if ($forceRehash) { |
|
149 | - $this->rebuildClassPathCache($this->corePluginDir, $this->cacheDir . 'classpath.cache.d' . |
|
150 | - Core::RELEASE_TAG . '.php'); |
|
151 | - foreach ($this->paths as $path => $file) { |
|
152 | - $this->rebuildClassPathCache($path, $file); |
|
153 | - } |
|
154 | - if (isset($this->classPath[$class])) { |
|
155 | - include_once $this->classPath[$class]; |
|
156 | - } elseif (isset($this->classPath[$class . 'Compile'])) { |
|
157 | - include_once $this->classPath[$class . 'Compile']; |
|
158 | - } else { |
|
159 | - throw new Exception('Plugin "' . $class . |
|
160 | - '" can not be found, maybe you forgot to bind it if it\'s a custom plugin ?', E_USER_NOTICE); |
|
161 | - } |
|
162 | - } else { |
|
163 | - throw new Exception('Plugin "' . $class . |
|
164 | - '" can not be found, maybe you forgot to bind it if it\'s a custom plugin ?', E_USER_NOTICE); |
|
165 | - } |
|
166 | - } |
|
167 | - } |
|
128 | + /** |
|
129 | + * Loads a plugin file. |
|
130 | + * |
|
131 | + * @param string $class the plugin name, without the `Plugin` prefix |
|
132 | + * @param bool $forceRehash if true, the class path caches will be rebuilt if the plugin is not found, in case it |
|
133 | + * has just been added, defaults to true |
|
134 | + * |
|
135 | + * @throws Exception |
|
136 | + */ |
|
137 | + public function loadPlugin($class, $forceRehash = true) |
|
138 | + { |
|
139 | + /** |
|
140 | + * An unknown class was requested (maybe newly added) or the |
|
141 | + * include failed so we rebuild the cache. include() will fail |
|
142 | + * with an uncatchable error if the file doesn't exist, which |
|
143 | + * usually means that the cache is stale and must be rebuilt, |
|
144 | + * so we check for that before trying to include() the plugin. |
|
145 | + */ |
|
146 | + if ((!isset($this->classPath[$class]) || !is_readable($this->classPath[$class])) || (!isset |
|
147 | + ($this->classPath[$class . 'Compile']) || !is_readable($this->classPath[$class . 'Compile']))) { |
|
148 | + if ($forceRehash) { |
|
149 | + $this->rebuildClassPathCache($this->corePluginDir, $this->cacheDir . 'classpath.cache.d' . |
|
150 | + Core::RELEASE_TAG . '.php'); |
|
151 | + foreach ($this->paths as $path => $file) { |
|
152 | + $this->rebuildClassPathCache($path, $file); |
|
153 | + } |
|
154 | + if (isset($this->classPath[$class])) { |
|
155 | + include_once $this->classPath[$class]; |
|
156 | + } elseif (isset($this->classPath[$class . 'Compile'])) { |
|
157 | + include_once $this->classPath[$class . 'Compile']; |
|
158 | + } else { |
|
159 | + throw new Exception('Plugin "' . $class . |
|
160 | + '" can not be found, maybe you forgot to bind it if it\'s a custom plugin ?', E_USER_NOTICE); |
|
161 | + } |
|
162 | + } else { |
|
163 | + throw new Exception('Plugin "' . $class . |
|
164 | + '" can not be found, maybe you forgot to bind it if it\'s a custom plugin ?', E_USER_NOTICE); |
|
165 | + } |
|
166 | + } |
|
167 | + } |
|
168 | 168 | |
169 | - /** |
|
170 | - * Adds a plugin directory, the plugins found in the new plugin directory |
|
171 | - * will take precedence over the other directories (including the default |
|
172 | - * dwoo plugin directory), you can use this for example to override plugins |
|
173 | - * in a specific directory for a specific application while keeping all your |
|
174 | - * usual plugins in the same place for all applications. |
|
175 | - * TOCOM don't forget that php functions overrides are not rehashed so you |
|
176 | - * need to clear the classpath caches by hand when adding those. |
|
177 | - * |
|
178 | - * @param string $pluginDirectory the plugin path to scan |
|
179 | - * |
|
180 | - * @throws Exception |
|
181 | - */ |
|
182 | - public function addDirectory($pluginDirectory) |
|
183 | - { |
|
184 | - $pluginDir = realpath($pluginDirectory); |
|
185 | - if (!$pluginDir) { |
|
186 | - throw new Exception('Plugin directory does not exist or can not be read : ' . $pluginDirectory); |
|
187 | - } |
|
188 | - $cacheFile = $this->cacheDir . 'classpath-' . substr(strtr($pluginDir, '/\\:' . PATH_SEPARATOR, '----'), |
|
189 | - strlen($pluginDir) > 80 ? - 80 : 0) . '.d' . Core::RELEASE_TAG . '.php'; |
|
190 | - $this->paths[$pluginDir] = $cacheFile; |
|
191 | - if (file_exists($cacheFile)) { |
|
192 | - $classpath = file_get_contents($cacheFile); |
|
193 | - $this->classPath = unserialize($classpath) + $this->classPath; |
|
194 | - } else { |
|
195 | - $this->rebuildClassPathCache($pluginDir, $cacheFile); |
|
196 | - } |
|
197 | - } |
|
169 | + /** |
|
170 | + * Adds a plugin directory, the plugins found in the new plugin directory |
|
171 | + * will take precedence over the other directories (including the default |
|
172 | + * dwoo plugin directory), you can use this for example to override plugins |
|
173 | + * in a specific directory for a specific application while keeping all your |
|
174 | + * usual plugins in the same place for all applications. |
|
175 | + * TOCOM don't forget that php functions overrides are not rehashed so you |
|
176 | + * need to clear the classpath caches by hand when adding those. |
|
177 | + * |
|
178 | + * @param string $pluginDirectory the plugin path to scan |
|
179 | + * |
|
180 | + * @throws Exception |
|
181 | + */ |
|
182 | + public function addDirectory($pluginDirectory) |
|
183 | + { |
|
184 | + $pluginDir = realpath($pluginDirectory); |
|
185 | + if (!$pluginDir) { |
|
186 | + throw new Exception('Plugin directory does not exist or can not be read : ' . $pluginDirectory); |
|
187 | + } |
|
188 | + $cacheFile = $this->cacheDir . 'classpath-' . substr(strtr($pluginDir, '/\\:' . PATH_SEPARATOR, '----'), |
|
189 | + strlen($pluginDir) > 80 ? - 80 : 0) . '.d' . Core::RELEASE_TAG . '.php'; |
|
190 | + $this->paths[$pluginDir] = $cacheFile; |
|
191 | + if (file_exists($cacheFile)) { |
|
192 | + $classpath = file_get_contents($cacheFile); |
|
193 | + $this->classPath = unserialize($classpath) + $this->classPath; |
|
194 | + } else { |
|
195 | + $this->rebuildClassPathCache($pluginDir, $cacheFile); |
|
196 | + } |
|
197 | + } |
|
198 | 198 | } |
@@ -61,14 +61,14 @@ discard block |
||
61 | 61 | */ |
62 | 62 | public function __construct($cacheDir) |
63 | 63 | { |
64 | - $this->corePluginDir = __DIR__ . DIRECTORY_SEPARATOR . 'Plugins'; |
|
65 | - $this->cacheDir = rtrim($cacheDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; |
|
64 | + $this->corePluginDir = __DIR__.DIRECTORY_SEPARATOR.'Plugins'; |
|
65 | + $this->cacheDir = rtrim($cacheDir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR; |
|
66 | 66 | |
67 | 67 | // include class paths or rebuild paths if the cache file isn't there |
68 | - $cacheFile = $this->cacheDir . 'classpath.cache.d' . Core::RELEASE_TAG . '.php'; |
|
68 | + $cacheFile = $this->cacheDir.'classpath.cache.d'.Core::RELEASE_TAG.'.php'; |
|
69 | 69 | if (file_exists($cacheFile)) { |
70 | 70 | $classpath = file_get_contents($cacheFile); |
71 | - $this->classPath = unserialize($classpath) + $this->classPath; |
|
71 | + $this->classPath = unserialize($classpath)+$this->classPath; |
|
72 | 72 | } else { |
73 | 73 | $this->rebuildClassPathCache($this->corePluginDir, $cacheFile); |
74 | 74 | } |
@@ -90,7 +90,7 @@ discard block |
||
90 | 90 | } |
91 | 91 | |
92 | 92 | // iterates over all files/folders |
93 | - $list = glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*'); |
|
93 | + $list = glob(rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.'*'); |
|
94 | 94 | if (is_array($list)) { |
95 | 95 | foreach ($list as $f) { |
96 | 96 | if (is_dir($f)) { |
@@ -118,7 +118,7 @@ discard block |
||
118 | 118 | // save in file if it's the first call (not recursed) |
119 | 119 | if ($cacheFile !== false) { |
120 | 120 | if (!file_put_contents($cacheFile, serialize($this->classPath))) { |
121 | - throw new Exception('Could not write into ' . $cacheFile . |
|
121 | + throw new Exception('Could not write into '.$cacheFile. |
|
122 | 122 | ', either because the folder is not there (create it) or because of the chmod configuration (please ensure this directory is writable by php), alternatively you can change the directory used with $dwoo->setCompileDir() or provide a custom loader object with $dwoo->setLoader()'); |
123 | 123 | } |
124 | 124 | $this->classPath += $tmp; |
@@ -144,23 +144,23 @@ discard block |
||
144 | 144 | * so we check for that before trying to include() the plugin. |
145 | 145 | */ |
146 | 146 | if ((!isset($this->classPath[$class]) || !is_readable($this->classPath[$class])) || (!isset |
147 | - ($this->classPath[$class . 'Compile']) || !is_readable($this->classPath[$class . 'Compile']))) { |
|
147 | + ($this->classPath[$class.'Compile']) || !is_readable($this->classPath[$class.'Compile']))) { |
|
148 | 148 | if ($forceRehash) { |
149 | - $this->rebuildClassPathCache($this->corePluginDir, $this->cacheDir . 'classpath.cache.d' . |
|
150 | - Core::RELEASE_TAG . '.php'); |
|
149 | + $this->rebuildClassPathCache($this->corePluginDir, $this->cacheDir.'classpath.cache.d'. |
|
150 | + Core::RELEASE_TAG.'.php'); |
|
151 | 151 | foreach ($this->paths as $path => $file) { |
152 | 152 | $this->rebuildClassPathCache($path, $file); |
153 | 153 | } |
154 | 154 | if (isset($this->classPath[$class])) { |
155 | 155 | include_once $this->classPath[$class]; |
156 | - } elseif (isset($this->classPath[$class . 'Compile'])) { |
|
157 | - include_once $this->classPath[$class . 'Compile']; |
|
156 | + } elseif (isset($this->classPath[$class.'Compile'])) { |
|
157 | + include_once $this->classPath[$class.'Compile']; |
|
158 | 158 | } else { |
159 | - throw new Exception('Plugin "' . $class . |
|
159 | + throw new Exception('Plugin "'.$class. |
|
160 | 160 | '" can not be found, maybe you forgot to bind it if it\'s a custom plugin ?', E_USER_NOTICE); |
161 | 161 | } |
162 | 162 | } else { |
163 | - throw new Exception('Plugin "' . $class . |
|
163 | + throw new Exception('Plugin "'.$class. |
|
164 | 164 | '" can not be found, maybe you forgot to bind it if it\'s a custom plugin ?', E_USER_NOTICE); |
165 | 165 | } |
166 | 166 | } |
@@ -183,14 +183,14 @@ discard block |
||
183 | 183 | { |
184 | 184 | $pluginDir = realpath($pluginDirectory); |
185 | 185 | if (!$pluginDir) { |
186 | - throw new Exception('Plugin directory does not exist or can not be read : ' . $pluginDirectory); |
|
186 | + throw new Exception('Plugin directory does not exist or can not be read : '.$pluginDirectory); |
|
187 | 187 | } |
188 | - $cacheFile = $this->cacheDir . 'classpath-' . substr(strtr($pluginDir, '/\\:' . PATH_SEPARATOR, '----'), |
|
189 | - strlen($pluginDir) > 80 ? - 80 : 0) . '.d' . Core::RELEASE_TAG . '.php'; |
|
188 | + $cacheFile = $this->cacheDir.'classpath-'.substr(strtr($pluginDir, '/\\:'.PATH_SEPARATOR, '----'), |
|
189 | + strlen($pluginDir) > 80 ? -80 : 0).'.d'.Core::RELEASE_TAG.'.php'; |
|
190 | 190 | $this->paths[$pluginDir] = $cacheFile; |
191 | 191 | if (file_exists($cacheFile)) { |
192 | 192 | $classpath = file_get_contents($cacheFile); |
193 | - $this->classPath = unserialize($classpath) + $this->classPath; |
|
193 | + $this->classPath = unserialize($classpath)+$this->classPath; |
|
194 | 194 | } else { |
195 | 195 | $this->rebuildClassPathCache($pluginDir, $cacheFile); |
196 | 196 | } |
@@ -85,8 +85,8 @@ |
||
85 | 85 | |
86 | 86 | /** |
87 | 87 | * @param $output |
88 | - * @param $dynamicId |
|
89 | - * @param $compiledFile |
|
88 | + * @param string $dynamicId |
|
89 | + * @param string $compiledFile |
|
90 | 90 | * |
91 | 91 | * @return mixed|string |
92 | 92 | */ |
@@ -28,89 +28,89 @@ |
||
28 | 28 | */ |
29 | 29 | class PluginDynamic extends BlockPlugin implements ICompilableBlock |
30 | 30 | { |
31 | - /** |
|
32 | - * |
|
33 | - */ |
|
34 | - public function init() |
|
35 | - { |
|
36 | - } |
|
31 | + /** |
|
32 | + * |
|
33 | + */ |
|
34 | + public function init() |
|
35 | + { |
|
36 | + } |
|
37 | 37 | |
38 | - /** |
|
39 | - * @param Compiler $compiler |
|
40 | - * @param array $params |
|
41 | - * @param string $prepend |
|
42 | - * @param string $append |
|
43 | - * @param string $type |
|
44 | - * |
|
45 | - * @return string |
|
46 | - */ |
|
47 | - public static function preProcessing(Compiler $compiler, array $params, $prepend, $append, $type) |
|
48 | - { |
|
49 | - return ''; |
|
50 | - } |
|
38 | + /** |
|
39 | + * @param Compiler $compiler |
|
40 | + * @param array $params |
|
41 | + * @param string $prepend |
|
42 | + * @param string $append |
|
43 | + * @param string $type |
|
44 | + * |
|
45 | + * @return string |
|
46 | + */ |
|
47 | + public static function preProcessing(Compiler $compiler, array $params, $prepend, $append, $type) |
|
48 | + { |
|
49 | + return ''; |
|
50 | + } |
|
51 | 51 | |
52 | - /** |
|
53 | - * @param Compiler $compiler |
|
54 | - * @param array $params |
|
55 | - * @param string $prepend |
|
56 | - * @param string $append |
|
57 | - * @param string $content |
|
58 | - * |
|
59 | - * @return string |
|
60 | - */ |
|
61 | - public static function postProcessing(Compiler $compiler, array $params, $prepend, $append, $content) |
|
62 | - { |
|
63 | - try { |
|
64 | - $compiler->findBlock('dynamic'); |
|
52 | + /** |
|
53 | + * @param Compiler $compiler |
|
54 | + * @param array $params |
|
55 | + * @param string $prepend |
|
56 | + * @param string $append |
|
57 | + * @param string $content |
|
58 | + * |
|
59 | + * @return string |
|
60 | + */ |
|
61 | + public static function postProcessing(Compiler $compiler, array $params, $prepend, $append, $content) |
|
62 | + { |
|
63 | + try { |
|
64 | + $compiler->findBlock('dynamic'); |
|
65 | 65 | |
66 | - return $content; |
|
67 | - } |
|
68 | - catch (CompilationException $e) { |
|
69 | - } |
|
70 | - $output = Compiler::PHP_OPEN . 'if($doCache) {' . "\n\t" . 'echo \'<dwoo:dynamic_\'.$dynamicId.\'>' . str_replace('\'', '\\\'', $content) . '</dwoo:dynamic_\'.$dynamicId.\'>\';' . "\n} else {\n\t"; |
|
71 | - if (substr($content, 0, strlen(Compiler::PHP_OPEN)) == Compiler::PHP_OPEN) { |
|
72 | - $output .= substr($content, strlen(Compiler::PHP_OPEN)); |
|
73 | - } else { |
|
74 | - $output .= Compiler::PHP_CLOSE . $content; |
|
75 | - } |
|
76 | - if (substr($output, - strlen(Compiler::PHP_CLOSE)) == Compiler::PHP_CLOSE) { |
|
77 | - $output = substr($output, 0, - strlen(Compiler::PHP_CLOSE)); |
|
78 | - } else { |
|
79 | - $output .= Compiler::PHP_OPEN; |
|
80 | - } |
|
81 | - $output .= "\n}" . Compiler::PHP_CLOSE; |
|
66 | + return $content; |
|
67 | + } |
|
68 | + catch (CompilationException $e) { |
|
69 | + } |
|
70 | + $output = Compiler::PHP_OPEN . 'if($doCache) {' . "\n\t" . 'echo \'<dwoo:dynamic_\'.$dynamicId.\'>' . str_replace('\'', '\\\'', $content) . '</dwoo:dynamic_\'.$dynamicId.\'>\';' . "\n} else {\n\t"; |
|
71 | + if (substr($content, 0, strlen(Compiler::PHP_OPEN)) == Compiler::PHP_OPEN) { |
|
72 | + $output .= substr($content, strlen(Compiler::PHP_OPEN)); |
|
73 | + } else { |
|
74 | + $output .= Compiler::PHP_CLOSE . $content; |
|
75 | + } |
|
76 | + if (substr($output, - strlen(Compiler::PHP_CLOSE)) == Compiler::PHP_CLOSE) { |
|
77 | + $output = substr($output, 0, - strlen(Compiler::PHP_CLOSE)); |
|
78 | + } else { |
|
79 | + $output .= Compiler::PHP_OPEN; |
|
80 | + } |
|
81 | + $output .= "\n}" . Compiler::PHP_CLOSE; |
|
82 | 82 | |
83 | - return $output; |
|
84 | - } |
|
83 | + return $output; |
|
84 | + } |
|
85 | 85 | |
86 | - /** |
|
87 | - * @param $output |
|
88 | - * @param $dynamicId |
|
89 | - * @param $compiledFile |
|
90 | - * |
|
91 | - * @return mixed|string |
|
92 | - */ |
|
93 | - public static function unescape($output, $dynamicId, $compiledFile) |
|
94 | - { |
|
95 | - $output = preg_replace_callback('/<dwoo:dynamic_(' . $dynamicId . ')>(.+?)<\/dwoo:dynamic_' . $dynamicId . '>/s', array( |
|
96 | - 'self', |
|
97 | - 'unescapePhp' |
|
98 | - ), $output, - 1, $count); |
|
99 | - // re-add the includes on top of the file |
|
100 | - if ($count && preg_match('#/\* template head \*/(.+?)/\* end template head \*/#s', file_get_contents($compiledFile), $m)) { |
|
101 | - $output = '<?php ' . $m[1] . ' ?>' . $output; |
|
102 | - } |
|
86 | + /** |
|
87 | + * @param $output |
|
88 | + * @param $dynamicId |
|
89 | + * @param $compiledFile |
|
90 | + * |
|
91 | + * @return mixed|string |
|
92 | + */ |
|
93 | + public static function unescape($output, $dynamicId, $compiledFile) |
|
94 | + { |
|
95 | + $output = preg_replace_callback('/<dwoo:dynamic_(' . $dynamicId . ')>(.+?)<\/dwoo:dynamic_' . $dynamicId . '>/s', array( |
|
96 | + 'self', |
|
97 | + 'unescapePhp' |
|
98 | + ), $output, - 1, $count); |
|
99 | + // re-add the includes on top of the file |
|
100 | + if ($count && preg_match('#/\* template head \*/(.+?)/\* end template head \*/#s', file_get_contents($compiledFile), $m)) { |
|
101 | + $output = '<?php ' . $m[1] . ' ?>' . $output; |
|
102 | + } |
|
103 | 103 | |
104 | - return $output; |
|
105 | - } |
|
104 | + return $output; |
|
105 | + } |
|
106 | 106 | |
107 | - /** |
|
108 | - * @param $match |
|
109 | - * |
|
110 | - * @return mixed |
|
111 | - */ |
|
112 | - public static function unescapePhp($match) |
|
113 | - { |
|
114 | - return preg_replace('{<\?php /\*' . $match[1] . '\*/ echo \'(.+?)\'; \?>}s', '$1', $match[2]); |
|
115 | - } |
|
107 | + /** |
|
108 | + * @param $match |
|
109 | + * |
|
110 | + * @return mixed |
|
111 | + */ |
|
112 | + public static function unescapePhp($match) |
|
113 | + { |
|
114 | + return preg_replace('{<\?php /\*' . $match[1] . '\*/ echo \'(.+?)\'; \?>}s', '$1', $match[2]); |
|
115 | + } |
|
116 | 116 | } |
@@ -67,18 +67,18 @@ discard block |
||
67 | 67 | } |
68 | 68 | catch (CompilationException $e) { |
69 | 69 | } |
70 | - $output = Compiler::PHP_OPEN . 'if($doCache) {' . "\n\t" . 'echo \'<dwoo:dynamic_\'.$dynamicId.\'>' . str_replace('\'', '\\\'', $content) . '</dwoo:dynamic_\'.$dynamicId.\'>\';' . "\n} else {\n\t"; |
|
70 | + $output = Compiler::PHP_OPEN.'if($doCache) {'."\n\t".'echo \'<dwoo:dynamic_\'.$dynamicId.\'>'.str_replace('\'', '\\\'', $content).'</dwoo:dynamic_\'.$dynamicId.\'>\';'."\n} else {\n\t"; |
|
71 | 71 | if (substr($content, 0, strlen(Compiler::PHP_OPEN)) == Compiler::PHP_OPEN) { |
72 | 72 | $output .= substr($content, strlen(Compiler::PHP_OPEN)); |
73 | 73 | } else { |
74 | - $output .= Compiler::PHP_CLOSE . $content; |
|
74 | + $output .= Compiler::PHP_CLOSE.$content; |
|
75 | 75 | } |
76 | 76 | if (substr($output, - strlen(Compiler::PHP_CLOSE)) == Compiler::PHP_CLOSE) { |
77 | 77 | $output = substr($output, 0, - strlen(Compiler::PHP_CLOSE)); |
78 | 78 | } else { |
79 | 79 | $output .= Compiler::PHP_OPEN; |
80 | 80 | } |
81 | - $output .= "\n}" . Compiler::PHP_CLOSE; |
|
81 | + $output .= "\n}".Compiler::PHP_CLOSE; |
|
82 | 82 | |
83 | 83 | return $output; |
84 | 84 | } |
@@ -92,13 +92,13 @@ discard block |
||
92 | 92 | */ |
93 | 93 | public static function unescape($output, $dynamicId, $compiledFile) |
94 | 94 | { |
95 | - $output = preg_replace_callback('/<dwoo:dynamic_(' . $dynamicId . ')>(.+?)<\/dwoo:dynamic_' . $dynamicId . '>/s', array( |
|
95 | + $output = preg_replace_callback('/<dwoo:dynamic_('.$dynamicId.')>(.+?)<\/dwoo:dynamic_'.$dynamicId.'>/s', array( |
|
96 | 96 | 'self', |
97 | 97 | 'unescapePhp' |
98 | 98 | ), $output, - 1, $count); |
99 | 99 | // re-add the includes on top of the file |
100 | 100 | if ($count && preg_match('#/\* template head \*/(.+?)/\* end template head \*/#s', file_get_contents($compiledFile), $m)) { |
101 | - $output = '<?php ' . $m[1] . ' ?>' . $output; |
|
101 | + $output = '<?php '.$m[1].' ?>'.$output; |
|
102 | 102 | } |
103 | 103 | |
104 | 104 | return $output; |
@@ -111,6 +111,6 @@ discard block |
||
111 | 111 | */ |
112 | 112 | public static function unescapePhp($match) |
113 | 113 | { |
114 | - return preg_replace('{<\?php /\*' . $match[1] . '\*/ echo \'(.+?)\'; \?>}s', '$1', $match[2]); |
|
114 | + return preg_replace('{<\?php /\*'.$match[1].'\*/ echo \'(.+?)\'; \?>}s', '$1', $match[2]); |
|
115 | 115 | } |
116 | 116 | } |
@@ -64,8 +64,7 @@ |
||
64 | 64 | $compiler->findBlock('dynamic'); |
65 | 65 | |
66 | 66 | return $content; |
67 | - } |
|
68 | - catch (CompilationException $e) { |
|
67 | + } catch (CompilationException $e) { |
|
69 | 68 | } |
70 | 69 | $output = Compiler::PHP_OPEN . 'if($doCache) {' . "\n\t" . 'echo \'<dwoo:dynamic_\'.$dynamicId.\'>' . str_replace('\'', '\\\'', $content) . '</dwoo:dynamic_\'.$dynamicId.\'>\';' . "\n} else {\n\t"; |
71 | 70 | if (substr($content, 0, strlen(Compiler::PHP_OPEN)) == Compiler::PHP_OPEN) { |
@@ -59,7 +59,7 @@ |
||
59 | 59 | * @param string $append |
60 | 60 | * @param string $content |
61 | 61 | * |
62 | - * @return mixed|string |
|
62 | + * @return string |
|
63 | 63 | */ |
64 | 64 | public static function postProcessing(Compiler $compiler, array $params, $prepend, $append, $content) |
65 | 65 | { |
@@ -31,59 +31,59 @@ |
||
31 | 31 | */ |
32 | 32 | class PluginStrip extends BlockPlugin implements ICompilableBlock |
33 | 33 | { |
34 | - /** |
|
35 | - * @param string $mode |
|
36 | - */ |
|
37 | - public function init($mode = 'default') |
|
38 | - { |
|
39 | - } |
|
34 | + /** |
|
35 | + * @param string $mode |
|
36 | + */ |
|
37 | + public function init($mode = 'default') |
|
38 | + { |
|
39 | + } |
|
40 | 40 | |
41 | - /** |
|
42 | - * @param Compiler $compiler |
|
43 | - * @param array $params |
|
44 | - * @param string $prepend |
|
45 | - * @param string $append |
|
46 | - * @param string $type |
|
47 | - * |
|
48 | - * @return string |
|
49 | - */ |
|
50 | - public static function preProcessing(Compiler $compiler, array $params, $prepend, $append, $type) |
|
51 | - { |
|
52 | - return ''; |
|
53 | - } |
|
41 | + /** |
|
42 | + * @param Compiler $compiler |
|
43 | + * @param array $params |
|
44 | + * @param string $prepend |
|
45 | + * @param string $append |
|
46 | + * @param string $type |
|
47 | + * |
|
48 | + * @return string |
|
49 | + */ |
|
50 | + public static function preProcessing(Compiler $compiler, array $params, $prepend, $append, $type) |
|
51 | + { |
|
52 | + return ''; |
|
53 | + } |
|
54 | 54 | |
55 | - /** |
|
56 | - * @param Compiler $compiler |
|
57 | - * @param array $params |
|
58 | - * @param string $prepend |
|
59 | - * @param string $append |
|
60 | - * @param string $content |
|
61 | - * |
|
62 | - * @return mixed|string |
|
63 | - */ |
|
64 | - public static function postProcessing(Compiler $compiler, array $params, $prepend, $append, $content) |
|
65 | - { |
|
66 | - $params = $compiler->getCompiledParams($params); |
|
55 | + /** |
|
56 | + * @param Compiler $compiler |
|
57 | + * @param array $params |
|
58 | + * @param string $prepend |
|
59 | + * @param string $append |
|
60 | + * @param string $content |
|
61 | + * |
|
62 | + * @return mixed|string |
|
63 | + */ |
|
64 | + public static function postProcessing(Compiler $compiler, array $params, $prepend, $append, $content) |
|
65 | + { |
|
66 | + $params = $compiler->getCompiledParams($params); |
|
67 | 67 | |
68 | - $mode = trim($params['mode'], '"\''); |
|
69 | - switch ($mode) { |
|
70 | - case 'js': |
|
71 | - case 'javascript': |
|
72 | - $content = preg_replace('#(?<!:)//\s[^\r\n]*|/\*.*?\*/#s', '', $content); |
|
68 | + $mode = trim($params['mode'], '"\''); |
|
69 | + switch ($mode) { |
|
70 | + case 'js': |
|
71 | + case 'javascript': |
|
72 | + $content = preg_replace('#(?<!:)//\s[^\r\n]*|/\*.*?\*/#s', '', $content); |
|
73 | 73 | |
74 | - case 'default': |
|
75 | - default: |
|
76 | - } |
|
77 | - $content = preg_replace(array( |
|
78 | - "/\n/", |
|
79 | - "/\r/", |
|
80 | - '/(<\?(?:php)?|<%)\s*/' |
|
81 | - ), array( |
|
82 | - '', |
|
83 | - '', |
|
84 | - '$1 ' |
|
85 | - ), preg_replace('#^\s*(.+?)\s*$#m', '$1', $content)); |
|
74 | + case 'default': |
|
75 | + default: |
|
76 | + } |
|
77 | + $content = preg_replace(array( |
|
78 | + "/\n/", |
|
79 | + "/\r/", |
|
80 | + '/(<\?(?:php)?|<%)\s*/' |
|
81 | + ), array( |
|
82 | + '', |
|
83 | + '', |
|
84 | + '$1 ' |
|
85 | + ), preg_replace('#^\s*(.+?)\s*$#m', '$1', $content)); |
|
86 | 86 | |
87 | - return $content; |
|
88 | - } |
|
87 | + return $content; |
|
88 | + } |
|
89 | 89 | } |
@@ -67,12 +67,12 @@ |
||
67 | 67 | |
68 | 68 | $mode = trim($params['mode'], '"\''); |
69 | 69 | switch ($mode) { |
70 | - case 'js': |
|
71 | - case 'javascript': |
|
72 | - $content = preg_replace('#(?<!:)//\s[^\r\n]*|/\*.*?\*/#s', '', $content); |
|
70 | + case 'js': |
|
71 | + case 'javascript': |
|
72 | + $content = preg_replace('#(?<!:)//\s[^\r\n]*|/\*.*?\*/#s', '', $content); |
|
73 | 73 | |
74 | - case 'default': |
|
75 | - default: |
|
74 | + case 'default': |
|
75 | + default: |
|
76 | 76 | } |
77 | 77 | $content = preg_replace(array( |
78 | 78 | "/\n/", |
@@ -86,6 +86,9 @@ discard block |
||
86 | 86 | return $out; |
87 | 87 | } |
88 | 88 | |
89 | + /** |
|
90 | + * @param string $i |
|
91 | + */ |
|
89 | 92 | protected function exportVar($i, $v) |
90 | 93 | { |
91 | 94 | if (is_string($v) || is_bool($v) || is_numeric($v)) { |
@@ -99,6 +102,9 @@ discard block |
||
99 | 102 | } |
100 | 103 | } |
101 | 104 | |
105 | + /** |
|
106 | + * @param string $i |
|
107 | + */ |
|
102 | 108 | protected function exportObj($i, $obj) |
103 | 109 | { |
104 | 110 | if (array_search($obj, $this->outputObjects, true) !== false) { |
@@ -29,156 +29,156 @@ |
||
29 | 29 | */ |
30 | 30 | class PluginDump extends Plugin |
31 | 31 | { |
32 | - protected $outputObjects; |
|
33 | - protected $outputMethods; |
|
34 | - |
|
35 | - public function process($var = '$', $show_methods = false) |
|
36 | - { |
|
37 | - $this->outputMethods = $show_methods; |
|
38 | - if ($var === '$') { |
|
39 | - $var = $this->core->getData(); |
|
40 | - $out = '<div style="background:#aaa; padding:5px; margin:5px; color:#000;">data'; |
|
41 | - } else { |
|
42 | - $out = '<div style="background:#aaa; padding:5px; margin:5px; color:#000;">dump'; |
|
43 | - } |
|
44 | - |
|
45 | - $this->outputObjects = array(); |
|
46 | - |
|
47 | - if (!is_array($var)) { |
|
48 | - if (is_object($var)) { |
|
49 | - return $this->exportObj('', $var); |
|
50 | - } else { |
|
51 | - return $this->exportVar('', $var); |
|
52 | - } |
|
53 | - } |
|
54 | - |
|
55 | - $scope = $this->core->getScope(); |
|
56 | - |
|
57 | - if ($var === $scope) { |
|
58 | - $out .= ' (current scope): <div style="background:#ccc;">'; |
|
59 | - } else { |
|
60 | - $out .= ':<div style="padding-left:20px;">'; |
|
61 | - } |
|
62 | - |
|
63 | - $out .= $this->export($var, $scope); |
|
64 | - |
|
65 | - return $out . '</div></div>'; |
|
66 | - } |
|
67 | - |
|
68 | - protected function export($var, $scope) |
|
69 | - { |
|
70 | - $out = ''; |
|
71 | - foreach ($var as $i => $v) { |
|
72 | - if (is_array($v) || (is_object($v) && $v instanceof Iterator)) { |
|
73 | - $out .= $i . ' (' . (is_array($v) ? 'array' : 'object: ' . get_class($v)) . ')'; |
|
74 | - if ($v === $scope) { |
|
75 | - $out .= ' (current scope):<div style="background:#ccc;padding-left:20px;">' . $this->export($v, $scope) . '</div>'; |
|
76 | - } else { |
|
77 | - $out .= ':<div style="padding-left:20px;">' . $this->export($v, $scope) . '</div>'; |
|
78 | - } |
|
79 | - } elseif (is_object($v)) { |
|
80 | - $out .= $this->exportObj($i . ' (object: ' . get_class($v) . '):', $v); |
|
81 | - } else { |
|
82 | - $out .= $this->exportVar($i . ' = ', $v); |
|
83 | - } |
|
84 | - } |
|
85 | - |
|
86 | - return $out; |
|
87 | - } |
|
88 | - |
|
89 | - protected function exportVar($i, $v) |
|
90 | - { |
|
91 | - if (is_string($v) || is_bool($v) || is_numeric($v)) { |
|
92 | - return $i . htmlentities(var_export($v, true)) . '<br />'; |
|
93 | - } elseif (is_null($v)) { |
|
94 | - return $i . 'null<br />'; |
|
95 | - } elseif (is_resource($v)) { |
|
96 | - return $i . 'resource(' . get_resource_type($v) . ')<br />'; |
|
97 | - } else { |
|
98 | - return $i . htmlentities(var_export($v, true)) . '<br />'; |
|
99 | - } |
|
100 | - } |
|
101 | - |
|
102 | - protected function exportObj($i, $obj) |
|
103 | - { |
|
104 | - if (array_search($obj, $this->outputObjects, true) !== false) { |
|
105 | - return $i . ' [recursion, skipped]<br />'; |
|
106 | - } |
|
107 | - |
|
108 | - $this->outputObjects[] = $obj; |
|
109 | - |
|
110 | - $list = (array)$obj; |
|
111 | - |
|
112 | - $protectedLength = strlen(get_class($obj)) + 2; |
|
113 | - |
|
114 | - $out = array(); |
|
115 | - |
|
116 | - if ($this->outputMethods) { |
|
117 | - $ref = new ReflectionObject($obj); |
|
118 | - |
|
119 | - foreach ($ref->getMethods() as $method) { |
|
120 | - if (!$method->isPublic()) { |
|
121 | - continue; |
|
122 | - } |
|
123 | - |
|
124 | - if (empty($out['method'])) { |
|
125 | - $out['method'] = ''; |
|
126 | - } |
|
127 | - |
|
128 | - $params = array(); |
|
129 | - foreach ($method->getParameters() as $param) { |
|
130 | - $params[] = ($param->isPassedByReference() ? '&' : '') . '$' . $param->getName() . ($param->isOptional() ? ' = ' . var_export($param->getDefaultValue(), true) : ''); |
|
131 | - } |
|
132 | - |
|
133 | - $out['method'] .= '(method) ' . $method->getName() . '(' . implode(', ', $params) . ')<br />'; |
|
134 | - } |
|
135 | - } |
|
136 | - |
|
137 | - foreach ($list as $attributeName => $attributeValue) { |
|
138 | - if (property_exists($obj, $attributeName)) { |
|
139 | - $key = 'public'; |
|
140 | - } elseif (substr($attributeName, 0, 3) === "\0*\0") { |
|
141 | - $key = 'protected'; |
|
142 | - $attributeName = substr($attributeName, 3); |
|
143 | - } else { |
|
144 | - $key = 'private'; |
|
145 | - $attributeName = substr($attributeName, $protectedLength); |
|
146 | - } |
|
147 | - |
|
148 | - if (empty($out[$key])) { |
|
149 | - $out[$key] = ''; |
|
150 | - } |
|
151 | - |
|
152 | - $out[$key] .= '(' . $key . ') '; |
|
153 | - |
|
154 | - if (is_array($attributeValue)) { |
|
155 | - $out[$key] .= $attributeName . ' (array):<br /> |
|
32 | + protected $outputObjects; |
|
33 | + protected $outputMethods; |
|
34 | + |
|
35 | + public function process($var = '$', $show_methods = false) |
|
36 | + { |
|
37 | + $this->outputMethods = $show_methods; |
|
38 | + if ($var === '$') { |
|
39 | + $var = $this->core->getData(); |
|
40 | + $out = '<div style="background:#aaa; padding:5px; margin:5px; color:#000;">data'; |
|
41 | + } else { |
|
42 | + $out = '<div style="background:#aaa; padding:5px; margin:5px; color:#000;">dump'; |
|
43 | + } |
|
44 | + |
|
45 | + $this->outputObjects = array(); |
|
46 | + |
|
47 | + if (!is_array($var)) { |
|
48 | + if (is_object($var)) { |
|
49 | + return $this->exportObj('', $var); |
|
50 | + } else { |
|
51 | + return $this->exportVar('', $var); |
|
52 | + } |
|
53 | + } |
|
54 | + |
|
55 | + $scope = $this->core->getScope(); |
|
56 | + |
|
57 | + if ($var === $scope) { |
|
58 | + $out .= ' (current scope): <div style="background:#ccc;">'; |
|
59 | + } else { |
|
60 | + $out .= ':<div style="padding-left:20px;">'; |
|
61 | + } |
|
62 | + |
|
63 | + $out .= $this->export($var, $scope); |
|
64 | + |
|
65 | + return $out . '</div></div>'; |
|
66 | + } |
|
67 | + |
|
68 | + protected function export($var, $scope) |
|
69 | + { |
|
70 | + $out = ''; |
|
71 | + foreach ($var as $i => $v) { |
|
72 | + if (is_array($v) || (is_object($v) && $v instanceof Iterator)) { |
|
73 | + $out .= $i . ' (' . (is_array($v) ? 'array' : 'object: ' . get_class($v)) . ')'; |
|
74 | + if ($v === $scope) { |
|
75 | + $out .= ' (current scope):<div style="background:#ccc;padding-left:20px;">' . $this->export($v, $scope) . '</div>'; |
|
76 | + } else { |
|
77 | + $out .= ':<div style="padding-left:20px;">' . $this->export($v, $scope) . '</div>'; |
|
78 | + } |
|
79 | + } elseif (is_object($v)) { |
|
80 | + $out .= $this->exportObj($i . ' (object: ' . get_class($v) . '):', $v); |
|
81 | + } else { |
|
82 | + $out .= $this->exportVar($i . ' = ', $v); |
|
83 | + } |
|
84 | + } |
|
85 | + |
|
86 | + return $out; |
|
87 | + } |
|
88 | + |
|
89 | + protected function exportVar($i, $v) |
|
90 | + { |
|
91 | + if (is_string($v) || is_bool($v) || is_numeric($v)) { |
|
92 | + return $i . htmlentities(var_export($v, true)) . '<br />'; |
|
93 | + } elseif (is_null($v)) { |
|
94 | + return $i . 'null<br />'; |
|
95 | + } elseif (is_resource($v)) { |
|
96 | + return $i . 'resource(' . get_resource_type($v) . ')<br />'; |
|
97 | + } else { |
|
98 | + return $i . htmlentities(var_export($v, true)) . '<br />'; |
|
99 | + } |
|
100 | + } |
|
101 | + |
|
102 | + protected function exportObj($i, $obj) |
|
103 | + { |
|
104 | + if (array_search($obj, $this->outputObjects, true) !== false) { |
|
105 | + return $i . ' [recursion, skipped]<br />'; |
|
106 | + } |
|
107 | + |
|
108 | + $this->outputObjects[] = $obj; |
|
109 | + |
|
110 | + $list = (array)$obj; |
|
111 | + |
|
112 | + $protectedLength = strlen(get_class($obj)) + 2; |
|
113 | + |
|
114 | + $out = array(); |
|
115 | + |
|
116 | + if ($this->outputMethods) { |
|
117 | + $ref = new ReflectionObject($obj); |
|
118 | + |
|
119 | + foreach ($ref->getMethods() as $method) { |
|
120 | + if (!$method->isPublic()) { |
|
121 | + continue; |
|
122 | + } |
|
123 | + |
|
124 | + if (empty($out['method'])) { |
|
125 | + $out['method'] = ''; |
|
126 | + } |
|
127 | + |
|
128 | + $params = array(); |
|
129 | + foreach ($method->getParameters() as $param) { |
|
130 | + $params[] = ($param->isPassedByReference() ? '&' : '') . '$' . $param->getName() . ($param->isOptional() ? ' = ' . var_export($param->getDefaultValue(), true) : ''); |
|
131 | + } |
|
132 | + |
|
133 | + $out['method'] .= '(method) ' . $method->getName() . '(' . implode(', ', $params) . ')<br />'; |
|
134 | + } |
|
135 | + } |
|
136 | + |
|
137 | + foreach ($list as $attributeName => $attributeValue) { |
|
138 | + if (property_exists($obj, $attributeName)) { |
|
139 | + $key = 'public'; |
|
140 | + } elseif (substr($attributeName, 0, 3) === "\0*\0") { |
|
141 | + $key = 'protected'; |
|
142 | + $attributeName = substr($attributeName, 3); |
|
143 | + } else { |
|
144 | + $key = 'private'; |
|
145 | + $attributeName = substr($attributeName, $protectedLength); |
|
146 | + } |
|
147 | + |
|
148 | + if (empty($out[$key])) { |
|
149 | + $out[$key] = ''; |
|
150 | + } |
|
151 | + |
|
152 | + $out[$key] .= '(' . $key . ') '; |
|
153 | + |
|
154 | + if (is_array($attributeValue)) { |
|
155 | + $out[$key] .= $attributeName . ' (array):<br /> |
|
156 | 156 | <div style="padding-left:20px;">' . $this->export($attributeValue, false) . '</div>'; |
157 | - } elseif (is_object($attributeValue)) { |
|
158 | - $out[$key] .= $this->exportObj($attributeName . ' (object: ' . get_class($attributeValue) . '):', $attributeValue); |
|
159 | - } else { |
|
160 | - $out[$key] .= $this->exportVar($attributeName . ' = ', $attributeValue); |
|
161 | - } |
|
162 | - } |
|
157 | + } elseif (is_object($attributeValue)) { |
|
158 | + $out[$key] .= $this->exportObj($attributeName . ' (object: ' . get_class($attributeValue) . '):', $attributeValue); |
|
159 | + } else { |
|
160 | + $out[$key] .= $this->exportVar($attributeName . ' = ', $attributeValue); |
|
161 | + } |
|
162 | + } |
|
163 | 163 | |
164 | - $return = $i . '<br /><div style="padding-left:20px;">'; |
|
164 | + $return = $i . '<br /><div style="padding-left:20px;">'; |
|
165 | 165 | |
166 | - if (!empty($out['method'])) { |
|
167 | - $return .= $out['method']; |
|
168 | - } |
|
166 | + if (!empty($out['method'])) { |
|
167 | + $return .= $out['method']; |
|
168 | + } |
|
169 | 169 | |
170 | - if (!empty($out['public'])) { |
|
171 | - $return .= $out['public']; |
|
172 | - } |
|
170 | + if (!empty($out['public'])) { |
|
171 | + $return .= $out['public']; |
|
172 | + } |
|
173 | 173 | |
174 | - if (!empty($out['protected'])) { |
|
175 | - $return .= $out['protected']; |
|
176 | - } |
|
174 | + if (!empty($out['protected'])) { |
|
175 | + $return .= $out['protected']; |
|
176 | + } |
|
177 | 177 | |
178 | - if (!empty($out['private'])) { |
|
179 | - $return .= $out['private']; |
|
180 | - } |
|
178 | + if (!empty($out['private'])) { |
|
179 | + $return .= $out['private']; |
|
180 | + } |
|
181 | 181 | |
182 | - return $return . '</div>'; |
|
183 | - } |
|
182 | + return $return . '</div>'; |
|
183 | + } |
|
184 | 184 | } |
@@ -62,7 +62,7 @@ discard block |
||
62 | 62 | |
63 | 63 | $out .= $this->export($var, $scope); |
64 | 64 | |
65 | - return $out . '</div></div>'; |
|
65 | + return $out.'</div></div>'; |
|
66 | 66 | } |
67 | 67 | |
68 | 68 | protected function export($var, $scope) |
@@ -70,16 +70,16 @@ discard block |
||
70 | 70 | $out = ''; |
71 | 71 | foreach ($var as $i => $v) { |
72 | 72 | if (is_array($v) || (is_object($v) && $v instanceof Iterator)) { |
73 | - $out .= $i . ' (' . (is_array($v) ? 'array' : 'object: ' . get_class($v)) . ')'; |
|
73 | + $out .= $i.' ('.(is_array($v) ? 'array' : 'object: '.get_class($v)).')'; |
|
74 | 74 | if ($v === $scope) { |
75 | - $out .= ' (current scope):<div style="background:#ccc;padding-left:20px;">' . $this->export($v, $scope) . '</div>'; |
|
75 | + $out .= ' (current scope):<div style="background:#ccc;padding-left:20px;">'.$this->export($v, $scope).'</div>'; |
|
76 | 76 | } else { |
77 | - $out .= ':<div style="padding-left:20px;">' . $this->export($v, $scope) . '</div>'; |
|
77 | + $out .= ':<div style="padding-left:20px;">'.$this->export($v, $scope).'</div>'; |
|
78 | 78 | } |
79 | 79 | } elseif (is_object($v)) { |
80 | - $out .= $this->exportObj($i . ' (object: ' . get_class($v) . '):', $v); |
|
80 | + $out .= $this->exportObj($i.' (object: '.get_class($v).'):', $v); |
|
81 | 81 | } else { |
82 | - $out .= $this->exportVar($i . ' = ', $v); |
|
82 | + $out .= $this->exportVar($i.' = ', $v); |
|
83 | 83 | } |
84 | 84 | } |
85 | 85 | |
@@ -89,27 +89,27 @@ discard block |
||
89 | 89 | protected function exportVar($i, $v) |
90 | 90 | { |
91 | 91 | if (is_string($v) || is_bool($v) || is_numeric($v)) { |
92 | - return $i . htmlentities(var_export($v, true)) . '<br />'; |
|
92 | + return $i.htmlentities(var_export($v, true)).'<br />'; |
|
93 | 93 | } elseif (is_null($v)) { |
94 | - return $i . 'null<br />'; |
|
94 | + return $i.'null<br />'; |
|
95 | 95 | } elseif (is_resource($v)) { |
96 | - return $i . 'resource(' . get_resource_type($v) . ')<br />'; |
|
96 | + return $i.'resource('.get_resource_type($v).')<br />'; |
|
97 | 97 | } else { |
98 | - return $i . htmlentities(var_export($v, true)) . '<br />'; |
|
98 | + return $i.htmlentities(var_export($v, true)).'<br />'; |
|
99 | 99 | } |
100 | 100 | } |
101 | 101 | |
102 | 102 | protected function exportObj($i, $obj) |
103 | 103 | { |
104 | 104 | if (array_search($obj, $this->outputObjects, true) !== false) { |
105 | - return $i . ' [recursion, skipped]<br />'; |
|
105 | + return $i.' [recursion, skipped]<br />'; |
|
106 | 106 | } |
107 | 107 | |
108 | 108 | $this->outputObjects[] = $obj; |
109 | 109 | |
110 | - $list = (array)$obj; |
|
110 | + $list = (array) $obj; |
|
111 | 111 | |
112 | - $protectedLength = strlen(get_class($obj)) + 2; |
|
112 | + $protectedLength = strlen(get_class($obj))+2; |
|
113 | 113 | |
114 | 114 | $out = array(); |
115 | 115 | |
@@ -127,10 +127,10 @@ discard block |
||
127 | 127 | |
128 | 128 | $params = array(); |
129 | 129 | foreach ($method->getParameters() as $param) { |
130 | - $params[] = ($param->isPassedByReference() ? '&' : '') . '$' . $param->getName() . ($param->isOptional() ? ' = ' . var_export($param->getDefaultValue(), true) : ''); |
|
130 | + $params[] = ($param->isPassedByReference() ? '&' : '').'$'.$param->getName().($param->isOptional() ? ' = '.var_export($param->getDefaultValue(), true) : ''); |
|
131 | 131 | } |
132 | 132 | |
133 | - $out['method'] .= '(method) ' . $method->getName() . '(' . implode(', ', $params) . ')<br />'; |
|
133 | + $out['method'] .= '(method) '.$method->getName().'('.implode(', ', $params).')<br />'; |
|
134 | 134 | } |
135 | 135 | } |
136 | 136 | |
@@ -149,19 +149,19 @@ discard block |
||
149 | 149 | $out[$key] = ''; |
150 | 150 | } |
151 | 151 | |
152 | - $out[$key] .= '(' . $key . ') '; |
|
152 | + $out[$key] .= '('.$key.') '; |
|
153 | 153 | |
154 | 154 | if (is_array($attributeValue)) { |
155 | - $out[$key] .= $attributeName . ' (array):<br /> |
|
156 | - <div style="padding-left:20px;">' . $this->export($attributeValue, false) . '</div>'; |
|
155 | + $out[$key] .= $attributeName.' (array):<br /> |
|
156 | + <div style="padding-left:20px;">' . $this->export($attributeValue, false).'</div>'; |
|
157 | 157 | } elseif (is_object($attributeValue)) { |
158 | - $out[$key] .= $this->exportObj($attributeName . ' (object: ' . get_class($attributeValue) . '):', $attributeValue); |
|
158 | + $out[$key] .= $this->exportObj($attributeName.' (object: '.get_class($attributeValue).'):', $attributeValue); |
|
159 | 159 | } else { |
160 | - $out[$key] .= $this->exportVar($attributeName . ' = ', $attributeValue); |
|
160 | + $out[$key] .= $this->exportVar($attributeName.' = ', $attributeValue); |
|
161 | 161 | } |
162 | 162 | } |
163 | 163 | |
164 | - $return = $i . '<br /><div style="padding-left:20px;">'; |
|
164 | + $return = $i.'<br /><div style="padding-left:20px;">'; |
|
165 | 165 | |
166 | 166 | if (!empty($out['method'])) { |
167 | 167 | $return .= $out['method']; |
@@ -179,6 +179,6 @@ discard block |
||
179 | 179 | $return .= $out['private']; |
180 | 180 | } |
181 | 181 | |
182 | - return $return . '</div>'; |
|
182 | + return $return.'</div>'; |
|
183 | 183 | } |
184 | 184 | } |
@@ -29,7 +29,7 @@ |
||
29 | 29 | /** |
30 | 30 | * @param string $input |
31 | 31 | * |
32 | - * @return mixed |
|
32 | + * @return string |
|
33 | 33 | */ |
34 | 34 | public function process($input) |
35 | 35 | { |
@@ -26,69 +26,69 @@ |
||
26 | 26 | */ |
27 | 27 | class PluginSmartyCompatible extends Processor |
28 | 28 | { |
29 | - /** |
|
30 | - * @param string $input |
|
31 | - * |
|
32 | - * @return mixed |
|
33 | - */ |
|
34 | - public function process($input) |
|
35 | - { |
|
36 | - list($l, $r) = $this->compiler->getDelimiters(); |
|
29 | + /** |
|
30 | + * @param string $input |
|
31 | + * |
|
32 | + * @return mixed |
|
33 | + */ |
|
34 | + public function process($input) |
|
35 | + { |
|
36 | + list($l, $r) = $this->compiler->getDelimiters(); |
|
37 | 37 | |
38 | - $rl = preg_quote($l, '/'); |
|
39 | - $rr = preg_quote($r, '/'); |
|
40 | - $sectionParam = '(?:(name|loop|start|step|max|show)\s*=\s*(\S+))?\s*'; |
|
41 | - $input = preg_replace_callback('/' . $rl . '\s*section ' . str_repeat($sectionParam, 6) . '\s*' . $rr . '(.+?)(?:' . $rl . '\s*sectionelse\s*' . $rr . '(.+?))?' . $rl . '\s*\/section\s*' . $rr . '/is', array( |
|
42 | - $this, |
|
43 | - 'convertSection' |
|
44 | - ), $input); |
|
45 | - $input = str_replace('$smarty.section.', '$smarty.for.', $input); |
|
38 | + $rl = preg_quote($l, '/'); |
|
39 | + $rr = preg_quote($r, '/'); |
|
40 | + $sectionParam = '(?:(name|loop|start|step|max|show)\s*=\s*(\S+))?\s*'; |
|
41 | + $input = preg_replace_callback('/' . $rl . '\s*section ' . str_repeat($sectionParam, 6) . '\s*' . $rr . '(.+?)(?:' . $rl . '\s*sectionelse\s*' . $rr . '(.+?))?' . $rl . '\s*\/section\s*' . $rr . '/is', array( |
|
42 | + $this, |
|
43 | + 'convertSection' |
|
44 | + ), $input); |
|
45 | + $input = str_replace('$smarty.section.', '$smarty.for.', $input); |
|
46 | 46 | |
47 | - $smarty = array( |
|
48 | - '/' . $rl . '\s*ldelim\s*' . $rr . '/', |
|
49 | - '/' . $rl . '\s*rdelim\s*' . $rr . '/', |
|
50 | - '/' . $rl . '\s*\$smarty\.ldelim\s*' . $rr . '/', |
|
51 | - '/' . $rl . '\s*\$smarty\.rdelim\s*' . $rr . '/', |
|
52 | - '/\$smarty\./', |
|
53 | - '/' . $rl . '\s*php\s*' . $rr . '/', |
|
54 | - '/' . $rl . '\s*\/php\s*' . $rr . '/', |
|
55 | - '/\|(@?)strip(\||' . $rr . ')/', |
|
56 | - '/' . $rl . '\s*sectionelse\s*' . $rr . '/', |
|
57 | - ); |
|
47 | + $smarty = array( |
|
48 | + '/' . $rl . '\s*ldelim\s*' . $rr . '/', |
|
49 | + '/' . $rl . '\s*rdelim\s*' . $rr . '/', |
|
50 | + '/' . $rl . '\s*\$smarty\.ldelim\s*' . $rr . '/', |
|
51 | + '/' . $rl . '\s*\$smarty\.rdelim\s*' . $rr . '/', |
|
52 | + '/\$smarty\./', |
|
53 | + '/' . $rl . '\s*php\s*' . $rr . '/', |
|
54 | + '/' . $rl . '\s*\/php\s*' . $rr . '/', |
|
55 | + '/\|(@?)strip(\||' . $rr . ')/', |
|
56 | + '/' . $rl . '\s*sectionelse\s*' . $rr . '/', |
|
57 | + ); |
|
58 | 58 | |
59 | - $dwoo = array( |
|
60 | - '\\' . $l, |
|
61 | - $r, |
|
62 | - '\\' . $l, |
|
63 | - $r, |
|
64 | - '$dwoo.', |
|
65 | - '<?php ', |
|
66 | - ' ?>', |
|
67 | - '|$1whitespace$2', |
|
68 | - $l . 'else' . $r, |
|
69 | - ); |
|
59 | + $dwoo = array( |
|
60 | + '\\' . $l, |
|
61 | + $r, |
|
62 | + '\\' . $l, |
|
63 | + $r, |
|
64 | + '$dwoo.', |
|
65 | + '<?php ', |
|
66 | + ' ?>', |
|
67 | + '|$1whitespace$2', |
|
68 | + $l . 'else' . $r, |
|
69 | + ); |
|
70 | 70 | |
71 | - if (preg_match('{\|@([a-z][a-z0-9_]*)}i', $input, $matches)) { |
|
72 | - trigger_error('The Smarty Compatibility Module has detected that you use |@' . $matches[1] . ' in your template, this might lead to problems as Dwoo interprets the @ operator differently than Smarty, see http://wiki.dwoo.org/index.php/Syntax#The_.40_Operator', E_USER_NOTICE); |
|
73 | - } |
|
71 | + if (preg_match('{\|@([a-z][a-z0-9_]*)}i', $input, $matches)) { |
|
72 | + trigger_error('The Smarty Compatibility Module has detected that you use |@' . $matches[1] . ' in your template, this might lead to problems as Dwoo interprets the @ operator differently than Smarty, see http://wiki.dwoo.org/index.php/Syntax#The_.40_Operator', E_USER_NOTICE); |
|
73 | + } |
|
74 | 74 | |
75 | - return preg_replace($smarty, $dwoo, $input); |
|
76 | - } |
|
75 | + return preg_replace($smarty, $dwoo, $input); |
|
76 | + } |
|
77 | 77 | |
78 | - /** |
|
79 | - * @param array $matches |
|
80 | - * |
|
81 | - * @return mixed |
|
82 | - */ |
|
83 | - protected function convertSection(array $matches) |
|
84 | - { |
|
85 | - $params = array(); |
|
86 | - $index = 1; |
|
87 | - while (!empty($matches[$index]) && $index < 13) { |
|
88 | - $params[$matches[$index]] = $matches[$index + 1]; |
|
89 | - $index += 2; |
|
90 | - } |
|
78 | + /** |
|
79 | + * @param array $matches |
|
80 | + * |
|
81 | + * @return mixed |
|
82 | + */ |
|
83 | + protected function convertSection(array $matches) |
|
84 | + { |
|
85 | + $params = array(); |
|
86 | + $index = 1; |
|
87 | + while (!empty($matches[$index]) && $index < 13) { |
|
88 | + $params[$matches[$index]] = $matches[$index + 1]; |
|
89 | + $index += 2; |
|
90 | + } |
|
91 | 91 | |
92 | - return str_replace('[' . trim($params['name'], '"\'') . ']', '[$' . trim($params['name'], '"\'') . ']', $matches[0]); |
|
93 | - } |
|
92 | + return str_replace('[' . trim($params['name'], '"\'') . ']', '[$' . trim($params['name'], '"\'') . ']', $matches[0]); |
|
93 | + } |
|
94 | 94 | } |
@@ -38,38 +38,38 @@ discard block |
||
38 | 38 | $rl = preg_quote($l, '/'); |
39 | 39 | $rr = preg_quote($r, '/'); |
40 | 40 | $sectionParam = '(?:(name|loop|start|step|max|show)\s*=\s*(\S+))?\s*'; |
41 | - $input = preg_replace_callback('/' . $rl . '\s*section ' . str_repeat($sectionParam, 6) . '\s*' . $rr . '(.+?)(?:' . $rl . '\s*sectionelse\s*' . $rr . '(.+?))?' . $rl . '\s*\/section\s*' . $rr . '/is', array( |
|
41 | + $input = preg_replace_callback('/'.$rl.'\s*section '.str_repeat($sectionParam, 6).'\s*'.$rr.'(.+?)(?:'.$rl.'\s*sectionelse\s*'.$rr.'(.+?))?'.$rl.'\s*\/section\s*'.$rr.'/is', array( |
|
42 | 42 | $this, |
43 | 43 | 'convertSection' |
44 | 44 | ), $input); |
45 | - $input = str_replace('$smarty.section.', '$smarty.for.', $input); |
|
45 | + $input = str_replace('$smarty.section.', '$smarty.for.', $input); |
|
46 | 46 | |
47 | 47 | $smarty = array( |
48 | - '/' . $rl . '\s*ldelim\s*' . $rr . '/', |
|
49 | - '/' . $rl . '\s*rdelim\s*' . $rr . '/', |
|
50 | - '/' . $rl . '\s*\$smarty\.ldelim\s*' . $rr . '/', |
|
51 | - '/' . $rl . '\s*\$smarty\.rdelim\s*' . $rr . '/', |
|
48 | + '/'.$rl.'\s*ldelim\s*'.$rr.'/', |
|
49 | + '/'.$rl.'\s*rdelim\s*'.$rr.'/', |
|
50 | + '/'.$rl.'\s*\$smarty\.ldelim\s*'.$rr.'/', |
|
51 | + '/'.$rl.'\s*\$smarty\.rdelim\s*'.$rr.'/', |
|
52 | 52 | '/\$smarty\./', |
53 | - '/' . $rl . '\s*php\s*' . $rr . '/', |
|
54 | - '/' . $rl . '\s*\/php\s*' . $rr . '/', |
|
55 | - '/\|(@?)strip(\||' . $rr . ')/', |
|
56 | - '/' . $rl . '\s*sectionelse\s*' . $rr . '/', |
|
53 | + '/'.$rl.'\s*php\s*'.$rr.'/', |
|
54 | + '/'.$rl.'\s*\/php\s*'.$rr.'/', |
|
55 | + '/\|(@?)strip(\||'.$rr.')/', |
|
56 | + '/'.$rl.'\s*sectionelse\s*'.$rr.'/', |
|
57 | 57 | ); |
58 | 58 | |
59 | 59 | $dwoo = array( |
60 | - '\\' . $l, |
|
60 | + '\\'.$l, |
|
61 | 61 | $r, |
62 | - '\\' . $l, |
|
62 | + '\\'.$l, |
|
63 | 63 | $r, |
64 | 64 | '$dwoo.', |
65 | 65 | '<?php ', |
66 | 66 | ' ?>', |
67 | 67 | '|$1whitespace$2', |
68 | - $l . 'else' . $r, |
|
68 | + $l.'else'.$r, |
|
69 | 69 | ); |
70 | 70 | |
71 | 71 | if (preg_match('{\|@([a-z][a-z0-9_]*)}i', $input, $matches)) { |
72 | - trigger_error('The Smarty Compatibility Module has detected that you use |@' . $matches[1] . ' in your template, this might lead to problems as Dwoo interprets the @ operator differently than Smarty, see http://wiki.dwoo.org/index.php/Syntax#The_.40_Operator', E_USER_NOTICE); |
|
72 | + trigger_error('The Smarty Compatibility Module has detected that you use |@'.$matches[1].' in your template, this might lead to problems as Dwoo interprets the @ operator differently than Smarty, see http://wiki.dwoo.org/index.php/Syntax#The_.40_Operator', E_USER_NOTICE); |
|
73 | 73 | } |
74 | 74 | |
75 | 75 | return preg_replace($smarty, $dwoo, $input); |
@@ -85,10 +85,10 @@ discard block |
||
85 | 85 | $params = array(); |
86 | 86 | $index = 1; |
87 | 87 | while (!empty($matches[$index]) && $index < 13) { |
88 | - $params[$matches[$index]] = $matches[$index + 1]; |
|
88 | + $params[$matches[$index]] = $matches[$index+1]; |
|
89 | 89 | $index += 2; |
90 | 90 | } |
91 | 91 | |
92 | - return str_replace('[' . trim($params['name'], '"\'') . ']', '[$' . trim($params['name'], '"\'') . ']', $matches[0]); |
|
92 | + return str_replace('['.trim($params['name'], '"\'').']', '[$'.trim($params['name'], '"\'').']', $matches[0]); |
|
93 | 93 | } |
94 | 94 | } |