Completed
Push — master ( 494091...32c874 )
by David
27s
created
lib/Dwoo/Adapters/ZendFramework/PluginProxy.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -46,7 +46,7 @@
 block discarded – undo
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
     {
Please login to merge, or discard this patch.
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -36,88 +36,88 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
lib/Dwoo/Adapters/ZendFramework/View.php 2 patches
Doc Comments   -2 removed lines patch added patch discarded remove patch
@@ -83,7 +83,6 @@  discard block
 block discarded – undo
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
 block discarded – undo
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
      */
Please login to merge, or discard this patch.
Indentation   +503 added lines, -503 removed lines patch added patch discarded remove patch
@@ -16,507 +16,507 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
lib/Dwoo/Compiler.php 5 patches
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
     {
Please login to merge, or discard this patch.
Braces   +3 added lines, -6 removed lines patch added patch discarded remove patch
@@ -478,8 +478,7 @@  discard block
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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)) {
Please login to merge, or discard this patch.
Indentation   +3630 added lines, -3630 removed lines patch added patch discarded remove patch
@@ -31,3636 +31,3636 @@
 block discarded – undo
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::CLASS_PLUGIN:
879
-                case Core::CLASS_PLUGIN + Core::BLOCK_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::CLASS_PLUGIN + Core::FUNC_PLUGIN:
889
-                    if (class_exists('Plugin' . $plugin) !== false) {
890
-                        $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)".
891
-                            "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
892
-                    } else {
893
-                        $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
894
-                            "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
895
-                    }
896
-                    break;
897
-                case Core::FUNC_PLUGIN:
898
-                    if (function_exists('Plugin' . $plugin) !== false) {
899
-                        $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)".
900
-                        "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
901
-                    } else {
902
-                        $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
903
-                        "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
904
-                    }
905
-                    break;
906
-                case Core::SMARTY_MODIFIER:
907
-                    $output .= "if (function_exists('smarty_modifier_$plugin')===false)".
908
-                    "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
909
-                    break;
910
-                case Core::SMARTY_FUNCTION:
911
-                    $output .= "if (function_exists('smarty_function_$plugin')===false)".
912
-                    "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
913
-                    break;
914
-                case Core::SMARTY_BLOCK:
915
-                    $output .= "if (function_exists('smarty_block_$plugin')===false)".
916
-                    "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
917
-                    break;
918
-                case Core::PROXY_PLUGIN:
919
-                    $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin);
920
-                    break;
921
-                default:
922
-                    throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type);
923
-            }
924
-        }
925
-
926
-        foreach ($this->templatePlugins as $function => $attr) {
927
-            if (isset($attr['called']) && $attr['called'] === true && !isset($attr['checked'])) {
928
-                $this->resolveSubTemplateDependencies($function);
929
-            }
930
-        }
931
-        foreach ($this->templatePlugins as $function) {
932
-            if (isset($function['called']) && $function['called'] === true) {
933
-                $output .= $function['body'] . PHP_EOL;
934
-            }
935
-        }
936
-
937
-        $output .= $compiled . "\n?>";
938
-
939
-        $output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*' . preg_quote(self::PHP_CLOSE, '/') . preg_quote(self::PHP_OPEN, '/') . ')/', ";\n", $output);
940
-        $output = str_replace(self::PHP_CLOSE . self::PHP_OPEN, "\n", $output);
941
-
942
-        // handle <?xml tag at the beginning
943
-        $output = preg_replace('#(/\* template body \*/ \?>\s*)<\?xml#is', '$1<?php echo \'<?xml\'; ?>', $output);
944
-
945
-        // add another line break after PHP closing tags that have a line break following,
946
-        // as we do not know whether it's intended, and PHP will strip it otherwise
947
-        $output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0' . "\n", $output);
948
-
949
-        if ($this->debug) {
950
-            echo '=============================================================================================' . "\n";
951
-            $lines = preg_split('{\r\n|\n|<br />}', $output);
952
-            array_shift($lines);
953
-            foreach ($lines as $i => $line) {
954
-                echo ($i + 1) . '. ' . $line . "\r\n";
955
-            }
956
-            echo '=============================================================================================' . "\n";
957
-        }
958
-
959
-        $this->template = $this->dwoo = null;
960
-        $tpl            = null;
961
-
962
-        return $output;
963
-    }
964
-
965
-    /**
966
-     * Checks what sub-templates are used in every sub-template so that we're sure they are all compiled.
967
-     *
968
-     * @param string $function the sub-template name
969
-     */
970
-    protected function resolveSubTemplateDependencies($function)
971
-    {
972
-        if ($this->debug) {
973
-            echo 'Compiler::' . __FUNCTION__ . "\n";
974
-        }
975
-
976
-        $body = $this->templatePlugins[$function]['body'];
977
-        foreach ($this->templatePlugins as $func => $attr) {
978
-            if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS .
979
-            'Plugin' . Core::toCamelCase($func)) !== false) {
980
-                $this->templatePlugins[$func]['called'] = true;
981
-                $this->resolveSubTemplateDependencies($func);
982
-            }
983
-        }
984
-        $this->templatePlugins[$function]['checked'] = true;
985
-    }
986
-
987
-    /**
988
-     * Adds compiled content to the current block.
989
-     *
990
-     * @param string $content   the content to push
991
-     * @param int    $lineCount newlines count in content, optional
992
-     *
993
-     * @throws CompilationException
994
-     */
995
-    public function push($content, $lineCount = null)
996
-    {
997
-        if ($lineCount === null) {
998
-            $lineCount = substr_count($content, "\n");
999
-        }
1000
-
1001
-        if ($this->curBlock['buffer'] === null && count($this->stack) > 1) {
1002
-            // buffer is not initialized yet (the block has just been created)
1003
-            $this->stack[count($this->stack) - 2]['buffer'] .= (string)$content;
1004
-            $this->curBlock['buffer'] = '';
1005
-        } else {
1006
-            if (!isset($this->curBlock['buffer'])) {
1007
-                throw new CompilationException($this, 'The template has been closed too early, you probably have an extra block-closing tag somewhere');
1008
-            }
1009
-            // append current content to current block's buffer
1010
-            $this->curBlock['buffer'] .= (string)$content;
1011
-        }
1012
-        $this->line += $lineCount;
1013
-    }
1014
-
1015
-    /**
1016
-     * Sets the scope.
1017
-     * set to null if the scope becomes "unstable" (i.e. too variable or unknown) so that
1018
-     * variables are compiled in a more evaluative way than just $this->scope['key']
1019
-     *
1020
-     * @param mixed $scope    a string i.e. "level1.level2" or an array i.e. array("level1", "level2")
1021
-     * @param bool  $absolute if true, the scope is set from the top level scope and not from the current scope
1022
-     *
1023
-     * @return array the current scope tree
1024
-     */
1025
-    public function setScope($scope, $absolute = false)
1026
-    {
1027
-        $old = $this->scopeTree;
1028
-
1029
-        if ($scope === null) {
1030
-            unset($this->scope);
1031
-            $this->scope = null;
1032
-        }
1033
-
1034
-        if (is_array($scope) === false) {
1035
-            $scope = explode('.', $scope);
1036
-        }
1037
-
1038
-        if ($absolute === true) {
1039
-            $this->scope     = &$this->data;
1040
-            $this->scopeTree = array();
1041
-        }
1042
-
1043
-        while (($bit = array_shift($scope)) !== null) {
1044
-            if ($bit === '_parent' || $bit === '_') {
1045
-                array_pop($this->scopeTree);
1046
-                reset($this->scopeTree);
1047
-                $this->scope = &$this->data;
1048
-                $cnt         = count($this->scopeTree);
1049
-                for ($i = 0; $i < $cnt; ++ $i) {
1050
-                    $this->scope = &$this->scope[$this->scopeTree[$i]];
1051
-                }
1052
-            } elseif ($bit === '_root' || $bit === '__') {
1053
-                $this->scope     = &$this->data;
1054
-                $this->scopeTree = array();
1055
-            } elseif (isset($this->scope[$bit])) {
1056
-                $this->scope       = &$this->scope[$bit];
1057
-                $this->scopeTree[] = $bit;
1058
-            } else {
1059
-                $this->scope[$bit] = array();
1060
-                $this->scope       = &$this->scope[$bit];
1061
-                $this->scopeTree[] = $bit;
1062
-            }
1063
-        }
1064
-
1065
-        return $old;
1066
-    }
1067
-
1068
-    /**
1069
-     * Adds a block to the top of the block stack.
1070
-     *
1071
-     * @param string $type      block type (name)
1072
-     * @param array  $params    the parameters array
1073
-     * @param int    $paramtype the parameters type (see mapParams), 0, 1 or 2
1074
-     *
1075
-     * @return string the preProcessing() method's output
1076
-     */
1077
-    public function addBlock($type, array $params, $paramtype)
1078
-    {
1079
-        if ($this->debug) {
1080
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1081
-        }
1082
-
1083
-        $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type);
1084
-        if (class_exists($class) === false) {
1085
-            $this->getDwoo()->getLoader()->loadPlugin($type);
1086
-        }
1087
-        $params = $this->mapParams($params, array($class, 'init'), $paramtype);
1088
-
1089
-        $this->stack[]  = array(
1090
-            'type'   => $type,
1091
-            'params' => $params,
1092
-            'custom' => false,
1093
-            'class'  => $class,
1094
-            'buffer' => null
1095
-        );
1096
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1097
-
1098
-        return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type);
1099
-    }
1100
-
1101
-    /**
1102
-     * Adds a custom block to the top of the block stack.
1103
-     *
1104
-     * @param string $type      block type (name)
1105
-     * @param array  $params    the parameters array
1106
-     * @param int    $paramtype the parameters type (see mapParams), 0, 1 or 2
1107
-     *
1108
-     * @return string the preProcessing() method's output
1109
-     */
1110
-    public function addCustomBlock($type, array $params, $paramtype)
1111
-    {
1112
-        $callback = $this->customPlugins[$type]['callback'];
1113
-        if (is_array($callback)) {
1114
-            $class = is_object($callback[0]) ? get_class($callback[0]) : $callback[0];
1115
-        } else {
1116
-            $class = $callback;
1117
-        }
1118
-
1119
-        $params = $this->mapParams($params, array($class, 'init'), $paramtype);
1120
-
1121
-        $this->stack[]  = array(
1122
-            'type'   => $type,
1123
-            'params' => $params,
1124
-            'custom' => true,
1125
-            'class'  => $class,
1126
-            'buffer' => null
1127
-        );
1128
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1129
-
1130
-        return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type);
1131
-    }
1132
-
1133
-    /**
1134
-     * Injects a block at the top of the plugin stack without calling its preProcessing method.
1135
-     * used by {else} blocks to re-add themselves after having closed everything up to their parent
1136
-     *
1137
-     * @param string $type   block type (name)
1138
-     * @param array  $params parameters array
1139
-     */
1140
-    public function injectBlock($type, array $params)
1141
-    {
1142
-        if ($this->debug) {
1143
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1144
-        }
1145
-
1146
-        $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type);
1147
-        if (class_exists($class) === false) {
1148
-            $this->getDwoo()->getLoader()->loadPlugin($type);
1149
-        }
1150
-        $this->stack[]  = array(
1151
-            'type'   => $type,
1152
-            'params' => $params,
1153
-            'custom' => false,
1154
-            'class'  => $class,
1155
-            'buffer' => null
1156
-        );
1157
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1158
-    }
1159
-
1160
-    /**
1161
-     * Removes the closest-to-top block of the given type and all other
1162
-     * blocks encountered while going down the block stack.
1163
-     *
1164
-     * @param string $type block type (name)
1165
-     *
1166
-     * @return string the output of all postProcessing() method's return values of the closed blocks
1167
-     * @throws CompilationException
1168
-     */
1169
-    public function removeBlock($type)
1170
-    {
1171
-        if ($this->debug) {
1172
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1173
-        }
1174
-
1175
-        $output = '';
1176
-
1177
-        $pluginType = $this->getPluginType($type);
1178
-        if ($pluginType & Core::SMARTY_BLOCK) {
1179
-            $type = 'Smartyinterface';
1180
-        }
1181
-        while (true) {
1182
-            while ($top = array_pop($this->stack)) {
1183
-                if ($top['custom']) {
1184
-                    $class = $top['class'];
1185
-                } else {
1186
-                    $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($top['type']);
1187
-                }
1188
-                if (count($this->stack)) {
1189
-                    $this->curBlock = &$this->stack[count($this->stack) - 1];
1190
-                    $this->push(call_user_func(array(
1191
-                        $class,
1192
-                        'postProcessing'
1193
-                    ), $this, $top['params'], '', '', $top['buffer']), 0);
1194
-                } else {
1195
-                    $null           = null;
1196
-                    $this->curBlock = &$null;
1197
-                    $output         = call_user_func(
1198
-                        array(
1199
-                        $class,
1200
-                        'postProcessing'
1201
-                        ), $this, $top['params'], '', '', $top['buffer']
1202
-                    );
1203
-                }
1204
-
1205
-                if ($top['type'] === $type) {
1206
-                    break 2;
1207
-                }
1208
-            }
1209
-
1210
-            throw new CompilationException($this, 'Syntax malformation, a block of type "' . $type . '" was closed but was not opened');
1211
-            break;
1212
-        }
1213
-
1214
-        return $output;
1215
-    }
1216
-
1217
-    /**
1218
-     * Returns a reference to the first block of the given type encountered and
1219
-     * optionally closes all blocks until it finds it
1220
-     * this is mainly used by {else} plugins to close everything that was opened
1221
-     * between their parent and themselves.
1222
-     *
1223
-     * @param string $type       the block type (name)
1224
-     * @param bool   $closeAlong whether to close all blocks encountered while going down the block stack or not
1225
-     *
1226
-     * @return mixed &array the array is as such: array('type'=>pluginName, 'params'=>parameter array,
1227
-     *               'custom'=>bool defining whether it's a custom plugin or not, for internal use)
1228
-     * @throws CompilationException
1229
-     */
1230
-    public function &findBlock($type, $closeAlong = false)
1231
-    {
1232
-        if ($closeAlong === true) {
1233
-            while ($b = end($this->stack)) {
1234
-                if ($b['type'] === $type) {
1235
-                    return $this->stack[key($this->stack)];
1236
-                }
1237
-                $this->push($this->removeTopBlock(), 0);
1238
-            }
1239
-        } else {
1240
-            end($this->stack);
1241
-            while ($b = current($this->stack)) {
1242
-                if ($b['type'] === $type) {
1243
-                    return $this->stack[key($this->stack)];
1244
-                }
1245
-                prev($this->stack);
1246
-            }
1247
-        }
1248
-
1249
-        throw new CompilationException($this, 'A parent block of type "' . $type . '" is required and can not be found');
1250
-    }
1251
-
1252
-    /**
1253
-     * Returns a reference to the current block array.
1254
-     *
1255
-     * @return array the array is as such: array('type'=>pluginName, 'params'=>parameter array,
1256
-     *                'custom'=>bool defining whether it's a custom plugin or not, for internal use)
1257
-     */
1258
-    public function &getCurrentBlock()
1259
-    {
1260
-        return $this->curBlock;
1261
-    }
1262
-
1263
-    /**
1264
-     * Removes the block at the top of the stack and calls its postProcessing() method.
1265
-     *
1266
-     * @return string the postProcessing() method's output
1267
-     * @throws CompilationException
1268
-     */
1269
-    public function removeTopBlock()
1270
-    {
1271
-        if ($this->debug) {
1272
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1273
-        }
1274
-
1275
-        $o = array_pop($this->stack);
1276
-        if ($o === null) {
1277
-            throw new CompilationException($this, 'Syntax malformation, a block of unknown type was closed but was not opened.');
1278
-        }
1279
-        if ($o['custom']) {
1280
-            $class = $o['class'];
1281
-        } else {
1282
-            $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($o['type']);
1283
-        }
1284
-
1285
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1286
-
1287
-        return call_user_func(array($class, 'postProcessing'), $this, $o['params'], '', '', $o['buffer']);
1288
-    }
1289
-
1290
-    /**
1291
-     * Returns the compiled parameters (for example a variable's compiled parameter will be "$this->scope['key']") out
1292
-     * of the given parameter array.
1293
-     *
1294
-     * @param array $params parameter array
1295
-     *
1296
-     * @return array filtered parameters
1297
-     */
1298
-    public function getCompiledParams(array $params)
1299
-    {
1300
-        foreach ($params as $k => $p) {
1301
-            if (is_array($p)) {
1302
-                $params[$k] = $p[0];
1303
-            }
1304
-        }
1305
-
1306
-        return $params;
1307
-    }
1308
-
1309
-    /**
1310
-     * Returns the real parameters (for example a variable's real parameter will be its key, etc) out of the given
1311
-     * parameter array.
1312
-     *
1313
-     * @param array $params parameter array
1314
-     *
1315
-     * @return array filtered parameters
1316
-     */
1317
-    public function getRealParams(array $params)
1318
-    {
1319
-        foreach ($params as $k => $p) {
1320
-            if (is_array($p)) {
1321
-                $params[$k] = $p[1];
1322
-            }
1323
-        }
1324
-
1325
-        return $params;
1326
-    }
1327
-
1328
-    /**
1329
-     * Returns the token of each parameter out of the given parameter array.
1330
-     *
1331
-     * @param array $params parameter array
1332
-     *
1333
-     * @return array tokens
1334
-     */
1335
-    public function getParamTokens(array $params)
1336
-    {
1337
-        foreach ($params as $k => $p) {
1338
-            if (is_array($p)) {
1339
-                $params[$k] = isset($p[2]) ? $p[2] : 0;
1340
-            }
1341
-        }
1342
-
1343
-        return $params;
1344
-    }
1345
-
1346
-    /**
1347
-     * Entry point of the parser, it redirects calls to other parse* functions.
1348
-     *
1349
-     * @param string $in            the string within which we must parse something
1350
-     * @param int    $from          the starting offset of the parsed area
1351
-     * @param int    $to            the ending offset of the parsed area
1352
-     * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
1353
-     *                              default
1354
-     * @param string $curBlock      the current parser-block being processed
1355
-     * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
1356
-     *                              or null by default
1357
-     *
1358
-     * @return string parsed values
1359
-     * @throws CompilationException
1360
-     */
1361
-    protected function parse($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
1362
-    {
1363
-        if ($this->debug) {
1364
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1365
-        }
1366
-
1367
-        if ($to === null) {
1368
-            $to = strlen($in);
1369
-        }
1370
-        $first = substr($in, $from, 1);
1371
-
1372
-        if ($first === false) {
1373
-            throw new CompilationException($this, 'Unexpected EOF, a template tag was not closed');
1374
-        }
1375
-
1376
-        while ($first === ' ' || $first === "\n" || $first === "\t" || $first === "\r") {
1377
-            if ($curBlock === 'root' && substr($in, $from, strlen($this->rd)) === $this->rd) {
1378
-                // end template tag
1379
-                $pointer += strlen($this->rd);
1380
-                if ($this->debug) {
1381
-                    echo 'TEMPLATE PARSING ENDED' . "\n";
1382
-                }
1383
-
1384
-                return false;
1385
-            }
1386
-            ++ $from;
1387
-            if ($pointer !== null) {
1388
-                ++ $pointer;
1389
-            }
1390
-            if ($from >= $to) {
1391
-                if (is_array($parsingParams)) {
1392
-                    return $parsingParams;
1393
-                } else {
1394
-                    return '';
1395
-                }
1396
-            }
1397
-            $first = $in[$from];
1398
-        }
1399
-
1400
-        $substr = substr($in, $from, $to - $from);
1401
-
1402
-        if ($this->debug) {
1403
-            echo 'PARSE CALL : PARSING "' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . '" @ ' . $from . ':' . $to . ' in ' . $curBlock . ' : pointer=' . $pointer . "\n";
1404
-        }
1405
-        $parsed = '';
1406
-
1407
-        if ($curBlock === 'root' && $first === '*') {
1408
-            $src      = $this->getTemplateSource();
1409
-            $startpos = $this->getPointer() - strlen($this->ld);
1410
-            if (substr($src, $startpos, strlen($this->ld)) === $this->ld) {
1411
-                if ($startpos > 0) {
1412
-                    do {
1413
-                        $char = substr($src, -- $startpos, 1);
1414
-                        if ($char == "\n") {
1415
-                            ++ $startpos;
1416
-                            $whitespaceStart = true;
1417
-                            break;
1418
-                        }
1419
-                    }
1420
-                    while ($startpos > 0 && ($char == ' ' || $char == "\t"));
1421
-                }
1422
-
1423
-                if (!isset($whitespaceStart)) {
1424
-                    $startpos = $this->getPointer();
1425
-                } else {
1426
-                    $pointer -= $this->getPointer() - $startpos;
1427
-                }
1428
-
1429
-                if ($this->allowNestedComments && strpos($src, $this->ld . '*', $this->getPointer()) !== false) {
1430
-                    $comOpen  = $this->ld . '*';
1431
-                    $comClose = '*' . $this->rd;
1432
-                    $level    = 1;
1433
-                    $ptr      = $this->getPointer();
1434
-
1435
-                    while ($level > 0 && $ptr < strlen($src)) {
1436
-                        $open  = strpos($src, $comOpen, $ptr);
1437
-                        $close = strpos($src, $comClose, $ptr);
1438
-
1439
-                        if ($open !== false && $close !== false) {
1440
-                            if ($open < $close) {
1441
-                                $ptr = $open + strlen($comOpen);
1442
-                                ++ $level;
1443
-                            } else {
1444
-                                $ptr = $close + strlen($comClose);
1445
-                                -- $level;
1446
-                            }
1447
-                        } elseif ($open !== false) {
1448
-                            $ptr = $open + strlen($comOpen);
1449
-                            ++ $level;
1450
-                        } elseif ($close !== false) {
1451
-                            $ptr = $close + strlen($comClose);
1452
-                            -- $level;
1453
-                        } else {
1454
-                            $ptr = strlen($src);
1455
-                        }
1456
-                    }
1457
-                    $endpos = $ptr - strlen('*' . $this->rd);
1458
-                } else {
1459
-                    $endpos = strpos($src, '*' . $this->rd, $startpos);
1460
-                    if ($endpos == false) {
1461
-                        throw new CompilationException($this, 'Un-ended comment');
1462
-                    }
1463
-                }
1464
-                $pointer += $endpos - $startpos + strlen('*' . $this->rd);
1465
-                if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos + strlen('*' . $this->rd)), $m)) {
1466
-                    $pointer += strlen($m[0]);
1467
-                    $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer']) - ($this->getPointer() - $startpos - strlen($this->ld)));
1468
-                }
1469
-
1470
-                return false;
1471
-            }
1472
-        }
1473
-
1474
-        if ($first === '$') {
1475
-            // var
1476
-            $out    = $this->parseVar($in, $from, $to, $parsingParams, $curBlock, $pointer);
1477
-            $parsed = 'var';
1478
-        } elseif ($first === '%' && preg_match('#^%[a-z_\\\\]#i', $substr)) {
1479
-            // Short constant
1480
-            $out = $this->parseConst($in, $from, $to, $parsingParams, $curBlock, $pointer);
1481
-        } elseif (($first === '"' || $first === "'") && !(is_array($parsingParams) && preg_match('#^([\'"])[a-z0-9_]+\1\s*=>?(?:\s+|[^=])#i', $substr))) {
1482
-            // string
1483
-            $out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer);
1484
-        } 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)) {
1485
-            // func
1486
-            $out    = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer);
1487
-            $parsed = 'func';
1488
-        } elseif ($first === ';') {
1489
-            // instruction end
1490
-            if ($this->debug) {
1491
-                echo 'END OF INSTRUCTION' . "\n";
1492
-            }
1493
-            if ($pointer !== null) {
1494
-                ++ $pointer;
1495
-            }
1496
-
1497
-            return $this->parse($in, $from + 1, $to, false, 'root', $pointer);
1498
-        } elseif ($curBlock === 'root' && preg_match('#^/([a-z_][a-z0-9_]*)?#i', $substr, $match)) {
1499
-            // close block
1500
-            if (!empty($match[1]) && $match[1] == 'else') {
1501
-                throw new CompilationException($this, 'Else blocks must not be closed explicitly, they are automatically closed when their parent block is closed');
1502
-            }
1503
-            if (!empty($match[1]) && $match[1] == 'elseif') {
1504
-                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');
1505
-            }
1506
-            if ($pointer !== null) {
1507
-                $pointer += strlen($match[0]);
1508
-            }
1509
-            if (empty($match[1])) {
1510
-                if ($this->curBlock['type'] == 'else' || $this->curBlock['type'] == 'elseif') {
1511
-                    $pointer -= strlen($match[0]);
1512
-                }
1513
-                if ($this->debug) {
1514
-                    echo 'TOP BLOCK CLOSED' . "\n";
1515
-                }
1516
-
1517
-                return $this->removeTopBlock();
1518
-            } else {
1519
-                if ($this->debug) {
1520
-                    echo 'BLOCK OF TYPE ' . $match[1] . ' CLOSED' . "\n";
1521
-                }
1522
-
1523
-                return $this->removeBlock($match[1]);
1524
-            }
1525
-        } elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) {
1526
-            // end template tag
1527
-            if ($this->debug) {
1528
-                echo 'TAG PARSING ENDED' . "\n";
1529
-            }
1530
-            $pointer += strlen($this->rd);
1531
-
1532
-            return false;
1533
-        } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*=' . ($curBlock === 'array' ? '>?' : '') . ')(?:\s+|[^=]).*#i', $substr, $match)) {
1534
-            // named parameter
1535
-            if ($this->debug) {
1536
-                echo 'NAMED PARAM FOUND' . "\n";
1537
-            }
1538
-            $len = strlen($match[1]);
1539
-            while (substr($in, $from + $len, 1) === ' ') {
1540
-                ++ $len;
1541
-            }
1542
-            if ($pointer !== null) {
1543
-                $pointer += $len;
1544
-            }
1545
-
1546
-            $output = array(
1547
-                trim($match[1], " \t\r\n=>'\""),
1548
-                $this->parse($in, $from + $len, $to, false, 'namedparam', $pointer)
1549
-            );
1550
-
1551
-            $parsingParams[] = $output;
1552
-
1553
-            return $parsingParams;
1554
-        } elseif (preg_match('#^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*::\$[a-z0-9_]+)#i', $substr, $match)) {
1555
-            // static member access
1556
-            $parsed = 'var';
1557
-            if (is_array($parsingParams)) {
1558
-                $parsingParams[] = array($match[1], $match[1]);
1559
-                $out             = $parsingParams;
1560
-            } else {
1561
-                $out = $match[1];
1562
-            }
1563
-            $pointer += strlen($match[1]);
1564
-        } elseif ($substr !== '' && (is_array($parsingParams) || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'expression')) {
1565
-            // unquoted string, bool or number
1566
-            $out = $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1567
-        } else {
1568
-            // parse error
1569
-            throw new CompilationException($this, 'Parse error in "' . substr($in, $from, $to - $from) . '"');
1570
-        }
1571
-
1572
-        if (empty($out)) {
1573
-            return '';
1574
-        }
1575
-
1576
-        $substr = substr($in, $pointer, $to - $pointer);
1577
-
1578
-        // var parsed, check if any var-extension applies
1579
-        if ($parsed === 'var') {
1580
-            if (preg_match('#^\s*([/%+*-])\s*([a-z0-9]|\$)#i', $substr, $match)) {
1581
-                if ($this->debug) {
1582
-                    echo 'PARSING POST-VAR EXPRESSION ' . $substr . "\n";
1583
-                }
1584
-                // parse expressions
1585
-                $pointer += strlen($match[0]) - 1;
1586
-                if (is_array($parsingParams)) {
1587
-                    if ($match[2] == '$') {
1588
-                        $expr = $this->parseVar($in, $pointer, $to, array(), $curBlock, $pointer);
1589
-                    } else {
1590
-                        $expr = $this->parse($in, $pointer, $to, array(), 'expression', $pointer);
1591
-                    }
1592
-                    $out[count($out) - 1][0] .= $match[1] . $expr[0][0];
1593
-                    $out[count($out) - 1][1] .= $match[1] . $expr[0][1];
1594
-                } else {
1595
-                    if ($match[2] == '$') {
1596
-                        $expr = $this->parseVar($in, $pointer, $to, false, $curBlock, $pointer);
1597
-                    } else {
1598
-                        $expr = $this->parse($in, $pointer, $to, false, 'expression', $pointer);
1599
-                    }
1600
-                    if (is_array($out) && is_array($expr)) {
1601
-                        $out[0] .= $match[1] . $expr[0];
1602
-                        $out[1] .= $match[1] . $expr[1];
1603
-                    } elseif (is_array($out)) {
1604
-                        $out[0] .= $match[1] . $expr;
1605
-                        $out[1] .= $match[1] . $expr;
1606
-                    } elseif (is_array($expr)) {
1607
-                        $out .= $match[1] . $expr[0];
1608
-                    } else {
1609
-                        $out .= $match[1] . $expr;
1610
-                    }
1611
-                }
1612
-            } elseif ($curBlock === 'root' && preg_match('#^(\s*(?:[+/*%-.]=|=|\+\+|--)\s*)(.*)#s', $substr, $match)) {
1613
-                if ($this->debug) {
1614
-                    echo 'PARSING POST-VAR ASSIGNMENT ' . $substr . "\n";
1615
-                }
1616
-                // parse assignment
1617
-                $value    = $match[2];
1618
-                $operator = trim($match[1]);
1619
-                if (substr($value, 0, 1) == '=') {
1620
-                    throw new CompilationException($this, 'Unexpected "=" in <em>' . $substr . '</em>');
1621
-                }
1622
-
1623
-                if ($pointer !== null) {
1624
-                    $pointer += strlen($match[1]);
1625
-                }
1626
-
1627
-                if ($operator !== '++' && $operator !== '--') {
1628
-                    $parts = array();
1629
-                    $ptr   = 0;
1630
-                    $parts = $this->parse($value, 0, strlen($value), $parts, 'condition', $ptr);
1631
-                    $pointer += $ptr;
1632
-
1633
-                    // load if plugin
1634
-                    try {
1635
-                        $this->getPluginType('if');
1636
-                    }
1637
-                    catch (Exception $e) {
1638
-                        throw new CompilationException($this, 'Assignments require the "if" plugin to be accessible');
1639
-                    }
1640
-
1641
-                    $parts  = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS . 'PluginIf', 'init'), 1);
1642
-                    $tokens = $this->getParamTokens($parts);
1643
-                    $parts  = $this->getCompiledParams($parts);
1644
-
1645
-                    $value = PluginIf::replaceKeywords($parts['*'], $tokens['*'], $this);
1646
-                    $echo  = '';
1647
-                } else {
1648
-                    $value = array();
1649
-                    $echo  = 'echo ';
1650
-                }
1651
-
1652
-                if ($this->autoEscape) {
1653
-                    $out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out);
1654
-                }
1655
-                $out = self::PHP_OPEN . $echo . $out . $operator . implode(' ', $value) . self::PHP_CLOSE;
1656
-            } elseif ($curBlock === 'array' && is_array($parsingParams) && preg_match('#^(\s*=>?\s*)#', $substr, $match)) {
1657
-                // parse namedparam with var as name (only for array)
1658
-                if ($this->debug) {
1659
-                    echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND' . "\n";
1660
-                }
1661
-                $len = strlen($match[1]);
1662
-                $var = $out[count($out) - 1];
1663
-                $pointer += $len;
1664
-
1665
-                $output = array($var[0], $this->parse($substr, $len, null, false, 'namedparam', $pointer));
1666
-
1667
-                $parsingParams[] = $output;
1668
-
1669
-                return $parsingParams;
1670
-            }
1671
-        }
1672
-
1673
-        if ($curBlock !== 'modifier' && ($parsed === 'func' || $parsed === 'var') && preg_match('#^(\|@?[a-z0-9_]+(:.*)?)+#i', $substr, $match)) {
1674
-            // parse modifier on funcs or vars
1675
-            $srcPointer = $pointer;
1676
-            if (is_array($parsingParams)) {
1677
-                $tmp                     = $this->replaceModifiers(
1678
-                    array(
1679
-                    null,
1680
-                    null,
1681
-                    $out[count($out) - 1][0],
1682
-                    $match[0]
1683
-                    ), $curBlock, $pointer
1684
-                );
1685
-                $out[count($out) - 1][0] = $tmp;
1686
-                $out[count($out) - 1][1] .= substr($substr, $srcPointer, $srcPointer - $pointer);
1687
-            } else {
1688
-                $out = $this->replaceModifiers(array(null, null, $out, $match[0]), $curBlock, $pointer);
1689
-            }
1690
-        }
1691
-
1692
-        // func parsed, check if any func-extension applies
1693
-        if ($parsed === 'func' && preg_match('#^->[a-z0-9_]+(\s*\(.+|->[a-z_].*)?#is', $substr, $match)) {
1694
-            // parse method call or property read
1695
-            $ptr = 0;
1696
-
1697
-            if (is_array($parsingParams)) {
1698
-                $output = $this->parseMethodCall($out[count($out) - 1][1], $match[0], $curBlock, $ptr);
1699
-
1700
-                $out[count($out) - 1][0] = $output;
1701
-                $out[count($out) - 1][1] .= substr($match[0], 0, $ptr);
1702
-            } else {
1703
-                $out = $this->parseMethodCall($out, $match[0], $curBlock, $ptr);
1704
-            }
1705
-
1706
-            $pointer += $ptr;
1707
-        }
1708
-
1709
-        if ($curBlock === 'root' && substr($out, 0, strlen(self::PHP_OPEN)) !== self::PHP_OPEN) {
1710
-            return self::PHP_OPEN . 'echo ' . $out . ';' . self::PHP_CLOSE;
1711
-        } else {
1712
-            return $out;
1713
-        }
1714
-    }
1715
-
1716
-    /**
1717
-     * Parses a function call.
1718
-     *
1719
-     * @param string $in            the string within which we must parse something
1720
-     * @param int    $from          the starting offset of the parsed area
1721
-     * @param int    $to            the ending offset of the parsed area
1722
-     * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
1723
-     *                              default
1724
-     * @param string $curBlock      the current parser-block being processed
1725
-     * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
1726
-     *                              or null by default
1727
-     *
1728
-     * @return string parsed values
1729
-     * @throws CompilationException
1730
-     * @throws Exception
1731
-     * @throws SecurityException
1732
-     */
1733
-    protected function parseFunction($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
1734
-    {
1735
-        $output = '';
1736
-        $cmdstr = substr($in, $from, $to - $from);
1737
-        preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*' . $this->rdr . '|\s*;)?/i', $cmdstr, $match);
1738
-
1739
-        if (empty($match[1])) {
1740
-            throw new CompilationException($this, 'Parse error, invalid function name : ' . substr($cmdstr, 0, 15));
1741
-        }
1742
-
1743
-        $func = $match[1];
1744
-
1745
-        if (!empty($match[2])) {
1746
-            $cmdstr = $match[1];
1747
-        }
1748
-
1749
-        if ($this->debug) {
1750
-            echo 'FUNC FOUND (' . $func . ')' . "\n";
1751
-        }
1752
-
1753
-        $paramsep = '';
1754
-
1755
-        if (is_array($parsingParams) || $curBlock != 'root') {
1756
-            $paramspos = strpos($cmdstr, '(');
1757
-            $paramsep  = ')';
1758
-        } elseif (preg_match_all('#^\s*[\\\\:a-z0-9_]+(\s*\(|\s+[^(])#i', $cmdstr, $match, PREG_OFFSET_CAPTURE)) {
1759
-            $paramspos = $match[1][0][1];
1760
-            $paramsep  = substr($match[1][0][0], - 1) === '(' ? ')' : '';
1761
-            if ($paramsep === ')') {
1762
-                $paramspos += strlen($match[1][0][0]) - 1;
1763
-                if (substr($cmdstr, 0, 2) === 'if' || substr($cmdstr, 0, 6) === 'elseif') {
1764
-                    $paramsep = '';
1765
-                    if (strlen($match[1][0][0]) > 1) {
1766
-                        -- $paramspos;
1767
-                    }
1768
-                }
1769
-            }
1770
-        } else {
1771
-            $paramspos = false;
1772
-        }
1773
-
1774
-        $state = 0;
1775
-
1776
-        if ($paramspos === false) {
1777
-            $params = array();
1778
-
1779
-            if ($curBlock !== 'root') {
1780
-                return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1781
-            }
1782
-        } else {
1783
-            if ($curBlock === 'condition') {
1784
-                // load if plugin
1785
-                $this->getPluginType('if');
1786
-
1787
-                if (PluginIf::replaceKeywords(array($func), array(self::T_UNQUOTED_STRING), $this) !== array($func)) {
1788
-                    return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1789
-                }
1790
-            }
1791
-            $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos - strlen($func)));
1792
-            $paramstr   = substr($cmdstr, $paramspos + 1);
1793
-            if (substr($paramstr, - 1, 1) === $paramsep) {
1794
-                $paramstr = substr($paramstr, 0, - 1);
1795
-            }
1796
-
1797
-            if (strlen($paramstr) === 0) {
1798
-                $params   = array();
1799
-                $paramstr = '';
1800
-            } else {
1801
-                $ptr    = 0;
1802
-                $params = array();
1803
-                if ($func === 'empty') {
1804
-                    $params = $this->parseVar($paramstr, $ptr, strlen($paramstr), $params, 'root', $ptr);
1805
-                } else {
1806
-                    while ($ptr < strlen($paramstr)) {
1807
-                        while (true) {
1808
-                            if ($ptr >= strlen($paramstr)) {
1809
-                                break 2;
1810
-                            }
1811
-
1812
-                            if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') {
1813
-                                if ($this->debug) {
1814
-                                    echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT ' . $ptr . "\n";
1815
-                                }
1816
-                                break 2;
1817
-                            } elseif ($paramstr[$ptr] === ';') {
1818
-                                ++ $ptr;
1819
-                                if ($this->debug) {
1820
-                                    echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT ' . $ptr . "\n";
1821
-                                }
1822
-                                break 2;
1823
-                            } elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') {
1824
-                                if ($this->debug) {
1825
-                                    echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT ' . $ptr . "\n";
1826
-                                }
1827
-                                break 2;
1828
-                            } elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
1829
-                                if ($this->debug) {
1830
-                                    echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT ' . $ptr . "\n";
1831
-                                }
1832
-                                break 2;
1833
-                            }
1834
-
1835
-                            if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") {
1836
-                                ++ $ptr;
1837
-                            } else {
1838
-                                break;
1839
-                            }
1840
-                        }
1841
-
1842
-                        if ($this->debug) {
1843
-                            echo 'FUNC START PARAM PARSING WITH POINTER AT ' . $ptr . "\n";
1844
-                        }
1845
-
1846
-                        if ($func === 'if' || $func === 'elseif' || $func === 'tif') {
1847
-                            $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'condition', $ptr);
1848
-                        } elseif ($func === 'array') {
1849
-                            $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'array', $ptr);
1850
-                        } else {
1851
-                            $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'function', $ptr);
1852
-                        }
1853
-
1854
-                        if ($this->debug) {
1855
-                            echo 'PARAM PARSED, POINTER AT ' . $ptr . ' (' . substr($paramstr, $ptr - 1, 3) . ')' . "\n";
1856
-                        }
1857
-                    }
1858
-                }
1859
-                $paramstr = substr($paramstr, 0, $ptr);
1860
-                $state    = 0;
1861
-                foreach ($params as $k => $p) {
1862
-                    if (is_array($p) && is_array($p[1])) {
1863
-                        $state |= 2;
1864
-                    } else {
1865
-                        if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m) && $func !== 'array') {
1866
-                            $params[$k] = array($m[2], array('true', 'true'));
1867
-                        } else {
1868
-                            if ($state & 2 && $func !== 'array') {
1869
-                                throw new CompilationException($this, 'You can not use an unnamed parameter after a named one');
1870
-                            }
1871
-                            $state |= 1;
1872
-                        }
1873
-                    }
1874
-                }
1875
-            }
1876
-        }
1877
-
1878
-        if ($pointer !== null) {
1879
-            $pointer += (isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func) + (isset($whitespace) ? $whitespace : 0);
1880
-            if ($this->debug) {
1881
-                echo 'FUNC ADDS ' . ((isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func)) . ' TO POINTER' . "\n";
1882
-            }
1883
-        }
1884
-
1885
-        if ($curBlock === 'method' || $func === 'do' || strstr($func, '::') !== false) {
1886
-            // handle static method calls with security policy
1887
-            if (strstr($func, '::') !== false && $this->securityPolicy !== null && $this->securityPolicy->isMethodAllowed(explode('::', strtolower($func))) !== true) {
1888
-                throw new SecurityException('Call to a disallowed php function : ' . $func);
1889
-            }
1890
-            $pluginType = Core::NATIVE_PLUGIN;
1891
-        } else {
1892
-            $pluginType = $this->getPluginType($func);
1893
-        }
1894
-
1895
-        // Blocks plugin
1896
-        if ($pluginType & Core::BLOCK_PLUGIN) {
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
-            if ($pluginType & Core::CUSTOM_PLUGIN) {
1901
-                return $this->addCustomBlock($func, $params, $state);
1902
-            } else {
1903
-                return $this->addBlock($func, $params, $state);
1904
-            }
1905
-        } elseif ($pluginType & Core::SMARTY_BLOCK) {
1906
-            if ($curBlock !== 'root' || is_array($parsingParams)) {
1907
-                throw new CompilationException($this, 'Block plugins can not be used as other plugin\'s arguments');
1908
-            }
1909
-
1910
-            if ($state & 2) {
1911
-                array_unshift($params, array('__functype', array($pluginType, $pluginType)));
1912
-                array_unshift($params, array('__funcname', array($func, $func)));
1913
-            } else {
1914
-                array_unshift($params, array($pluginType, $pluginType));
1915
-                array_unshift($params, array($func, $func));
1916
-            }
1917
-
1918
-            return $this->addBlock('smartyinterface', $params, $state);
1919
-        }
1920
-
1921
-        // Native & Smarty plugins
1922
-        if ($pluginType & Core::NATIVE_PLUGIN || $pluginType & Core::SMARTY_FUNCTION || $pluginType & Core::SMARTY_BLOCK) {
1923
-            $params = $this->mapParams($params, null, $state);
1924
-        } // PHP class plugin
1925
-        elseif ($pluginType & Core::CLASS_PLUGIN) {
1926
-            if ($pluginType & Core::CUSTOM_PLUGIN) {
1927
-                $params = $this->mapParams(
1928
-                    $params, array(
1929
-                    $this->customPlugins[$func]['class'],
1930
-                    $this->customPlugins[$func]['function']
1931
-                ), $state);
1932
-            } else {
1933
-                if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
1934
-                    $params = $this->mapParams($params, array(
1935
-                        'Plugin' . Core::toCamelCase($func),
1936
-                        ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1937
-                    ), $state);
1938
-                } elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== false) {
1939
-                    $params = $this->mapParams($params, array(
1940
-                        Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func),
1941
-                        ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1942
-                    ), $state);
1943
-                } else {
1944
-                    $params = $this->mapParams($params, array(
1945
-                        Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
1946
-                        ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1947
-                    ), $state);
1948
-                }
1949
-            }
1950
-        } // PHP function plugin
1951
-        elseif ($pluginType & Core::FUNC_PLUGIN) {
1952
-            if ($pluginType & Core::CUSTOM_PLUGIN) {
1953
-                $params = $this->mapParams($params, $this->customPlugins[$func]['callback'], $state);
1954
-            } else {
1955
-                // Custom plugin
1956
-                if (function_exists('Plugin' . Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ?
1957
-                        'Compile' : '')) !== false) {
1958
-                    $params = $this->mapParams($params, 'Plugin' . Core::toCamelCase($func) . (($pluginType &
1959
-                            Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1960
-                } // Builtin helper plugin
1961
-                elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . (
1962
-                    ($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) !== false) {
1963
-                    $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase
1964
-                        ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1965
-                } // Builtin function plugin
1966
-                else {
1967
-                    $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase
1968
-                        ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1969
-                }
1970
-            }
1971
-        } // Smarty modifier
1972
-        elseif ($pluginType & Core::SMARTY_MODIFIER) {
1973
-            $output = 'smarty_modifier_' . $func . '(' . implode(', ', $params) . ')';
1974
-        } // Proxy plugin
1975
-        elseif ($pluginType & Core::PROXY_PLUGIN) {
1976
-            $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state);
1977
-        } // Template plugin
1978
-        elseif ($pluginType & Core::TEMPLATE_PLUGIN) {
1979
-            // transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values))
1980
-            $map = array();
1981
-            foreach ($this->templatePlugins[$func]['params'] as $param => $defValue) {
1982
-                if ($param == 'rest') {
1983
-                    $param = '*';
1984
-                }
1985
-                $hasDefault = $defValue !== null;
1986
-                if ($defValue === 'null') {
1987
-                    $defValue = null;
1988
-                } elseif ($defValue === 'false') {
1989
-                    $defValue = false;
1990
-                } elseif ($defValue === 'true') {
1991
-                    $defValue = true;
1992
-                } elseif (preg_match('#^([\'"]).*?\1$#', $defValue)) {
1993
-                    $defValue = substr($defValue, 1, - 1);
1994
-                }
1995
-                $map[] = array($param, $hasDefault, $defValue);
1996
-            }
1997
-
1998
-            $params = $this->mapParams($params, null, $state, $map);
1999
-        }
2000
-
2001
-        // only keep php-syntax-safe values for non-block plugins
2002
-        $tokens = array();
2003
-        foreach ($params as $k => $p) {
2004
-            $tokens[$k] = isset($p[2]) ? $p[2] : 0;
2005
-            $params[$k] = $p[0];
2006
-        }
2007
-
2008
-        // Native plugin
2009
-        if ($pluginType & Core::NATIVE_PLUGIN) {
2010
-            if ($func === 'do') {
2011
-                $output = '';
2012
-                if (isset($params['*'])) {
2013
-                    $output = implode(';', $params['*']) . ';';
2014
-                }
2015
-
2016
-                if (is_array($parsingParams) || $curBlock !== 'root') {
2017
-                    throw new CompilationException($this, 'Do can not be used inside another function or block');
2018
-                }
2019
-
2020
-                return self::PHP_OPEN . $output . self::PHP_CLOSE;
2021
-            } else {
2022
-                if (isset($params['*'])) {
2023
-                    $output = $func . '(' . implode(', ', $params['*']) . ')';
2024
-                } else {
2025
-                    $output = $func . '()';
2026
-                }
2027
-            }
2028
-        } // Block class OR Function class
2029
-        elseif ($pluginType & Core::CLASS_PLUGIN || ($pluginType & Core::FUNC_PLUGIN && $pluginType & Core::CLASS_PLUGIN)) {
2030
-            if ($pluginType & Core::COMPILABLE_PLUGIN) {
2031
-                if ($pluginType & Core::CUSTOM_PLUGIN) {
2032
-                    $callback = $this->customPlugins[$func]['callback'];
2033
-                    if (!is_array($callback)) {
2034
-                        if (!method_exists($callback, 'compile')) {
2035
-                            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');
2036
-                        }
2037
-                        if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) {
2038
-                            $funcCompiler = array($callback, 'compile');
2039
-                        } else {
2040
-                            $funcCompiler = array(new $callback(), 'compile');
2041
-                        }
2042
-                    } else {
2043
-                        $funcCompiler = $callback;
2044
-                    }
2045
-                } else {
2046
-                    if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2047
-                        $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile');
2048
-                    } elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== false) {
2049
-                        $funcCompiler = array(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func), 'compile');
2050
-                    } else {
2051
-                        $funcCompiler = array(
2052
-                            Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
2053
-                            'compile'
2054
-                        );
2055
-                    }
2056
-                    array_unshift($params, $this);
2057
-                }
2058
-                // @TODO: Is it a real fix ?
2059
-                if ($func === 'tif') {
2060
-                    $params[] = $tokens;
2061
-                }
2062
-                $output = call_user_func_array($funcCompiler, $params);
2063
-            } else {
2064
-                $params = self::implode_r($params);
2065
-                if ($pluginType & Core::CUSTOM_PLUGIN) {
2066
-                    $callback = $this->customPlugins[$func]['callback'];
2067
-                    if (!is_array($callback)) {
2068
-                        if (!method_exists($callback, 'process')) {
2069
-                            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');
2070
-                        }
2071
-                        if (($ref = new ReflectionMethod($callback, 'process')) && $ref->isStatic()) {
2072
-                            $output = 'call_user_func(array(\'' . $callback . '\', \'process\'), ' . $params . ')';
2073
-                        } else {
2074
-                            $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback . '\'), \'process\'), ' . $params . ')';
2075
-                        }
2076
-                    } elseif (is_object($callback[0])) {
2077
-                        $output = 'call_user_func(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), ' . $params . ')';
2078
-                    } elseif (($ref = new ReflectionMethod($callback[0], $callback[1])) && $ref->isStatic()) {
2079
-                        $output = 'call_user_func(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), ' . $params . ')';
2080
-                    } else {
2081
-                        $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback[0] . '\'), \'' . $callback[1] . '\'), ' . $params . ')';
2082
-                    }
2083
-                    if (empty($params)) {
2084
-                        $output = substr($output, 0, - 3) . ')';
2085
-                    }
2086
-                } else {
2087
-                    if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2088
-                        $output = '$this->classCall(\'Plugin' . $func . '\', array(' . $params . '))';
2089
-                    } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== false) {
2090
-                        $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::CLASS_PLUGIN:
879
+				case Core::CLASS_PLUGIN + Core::BLOCK_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::CLASS_PLUGIN + Core::FUNC_PLUGIN:
889
+					if (class_exists('Plugin' . $plugin) !== false) {
890
+						$output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)".
891
+							"\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
892
+					} else {
893
+						$output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
894
+							"\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
895
+					}
896
+					break;
897
+				case Core::FUNC_PLUGIN:
898
+					if (function_exists('Plugin' . $plugin) !== false) {
899
+						$output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)".
900
+						"\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
901
+					} else {
902
+						$output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
903
+						"\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
904
+					}
905
+					break;
906
+				case Core::SMARTY_MODIFIER:
907
+					$output .= "if (function_exists('smarty_modifier_$plugin')===false)".
908
+					"\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
909
+					break;
910
+				case Core::SMARTY_FUNCTION:
911
+					$output .= "if (function_exists('smarty_function_$plugin')===false)".
912
+					"\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
913
+					break;
914
+				case Core::SMARTY_BLOCK:
915
+					$output .= "if (function_exists('smarty_block_$plugin')===false)".
916
+					"\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
917
+					break;
918
+				case Core::PROXY_PLUGIN:
919
+					$output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin);
920
+					break;
921
+				default:
922
+					throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type);
923
+			}
924
+		}
925
+
926
+		foreach ($this->templatePlugins as $function => $attr) {
927
+			if (isset($attr['called']) && $attr['called'] === true && !isset($attr['checked'])) {
928
+				$this->resolveSubTemplateDependencies($function);
929
+			}
930
+		}
931
+		foreach ($this->templatePlugins as $function) {
932
+			if (isset($function['called']) && $function['called'] === true) {
933
+				$output .= $function['body'] . PHP_EOL;
934
+			}
935
+		}
936
+
937
+		$output .= $compiled . "\n?>";
938
+
939
+		$output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*' . preg_quote(self::PHP_CLOSE, '/') . preg_quote(self::PHP_OPEN, '/') . ')/', ";\n", $output);
940
+		$output = str_replace(self::PHP_CLOSE . self::PHP_OPEN, "\n", $output);
941
+
942
+		// handle <?xml tag at the beginning
943
+		$output = preg_replace('#(/\* template body \*/ \?>\s*)<\?xml#is', '$1<?php echo \'<?xml\'; ?>', $output);
944
+
945
+		// add another line break after PHP closing tags that have a line break following,
946
+		// as we do not know whether it's intended, and PHP will strip it otherwise
947
+		$output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0' . "\n", $output);
948
+
949
+		if ($this->debug) {
950
+			echo '=============================================================================================' . "\n";
951
+			$lines = preg_split('{\r\n|\n|<br />}', $output);
952
+			array_shift($lines);
953
+			foreach ($lines as $i => $line) {
954
+				echo ($i + 1) . '. ' . $line . "\r\n";
955
+			}
956
+			echo '=============================================================================================' . "\n";
957
+		}
958
+
959
+		$this->template = $this->dwoo = null;
960
+		$tpl            = null;
961
+
962
+		return $output;
963
+	}
964
+
965
+	/**
966
+	 * Checks what sub-templates are used in every sub-template so that we're sure they are all compiled.
967
+	 *
968
+	 * @param string $function the sub-template name
969
+	 */
970
+	protected function resolveSubTemplateDependencies($function)
971
+	{
972
+		if ($this->debug) {
973
+			echo 'Compiler::' . __FUNCTION__ . "\n";
974
+		}
975
+
976
+		$body = $this->templatePlugins[$function]['body'];
977
+		foreach ($this->templatePlugins as $func => $attr) {
978
+			if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS .
979
+			'Plugin' . Core::toCamelCase($func)) !== false) {
980
+				$this->templatePlugins[$func]['called'] = true;
981
+				$this->resolveSubTemplateDependencies($func);
982
+			}
983
+		}
984
+		$this->templatePlugins[$function]['checked'] = true;
985
+	}
986
+
987
+	/**
988
+	 * Adds compiled content to the current block.
989
+	 *
990
+	 * @param string $content   the content to push
991
+	 * @param int    $lineCount newlines count in content, optional
992
+	 *
993
+	 * @throws CompilationException
994
+	 */
995
+	public function push($content, $lineCount = null)
996
+	{
997
+		if ($lineCount === null) {
998
+			$lineCount = substr_count($content, "\n");
999
+		}
1000
+
1001
+		if ($this->curBlock['buffer'] === null && count($this->stack) > 1) {
1002
+			// buffer is not initialized yet (the block has just been created)
1003
+			$this->stack[count($this->stack) - 2]['buffer'] .= (string)$content;
1004
+			$this->curBlock['buffer'] = '';
1005
+		} else {
1006
+			if (!isset($this->curBlock['buffer'])) {
1007
+				throw new CompilationException($this, 'The template has been closed too early, you probably have an extra block-closing tag somewhere');
1008
+			}
1009
+			// append current content to current block's buffer
1010
+			$this->curBlock['buffer'] .= (string)$content;
1011
+		}
1012
+		$this->line += $lineCount;
1013
+	}
1014
+
1015
+	/**
1016
+	 * Sets the scope.
1017
+	 * set to null if the scope becomes "unstable" (i.e. too variable or unknown) so that
1018
+	 * variables are compiled in a more evaluative way than just $this->scope['key']
1019
+	 *
1020
+	 * @param mixed $scope    a string i.e. "level1.level2" or an array i.e. array("level1", "level2")
1021
+	 * @param bool  $absolute if true, the scope is set from the top level scope and not from the current scope
1022
+	 *
1023
+	 * @return array the current scope tree
1024
+	 */
1025
+	public function setScope($scope, $absolute = false)
1026
+	{
1027
+		$old = $this->scopeTree;
1028
+
1029
+		if ($scope === null) {
1030
+			unset($this->scope);
1031
+			$this->scope = null;
1032
+		}
1033
+
1034
+		if (is_array($scope) === false) {
1035
+			$scope = explode('.', $scope);
1036
+		}
1037
+
1038
+		if ($absolute === true) {
1039
+			$this->scope     = &$this->data;
1040
+			$this->scopeTree = array();
1041
+		}
1042
+
1043
+		while (($bit = array_shift($scope)) !== null) {
1044
+			if ($bit === '_parent' || $bit === '_') {
1045
+				array_pop($this->scopeTree);
1046
+				reset($this->scopeTree);
1047
+				$this->scope = &$this->data;
1048
+				$cnt         = count($this->scopeTree);
1049
+				for ($i = 0; $i < $cnt; ++ $i) {
1050
+					$this->scope = &$this->scope[$this->scopeTree[$i]];
1051
+				}
1052
+			} elseif ($bit === '_root' || $bit === '__') {
1053
+				$this->scope     = &$this->data;
1054
+				$this->scopeTree = array();
1055
+			} elseif (isset($this->scope[$bit])) {
1056
+				$this->scope       = &$this->scope[$bit];
1057
+				$this->scopeTree[] = $bit;
1058
+			} else {
1059
+				$this->scope[$bit] = array();
1060
+				$this->scope       = &$this->scope[$bit];
1061
+				$this->scopeTree[] = $bit;
1062
+			}
1063
+		}
1064
+
1065
+		return $old;
1066
+	}
1067
+
1068
+	/**
1069
+	 * Adds a block to the top of the block stack.
1070
+	 *
1071
+	 * @param string $type      block type (name)
1072
+	 * @param array  $params    the parameters array
1073
+	 * @param int    $paramtype the parameters type (see mapParams), 0, 1 or 2
1074
+	 *
1075
+	 * @return string the preProcessing() method's output
1076
+	 */
1077
+	public function addBlock($type, array $params, $paramtype)
1078
+	{
1079
+		if ($this->debug) {
1080
+			echo 'Compiler::' . __FUNCTION__ . "\n";
1081
+		}
1082
+
1083
+		$class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type);
1084
+		if (class_exists($class) === false) {
1085
+			$this->getDwoo()->getLoader()->loadPlugin($type);
1086
+		}
1087
+		$params = $this->mapParams($params, array($class, 'init'), $paramtype);
1088
+
1089
+		$this->stack[]  = array(
1090
+			'type'   => $type,
1091
+			'params' => $params,
1092
+			'custom' => false,
1093
+			'class'  => $class,
1094
+			'buffer' => null
1095
+		);
1096
+		$this->curBlock = &$this->stack[count($this->stack) - 1];
1097
+
1098
+		return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type);
1099
+	}
1100
+
1101
+	/**
1102
+	 * Adds a custom block to the top of the block stack.
1103
+	 *
1104
+	 * @param string $type      block type (name)
1105
+	 * @param array  $params    the parameters array
1106
+	 * @param int    $paramtype the parameters type (see mapParams), 0, 1 or 2
1107
+	 *
1108
+	 * @return string the preProcessing() method's output
1109
+	 */
1110
+	public function addCustomBlock($type, array $params, $paramtype)
1111
+	{
1112
+		$callback = $this->customPlugins[$type]['callback'];
1113
+		if (is_array($callback)) {
1114
+			$class = is_object($callback[0]) ? get_class($callback[0]) : $callback[0];
1115
+		} else {
1116
+			$class = $callback;
1117
+		}
1118
+
1119
+		$params = $this->mapParams($params, array($class, 'init'), $paramtype);
1120
+
1121
+		$this->stack[]  = array(
1122
+			'type'   => $type,
1123
+			'params' => $params,
1124
+			'custom' => true,
1125
+			'class'  => $class,
1126
+			'buffer' => null
1127
+		);
1128
+		$this->curBlock = &$this->stack[count($this->stack) - 1];
1129
+
1130
+		return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type);
1131
+	}
1132
+
1133
+	/**
1134
+	 * Injects a block at the top of the plugin stack without calling its preProcessing method.
1135
+	 * used by {else} blocks to re-add themselves after having closed everything up to their parent
1136
+	 *
1137
+	 * @param string $type   block type (name)
1138
+	 * @param array  $params parameters array
1139
+	 */
1140
+	public function injectBlock($type, array $params)
1141
+	{
1142
+		if ($this->debug) {
1143
+			echo 'Compiler::' . __FUNCTION__ . "\n";
1144
+		}
1145
+
1146
+		$class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type);
1147
+		if (class_exists($class) === false) {
1148
+			$this->getDwoo()->getLoader()->loadPlugin($type);
1149
+		}
1150
+		$this->stack[]  = array(
1151
+			'type'   => $type,
1152
+			'params' => $params,
1153
+			'custom' => false,
1154
+			'class'  => $class,
1155
+			'buffer' => null
1156
+		);
1157
+		$this->curBlock = &$this->stack[count($this->stack) - 1];
1158
+	}
1159
+
1160
+	/**
1161
+	 * Removes the closest-to-top block of the given type and all other
1162
+	 * blocks encountered while going down the block stack.
1163
+	 *
1164
+	 * @param string $type block type (name)
1165
+	 *
1166
+	 * @return string the output of all postProcessing() method's return values of the closed blocks
1167
+	 * @throws CompilationException
1168
+	 */
1169
+	public function removeBlock($type)
1170
+	{
1171
+		if ($this->debug) {
1172
+			echo 'Compiler::' . __FUNCTION__ . "\n";
1173
+		}
1174
+
1175
+		$output = '';
1176
+
1177
+		$pluginType = $this->getPluginType($type);
1178
+		if ($pluginType & Core::SMARTY_BLOCK) {
1179
+			$type = 'Smartyinterface';
1180
+		}
1181
+		while (true) {
1182
+			while ($top = array_pop($this->stack)) {
1183
+				if ($top['custom']) {
1184
+					$class = $top['class'];
1185
+				} else {
1186
+					$class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($top['type']);
1187
+				}
1188
+				if (count($this->stack)) {
1189
+					$this->curBlock = &$this->stack[count($this->stack) - 1];
1190
+					$this->push(call_user_func(array(
1191
+						$class,
1192
+						'postProcessing'
1193
+					), $this, $top['params'], '', '', $top['buffer']), 0);
1194
+				} else {
1195
+					$null           = null;
1196
+					$this->curBlock = &$null;
1197
+					$output         = call_user_func(
1198
+						array(
1199
+						$class,
1200
+						'postProcessing'
1201
+						), $this, $top['params'], '', '', $top['buffer']
1202
+					);
1203
+				}
1204
+
1205
+				if ($top['type'] === $type) {
1206
+					break 2;
1207
+				}
1208
+			}
1209
+
1210
+			throw new CompilationException($this, 'Syntax malformation, a block of type "' . $type . '" was closed but was not opened');
1211
+			break;
1212
+		}
1213
+
1214
+		return $output;
1215
+	}
1216
+
1217
+	/**
1218
+	 * Returns a reference to the first block of the given type encountered and
1219
+	 * optionally closes all blocks until it finds it
1220
+	 * this is mainly used by {else} plugins to close everything that was opened
1221
+	 * between their parent and themselves.
1222
+	 *
1223
+	 * @param string $type       the block type (name)
1224
+	 * @param bool   $closeAlong whether to close all blocks encountered while going down the block stack or not
1225
+	 *
1226
+	 * @return mixed &array the array is as such: array('type'=>pluginName, 'params'=>parameter array,
1227
+	 *               'custom'=>bool defining whether it's a custom plugin or not, for internal use)
1228
+	 * @throws CompilationException
1229
+	 */
1230
+	public function &findBlock($type, $closeAlong = false)
1231
+	{
1232
+		if ($closeAlong === true) {
1233
+			while ($b = end($this->stack)) {
1234
+				if ($b['type'] === $type) {
1235
+					return $this->stack[key($this->stack)];
1236
+				}
1237
+				$this->push($this->removeTopBlock(), 0);
1238
+			}
1239
+		} else {
1240
+			end($this->stack);
1241
+			while ($b = current($this->stack)) {
1242
+				if ($b['type'] === $type) {
1243
+					return $this->stack[key($this->stack)];
1244
+				}
1245
+				prev($this->stack);
1246
+			}
1247
+		}
1248
+
1249
+		throw new CompilationException($this, 'A parent block of type "' . $type . '" is required and can not be found');
1250
+	}
1251
+
1252
+	/**
1253
+	 * Returns a reference to the current block array.
1254
+	 *
1255
+	 * @return array the array is as such: array('type'=>pluginName, 'params'=>parameter array,
1256
+	 *                'custom'=>bool defining whether it's a custom plugin or not, for internal use)
1257
+	 */
1258
+	public function &getCurrentBlock()
1259
+	{
1260
+		return $this->curBlock;
1261
+	}
1262
+
1263
+	/**
1264
+	 * Removes the block at the top of the stack and calls its postProcessing() method.
1265
+	 *
1266
+	 * @return string the postProcessing() method's output
1267
+	 * @throws CompilationException
1268
+	 */
1269
+	public function removeTopBlock()
1270
+	{
1271
+		if ($this->debug) {
1272
+			echo 'Compiler::' . __FUNCTION__ . "\n";
1273
+		}
1274
+
1275
+		$o = array_pop($this->stack);
1276
+		if ($o === null) {
1277
+			throw new CompilationException($this, 'Syntax malformation, a block of unknown type was closed but was not opened.');
1278
+		}
1279
+		if ($o['custom']) {
1280
+			$class = $o['class'];
1281
+		} else {
1282
+			$class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($o['type']);
1283
+		}
1284
+
1285
+		$this->curBlock = &$this->stack[count($this->stack) - 1];
1286
+
1287
+		return call_user_func(array($class, 'postProcessing'), $this, $o['params'], '', '', $o['buffer']);
1288
+	}
1289
+
1290
+	/**
1291
+	 * Returns the compiled parameters (for example a variable's compiled parameter will be "$this->scope['key']") out
1292
+	 * of the given parameter array.
1293
+	 *
1294
+	 * @param array $params parameter array
1295
+	 *
1296
+	 * @return array filtered parameters
1297
+	 */
1298
+	public function getCompiledParams(array $params)
1299
+	{
1300
+		foreach ($params as $k => $p) {
1301
+			if (is_array($p)) {
1302
+				$params[$k] = $p[0];
1303
+			}
1304
+		}
1305
+
1306
+		return $params;
1307
+	}
1308
+
1309
+	/**
1310
+	 * Returns the real parameters (for example a variable's real parameter will be its key, etc) out of the given
1311
+	 * parameter array.
1312
+	 *
1313
+	 * @param array $params parameter array
1314
+	 *
1315
+	 * @return array filtered parameters
1316
+	 */
1317
+	public function getRealParams(array $params)
1318
+	{
1319
+		foreach ($params as $k => $p) {
1320
+			if (is_array($p)) {
1321
+				$params[$k] = $p[1];
1322
+			}
1323
+		}
1324
+
1325
+		return $params;
1326
+	}
1327
+
1328
+	/**
1329
+	 * Returns the token of each parameter out of the given parameter array.
1330
+	 *
1331
+	 * @param array $params parameter array
1332
+	 *
1333
+	 * @return array tokens
1334
+	 */
1335
+	public function getParamTokens(array $params)
1336
+	{
1337
+		foreach ($params as $k => $p) {
1338
+			if (is_array($p)) {
1339
+				$params[$k] = isset($p[2]) ? $p[2] : 0;
1340
+			}
1341
+		}
1342
+
1343
+		return $params;
1344
+	}
1345
+
1346
+	/**
1347
+	 * Entry point of the parser, it redirects calls to other parse* functions.
1348
+	 *
1349
+	 * @param string $in            the string within which we must parse something
1350
+	 * @param int    $from          the starting offset of the parsed area
1351
+	 * @param int    $to            the ending offset of the parsed area
1352
+	 * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
1353
+	 *                              default
1354
+	 * @param string $curBlock      the current parser-block being processed
1355
+	 * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
1356
+	 *                              or null by default
1357
+	 *
1358
+	 * @return string parsed values
1359
+	 * @throws CompilationException
1360
+	 */
1361
+	protected function parse($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
1362
+	{
1363
+		if ($this->debug) {
1364
+			echo 'Compiler::' . __FUNCTION__ . "\n";
1365
+		}
1366
+
1367
+		if ($to === null) {
1368
+			$to = strlen($in);
1369
+		}
1370
+		$first = substr($in, $from, 1);
1371
+
1372
+		if ($first === false) {
1373
+			throw new CompilationException($this, 'Unexpected EOF, a template tag was not closed');
1374
+		}
1375
+
1376
+		while ($first === ' ' || $first === "\n" || $first === "\t" || $first === "\r") {
1377
+			if ($curBlock === 'root' && substr($in, $from, strlen($this->rd)) === $this->rd) {
1378
+				// end template tag
1379
+				$pointer += strlen($this->rd);
1380
+				if ($this->debug) {
1381
+					echo 'TEMPLATE PARSING ENDED' . "\n";
1382
+				}
1383
+
1384
+				return false;
1385
+			}
1386
+			++ $from;
1387
+			if ($pointer !== null) {
1388
+				++ $pointer;
1389
+			}
1390
+			if ($from >= $to) {
1391
+				if (is_array($parsingParams)) {
1392
+					return $parsingParams;
1393
+				} else {
1394
+					return '';
1395
+				}
1396
+			}
1397
+			$first = $in[$from];
1398
+		}
1399
+
1400
+		$substr = substr($in, $from, $to - $from);
1401
+
1402
+		if ($this->debug) {
1403
+			echo 'PARSE CALL : PARSING "' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . '" @ ' . $from . ':' . $to . ' in ' . $curBlock . ' : pointer=' . $pointer . "\n";
1404
+		}
1405
+		$parsed = '';
1406
+
1407
+		if ($curBlock === 'root' && $first === '*') {
1408
+			$src      = $this->getTemplateSource();
1409
+			$startpos = $this->getPointer() - strlen($this->ld);
1410
+			if (substr($src, $startpos, strlen($this->ld)) === $this->ld) {
1411
+				if ($startpos > 0) {
1412
+					do {
1413
+						$char = substr($src, -- $startpos, 1);
1414
+						if ($char == "\n") {
1415
+							++ $startpos;
1416
+							$whitespaceStart = true;
1417
+							break;
1418
+						}
1419
+					}
1420
+					while ($startpos > 0 && ($char == ' ' || $char == "\t"));
1421
+				}
1422
+
1423
+				if (!isset($whitespaceStart)) {
1424
+					$startpos = $this->getPointer();
1425
+				} else {
1426
+					$pointer -= $this->getPointer() - $startpos;
1427
+				}
1428
+
1429
+				if ($this->allowNestedComments && strpos($src, $this->ld . '*', $this->getPointer()) !== false) {
1430
+					$comOpen  = $this->ld . '*';
1431
+					$comClose = '*' . $this->rd;
1432
+					$level    = 1;
1433
+					$ptr      = $this->getPointer();
1434
+
1435
+					while ($level > 0 && $ptr < strlen($src)) {
1436
+						$open  = strpos($src, $comOpen, $ptr);
1437
+						$close = strpos($src, $comClose, $ptr);
1438
+
1439
+						if ($open !== false && $close !== false) {
1440
+							if ($open < $close) {
1441
+								$ptr = $open + strlen($comOpen);
1442
+								++ $level;
1443
+							} else {
1444
+								$ptr = $close + strlen($comClose);
1445
+								-- $level;
1446
+							}
1447
+						} elseif ($open !== false) {
1448
+							$ptr = $open + strlen($comOpen);
1449
+							++ $level;
1450
+						} elseif ($close !== false) {
1451
+							$ptr = $close + strlen($comClose);
1452
+							-- $level;
1453
+						} else {
1454
+							$ptr = strlen($src);
1455
+						}
1456
+					}
1457
+					$endpos = $ptr - strlen('*' . $this->rd);
1458
+				} else {
1459
+					$endpos = strpos($src, '*' . $this->rd, $startpos);
1460
+					if ($endpos == false) {
1461
+						throw new CompilationException($this, 'Un-ended comment');
1462
+					}
1463
+				}
1464
+				$pointer += $endpos - $startpos + strlen('*' . $this->rd);
1465
+				if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos + strlen('*' . $this->rd)), $m)) {
1466
+					$pointer += strlen($m[0]);
1467
+					$this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer']) - ($this->getPointer() - $startpos - strlen($this->ld)));
1468
+				}
1469
+
1470
+				return false;
1471
+			}
1472
+		}
1473
+
1474
+		if ($first === '$') {
1475
+			// var
1476
+			$out    = $this->parseVar($in, $from, $to, $parsingParams, $curBlock, $pointer);
1477
+			$parsed = 'var';
1478
+		} elseif ($first === '%' && preg_match('#^%[a-z_\\\\]#i', $substr)) {
1479
+			// Short constant
1480
+			$out = $this->parseConst($in, $from, $to, $parsingParams, $curBlock, $pointer);
1481
+		} elseif (($first === '"' || $first === "'") && !(is_array($parsingParams) && preg_match('#^([\'"])[a-z0-9_]+\1\s*=>?(?:\s+|[^=])#i', $substr))) {
1482
+			// string
1483
+			$out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer);
1484
+		} 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)) {
1485
+			// func
1486
+			$out    = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer);
1487
+			$parsed = 'func';
1488
+		} elseif ($first === ';') {
1489
+			// instruction end
1490
+			if ($this->debug) {
1491
+				echo 'END OF INSTRUCTION' . "\n";
1492
+			}
1493
+			if ($pointer !== null) {
1494
+				++ $pointer;
1495
+			}
1496
+
1497
+			return $this->parse($in, $from + 1, $to, false, 'root', $pointer);
1498
+		} elseif ($curBlock === 'root' && preg_match('#^/([a-z_][a-z0-9_]*)?#i', $substr, $match)) {
1499
+			// close block
1500
+			if (!empty($match[1]) && $match[1] == 'else') {
1501
+				throw new CompilationException($this, 'Else blocks must not be closed explicitly, they are automatically closed when their parent block is closed');
1502
+			}
1503
+			if (!empty($match[1]) && $match[1] == 'elseif') {
1504
+				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');
1505
+			}
1506
+			if ($pointer !== null) {
1507
+				$pointer += strlen($match[0]);
1508
+			}
1509
+			if (empty($match[1])) {
1510
+				if ($this->curBlock['type'] == 'else' || $this->curBlock['type'] == 'elseif') {
1511
+					$pointer -= strlen($match[0]);
1512
+				}
1513
+				if ($this->debug) {
1514
+					echo 'TOP BLOCK CLOSED' . "\n";
1515
+				}
1516
+
1517
+				return $this->removeTopBlock();
1518
+			} else {
1519
+				if ($this->debug) {
1520
+					echo 'BLOCK OF TYPE ' . $match[1] . ' CLOSED' . "\n";
1521
+				}
1522
+
1523
+				return $this->removeBlock($match[1]);
1524
+			}
1525
+		} elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) {
1526
+			// end template tag
1527
+			if ($this->debug) {
1528
+				echo 'TAG PARSING ENDED' . "\n";
1529
+			}
1530
+			$pointer += strlen($this->rd);
1531
+
1532
+			return false;
1533
+		} elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*=' . ($curBlock === 'array' ? '>?' : '') . ')(?:\s+|[^=]).*#i', $substr, $match)) {
1534
+			// named parameter
1535
+			if ($this->debug) {
1536
+				echo 'NAMED PARAM FOUND' . "\n";
1537
+			}
1538
+			$len = strlen($match[1]);
1539
+			while (substr($in, $from + $len, 1) === ' ') {
1540
+				++ $len;
1541
+			}
1542
+			if ($pointer !== null) {
1543
+				$pointer += $len;
1544
+			}
1545
+
1546
+			$output = array(
1547
+				trim($match[1], " \t\r\n=>'\""),
1548
+				$this->parse($in, $from + $len, $to, false, 'namedparam', $pointer)
1549
+			);
1550
+
1551
+			$parsingParams[] = $output;
1552
+
1553
+			return $parsingParams;
1554
+		} elseif (preg_match('#^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*::\$[a-z0-9_]+)#i', $substr, $match)) {
1555
+			// static member access
1556
+			$parsed = 'var';
1557
+			if (is_array($parsingParams)) {
1558
+				$parsingParams[] = array($match[1], $match[1]);
1559
+				$out             = $parsingParams;
1560
+			} else {
1561
+				$out = $match[1];
1562
+			}
1563
+			$pointer += strlen($match[1]);
1564
+		} elseif ($substr !== '' && (is_array($parsingParams) || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'expression')) {
1565
+			// unquoted string, bool or number
1566
+			$out = $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1567
+		} else {
1568
+			// parse error
1569
+			throw new CompilationException($this, 'Parse error in "' . substr($in, $from, $to - $from) . '"');
1570
+		}
1571
+
1572
+		if (empty($out)) {
1573
+			return '';
1574
+		}
1575
+
1576
+		$substr = substr($in, $pointer, $to - $pointer);
1577
+
1578
+		// var parsed, check if any var-extension applies
1579
+		if ($parsed === 'var') {
1580
+			if (preg_match('#^\s*([/%+*-])\s*([a-z0-9]|\$)#i', $substr, $match)) {
1581
+				if ($this->debug) {
1582
+					echo 'PARSING POST-VAR EXPRESSION ' . $substr . "\n";
1583
+				}
1584
+				// parse expressions
1585
+				$pointer += strlen($match[0]) - 1;
1586
+				if (is_array($parsingParams)) {
1587
+					if ($match[2] == '$') {
1588
+						$expr = $this->parseVar($in, $pointer, $to, array(), $curBlock, $pointer);
1589
+					} else {
1590
+						$expr = $this->parse($in, $pointer, $to, array(), 'expression', $pointer);
1591
+					}
1592
+					$out[count($out) - 1][0] .= $match[1] . $expr[0][0];
1593
+					$out[count($out) - 1][1] .= $match[1] . $expr[0][1];
1594
+				} else {
1595
+					if ($match[2] == '$') {
1596
+						$expr = $this->parseVar($in, $pointer, $to, false, $curBlock, $pointer);
1597
+					} else {
1598
+						$expr = $this->parse($in, $pointer, $to, false, 'expression', $pointer);
1599
+					}
1600
+					if (is_array($out) && is_array($expr)) {
1601
+						$out[0] .= $match[1] . $expr[0];
1602
+						$out[1] .= $match[1] . $expr[1];
1603
+					} elseif (is_array($out)) {
1604
+						$out[0] .= $match[1] . $expr;
1605
+						$out[1] .= $match[1] . $expr;
1606
+					} elseif (is_array($expr)) {
1607
+						$out .= $match[1] . $expr[0];
1608
+					} else {
1609
+						$out .= $match[1] . $expr;
1610
+					}
1611
+				}
1612
+			} elseif ($curBlock === 'root' && preg_match('#^(\s*(?:[+/*%-.]=|=|\+\+|--)\s*)(.*)#s', $substr, $match)) {
1613
+				if ($this->debug) {
1614
+					echo 'PARSING POST-VAR ASSIGNMENT ' . $substr . "\n";
1615
+				}
1616
+				// parse assignment
1617
+				$value    = $match[2];
1618
+				$operator = trim($match[1]);
1619
+				if (substr($value, 0, 1) == '=') {
1620
+					throw new CompilationException($this, 'Unexpected "=" in <em>' . $substr . '</em>');
1621
+				}
1622
+
1623
+				if ($pointer !== null) {
1624
+					$pointer += strlen($match[1]);
1625
+				}
1626
+
1627
+				if ($operator !== '++' && $operator !== '--') {
1628
+					$parts = array();
1629
+					$ptr   = 0;
1630
+					$parts = $this->parse($value, 0, strlen($value), $parts, 'condition', $ptr);
1631
+					$pointer += $ptr;
1632
+
1633
+					// load if plugin
1634
+					try {
1635
+						$this->getPluginType('if');
1636
+					}
1637
+					catch (Exception $e) {
1638
+						throw new CompilationException($this, 'Assignments require the "if" plugin to be accessible');
1639
+					}
1640
+
1641
+					$parts  = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS . 'PluginIf', 'init'), 1);
1642
+					$tokens = $this->getParamTokens($parts);
1643
+					$parts  = $this->getCompiledParams($parts);
1644
+
1645
+					$value = PluginIf::replaceKeywords($parts['*'], $tokens['*'], $this);
1646
+					$echo  = '';
1647
+				} else {
1648
+					$value = array();
1649
+					$echo  = 'echo ';
1650
+				}
1651
+
1652
+				if ($this->autoEscape) {
1653
+					$out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out);
1654
+				}
1655
+				$out = self::PHP_OPEN . $echo . $out . $operator . implode(' ', $value) . self::PHP_CLOSE;
1656
+			} elseif ($curBlock === 'array' && is_array($parsingParams) && preg_match('#^(\s*=>?\s*)#', $substr, $match)) {
1657
+				// parse namedparam with var as name (only for array)
1658
+				if ($this->debug) {
1659
+					echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND' . "\n";
1660
+				}
1661
+				$len = strlen($match[1]);
1662
+				$var = $out[count($out) - 1];
1663
+				$pointer += $len;
1664
+
1665
+				$output = array($var[0], $this->parse($substr, $len, null, false, 'namedparam', $pointer));
1666
+
1667
+				$parsingParams[] = $output;
1668
+
1669
+				return $parsingParams;
1670
+			}
1671
+		}
1672
+
1673
+		if ($curBlock !== 'modifier' && ($parsed === 'func' || $parsed === 'var') && preg_match('#^(\|@?[a-z0-9_]+(:.*)?)+#i', $substr, $match)) {
1674
+			// parse modifier on funcs or vars
1675
+			$srcPointer = $pointer;
1676
+			if (is_array($parsingParams)) {
1677
+				$tmp                     = $this->replaceModifiers(
1678
+					array(
1679
+					null,
1680
+					null,
1681
+					$out[count($out) - 1][0],
1682
+					$match[0]
1683
+					), $curBlock, $pointer
1684
+				);
1685
+				$out[count($out) - 1][0] = $tmp;
1686
+				$out[count($out) - 1][1] .= substr($substr, $srcPointer, $srcPointer - $pointer);
1687
+			} else {
1688
+				$out = $this->replaceModifiers(array(null, null, $out, $match[0]), $curBlock, $pointer);
1689
+			}
1690
+		}
1691
+
1692
+		// func parsed, check if any func-extension applies
1693
+		if ($parsed === 'func' && preg_match('#^->[a-z0-9_]+(\s*\(.+|->[a-z_].*)?#is', $substr, $match)) {
1694
+			// parse method call or property read
1695
+			$ptr = 0;
1696
+
1697
+			if (is_array($parsingParams)) {
1698
+				$output = $this->parseMethodCall($out[count($out) - 1][1], $match[0], $curBlock, $ptr);
1699
+
1700
+				$out[count($out) - 1][0] = $output;
1701
+				$out[count($out) - 1][1] .= substr($match[0], 0, $ptr);
1702
+			} else {
1703
+				$out = $this->parseMethodCall($out, $match[0], $curBlock, $ptr);
1704
+			}
1705
+
1706
+			$pointer += $ptr;
1707
+		}
1708
+
1709
+		if ($curBlock === 'root' && substr($out, 0, strlen(self::PHP_OPEN)) !== self::PHP_OPEN) {
1710
+			return self::PHP_OPEN . 'echo ' . $out . ';' . self::PHP_CLOSE;
1711
+		} else {
1712
+			return $out;
1713
+		}
1714
+	}
1715
+
1716
+	/**
1717
+	 * Parses a function call.
1718
+	 *
1719
+	 * @param string $in            the string within which we must parse something
1720
+	 * @param int    $from          the starting offset of the parsed area
1721
+	 * @param int    $to            the ending offset of the parsed area
1722
+	 * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
1723
+	 *                              default
1724
+	 * @param string $curBlock      the current parser-block being processed
1725
+	 * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
1726
+	 *                              or null by default
1727
+	 *
1728
+	 * @return string parsed values
1729
+	 * @throws CompilationException
1730
+	 * @throws Exception
1731
+	 * @throws SecurityException
1732
+	 */
1733
+	protected function parseFunction($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
1734
+	{
1735
+		$output = '';
1736
+		$cmdstr = substr($in, $from, $to - $from);
1737
+		preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*' . $this->rdr . '|\s*;)?/i', $cmdstr, $match);
1738
+
1739
+		if (empty($match[1])) {
1740
+			throw new CompilationException($this, 'Parse error, invalid function name : ' . substr($cmdstr, 0, 15));
1741
+		}
1742
+
1743
+		$func = $match[1];
1744
+
1745
+		if (!empty($match[2])) {
1746
+			$cmdstr = $match[1];
1747
+		}
1748
+
1749
+		if ($this->debug) {
1750
+			echo 'FUNC FOUND (' . $func . ')' . "\n";
1751
+		}
1752
+
1753
+		$paramsep = '';
1754
+
1755
+		if (is_array($parsingParams) || $curBlock != 'root') {
1756
+			$paramspos = strpos($cmdstr, '(');
1757
+			$paramsep  = ')';
1758
+		} elseif (preg_match_all('#^\s*[\\\\:a-z0-9_]+(\s*\(|\s+[^(])#i', $cmdstr, $match, PREG_OFFSET_CAPTURE)) {
1759
+			$paramspos = $match[1][0][1];
1760
+			$paramsep  = substr($match[1][0][0], - 1) === '(' ? ')' : '';
1761
+			if ($paramsep === ')') {
1762
+				$paramspos += strlen($match[1][0][0]) - 1;
1763
+				if (substr($cmdstr, 0, 2) === 'if' || substr($cmdstr, 0, 6) === 'elseif') {
1764
+					$paramsep = '';
1765
+					if (strlen($match[1][0][0]) > 1) {
1766
+						-- $paramspos;
1767
+					}
1768
+				}
1769
+			}
1770
+		} else {
1771
+			$paramspos = false;
1772
+		}
1773
+
1774
+		$state = 0;
1775
+
1776
+		if ($paramspos === false) {
1777
+			$params = array();
1778
+
1779
+			if ($curBlock !== 'root') {
1780
+				return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1781
+			}
1782
+		} else {
1783
+			if ($curBlock === 'condition') {
1784
+				// load if plugin
1785
+				$this->getPluginType('if');
1786
+
1787
+				if (PluginIf::replaceKeywords(array($func), array(self::T_UNQUOTED_STRING), $this) !== array($func)) {
1788
+					return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1789
+				}
1790
+			}
1791
+			$whitespace = strlen(substr($cmdstr, strlen($func), $paramspos - strlen($func)));
1792
+			$paramstr   = substr($cmdstr, $paramspos + 1);
1793
+			if (substr($paramstr, - 1, 1) === $paramsep) {
1794
+				$paramstr = substr($paramstr, 0, - 1);
1795
+			}
1796
+
1797
+			if (strlen($paramstr) === 0) {
1798
+				$params   = array();
1799
+				$paramstr = '';
1800
+			} else {
1801
+				$ptr    = 0;
1802
+				$params = array();
1803
+				if ($func === 'empty') {
1804
+					$params = $this->parseVar($paramstr, $ptr, strlen($paramstr), $params, 'root', $ptr);
1805
+				} else {
1806
+					while ($ptr < strlen($paramstr)) {
1807
+						while (true) {
1808
+							if ($ptr >= strlen($paramstr)) {
1809
+								break 2;
1810
+							}
1811
+
1812
+							if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') {
1813
+								if ($this->debug) {
1814
+									echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT ' . $ptr . "\n";
1815
+								}
1816
+								break 2;
1817
+							} elseif ($paramstr[$ptr] === ';') {
1818
+								++ $ptr;
1819
+								if ($this->debug) {
1820
+									echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT ' . $ptr . "\n";
1821
+								}
1822
+								break 2;
1823
+							} elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') {
1824
+								if ($this->debug) {
1825
+									echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT ' . $ptr . "\n";
1826
+								}
1827
+								break 2;
1828
+							} elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
1829
+								if ($this->debug) {
1830
+									echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT ' . $ptr . "\n";
1831
+								}
1832
+								break 2;
1833
+							}
1834
+
1835
+							if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") {
1836
+								++ $ptr;
1837
+							} else {
1838
+								break;
1839
+							}
1840
+						}
1841
+
1842
+						if ($this->debug) {
1843
+							echo 'FUNC START PARAM PARSING WITH POINTER AT ' . $ptr . "\n";
1844
+						}
1845
+
1846
+						if ($func === 'if' || $func === 'elseif' || $func === 'tif') {
1847
+							$params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'condition', $ptr);
1848
+						} elseif ($func === 'array') {
1849
+							$params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'array', $ptr);
1850
+						} else {
1851
+							$params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'function', $ptr);
1852
+						}
1853
+
1854
+						if ($this->debug) {
1855
+							echo 'PARAM PARSED, POINTER AT ' . $ptr . ' (' . substr($paramstr, $ptr - 1, 3) . ')' . "\n";
1856
+						}
1857
+					}
1858
+				}
1859
+				$paramstr = substr($paramstr, 0, $ptr);
1860
+				$state    = 0;
1861
+				foreach ($params as $k => $p) {
1862
+					if (is_array($p) && is_array($p[1])) {
1863
+						$state |= 2;
1864
+					} else {
1865
+						if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m) && $func !== 'array') {
1866
+							$params[$k] = array($m[2], array('true', 'true'));
1867
+						} else {
1868
+							if ($state & 2 && $func !== 'array') {
1869
+								throw new CompilationException($this, 'You can not use an unnamed parameter after a named one');
1870
+							}
1871
+							$state |= 1;
1872
+						}
1873
+					}
1874
+				}
1875
+			}
1876
+		}
1877
+
1878
+		if ($pointer !== null) {
1879
+			$pointer += (isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func) + (isset($whitespace) ? $whitespace : 0);
1880
+			if ($this->debug) {
1881
+				echo 'FUNC ADDS ' . ((isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func)) . ' TO POINTER' . "\n";
1882
+			}
1883
+		}
1884
+
1885
+		if ($curBlock === 'method' || $func === 'do' || strstr($func, '::') !== false) {
1886
+			// handle static method calls with security policy
1887
+			if (strstr($func, '::') !== false && $this->securityPolicy !== null && $this->securityPolicy->isMethodAllowed(explode('::', strtolower($func))) !== true) {
1888
+				throw new SecurityException('Call to a disallowed php function : ' . $func);
1889
+			}
1890
+			$pluginType = Core::NATIVE_PLUGIN;
1891
+		} else {
1892
+			$pluginType = $this->getPluginType($func);
1893
+		}
1894
+
1895
+		// Blocks plugin
1896
+		if ($pluginType & Core::BLOCK_PLUGIN) {
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
+			if ($pluginType & Core::CUSTOM_PLUGIN) {
1901
+				return $this->addCustomBlock($func, $params, $state);
1902
+			} else {
1903
+				return $this->addBlock($func, $params, $state);
1904
+			}
1905
+		} elseif ($pluginType & Core::SMARTY_BLOCK) {
1906
+			if ($curBlock !== 'root' || is_array($parsingParams)) {
1907
+				throw new CompilationException($this, 'Block plugins can not be used as other plugin\'s arguments');
1908
+			}
1909
+
1910
+			if ($state & 2) {
1911
+				array_unshift($params, array('__functype', array($pluginType, $pluginType)));
1912
+				array_unshift($params, array('__funcname', array($func, $func)));
1913
+			} else {
1914
+				array_unshift($params, array($pluginType, $pluginType));
1915
+				array_unshift($params, array($func, $func));
1916
+			}
1917
+
1918
+			return $this->addBlock('smartyinterface', $params, $state);
1919
+		}
1920
+
1921
+		// Native & Smarty plugins
1922
+		if ($pluginType & Core::NATIVE_PLUGIN || $pluginType & Core::SMARTY_FUNCTION || $pluginType & Core::SMARTY_BLOCK) {
1923
+			$params = $this->mapParams($params, null, $state);
1924
+		} // PHP class plugin
1925
+		elseif ($pluginType & Core::CLASS_PLUGIN) {
1926
+			if ($pluginType & Core::CUSTOM_PLUGIN) {
1927
+				$params = $this->mapParams(
1928
+					$params, array(
1929
+					$this->customPlugins[$func]['class'],
1930
+					$this->customPlugins[$func]['function']
1931
+				), $state);
1932
+			} else {
1933
+				if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
1934
+					$params = $this->mapParams($params, array(
1935
+						'Plugin' . Core::toCamelCase($func),
1936
+						($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1937
+					), $state);
1938
+				} elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== false) {
1939
+					$params = $this->mapParams($params, array(
1940
+						Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func),
1941
+						($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1942
+					), $state);
1943
+				} else {
1944
+					$params = $this->mapParams($params, array(
1945
+						Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
1946
+						($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1947
+					), $state);
1948
+				}
1949
+			}
1950
+		} // PHP function plugin
1951
+		elseif ($pluginType & Core::FUNC_PLUGIN) {
1952
+			if ($pluginType & Core::CUSTOM_PLUGIN) {
1953
+				$params = $this->mapParams($params, $this->customPlugins[$func]['callback'], $state);
1954
+			} else {
1955
+				// Custom plugin
1956
+				if (function_exists('Plugin' . Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ?
1957
+						'Compile' : '')) !== false) {
1958
+					$params = $this->mapParams($params, 'Plugin' . Core::toCamelCase($func) . (($pluginType &
1959
+							Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1960
+				} // Builtin helper plugin
1961
+				elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . (
1962
+					($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) !== false) {
1963
+					$params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase
1964
+						($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1965
+				} // Builtin function plugin
1966
+				else {
1967
+					$params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase
1968
+						($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1969
+				}
1970
+			}
1971
+		} // Smarty modifier
1972
+		elseif ($pluginType & Core::SMARTY_MODIFIER) {
1973
+			$output = 'smarty_modifier_' . $func . '(' . implode(', ', $params) . ')';
1974
+		} // Proxy plugin
1975
+		elseif ($pluginType & Core::PROXY_PLUGIN) {
1976
+			$params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state);
1977
+		} // Template plugin
1978
+		elseif ($pluginType & Core::TEMPLATE_PLUGIN) {
1979
+			// transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values))
1980
+			$map = array();
1981
+			foreach ($this->templatePlugins[$func]['params'] as $param => $defValue) {
1982
+				if ($param == 'rest') {
1983
+					$param = '*';
1984
+				}
1985
+				$hasDefault = $defValue !== null;
1986
+				if ($defValue === 'null') {
1987
+					$defValue = null;
1988
+				} elseif ($defValue === 'false') {
1989
+					$defValue = false;
1990
+				} elseif ($defValue === 'true') {
1991
+					$defValue = true;
1992
+				} elseif (preg_match('#^([\'"]).*?\1$#', $defValue)) {
1993
+					$defValue = substr($defValue, 1, - 1);
1994
+				}
1995
+				$map[] = array($param, $hasDefault, $defValue);
1996
+			}
1997
+
1998
+			$params = $this->mapParams($params, null, $state, $map);
1999
+		}
2000
+
2001
+		// only keep php-syntax-safe values for non-block plugins
2002
+		$tokens = array();
2003
+		foreach ($params as $k => $p) {
2004
+			$tokens[$k] = isset($p[2]) ? $p[2] : 0;
2005
+			$params[$k] = $p[0];
2006
+		}
2007
+
2008
+		// Native plugin
2009
+		if ($pluginType & Core::NATIVE_PLUGIN) {
2010
+			if ($func === 'do') {
2011
+				$output = '';
2012
+				if (isset($params['*'])) {
2013
+					$output = implode(';', $params['*']) . ';';
2014
+				}
2015
+
2016
+				if (is_array($parsingParams) || $curBlock !== 'root') {
2017
+					throw new CompilationException($this, 'Do can not be used inside another function or block');
2018
+				}
2019
+
2020
+				return self::PHP_OPEN . $output . self::PHP_CLOSE;
2021
+			} else {
2022
+				if (isset($params['*'])) {
2023
+					$output = $func . '(' . implode(', ', $params['*']) . ')';
2024
+				} else {
2025
+					$output = $func . '()';
2026
+				}
2027
+			}
2028
+		} // Block class OR Function class
2029
+		elseif ($pluginType & Core::CLASS_PLUGIN || ($pluginType & Core::FUNC_PLUGIN && $pluginType & Core::CLASS_PLUGIN)) {
2030
+			if ($pluginType & Core::COMPILABLE_PLUGIN) {
2031
+				if ($pluginType & Core::CUSTOM_PLUGIN) {
2032
+					$callback = $this->customPlugins[$func]['callback'];
2033
+					if (!is_array($callback)) {
2034
+						if (!method_exists($callback, 'compile')) {
2035
+							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');
2036
+						}
2037
+						if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) {
2038
+							$funcCompiler = array($callback, 'compile');
2039
+						} else {
2040
+							$funcCompiler = array(new $callback(), 'compile');
2041
+						}
2042
+					} else {
2043
+						$funcCompiler = $callback;
2044
+					}
2045
+				} else {
2046
+					if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2047
+						$funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile');
2048
+					} elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== false) {
2049
+						$funcCompiler = array(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func), 'compile');
2050
+					} else {
2051
+						$funcCompiler = array(
2052
+							Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
2053
+							'compile'
2054
+						);
2055
+					}
2056
+					array_unshift($params, $this);
2057
+				}
2058
+				// @TODO: Is it a real fix ?
2059
+				if ($func === 'tif') {
2060
+					$params[] = $tokens;
2061
+				}
2062
+				$output = call_user_func_array($funcCompiler, $params);
2063
+			} else {
2064
+				$params = self::implode_r($params);
2065
+				if ($pluginType & Core::CUSTOM_PLUGIN) {
2066
+					$callback = $this->customPlugins[$func]['callback'];
2067
+					if (!is_array($callback)) {
2068
+						if (!method_exists($callback, 'process')) {
2069
+							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');
2070
+						}
2071
+						if (($ref = new ReflectionMethod($callback, 'process')) && $ref->isStatic()) {
2072
+							$output = 'call_user_func(array(\'' . $callback . '\', \'process\'), ' . $params . ')';
2073
+						} else {
2074
+							$output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback . '\'), \'process\'), ' . $params . ')';
2075
+						}
2076
+					} elseif (is_object($callback[0])) {
2077
+						$output = 'call_user_func(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), ' . $params . ')';
2078
+					} elseif (($ref = new ReflectionMethod($callback[0], $callback[1])) && $ref->isStatic()) {
2079
+						$output = 'call_user_func(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), ' . $params . ')';
2080
+					} else {
2081
+						$output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback[0] . '\'), \'' . $callback[1] . '\'), ' . $params . ')';
2082
+					}
2083
+					if (empty($params)) {
2084
+						$output = substr($output, 0, - 3) . ')';
2085
+					}
2086
+				} else {
2087
+					if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2088
+						$output = '$this->classCall(\'Plugin' . $func . '\', array(' . $params . '))';
2089
+					} elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== false) {
2090
+						$output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', 
2091 2091
                         array(' . $params . '))';
2092
-                    } else {
2093
-                        $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))';
2094
-                    }
2095
-                }
2096
-            }
2097
-        } // Function plugin only (cannot be a class)
2098
-        elseif ($pluginType & Core::FUNC_PLUGIN) {
2099
-            if ($pluginType & Core::COMPILABLE_PLUGIN) {
2100
-                if ($pluginType & Core::CUSTOM_PLUGIN) {
2101
-                    $funcCompiler = $this->customPlugins[$func]['callback'];
2102
-                } else {
2103
-                    // Custom plugin
2104
-                    if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
2105
-                        $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile';
2106
-                    } // Builtin helper plugin
2107
-                    elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
2108
-                        $funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) .
2109
-                            'Compile';
2110
-                    } // Builtin function plugin
2111
-                    else {
2112
-                        $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) .
2113
-                            'Compile';
2114
-                    }
2115
-                }
2116
-                array_unshift($params, $this);
2117
-                // @TODO: Is it a real fix ?
2118
-                if ($func === 'tif') {
2119
-                    $params[] = $tokens;
2120
-                }
2121
-                $output = call_user_func_array($funcCompiler, $params);
2122
-            } else {
2123
-                array_unshift($params, '$this');
2124
-                $params = self::implode_r($params);
2125
-                if ($pluginType & Core::CUSTOM_PLUGIN) {
2126
-                    $callback = $this->customPlugins[$func]['callback'];
2127
-                    if ($callback instanceof Closure) {
2128
-                        $output = 'call_user_func($this->getCustomPlugin(\'' . $func . '\'), ' . $params . ')';
2129
-                    } else {
2130
-                        $output = 'call_user_func(\'' . $callback . '\', ' . $params . ')';
2131
-                    }
2132
-                } else {
2133
-                    // Custom plugin
2134
-                    if (function_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2135
-                        $output = 'Plugin' . Core::toCamelCase($func) . '(' . $params .
2136
-                            ')';
2137
-                    } // Builtin helper plugin
2138
-                    elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !==
2139
-                        false) {
2140
-                        $output = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . '(' .
2141
-                            $params . ')';
2142
-                    } // Builtin function plugin
2143
-                    else {
2144
-                        $output = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '(' .
2145
-                            $params . ')';
2146
-                    }
2147
-                }
2148
-            }
2149
-        } // Proxy plugin
2150
-        elseif ($pluginType & Core::PROXY_PLUGIN) {
2151
-            $output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params);
2152
-        } // Smarty function (@deprecated)
2153
-        elseif ($pluginType & Core::SMARTY_FUNCTION) {
2154
-            $params = '';
2155
-            if (isset($params['*'])) {
2156
-                $params = self::implode_r($params['*'], true);
2157
-            }
2158
-
2159
-            if ($pluginType & Core::CUSTOM_PLUGIN) {
2160
-                $callback = $this->customPlugins[$func]['callback'];
2161
-                if (is_array($callback)) {
2162
-                    if (is_object($callback[0])) {
2163
-                        $output = 'call_user_func_array(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
2164
-                    } else {
2165
-                        $output = 'call_user_func_array(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
2166
-                    }
2167
-                } else {
2168
-                    $output = $callback . '(array(' . $params . '), $this)';
2169
-                }
2170
-            } else {
2171
-                $output = 'smarty_function_' . $func . '(array(' . $params . '), $this)';
2172
-            }
2173
-        } // Template plugin
2174
-        elseif ($pluginType & Core::TEMPLATE_PLUGIN) {
2175
-            array_unshift($params, '$this');
2176
-            $params                                 = self::implode_r($params);
2177
-            $output                                 = 'Plugin' . Core::toCamelCase($func) .
2178
-                $this->templatePlugins[$func]['uuid'] . '(' . $params . ')';
2179
-            $this->templatePlugins[$func]['called'] = true;
2180
-        }
2181
-
2182
-        if (is_array($parsingParams)) {
2183
-            $parsingParams[] = array($output, $output);
2184
-
2185
-            return $parsingParams;
2186
-        } elseif ($curBlock === 'namedparam') {
2187
-            return array($output, $output);
2188
-        }
2189
-
2190
-        return $output;
2191
-    }
2192
-
2193
-    /**
2194
-     * Parses a string.
2195
-     *
2196
-     * @param string $in            the string within which we must parse something
2197
-     * @param int    $from          the starting offset of the parsed area
2198
-     * @param int    $to            the ending offset of the parsed area
2199
-     * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2200
-     *                              default
2201
-     * @param string $curBlock      the current parser-block being processed
2202
-     * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2203
-     *                              or null by default
2204
-     *
2205
-     * @return string parsed values
2206
-     * @throws CompilationException
2207
-     */
2208
-    protected function parseString($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2209
-    {
2210
-        $substr = substr($in, $from, $to - $from);
2211
-        $first  = $substr[0];
2212
-
2213
-        if ($this->debug) {
2214
-            echo 'STRING FOUND (in ' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . ')' . "\n";
2215
-        }
2216
-        $strend = false;
2217
-        $o      = $from + 1;
2218
-        while ($strend === false) {
2219
-            $strend = strpos($in, $first, $o);
2220
-            if ($strend === false) {
2221
-                throw new CompilationException($this, 'Unfinished string, started with ' . substr($in, $from, $to - $from));
2222
-            }
2223
-            if (substr($in, $strend - 1, 1) === '\\') {
2224
-                $o      = $strend + 1;
2225
-                $strend = false;
2226
-            }
2227
-        }
2228
-        if ($this->debug) {
2229
-            echo 'STRING DELIMITED: ' . substr($in, $from, $strend + 1 - $from) . "\n";
2230
-        }
2231
-
2232
-        $srcOutput = substr($in, $from, $strend + 1 - $from);
2233
-
2234
-        if ($pointer !== null) {
2235
-            $pointer += strlen($srcOutput);
2236
-        }
2237
-
2238
-        $output = $this->replaceStringVars($srcOutput, $first);
2239
-
2240
-        // handle modifiers
2241
-        if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend + 1 - $from), $match)) {
2242
-            $modstr = $match[1];
2243
-
2244
-            if ($curBlock === 'root' && substr($modstr, - 1) === '}') {
2245
-                $modstr = substr($modstr, 0, - 1);
2246
-            }
2247
-            $modstr = str_replace('\\' . $first, $first, $modstr);
2248
-            $ptr    = 0;
2249
-            $output = $this->replaceModifiers(array(null, null, $output, $modstr), 'string', $ptr);
2250
-
2251
-            $strend += $ptr;
2252
-            if ($pointer !== null) {
2253
-                $pointer += $ptr;
2254
-            }
2255
-            $srcOutput .= substr($substr, $strend + 1 - $from, $ptr);
2256
-        }
2257
-
2258
-        if (is_array($parsingParams)) {
2259
-            $parsingParams[] = array($output, substr($srcOutput, 1, - 1));
2260
-
2261
-            return $parsingParams;
2262
-        } elseif ($curBlock === 'namedparam') {
2263
-            return array($output, substr($srcOutput, 1, - 1));
2264
-        } else {
2265
-            return $output;
2266
-        }
2267
-    }
2268
-
2269
-    /**
2270
-     * Parses a constant.
2271
-     *
2272
-     * @param string $in            the string within which we must parse something
2273
-     * @param int    $from          the starting offset of the parsed area
2274
-     * @param int    $to            the ending offset of the parsed area
2275
-     * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2276
-     *                              default
2277
-     * @param string $curBlock      the current parser-block being processed
2278
-     * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2279
-     *                              or null by default
2280
-     *
2281
-     * @return string parsed values
2282
-     * @throws CompilationException
2283
-     */
2284
-    protected function parseConst($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2285
-    {
2286
-        $substr = substr($in, $from, $to - $from);
2287
-
2288
-        if ($this->debug) {
2289
-            echo 'CONST FOUND : ' . $substr . "\n";
2290
-        }
2291
-
2292
-        if (!preg_match('#^%([\\\\a-z0-9_:]+)#i', $substr, $m)) {
2293
-            throw new CompilationException($this, 'Invalid constant');
2294
-        }
2295
-
2296
-        if ($pointer !== null) {
2297
-            $pointer += strlen($m[0]);
2298
-        }
2299
-
2300
-        $output = $this->parseConstKey($m[1], $curBlock);
2301
-
2302
-        if (is_array($parsingParams)) {
2303
-            $parsingParams[] = array($output, $m[1]);
2304
-
2305
-            return $parsingParams;
2306
-        } elseif ($curBlock === 'namedparam') {
2307
-            return array($output, $m[1]);
2308
-        } else {
2309
-            return $output;
2310
-        }
2311
-    }
2312
-
2313
-    /**
2314
-     * Parses a constant.
2315
-     *
2316
-     * @param string $key      the constant to parse
2317
-     * @param string $curBlock the current parser-block being processed
2318
-     *
2319
-     * @return string parsed constant
2320
-     */
2321
-    protected function parseConstKey($key, $curBlock)
2322
-    {
2323
-        if ($this->securityPolicy !== null && $this->securityPolicy->getConstantHandling() === SecurityPolicy::CONST_DISALLOW) {
2324
-            return 'null';
2325
-        }
2326
-
2327
-        if ($curBlock !== 'root') {
2328
-            $output = '(defined("' . $key . '") ? ' . $key . ' : null)';
2329
-        } else {
2330
-            $output = $key;
2331
-        }
2332
-
2333
-        return $output;
2334
-    }
2335
-
2336
-    /**
2337
-     * Parses a variable.
2338
-     *
2339
-     * @param string $in            the string within which we must parse something
2340
-     * @param int    $from          the starting offset of the parsed area
2341
-     * @param int    $to            the ending offset of the parsed area
2342
-     * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2343
-     *                              default
2344
-     * @param string $curBlock      the current parser-block being processed
2345
-     * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2346
-     *                              or null by default
2347
-     *
2348
-     * @return string parsed values
2349
-     * @throws CompilationException
2350
-     */
2351
-    protected function parseVar($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2352
-    {
2353
-        $substr = substr($in, $from, $to - $from);
2354
-
2355
-        // var key
2356
-        $varRegex = '(\\$?\\.?[a-z0-9\\\\_:]*(?:(?:(?:\\.|->)(?:[a-z0-9\\\\_:]+|(?R))|\\[(?:[a-z0-9\\\\_:]+|(?R)|(["\'])[^\\2]*?\\2)\\]))*)';
2357
-        // method call
2358
-        $methodCall = ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'expression' || $curBlock === 'delimited_string' ? '(\(.*)?' : '()');
2359
-        // simple math expressions
2360
-        $simpleMathExpressions = ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'delimited_string' ? '((?:(?:[+\/*%=-])(?:(?<!=)=?-?[$%][a-z0-9\\\\.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9\.,]*|[+-]))*)' : '()');
2361
-        // modifiers
2362
-        $modifiers = $curBlock !== 'modifier' ? '((?:\|(?:@?[a-z0-9\\\\_]+(?:(?::("|\').*?\5|:[^`]*))*))+)?' : '(())';
2363
-
2364
-        $regex = '#';
2365
-        $regex .= $varRegex;
2366
-        $regex .= $methodCall;
2367
-        $regex .= $simpleMathExpressions;
2368
-        $regex .= $modifiers;
2369
-        $regex .= '#i';
2370
-
2371
-        if (preg_match($regex, $substr, $match)) {
2372
-            $key = substr($match[1], 1);
2373
-
2374
-            $matchedLength = strlen($match[0]);
2375
-            $hasModifiers  = !empty($match[5]);
2376
-            $hasExpression = !empty($match[4]);
2377
-            $hasMethodCall = !empty($match[3]);
2378
-
2379
-            if (substr($key, - 1) == '.') {
2380
-                $key = substr($key, 0, - 1);
2381
-                -- $matchedLength;
2382
-            }
2383
-
2384
-            if ($hasMethodCall) {
2385
-                $matchedLength -= strlen($match[3]) + strlen(substr($match[1], strrpos($match[1], '->')));
2386
-                $key        = substr($match[1], 1, strrpos($match[1], '->') - 1);
2387
-                $methodCall = substr($match[1], strrpos($match[1], '->')) . $match[3];
2388
-            }
2389
-
2390
-            if ($hasModifiers) {
2391
-                $matchedLength -= strlen($match[5]);
2392
-            }
2393
-
2394
-            if ($pointer !== null) {
2395
-                $pointer += $matchedLength;
2396
-            }
2397
-
2398
-            // replace useless brackets by dot accessed vars and strip enclosing quotes if present
2399
-            $key = preg_replace('#\[(["\']?)([^$%\[.>-]+)\1\]#', '.$2', $key);
2400
-
2401
-            if ($this->debug) {
2402
-                if ($hasMethodCall) {
2403
-                    echo 'METHOD CALL FOUND : $' . $key . substr($methodCall, 0, 30) . "\n";
2404
-                } else {
2405
-                    echo 'VAR FOUND : $' . $key . "\n";
2406
-                }
2407
-            }
2408
-
2409
-            $key = str_replace('"', '\\"', $key);
2410
-
2411
-            $cnt = substr_count($key, '$');
2412
-            if ($cnt > 0) {
2413
-                $uid           = 0;
2414
-                $parsed        = array($uid => '');
2415
-                $current       = &$parsed;
2416
-                $curTxt        = &$parsed[$uid ++];
2417
-                $tree          = array();
2418
-                $chars         = str_split($key, 1);
2419
-                $inSplittedVar = false;
2420
-                $bracketCount  = 0;
2421
-
2422
-                while (($char = array_shift($chars)) !== null) {
2423
-                    if ($char === '[') {
2424
-                        if (count($tree) > 0) {
2425
-                            ++ $bracketCount;
2426
-                        } else {
2427
-                            $tree[]        = &$current;
2428
-                            $current[$uid] = array($uid + 1 => '');
2429
-                            $current       = &$current[$uid ++];
2430
-                            $curTxt        = &$current[$uid ++];
2431
-                            continue;
2432
-                        }
2433
-                    } elseif ($char === ']') {
2434
-                        if ($bracketCount > 0) {
2435
-                            -- $bracketCount;
2436
-                        } else {
2437
-                            $current = &$tree[count($tree) - 1];
2438
-                            array_pop($tree);
2439
-                            if (current($chars) !== '[' && current($chars) !== false && current($chars) !== ']') {
2440
-                                $current[$uid] = '';
2441
-                                $curTxt        = &$current[$uid ++];
2442
-                            }
2443
-                            continue;
2444
-                        }
2445
-                    } elseif ($char === '$') {
2446
-                        if (count($tree) == 0) {
2447
-                            $curTxt        = &$current[$uid ++];
2448
-                            $inSplittedVar = true;
2449
-                        }
2450
-                    } elseif (($char === '.' || $char === '-') && count($tree) == 0 && $inSplittedVar) {
2451
-                        $curTxt        = &$current[$uid ++];
2452
-                        $inSplittedVar = false;
2453
-                    }
2454
-
2455
-                    $curTxt .= $char;
2456
-                }
2457
-                unset($uid, $current, $curTxt, $tree, $chars);
2458
-
2459
-                if ($this->debug) {
2460
-                    echo 'RECURSIVE VAR REPLACEMENT : ' . $key . "\n";
2461
-                }
2462
-
2463
-                $key = $this->flattenVarTree($parsed);
2464
-
2465
-                if ($this->debug) {
2466
-                    echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n";
2467
-                }
2468
-
2469
-                $output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("' . $key . '")');
2470
-            } else {
2471
-                $output = $this->parseVarKey($key, $hasModifiers ? 'modifier' : $curBlock);
2472
-            }
2473
-
2474
-
2475
-            // methods
2476
-            if ($hasMethodCall) {
2477
-                $ptr = 0;
2478
-
2479
-                $output = $this->parseMethodCall($output, $methodCall, $curBlock, $ptr);
2480
-
2481
-                if ($pointer !== null) {
2482
-                    $pointer += $ptr;
2483
-                }
2484
-                $matchedLength += $ptr;
2485
-            }
2486
-
2487
-            if ($hasExpression) {
2488
-                // expressions
2489
-                preg_match_all('#(?:([+/*%=-])(=?-?[%$][a-z0-9\\\\.[\]>_:-]+(?:\([^)]*\))?|=?-?[0-9.,]+|\1))#i', $match[4], $expMatch);
2490
-                foreach ($expMatch[1] as $k => $operator) {
2491
-                    if (substr($expMatch[2][$k], 0, 1) === '=') {
2492
-                        $assign = true;
2493
-                        if ($operator === '=') {
2494
-                            throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, can not use "==" in expressions');
2495
-                        }
2496
-                        if ($curBlock !== 'root') {
2497
-                            throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}');
2498
-                        }
2499
-                        $operator .= '=';
2500
-                        $expMatch[2][$k] = substr($expMatch[2][$k], 1);
2501
-                    }
2502
-
2503
-                    if (substr($expMatch[2][$k], 0, 1) === '-' && strlen($expMatch[2][$k]) > 1) {
2504
-                        $operator .= '-';
2505
-                        $expMatch[2][$k] = substr($expMatch[2][$k], 1);
2506
-                    }
2507
-                    if (($operator === '+' || $operator === '-') && $expMatch[2][$k] === $operator) {
2508
-                        $output = '(' . $output . $operator . $operator . ')';
2509
-                        break;
2510
-                    } elseif (substr($expMatch[2][$k], 0, 1) === '$') {
2511
-                        $output = '(' . $output . ' ' . $operator . ' ' . $this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')';
2512
-                    } elseif (substr($expMatch[2][$k], 0, 1) === '%') {
2513
-                        $output = '(' . $output . ' ' . $operator . ' ' . $this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')';
2514
-                    } elseif (!empty($expMatch[2][$k])) {
2515
-                        $output = '(' . $output . ' ' . $operator . ' ' . str_replace(',', '.', $expMatch[2][$k]) . ')';
2516
-                    } else {
2517
-                        throw new CompilationException($this, 'Unfinished expression <em>' . $substr . '</em>, missing var or number after math operator');
2518
-                    }
2519
-                }
2520
-            }
2521
-
2522
-            if ($this->autoEscape === true && $curBlock !== 'condition') {
2523
-                $output = '(is_string($tmp=' . $output . ') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)';
2524
-            }
2525
-
2526
-            // handle modifiers
2527
-            if ($curBlock !== 'modifier' && $hasModifiers) {
2528
-                $ptr    = 0;
2529
-                $output = $this->replaceModifiers(array(null, null, $output, $match[5]), 'var', $ptr);
2530
-                if ($pointer !== null) {
2531
-                    $pointer += $ptr;
2532
-                }
2533
-                $matchedLength += $ptr;
2534
-            }
2535
-
2536
-            if (is_array($parsingParams)) {
2537
-                $parsingParams[] = array($output, $key);
2538
-
2539
-                return $parsingParams;
2540
-            } elseif ($curBlock === 'namedparam') {
2541
-                return array($output, $key);
2542
-            } elseif ($curBlock === 'string' || $curBlock === 'delimited_string') {
2543
-                return array($matchedLength, $output);
2544
-            } elseif ($curBlock === 'expression' || $curBlock === 'variable') {
2545
-                return $output;
2546
-            } elseif (isset($assign)) {
2547
-                return self::PHP_OPEN . $output . ';' . self::PHP_CLOSE;
2548
-            } else {
2549
-                return $output;
2550
-            }
2551
-        } else {
2552
-            if ($curBlock === 'string' || $curBlock === 'delimited_string') {
2553
-                return array(0, '');
2554
-            } else {
2555
-                throw new CompilationException($this, 'Invalid variable name <em>' . $substr . '</em>');
2556
-            }
2557
-        }
2558
-    }
2559
-
2560
-    /**
2561
-     * Parses any number of chained method calls/property reads.
2562
-     *
2563
-     * @param string $output     the variable or whatever upon which the method are called
2564
-     * @param string $methodCall method call source, starting at "->"
2565
-     * @param string $curBlock   the current parser-block being processed
2566
-     * @param int    $pointer    a reference to a pointer that will be increased by the amount of characters parsed
2567
-     *
2568
-     * @return string parsed call(s)/read(s)
2569
-     */
2570
-    protected function parseMethodCall($output, $methodCall, $curBlock, &$pointer)
2571
-    {
2572
-        $ptr = 0;
2573
-        $len = strlen($methodCall);
2574
-
2575
-        while ($ptr < $len) {
2576
-            if (strpos($methodCall, '->', $ptr) === $ptr) {
2577
-                $ptr += 2;
2578
-            }
2579
-
2580
-            if (in_array(
2581
-                $methodCall[$ptr], array(
2582
-                    ';',
2583
-                    ',',
2584
-                    '/',
2585
-                    ' ',
2586
-                    "\t",
2587
-                    "\r",
2588
-                    "\n",
2589
-                    ')',
2590
-                    '+',
2591
-                    '*',
2592
-                    '%',
2593
-                    '=',
2594
-                    '-',
2595
-                    '|'
2596
-                )
2597
-            ) || substr($methodCall, $ptr, strlen($this->rd)) === $this->rd
2598
-            ) {
2599
-                // break char found
2600
-                break;
2601
-            }
2602
-
2603
-            if (!preg_match('/^([a-z0-9_]+)(\(.*?\))?/i', substr($methodCall, $ptr), $methMatch)) {
2604
-                break;
2605
-            }
2606
-
2607
-            if (empty($methMatch[2])) {
2608
-                // property
2609
-                if ($curBlock === 'root') {
2610
-                    $output .= '->' . $methMatch[1];
2611
-                } else {
2612
-                    $output = '(($tmp = ' . $output . ') ? $tmp->' . $methMatch[1] . ' : null)';
2613
-                }
2614
-                $ptr += strlen($methMatch[1]);
2615
-            } else {
2616
-                // method
2617
-                if (substr($methMatch[2], 0, 2) === '()') {
2618
-                    $parsedCall = $methMatch[1] . '()';
2619
-                    $ptr += strlen($methMatch[1]) + 2;
2620
-                } else {
2621
-                    $parsedCall = $this->parseFunction($methodCall, $ptr, strlen($methodCall), false, 'method', $ptr);
2622
-                }
2623
-                if ($this->securityPolicy !== null) {
2624
-                    $argPos = strpos($parsedCall, '(');
2625
-                    $method = strtolower(substr($parsedCall, 0, $argPos));
2626
-                    $args   = substr($parsedCall, $argPos);
2627
-                    if ($curBlock === 'root') {
2628
-                        $output = '$this->getSecurityPolicy()->callMethod($this, ' . $output . ', ' . var_export($method, true) . ', array' . $args . ')';
2629
-                    } else {
2630
-                        $output = '(($tmp = ' . $output . ') ? $this->getSecurityPolicy()->callMethod($this, $tmp, ' . var_export($method, true) . ', array' . $args . ') : null)';
2631
-                    }
2632
-                } else {
2633
-                    if ($curBlock === 'root') {
2634
-                        $output .= '->' . $parsedCall;
2635
-                    } else {
2636
-                        $output = '(($tmp = ' . $output . ') ? $tmp->' . $parsedCall . ' : null)';
2637
-                    }
2638
-                }
2639
-            }
2640
-        }
2641
-
2642
-        $pointer += $ptr;
2643
-
2644
-        return $output;
2645
-    }
2646
-
2647
-    /**
2648
-     * Parses a constant variable (a variable that doesn't contain another variable) and preprocesses it to save
2649
-     * runtime processing time.
2650
-     *
2651
-     * @param string $key      the variable to parse
2652
-     * @param string $curBlock the current parser-block being processed
2653
-     *
2654
-     * @return string parsed variable
2655
-     */
2656
-    protected function parseVarKey($key, $curBlock)
2657
-    {
2658
-        if ($key === '') {
2659
-            return '$this->scope';
2660
-        }
2661
-        if (substr($key, 0, 1) === '.') {
2662
-            $key = 'dwoo' . $key;
2663
-        }
2664
-        if (preg_match('#dwoo\.(get|post|server|cookies|session|env|request)((?:\.[a-z0-9_-]+)+)#i', $key, $m)) {
2665
-            $global = strtoupper($m[1]);
2666
-            if ($global === 'COOKIES') {
2667
-                $global = 'COOKIE';
2668
-            }
2669
-            $key = '$_' . $global;
2670
-            foreach (explode('.', ltrim($m[2], '.')) as $part) {
2671
-                $key .= '[' . var_export($part, true) . ']';
2672
-            }
2673
-            if ($curBlock === 'root') {
2674
-                $output = $key;
2675
-            } else {
2676
-                $output = '(isset(' . $key . ')?' . $key . ':null)';
2677
-            }
2678
-        } elseif (preg_match('#dwoo\\.const\\.([a-z0-9\\\\_:]+)#i', $key, $m)) {
2679
-            return $this->parseConstKey($m[1], $curBlock);
2680
-        } elseif ($this->scope !== null) {
2681
-            if (strstr($key, '.') === false && strstr($key, '[') === false && strstr($key, '->') === false) {
2682
-                if ($key === 'dwoo') {
2683
-                    $output = '$this->globals';
2684
-                } elseif ($key === '_root' || $key === '__') {
2685
-                    $output = '$this->data';
2686
-                } elseif ($key === '_parent' || $key === '_') {
2687
-                    $output = '$this->readParentVar(1)';
2688
-                } elseif ($key === '_key') {
2689
-                    $output = '$tmp_key';
2690
-                } else {
2691
-                    if ($curBlock === 'root') {
2692
-                        $output = '$this->scope["' . $key . '"]';
2693
-                    } else {
2694
-                        $output = '(isset($this->scope["' . $key . '"]) ? $this->scope["' . $key . '"] : null)';
2695
-                    }
2696
-                }
2697
-            } else {
2698
-                preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+|(\\\?[\'"])[^\3]*?\3)\]?#i', $key, $m);
2699
-
2700
-                $i = $m[2][0];
2701
-                if ($i === '_parent' || $i === '_') {
2702
-                    $parentCnt = 0;
2703
-
2704
-                    while (true) {
2705
-                        ++ $parentCnt;
2706
-                        array_shift($m[2]);
2707
-                        array_shift($m[1]);
2708
-                        if (current($m[2]) === '_parent') {
2709
-                            continue;
2710
-                        }
2711
-                        break;
2712
-                    }
2713
-
2714
-                    $output = '$this->readParentVar(' . $parentCnt . ')';
2715
-                } else {
2716
-                    if ($i === 'dwoo') {
2717
-                        $output = '$this->globals';
2718
-                        array_shift($m[2]);
2719
-                        array_shift($m[1]);
2720
-                    } elseif ($i === '_root' || $i === '__') {
2721
-                        $output = '$this->data';
2722
-                        array_shift($m[2]);
2723
-                        array_shift($m[1]);
2724
-                    } elseif ($i === '_key') {
2725
-                        $output = '$tmp_key';
2726
-                    } else {
2727
-                        $output = '$this->scope';
2728
-                    }
2729
-
2730
-                    while (count($m[1]) && $m[1][0] !== '->') {
2731
-                        $m[2][0] = preg_replace('/(^\\\([\'"])|\\\([\'"])$)/x', '$2$3', $m[2][0]);
2732
-                        if (substr($m[2][0], 0, 1) == '"' || substr($m[2][0], 0, 1) == "'") {
2733
-                            $output .= '[' . $m[2][0] . ']';
2734
-                        } else {
2735
-                            $output .= '["' . $m[2][0] . '"]';
2736
-                        }
2737
-                        array_shift($m[2]);
2738
-                        array_shift($m[1]);
2739
-                    }
2740
-
2741
-                    if ($curBlock !== 'root') {
2742
-                        $output = '(isset(' . $output . ') ? ' . $output . ':null)';
2743
-                    }
2744
-                }
2745
-
2746
-                if (count($m[2])) {
2747
-                    unset($m[0]);
2748
-                    $output = '$this->readVarInto(' . str_replace("\n", '', var_export($m, true)) . ', ' . $output . ', ' . ($curBlock == 'root' ? 'false' : 'true') . ')';
2749
-                }
2750
-            }
2751
-        } else {
2752
-            preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+)\]?#i', $key, $m);
2753
-            unset($m[0]);
2754
-            $output = '$this->readVar(' . str_replace("\n", '', var_export($m, true)) . ')';
2755
-        }
2756
-
2757
-        return $output;
2758
-    }
2759
-
2760
-    /**
2761
-     * Flattens a variable tree, this helps in parsing very complex variables such as $var.foo[$foo.bar->baz].baz,
2762
-     * it computes the contents of the brackets first and works out from there.
2763
-     *
2764
-     * @param array $tree     the variable tree parsed by he parseVar() method that must be flattened
2765
-     * @param bool  $recursed leave that to false by default, it is only for internal use
2766
-     *
2767
-     * @return string flattened tree
2768
-     */
2769
-    protected function flattenVarTree(array $tree, $recursed = false)
2770
-    {
2771
-        $out = $recursed ? '".$this->readVarInto(' : '';
2772
-        foreach ($tree as $bit) {
2773
-            if (is_array($bit)) {
2774
-                $out .= '.' . $this->flattenVarTree($bit, false);
2775
-            } else {
2776
-                $key = str_replace('"', '\\"', $bit);
2777
-
2778
-                if (substr($key, 0, 1) === '$') {
2779
-                    $out .= '".' . $this->parseVar($key, 0, strlen($key), false, 'variable') . '."';
2780
-                } else {
2781
-                    $cnt = substr_count($key, '$');
2782
-
2783
-                    if ($this->debug) {
2784
-                        echo 'PARSING SUBVARS IN : ' . $key . "\n";
2785
-                    }
2786
-                    if ($cnt > 0) {
2787
-                        while (-- $cnt >= 0) {
2788
-                            if (isset($last)) {
2789
-                                $last = strrpos($key, '$', - (strlen($key) - $last + 1));
2790
-                            } else {
2791
-                                $last = strrpos($key, '$');
2792
-                            }
2793
-                            preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch);
2794
-
2795
-                            $len = strlen($submatch[0]);
2796
-                            $key = substr_replace(
2797
-                                $key, preg_replace_callback(
2798
-                                    '#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array(
2799
-                                        $this,
2800
-                                        'replaceVarKeyHelper'
2801
-                                    ), substr($key, $last, $len)
2802
-                                ), $last, $len
2803
-                            );
2804
-                            if ($this->debug) {
2805
-                                echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n";
2806
-                            }
2807
-                        }
2808
-                        unset($last);
2809
-
2810
-                        $out .= $key;
2811
-                    } else {
2812
-                        $out .= $key;
2813
-                    }
2814
-                }
2815
-            }
2816
-        }
2817
-        $out .= $recursed ? ', true)."' : '';
2818
-
2819
-        return $out;
2820
-    }
2821
-
2822
-    /**
2823
-     * Helper function that parses a variable.
2824
-     *
2825
-     * @param array $match the matched variable, array(1=>"string match")
2826
-     *
2827
-     * @return string parsed variable
2828
-     */
2829
-    protected function replaceVarKeyHelper($match)
2830
-    {
2831
-        return '".' . $this->parseVar($match[0], 0, strlen($match[0]), false, 'variable') . '."';
2832
-    }
2833
-
2834
-    /**
2835
-     * Parses various constants, operators or non-quoted strings.
2836
-     *
2837
-     * @param string $in            the string within which we must parse something
2838
-     * @param int    $from          the starting offset of the parsed area
2839
-     * @param int    $to            the ending offset of the parsed area
2840
-     * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2841
-     *                              default
2842
-     * @param string $curBlock      the current parser-block being processed
2843
-     * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2844
-     *                              or null by default
2845
-     *
2846
-     * @return string parsed values
2847
-     * @throws Exception
2848
-     */
2849
-    protected function parseOthers($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2850
-    {
2851
-        $substr = substr($in, $from, $to - $from);
2852
-
2853
-        $end = strlen($substr);
2854
-
2855
-        if ($curBlock === 'condition') {
2856
-            $breakChars = array(
2857
-                '(',
2858
-                ')',
2859
-                ' ',
2860
-                '||',
2861
-                '&&',
2862
-                '|',
2863
-                '&',
2864
-                '>=',
2865
-                '<=',
2866
-                '===',
2867
-                '==',
2868
-                '=',
2869
-                '!==',
2870
-                '!=',
2871
-                '<<',
2872
-                '<',
2873
-                '>>',
2874
-                '>',
2875
-                '^',
2876
-                '~',
2877
-                ',',
2878
-                '+',
2879
-                '-',
2880
-                '*',
2881
-                '/',
2882
-                '%',
2883
-                '!',
2884
-                '?',
2885
-                ':',
2886
-                $this->rd,
2887
-                ';'
2888
-            );
2889
-        } elseif ($curBlock === 'modifier') {
2890
-            $breakChars = array(' ', ',', ')', ':', '|', "\r", "\n", "\t", ';', $this->rd);
2891
-        } elseif ($curBlock === 'expression') {
2892
-            $breakChars = array('/', '%', '+', '-', '*', ' ', ',', ')', "\r", "\n", "\t", ';', $this->rd);
2893
-        } else {
2894
-            $breakChars = array(' ', ',', ')', "\r", "\n", "\t", ';', $this->rd);
2895
-        }
2896
-
2897
-        $breaker = false;
2898
-        while (list($k, $char) = each($breakChars)) {
2899
-            $test = strpos($substr, $char);
2900
-            if ($test !== false && $test < $end) {
2901
-                $end     = $test;
2902
-                $breaker = $k;
2903
-            }
2904
-        }
2905
-
2906
-        if ($curBlock === 'condition') {
2907
-            if ($end === 0 && $breaker !== false) {
2908
-                $end = strlen($breakChars[$breaker]);
2909
-            }
2910
-        }
2911
-
2912
-        if ($end !== false) {
2913
-            $substr = substr($substr, 0, $end);
2914
-        }
2915
-
2916
-        if ($pointer !== null) {
2917
-            $pointer += strlen($substr);
2918
-        }
2919
-
2920
-        $src    = $substr;
2921
-        $substr = trim($substr);
2922
-
2923
-        if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') {
2924
-            if ($this->debug) {
2925
-                echo 'BOOLEAN(FALSE) PARSED' . "\n";
2926
-            }
2927
-            $substr = 'false';
2928
-            $type   = self::T_BOOL;
2929
-        } elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') {
2930
-            if ($this->debug) {
2931
-                echo 'BOOLEAN(TRUE) PARSED' . "\n";
2932
-            }
2933
-            $substr = 'true';
2934
-            $type   = self::T_BOOL;
2935
-        } elseif ($substr === 'null' || $substr === 'NULL') {
2936
-            if ($this->debug) {
2937
-                echo 'NULL PARSED' . "\n";
2938
-            }
2939
-            $substr = 'null';
2940
-            $type   = self::T_NULL;
2941
-        } elseif (is_numeric($substr)) {
2942
-            $substr = (float)$substr;
2943
-            if ((int)$substr == $substr) {
2944
-                $substr = (int)$substr;
2945
-            }
2946
-            $type = self::T_NUMERIC;
2947
-            if ($this->debug) {
2948
-                echo 'NUMBER (' . $substr . ') PARSED' . "\n";
2949
-            }
2950
-        } elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) {
2951
-            if ($this->debug) {
2952
-                echo 'SIMPLE MATH PARSED . "\n"';
2953
-            }
2954
-            $type   = self::T_MATH;
2955
-            $substr = '(' . $substr . ')';
2956
-        } elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) {
2957
-            if ($this->debug) {
2958
-                echo 'BREAKCHAR (' . $substr . ') PARSED' . "\n";
2959
-            }
2960
-            $type = self::T_BREAKCHAR;
2961
-            //$substr = '"'.$substr.'"';
2962
-        } else {
2963
-            $substr = $this->replaceStringVars('\'' . str_replace('\'', '\\\'', $substr) . '\'', '\'', $curBlock);
2964
-            $type   = self::T_UNQUOTED_STRING;
2965
-            if ($this->debug) {
2966
-                echo 'BLABBER (' . $substr . ') CASTED AS STRING' . "\n";
2967
-            }
2968
-        }
2969
-
2970
-        if (is_array($parsingParams)) {
2971
-            $parsingParams[] = array($substr, $src, $type);
2972
-
2973
-            return $parsingParams;
2974
-        } elseif ($curBlock === 'namedparam') {
2975
-            return array($substr, $src, $type);
2976
-        } elseif ($curBlock === 'expression') {
2977
-            return $substr;
2978
-        } else {
2979
-            throw new Exception('Something went wrong');
2980
-        }
2981
-    }
2982
-
2983
-    /**
2984
-     * Replaces variables within a parsed string.
2985
-     *
2986
-     * @param string $string   the parsed string
2987
-     * @param string $first    the first character parsed in the string, which is the string delimiter (' or ")
2988
-     * @param string $curBlock the current parser-block being processed
2989
-     *
2990
-     * @return string the original string with variables replaced
2991
-     */
2992
-    protected function replaceStringVars($string, $first, $curBlock = '')
2993
-    {
2994
-        $pos = 0;
2995
-        if ($this->debug) {
2996
-            echo 'STRING VAR REPLACEMENT : ' . $string . "\n";
2997
-        }
2998
-        // replace vars
2999
-        while (($pos = strpos($string, '$', $pos)) !== false) {
3000
-            $prev = substr($string, $pos - 1, 1);
3001
-            if ($prev === '\\') {
3002
-                ++ $pos;
3003
-                continue;
3004
-            }
3005
-
3006
-            $var = $this->parse($string, $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string')));
3007
-            $len = $var[0];
3008
-            $var = $this->parse(str_replace('\\' . $first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string')));
3009
-
3010
-            if ($prev === '`' && substr($string, $pos + $len, 1) === '`') {
3011
-                $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos - 1, $len + 2);
3012
-            } else {
3013
-                $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos, $len);
3014
-            }
3015
-            $pos += strlen($var[1]) + 2;
3016
-            if ($this->debug) {
3017
-                echo 'STRING VAR REPLACEMENT DONE : ' . $string . "\n";
3018
-            }
3019
-        }
3020
-
3021
-        // handle modifiers
3022
-        // TODO Obsolete?
3023
-        $string = preg_replace_callback(
3024
-            '#("|\')\.(.+?)\.\1((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').+?\4|:[^`]*))*))+)#i', array(
3025
-            $this,
3026
-            'replaceModifiers'
3027
-            ), $string
3028
-        );
3029
-
3030
-        // replace escaped dollar operators by unescaped ones if required
3031
-        if ($first === "'") {
3032
-            $string = str_replace('\\$', '$', $string);
3033
-        }
3034
-
3035
-        return $string;
3036
-    }
3037
-
3038
-    /**
3039
-     * Replaces the modifiers applied to a string or a variable.
3040
-     *
3041
-     * @param array  $m        the regex matches that must be array(1=>"double or single quotes enclosing a string,
3042
-     *                         when applicable", 2=>"the string or var", 3=>"the modifiers matched")
3043
-     * @param string $curBlock the current parser-block being processed
3044
-     * @param null   $pointer
3045
-     *
3046
-     * @return string the input enclosed with various function calls according to the modifiers found
3047
-     * @throws CompilationException
3048
-     * @throws Exception
3049
-     */
3050
-    protected function replaceModifiers(array $m, $curBlock = null, &$pointer = null)
3051
-    {
3052
-        if ($this->debug) {
3053
-            echo 'PARSING MODIFIERS : ' . $m[3] . "\n";
3054
-        }
3055
-
3056
-        if ($pointer !== null) {
3057
-            $pointer += strlen($m[3]);
3058
-        }
3059
-        // remove first pipe
3060
-        $cmdstrsrc = substr($m[3], 1);
3061
-        // remove last quote if present
3062
-        if (substr($cmdstrsrc, - 1, 1) === $m[1]) {
3063
-            $cmdstrsrc = substr($cmdstrsrc, 0, - 1);
3064
-            $add       = $m[1];
3065
-        }
3066
-
3067
-        $output = $m[2];
3068
-
3069
-        $continue = true;
3070
-        while (strlen($cmdstrsrc) > 0 && $continue) {
3071
-            if ($cmdstrsrc[0] === '|') {
3072
-                $cmdstrsrc = substr($cmdstrsrc, 1);
3073
-                continue;
3074
-            }
3075
-            if ($cmdstrsrc[0] === ' ' || $cmdstrsrc[0] === ';' || substr($cmdstrsrc, 0, strlen($this->rd)) === $this->rd) {
3076
-                if ($this->debug) {
3077
-                    echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND' . "\n";
3078
-                }
3079
-                $continue = false;
3080
-                if ($pointer !== null) {
3081
-                    $pointer -= strlen($cmdstrsrc);
3082
-                }
3083
-                break;
3084
-            }
3085
-            $cmdstr   = $cmdstrsrc;
3086
-            $paramsep = ':';
3087
-            if (!preg_match('/^(@{0,2}[a-z_][a-z0-9_]*)(:)?/i', $cmdstr, $match)) {
3088
-                throw new CompilationException($this, 'Invalid modifier name, started with : ' . substr($cmdstr, 0, 10));
3089
-            }
3090
-            $paramspos = !empty($match[2]) ? strlen($match[1]) : false;
3091
-            $func      = $match[1];
3092
-
3093
-            $state = 0;
3094
-            if ($paramspos === false) {
3095
-                $cmdstrsrc = substr($cmdstrsrc, strlen($func));
3096
-                $params    = array();
3097
-                if ($this->debug) {
3098
-                    echo 'MODIFIER (' . $func . ') CALLED WITH NO PARAMS' . "\n";
3099
-                }
3100
-            } else {
3101
-                $paramstr = substr($cmdstr, $paramspos + 1);
3102
-                if (substr($paramstr, - 1, 1) === $paramsep) {
3103
-                    $paramstr = substr($paramstr, 0, - 1);
3104
-                }
3105
-
3106
-                $ptr    = 0;
3107
-                $params = array();
3108
-                while ($ptr < strlen($paramstr)) {
3109
-                    if ($this->debug) {
3110
-                        echo 'MODIFIER (' . $func . ') START PARAM PARSING WITH POINTER AT ' . $ptr . "\n";
3111
-                    }
3112
-                    if ($this->debug) {
3113
-                        echo $paramstr . '--' . $ptr . '--' . strlen($paramstr) . '--modifier' . "\n";
3114
-                    }
3115
-                    $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'modifier', $ptr);
3116
-                    if ($this->debug) {
3117
-                        echo 'PARAM PARSED, POINTER AT ' . $ptr . "\n";
3118
-                    }
3119
-
3120
-                    if ($ptr >= strlen($paramstr)) {
3121
-                        if ($this->debug) {
3122
-                            echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED' . "\n";
3123
-                        }
3124
-                        break;
3125
-                    }
3126
-
3127
-                    if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === '|' || $paramstr[$ptr] === ';' || substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
3128
-                        if ($this->debug) {
3129
-                            echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT ' . $ptr . "\n";
3130
-                        }
3131
-                        if ($paramstr[$ptr] !== '|') {
3132
-                            $continue = false;
3133
-                            if ($pointer !== null) {
3134
-                                $pointer -= strlen($paramstr) - $ptr;
3135
-                            }
3136
-                        }
3137
-                        ++ $ptr;
3138
-                        break;
3139
-                    }
3140
-                    if ($ptr < strlen($paramstr) && $paramstr[$ptr] === ':') {
3141
-                        ++ $ptr;
3142
-                    }
3143
-                }
3144
-                $cmdstrsrc = substr($cmdstrsrc, strlen($func) + 1 + $ptr);
3145
-                foreach ($params as $k => $p) {
3146
-                    if (is_array($p) && is_array($p[1])) {
3147
-                        $state |= 2;
3148
-                    } else {
3149
-                        if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m)) {
3150
-                            $params[$k] = array($m[2], array('true', 'true'));
3151
-                        } else {
3152
-                            if ($state & 2) {
3153
-                                throw new CompilationException($this, 'You can not use an unnamed parameter after a named one');
3154
-                            }
3155
-                            $state |= 1;
3156
-                        }
3157
-                    }
3158
-                }
3159
-            }
3160
-
3161
-            // check if we must use array_map with this plugin or not
3162
-            $mapped = false;
3163
-            if (substr($func, 0, 1) === '@') {
3164
-                $func   = substr($func, 1);
3165
-                $mapped = true;
3166
-            }
3167
-
3168
-            $pluginType = $this->getPluginType($func);
3169
-
3170
-            if ($state & 2) {
3171
-                array_unshift($params, array('value', is_array($output) ? $output : array($output, $output)));
3172
-            } else {
3173
-                array_unshift($params, is_array($output) ? $output : array($output, $output));
3174
-            }
3175
-
3176
-            if ($pluginType & Core::NATIVE_PLUGIN) {
3177
-                $params = $this->mapParams($params, null, $state);
3178
-
3179
-                $params = $params['*'][0];
3180
-
3181
-                $params = self::implode_r($params);
3182
-
3183
-                if ($mapped) {
3184
-                    $output = '$this->arrayMap(\'' . $func . '\', array(' . $params . '))';
3185
-                } else {
3186
-                    $output = $func . '(' . $params . ')';
3187
-                }
3188
-            } elseif ($pluginType & Core::PROXY_PLUGIN) {
3189
-                $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state);
3190
-                foreach ($params as &$p) {
3191
-                    $p = $p[0];
3192
-                }
3193
-                $output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params);
3194
-            } elseif ($pluginType & Core::SMARTY_MODIFIER) {
3195
-                $params = $this->mapParams($params, null, $state);
3196
-                $params = $params['*'][0];
3197
-
3198
-                $params = self::implode_r($params);
3199
-
3200
-                if ($pluginType & Core::CUSTOM_PLUGIN) {
3201
-                    $callback = $this->customPlugins[$func]['callback'];
3202
-                    if (is_array($callback)) {
3203
-                        if (is_object($callback[0])) {
3204
-                            $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))';
3205
-                        } else {
3206
-                            $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))';
3207
-                        }
3208
-                    } elseif ($mapped) {
3209
-                        $output = '$this->arrayMap(\'' . $callback . '\', array(' . $params . '))';
3210
-                    } else {
3211
-                        $output = $callback . '(' . $params . ')';
3212
-                    }
3213
-                } elseif ($mapped) {
3214
-                    $output = '$this->arrayMap(\'smarty_modifier_' . $func . '\', array(' . $params . '))';
3215
-                } else {
3216
-                    $output = 'smarty_modifier_' . $func . '(' . $params . ')';
3217
-                }
3218
-            } else {
3219
-                if ($pluginType & Core::CUSTOM_PLUGIN) {
3220
-                    $callback   = $this->customPlugins[$func]['callback'];
3221
-                    $pluginName = $callback;
3222
-                } else {
3223
-                    if (class_exists('Plugin' . Core::toCamelCase($func)) !== false || function_exists('Plugin' .
3224
-                            Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''))
3225
-                        !== false) {
3226
-                        $pluginName = 'Plugin' . Core::toCamelCase($func);
3227
-                    } else {
3228
-                        $pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func);
3229
-                    }
3230
-                    if ($pluginType & Core::CLASS_PLUGIN) {
3231
-                        $callback = array($pluginName, ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process');
3232
-                    } else {
3233
-                        $callback = $pluginName . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '');
3234
-                    }
3235
-                }
3236
-                $params = $this->mapParams($params, $callback, $state);
3237
-
3238
-                foreach ($params as &$p) {
3239
-                    $p = $p[0];
3240
-                }
3241
-
3242
-                // Only for PHP function, who is not a PHP class
3243
-                if ($pluginType & Core::FUNC_PLUGIN && !($pluginType & Core::CLASS_PLUGIN)) {
3244
-                    if ($pluginType & Core::COMPILABLE_PLUGIN) {
3245
-                        if ($mapped) {
3246
-                            throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.');
3247
-                        }
3248
-                        if ($pluginType & Core::CUSTOM_PLUGIN) {
3249
-                            $funcCompiler = $this->customPlugins[$func]['callback'];
3250
-                        } else {
3251
-                            if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
3252
-                                $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile';
3253
-                            } else {
3254
-                                $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) .
3255
-                                    'Compile';
3256
-                            }
3257
-                        }
3258
-                        array_unshift($params, $this);
3259
-                        $output = call_user_func_array($funcCompiler, $params);
3260
-                    } else {
3261
-                        array_unshift($params, '$this');
3262
-
3263
-                        $params = self::implode_r($params);
3264
-                        if ($mapped) {
3265
-                            $output = '$this->arrayMap(\'' . $pluginName . '\', array(' . $params . '))';
3266
-                        } else {
3267
-                            $output = $pluginName . '(' . $params . ')';
3268
-                        }
3269
-                    }
3270
-                } else {
3271
-                    if ($pluginType & Core::COMPILABLE_PLUGIN) {
3272
-                        if ($mapped) {
3273
-                            throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.');
3274
-                        }
3275
-                        if ($pluginType & Core::CUSTOM_PLUGIN) {
3276
-                            $callback = $this->customPlugins[$func]['callback'];
3277
-                            if (!is_array($callback)) {
3278
-                                if (!method_exists($callback, 'compile')) {
3279
-                                    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');
3280
-                                }
3281
-                                if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) {
3282
-                                    $funcCompiler = array($callback, 'compile');
3283
-                                } else {
3284
-                                    $funcCompiler = array(new $callback(), 'compile');
3285
-                                }
3286
-                            } else {
3287
-                                $funcCompiler = $callback;
3288
-                            }
3289
-                        } else {
3290
-                            if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
3291
-                                $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile');
3292
-                            } else {
3293
-                                $funcCompiler = array(
3294
-                                    Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
3295
-                                    'compile'
3296
-                                );
3297
-                            }
3298
-                            array_unshift($params, $this);
3299
-                        }
3300
-                        $output = call_user_func_array($funcCompiler, $params);
3301
-                    } else {
3302
-                        $params = self::implode_r($params);
3303
-
3304
-                        if ($pluginType & Core::CUSTOM_PLUGIN) {
3305
-                            if (is_object($callback[0])) {
3306
-                                $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))';
3307
-                            } else {
3308
-                                $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))';
3309
-                            }
3310
-                        } elseif ($mapped) {
3311
-                            $output = '$this->arrayMap(array($this->getObjectPlugin(\''.
3312
-                                Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '\'), 
2092
+					} else {
2093
+						$output = '$this->classCall(\'' . $func . '\', array(' . $params . '))';
2094
+					}
2095
+				}
2096
+			}
2097
+		} // Function plugin only (cannot be a class)
2098
+		elseif ($pluginType & Core::FUNC_PLUGIN) {
2099
+			if ($pluginType & Core::COMPILABLE_PLUGIN) {
2100
+				if ($pluginType & Core::CUSTOM_PLUGIN) {
2101
+					$funcCompiler = $this->customPlugins[$func]['callback'];
2102
+				} else {
2103
+					// Custom plugin
2104
+					if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
2105
+						$funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile';
2106
+					} // Builtin helper plugin
2107
+					elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
2108
+						$funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) .
2109
+							'Compile';
2110
+					} // Builtin function plugin
2111
+					else {
2112
+						$funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) .
2113
+							'Compile';
2114
+					}
2115
+				}
2116
+				array_unshift($params, $this);
2117
+				// @TODO: Is it a real fix ?
2118
+				if ($func === 'tif') {
2119
+					$params[] = $tokens;
2120
+				}
2121
+				$output = call_user_func_array($funcCompiler, $params);
2122
+			} else {
2123
+				array_unshift($params, '$this');
2124
+				$params = self::implode_r($params);
2125
+				if ($pluginType & Core::CUSTOM_PLUGIN) {
2126
+					$callback = $this->customPlugins[$func]['callback'];
2127
+					if ($callback instanceof Closure) {
2128
+						$output = 'call_user_func($this->getCustomPlugin(\'' . $func . '\'), ' . $params . ')';
2129
+					} else {
2130
+						$output = 'call_user_func(\'' . $callback . '\', ' . $params . ')';
2131
+					}
2132
+				} else {
2133
+					// Custom plugin
2134
+					if (function_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2135
+						$output = 'Plugin' . Core::toCamelCase($func) . '(' . $params .
2136
+							')';
2137
+					} // Builtin helper plugin
2138
+					elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !==
2139
+						false) {
2140
+						$output = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . '(' .
2141
+							$params . ')';
2142
+					} // Builtin function plugin
2143
+					else {
2144
+						$output = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '(' .
2145
+							$params . ')';
2146
+					}
2147
+				}
2148
+			}
2149
+		} // Proxy plugin
2150
+		elseif ($pluginType & Core::PROXY_PLUGIN) {
2151
+			$output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params);
2152
+		} // Smarty function (@deprecated)
2153
+		elseif ($pluginType & Core::SMARTY_FUNCTION) {
2154
+			$params = '';
2155
+			if (isset($params['*'])) {
2156
+				$params = self::implode_r($params['*'], true);
2157
+			}
2158
+
2159
+			if ($pluginType & Core::CUSTOM_PLUGIN) {
2160
+				$callback = $this->customPlugins[$func]['callback'];
2161
+				if (is_array($callback)) {
2162
+					if (is_object($callback[0])) {
2163
+						$output = 'call_user_func_array(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
2164
+					} else {
2165
+						$output = 'call_user_func_array(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
2166
+					}
2167
+				} else {
2168
+					$output = $callback . '(array(' . $params . '), $this)';
2169
+				}
2170
+			} else {
2171
+				$output = 'smarty_function_' . $func . '(array(' . $params . '), $this)';
2172
+			}
2173
+		} // Template plugin
2174
+		elseif ($pluginType & Core::TEMPLATE_PLUGIN) {
2175
+			array_unshift($params, '$this');
2176
+			$params                                 = self::implode_r($params);
2177
+			$output                                 = 'Plugin' . Core::toCamelCase($func) .
2178
+				$this->templatePlugins[$func]['uuid'] . '(' . $params . ')';
2179
+			$this->templatePlugins[$func]['called'] = true;
2180
+		}
2181
+
2182
+		if (is_array($parsingParams)) {
2183
+			$parsingParams[] = array($output, $output);
2184
+
2185
+			return $parsingParams;
2186
+		} elseif ($curBlock === 'namedparam') {
2187
+			return array($output, $output);
2188
+		}
2189
+
2190
+		return $output;
2191
+	}
2192
+
2193
+	/**
2194
+	 * Parses a string.
2195
+	 *
2196
+	 * @param string $in            the string within which we must parse something
2197
+	 * @param int    $from          the starting offset of the parsed area
2198
+	 * @param int    $to            the ending offset of the parsed area
2199
+	 * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2200
+	 *                              default
2201
+	 * @param string $curBlock      the current parser-block being processed
2202
+	 * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2203
+	 *                              or null by default
2204
+	 *
2205
+	 * @return string parsed values
2206
+	 * @throws CompilationException
2207
+	 */
2208
+	protected function parseString($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2209
+	{
2210
+		$substr = substr($in, $from, $to - $from);
2211
+		$first  = $substr[0];
2212
+
2213
+		if ($this->debug) {
2214
+			echo 'STRING FOUND (in ' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . ')' . "\n";
2215
+		}
2216
+		$strend = false;
2217
+		$o      = $from + 1;
2218
+		while ($strend === false) {
2219
+			$strend = strpos($in, $first, $o);
2220
+			if ($strend === false) {
2221
+				throw new CompilationException($this, 'Unfinished string, started with ' . substr($in, $from, $to - $from));
2222
+			}
2223
+			if (substr($in, $strend - 1, 1) === '\\') {
2224
+				$o      = $strend + 1;
2225
+				$strend = false;
2226
+			}
2227
+		}
2228
+		if ($this->debug) {
2229
+			echo 'STRING DELIMITED: ' . substr($in, $from, $strend + 1 - $from) . "\n";
2230
+		}
2231
+
2232
+		$srcOutput = substr($in, $from, $strend + 1 - $from);
2233
+
2234
+		if ($pointer !== null) {
2235
+			$pointer += strlen($srcOutput);
2236
+		}
2237
+
2238
+		$output = $this->replaceStringVars($srcOutput, $first);
2239
+
2240
+		// handle modifiers
2241
+		if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend + 1 - $from), $match)) {
2242
+			$modstr = $match[1];
2243
+
2244
+			if ($curBlock === 'root' && substr($modstr, - 1) === '}') {
2245
+				$modstr = substr($modstr, 0, - 1);
2246
+			}
2247
+			$modstr = str_replace('\\' . $first, $first, $modstr);
2248
+			$ptr    = 0;
2249
+			$output = $this->replaceModifiers(array(null, null, $output, $modstr), 'string', $ptr);
2250
+
2251
+			$strend += $ptr;
2252
+			if ($pointer !== null) {
2253
+				$pointer += $ptr;
2254
+			}
2255
+			$srcOutput .= substr($substr, $strend + 1 - $from, $ptr);
2256
+		}
2257
+
2258
+		if (is_array($parsingParams)) {
2259
+			$parsingParams[] = array($output, substr($srcOutput, 1, - 1));
2260
+
2261
+			return $parsingParams;
2262
+		} elseif ($curBlock === 'namedparam') {
2263
+			return array($output, substr($srcOutput, 1, - 1));
2264
+		} else {
2265
+			return $output;
2266
+		}
2267
+	}
2268
+
2269
+	/**
2270
+	 * Parses a constant.
2271
+	 *
2272
+	 * @param string $in            the string within which we must parse something
2273
+	 * @param int    $from          the starting offset of the parsed area
2274
+	 * @param int    $to            the ending offset of the parsed area
2275
+	 * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2276
+	 *                              default
2277
+	 * @param string $curBlock      the current parser-block being processed
2278
+	 * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2279
+	 *                              or null by default
2280
+	 *
2281
+	 * @return string parsed values
2282
+	 * @throws CompilationException
2283
+	 */
2284
+	protected function parseConst($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2285
+	{
2286
+		$substr = substr($in, $from, $to - $from);
2287
+
2288
+		if ($this->debug) {
2289
+			echo 'CONST FOUND : ' . $substr . "\n";
2290
+		}
2291
+
2292
+		if (!preg_match('#^%([\\\\a-z0-9_:]+)#i', $substr, $m)) {
2293
+			throw new CompilationException($this, 'Invalid constant');
2294
+		}
2295
+
2296
+		if ($pointer !== null) {
2297
+			$pointer += strlen($m[0]);
2298
+		}
2299
+
2300
+		$output = $this->parseConstKey($m[1], $curBlock);
2301
+
2302
+		if (is_array($parsingParams)) {
2303
+			$parsingParams[] = array($output, $m[1]);
2304
+
2305
+			return $parsingParams;
2306
+		} elseif ($curBlock === 'namedparam') {
2307
+			return array($output, $m[1]);
2308
+		} else {
2309
+			return $output;
2310
+		}
2311
+	}
2312
+
2313
+	/**
2314
+	 * Parses a constant.
2315
+	 *
2316
+	 * @param string $key      the constant to parse
2317
+	 * @param string $curBlock the current parser-block being processed
2318
+	 *
2319
+	 * @return string parsed constant
2320
+	 */
2321
+	protected function parseConstKey($key, $curBlock)
2322
+	{
2323
+		if ($this->securityPolicy !== null && $this->securityPolicy->getConstantHandling() === SecurityPolicy::CONST_DISALLOW) {
2324
+			return 'null';
2325
+		}
2326
+
2327
+		if ($curBlock !== 'root') {
2328
+			$output = '(defined("' . $key . '") ? ' . $key . ' : null)';
2329
+		} else {
2330
+			$output = $key;
2331
+		}
2332
+
2333
+		return $output;
2334
+	}
2335
+
2336
+	/**
2337
+	 * Parses a variable.
2338
+	 *
2339
+	 * @param string $in            the string within which we must parse something
2340
+	 * @param int    $from          the starting offset of the parsed area
2341
+	 * @param int    $to            the ending offset of the parsed area
2342
+	 * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2343
+	 *                              default
2344
+	 * @param string $curBlock      the current parser-block being processed
2345
+	 * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2346
+	 *                              or null by default
2347
+	 *
2348
+	 * @return string parsed values
2349
+	 * @throws CompilationException
2350
+	 */
2351
+	protected function parseVar($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2352
+	{
2353
+		$substr = substr($in, $from, $to - $from);
2354
+
2355
+		// var key
2356
+		$varRegex = '(\\$?\\.?[a-z0-9\\\\_:]*(?:(?:(?:\\.|->)(?:[a-z0-9\\\\_:]+|(?R))|\\[(?:[a-z0-9\\\\_:]+|(?R)|(["\'])[^\\2]*?\\2)\\]))*)';
2357
+		// method call
2358
+		$methodCall = ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'expression' || $curBlock === 'delimited_string' ? '(\(.*)?' : '()');
2359
+		// simple math expressions
2360
+		$simpleMathExpressions = ($curBlock === 'root' || $curBlock === 'function' || $curBlock === 'namedparam' || $curBlock === 'condition' || $curBlock === 'variable' || $curBlock === 'delimited_string' ? '((?:(?:[+\/*%=-])(?:(?<!=)=?-?[$%][a-z0-9\\\\.[\]>_:-]+(?:\([^)]*\))?|(?<!=)=?-?[0-9\.,]*|[+-]))*)' : '()');
2361
+		// modifiers
2362
+		$modifiers = $curBlock !== 'modifier' ? '((?:\|(?:@?[a-z0-9\\\\_]+(?:(?::("|\').*?\5|:[^`]*))*))+)?' : '(())';
2363
+
2364
+		$regex = '#';
2365
+		$regex .= $varRegex;
2366
+		$regex .= $methodCall;
2367
+		$regex .= $simpleMathExpressions;
2368
+		$regex .= $modifiers;
2369
+		$regex .= '#i';
2370
+
2371
+		if (preg_match($regex, $substr, $match)) {
2372
+			$key = substr($match[1], 1);
2373
+
2374
+			$matchedLength = strlen($match[0]);
2375
+			$hasModifiers  = !empty($match[5]);
2376
+			$hasExpression = !empty($match[4]);
2377
+			$hasMethodCall = !empty($match[3]);
2378
+
2379
+			if (substr($key, - 1) == '.') {
2380
+				$key = substr($key, 0, - 1);
2381
+				-- $matchedLength;
2382
+			}
2383
+
2384
+			if ($hasMethodCall) {
2385
+				$matchedLength -= strlen($match[3]) + strlen(substr($match[1], strrpos($match[1], '->')));
2386
+				$key        = substr($match[1], 1, strrpos($match[1], '->') - 1);
2387
+				$methodCall = substr($match[1], strrpos($match[1], '->')) . $match[3];
2388
+			}
2389
+
2390
+			if ($hasModifiers) {
2391
+				$matchedLength -= strlen($match[5]);
2392
+			}
2393
+
2394
+			if ($pointer !== null) {
2395
+				$pointer += $matchedLength;
2396
+			}
2397
+
2398
+			// replace useless brackets by dot accessed vars and strip enclosing quotes if present
2399
+			$key = preg_replace('#\[(["\']?)([^$%\[.>-]+)\1\]#', '.$2', $key);
2400
+
2401
+			if ($this->debug) {
2402
+				if ($hasMethodCall) {
2403
+					echo 'METHOD CALL FOUND : $' . $key . substr($methodCall, 0, 30) . "\n";
2404
+				} else {
2405
+					echo 'VAR FOUND : $' . $key . "\n";
2406
+				}
2407
+			}
2408
+
2409
+			$key = str_replace('"', '\\"', $key);
2410
+
2411
+			$cnt = substr_count($key, '$');
2412
+			if ($cnt > 0) {
2413
+				$uid           = 0;
2414
+				$parsed        = array($uid => '');
2415
+				$current       = &$parsed;
2416
+				$curTxt        = &$parsed[$uid ++];
2417
+				$tree          = array();
2418
+				$chars         = str_split($key, 1);
2419
+				$inSplittedVar = false;
2420
+				$bracketCount  = 0;
2421
+
2422
+				while (($char = array_shift($chars)) !== null) {
2423
+					if ($char === '[') {
2424
+						if (count($tree) > 0) {
2425
+							++ $bracketCount;
2426
+						} else {
2427
+							$tree[]        = &$current;
2428
+							$current[$uid] = array($uid + 1 => '');
2429
+							$current       = &$current[$uid ++];
2430
+							$curTxt        = &$current[$uid ++];
2431
+							continue;
2432
+						}
2433
+					} elseif ($char === ']') {
2434
+						if ($bracketCount > 0) {
2435
+							-- $bracketCount;
2436
+						} else {
2437
+							$current = &$tree[count($tree) - 1];
2438
+							array_pop($tree);
2439
+							if (current($chars) !== '[' && current($chars) !== false && current($chars) !== ']') {
2440
+								$current[$uid] = '';
2441
+								$curTxt        = &$current[$uid ++];
2442
+							}
2443
+							continue;
2444
+						}
2445
+					} elseif ($char === '$') {
2446
+						if (count($tree) == 0) {
2447
+							$curTxt        = &$current[$uid ++];
2448
+							$inSplittedVar = true;
2449
+						}
2450
+					} elseif (($char === '.' || $char === '-') && count($tree) == 0 && $inSplittedVar) {
2451
+						$curTxt        = &$current[$uid ++];
2452
+						$inSplittedVar = false;
2453
+					}
2454
+
2455
+					$curTxt .= $char;
2456
+				}
2457
+				unset($uid, $current, $curTxt, $tree, $chars);
2458
+
2459
+				if ($this->debug) {
2460
+					echo 'RECURSIVE VAR REPLACEMENT : ' . $key . "\n";
2461
+				}
2462
+
2463
+				$key = $this->flattenVarTree($parsed);
2464
+
2465
+				if ($this->debug) {
2466
+					echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n";
2467
+				}
2468
+
2469
+				$output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("' . $key . '")');
2470
+			} else {
2471
+				$output = $this->parseVarKey($key, $hasModifiers ? 'modifier' : $curBlock);
2472
+			}
2473
+
2474
+
2475
+			// methods
2476
+			if ($hasMethodCall) {
2477
+				$ptr = 0;
2478
+
2479
+				$output = $this->parseMethodCall($output, $methodCall, $curBlock, $ptr);
2480
+
2481
+				if ($pointer !== null) {
2482
+					$pointer += $ptr;
2483
+				}
2484
+				$matchedLength += $ptr;
2485
+			}
2486
+
2487
+			if ($hasExpression) {
2488
+				// expressions
2489
+				preg_match_all('#(?:([+/*%=-])(=?-?[%$][a-z0-9\\\\.[\]>_:-]+(?:\([^)]*\))?|=?-?[0-9.,]+|\1))#i', $match[4], $expMatch);
2490
+				foreach ($expMatch[1] as $k => $operator) {
2491
+					if (substr($expMatch[2][$k], 0, 1) === '=') {
2492
+						$assign = true;
2493
+						if ($operator === '=') {
2494
+							throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, can not use "==" in expressions');
2495
+						}
2496
+						if ($curBlock !== 'root') {
2497
+							throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}');
2498
+						}
2499
+						$operator .= '=';
2500
+						$expMatch[2][$k] = substr($expMatch[2][$k], 1);
2501
+					}
2502
+
2503
+					if (substr($expMatch[2][$k], 0, 1) === '-' && strlen($expMatch[2][$k]) > 1) {
2504
+						$operator .= '-';
2505
+						$expMatch[2][$k] = substr($expMatch[2][$k], 1);
2506
+					}
2507
+					if (($operator === '+' || $operator === '-') && $expMatch[2][$k] === $operator) {
2508
+						$output = '(' . $output . $operator . $operator . ')';
2509
+						break;
2510
+					} elseif (substr($expMatch[2][$k], 0, 1) === '$') {
2511
+						$output = '(' . $output . ' ' . $operator . ' ' . $this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')';
2512
+					} elseif (substr($expMatch[2][$k], 0, 1) === '%') {
2513
+						$output = '(' . $output . ' ' . $operator . ' ' . $this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')';
2514
+					} elseif (!empty($expMatch[2][$k])) {
2515
+						$output = '(' . $output . ' ' . $operator . ' ' . str_replace(',', '.', $expMatch[2][$k]) . ')';
2516
+					} else {
2517
+						throw new CompilationException($this, 'Unfinished expression <em>' . $substr . '</em>, missing var or number after math operator');
2518
+					}
2519
+				}
2520
+			}
2521
+
2522
+			if ($this->autoEscape === true && $curBlock !== 'condition') {
2523
+				$output = '(is_string($tmp=' . $output . ') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)';
2524
+			}
2525
+
2526
+			// handle modifiers
2527
+			if ($curBlock !== 'modifier' && $hasModifiers) {
2528
+				$ptr    = 0;
2529
+				$output = $this->replaceModifiers(array(null, null, $output, $match[5]), 'var', $ptr);
2530
+				if ($pointer !== null) {
2531
+					$pointer += $ptr;
2532
+				}
2533
+				$matchedLength += $ptr;
2534
+			}
2535
+
2536
+			if (is_array($parsingParams)) {
2537
+				$parsingParams[] = array($output, $key);
2538
+
2539
+				return $parsingParams;
2540
+			} elseif ($curBlock === 'namedparam') {
2541
+				return array($output, $key);
2542
+			} elseif ($curBlock === 'string' || $curBlock === 'delimited_string') {
2543
+				return array($matchedLength, $output);
2544
+			} elseif ($curBlock === 'expression' || $curBlock === 'variable') {
2545
+				return $output;
2546
+			} elseif (isset($assign)) {
2547
+				return self::PHP_OPEN . $output . ';' . self::PHP_CLOSE;
2548
+			} else {
2549
+				return $output;
2550
+			}
2551
+		} else {
2552
+			if ($curBlock === 'string' || $curBlock === 'delimited_string') {
2553
+				return array(0, '');
2554
+			} else {
2555
+				throw new CompilationException($this, 'Invalid variable name <em>' . $substr . '</em>');
2556
+			}
2557
+		}
2558
+	}
2559
+
2560
+	/**
2561
+	 * Parses any number of chained method calls/property reads.
2562
+	 *
2563
+	 * @param string $output     the variable or whatever upon which the method are called
2564
+	 * @param string $methodCall method call source, starting at "->"
2565
+	 * @param string $curBlock   the current parser-block being processed
2566
+	 * @param int    $pointer    a reference to a pointer that will be increased by the amount of characters parsed
2567
+	 *
2568
+	 * @return string parsed call(s)/read(s)
2569
+	 */
2570
+	protected function parseMethodCall($output, $methodCall, $curBlock, &$pointer)
2571
+	{
2572
+		$ptr = 0;
2573
+		$len = strlen($methodCall);
2574
+
2575
+		while ($ptr < $len) {
2576
+			if (strpos($methodCall, '->', $ptr) === $ptr) {
2577
+				$ptr += 2;
2578
+			}
2579
+
2580
+			if (in_array(
2581
+				$methodCall[$ptr], array(
2582
+					';',
2583
+					',',
2584
+					'/',
2585
+					' ',
2586
+					"\t",
2587
+					"\r",
2588
+					"\n",
2589
+					')',
2590
+					'+',
2591
+					'*',
2592
+					'%',
2593
+					'=',
2594
+					'-',
2595
+					'|'
2596
+				)
2597
+			) || substr($methodCall, $ptr, strlen($this->rd)) === $this->rd
2598
+			) {
2599
+				// break char found
2600
+				break;
2601
+			}
2602
+
2603
+			if (!preg_match('/^([a-z0-9_]+)(\(.*?\))?/i', substr($methodCall, $ptr), $methMatch)) {
2604
+				break;
2605
+			}
2606
+
2607
+			if (empty($methMatch[2])) {
2608
+				// property
2609
+				if ($curBlock === 'root') {
2610
+					$output .= '->' . $methMatch[1];
2611
+				} else {
2612
+					$output = '(($tmp = ' . $output . ') ? $tmp->' . $methMatch[1] . ' : null)';
2613
+				}
2614
+				$ptr += strlen($methMatch[1]);
2615
+			} else {
2616
+				// method
2617
+				if (substr($methMatch[2], 0, 2) === '()') {
2618
+					$parsedCall = $methMatch[1] . '()';
2619
+					$ptr += strlen($methMatch[1]) + 2;
2620
+				} else {
2621
+					$parsedCall = $this->parseFunction($methodCall, $ptr, strlen($methodCall), false, 'method', $ptr);
2622
+				}
2623
+				if ($this->securityPolicy !== null) {
2624
+					$argPos = strpos($parsedCall, '(');
2625
+					$method = strtolower(substr($parsedCall, 0, $argPos));
2626
+					$args   = substr($parsedCall, $argPos);
2627
+					if ($curBlock === 'root') {
2628
+						$output = '$this->getSecurityPolicy()->callMethod($this, ' . $output . ', ' . var_export($method, true) . ', array' . $args . ')';
2629
+					} else {
2630
+						$output = '(($tmp = ' . $output . ') ? $this->getSecurityPolicy()->callMethod($this, $tmp, ' . var_export($method, true) . ', array' . $args . ') : null)';
2631
+					}
2632
+				} else {
2633
+					if ($curBlock === 'root') {
2634
+						$output .= '->' . $parsedCall;
2635
+					} else {
2636
+						$output = '(($tmp = ' . $output . ') ? $tmp->' . $parsedCall . ' : null)';
2637
+					}
2638
+				}
2639
+			}
2640
+		}
2641
+
2642
+		$pointer += $ptr;
2643
+
2644
+		return $output;
2645
+	}
2646
+
2647
+	/**
2648
+	 * Parses a constant variable (a variable that doesn't contain another variable) and preprocesses it to save
2649
+	 * runtime processing time.
2650
+	 *
2651
+	 * @param string $key      the variable to parse
2652
+	 * @param string $curBlock the current parser-block being processed
2653
+	 *
2654
+	 * @return string parsed variable
2655
+	 */
2656
+	protected function parseVarKey($key, $curBlock)
2657
+	{
2658
+		if ($key === '') {
2659
+			return '$this->scope';
2660
+		}
2661
+		if (substr($key, 0, 1) === '.') {
2662
+			$key = 'dwoo' . $key;
2663
+		}
2664
+		if (preg_match('#dwoo\.(get|post|server|cookies|session|env|request)((?:\.[a-z0-9_-]+)+)#i', $key, $m)) {
2665
+			$global = strtoupper($m[1]);
2666
+			if ($global === 'COOKIES') {
2667
+				$global = 'COOKIE';
2668
+			}
2669
+			$key = '$_' . $global;
2670
+			foreach (explode('.', ltrim($m[2], '.')) as $part) {
2671
+				$key .= '[' . var_export($part, true) . ']';
2672
+			}
2673
+			if ($curBlock === 'root') {
2674
+				$output = $key;
2675
+			} else {
2676
+				$output = '(isset(' . $key . ')?' . $key . ':null)';
2677
+			}
2678
+		} elseif (preg_match('#dwoo\\.const\\.([a-z0-9\\\\_:]+)#i', $key, $m)) {
2679
+			return $this->parseConstKey($m[1], $curBlock);
2680
+		} elseif ($this->scope !== null) {
2681
+			if (strstr($key, '.') === false && strstr($key, '[') === false && strstr($key, '->') === false) {
2682
+				if ($key === 'dwoo') {
2683
+					$output = '$this->globals';
2684
+				} elseif ($key === '_root' || $key === '__') {
2685
+					$output = '$this->data';
2686
+				} elseif ($key === '_parent' || $key === '_') {
2687
+					$output = '$this->readParentVar(1)';
2688
+				} elseif ($key === '_key') {
2689
+					$output = '$tmp_key';
2690
+				} else {
2691
+					if ($curBlock === 'root') {
2692
+						$output = '$this->scope["' . $key . '"]';
2693
+					} else {
2694
+						$output = '(isset($this->scope["' . $key . '"]) ? $this->scope["' . $key . '"] : null)';
2695
+					}
2696
+				}
2697
+			} else {
2698
+				preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+|(\\\?[\'"])[^\3]*?\3)\]?#i', $key, $m);
2699
+
2700
+				$i = $m[2][0];
2701
+				if ($i === '_parent' || $i === '_') {
2702
+					$parentCnt = 0;
2703
+
2704
+					while (true) {
2705
+						++ $parentCnt;
2706
+						array_shift($m[2]);
2707
+						array_shift($m[1]);
2708
+						if (current($m[2]) === '_parent') {
2709
+							continue;
2710
+						}
2711
+						break;
2712
+					}
2713
+
2714
+					$output = '$this->readParentVar(' . $parentCnt . ')';
2715
+				} else {
2716
+					if ($i === 'dwoo') {
2717
+						$output = '$this->globals';
2718
+						array_shift($m[2]);
2719
+						array_shift($m[1]);
2720
+					} elseif ($i === '_root' || $i === '__') {
2721
+						$output = '$this->data';
2722
+						array_shift($m[2]);
2723
+						array_shift($m[1]);
2724
+					} elseif ($i === '_key') {
2725
+						$output = '$tmp_key';
2726
+					} else {
2727
+						$output = '$this->scope';
2728
+					}
2729
+
2730
+					while (count($m[1]) && $m[1][0] !== '->') {
2731
+						$m[2][0] = preg_replace('/(^\\\([\'"])|\\\([\'"])$)/x', '$2$3', $m[2][0]);
2732
+						if (substr($m[2][0], 0, 1) == '"' || substr($m[2][0], 0, 1) == "'") {
2733
+							$output .= '[' . $m[2][0] . ']';
2734
+						} else {
2735
+							$output .= '["' . $m[2][0] . '"]';
2736
+						}
2737
+						array_shift($m[2]);
2738
+						array_shift($m[1]);
2739
+					}
2740
+
2741
+					if ($curBlock !== 'root') {
2742
+						$output = '(isset(' . $output . ') ? ' . $output . ':null)';
2743
+					}
2744
+				}
2745
+
2746
+				if (count($m[2])) {
2747
+					unset($m[0]);
2748
+					$output = '$this->readVarInto(' . str_replace("\n", '', var_export($m, true)) . ', ' . $output . ', ' . ($curBlock == 'root' ? 'false' : 'true') . ')';
2749
+				}
2750
+			}
2751
+		} else {
2752
+			preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+)\]?#i', $key, $m);
2753
+			unset($m[0]);
2754
+			$output = '$this->readVar(' . str_replace("\n", '', var_export($m, true)) . ')';
2755
+		}
2756
+
2757
+		return $output;
2758
+	}
2759
+
2760
+	/**
2761
+	 * Flattens a variable tree, this helps in parsing very complex variables such as $var.foo[$foo.bar->baz].baz,
2762
+	 * it computes the contents of the brackets first and works out from there.
2763
+	 *
2764
+	 * @param array $tree     the variable tree parsed by he parseVar() method that must be flattened
2765
+	 * @param bool  $recursed leave that to false by default, it is only for internal use
2766
+	 *
2767
+	 * @return string flattened tree
2768
+	 */
2769
+	protected function flattenVarTree(array $tree, $recursed = false)
2770
+	{
2771
+		$out = $recursed ? '".$this->readVarInto(' : '';
2772
+		foreach ($tree as $bit) {
2773
+			if (is_array($bit)) {
2774
+				$out .= '.' . $this->flattenVarTree($bit, false);
2775
+			} else {
2776
+				$key = str_replace('"', '\\"', $bit);
2777
+
2778
+				if (substr($key, 0, 1) === '$') {
2779
+					$out .= '".' . $this->parseVar($key, 0, strlen($key), false, 'variable') . '."';
2780
+				} else {
2781
+					$cnt = substr_count($key, '$');
2782
+
2783
+					if ($this->debug) {
2784
+						echo 'PARSING SUBVARS IN : ' . $key . "\n";
2785
+					}
2786
+					if ($cnt > 0) {
2787
+						while (-- $cnt >= 0) {
2788
+							if (isset($last)) {
2789
+								$last = strrpos($key, '$', - (strlen($key) - $last + 1));
2790
+							} else {
2791
+								$last = strrpos($key, '$');
2792
+							}
2793
+							preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch);
2794
+
2795
+							$len = strlen($submatch[0]);
2796
+							$key = substr_replace(
2797
+								$key, preg_replace_callback(
2798
+									'#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array(
2799
+										$this,
2800
+										'replaceVarKeyHelper'
2801
+									), substr($key, $last, $len)
2802
+								), $last, $len
2803
+							);
2804
+							if ($this->debug) {
2805
+								echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n";
2806
+							}
2807
+						}
2808
+						unset($last);
2809
+
2810
+						$out .= $key;
2811
+					} else {
2812
+						$out .= $key;
2813
+					}
2814
+				}
2815
+			}
2816
+		}
2817
+		$out .= $recursed ? ', true)."' : '';
2818
+
2819
+		return $out;
2820
+	}
2821
+
2822
+	/**
2823
+	 * Helper function that parses a variable.
2824
+	 *
2825
+	 * @param array $match the matched variable, array(1=>"string match")
2826
+	 *
2827
+	 * @return string parsed variable
2828
+	 */
2829
+	protected function replaceVarKeyHelper($match)
2830
+	{
2831
+		return '".' . $this->parseVar($match[0], 0, strlen($match[0]), false, 'variable') . '."';
2832
+	}
2833
+
2834
+	/**
2835
+	 * Parses various constants, operators or non-quoted strings.
2836
+	 *
2837
+	 * @param string $in            the string within which we must parse something
2838
+	 * @param int    $from          the starting offset of the parsed area
2839
+	 * @param int    $to            the ending offset of the parsed area
2840
+	 * @param mixed  $parsingParams must be an array if we are parsing a function or modifier's parameters, or false by
2841
+	 *                              default
2842
+	 * @param string $curBlock      the current parser-block being processed
2843
+	 * @param mixed  $pointer       a reference to a pointer that will be increased by the amount of characters parsed,
2844
+	 *                              or null by default
2845
+	 *
2846
+	 * @return string parsed values
2847
+	 * @throws Exception
2848
+	 */
2849
+	protected function parseOthers($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2850
+	{
2851
+		$substr = substr($in, $from, $to - $from);
2852
+
2853
+		$end = strlen($substr);
2854
+
2855
+		if ($curBlock === 'condition') {
2856
+			$breakChars = array(
2857
+				'(',
2858
+				')',
2859
+				' ',
2860
+				'||',
2861
+				'&&',
2862
+				'|',
2863
+				'&',
2864
+				'>=',
2865
+				'<=',
2866
+				'===',
2867
+				'==',
2868
+				'=',
2869
+				'!==',
2870
+				'!=',
2871
+				'<<',
2872
+				'<',
2873
+				'>>',
2874
+				'>',
2875
+				'^',
2876
+				'~',
2877
+				',',
2878
+				'+',
2879
+				'-',
2880
+				'*',
2881
+				'/',
2882
+				'%',
2883
+				'!',
2884
+				'?',
2885
+				':',
2886
+				$this->rd,
2887
+				';'
2888
+			);
2889
+		} elseif ($curBlock === 'modifier') {
2890
+			$breakChars = array(' ', ',', ')', ':', '|', "\r", "\n", "\t", ';', $this->rd);
2891
+		} elseif ($curBlock === 'expression') {
2892
+			$breakChars = array('/', '%', '+', '-', '*', ' ', ',', ')', "\r", "\n", "\t", ';', $this->rd);
2893
+		} else {
2894
+			$breakChars = array(' ', ',', ')', "\r", "\n", "\t", ';', $this->rd);
2895
+		}
2896
+
2897
+		$breaker = false;
2898
+		while (list($k, $char) = each($breakChars)) {
2899
+			$test = strpos($substr, $char);
2900
+			if ($test !== false && $test < $end) {
2901
+				$end     = $test;
2902
+				$breaker = $k;
2903
+			}
2904
+		}
2905
+
2906
+		if ($curBlock === 'condition') {
2907
+			if ($end === 0 && $breaker !== false) {
2908
+				$end = strlen($breakChars[$breaker]);
2909
+			}
2910
+		}
2911
+
2912
+		if ($end !== false) {
2913
+			$substr = substr($substr, 0, $end);
2914
+		}
2915
+
2916
+		if ($pointer !== null) {
2917
+			$pointer += strlen($substr);
2918
+		}
2919
+
2920
+		$src    = $substr;
2921
+		$substr = trim($substr);
2922
+
2923
+		if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') {
2924
+			if ($this->debug) {
2925
+				echo 'BOOLEAN(FALSE) PARSED' . "\n";
2926
+			}
2927
+			$substr = 'false';
2928
+			$type   = self::T_BOOL;
2929
+		} elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') {
2930
+			if ($this->debug) {
2931
+				echo 'BOOLEAN(TRUE) PARSED' . "\n";
2932
+			}
2933
+			$substr = 'true';
2934
+			$type   = self::T_BOOL;
2935
+		} elseif ($substr === 'null' || $substr === 'NULL') {
2936
+			if ($this->debug) {
2937
+				echo 'NULL PARSED' . "\n";
2938
+			}
2939
+			$substr = 'null';
2940
+			$type   = self::T_NULL;
2941
+		} elseif (is_numeric($substr)) {
2942
+			$substr = (float)$substr;
2943
+			if ((int)$substr == $substr) {
2944
+				$substr = (int)$substr;
2945
+			}
2946
+			$type = self::T_NUMERIC;
2947
+			if ($this->debug) {
2948
+				echo 'NUMBER (' . $substr . ') PARSED' . "\n";
2949
+			}
2950
+		} elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) {
2951
+			if ($this->debug) {
2952
+				echo 'SIMPLE MATH PARSED . "\n"';
2953
+			}
2954
+			$type   = self::T_MATH;
2955
+			$substr = '(' . $substr . ')';
2956
+		} elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) {
2957
+			if ($this->debug) {
2958
+				echo 'BREAKCHAR (' . $substr . ') PARSED' . "\n";
2959
+			}
2960
+			$type = self::T_BREAKCHAR;
2961
+			//$substr = '"'.$substr.'"';
2962
+		} else {
2963
+			$substr = $this->replaceStringVars('\'' . str_replace('\'', '\\\'', $substr) . '\'', '\'', $curBlock);
2964
+			$type   = self::T_UNQUOTED_STRING;
2965
+			if ($this->debug) {
2966
+				echo 'BLABBER (' . $substr . ') CASTED AS STRING' . "\n";
2967
+			}
2968
+		}
2969
+
2970
+		if (is_array($parsingParams)) {
2971
+			$parsingParams[] = array($substr, $src, $type);
2972
+
2973
+			return $parsingParams;
2974
+		} elseif ($curBlock === 'namedparam') {
2975
+			return array($substr, $src, $type);
2976
+		} elseif ($curBlock === 'expression') {
2977
+			return $substr;
2978
+		} else {
2979
+			throw new Exception('Something went wrong');
2980
+		}
2981
+	}
2982
+
2983
+	/**
2984
+	 * Replaces variables within a parsed string.
2985
+	 *
2986
+	 * @param string $string   the parsed string
2987
+	 * @param string $first    the first character parsed in the string, which is the string delimiter (' or ")
2988
+	 * @param string $curBlock the current parser-block being processed
2989
+	 *
2990
+	 * @return string the original string with variables replaced
2991
+	 */
2992
+	protected function replaceStringVars($string, $first, $curBlock = '')
2993
+	{
2994
+		$pos = 0;
2995
+		if ($this->debug) {
2996
+			echo 'STRING VAR REPLACEMENT : ' . $string . "\n";
2997
+		}
2998
+		// replace vars
2999
+		while (($pos = strpos($string, '$', $pos)) !== false) {
3000
+			$prev = substr($string, $pos - 1, 1);
3001
+			if ($prev === '\\') {
3002
+				++ $pos;
3003
+				continue;
3004
+			}
3005
+
3006
+			$var = $this->parse($string, $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string')));
3007
+			$len = $var[0];
3008
+			$var = $this->parse(str_replace('\\' . $first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string')));
3009
+
3010
+			if ($prev === '`' && substr($string, $pos + $len, 1) === '`') {
3011
+				$string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos - 1, $len + 2);
3012
+			} else {
3013
+				$string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos, $len);
3014
+			}
3015
+			$pos += strlen($var[1]) + 2;
3016
+			if ($this->debug) {
3017
+				echo 'STRING VAR REPLACEMENT DONE : ' . $string . "\n";
3018
+			}
3019
+		}
3020
+
3021
+		// handle modifiers
3022
+		// TODO Obsolete?
3023
+		$string = preg_replace_callback(
3024
+			'#("|\')\.(.+?)\.\1((?:\|(?:@?[a-z0-9_]+(?:(?::("|\').+?\4|:[^`]*))*))+)#i', array(
3025
+			$this,
3026
+			'replaceModifiers'
3027
+			), $string
3028
+		);
3029
+
3030
+		// replace escaped dollar operators by unescaped ones if required
3031
+		if ($first === "'") {
3032
+			$string = str_replace('\\$', '$', $string);
3033
+		}
3034
+
3035
+		return $string;
3036
+	}
3037
+
3038
+	/**
3039
+	 * Replaces the modifiers applied to a string or a variable.
3040
+	 *
3041
+	 * @param array  $m        the regex matches that must be array(1=>"double or single quotes enclosing a string,
3042
+	 *                         when applicable", 2=>"the string or var", 3=>"the modifiers matched")
3043
+	 * @param string $curBlock the current parser-block being processed
3044
+	 * @param null   $pointer
3045
+	 *
3046
+	 * @return string the input enclosed with various function calls according to the modifiers found
3047
+	 * @throws CompilationException
3048
+	 * @throws Exception
3049
+	 */
3050
+	protected function replaceModifiers(array $m, $curBlock = null, &$pointer = null)
3051
+	{
3052
+		if ($this->debug) {
3053
+			echo 'PARSING MODIFIERS : ' . $m[3] . "\n";
3054
+		}
3055
+
3056
+		if ($pointer !== null) {
3057
+			$pointer += strlen($m[3]);
3058
+		}
3059
+		// remove first pipe
3060
+		$cmdstrsrc = substr($m[3], 1);
3061
+		// remove last quote if present
3062
+		if (substr($cmdstrsrc, - 1, 1) === $m[1]) {
3063
+			$cmdstrsrc = substr($cmdstrsrc, 0, - 1);
3064
+			$add       = $m[1];
3065
+		}
3066
+
3067
+		$output = $m[2];
3068
+
3069
+		$continue = true;
3070
+		while (strlen($cmdstrsrc) > 0 && $continue) {
3071
+			if ($cmdstrsrc[0] === '|') {
3072
+				$cmdstrsrc = substr($cmdstrsrc, 1);
3073
+				continue;
3074
+			}
3075
+			if ($cmdstrsrc[0] === ' ' || $cmdstrsrc[0] === ';' || substr($cmdstrsrc, 0, strlen($this->rd)) === $this->rd) {
3076
+				if ($this->debug) {
3077
+					echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND' . "\n";
3078
+				}
3079
+				$continue = false;
3080
+				if ($pointer !== null) {
3081
+					$pointer -= strlen($cmdstrsrc);
3082
+				}
3083
+				break;
3084
+			}
3085
+			$cmdstr   = $cmdstrsrc;
3086
+			$paramsep = ':';
3087
+			if (!preg_match('/^(@{0,2}[a-z_][a-z0-9_]*)(:)?/i', $cmdstr, $match)) {
3088
+				throw new CompilationException($this, 'Invalid modifier name, started with : ' . substr($cmdstr, 0, 10));
3089
+			}
3090
+			$paramspos = !empty($match[2]) ? strlen($match[1]) : false;
3091
+			$func      = $match[1];
3092
+
3093
+			$state = 0;
3094
+			if ($paramspos === false) {
3095
+				$cmdstrsrc = substr($cmdstrsrc, strlen($func));
3096
+				$params    = array();
3097
+				if ($this->debug) {
3098
+					echo 'MODIFIER (' . $func . ') CALLED WITH NO PARAMS' . "\n";
3099
+				}
3100
+			} else {
3101
+				$paramstr = substr($cmdstr, $paramspos + 1);
3102
+				if (substr($paramstr, - 1, 1) === $paramsep) {
3103
+					$paramstr = substr($paramstr, 0, - 1);
3104
+				}
3105
+
3106
+				$ptr    = 0;
3107
+				$params = array();
3108
+				while ($ptr < strlen($paramstr)) {
3109
+					if ($this->debug) {
3110
+						echo 'MODIFIER (' . $func . ') START PARAM PARSING WITH POINTER AT ' . $ptr . "\n";
3111
+					}
3112
+					if ($this->debug) {
3113
+						echo $paramstr . '--' . $ptr . '--' . strlen($paramstr) . '--modifier' . "\n";
3114
+					}
3115
+					$params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'modifier', $ptr);
3116
+					if ($this->debug) {
3117
+						echo 'PARAM PARSED, POINTER AT ' . $ptr . "\n";
3118
+					}
3119
+
3120
+					if ($ptr >= strlen($paramstr)) {
3121
+						if ($this->debug) {
3122
+							echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED' . "\n";
3123
+						}
3124
+						break;
3125
+					}
3126
+
3127
+					if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === '|' || $paramstr[$ptr] === ';' || substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
3128
+						if ($this->debug) {
3129
+							echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT ' . $ptr . "\n";
3130
+						}
3131
+						if ($paramstr[$ptr] !== '|') {
3132
+							$continue = false;
3133
+							if ($pointer !== null) {
3134
+								$pointer -= strlen($paramstr) - $ptr;
3135
+							}
3136
+						}
3137
+						++ $ptr;
3138
+						break;
3139
+					}
3140
+					if ($ptr < strlen($paramstr) && $paramstr[$ptr] === ':') {
3141
+						++ $ptr;
3142
+					}
3143
+				}
3144
+				$cmdstrsrc = substr($cmdstrsrc, strlen($func) + 1 + $ptr);
3145
+				foreach ($params as $k => $p) {
3146
+					if (is_array($p) && is_array($p[1])) {
3147
+						$state |= 2;
3148
+					} else {
3149
+						if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m)) {
3150
+							$params[$k] = array($m[2], array('true', 'true'));
3151
+						} else {
3152
+							if ($state & 2) {
3153
+								throw new CompilationException($this, 'You can not use an unnamed parameter after a named one');
3154
+							}
3155
+							$state |= 1;
3156
+						}
3157
+					}
3158
+				}
3159
+			}
3160
+
3161
+			// check if we must use array_map with this plugin or not
3162
+			$mapped = false;
3163
+			if (substr($func, 0, 1) === '@') {
3164
+				$func   = substr($func, 1);
3165
+				$mapped = true;
3166
+			}
3167
+
3168
+			$pluginType = $this->getPluginType($func);
3169
+
3170
+			if ($state & 2) {
3171
+				array_unshift($params, array('value', is_array($output) ? $output : array($output, $output)));
3172
+			} else {
3173
+				array_unshift($params, is_array($output) ? $output : array($output, $output));
3174
+			}
3175
+
3176
+			if ($pluginType & Core::NATIVE_PLUGIN) {
3177
+				$params = $this->mapParams($params, null, $state);
3178
+
3179
+				$params = $params['*'][0];
3180
+
3181
+				$params = self::implode_r($params);
3182
+
3183
+				if ($mapped) {
3184
+					$output = '$this->arrayMap(\'' . $func . '\', array(' . $params . '))';
3185
+				} else {
3186
+					$output = $func . '(' . $params . ')';
3187
+				}
3188
+			} elseif ($pluginType & Core::PROXY_PLUGIN) {
3189
+				$params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state);
3190
+				foreach ($params as &$p) {
3191
+					$p = $p[0];
3192
+				}
3193
+				$output = call_user_func(array($this->getDwoo()->getPluginProxy(), 'getCode'), $func, $params);
3194
+			} elseif ($pluginType & Core::SMARTY_MODIFIER) {
3195
+				$params = $this->mapParams($params, null, $state);
3196
+				$params = $params['*'][0];
3197
+
3198
+				$params = self::implode_r($params);
3199
+
3200
+				if ($pluginType & Core::CUSTOM_PLUGIN) {
3201
+					$callback = $this->customPlugins[$func]['callback'];
3202
+					if (is_array($callback)) {
3203
+						if (is_object($callback[0])) {
3204
+							$output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))';
3205
+						} else {
3206
+							$output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))';
3207
+						}
3208
+					} elseif ($mapped) {
3209
+						$output = '$this->arrayMap(\'' . $callback . '\', array(' . $params . '))';
3210
+					} else {
3211
+						$output = $callback . '(' . $params . ')';
3212
+					}
3213
+				} elseif ($mapped) {
3214
+					$output = '$this->arrayMap(\'smarty_modifier_' . $func . '\', array(' . $params . '))';
3215
+				} else {
3216
+					$output = 'smarty_modifier_' . $func . '(' . $params . ')';
3217
+				}
3218
+			} else {
3219
+				if ($pluginType & Core::CUSTOM_PLUGIN) {
3220
+					$callback   = $this->customPlugins[$func]['callback'];
3221
+					$pluginName = $callback;
3222
+				} else {
3223
+					if (class_exists('Plugin' . Core::toCamelCase($func)) !== false || function_exists('Plugin' .
3224
+							Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''))
3225
+						!== false) {
3226
+						$pluginName = 'Plugin' . Core::toCamelCase($func);
3227
+					} else {
3228
+						$pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func);
3229
+					}
3230
+					if ($pluginType & Core::CLASS_PLUGIN) {
3231
+						$callback = array($pluginName, ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process');
3232
+					} else {
3233
+						$callback = $pluginName . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '');
3234
+					}
3235
+				}
3236
+				$params = $this->mapParams($params, $callback, $state);
3237
+
3238
+				foreach ($params as &$p) {
3239
+					$p = $p[0];
3240
+				}
3241
+
3242
+				// Only for PHP function, who is not a PHP class
3243
+				if ($pluginType & Core::FUNC_PLUGIN && !($pluginType & Core::CLASS_PLUGIN)) {
3244
+					if ($pluginType & Core::COMPILABLE_PLUGIN) {
3245
+						if ($mapped) {
3246
+							throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.');
3247
+						}
3248
+						if ($pluginType & Core::CUSTOM_PLUGIN) {
3249
+							$funcCompiler = $this->customPlugins[$func]['callback'];
3250
+						} else {
3251
+							if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
3252
+								$funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile';
3253
+							} else {
3254
+								$funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) .
3255
+									'Compile';
3256
+							}
3257
+						}
3258
+						array_unshift($params, $this);
3259
+						$output = call_user_func_array($funcCompiler, $params);
3260
+					} else {
3261
+						array_unshift($params, '$this');
3262
+
3263
+						$params = self::implode_r($params);
3264
+						if ($mapped) {
3265
+							$output = '$this->arrayMap(\'' . $pluginName . '\', array(' . $params . '))';
3266
+						} else {
3267
+							$output = $pluginName . '(' . $params . ')';
3268
+						}
3269
+					}
3270
+				} else {
3271
+					if ($pluginType & Core::COMPILABLE_PLUGIN) {
3272
+						if ($mapped) {
3273
+							throw new CompilationException($this, 'The @ operator can not be used on compiled plugins.');
3274
+						}
3275
+						if ($pluginType & Core::CUSTOM_PLUGIN) {
3276
+							$callback = $this->customPlugins[$func]['callback'];
3277
+							if (!is_array($callback)) {
3278
+								if (!method_exists($callback, 'compile')) {
3279
+									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');
3280
+								}
3281
+								if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) {
3282
+									$funcCompiler = array($callback, 'compile');
3283
+								} else {
3284
+									$funcCompiler = array(new $callback(), 'compile');
3285
+								}
3286
+							} else {
3287
+								$funcCompiler = $callback;
3288
+							}
3289
+						} else {
3290
+							if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
3291
+								$funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile');
3292
+							} else {
3293
+								$funcCompiler = array(
3294
+									Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
3295
+									'compile'
3296
+								);
3297
+							}
3298
+							array_unshift($params, $this);
3299
+						}
3300
+						$output = call_user_func_array($funcCompiler, $params);
3301
+					} else {
3302
+						$params = self::implode_r($params);
3303
+
3304
+						if ($pluginType & Core::CUSTOM_PLUGIN) {
3305
+							if (is_object($callback[0])) {
3306
+								$output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))';
3307
+							} else {
3308
+								$output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))';
3309
+							}
3310
+						} elseif ($mapped) {
3311
+							$output = '$this->arrayMap(array($this->getObjectPlugin(\''.
3312
+								Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '\'), 
3313 3313
                             \'process\'), array(' . $params . '))';
3314
-                        } else {
3315
-                            if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
3316
-                                $output = '$this->classCall(\'Plugin' . Core::toCamelCase($func) . '\', array(' . $params . '))';
3317
-                            } elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($func)) !== false) {
3318
-                                $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . $func . '\', array(' . $params . '))';
3319
-                            } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== false) {
3320
-                                $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', array(' . $params . '))';
3321
-                            } else {
3322
-                                $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))';
3323
-                            }
3324
-                        }
3325
-                    }
3326
-                }
3327
-            }
3328
-        }
3329
-
3330
-        if ($curBlock === 'namedparam') {
3331
-            return array($output, $output);
3332
-        } elseif ($curBlock === 'var' || $m[1] === null) {
3333
-            return $output;
3334
-        } elseif ($curBlock === 'string' || $curBlock === 'root') {
3335
-            return $m[1] . '.' . $output . '.' . $m[1] . (isset($add) ? $add : null);
3336
-        }
3337
-
3338
-        return '';
3339
-    }
3340
-
3341
-    /**
3342
-     * Recursively implodes an array in a similar manner as var_export() does but with some tweaks
3343
-     * to handle pre-compiled values and the fact that we do not need to enclose everything with
3344
-     * "array" and do not require top-level keys to be displayed.
3345
-     *
3346
-     * @param array $params        the array to implode
3347
-     * @param bool  $recursiveCall if set to true, the function outputs key names for the top level
3348
-     *
3349
-     * @return string the imploded array
3350
-     */
3351
-    public static function implode_r(array $params, $recursiveCall = false)
3352
-    {
3353
-        $out = '';
3354
-        foreach ($params as $k => $p) {
3355
-            if (is_array($p)) {
3356
-                $out2 = 'array(';
3357
-                foreach ($p as $k2 => $v) {
3358
-                    $out2 .= var_export($k2, true) . ' => ' . (is_array($v) ? 'array(' . self::implode_r($v, true) . ')' : $v) . ', ';
3359
-                }
3360
-                $p = rtrim($out2, ', ') . ')';
3361
-            }
3362
-            if ($recursiveCall) {
3363
-                $out .= var_export($k, true) . ' => ' . $p . ', ';
3364
-            } else {
3365
-                $out .= $p . ', ';
3366
-            }
3367
-        }
3368
-
3369
-        return rtrim($out, ', ');
3370
-    }
3371
-
3372
-    /**
3373
-     * Returns the plugin type of a plugin and adds it to the used plugins array if required.
3374
-     *
3375
-     * @param string $name plugin name, as found in the template
3376
-     *
3377
-     * @return int type as a multi bit flag composed of the Dwoo plugin types constants
3378
-     * @throws Exception
3379
-     * @throws SecurityException
3380
-     * @throws Exception
3381
-     */
3382
-    protected function getPluginType($name)
3383
-    {
3384
-        $pluginType = - 1;
3385
-
3386
-        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)) {
3387
-            $phpFunc = true;
3388
-        } elseif ($this->securityPolicy !== null && function_exists($name) && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) === false) {
3389
-            throw new SecurityException('Call to a disallowed php function : ' . $name);
3390
-        }
3391
-
3392
-        while ($pluginType <= 0) {
3393
-            // Template plugin compilable
3394
-            if (isset($this->templatePlugins[$name])) {
3395
-                $pluginType = Core::TEMPLATE_PLUGIN | Core::COMPILABLE_PLUGIN;
3396
-            } // Custom plugin
3397
-            elseif (isset($this->customPlugins[$name])) {
3398
-                $pluginType = $this->customPlugins[$name]['type'] | Core::CUSTOM_PLUGIN;
3399
-            } // Class blocks plugin
3400
-            elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3401
-                $pluginType = Core::CLASS_PLUGIN;
3402
-                if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), 'Dwoo\Block\Plugin')) {
3403
-                    $pluginType += Core::BLOCK_PLUGIN;
3404
-                }
3405
-                $interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name));
3406
-                if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3407
-                    $pluginType |= Core::COMPILABLE_PLUGIN;
3408
-                }
3409
-            } // Class functions plugin
3410
-            elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3411
-                $pluginType = Core::FUNC_PLUGIN + Core::CLASS_PLUGIN;
3412
-                $interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name));
3413
-                if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3414
-                    $pluginType |= Core::COMPILABLE_PLUGIN;
3415
-                }
3416
-            } // Class without namespace
3417
-            elseif (class_exists('Plugin' . Core::toCamelCase($name)) !== false) {
3418
-                $pluginType = Core::CLASS_PLUGIN;
3419
-                $interfaces = class_implements('Plugin' . Core::toCamelCase($name));
3420
-                if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3421
-                    $pluginType |= Core::COMPILABLE_PLUGIN;
3422
-                }
3423
-            } // Function plugin (with/without namespaces)
3424
-            elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase ($name)) !==
3425
-                false || function_exists('Plugin' . Core::toCamelCase($name)) !== false) {
3426
-                $pluginType = Core::FUNC_PLUGIN;
3427
-            } // Function plugin compile (with/without namespaces)
3428
-            elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name) .
3429
-                    'Compile') !== false || function_exists('Plugin' . Core::toCamelCase($name) . 'Compile') !==
3430
-                false) {
3431
-                $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN;
3432
-            } // Helper plugin class compile
3433
-            elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3434
-                $pluginType = Core::CLASS_PLUGIN | Core::COMPILABLE_PLUGIN;
3435
-            } // Helper plugin function compile
3436
-            elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name) . 'Compile') !== false) {
3437
-                $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN;
3438
-            } // Smarty modifier
3439
-            elseif (function_exists('smarty_modifier_' . $name) !== false) {
3440
-                $pluginType = Core::SMARTY_MODIFIER;
3441
-            } // Smarty function
3442
-            elseif (function_exists('smarty_function_' . $name) !== false) {
3443
-                $pluginType = Core::SMARTY_FUNCTION;
3444
-            } // Smarty block
3445
-            elseif (function_exists('smarty_block_' . $name) !== false) {
3446
-                $pluginType = Core::SMARTY_BLOCK;
3447
-            } // Everything else
3448
-            else {
3449
-                if ($pluginType === - 1) {
3450
-                    try {
3451
-                        $this->getDwoo()->getLoader()->loadPlugin('Plugin' . Core::toCamelCase($name));
3452
-                    }
3453
-                    catch (Exception $e) {
3454
-                        if (isset($phpFunc)) {
3455
-                            $pluginType = Core::NATIVE_PLUGIN;
3456
-                        } elseif (is_object($this->getDwoo()->getPluginProxy()) && $this->getDwoo()->getPluginProxy()->handles($name)) {
3457
-                            $pluginType = Core::PROXY_PLUGIN;
3458
-                            break;
3459
-                        } else {
3460
-                            throw $e;
3461
-                        }
3462
-                    }
3463
-                } else {
3464
-                    throw new Exception('Plugin "' . $name . '" could not be found, type:' . $pluginType);
3465
-                }
3466
-                ++ $pluginType;
3467
-            }
3468
-        }
3469
-
3470
-        if (($pluginType & Core::COMPILABLE_PLUGIN) === 0 && ($pluginType & Core::NATIVE_PLUGIN) === 0 && ($pluginType & Core::PROXY_PLUGIN) === 0) {
3471
-            $this->addUsedPlugin(Core::toCamelCase($name), $pluginType);
3472
-        }
3473
-
3474
-        return $pluginType;
3475
-    }
3476
-
3477
-    /**
3478
-     * Allows a plugin to load another one at compile time, this will also mark
3479
-     * it as used by this template so it will be loaded at runtime (which can be
3480
-     * useful for compiled plugins that rely on another plugin when their compiled
3481
-     * code runs).
3482
-     *
3483
-     * @param string $name the plugin name
3484
-     *
3485
-     * @return void
3486
-     */
3487
-    public function loadPlugin($name)
3488
-    {
3489
-        $this->getPluginType($name);
3490
-    }
3491
-
3492
-    /**
3493
-     * Runs htmlentities over the matched <?php ?> blocks when the security policy enforces that.
3494
-     *
3495
-     * @param array $match matched php block
3496
-     *
3497
-     * @return string the htmlentities-converted string
3498
-     */
3499
-    protected function phpTagEncodingHelper($match)
3500
-    {
3501
-        return htmlspecialchars($match[0]);
3502
-    }
3503
-
3504
-    /**
3505
-     * Maps the parameters received from the template onto the parameters required by the given callback.
3506
-     *
3507
-     * @param array    $params   the array of parameters
3508
-     * @param callback $callback the function or method to reflect on to find out the required parameters
3509
-     * @param int      $callType the type of call in the template, 0 = no params, 1 = php-style call, 2 = named
3510
-     *                           parameters call
3511
-     * @param array    $map      the parameter map to use, if not provided it will be built from the callback
3512
-     *
3513
-     * @return array parameters sorted in the correct order with missing optional parameters filled
3514
-     * @throws CompilationException
3515
-     */
3516
-    protected function mapParams(array $params, $callback, $callType = 2, $map = null)
3517
-    {
3518
-        if (!$map) {
3519
-            $map = $this->getParamMap($callback);
3520
-        }
3521
-
3522
-        $paramlist = array();
3523
-
3524
-        // transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values))
3525
-        $ps = array();
3526
-        foreach ($params as $p) {
3527
-            if (is_array($p[1])) {
3528
-                $ps[$p[0]] = $p[1];
3529
-            } else {
3530
-                $ps[] = $p;
3531
-            }
3532
-        }
3533
-
3534
-        // loops over the param map and assigns values from the template or default value for unset optional params
3535
-        while (list($k, $v) = each($map)) {
3536
-            if ($v[0] === '*') {
3537
-                // "rest" array parameter, fill every remaining params in it and then break
3538
-                if (count($ps) === 0) {
3539
-                    if ($v[1] === false) {
3540
-                        throw new CompilationException(
3541
-                            $this, 'Rest argument missing for ' . str_replace(
3542
-                                array(
3543
-                                    Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin',
3544
-                                'Compile'
3545
-                                ), '', (is_array($callback) ? $callback[0] : $callback)
3546
-                            )
3547
-                        );
3548
-                    } else {
3549
-                        break;
3550
-                    }
3551
-                }
3552
-                $tmp  = array();
3553
-                $tmp2 = array();
3554
-                $tmp3 = array();
3555
-                foreach ($ps as $i => $p) {
3556
-                    $tmp[$i]  = $p[0];
3557
-                    $tmp2[$i] = $p[1];
3558
-                    $tmp3[$i] = isset($p[2]) ? $p[2] : 0;
3559
-                    unset($ps[$i]);
3560
-                }
3561
-                $paramlist[$v[0]] = array($tmp, $tmp2, $tmp3);
3562
-                unset($tmp, $tmp2, $i, $p);
3563
-                break;
3564
-            } elseif (isset($ps[$v[0]])) {
3565
-                // parameter is defined as named param
3566
-                $paramlist[$v[0]] = $ps[$v[0]];
3567
-                unset($ps[$v[0]]);
3568
-            } elseif (isset($ps[$k])) {
3569
-                // parameter is defined as ordered param
3570
-                $paramlist[$v[0]] = $ps[$k];
3571
-                unset($ps[$k]);
3572
-            } elseif ($v[1] === false) {
3573
-                // parameter is not defined and not optional, throw error
3574
-                if (is_array($callback)) {
3575
-                    if (is_object($callback[0])) {
3576
-                        $name = get_class($callback[0]) . '::' . $callback[1];
3577
-                    } else {
3578
-                        $name = $callback[0];
3579
-                    }
3580
-                } else {
3581
-                    $name = $callback;
3582
-                }
3583
-
3584
-                throw new CompilationException(
3585
-                    $this, 'Argument ' . $k . '/' . $v[0] . ' missing for ' . str_replace(
3586
-                        array(
3587
-                            Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin',
3588
-                        'Compile'
3589
-                        ), '', $name
3590
-                    )
3591
-                );
3592
-            } elseif ($v[2] === null) {
3593
-                // enforce lowercased null if default value is null (php outputs NULL with var export)
3594
-                $paramlist[$v[0]] = array('null', null, self::T_NULL);
3595
-            } else {
3596
-                // outputs default value with var_export
3597
-                $paramlist[$v[0]] = array(var_export($v[2], true), $v[2]);
3598
-            }
3599
-        }
3600
-
3601
-        if (count($ps)) {
3602
-            foreach ($ps as $i => $p) {
3603
-                array_push($paramlist, $p);
3604
-            }
3605
-        }
3606
-
3607
-        return $paramlist;
3608
-    }
3609
-
3610
-    /**
3611
-     * Returns the parameter map of the given callback, it filters out entries typed as Dwoo and Compiler and turns the
3612
-     * rest parameter into a "*".
3613
-     *
3614
-     * @param callback $callback the function/method to reflect on
3615
-     *
3616
-     * @return array processed parameter map
3617
-     */
3618
-    protected function getParamMap($callback)
3619
-    {
3620
-        if (is_null($callback)) {
3621
-            return array(array('*', true));
3622
-        }
3623
-        if (is_array($callback)) {
3624
-            $ref = new ReflectionMethod($callback[0], $callback[1]);
3625
-        } else {
3626
-            $ref = new ReflectionFunction($callback);
3627
-        }
3628
-
3629
-        $out = array();
3630
-        foreach ($ref->getParameters() as $param) {
3631
-            if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Core') {
3632
-                continue;
3633
-            }
3634
-            if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Compiler') {
3635
-                continue;
3636
-            }
3637
-            if ($param->getName() === 'rest' && $param->isArray() === true) {
3638
-                $out[] = array('*', $param->isOptional(), null);
3639
-                continue;
3640
-            }
3641
-            $out[] = array(
3642
-                $param->getName(),
3643
-                $param->isOptional(),
3644
-                $param->isOptional() ? $param->getDefaultValue() : null
3645
-            );
3646
-        }
3647
-
3648
-        return $out;
3649
-    }
3650
-
3651
-    /**
3652
-     * Returns a default instance of this compiler, used by default by all Dwoo templates that do not have a
3653
-     * specific compiler assigned and when you do not override the default compiler factory function.
3654
-     *
3655
-     * @see    Core::setDefaultCompilerFactory()
3656
-     * @return Compiler
3657
-     */
3658
-    public static function compilerFactory()
3659
-    {
3660
-        if (self::$instance === null) {
3661
-            self::$instance = new self();
3662
-        }
3663
-
3664
-        return self::$instance;
3665
-    }
3314
+						} else {
3315
+							if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
3316
+								$output = '$this->classCall(\'Plugin' . Core::toCamelCase($func) . '\', array(' . $params . '))';
3317
+							} elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($func)) !== false) {
3318
+								$output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . $func . '\', array(' . $params . '))';
3319
+							} elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== false) {
3320
+								$output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', array(' . $params . '))';
3321
+							} else {
3322
+								$output = '$this->classCall(\'' . $func . '\', array(' . $params . '))';
3323
+							}
3324
+						}
3325
+					}
3326
+				}
3327
+			}
3328
+		}
3329
+
3330
+		if ($curBlock === 'namedparam') {
3331
+			return array($output, $output);
3332
+		} elseif ($curBlock === 'var' || $m[1] === null) {
3333
+			return $output;
3334
+		} elseif ($curBlock === 'string' || $curBlock === 'root') {
3335
+			return $m[1] . '.' . $output . '.' . $m[1] . (isset($add) ? $add : null);
3336
+		}
3337
+
3338
+		return '';
3339
+	}
3340
+
3341
+	/**
3342
+	 * Recursively implodes an array in a similar manner as var_export() does but with some tweaks
3343
+	 * to handle pre-compiled values and the fact that we do not need to enclose everything with
3344
+	 * "array" and do not require top-level keys to be displayed.
3345
+	 *
3346
+	 * @param array $params        the array to implode
3347
+	 * @param bool  $recursiveCall if set to true, the function outputs key names for the top level
3348
+	 *
3349
+	 * @return string the imploded array
3350
+	 */
3351
+	public static function implode_r(array $params, $recursiveCall = false)
3352
+	{
3353
+		$out = '';
3354
+		foreach ($params as $k => $p) {
3355
+			if (is_array($p)) {
3356
+				$out2 = 'array(';
3357
+				foreach ($p as $k2 => $v) {
3358
+					$out2 .= var_export($k2, true) . ' => ' . (is_array($v) ? 'array(' . self::implode_r($v, true) . ')' : $v) . ', ';
3359
+				}
3360
+				$p = rtrim($out2, ', ') . ')';
3361
+			}
3362
+			if ($recursiveCall) {
3363
+				$out .= var_export($k, true) . ' => ' . $p . ', ';
3364
+			} else {
3365
+				$out .= $p . ', ';
3366
+			}
3367
+		}
3368
+
3369
+		return rtrim($out, ', ');
3370
+	}
3371
+
3372
+	/**
3373
+	 * Returns the plugin type of a plugin and adds it to the used plugins array if required.
3374
+	 *
3375
+	 * @param string $name plugin name, as found in the template
3376
+	 *
3377
+	 * @return int type as a multi bit flag composed of the Dwoo plugin types constants
3378
+	 * @throws Exception
3379
+	 * @throws SecurityException
3380
+	 * @throws Exception
3381
+	 */
3382
+	protected function getPluginType($name)
3383
+	{
3384
+		$pluginType = - 1;
3385
+
3386
+		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)) {
3387
+			$phpFunc = true;
3388
+		} elseif ($this->securityPolicy !== null && function_exists($name) && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) === false) {
3389
+			throw new SecurityException('Call to a disallowed php function : ' . $name);
3390
+		}
3391
+
3392
+		while ($pluginType <= 0) {
3393
+			// Template plugin compilable
3394
+			if (isset($this->templatePlugins[$name])) {
3395
+				$pluginType = Core::TEMPLATE_PLUGIN | Core::COMPILABLE_PLUGIN;
3396
+			} // Custom plugin
3397
+			elseif (isset($this->customPlugins[$name])) {
3398
+				$pluginType = $this->customPlugins[$name]['type'] | Core::CUSTOM_PLUGIN;
3399
+			} // Class blocks plugin
3400
+			elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3401
+				$pluginType = Core::CLASS_PLUGIN;
3402
+				if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), 'Dwoo\Block\Plugin')) {
3403
+					$pluginType += Core::BLOCK_PLUGIN;
3404
+				}
3405
+				$interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name));
3406
+				if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3407
+					$pluginType |= Core::COMPILABLE_PLUGIN;
3408
+				}
3409
+			} // Class functions plugin
3410
+			elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3411
+				$pluginType = Core::FUNC_PLUGIN + Core::CLASS_PLUGIN;
3412
+				$interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name));
3413
+				if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3414
+					$pluginType |= Core::COMPILABLE_PLUGIN;
3415
+				}
3416
+			} // Class without namespace
3417
+			elseif (class_exists('Plugin' . Core::toCamelCase($name)) !== false) {
3418
+				$pluginType = Core::CLASS_PLUGIN;
3419
+				$interfaces = class_implements('Plugin' . Core::toCamelCase($name));
3420
+				if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3421
+					$pluginType |= Core::COMPILABLE_PLUGIN;
3422
+				}
3423
+			} // Function plugin (with/without namespaces)
3424
+			elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase ($name)) !==
3425
+				false || function_exists('Plugin' . Core::toCamelCase($name)) !== false) {
3426
+				$pluginType = Core::FUNC_PLUGIN;
3427
+			} // Function plugin compile (with/without namespaces)
3428
+			elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name) .
3429
+					'Compile') !== false || function_exists('Plugin' . Core::toCamelCase($name) . 'Compile') !==
3430
+				false) {
3431
+				$pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN;
3432
+			} // Helper plugin class compile
3433
+			elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3434
+				$pluginType = Core::CLASS_PLUGIN | Core::COMPILABLE_PLUGIN;
3435
+			} // Helper plugin function compile
3436
+			elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name) . 'Compile') !== false) {
3437
+				$pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN;
3438
+			} // Smarty modifier
3439
+			elseif (function_exists('smarty_modifier_' . $name) !== false) {
3440
+				$pluginType = Core::SMARTY_MODIFIER;
3441
+			} // Smarty function
3442
+			elseif (function_exists('smarty_function_' . $name) !== false) {
3443
+				$pluginType = Core::SMARTY_FUNCTION;
3444
+			} // Smarty block
3445
+			elseif (function_exists('smarty_block_' . $name) !== false) {
3446
+				$pluginType = Core::SMARTY_BLOCK;
3447
+			} // Everything else
3448
+			else {
3449
+				if ($pluginType === - 1) {
3450
+					try {
3451
+						$this->getDwoo()->getLoader()->loadPlugin('Plugin' . Core::toCamelCase($name));
3452
+					}
3453
+					catch (Exception $e) {
3454
+						if (isset($phpFunc)) {
3455
+							$pluginType = Core::NATIVE_PLUGIN;
3456
+						} elseif (is_object($this->getDwoo()->getPluginProxy()) && $this->getDwoo()->getPluginProxy()->handles($name)) {
3457
+							$pluginType = Core::PROXY_PLUGIN;
3458
+							break;
3459
+						} else {
3460
+							throw $e;
3461
+						}
3462
+					}
3463
+				} else {
3464
+					throw new Exception('Plugin "' . $name . '" could not be found, type:' . $pluginType);
3465
+				}
3466
+				++ $pluginType;
3467
+			}
3468
+		}
3469
+
3470
+		if (($pluginType & Core::COMPILABLE_PLUGIN) === 0 && ($pluginType & Core::NATIVE_PLUGIN) === 0 && ($pluginType & Core::PROXY_PLUGIN) === 0) {
3471
+			$this->addUsedPlugin(Core::toCamelCase($name), $pluginType);
3472
+		}
3473
+
3474
+		return $pluginType;
3475
+	}
3476
+
3477
+	/**
3478
+	 * Allows a plugin to load another one at compile time, this will also mark
3479
+	 * it as used by this template so it will be loaded at runtime (which can be
3480
+	 * useful for compiled plugins that rely on another plugin when their compiled
3481
+	 * code runs).
3482
+	 *
3483
+	 * @param string $name the plugin name
3484
+	 *
3485
+	 * @return void
3486
+	 */
3487
+	public function loadPlugin($name)
3488
+	{
3489
+		$this->getPluginType($name);
3490
+	}
3491
+
3492
+	/**
3493
+	 * Runs htmlentities over the matched <?php ?> blocks when the security policy enforces that.
3494
+	 *
3495
+	 * @param array $match matched php block
3496
+	 *
3497
+	 * @return string the htmlentities-converted string
3498
+	 */
3499
+	protected function phpTagEncodingHelper($match)
3500
+	{
3501
+		return htmlspecialchars($match[0]);
3502
+	}
3503
+
3504
+	/**
3505
+	 * Maps the parameters received from the template onto the parameters required by the given callback.
3506
+	 *
3507
+	 * @param array    $params   the array of parameters
3508
+	 * @param callback $callback the function or method to reflect on to find out the required parameters
3509
+	 * @param int      $callType the type of call in the template, 0 = no params, 1 = php-style call, 2 = named
3510
+	 *                           parameters call
3511
+	 * @param array    $map      the parameter map to use, if not provided it will be built from the callback
3512
+	 *
3513
+	 * @return array parameters sorted in the correct order with missing optional parameters filled
3514
+	 * @throws CompilationException
3515
+	 */
3516
+	protected function mapParams(array $params, $callback, $callType = 2, $map = null)
3517
+	{
3518
+		if (!$map) {
3519
+			$map = $this->getParamMap($callback);
3520
+		}
3521
+
3522
+		$paramlist = array();
3523
+
3524
+		// transforms the parameter array from (x=>array('paramname'=>array(values))) to (paramname=>array(values))
3525
+		$ps = array();
3526
+		foreach ($params as $p) {
3527
+			if (is_array($p[1])) {
3528
+				$ps[$p[0]] = $p[1];
3529
+			} else {
3530
+				$ps[] = $p;
3531
+			}
3532
+		}
3533
+
3534
+		// loops over the param map and assigns values from the template or default value for unset optional params
3535
+		while (list($k, $v) = each($map)) {
3536
+			if ($v[0] === '*') {
3537
+				// "rest" array parameter, fill every remaining params in it and then break
3538
+				if (count($ps) === 0) {
3539
+					if ($v[1] === false) {
3540
+						throw new CompilationException(
3541
+							$this, 'Rest argument missing for ' . str_replace(
3542
+								array(
3543
+									Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin',
3544
+								'Compile'
3545
+								), '', (is_array($callback) ? $callback[0] : $callback)
3546
+							)
3547
+						);
3548
+					} else {
3549
+						break;
3550
+					}
3551
+				}
3552
+				$tmp  = array();
3553
+				$tmp2 = array();
3554
+				$tmp3 = array();
3555
+				foreach ($ps as $i => $p) {
3556
+					$tmp[$i]  = $p[0];
3557
+					$tmp2[$i] = $p[1];
3558
+					$tmp3[$i] = isset($p[2]) ? $p[2] : 0;
3559
+					unset($ps[$i]);
3560
+				}
3561
+				$paramlist[$v[0]] = array($tmp, $tmp2, $tmp3);
3562
+				unset($tmp, $tmp2, $i, $p);
3563
+				break;
3564
+			} elseif (isset($ps[$v[0]])) {
3565
+				// parameter is defined as named param
3566
+				$paramlist[$v[0]] = $ps[$v[0]];
3567
+				unset($ps[$v[0]]);
3568
+			} elseif (isset($ps[$k])) {
3569
+				// parameter is defined as ordered param
3570
+				$paramlist[$v[0]] = $ps[$k];
3571
+				unset($ps[$k]);
3572
+			} elseif ($v[1] === false) {
3573
+				// parameter is not defined and not optional, throw error
3574
+				if (is_array($callback)) {
3575
+					if (is_object($callback[0])) {
3576
+						$name = get_class($callback[0]) . '::' . $callback[1];
3577
+					} else {
3578
+						$name = $callback[0];
3579
+					}
3580
+				} else {
3581
+					$name = $callback;
3582
+				}
3583
+
3584
+				throw new CompilationException(
3585
+					$this, 'Argument ' . $k . '/' . $v[0] . ' missing for ' . str_replace(
3586
+						array(
3587
+							Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin',
3588
+						'Compile'
3589
+						), '', $name
3590
+					)
3591
+				);
3592
+			} elseif ($v[2] === null) {
3593
+				// enforce lowercased null if default value is null (php outputs NULL with var export)
3594
+				$paramlist[$v[0]] = array('null', null, self::T_NULL);
3595
+			} else {
3596
+				// outputs default value with var_export
3597
+				$paramlist[$v[0]] = array(var_export($v[2], true), $v[2]);
3598
+			}
3599
+		}
3600
+
3601
+		if (count($ps)) {
3602
+			foreach ($ps as $i => $p) {
3603
+				array_push($paramlist, $p);
3604
+			}
3605
+		}
3606
+
3607
+		return $paramlist;
3608
+	}
3609
+
3610
+	/**
3611
+	 * Returns the parameter map of the given callback, it filters out entries typed as Dwoo and Compiler and turns the
3612
+	 * rest parameter into a "*".
3613
+	 *
3614
+	 * @param callback $callback the function/method to reflect on
3615
+	 *
3616
+	 * @return array processed parameter map
3617
+	 */
3618
+	protected function getParamMap($callback)
3619
+	{
3620
+		if (is_null($callback)) {
3621
+			return array(array('*', true));
3622
+		}
3623
+		if (is_array($callback)) {
3624
+			$ref = new ReflectionMethod($callback[0], $callback[1]);
3625
+		} else {
3626
+			$ref = new ReflectionFunction($callback);
3627
+		}
3628
+
3629
+		$out = array();
3630
+		foreach ($ref->getParameters() as $param) {
3631
+			if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Core') {
3632
+				continue;
3633
+			}
3634
+			if (($class = $param->getClass()) !== null && $class->name === 'Dwoo\Compiler') {
3635
+				continue;
3636
+			}
3637
+			if ($param->getName() === 'rest' && $param->isArray() === true) {
3638
+				$out[] = array('*', $param->isOptional(), null);
3639
+				continue;
3640
+			}
3641
+			$out[] = array(
3642
+				$param->getName(),
3643
+				$param->isOptional(),
3644
+				$param->isOptional() ? $param->getDefaultValue() : null
3645
+			);
3646
+		}
3647
+
3648
+		return $out;
3649
+	}
3650
+
3651
+	/**
3652
+	 * Returns a default instance of this compiler, used by default by all Dwoo templates that do not have a
3653
+	 * specific compiler assigned and when you do not override the default compiler factory function.
3654
+	 *
3655
+	 * @see    Core::setDefaultCompilerFactory()
3656
+	 * @return Compiler
3657
+	 */
3658
+	public static function compilerFactory()
3659
+	{
3660
+		if (self::$instance === null) {
3661
+			self::$instance = new self();
3662
+		}
3663
+
3664
+		return self::$instance;
3665
+	}
3666 3666
 }
Please login to merge, or discard this patch.
Switch Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -769,13 +769,13 @@  discard block
 block discarded – undo
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,51 +875,51 @@  discard block
 block discarded – undo
875 875
             }
876 876
 
877 877
             switch ($type) {
878
-                case Core::CLASS_PLUGIN:
879
-                case Core::CLASS_PLUGIN + Core::BLOCK_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::CLASS_PLUGIN + Core::FUNC_PLUGIN:
889
-                    if (class_exists('Plugin' . $plugin) !== false) {
890
-                        $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)".
891
-                            "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
892
-                    } else {
893
-                        $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
894
-                            "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
895
-                    }
896
-                    break;
897
-                case Core::FUNC_PLUGIN:
898
-                    if (function_exists('Plugin' . $plugin) !== false) {
899
-                        $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)".
878
+            case Core::CLASS_PLUGIN:
879
+            case Core::CLASS_PLUGIN + Core::BLOCK_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::CLASS_PLUGIN + Core::FUNC_PLUGIN:
889
+                if (class_exists('Plugin' . $plugin) !== false) {
890
+                    $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)".
900 891
                         "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
901
-                    } else {
902
-                        $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
892
+                } else {
893
+                    $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
903 894
                         "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
904
-                    }
905
-                    break;
906
-                case Core::SMARTY_MODIFIER:
907
-                    $output .= "if (function_exists('smarty_modifier_$plugin')===false)".
908
-                    "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
909
-                    break;
910
-                case Core::SMARTY_FUNCTION:
911
-                    $output .= "if (function_exists('smarty_function_$plugin')===false)".
912
-                    "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
913
-                    break;
914
-                case Core::SMARTY_BLOCK:
915
-                    $output .= "if (function_exists('smarty_block_$plugin')===false)".
916
-                    "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
917
-                    break;
918
-                case Core::PROXY_PLUGIN:
919
-                    $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin);
920
-                    break;
921
-                default:
922
-                    throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type);
895
+                }
896
+                break;
897
+            case Core::FUNC_PLUGIN:
898
+                if (function_exists('Plugin' . $plugin) !== false) {
899
+                    $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)".
900
+                    "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
901
+                } else {
902
+                    $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
903
+                    "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
904
+                }
905
+                break;
906
+            case Core::SMARTY_MODIFIER:
907
+                $output .= "if (function_exists('smarty_modifier_$plugin')===false)".
908
+                "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
909
+                break;
910
+            case Core::SMARTY_FUNCTION:
911
+                $output .= "if (function_exists('smarty_function_$plugin')===false)".
912
+                "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
913
+                break;
914
+            case Core::SMARTY_BLOCK:
915
+                $output .= "if (function_exists('smarty_block_$plugin')===false)".
916
+                "\n\t\$this->getLoader()->loadPlugin('$plugin');\n";
917
+                break;
918
+            case Core::PROXY_PLUGIN:
919
+                $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin);
920
+                break;
921
+            default:
922
+                throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type);
923 923
             }
924 924
         }
925 925
 
Please login to merge, or discard this patch.
Spacing   +379 added lines, -381 removed lines patch added patch discarded remove patch
@@ -294,7 +294,7 @@  discard block
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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";
@@ -876,30 +876,30 @@  discard block
 block discarded – undo
876 876
 
877 877
             switch ($type) {
878 878
                 case Core::CLASS_PLUGIN:
879
-                case Core::CLASS_PLUGIN + Core::BLOCK_PLUGIN:
880
-                    if (class_exists('Plugin' . $plugin) !== false) {
881
-                        $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)".
879
+                case Core::CLASS_PLUGIN+Core::BLOCK_PLUGIN:
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
-                case Core::CLASS_PLUGIN + Core::FUNC_PLUGIN:
889
-                    if (class_exists('Plugin' . $plugin) !== false) {
890
-                        $output .= "if (class_exists('" . "Plugin" . $plugin . "')===false)".
888
+                case Core::CLASS_PLUGIN+Core::FUNC_PLUGIN:
889
+                    if (class_exists('Plugin'.$plugin) !== false) {
890
+                        $output .= "if (class_exists('"."Plugin".$plugin."')===false)".
891 891
                             "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
892 892
                     } else {
893
-                        $output .= "if (class_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
893
+                        $output .= "if (class_exists('".Core::NAMESPACE_PLUGINS_FUNCTIONS."Plugin".$plugin."')===false)".
894 894
                             "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
895 895
                     }
896 896
                     break;
897 897
                 case Core::FUNC_PLUGIN:
898
-                    if (function_exists('Plugin' . $plugin) !== false) {
899
-                        $output .= "if (function_exists('" . "Plugin" . $plugin . "')===false)".
898
+                    if (function_exists('Plugin'.$plugin) !== false) {
899
+                        $output .= "if (function_exists('"."Plugin".$plugin."')===false)".
900 900
                         "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
901 901
                     } else {
902
-                        $output .= "if (function_exists('" . Core::NAMESPACE_PLUGINS_FUNCTIONS . "Plugin" . $plugin . "')===false)".
902
+                        $output .= "if (function_exists('".Core::NAMESPACE_PLUGINS_FUNCTIONS."Plugin".$plugin."')===false)".
903 903
                         "\n\t\$this->getLoader()->loadPlugin('Plugin$plugin');\n";
904 904
                     }
905 905
                     break;
@@ -919,7 +919,7 @@  discard block
 block discarded – undo
919 919
                     $output .= $this->getDwoo()->getPluginProxy()->getLoader($plugin);
920 920
                     break;
921 921
                 default:
922
-                    throw new CompilationException($this, 'Type error for ' . $plugin . ' with type' . $type);
922
+                    throw new CompilationException($this, 'Type error for '.$plugin.' with type'.$type);
923 923
             }
924 924
         }
925 925
 
@@ -930,30 +930,30 @@  discard block
 block discarded – undo
930 930
         }
931 931
         foreach ($this->templatePlugins as $function) {
932 932
             if (isset($function['called']) && $function['called'] === true) {
933
-                $output .= $function['body'] . PHP_EOL;
933
+                $output .= $function['body'].PHP_EOL;
934 934
             }
935 935
         }
936 936
 
937
-        $output .= $compiled . "\n?>";
937
+        $output .= $compiled."\n?>";
938 938
 
939
-        $output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*' . preg_quote(self::PHP_CLOSE, '/') . preg_quote(self::PHP_OPEN, '/') . ')/', ";\n", $output);
940
-        $output = str_replace(self::PHP_CLOSE . self::PHP_OPEN, "\n", $output);
939
+        $output = preg_replace('/(?<!;|\}|\*\/|\n|\{)(\s*'.preg_quote(self::PHP_CLOSE, '/').preg_quote(self::PHP_OPEN, '/').')/', ";\n", $output);
940
+        $output = str_replace(self::PHP_CLOSE.self::PHP_OPEN, "\n", $output);
941 941
 
942 942
         // handle <?xml tag at the beginning
943 943
         $output = preg_replace('#(/\* template body \*/ \?>\s*)<\?xml#is', '$1<?php echo \'<?xml\'; ?>', $output);
944 944
 
945 945
         // add another line break after PHP closing tags that have a line break following,
946 946
         // as we do not know whether it's intended, and PHP will strip it otherwise
947
-        $output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0' . "\n", $output);
947
+        $output = preg_replace('/(?<!"|<\?xml)\s*\?>\n/', '$0'."\n", $output);
948 948
 
949 949
         if ($this->debug) {
950
-            echo '=============================================================================================' . "\n";
950
+            echo '============================================================================================='."\n";
951 951
             $lines = preg_split('{\r\n|\n|<br />}', $output);
952 952
             array_shift($lines);
953 953
             foreach ($lines as $i => $line) {
954
-                echo ($i + 1) . '. ' . $line . "\r\n";
954
+                echo ($i+1).'. '.$line."\r\n";
955 955
             }
956
-            echo '=============================================================================================' . "\n";
956
+            echo '============================================================================================='."\n";
957 957
         }
958 958
 
959 959
         $this->template = $this->dwoo = null;
@@ -970,13 +970,13 @@  discard block
 block discarded – undo
970 970
     protected function resolveSubTemplateDependencies($function)
971 971
     {
972 972
         if ($this->debug) {
973
-            echo 'Compiler::' . __FUNCTION__ . "\n";
973
+            echo 'Compiler::'.__FUNCTION__."\n";
974 974
         }
975 975
 
976 976
         $body = $this->templatePlugins[$function]['body'];
977 977
         foreach ($this->templatePlugins as $func => $attr) {
978
-            if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS .
979
-            'Plugin' . Core::toCamelCase($func)) !== false) {
978
+            if ($func !== $function && !isset($attr['called']) && strpos($body, Core::NAMESPACE_PLUGINS_FUNCTIONS.
979
+            'Plugin'.Core::toCamelCase($func)) !== false) {
980 980
                 $this->templatePlugins[$func]['called'] = true;
981 981
                 $this->resolveSubTemplateDependencies($func);
982 982
             }
@@ -1000,14 +1000,14 @@  discard block
 block discarded – undo
1000 1000
 
1001 1001
         if ($this->curBlock['buffer'] === null && count($this->stack) > 1) {
1002 1002
             // buffer is not initialized yet (the block has just been created)
1003
-            $this->stack[count($this->stack) - 2]['buffer'] .= (string)$content;
1003
+            $this->stack[count($this->stack)-2]['buffer'] .= (string) $content;
1004 1004
             $this->curBlock['buffer'] = '';
1005 1005
         } else {
1006 1006
             if (!isset($this->curBlock['buffer'])) {
1007 1007
                 throw new CompilationException($this, 'The template has been closed too early, you probably have an extra block-closing tag somewhere');
1008 1008
             }
1009 1009
             // append current content to current block's buffer
1010
-            $this->curBlock['buffer'] .= (string)$content;
1010
+            $this->curBlock['buffer'] .= (string) $content;
1011 1011
         }
1012 1012
         $this->line += $lineCount;
1013 1013
     }
@@ -1077,23 +1077,23 @@  discard block
 block discarded – undo
1077 1077
     public function addBlock($type, array $params, $paramtype)
1078 1078
     {
1079 1079
         if ($this->debug) {
1080
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1080
+            echo 'Compiler::'.__FUNCTION__."\n";
1081 1081
         }
1082 1082
 
1083
-        $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type);
1083
+        $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($type);
1084 1084
         if (class_exists($class) === false) {
1085 1085
             $this->getDwoo()->getLoader()->loadPlugin($type);
1086 1086
         }
1087 1087
         $params = $this->mapParams($params, array($class, 'init'), $paramtype);
1088 1088
 
1089
-        $this->stack[]  = array(
1089
+        $this->stack[] = array(
1090 1090
             'type'   => $type,
1091 1091
             'params' => $params,
1092 1092
             'custom' => false,
1093 1093
             'class'  => $class,
1094 1094
             'buffer' => null
1095 1095
         );
1096
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1096
+        $this->curBlock = &$this->stack[count($this->stack)-1];
1097 1097
 
1098 1098
         return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type);
1099 1099
     }
@@ -1118,14 +1118,14 @@  discard block
 block discarded – undo
1118 1118
 
1119 1119
         $params = $this->mapParams($params, array($class, 'init'), $paramtype);
1120 1120
 
1121
-        $this->stack[]  = array(
1121
+        $this->stack[] = array(
1122 1122
             'type'   => $type,
1123 1123
             'params' => $params,
1124 1124
             'custom' => true,
1125 1125
             'class'  => $class,
1126 1126
             'buffer' => null
1127 1127
         );
1128
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1128
+        $this->curBlock = &$this->stack[count($this->stack)-1];
1129 1129
 
1130 1130
         return call_user_func(array($class, 'preProcessing'), $this, $params, '', '', $type);
1131 1131
     }
@@ -1140,21 +1140,21 @@  discard block
 block discarded – undo
1140 1140
     public function injectBlock($type, array $params)
1141 1141
     {
1142 1142
         if ($this->debug) {
1143
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1143
+            echo 'Compiler::'.__FUNCTION__."\n";
1144 1144
         }
1145 1145
 
1146
-        $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($type);
1146
+        $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($type);
1147 1147
         if (class_exists($class) === false) {
1148 1148
             $this->getDwoo()->getLoader()->loadPlugin($type);
1149 1149
         }
1150
-        $this->stack[]  = array(
1150
+        $this->stack[] = array(
1151 1151
             'type'   => $type,
1152 1152
             'params' => $params,
1153 1153
             'custom' => false,
1154 1154
             'class'  => $class,
1155 1155
             'buffer' => null
1156 1156
         );
1157
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1157
+        $this->curBlock = &$this->stack[count($this->stack)-1];
1158 1158
     }
1159 1159
 
1160 1160
     /**
@@ -1169,7 +1169,7 @@  discard block
 block discarded – undo
1169 1169
     public function removeBlock($type)
1170 1170
     {
1171 1171
         if ($this->debug) {
1172
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1172
+            echo 'Compiler::'.__FUNCTION__."\n";
1173 1173
         }
1174 1174
 
1175 1175
         $output = '';
@@ -1183,10 +1183,10 @@  discard block
 block discarded – undo
1183 1183
                 if ($top['custom']) {
1184 1184
                     $class = $top['class'];
1185 1185
                 } else {
1186
-                    $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($top['type']);
1186
+                    $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($top['type']);
1187 1187
                 }
1188 1188
                 if (count($this->stack)) {
1189
-                    $this->curBlock = &$this->stack[count($this->stack) - 1];
1189
+                    $this->curBlock = &$this->stack[count($this->stack)-1];
1190 1190
                     $this->push(call_user_func(array(
1191 1191
                         $class,
1192 1192
                         'postProcessing'
@@ -1207,7 +1207,7 @@  discard block
 block discarded – undo
1207 1207
                 }
1208 1208
             }
1209 1209
 
1210
-            throw new CompilationException($this, 'Syntax malformation, a block of type "' . $type . '" was closed but was not opened');
1210
+            throw new CompilationException($this, 'Syntax malformation, a block of type "'.$type.'" was closed but was not opened');
1211 1211
             break;
1212 1212
         }
1213 1213
 
@@ -1246,7 +1246,7 @@  discard block
 block discarded – undo
1246 1246
             }
1247 1247
         }
1248 1248
 
1249
-        throw new CompilationException($this, 'A parent block of type "' . $type . '" is required and can not be found');
1249
+        throw new CompilationException($this, 'A parent block of type "'.$type.'" is required and can not be found');
1250 1250
     }
1251 1251
 
1252 1252
     /**
@@ -1269,7 +1269,7 @@  discard block
 block discarded – undo
1269 1269
     public function removeTopBlock()
1270 1270
     {
1271 1271
         if ($this->debug) {
1272
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1272
+            echo 'Compiler::'.__FUNCTION__."\n";
1273 1273
         }
1274 1274
 
1275 1275
         $o = array_pop($this->stack);
@@ -1279,10 +1279,10 @@  discard block
 block discarded – undo
1279 1279
         if ($o['custom']) {
1280 1280
             $class = $o['class'];
1281 1281
         } else {
1282
-            $class = Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($o['type']);
1282
+            $class = Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($o['type']);
1283 1283
         }
1284 1284
 
1285
-        $this->curBlock = &$this->stack[count($this->stack) - 1];
1285
+        $this->curBlock = &$this->stack[count($this->stack)-1];
1286 1286
 
1287 1287
         return call_user_func(array($class, 'postProcessing'), $this, $o['params'], '', '', $o['buffer']);
1288 1288
     }
@@ -1361,7 +1361,7 @@  discard block
 block discarded – undo
1361 1361
     protected function parse($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
1362 1362
     {
1363 1363
         if ($this->debug) {
1364
-            echo 'Compiler::' . __FUNCTION__ . "\n";
1364
+            echo 'Compiler::'.__FUNCTION__."\n";
1365 1365
         }
1366 1366
 
1367 1367
         if ($to === null) {
@@ -1378,14 +1378,14 @@  discard block
 block discarded – undo
1378 1378
                 // end template tag
1379 1379
                 $pointer += strlen($this->rd);
1380 1380
                 if ($this->debug) {
1381
-                    echo 'TEMPLATE PARSING ENDED' . "\n";
1381
+                    echo 'TEMPLATE PARSING ENDED'."\n";
1382 1382
                 }
1383 1383
 
1384 1384
                 return false;
1385 1385
             }
1386
-            ++ $from;
1386
+            ++$from;
1387 1387
             if ($pointer !== null) {
1388
-                ++ $pointer;
1388
+                ++$pointer;
1389 1389
             }
1390 1390
             if ($from >= $to) {
1391 1391
                 if (is_array($parsingParams)) {
@@ -1397,22 +1397,22 @@  discard block
 block discarded – undo
1397 1397
             $first = $in[$from];
1398 1398
         }
1399 1399
 
1400
-        $substr = substr($in, $from, $to - $from);
1400
+        $substr = substr($in, $from, $to-$from);
1401 1401
 
1402 1402
         if ($this->debug) {
1403
-            echo 'PARSE CALL : PARSING "' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . '" @ ' . $from . ':' . $to . ' in ' . $curBlock . ' : pointer=' . $pointer . "\n";
1403
+            echo 'PARSE CALL : PARSING "'.htmlentities(substr($in, $from, min($to-$from, 50))).(($to-$from) > 50 ? '...' : '').'" @ '.$from.':'.$to.' in '.$curBlock.' : pointer='.$pointer."\n";
1404 1404
         }
1405 1405
         $parsed = '';
1406 1406
 
1407 1407
         if ($curBlock === 'root' && $first === '*') {
1408 1408
             $src      = $this->getTemplateSource();
1409
-            $startpos = $this->getPointer() - strlen($this->ld);
1409
+            $startpos = $this->getPointer()-strlen($this->ld);
1410 1410
             if (substr($src, $startpos, strlen($this->ld)) === $this->ld) {
1411 1411
                 if ($startpos > 0) {
1412 1412
                     do {
1413 1413
                         $char = substr($src, -- $startpos, 1);
1414 1414
                         if ($char == "\n") {
1415
-                            ++ $startpos;
1415
+                            ++$startpos;
1416 1416
                             $whitespaceStart = true;
1417 1417
                             break;
1418 1418
                         }
@@ -1423,12 +1423,12 @@  discard block
 block discarded – undo
1423 1423
                 if (!isset($whitespaceStart)) {
1424 1424
                     $startpos = $this->getPointer();
1425 1425
                 } else {
1426
-                    $pointer -= $this->getPointer() - $startpos;
1426
+                    $pointer -= $this->getPointer()-$startpos;
1427 1427
                 }
1428 1428
 
1429
-                if ($this->allowNestedComments && strpos($src, $this->ld . '*', $this->getPointer()) !== false) {
1430
-                    $comOpen  = $this->ld . '*';
1431
-                    $comClose = '*' . $this->rd;
1429
+                if ($this->allowNestedComments && strpos($src, $this->ld.'*', $this->getPointer()) !== false) {
1430
+                    $comOpen  = $this->ld.'*';
1431
+                    $comClose = '*'.$this->rd;
1432 1432
                     $level    = 1;
1433 1433
                     $ptr      = $this->getPointer();
1434 1434
 
@@ -1438,33 +1438,33 @@  discard block
 block discarded – undo
1438 1438
 
1439 1439
                         if ($open !== false && $close !== false) {
1440 1440
                             if ($open < $close) {
1441
-                                $ptr = $open + strlen($comOpen);
1442
-                                ++ $level;
1441
+                                $ptr = $open+strlen($comOpen);
1442
+                                ++$level;
1443 1443
                             } else {
1444
-                                $ptr = $close + strlen($comClose);
1445
-                                -- $level;
1444
+                                $ptr = $close+strlen($comClose);
1445
+                                --$level;
1446 1446
                             }
1447 1447
                         } elseif ($open !== false) {
1448
-                            $ptr = $open + strlen($comOpen);
1449
-                            ++ $level;
1448
+                            $ptr = $open+strlen($comOpen);
1449
+                            ++$level;
1450 1450
                         } elseif ($close !== false) {
1451
-                            $ptr = $close + strlen($comClose);
1452
-                            -- $level;
1451
+                            $ptr = $close+strlen($comClose);
1452
+                            --$level;
1453 1453
                         } else {
1454 1454
                             $ptr = strlen($src);
1455 1455
                         }
1456 1456
                     }
1457
-                    $endpos = $ptr - strlen('*' . $this->rd);
1457
+                    $endpos = $ptr-strlen('*'.$this->rd);
1458 1458
                 } else {
1459
-                    $endpos = strpos($src, '*' . $this->rd, $startpos);
1459
+                    $endpos = strpos($src, '*'.$this->rd, $startpos);
1460 1460
                     if ($endpos == false) {
1461 1461
                         throw new CompilationException($this, 'Un-ended comment');
1462 1462
                     }
1463 1463
                 }
1464
-                $pointer += $endpos - $startpos + strlen('*' . $this->rd);
1465
-                if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos + strlen('*' . $this->rd)), $m)) {
1464
+                $pointer += $endpos-$startpos+strlen('*'.$this->rd);
1465
+                if (isset($whitespaceStart) && preg_match('#^[\t ]*\r?\n#', substr($src, $endpos+strlen('*'.$this->rd)), $m)) {
1466 1466
                     $pointer += strlen($m[0]);
1467
-                    $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer']) - ($this->getPointer() - $startpos - strlen($this->ld)));
1467
+                    $this->curBlock['buffer'] = substr($this->curBlock['buffer'], 0, strlen($this->curBlock['buffer'])-($this->getPointer()-$startpos-strlen($this->ld)));
1468 1468
                 }
1469 1469
 
1470 1470
                 return false;
@@ -1481,20 +1481,20 @@  discard block
 block discarded – undo
1481 1481
         } elseif (($first === '"' || $first === "'") && !(is_array($parsingParams) && preg_match('#^([\'"])[a-z0-9_]+\1\s*=>?(?:\s+|[^=])#i', $substr))) {
1482 1482
             // string
1483 1483
             $out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer);
1484
-        } 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)) {
1484
+        } 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)) {
1485 1485
             // func
1486 1486
             $out    = $this->parseFunction($in, $from, $to, $parsingParams, $curBlock, $pointer);
1487 1487
             $parsed = 'func';
1488 1488
         } elseif ($first === ';') {
1489 1489
             // instruction end
1490 1490
             if ($this->debug) {
1491
-                echo 'END OF INSTRUCTION' . "\n";
1491
+                echo 'END OF INSTRUCTION'."\n";
1492 1492
             }
1493 1493
             if ($pointer !== null) {
1494
-                ++ $pointer;
1494
+                ++$pointer;
1495 1495
             }
1496 1496
 
1497
-            return $this->parse($in, $from + 1, $to, false, 'root', $pointer);
1497
+            return $this->parse($in, $from+1, $to, false, 'root', $pointer);
1498 1498
         } elseif ($curBlock === 'root' && preg_match('#^/([a-z_][a-z0-9_]*)?#i', $substr, $match)) {
1499 1499
             // close block
1500 1500
             if (!empty($match[1]) && $match[1] == 'else') {
@@ -1511,13 +1511,13 @@  discard block
 block discarded – undo
1511 1511
                     $pointer -= strlen($match[0]);
1512 1512
                 }
1513 1513
                 if ($this->debug) {
1514
-                    echo 'TOP BLOCK CLOSED' . "\n";
1514
+                    echo 'TOP BLOCK CLOSED'."\n";
1515 1515
                 }
1516 1516
 
1517 1517
                 return $this->removeTopBlock();
1518 1518
             } else {
1519 1519
                 if ($this->debug) {
1520
-                    echo 'BLOCK OF TYPE ' . $match[1] . ' CLOSED' . "\n";
1520
+                    echo 'BLOCK OF TYPE '.$match[1].' CLOSED'."\n";
1521 1521
                 }
1522 1522
 
1523 1523
                 return $this->removeBlock($match[1]);
@@ -1525,19 +1525,19 @@  discard block
 block discarded – undo
1525 1525
         } elseif ($curBlock === 'root' && substr($substr, 0, strlen($this->rd)) === $this->rd) {
1526 1526
             // end template tag
1527 1527
             if ($this->debug) {
1528
-                echo 'TAG PARSING ENDED' . "\n";
1528
+                echo 'TAG PARSING ENDED'."\n";
1529 1529
             }
1530 1530
             $pointer += strlen($this->rd);
1531 1531
 
1532 1532
             return false;
1533
-        } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*=' . ($curBlock === 'array' ? '>?' : '') . ')(?:\s+|[^=]).*#i', $substr, $match)) {
1533
+        } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*='.($curBlock === 'array' ? '>?' : '').')(?:\s+|[^=]).*#i', $substr, $match)) {
1534 1534
             // named parameter
1535 1535
             if ($this->debug) {
1536
-                echo 'NAMED PARAM FOUND' . "\n";
1536
+                echo 'NAMED PARAM FOUND'."\n";
1537 1537
             }
1538 1538
             $len = strlen($match[1]);
1539
-            while (substr($in, $from + $len, 1) === ' ') {
1540
-                ++ $len;
1539
+            while (substr($in, $from+$len, 1) === ' ') {
1540
+                ++$len;
1541 1541
             }
1542 1542
             if ($pointer !== null) {
1543 1543
                 $pointer += $len;
@@ -1545,7 +1545,7 @@  discard block
 block discarded – undo
1545 1545
 
1546 1546
             $output = array(
1547 1547
                 trim($match[1], " \t\r\n=>'\""),
1548
-                $this->parse($in, $from + $len, $to, false, 'namedparam', $pointer)
1548
+                $this->parse($in, $from+$len, $to, false, 'namedparam', $pointer)
1549 1549
             );
1550 1550
 
1551 1551
             $parsingParams[] = $output;
@@ -1566,31 +1566,31 @@  discard block
 block discarded – undo
1566 1566
             $out = $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1567 1567
         } else {
1568 1568
             // parse error
1569
-            throw new CompilationException($this, 'Parse error in "' . substr($in, $from, $to - $from) . '"');
1569
+            throw new CompilationException($this, 'Parse error in "'.substr($in, $from, $to-$from).'"');
1570 1570
         }
1571 1571
 
1572 1572
         if (empty($out)) {
1573 1573
             return '';
1574 1574
         }
1575 1575
 
1576
-        $substr = substr($in, $pointer, $to - $pointer);
1576
+        $substr = substr($in, $pointer, $to-$pointer);
1577 1577
 
1578 1578
         // var parsed, check if any var-extension applies
1579 1579
         if ($parsed === 'var') {
1580 1580
             if (preg_match('#^\s*([/%+*-])\s*([a-z0-9]|\$)#i', $substr, $match)) {
1581 1581
                 if ($this->debug) {
1582
-                    echo 'PARSING POST-VAR EXPRESSION ' . $substr . "\n";
1582
+                    echo 'PARSING POST-VAR EXPRESSION '.$substr."\n";
1583 1583
                 }
1584 1584
                 // parse expressions
1585
-                $pointer += strlen($match[0]) - 1;
1585
+                $pointer += strlen($match[0])-1;
1586 1586
                 if (is_array($parsingParams)) {
1587 1587
                     if ($match[2] == '$') {
1588 1588
                         $expr = $this->parseVar($in, $pointer, $to, array(), $curBlock, $pointer);
1589 1589
                     } else {
1590 1590
                         $expr = $this->parse($in, $pointer, $to, array(), 'expression', $pointer);
1591 1591
                     }
1592
-                    $out[count($out) - 1][0] .= $match[1] . $expr[0][0];
1593
-                    $out[count($out) - 1][1] .= $match[1] . $expr[0][1];
1592
+                    $out[count($out)-1][0] .= $match[1].$expr[0][0];
1593
+                    $out[count($out)-1][1] .= $match[1].$expr[0][1];
1594 1594
                 } else {
1595 1595
                     if ($match[2] == '$') {
1596 1596
                         $expr = $this->parseVar($in, $pointer, $to, false, $curBlock, $pointer);
@@ -1598,26 +1598,26 @@  discard block
 block discarded – undo
1598 1598
                         $expr = $this->parse($in, $pointer, $to, false, 'expression', $pointer);
1599 1599
                     }
1600 1600
                     if (is_array($out) && is_array($expr)) {
1601
-                        $out[0] .= $match[1] . $expr[0];
1602
-                        $out[1] .= $match[1] . $expr[1];
1601
+                        $out[0] .= $match[1].$expr[0];
1602
+                        $out[1] .= $match[1].$expr[1];
1603 1603
                     } elseif (is_array($out)) {
1604
-                        $out[0] .= $match[1] . $expr;
1605
-                        $out[1] .= $match[1] . $expr;
1604
+                        $out[0] .= $match[1].$expr;
1605
+                        $out[1] .= $match[1].$expr;
1606 1606
                     } elseif (is_array($expr)) {
1607
-                        $out .= $match[1] . $expr[0];
1607
+                        $out .= $match[1].$expr[0];
1608 1608
                     } else {
1609
-                        $out .= $match[1] . $expr;
1609
+                        $out .= $match[1].$expr;
1610 1610
                     }
1611 1611
                 }
1612 1612
             } elseif ($curBlock === 'root' && preg_match('#^(\s*(?:[+/*%-.]=|=|\+\+|--)\s*)(.*)#s', $substr, $match)) {
1613 1613
                 if ($this->debug) {
1614
-                    echo 'PARSING POST-VAR ASSIGNMENT ' . $substr . "\n";
1614
+                    echo 'PARSING POST-VAR ASSIGNMENT '.$substr."\n";
1615 1615
                 }
1616 1616
                 // parse assignment
1617 1617
                 $value    = $match[2];
1618 1618
                 $operator = trim($match[1]);
1619 1619
                 if (substr($value, 0, 1) == '=') {
1620
-                    throw new CompilationException($this, 'Unexpected "=" in <em>' . $substr . '</em>');
1620
+                    throw new CompilationException($this, 'Unexpected "=" in <em>'.$substr.'</em>');
1621 1621
                 }
1622 1622
 
1623 1623
                 if ($pointer !== null) {
@@ -1638,7 +1638,7 @@  discard block
 block discarded – undo
1638 1638
                         throw new CompilationException($this, 'Assignments require the "if" plugin to be accessible');
1639 1639
                     }
1640 1640
 
1641
-                    $parts  = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS . 'PluginIf', 'init'), 1);
1641
+                    $parts  = $this->mapParams($parts, array(Core::NAMESPACE_PLUGINS_BLOCKS.'PluginIf', 'init'), 1);
1642 1642
                     $tokens = $this->getParamTokens($parts);
1643 1643
                     $parts  = $this->getCompiledParams($parts);
1644 1644
 
@@ -1652,14 +1652,14 @@  discard block
 block discarded – undo
1652 1652
                 if ($this->autoEscape) {
1653 1653
                     $out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out);
1654 1654
                 }
1655
-                $out = self::PHP_OPEN . $echo . $out . $operator . implode(' ', $value) . self::PHP_CLOSE;
1655
+                $out = self::PHP_OPEN.$echo.$out.$operator.implode(' ', $value).self::PHP_CLOSE;
1656 1656
             } elseif ($curBlock === 'array' && is_array($parsingParams) && preg_match('#^(\s*=>?\s*)#', $substr, $match)) {
1657 1657
                 // parse namedparam with var as name (only for array)
1658 1658
                 if ($this->debug) {
1659
-                    echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND' . "\n";
1659
+                    echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND'."\n";
1660 1660
                 }
1661 1661
                 $len = strlen($match[1]);
1662
-                $var = $out[count($out) - 1];
1662
+                $var = $out[count($out)-1];
1663 1663
                 $pointer += $len;
1664 1664
 
1665 1665
                 $output = array($var[0], $this->parse($substr, $len, null, false, 'namedparam', $pointer));
@@ -1674,16 +1674,16 @@  discard block
 block discarded – undo
1674 1674
             // parse modifier on funcs or vars
1675 1675
             $srcPointer = $pointer;
1676 1676
             if (is_array($parsingParams)) {
1677
-                $tmp                     = $this->replaceModifiers(
1677
+                $tmp = $this->replaceModifiers(
1678 1678
                     array(
1679 1679
                     null,
1680 1680
                     null,
1681
-                    $out[count($out) - 1][0],
1681
+                    $out[count($out)-1][0],
1682 1682
                     $match[0]
1683 1683
                     ), $curBlock, $pointer
1684 1684
                 );
1685
-                $out[count($out) - 1][0] = $tmp;
1686
-                $out[count($out) - 1][1] .= substr($substr, $srcPointer, $srcPointer - $pointer);
1685
+                $out[count($out)-1][0] = $tmp;
1686
+                $out[count($out)-1][1] .= substr($substr, $srcPointer, $srcPointer-$pointer);
1687 1687
             } else {
1688 1688
                 $out = $this->replaceModifiers(array(null, null, $out, $match[0]), $curBlock, $pointer);
1689 1689
             }
@@ -1695,10 +1695,10 @@  discard block
 block discarded – undo
1695 1695
             $ptr = 0;
1696 1696
 
1697 1697
             if (is_array($parsingParams)) {
1698
-                $output = $this->parseMethodCall($out[count($out) - 1][1], $match[0], $curBlock, $ptr);
1698
+                $output = $this->parseMethodCall($out[count($out)-1][1], $match[0], $curBlock, $ptr);
1699 1699
 
1700
-                $out[count($out) - 1][0] = $output;
1701
-                $out[count($out) - 1][1] .= substr($match[0], 0, $ptr);
1700
+                $out[count($out)-1][0] = $output;
1701
+                $out[count($out)-1][1] .= substr($match[0], 0, $ptr);
1702 1702
             } else {
1703 1703
                 $out = $this->parseMethodCall($out, $match[0], $curBlock, $ptr);
1704 1704
             }
@@ -1707,7 +1707,7 @@  discard block
 block discarded – undo
1707 1707
         }
1708 1708
 
1709 1709
         if ($curBlock === 'root' && substr($out, 0, strlen(self::PHP_OPEN)) !== self::PHP_OPEN) {
1710
-            return self::PHP_OPEN . 'echo ' . $out . ';' . self::PHP_CLOSE;
1710
+            return self::PHP_OPEN.'echo '.$out.';'.self::PHP_CLOSE;
1711 1711
         } else {
1712 1712
             return $out;
1713 1713
         }
@@ -1733,11 +1733,11 @@  discard block
 block discarded – undo
1733 1733
     protected function parseFunction($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
1734 1734
     {
1735 1735
         $output = '';
1736
-        $cmdstr = substr($in, $from, $to - $from);
1737
-        preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*' . $this->rdr . '|\s*;)?/i', $cmdstr, $match);
1736
+        $cmdstr = substr($in, $from, $to-$from);
1737
+        preg_match('/^(\\\\?[a-z_](?:\\\\?[a-z0-9_]+)*(?:::[a-z_][a-z0-9_]*)?)(\s*'.$this->rdr.'|\s*;)?/i', $cmdstr, $match);
1738 1738
 
1739 1739
         if (empty($match[1])) {
1740
-            throw new CompilationException($this, 'Parse error, invalid function name : ' . substr($cmdstr, 0, 15));
1740
+            throw new CompilationException($this, 'Parse error, invalid function name : '.substr($cmdstr, 0, 15));
1741 1741
         }
1742 1742
 
1743 1743
         $func = $match[1];
@@ -1747,7 +1747,7 @@  discard block
 block discarded – undo
1747 1747
         }
1748 1748
 
1749 1749
         if ($this->debug) {
1750
-            echo 'FUNC FOUND (' . $func . ')' . "\n";
1750
+            echo 'FUNC FOUND ('.$func.')'."\n";
1751 1751
         }
1752 1752
 
1753 1753
         $paramsep = '';
@@ -1759,11 +1759,11 @@  discard block
 block discarded – undo
1759 1759
             $paramspos = $match[1][0][1];
1760 1760
             $paramsep  = substr($match[1][0][0], - 1) === '(' ? ')' : '';
1761 1761
             if ($paramsep === ')') {
1762
-                $paramspos += strlen($match[1][0][0]) - 1;
1762
+                $paramspos += strlen($match[1][0][0])-1;
1763 1763
                 if (substr($cmdstr, 0, 2) === 'if' || substr($cmdstr, 0, 6) === 'elseif') {
1764 1764
                     $paramsep = '';
1765 1765
                     if (strlen($match[1][0][0]) > 1) {
1766
-                        -- $paramspos;
1766
+                        --$paramspos;
1767 1767
                     }
1768 1768
                 }
1769 1769
             }
@@ -1788,8 +1788,8 @@  discard block
 block discarded – undo
1788 1788
                     return $this->parseOthers($in, $from, $to, $parsingParams, $curBlock, $pointer);
1789 1789
                 }
1790 1790
             }
1791
-            $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos - strlen($func)));
1792
-            $paramstr   = substr($cmdstr, $paramspos + 1);
1791
+            $whitespace = strlen(substr($cmdstr, strlen($func), $paramspos-strlen($func)));
1792
+            $paramstr   = substr($cmdstr, $paramspos+1);
1793 1793
             if (substr($paramstr, - 1, 1) === $paramsep) {
1794 1794
                 $paramstr = substr($paramstr, 0, - 1);
1795 1795
             }
@@ -1811,36 +1811,36 @@  discard block
 block discarded – undo
1811 1811
 
1812 1812
                             if ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === ')') {
1813 1813
                                 if ($this->debug) {
1814
-                                    echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT ' . $ptr . "\n";
1814
+                                    echo 'PARAM PARSING ENDED, ")" FOUND, POINTER AT '.$ptr."\n";
1815 1815
                                 }
1816 1816
                                 break 2;
1817 1817
                             } elseif ($paramstr[$ptr] === ';') {
1818
-                                ++ $ptr;
1818
+                                ++$ptr;
1819 1819
                                 if ($this->debug) {
1820
-                                    echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT ' . $ptr . "\n";
1820
+                                    echo 'PARAM PARSING ENDED, ";" FOUND, POINTER AT '.$ptr."\n";
1821 1821
                                 }
1822 1822
                                 break 2;
1823 1823
                             } elseif ($func !== 'if' && $func !== 'elseif' && $paramstr[$ptr] === '/') {
1824 1824
                                 if ($this->debug) {
1825
-                                    echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT ' . $ptr . "\n";
1825
+                                    echo 'PARAM PARSING ENDED, "/" FOUND, POINTER AT '.$ptr."\n";
1826 1826
                                 }
1827 1827
                                 break 2;
1828 1828
                             } elseif (substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
1829 1829
                                 if ($this->debug) {
1830
-                                    echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT ' . $ptr . "\n";
1830
+                                    echo 'PARAM PARSING ENDED, RIGHT DELIMITER FOUND, POINTER AT '.$ptr."\n";
1831 1831
                                 }
1832 1832
                                 break 2;
1833 1833
                             }
1834 1834
 
1835 1835
                             if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === ',' || $paramstr[$ptr] === "\r" || $paramstr[$ptr] === "\n" || $paramstr[$ptr] === "\t") {
1836
-                                ++ $ptr;
1836
+                                ++$ptr;
1837 1837
                             } else {
1838 1838
                                 break;
1839 1839
                             }
1840 1840
                         }
1841 1841
 
1842 1842
                         if ($this->debug) {
1843
-                            echo 'FUNC START PARAM PARSING WITH POINTER AT ' . $ptr . "\n";
1843
+                            echo 'FUNC START PARAM PARSING WITH POINTER AT '.$ptr."\n";
1844 1844
                         }
1845 1845
 
1846 1846
                         if ($func === 'if' || $func === 'elseif' || $func === 'tif') {
@@ -1852,7 +1852,7 @@  discard block
 block discarded – undo
1852 1852
                         }
1853 1853
 
1854 1854
                         if ($this->debug) {
1855
-                            echo 'PARAM PARSED, POINTER AT ' . $ptr . ' (' . substr($paramstr, $ptr - 1, 3) . ')' . "\n";
1855
+                            echo 'PARAM PARSED, POINTER AT '.$ptr.' ('.substr($paramstr, $ptr-1, 3).')'."\n";
1856 1856
                         }
1857 1857
                     }
1858 1858
                 }
@@ -1876,16 +1876,16 @@  discard block
 block discarded – undo
1876 1876
         }
1877 1877
 
1878 1878
         if ($pointer !== null) {
1879
-            $pointer += (isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func) + (isset($whitespace) ? $whitespace : 0);
1879
+            $pointer += (isset($paramstr) ? strlen($paramstr) : 0)+(')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1))+strlen($func)+(isset($whitespace) ? $whitespace : 0);
1880 1880
             if ($this->debug) {
1881
-                echo 'FUNC ADDS ' . ((isset($paramstr) ? strlen($paramstr) : 0) + (')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1)) + strlen($func)) . ' TO POINTER' . "\n";
1881
+                echo 'FUNC ADDS '.((isset($paramstr) ? strlen($paramstr) : 0)+(')' === $paramsep ? 2 : ($paramspos === false ? 0 : 1))+strlen($func)).' TO POINTER'."\n";
1882 1882
             }
1883 1883
         }
1884 1884
 
1885 1885
         if ($curBlock === 'method' || $func === 'do' || strstr($func, '::') !== false) {
1886 1886
             // handle static method calls with security policy
1887 1887
             if (strstr($func, '::') !== false && $this->securityPolicy !== null && $this->securityPolicy->isMethodAllowed(explode('::', strtolower($func))) !== true) {
1888
-                throw new SecurityException('Call to a disallowed php function : ' . $func);
1888
+                throw new SecurityException('Call to a disallowed php function : '.$func);
1889 1889
             }
1890 1890
             $pluginType = Core::NATIVE_PLUGIN;
1891 1891
         } else {
@@ -1930,19 +1930,19 @@  discard block
 block discarded – undo
1930 1930
                     $this->customPlugins[$func]['function']
1931 1931
                 ), $state);
1932 1932
             } else {
1933
-                if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
1933
+                if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) {
1934 1934
                     $params = $this->mapParams($params, array(
1935
-                        'Plugin' . Core::toCamelCase($func),
1935
+                        'Plugin'.Core::toCamelCase($func),
1936 1936
                         ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1937 1937
                     ), $state);
1938
-                } elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== false) {
1938
+                } elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func)) !== false) {
1939 1939
                     $params = $this->mapParams($params, array(
1940
-                        Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func),
1940
+                        Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func),
1941 1941
                         ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1942 1942
                     ), $state);
1943 1943
                 } else {
1944 1944
                     $params = $this->mapParams($params, array(
1945
-                        Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
1945
+                        Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func),
1946 1946
                         ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process'
1947 1947
                     ), $state);
1948 1948
                 }
@@ -1953,24 +1953,22 @@  discard block
 block discarded – undo
1953 1953
                 $params = $this->mapParams($params, $this->customPlugins[$func]['callback'], $state);
1954 1954
             } else {
1955 1955
                 // Custom plugin
1956
-                if (function_exists('Plugin' . Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ?
1956
+                if (function_exists('Plugin'.Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ?
1957 1957
                         'Compile' : '')) !== false) {
1958
-                    $params = $this->mapParams($params, 'Plugin' . Core::toCamelCase($func) . (($pluginType &
1958
+                    $params = $this->mapParams($params, 'Plugin'.Core::toCamelCase($func).(($pluginType &
1959 1959
                             Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1960 1960
                 } // Builtin helper plugin
1961
-                elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . (
1961
+                elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).(
1962 1962
                     ($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '')) !== false) {
1963
-                    $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase
1964
-                        ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1963
+                    $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1965 1964
                 } // Builtin function plugin
1966 1965
                 else {
1967
-                    $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase
1968
-                        ($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1966
+                    $params = $this->mapParams($params, Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''), $state);
1969 1967
                 }
1970 1968
             }
1971 1969
         } // Smarty modifier
1972 1970
         elseif ($pluginType & Core::SMARTY_MODIFIER) {
1973
-            $output = 'smarty_modifier_' . $func . '(' . implode(', ', $params) . ')';
1971
+            $output = 'smarty_modifier_'.$func.'('.implode(', ', $params).')';
1974 1972
         } // Proxy plugin
1975 1973
         elseif ($pluginType & Core::PROXY_PLUGIN) {
1976 1974
             $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state);
@@ -2010,19 +2008,19 @@  discard block
 block discarded – undo
2010 2008
             if ($func === 'do') {
2011 2009
                 $output = '';
2012 2010
                 if (isset($params['*'])) {
2013
-                    $output = implode(';', $params['*']) . ';';
2011
+                    $output = implode(';', $params['*']).';';
2014 2012
                 }
2015 2013
 
2016 2014
                 if (is_array($parsingParams) || $curBlock !== 'root') {
2017 2015
                     throw new CompilationException($this, 'Do can not be used inside another function or block');
2018 2016
                 }
2019 2017
 
2020
-                return self::PHP_OPEN . $output . self::PHP_CLOSE;
2018
+                return self::PHP_OPEN.$output.self::PHP_CLOSE;
2021 2019
             } else {
2022 2020
                 if (isset($params['*'])) {
2023
-                    $output = $func . '(' . implode(', ', $params['*']) . ')';
2021
+                    $output = $func.'('.implode(', ', $params['*']).')';
2024 2022
                 } else {
2025
-                    $output = $func . '()';
2023
+                    $output = $func.'()';
2026 2024
                 }
2027 2025
             }
2028 2026
         } // Block class OR Function class
@@ -2032,7 +2030,7 @@  discard block
 block discarded – undo
2032 2030
                     $callback = $this->customPlugins[$func]['callback'];
2033 2031
                     if (!is_array($callback)) {
2034 2032
                         if (!method_exists($callback, 'compile')) {
2035
-                            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');
2033
+                            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');
2036 2034
                         }
2037 2035
                         if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) {
2038 2036
                             $funcCompiler = array($callback, 'compile');
@@ -2043,13 +2041,13 @@  discard block
 block discarded – undo
2043 2041
                         $funcCompiler = $callback;
2044 2042
                     }
2045 2043
                 } else {
2046
-                    if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2047
-                        $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile');
2048
-                    } elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !== false) {
2049
-                        $funcCompiler = array(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func), 'compile');
2044
+                    if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) {
2045
+                        $funcCompiler = array('Plugin'.Core::toCamelCase($func), 'compile');
2046
+                    } elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func)) !== false) {
2047
+                        $funcCompiler = array(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func), 'compile');
2050 2048
                     } else {
2051 2049
                         $funcCompiler = array(
2052
-                            Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
2050
+                            Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func),
2053 2051
                             'compile'
2054 2052
                         );
2055 2053
                     }
@@ -2066,31 +2064,31 @@  discard block
 block discarded – undo
2066 2064
                     $callback = $this->customPlugins[$func]['callback'];
2067 2065
                     if (!is_array($callback)) {
2068 2066
                         if (!method_exists($callback, 'process')) {
2069
-                            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');
2067
+                            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');
2070 2068
                         }
2071 2069
                         if (($ref = new ReflectionMethod($callback, 'process')) && $ref->isStatic()) {
2072
-                            $output = 'call_user_func(array(\'' . $callback . '\', \'process\'), ' . $params . ')';
2070
+                            $output = 'call_user_func(array(\''.$callback.'\', \'process\'), '.$params.')';
2073 2071
                         } else {
2074
-                            $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback . '\'), \'process\'), ' . $params . ')';
2072
+                            $output = 'call_user_func(array($this->getObjectPlugin(\''.$callback.'\'), \'process\'), '.$params.')';
2075 2073
                         }
2076 2074
                     } elseif (is_object($callback[0])) {
2077
-                        $output = 'call_user_func(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), ' . $params . ')';
2075
+                        $output = 'call_user_func(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), '.$params.')';
2078 2076
                     } elseif (($ref = new ReflectionMethod($callback[0], $callback[1])) && $ref->isStatic()) {
2079
-                        $output = 'call_user_func(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), ' . $params . ')';
2077
+                        $output = 'call_user_func(array(\''.$callback[0].'\', \''.$callback[1].'\'), '.$params.')';
2080 2078
                     } else {
2081
-                        $output = 'call_user_func(array($this->getObjectPlugin(\'' . $callback[0] . '\'), \'' . $callback[1] . '\'), ' . $params . ')';
2079
+                        $output = 'call_user_func(array($this->getObjectPlugin(\''.$callback[0].'\'), \''.$callback[1].'\'), '.$params.')';
2082 2080
                     }
2083 2081
                     if (empty($params)) {
2084
-                        $output = substr($output, 0, - 3) . ')';
2082
+                        $output = substr($output, 0, - 3).')';
2085 2083
                     }
2086 2084
                 } else {
2087
-                    if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2088
-                        $output = '$this->classCall(\'Plugin' . $func . '\', array(' . $params . '))';
2089
-                    } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== false) {
2090
-                        $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', 
2091
-                        array(' . $params . '))';
2085
+                    if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) {
2086
+                        $output = '$this->classCall(\'Plugin'.$func.'\', array('.$params.'))';
2087
+                    } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func)) !== false) {
2088
+                        $output = '$this->classCall(\''.Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.$func.'\', 
2089
+                        array(' . $params.'))';
2092 2090
                     } else {
2093
-                        $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))';
2091
+                        $output = '$this->classCall(\''.$func.'\', array('.$params.'))';
2094 2092
                     }
2095 2093
                 }
2096 2094
             }
@@ -2101,15 +2099,15 @@  discard block
 block discarded – undo
2101 2099
                     $funcCompiler = $this->customPlugins[$func]['callback'];
2102 2100
                 } else {
2103 2101
                     // Custom plugin
2104
-                    if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
2105
-                        $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile';
2102
+                    if (function_exists('Plugin'.Core::toCamelCase($func).'Compile') !== false) {
2103
+                        $funcCompiler = 'Plugin'.Core::toCamelCase($func).'Compile';
2106 2104
                     } // Builtin helper plugin
2107
-                    elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
2108
-                        $funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) .
2105
+                    elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).'Compile') !== false) {
2106
+                        $funcCompiler = Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).
2109 2107
                             'Compile';
2110 2108
                     } // Builtin function plugin
2111 2109
                     else {
2112
-                        $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) .
2110
+                        $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).
2113 2111
                             'Compile';
2114 2112
                     }
2115 2113
                 }
@@ -2125,24 +2123,24 @@  discard block
 block discarded – undo
2125 2123
                 if ($pluginType & Core::CUSTOM_PLUGIN) {
2126 2124
                     $callback = $this->customPlugins[$func]['callback'];
2127 2125
                     if ($callback instanceof Closure) {
2128
-                        $output = 'call_user_func($this->getCustomPlugin(\'' . $func . '\'), ' . $params . ')';
2126
+                        $output = 'call_user_func($this->getCustomPlugin(\''.$func.'\'), '.$params.')';
2129 2127
                     } else {
2130
-                        $output = 'call_user_func(\'' . $callback . '\', ' . $params . ')';
2128
+                        $output = 'call_user_func(\''.$callback.'\', '.$params.')';
2131 2129
                     }
2132 2130
                 } else {
2133 2131
                     // Custom plugin
2134
-                    if (function_exists('Plugin' . Core::toCamelCase($func)) !== false) {
2135
-                        $output = 'Plugin' . Core::toCamelCase($func) . '(' . $params .
2132
+                    if (function_exists('Plugin'.Core::toCamelCase($func)) !== false) {
2133
+                        $output = 'Plugin'.Core::toCamelCase($func).'('.$params.
2136 2134
                             ')';
2137 2135
                     } // Builtin helper plugin
2138
-                    elseif(function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func)) !==
2136
+                    elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func)) !==
2139 2137
                         false) {
2140
-                        $output = Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($func) . '(' .
2141
-                            $params . ')';
2138
+                        $output = Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($func).'('.
2139
+                            $params.')';
2142 2140
                     } // Builtin function plugin
2143 2141
                     else {
2144
-                        $output = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '(' .
2145
-                            $params . ')';
2142
+                        $output = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).'('.
2143
+                            $params.')';
2146 2144
                     }
2147 2145
                 }
2148 2146
             }
@@ -2160,22 +2158,22 @@  discard block
 block discarded – undo
2160 2158
                 $callback = $this->customPlugins[$func]['callback'];
2161 2159
                 if (is_array($callback)) {
2162 2160
                     if (is_object($callback[0])) {
2163
-                        $output = 'call_user_func_array(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
2161
+                        $output = 'call_user_func_array(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), array(array('.$params.'), $this))';
2164 2162
                     } else {
2165
-                        $output = 'call_user_func_array(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(array(' . $params . '), $this))';
2163
+                        $output = 'call_user_func_array(array(\''.$callback[0].'\', \''.$callback[1].'\'), array(array('.$params.'), $this))';
2166 2164
                     }
2167 2165
                 } else {
2168
-                    $output = $callback . '(array(' . $params . '), $this)';
2166
+                    $output = $callback.'(array('.$params.'), $this)';
2169 2167
                 }
2170 2168
             } else {
2171
-                $output = 'smarty_function_' . $func . '(array(' . $params . '), $this)';
2169
+                $output = 'smarty_function_'.$func.'(array('.$params.'), $this)';
2172 2170
             }
2173 2171
         } // Template plugin
2174 2172
         elseif ($pluginType & Core::TEMPLATE_PLUGIN) {
2175 2173
             array_unshift($params, '$this');
2176 2174
             $params                                 = self::implode_r($params);
2177
-            $output                                 = 'Plugin' . Core::toCamelCase($func) .
2178
-                $this->templatePlugins[$func]['uuid'] . '(' . $params . ')';
2175
+            $output                                 = 'Plugin'.Core::toCamelCase($func).
2176
+                $this->templatePlugins[$func]['uuid'].'('.$params.')';
2179 2177
             $this->templatePlugins[$func]['called'] = true;
2180 2178
         }
2181 2179
 
@@ -2207,29 +2205,29 @@  discard block
 block discarded – undo
2207 2205
      */
2208 2206
     protected function parseString($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2209 2207
     {
2210
-        $substr = substr($in, $from, $to - $from);
2208
+        $substr = substr($in, $from, $to-$from);
2211 2209
         $first  = $substr[0];
2212 2210
 
2213 2211
         if ($this->debug) {
2214
-            echo 'STRING FOUND (in ' . htmlentities(substr($in, $from, min($to - $from, 50))) . (($to - $from) > 50 ? '...' : '') . ')' . "\n";
2212
+            echo 'STRING FOUND (in '.htmlentities(substr($in, $from, min($to-$from, 50))).(($to-$from) > 50 ? '...' : '').')'."\n";
2215 2213
         }
2216 2214
         $strend = false;
2217
-        $o      = $from + 1;
2215
+        $o      = $from+1;
2218 2216
         while ($strend === false) {
2219 2217
             $strend = strpos($in, $first, $o);
2220 2218
             if ($strend === false) {
2221
-                throw new CompilationException($this, 'Unfinished string, started with ' . substr($in, $from, $to - $from));
2219
+                throw new CompilationException($this, 'Unfinished string, started with '.substr($in, $from, $to-$from));
2222 2220
             }
2223
-            if (substr($in, $strend - 1, 1) === '\\') {
2224
-                $o      = $strend + 1;
2221
+            if (substr($in, $strend-1, 1) === '\\') {
2222
+                $o      = $strend+1;
2225 2223
                 $strend = false;
2226 2224
             }
2227 2225
         }
2228 2226
         if ($this->debug) {
2229
-            echo 'STRING DELIMITED: ' . substr($in, $from, $strend + 1 - $from) . "\n";
2227
+            echo 'STRING DELIMITED: '.substr($in, $from, $strend+1-$from)."\n";
2230 2228
         }
2231 2229
 
2232
-        $srcOutput = substr($in, $from, $strend + 1 - $from);
2230
+        $srcOutput = substr($in, $from, $strend+1-$from);
2233 2231
 
2234 2232
         if ($pointer !== null) {
2235 2233
             $pointer += strlen($srcOutput);
@@ -2238,13 +2236,13 @@  discard block
 block discarded – undo
2238 2236
         $output = $this->replaceStringVars($srcOutput, $first);
2239 2237
 
2240 2238
         // handle modifiers
2241
-        if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend + 1 - $from), $match)) {
2239
+        if ($curBlock !== 'modifier' && preg_match('#^((?:\|(?:@?[a-z0-9_]+(?::.*)*))+)#i', substr($substr, $strend+1-$from), $match)) {
2242 2240
             $modstr = $match[1];
2243 2241
 
2244 2242
             if ($curBlock === 'root' && substr($modstr, - 1) === '}') {
2245 2243
                 $modstr = substr($modstr, 0, - 1);
2246 2244
             }
2247
-            $modstr = str_replace('\\' . $first, $first, $modstr);
2245
+            $modstr = str_replace('\\'.$first, $first, $modstr);
2248 2246
             $ptr    = 0;
2249 2247
             $output = $this->replaceModifiers(array(null, null, $output, $modstr), 'string', $ptr);
2250 2248
 
@@ -2252,7 +2250,7 @@  discard block
 block discarded – undo
2252 2250
             if ($pointer !== null) {
2253 2251
                 $pointer += $ptr;
2254 2252
             }
2255
-            $srcOutput .= substr($substr, $strend + 1 - $from, $ptr);
2253
+            $srcOutput .= substr($substr, $strend+1-$from, $ptr);
2256 2254
         }
2257 2255
 
2258 2256
         if (is_array($parsingParams)) {
@@ -2283,10 +2281,10 @@  discard block
 block discarded – undo
2283 2281
      */
2284 2282
     protected function parseConst($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2285 2283
     {
2286
-        $substr = substr($in, $from, $to - $from);
2284
+        $substr = substr($in, $from, $to-$from);
2287 2285
 
2288 2286
         if ($this->debug) {
2289
-            echo 'CONST FOUND : ' . $substr . "\n";
2287
+            echo 'CONST FOUND : '.$substr."\n";
2290 2288
         }
2291 2289
 
2292 2290
         if (!preg_match('#^%([\\\\a-z0-9_:]+)#i', $substr, $m)) {
@@ -2325,7 +2323,7 @@  discard block
 block discarded – undo
2325 2323
         }
2326 2324
 
2327 2325
         if ($curBlock !== 'root') {
2328
-            $output = '(defined("' . $key . '") ? ' . $key . ' : null)';
2326
+            $output = '(defined("'.$key.'") ? '.$key.' : null)';
2329 2327
         } else {
2330 2328
             $output = $key;
2331 2329
         }
@@ -2350,7 +2348,7 @@  discard block
 block discarded – undo
2350 2348
      */
2351 2349
     protected function parseVar($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2352 2350
     {
2353
-        $substr = substr($in, $from, $to - $from);
2351
+        $substr = substr($in, $from, $to-$from);
2354 2352
 
2355 2353
         // var key
2356 2354
         $varRegex = '(\\$?\\.?[a-z0-9\\\\_:]*(?:(?:(?:\\.|->)(?:[a-z0-9\\\\_:]+|(?R))|\\[(?:[a-z0-9\\\\_:]+|(?R)|(["\'])[^\\2]*?\\2)\\]))*)';
@@ -2378,13 +2376,13 @@  discard block
 block discarded – undo
2378 2376
 
2379 2377
             if (substr($key, - 1) == '.') {
2380 2378
                 $key = substr($key, 0, - 1);
2381
-                -- $matchedLength;
2379
+                --$matchedLength;
2382 2380
             }
2383 2381
 
2384 2382
             if ($hasMethodCall) {
2385
-                $matchedLength -= strlen($match[3]) + strlen(substr($match[1], strrpos($match[1], '->')));
2386
-                $key        = substr($match[1], 1, strrpos($match[1], '->') - 1);
2387
-                $methodCall = substr($match[1], strrpos($match[1], '->')) . $match[3];
2383
+                $matchedLength -= strlen($match[3])+strlen(substr($match[1], strrpos($match[1], '->')));
2384
+                $key        = substr($match[1], 1, strrpos($match[1], '->')-1);
2385
+                $methodCall = substr($match[1], strrpos($match[1], '->')).$match[3];
2388 2386
             }
2389 2387
 
2390 2388
             if ($hasModifiers) {
@@ -2400,9 +2398,9 @@  discard block
 block discarded – undo
2400 2398
 
2401 2399
             if ($this->debug) {
2402 2400
                 if ($hasMethodCall) {
2403
-                    echo 'METHOD CALL FOUND : $' . $key . substr($methodCall, 0, 30) . "\n";
2401
+                    echo 'METHOD CALL FOUND : $'.$key.substr($methodCall, 0, 30)."\n";
2404 2402
                 } else {
2405
-                    echo 'VAR FOUND : $' . $key . "\n";
2403
+                    echo 'VAR FOUND : $'.$key."\n";
2406 2404
                 }
2407 2405
             }
2408 2406
 
@@ -2413,7 +2411,7 @@  discard block
 block discarded – undo
2413 2411
                 $uid           = 0;
2414 2412
                 $parsed        = array($uid => '');
2415 2413
                 $current       = &$parsed;
2416
-                $curTxt        = &$parsed[$uid ++];
2414
+                $curTxt        = &$parsed[$uid++];
2417 2415
                 $tree          = array();
2418 2416
                 $chars         = str_split($key, 1);
2419 2417
                 $inSplittedVar = false;
@@ -2422,33 +2420,33 @@  discard block
 block discarded – undo
2422 2420
                 while (($char = array_shift($chars)) !== null) {
2423 2421
                     if ($char === '[') {
2424 2422
                         if (count($tree) > 0) {
2425
-                            ++ $bracketCount;
2423
+                            ++$bracketCount;
2426 2424
                         } else {
2427 2425
                             $tree[]        = &$current;
2428
-                            $current[$uid] = array($uid + 1 => '');
2429
-                            $current       = &$current[$uid ++];
2430
-                            $curTxt        = &$current[$uid ++];
2426
+                            $current[$uid] = array($uid+1 => '');
2427
+                            $current       = &$current[$uid++];
2428
+                            $curTxt        = &$current[$uid++];
2431 2429
                             continue;
2432 2430
                         }
2433 2431
                     } elseif ($char === ']') {
2434 2432
                         if ($bracketCount > 0) {
2435
-                            -- $bracketCount;
2433
+                            --$bracketCount;
2436 2434
                         } else {
2437
-                            $current = &$tree[count($tree) - 1];
2435
+                            $current = &$tree[count($tree)-1];
2438 2436
                             array_pop($tree);
2439 2437
                             if (current($chars) !== '[' && current($chars) !== false && current($chars) !== ']') {
2440 2438
                                 $current[$uid] = '';
2441
-                                $curTxt        = &$current[$uid ++];
2439
+                                $curTxt        = &$current[$uid++];
2442 2440
                             }
2443 2441
                             continue;
2444 2442
                         }
2445 2443
                     } elseif ($char === '$') {
2446 2444
                         if (count($tree) == 0) {
2447
-                            $curTxt        = &$current[$uid ++];
2445
+                            $curTxt        = &$current[$uid++];
2448 2446
                             $inSplittedVar = true;
2449 2447
                         }
2450 2448
                     } elseif (($char === '.' || $char === '-') && count($tree) == 0 && $inSplittedVar) {
2451
-                        $curTxt        = &$current[$uid ++];
2449
+                        $curTxt        = &$current[$uid++];
2452 2450
                         $inSplittedVar = false;
2453 2451
                     }
2454 2452
 
@@ -2457,16 +2455,16 @@  discard block
 block discarded – undo
2457 2455
                 unset($uid, $current, $curTxt, $tree, $chars);
2458 2456
 
2459 2457
                 if ($this->debug) {
2460
-                    echo 'RECURSIVE VAR REPLACEMENT : ' . $key . "\n";
2458
+                    echo 'RECURSIVE VAR REPLACEMENT : '.$key."\n";
2461 2459
                 }
2462 2460
 
2463 2461
                 $key = $this->flattenVarTree($parsed);
2464 2462
 
2465 2463
                 if ($this->debug) {
2466
-                    echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n";
2464
+                    echo 'RECURSIVE VAR REPLACEMENT DONE : '.$key."\n";
2467 2465
                 }
2468 2466
 
2469
-                $output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("' . $key . '")');
2467
+                $output = preg_replace('#(^""\.|""\.|\.""$|(\()""\.|\.""(\)))#', '$2$3', '$this->readVar("'.$key.'")');
2470 2468
             } else {
2471 2469
                 $output = $this->parseVarKey($key, $hasModifiers ? 'modifier' : $curBlock);
2472 2470
             }
@@ -2491,10 +2489,10 @@  discard block
 block discarded – undo
2491 2489
                     if (substr($expMatch[2][$k], 0, 1) === '=') {
2492 2490
                         $assign = true;
2493 2491
                         if ($operator === '=') {
2494
-                            throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, can not use "==" in expressions');
2492
+                            throw new CompilationException($this, 'Invalid expression <em>'.$substr.'</em>, can not use "==" in expressions');
2495 2493
                         }
2496 2494
                         if ($curBlock !== 'root') {
2497
-                            throw new CompilationException($this, 'Invalid expression <em>' . $substr . '</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}');
2495
+                            throw new CompilationException($this, 'Invalid expression <em>'.$substr.'</em>, assignments can only be used in top level expressions like {$foo+=3} or {$foo="bar"}');
2498 2496
                         }
2499 2497
                         $operator .= '=';
2500 2498
                         $expMatch[2][$k] = substr($expMatch[2][$k], 1);
@@ -2505,22 +2503,22 @@  discard block
 block discarded – undo
2505 2503
                         $expMatch[2][$k] = substr($expMatch[2][$k], 1);
2506 2504
                     }
2507 2505
                     if (($operator === '+' || $operator === '-') && $expMatch[2][$k] === $operator) {
2508
-                        $output = '(' . $output . $operator . $operator . ')';
2506
+                        $output = '('.$output.$operator.$operator.')';
2509 2507
                         break;
2510 2508
                     } elseif (substr($expMatch[2][$k], 0, 1) === '$') {
2511
-                        $output = '(' . $output . ' ' . $operator . ' ' . $this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')';
2509
+                        $output = '('.$output.' '.$operator.' '.$this->parseVar($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression').')';
2512 2510
                     } elseif (substr($expMatch[2][$k], 0, 1) === '%') {
2513
-                        $output = '(' . $output . ' ' . $operator . ' ' . $this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression') . ')';
2511
+                        $output = '('.$output.' '.$operator.' '.$this->parseConst($expMatch[2][$k], 0, strlen($expMatch[2][$k]), false, 'expression').')';
2514 2512
                     } elseif (!empty($expMatch[2][$k])) {
2515
-                        $output = '(' . $output . ' ' . $operator . ' ' . str_replace(',', '.', $expMatch[2][$k]) . ')';
2513
+                        $output = '('.$output.' '.$operator.' '.str_replace(',', '.', $expMatch[2][$k]).')';
2516 2514
                     } else {
2517
-                        throw new CompilationException($this, 'Unfinished expression <em>' . $substr . '</em>, missing var or number after math operator');
2515
+                        throw new CompilationException($this, 'Unfinished expression <em>'.$substr.'</em>, missing var or number after math operator');
2518 2516
                     }
2519 2517
                 }
2520 2518
             }
2521 2519
 
2522 2520
             if ($this->autoEscape === true && $curBlock !== 'condition') {
2523
-                $output = '(is_string($tmp=' . $output . ') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)';
2521
+                $output = '(is_string($tmp='.$output.') ? htmlspecialchars($tmp, ENT_QUOTES, $this->charset) : $tmp)';
2524 2522
             }
2525 2523
 
2526 2524
             // handle modifiers
@@ -2544,7 +2542,7 @@  discard block
 block discarded – undo
2544 2542
             } elseif ($curBlock === 'expression' || $curBlock === 'variable') {
2545 2543
                 return $output;
2546 2544
             } elseif (isset($assign)) {
2547
-                return self::PHP_OPEN . $output . ';' . self::PHP_CLOSE;
2545
+                return self::PHP_OPEN.$output.';'.self::PHP_CLOSE;
2548 2546
             } else {
2549 2547
                 return $output;
2550 2548
             }
@@ -2552,7 +2550,7 @@  discard block
 block discarded – undo
2552 2550
             if ($curBlock === 'string' || $curBlock === 'delimited_string') {
2553 2551
                 return array(0, '');
2554 2552
             } else {
2555
-                throw new CompilationException($this, 'Invalid variable name <em>' . $substr . '</em>');
2553
+                throw new CompilationException($this, 'Invalid variable name <em>'.$substr.'</em>');
2556 2554
             }
2557 2555
         }
2558 2556
     }
@@ -2607,16 +2605,16 @@  discard block
 block discarded – undo
2607 2605
             if (empty($methMatch[2])) {
2608 2606
                 // property
2609 2607
                 if ($curBlock === 'root') {
2610
-                    $output .= '->' . $methMatch[1];
2608
+                    $output .= '->'.$methMatch[1];
2611 2609
                 } else {
2612
-                    $output = '(($tmp = ' . $output . ') ? $tmp->' . $methMatch[1] . ' : null)';
2610
+                    $output = '(($tmp = '.$output.') ? $tmp->'.$methMatch[1].' : null)';
2613 2611
                 }
2614 2612
                 $ptr += strlen($methMatch[1]);
2615 2613
             } else {
2616 2614
                 // method
2617 2615
                 if (substr($methMatch[2], 0, 2) === '()') {
2618
-                    $parsedCall = $methMatch[1] . '()';
2619
-                    $ptr += strlen($methMatch[1]) + 2;
2616
+                    $parsedCall = $methMatch[1].'()';
2617
+                    $ptr += strlen($methMatch[1])+2;
2620 2618
                 } else {
2621 2619
                     $parsedCall = $this->parseFunction($methodCall, $ptr, strlen($methodCall), false, 'method', $ptr);
2622 2620
                 }
@@ -2625,15 +2623,15 @@  discard block
 block discarded – undo
2625 2623
                     $method = strtolower(substr($parsedCall, 0, $argPos));
2626 2624
                     $args   = substr($parsedCall, $argPos);
2627 2625
                     if ($curBlock === 'root') {
2628
-                        $output = '$this->getSecurityPolicy()->callMethod($this, ' . $output . ', ' . var_export($method, true) . ', array' . $args . ')';
2626
+                        $output = '$this->getSecurityPolicy()->callMethod($this, '.$output.', '.var_export($method, true).', array'.$args.')';
2629 2627
                     } else {
2630
-                        $output = '(($tmp = ' . $output . ') ? $this->getSecurityPolicy()->callMethod($this, $tmp, ' . var_export($method, true) . ', array' . $args . ') : null)';
2628
+                        $output = '(($tmp = '.$output.') ? $this->getSecurityPolicy()->callMethod($this, $tmp, '.var_export($method, true).', array'.$args.') : null)';
2631 2629
                     }
2632 2630
                 } else {
2633 2631
                     if ($curBlock === 'root') {
2634
-                        $output .= '->' . $parsedCall;
2632
+                        $output .= '->'.$parsedCall;
2635 2633
                     } else {
2636
-                        $output = '(($tmp = ' . $output . ') ? $tmp->' . $parsedCall . ' : null)';
2634
+                        $output = '(($tmp = '.$output.') ? $tmp->'.$parsedCall.' : null)';
2637 2635
                     }
2638 2636
                 }
2639 2637
             }
@@ -2659,21 +2657,21 @@  discard block
 block discarded – undo
2659 2657
             return '$this->scope';
2660 2658
         }
2661 2659
         if (substr($key, 0, 1) === '.') {
2662
-            $key = 'dwoo' . $key;
2660
+            $key = 'dwoo'.$key;
2663 2661
         }
2664 2662
         if (preg_match('#dwoo\.(get|post|server|cookies|session|env|request)((?:\.[a-z0-9_-]+)+)#i', $key, $m)) {
2665 2663
             $global = strtoupper($m[1]);
2666 2664
             if ($global === 'COOKIES') {
2667 2665
                 $global = 'COOKIE';
2668 2666
             }
2669
-            $key = '$_' . $global;
2667
+            $key = '$_'.$global;
2670 2668
             foreach (explode('.', ltrim($m[2], '.')) as $part) {
2671
-                $key .= '[' . var_export($part, true) . ']';
2669
+                $key .= '['.var_export($part, true).']';
2672 2670
             }
2673 2671
             if ($curBlock === 'root') {
2674 2672
                 $output = $key;
2675 2673
             } else {
2676
-                $output = '(isset(' . $key . ')?' . $key . ':null)';
2674
+                $output = '(isset('.$key.')?'.$key.':null)';
2677 2675
             }
2678 2676
         } elseif (preg_match('#dwoo\\.const\\.([a-z0-9\\\\_:]+)#i', $key, $m)) {
2679 2677
             return $this->parseConstKey($m[1], $curBlock);
@@ -2689,9 +2687,9 @@  discard block
 block discarded – undo
2689 2687
                     $output = '$tmp_key';
2690 2688
                 } else {
2691 2689
                     if ($curBlock === 'root') {
2692
-                        $output = '$this->scope["' . $key . '"]';
2690
+                        $output = '$this->scope["'.$key.'"]';
2693 2691
                     } else {
2694
-                        $output = '(isset($this->scope["' . $key . '"]) ? $this->scope["' . $key . '"] : null)';
2692
+                        $output = '(isset($this->scope["'.$key.'"]) ? $this->scope["'.$key.'"] : null)';
2695 2693
                     }
2696 2694
                 }
2697 2695
             } else {
@@ -2702,7 +2700,7 @@  discard block
 block discarded – undo
2702 2700
                     $parentCnt = 0;
2703 2701
 
2704 2702
                     while (true) {
2705
-                        ++ $parentCnt;
2703
+                        ++$parentCnt;
2706 2704
                         array_shift($m[2]);
2707 2705
                         array_shift($m[1]);
2708 2706
                         if (current($m[2]) === '_parent') {
@@ -2711,7 +2709,7 @@  discard block
 block discarded – undo
2711 2709
                         break;
2712 2710
                     }
2713 2711
 
2714
-                    $output = '$this->readParentVar(' . $parentCnt . ')';
2712
+                    $output = '$this->readParentVar('.$parentCnt.')';
2715 2713
                 } else {
2716 2714
                     if ($i === 'dwoo') {
2717 2715
                         $output = '$this->globals';
@@ -2730,28 +2728,28 @@  discard block
 block discarded – undo
2730 2728
                     while (count($m[1]) && $m[1][0] !== '->') {
2731 2729
                         $m[2][0] = preg_replace('/(^\\\([\'"])|\\\([\'"])$)/x', '$2$3', $m[2][0]);
2732 2730
                         if (substr($m[2][0], 0, 1) == '"' || substr($m[2][0], 0, 1) == "'") {
2733
-                            $output .= '[' . $m[2][0] . ']';
2731
+                            $output .= '['.$m[2][0].']';
2734 2732
                         } else {
2735
-                            $output .= '["' . $m[2][0] . '"]';
2733
+                            $output .= '["'.$m[2][0].'"]';
2736 2734
                         }
2737 2735
                         array_shift($m[2]);
2738 2736
                         array_shift($m[1]);
2739 2737
                     }
2740 2738
 
2741 2739
                     if ($curBlock !== 'root') {
2742
-                        $output = '(isset(' . $output . ') ? ' . $output . ':null)';
2740
+                        $output = '(isset('.$output.') ? '.$output.':null)';
2743 2741
                     }
2744 2742
                 }
2745 2743
 
2746 2744
                 if (count($m[2])) {
2747 2745
                     unset($m[0]);
2748
-                    $output = '$this->readVarInto(' . str_replace("\n", '', var_export($m, true)) . ', ' . $output . ', ' . ($curBlock == 'root' ? 'false' : 'true') . ')';
2746
+                    $output = '$this->readVarInto('.str_replace("\n", '', var_export($m, true)).', '.$output.', '.($curBlock == 'root' ? 'false' : 'true').')';
2749 2747
                 }
2750 2748
             }
2751 2749
         } else {
2752 2750
             preg_match_all('#(\[|->|\.)?((?:[a-z0-9_]|-(?!>))+)\]?#i', $key, $m);
2753 2751
             unset($m[0]);
2754
-            $output = '$this->readVar(' . str_replace("\n", '', var_export($m, true)) . ')';
2752
+            $output = '$this->readVar('.str_replace("\n", '', var_export($m, true)).')';
2755 2753
         }
2756 2754
 
2757 2755
         return $output;
@@ -2771,38 +2769,38 @@  discard block
 block discarded – undo
2771 2769
         $out = $recursed ? '".$this->readVarInto(' : '';
2772 2770
         foreach ($tree as $bit) {
2773 2771
             if (is_array($bit)) {
2774
-                $out .= '.' . $this->flattenVarTree($bit, false);
2772
+                $out .= '.'.$this->flattenVarTree($bit, false);
2775 2773
             } else {
2776 2774
                 $key = str_replace('"', '\\"', $bit);
2777 2775
 
2778 2776
                 if (substr($key, 0, 1) === '$') {
2779
-                    $out .= '".' . $this->parseVar($key, 0, strlen($key), false, 'variable') . '."';
2777
+                    $out .= '".'.$this->parseVar($key, 0, strlen($key), false, 'variable').'."';
2780 2778
                 } else {
2781 2779
                     $cnt = substr_count($key, '$');
2782 2780
 
2783 2781
                     if ($this->debug) {
2784
-                        echo 'PARSING SUBVARS IN : ' . $key . "\n";
2782
+                        echo 'PARSING SUBVARS IN : '.$key."\n";
2785 2783
                     }
2786 2784
                     if ($cnt > 0) {
2787
-                        while (-- $cnt >= 0) {
2785
+                        while (--$cnt >= 0) {
2788 2786
                             if (isset($last)) {
2789
-                                $last = strrpos($key, '$', - (strlen($key) - $last + 1));
2787
+                                $last = strrpos($key, '$', - (strlen($key)-$last+1));
2790 2788
                             } else {
2791 2789
                                 $last = strrpos($key, '$');
2792 2790
                             }
2793
-                            preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch);
2791
+                            preg_match('#\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*'.'((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', substr($key, $last), $submatch);
2794 2792
 
2795 2793
                             $len = strlen($submatch[0]);
2796 2794
                             $key = substr_replace(
2797 2795
                                 $key, preg_replace_callback(
2798
-                                    '#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)' . '((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array(
2796
+                                    '#(\$[a-z0-9_]+((?:(?:\.|->)(?:[a-z0-9_]+|(?R))|\[(?:[a-z0-9_]+|(?R))\]))*)'.'((?:(?:[+/*%-])(?:\$[a-z0-9.[\]>_:-]+(?:\([^)]*\))?|[0-9.,]*))*)#i', array(
2799 2797
                                         $this,
2800 2798
                                         'replaceVarKeyHelper'
2801 2799
                                     ), substr($key, $last, $len)
2802 2800
                                 ), $last, $len
2803 2801
                             );
2804 2802
                             if ($this->debug) {
2805
-                                echo 'RECURSIVE VAR REPLACEMENT DONE : ' . $key . "\n";
2803
+                                echo 'RECURSIVE VAR REPLACEMENT DONE : '.$key."\n";
2806 2804
                             }
2807 2805
                         }
2808 2806
                         unset($last);
@@ -2828,7 +2826,7 @@  discard block
 block discarded – undo
2828 2826
      */
2829 2827
     protected function replaceVarKeyHelper($match)
2830 2828
     {
2831
-        return '".' . $this->parseVar($match[0], 0, strlen($match[0]), false, 'variable') . '."';
2829
+        return '".'.$this->parseVar($match[0], 0, strlen($match[0]), false, 'variable').'."';
2832 2830
     }
2833 2831
 
2834 2832
     /**
@@ -2848,7 +2846,7 @@  discard block
 block discarded – undo
2848 2846
      */
2849 2847
     protected function parseOthers($in, $from, $to, $parsingParams = false, $curBlock = '', &$pointer = null)
2850 2848
     {
2851
-        $substr = substr($in, $from, $to - $from);
2849
+        $substr = substr($in, $from, $to-$from);
2852 2850
 
2853 2851
         $end = strlen($substr);
2854 2852
 
@@ -2922,48 +2920,48 @@  discard block
 block discarded – undo
2922 2920
 
2923 2921
         if (strtolower($substr) === 'false' || strtolower($substr) === 'no' || strtolower($substr) === 'off') {
2924 2922
             if ($this->debug) {
2925
-                echo 'BOOLEAN(FALSE) PARSED' . "\n";
2923
+                echo 'BOOLEAN(FALSE) PARSED'."\n";
2926 2924
             }
2927 2925
             $substr = 'false';
2928 2926
             $type   = self::T_BOOL;
2929 2927
         } elseif (strtolower($substr) === 'true' || strtolower($substr) === 'yes' || strtolower($substr) === 'on') {
2930 2928
             if ($this->debug) {
2931
-                echo 'BOOLEAN(TRUE) PARSED' . "\n";
2929
+                echo 'BOOLEAN(TRUE) PARSED'."\n";
2932 2930
             }
2933 2931
             $substr = 'true';
2934 2932
             $type   = self::T_BOOL;
2935 2933
         } elseif ($substr === 'null' || $substr === 'NULL') {
2936 2934
             if ($this->debug) {
2937
-                echo 'NULL PARSED' . "\n";
2935
+                echo 'NULL PARSED'."\n";
2938 2936
             }
2939 2937
             $substr = 'null';
2940 2938
             $type   = self::T_NULL;
2941 2939
         } elseif (is_numeric($substr)) {
2942
-            $substr = (float)$substr;
2943
-            if ((int)$substr == $substr) {
2944
-                $substr = (int)$substr;
2940
+            $substr = (float) $substr;
2941
+            if ((int) $substr == $substr) {
2942
+                $substr = (int) $substr;
2945 2943
             }
2946 2944
             $type = self::T_NUMERIC;
2947 2945
             if ($this->debug) {
2948
-                echo 'NUMBER (' . $substr . ') PARSED' . "\n";
2946
+                echo 'NUMBER ('.$substr.') PARSED'."\n";
2949 2947
             }
2950 2948
         } elseif (preg_match('{^-?(\d+|\d*(\.\d+))\s*([/*%+-]\s*-?(\d+|\d*(\.\d+)))+$}', $substr)) {
2951 2949
             if ($this->debug) {
2952 2950
                 echo 'SIMPLE MATH PARSED . "\n"';
2953 2951
             }
2954 2952
             $type   = self::T_MATH;
2955
-            $substr = '(' . $substr . ')';
2953
+            $substr = '('.$substr.')';
2956 2954
         } elseif ($curBlock === 'condition' && array_search($substr, $breakChars, true) !== false) {
2957 2955
             if ($this->debug) {
2958
-                echo 'BREAKCHAR (' . $substr . ') PARSED' . "\n";
2956
+                echo 'BREAKCHAR ('.$substr.') PARSED'."\n";
2959 2957
             }
2960 2958
             $type = self::T_BREAKCHAR;
2961 2959
             //$substr = '"'.$substr.'"';
2962 2960
         } else {
2963
-            $substr = $this->replaceStringVars('\'' . str_replace('\'', '\\\'', $substr) . '\'', '\'', $curBlock);
2961
+            $substr = $this->replaceStringVars('\''.str_replace('\'', '\\\'', $substr).'\'', '\'', $curBlock);
2964 2962
             $type   = self::T_UNQUOTED_STRING;
2965 2963
             if ($this->debug) {
2966
-                echo 'BLABBER (' . $substr . ') CASTED AS STRING' . "\n";
2964
+                echo 'BLABBER ('.$substr.') CASTED AS STRING'."\n";
2967 2965
             }
2968 2966
         }
2969 2967
 
@@ -2993,28 +2991,28 @@  discard block
 block discarded – undo
2993 2991
     {
2994 2992
         $pos = 0;
2995 2993
         if ($this->debug) {
2996
-            echo 'STRING VAR REPLACEMENT : ' . $string . "\n";
2994
+            echo 'STRING VAR REPLACEMENT : '.$string."\n";
2997 2995
         }
2998 2996
         // replace vars
2999 2997
         while (($pos = strpos($string, '$', $pos)) !== false) {
3000
-            $prev = substr($string, $pos - 1, 1);
2998
+            $prev = substr($string, $pos-1, 1);
3001 2999
             if ($prev === '\\') {
3002
-                ++ $pos;
3000
+                ++$pos;
3003 3001
                 continue;
3004 3002
             }
3005 3003
 
3006 3004
             $var = $this->parse($string, $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string')));
3007 3005
             $len = $var[0];
3008
-            $var = $this->parse(str_replace('\\' . $first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string')));
3006
+            $var = $this->parse(str_replace('\\'.$first, $first, $string), $pos, null, false, ($curBlock === 'modifier' ? 'modifier' : ($prev === '`' ? 'delimited_string' : 'string')));
3009 3007
 
3010
-            if ($prev === '`' && substr($string, $pos + $len, 1) === '`') {
3011
-                $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos - 1, $len + 2);
3008
+            if ($prev === '`' && substr($string, $pos+$len, 1) === '`') {
3009
+                $string = substr_replace($string, $first.'.'.$var[1].'.'.$first, $pos-1, $len+2);
3012 3010
             } else {
3013
-                $string = substr_replace($string, $first . '.' . $var[1] . '.' . $first, $pos, $len);
3011
+                $string = substr_replace($string, $first.'.'.$var[1].'.'.$first, $pos, $len);
3014 3012
             }
3015
-            $pos += strlen($var[1]) + 2;
3013
+            $pos += strlen($var[1])+2;
3016 3014
             if ($this->debug) {
3017
-                echo 'STRING VAR REPLACEMENT DONE : ' . $string . "\n";
3015
+                echo 'STRING VAR REPLACEMENT DONE : '.$string."\n";
3018 3016
             }
3019 3017
         }
3020 3018
 
@@ -3050,7 +3048,7 @@  discard block
 block discarded – undo
3050 3048
     protected function replaceModifiers(array $m, $curBlock = null, &$pointer = null)
3051 3049
     {
3052 3050
         if ($this->debug) {
3053
-            echo 'PARSING MODIFIERS : ' . $m[3] . "\n";
3051
+            echo 'PARSING MODIFIERS : '.$m[3]."\n";
3054 3052
         }
3055 3053
 
3056 3054
         if ($pointer !== null) {
@@ -3074,7 +3072,7 @@  discard block
 block discarded – undo
3074 3072
             }
3075 3073
             if ($cmdstrsrc[0] === ' ' || $cmdstrsrc[0] === ';' || substr($cmdstrsrc, 0, strlen($this->rd)) === $this->rd) {
3076 3074
                 if ($this->debug) {
3077
-                    echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND' . "\n";
3075
+                    echo 'MODIFIER PARSING ENDED, RIGHT DELIMITER or ";" FOUND'."\n";
3078 3076
                 }
3079 3077
                 $continue = false;
3080 3078
                 if ($pointer !== null) {
@@ -3085,7 +3083,7 @@  discard block
 block discarded – undo
3085 3083
             $cmdstr   = $cmdstrsrc;
3086 3084
             $paramsep = ':';
3087 3085
             if (!preg_match('/^(@{0,2}[a-z_][a-z0-9_]*)(:)?/i', $cmdstr, $match)) {
3088
-                throw new CompilationException($this, 'Invalid modifier name, started with : ' . substr($cmdstr, 0, 10));
3086
+                throw new CompilationException($this, 'Invalid modifier name, started with : '.substr($cmdstr, 0, 10));
3089 3087
             }
3090 3088
             $paramspos = !empty($match[2]) ? strlen($match[1]) : false;
3091 3089
             $func      = $match[1];
@@ -3095,10 +3093,10 @@  discard block
 block discarded – undo
3095 3093
                 $cmdstrsrc = substr($cmdstrsrc, strlen($func));
3096 3094
                 $params    = array();
3097 3095
                 if ($this->debug) {
3098
-                    echo 'MODIFIER (' . $func . ') CALLED WITH NO PARAMS' . "\n";
3096
+                    echo 'MODIFIER ('.$func.') CALLED WITH NO PARAMS'."\n";
3099 3097
                 }
3100 3098
             } else {
3101
-                $paramstr = substr($cmdstr, $paramspos + 1);
3099
+                $paramstr = substr($cmdstr, $paramspos+1);
3102 3100
                 if (substr($paramstr, - 1, 1) === $paramsep) {
3103 3101
                     $paramstr = substr($paramstr, 0, - 1);
3104 3102
                 }
@@ -3107,41 +3105,41 @@  discard block
 block discarded – undo
3107 3105
                 $params = array();
3108 3106
                 while ($ptr < strlen($paramstr)) {
3109 3107
                     if ($this->debug) {
3110
-                        echo 'MODIFIER (' . $func . ') START PARAM PARSING WITH POINTER AT ' . $ptr . "\n";
3108
+                        echo 'MODIFIER ('.$func.') START PARAM PARSING WITH POINTER AT '.$ptr."\n";
3111 3109
                     }
3112 3110
                     if ($this->debug) {
3113
-                        echo $paramstr . '--' . $ptr . '--' . strlen($paramstr) . '--modifier' . "\n";
3111
+                        echo $paramstr.'--'.$ptr.'--'.strlen($paramstr).'--modifier'."\n";
3114 3112
                     }
3115 3113
                     $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'modifier', $ptr);
3116 3114
                     if ($this->debug) {
3117
-                        echo 'PARAM PARSED, POINTER AT ' . $ptr . "\n";
3115
+                        echo 'PARAM PARSED, POINTER AT '.$ptr."\n";
3118 3116
                     }
3119 3117
 
3120 3118
                     if ($ptr >= strlen($paramstr)) {
3121 3119
                         if ($this->debug) {
3122
-                            echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED' . "\n";
3120
+                            echo 'PARAM PARSING ENDED, PARAM STRING CONSUMED'."\n";
3123 3121
                         }
3124 3122
                         break;
3125 3123
                     }
3126 3124
 
3127 3125
                     if ($paramstr[$ptr] === ' ' || $paramstr[$ptr] === '|' || $paramstr[$ptr] === ';' || substr($paramstr, $ptr, strlen($this->rd)) === $this->rd) {
3128 3126
                         if ($this->debug) {
3129
-                            echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT ' . $ptr . "\n";
3127
+                            echo 'PARAM PARSING ENDED, " ", "|", RIGHT DELIMITER or ";" FOUND, POINTER AT '.$ptr."\n";
3130 3128
                         }
3131 3129
                         if ($paramstr[$ptr] !== '|') {
3132 3130
                             $continue = false;
3133 3131
                             if ($pointer !== null) {
3134
-                                $pointer -= strlen($paramstr) - $ptr;
3132
+                                $pointer -= strlen($paramstr)-$ptr;
3135 3133
                             }
3136 3134
                         }
3137
-                        ++ $ptr;
3135
+                        ++$ptr;
3138 3136
                         break;
3139 3137
                     }
3140 3138
                     if ($ptr < strlen($paramstr) && $paramstr[$ptr] === ':') {
3141
-                        ++ $ptr;
3139
+                        ++$ptr;
3142 3140
                     }
3143 3141
                 }
3144
-                $cmdstrsrc = substr($cmdstrsrc, strlen($func) + 1 + $ptr);
3142
+                $cmdstrsrc = substr($cmdstrsrc, strlen($func)+1+$ptr);
3145 3143
                 foreach ($params as $k => $p) {
3146 3144
                     if (is_array($p) && is_array($p[1])) {
3147 3145
                         $state |= 2;
@@ -3181,9 +3179,9 @@  discard block
 block discarded – undo
3181 3179
                 $params = self::implode_r($params);
3182 3180
 
3183 3181
                 if ($mapped) {
3184
-                    $output = '$this->arrayMap(\'' . $func . '\', array(' . $params . '))';
3182
+                    $output = '$this->arrayMap(\''.$func.'\', array('.$params.'))';
3185 3183
                 } else {
3186
-                    $output = $func . '(' . $params . ')';
3184
+                    $output = $func.'('.$params.')';
3187 3185
                 }
3188 3186
             } elseif ($pluginType & Core::PROXY_PLUGIN) {
3189 3187
                 $params = $this->mapParams($params, $this->getDwoo()->getPluginProxy()->getCallback($func), $state);
@@ -3201,36 +3199,36 @@  discard block
 block discarded – undo
3201 3199
                     $callback = $this->customPlugins[$func]['callback'];
3202 3200
                     if (is_array($callback)) {
3203 3201
                         if (is_object($callback[0])) {
3204
-                            $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))';
3202
+                            $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), array('.$params.'))';
3205 3203
                         } else {
3206
-                            $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))';
3204
+                            $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array(\''.$callback[0].'\', \''.$callback[1].'\'), array('.$params.'))';
3207 3205
                         }
3208 3206
                     } elseif ($mapped) {
3209
-                        $output = '$this->arrayMap(\'' . $callback . '\', array(' . $params . '))';
3207
+                        $output = '$this->arrayMap(\''.$callback.'\', array('.$params.'))';
3210 3208
                     } else {
3211
-                        $output = $callback . '(' . $params . ')';
3209
+                        $output = $callback.'('.$params.')';
3212 3210
                     }
3213 3211
                 } elseif ($mapped) {
3214
-                    $output = '$this->arrayMap(\'smarty_modifier_' . $func . '\', array(' . $params . '))';
3212
+                    $output = '$this->arrayMap(\'smarty_modifier_'.$func.'\', array('.$params.'))';
3215 3213
                 } else {
3216
-                    $output = 'smarty_modifier_' . $func . '(' . $params . ')';
3214
+                    $output = 'smarty_modifier_'.$func.'('.$params.')';
3217 3215
                 }
3218 3216
             } else {
3219 3217
                 if ($pluginType & Core::CUSTOM_PLUGIN) {
3220 3218
                     $callback   = $this->customPlugins[$func]['callback'];
3221 3219
                     $pluginName = $callback;
3222 3220
                 } else {
3223
-                    if (class_exists('Plugin' . Core::toCamelCase($func)) !== false || function_exists('Plugin' .
3224
-                            Core::toCamelCase($func) . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''))
3221
+                    if (class_exists('Plugin'.Core::toCamelCase($func)) !== false || function_exists('Plugin'.
3222
+                            Core::toCamelCase($func).(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : ''))
3225 3223
                         !== false) {
3226
-                        $pluginName = 'Plugin' . Core::toCamelCase($func);
3224
+                        $pluginName = 'Plugin'.Core::toCamelCase($func);
3227 3225
                     } else {
3228
-                        $pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func);
3226
+                        $pluginName = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func);
3229 3227
                     }
3230 3228
                     if ($pluginType & Core::CLASS_PLUGIN) {
3231 3229
                         $callback = array($pluginName, ($pluginType & Core::COMPILABLE_PLUGIN) ? 'compile' : 'process');
3232 3230
                     } else {
3233
-                        $callback = $pluginName . (($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '');
3231
+                        $callback = $pluginName.(($pluginType & Core::COMPILABLE_PLUGIN) ? 'Compile' : '');
3234 3232
                     }
3235 3233
                 }
3236 3234
                 $params = $this->mapParams($params, $callback, $state);
@@ -3248,10 +3246,10 @@  discard block
 block discarded – undo
3248 3246
                         if ($pluginType & Core::CUSTOM_PLUGIN) {
3249 3247
                             $funcCompiler = $this->customPlugins[$func]['callback'];
3250 3248
                         } else {
3251
-                            if (function_exists('Plugin' . Core::toCamelCase($func) . 'Compile') !== false) {
3252
-                                $funcCompiler = 'Plugin' . Core::toCamelCase($func) . 'Compile';
3249
+                            if (function_exists('Plugin'.Core::toCamelCase($func).'Compile') !== false) {
3250
+                                $funcCompiler = 'Plugin'.Core::toCamelCase($func).'Compile';
3253 3251
                             } else {
3254
-                                $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) .
3252
+                                $funcCompiler = Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).
3255 3253
                                     'Compile';
3256 3254
                             }
3257 3255
                         }
@@ -3262,9 +3260,9 @@  discard block
 block discarded – undo
3262 3260
 
3263 3261
                         $params = self::implode_r($params);
3264 3262
                         if ($mapped) {
3265
-                            $output = '$this->arrayMap(\'' . $pluginName . '\', array(' . $params . '))';
3263
+                            $output = '$this->arrayMap(\''.$pluginName.'\', array('.$params.'))';
3266 3264
                         } else {
3267
-                            $output = $pluginName . '(' . $params . ')';
3265
+                            $output = $pluginName.'('.$params.')';
3268 3266
                         }
3269 3267
                     }
3270 3268
                 } else {
@@ -3276,7 +3274,7 @@  discard block
 block discarded – undo
3276 3274
                             $callback = $this->customPlugins[$func]['callback'];
3277 3275
                             if (!is_array($callback)) {
3278 3276
                                 if (!method_exists($callback, 'compile')) {
3279
-                                    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');
3277
+                                    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');
3280 3278
                                 }
3281 3279
                                 if (($ref = new ReflectionMethod($callback, 'compile')) && $ref->isStatic()) {
3282 3280
                                     $funcCompiler = array($callback, 'compile');
@@ -3287,11 +3285,11 @@  discard block
 block discarded – undo
3287 3285
                                 $funcCompiler = $callback;
3288 3286
                             }
3289 3287
                         } else {
3290
-                            if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
3291
-                                $funcCompiler = array('Plugin' . Core::toCamelCase($func), 'compile');
3288
+                            if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) {
3289
+                                $funcCompiler = array('Plugin'.Core::toCamelCase($func), 'compile');
3292 3290
                             } else {
3293 3291
                                 $funcCompiler = array(
3294
-                                    Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func),
3292
+                                    Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func),
3295 3293
                                     'compile'
3296 3294
                                 );
3297 3295
                             }
@@ -3303,23 +3301,23 @@  discard block
 block discarded – undo
3303 3301
 
3304 3302
                         if ($pluginType & Core::CUSTOM_PLUGIN) {
3305 3303
                             if (is_object($callback[0])) {
3306
-                                $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array($this->plugins[\'' . $func . '\'][\'callback\'][0], \'' . $callback[1] . '\'), array(' . $params . '))';
3304
+                                $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array($this->plugins[\''.$func.'\'][\'callback\'][0], \''.$callback[1].'\'), array('.$params.'))';
3307 3305
                             } else {
3308
-                                $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array') . '(array(\'' . $callback[0] . '\', \'' . $callback[1] . '\'), array(' . $params . '))';
3306
+                                $output = ($mapped ? '$this->arrayMap' : 'call_user_func_array').'(array(\''.$callback[0].'\', \''.$callback[1].'\'), array('.$params.'))';
3309 3307
                             }
3310 3308
                         } elseif ($mapped) {
3311 3309
                             $output = '$this->arrayMap(array($this->getObjectPlugin(\''.
3312
-                                Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func) . '\'), 
3313
-                            \'process\'), array(' . $params . '))';
3310
+                                Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func).'\'), 
3311
+                            \'process\'), array(' . $params.'))';
3314 3312
                         } else {
3315
-                            if (class_exists('Plugin' . Core::toCamelCase($func)) !== false) {
3316
-                                $output = '$this->classCall(\'Plugin' . Core::toCamelCase($func) . '\', array(' . $params . '))';
3317
-                            } elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($func)) !== false) {
3318
-                                $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . $func . '\', array(' . $params . '))';
3319
-                            } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($func)) !== false) {
3320
-                                $output = '$this->classCall(\'' . Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . $func . '\', array(' . $params . '))';
3313
+                            if (class_exists('Plugin'.Core::toCamelCase($func)) !== false) {
3314
+                                $output = '$this->classCall(\'Plugin'.Core::toCamelCase($func).'\', array('.$params.'))';
3315
+                            } elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($func)) !== false) {
3316
+                                $output = '$this->classCall(\''.Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.$func.'\', array('.$params.'))';
3317
+                            } elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($func)) !== false) {
3318
+                                $output = '$this->classCall(\''.Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.$func.'\', array('.$params.'))';
3321 3319
                             } else {
3322
-                                $output = '$this->classCall(\'' . $func . '\', array(' . $params . '))';
3320
+                                $output = '$this->classCall(\''.$func.'\', array('.$params.'))';
3323 3321
                             }
3324 3322
                         }
3325 3323
                     }
@@ -3332,7 +3330,7 @@  discard block
 block discarded – undo
3332 3330
         } elseif ($curBlock === 'var' || $m[1] === null) {
3333 3331
             return $output;
3334 3332
         } elseif ($curBlock === 'string' || $curBlock === 'root') {
3335
-            return $m[1] . '.' . $output . '.' . $m[1] . (isset($add) ? $add : null);
3333
+            return $m[1].'.'.$output.'.'.$m[1].(isset($add) ? $add : null);
3336 3334
         }
3337 3335
 
3338 3336
         return '';
@@ -3355,14 +3353,14 @@  discard block
 block discarded – undo
3355 3353
             if (is_array($p)) {
3356 3354
                 $out2 = 'array(';
3357 3355
                 foreach ($p as $k2 => $v) {
3358
-                    $out2 .= var_export($k2, true) . ' => ' . (is_array($v) ? 'array(' . self::implode_r($v, true) . ')' : $v) . ', ';
3356
+                    $out2 .= var_export($k2, true).' => '.(is_array($v) ? 'array('.self::implode_r($v, true).')' : $v).', ';
3359 3357
                 }
3360
-                $p = rtrim($out2, ', ') . ')';
3358
+                $p = rtrim($out2, ', ').')';
3361 3359
             }
3362 3360
             if ($recursiveCall) {
3363
-                $out .= var_export($k, true) . ' => ' . $p . ', ';
3361
+                $out .= var_export($k, true).' => '.$p.', ';
3364 3362
             } else {
3365
-                $out .= $p . ', ';
3363
+                $out .= $p.', ';
3366 3364
             }
3367 3365
         }
3368 3366
 
@@ -3386,7 +3384,7 @@  discard block
 block discarded – undo
3386 3384
         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)) {
3387 3385
             $phpFunc = true;
3388 3386
         } elseif ($this->securityPolicy !== null && function_exists($name) && array_key_exists(strtolower($name), $this->securityPolicy->getAllowedPhpFunctions()) === false) {
3389
-            throw new SecurityException('Call to a disallowed php function : ' . $name);
3387
+            throw new SecurityException('Call to a disallowed php function : '.$name);
3390 3388
         }
3391 3389
 
3392 3390
         while ($pluginType <= 0) {
@@ -3397,58 +3395,58 @@  discard block
 block discarded – undo
3397 3395
             elseif (isset($this->customPlugins[$name])) {
3398 3396
                 $pluginType = $this->customPlugins[$name]['type'] | Core::CUSTOM_PLUGIN;
3399 3397
             } // Class blocks plugin
3400
-            elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3398
+            elseif (class_exists(Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($name)) !== false) {
3401 3399
                 $pluginType = Core::CLASS_PLUGIN;
3402
-                if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name), 'Dwoo\Block\Plugin')) {
3400
+                if (is_subclass_of(Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($name), 'Dwoo\Block\Plugin')) {
3403 3401
                     $pluginType += Core::BLOCK_PLUGIN;
3404 3402
                 }
3405
-                $interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . Core::toCamelCase($name));
3403
+                $interfaces = class_implements(Core::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.Core::toCamelCase($name));
3406 3404
                 if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3407 3405
                     $pluginType |= Core::COMPILABLE_PLUGIN;
3408 3406
                 }
3409 3407
             } // Class functions plugin
3410
-            elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3411
-                $pluginType = Core::FUNC_PLUGIN + Core::CLASS_PLUGIN;
3412
-                $interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name));
3408
+            elseif (class_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name)) !== false) {
3409
+                $pluginType = Core::FUNC_PLUGIN+Core::CLASS_PLUGIN;
3410
+                $interfaces = class_implements(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name));
3413 3411
                 if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3414 3412
                     $pluginType |= Core::COMPILABLE_PLUGIN;
3415 3413
                 }
3416 3414
             } // Class without namespace
3417
-            elseif (class_exists('Plugin' . Core::toCamelCase($name)) !== false) {
3415
+            elseif (class_exists('Plugin'.Core::toCamelCase($name)) !== false) {
3418 3416
                 $pluginType = Core::CLASS_PLUGIN;
3419
-                $interfaces = class_implements('Plugin' . Core::toCamelCase($name));
3417
+                $interfaces = class_implements('Plugin'.Core::toCamelCase($name));
3420 3418
                 if (in_array('Dwoo\ICompilable', $interfaces) !== false || in_array('Dwoo\ICompilable\Block', $interfaces) !== false) {
3421 3419
                     $pluginType |= Core::COMPILABLE_PLUGIN;
3422 3420
                 }
3423 3421
             } // Function plugin (with/without namespaces)
3424
-            elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase ($name)) !==
3425
-                false || function_exists('Plugin' . Core::toCamelCase($name)) !== false) {
3422
+            elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name)) !==
3423
+                false || function_exists('Plugin'.Core::toCamelCase($name)) !== false) {
3426 3424
                 $pluginType = Core::FUNC_PLUGIN;
3427 3425
             } // Function plugin compile (with/without namespaces)
3428
-            elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin' . Core::toCamelCase($name) .
3429
-                    'Compile') !== false || function_exists('Plugin' . Core::toCamelCase($name) . 'Compile') !==
3426
+            elseif (function_exists(Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin'.Core::toCamelCase($name).
3427
+                    'Compile') !== false || function_exists('Plugin'.Core::toCamelCase($name).'Compile') !==
3430 3428
                 false) {
3431 3429
                 $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN;
3432 3430
             } // Helper plugin class compile
3433
-            elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name)) !== false) {
3431
+            elseif (class_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($name)) !== false) {
3434 3432
                 $pluginType = Core::CLASS_PLUGIN | Core::COMPILABLE_PLUGIN;
3435 3433
             } // Helper plugin function compile
3436
-            elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS . 'Plugin' . Core::toCamelCase($name) . 'Compile') !== false) {
3434
+            elseif (function_exists(Core::NAMESPACE_PLUGINS_HELPERS.'Plugin'.Core::toCamelCase($name).'Compile') !== false) {
3437 3435
                 $pluginType = Core::FUNC_PLUGIN | Core::COMPILABLE_PLUGIN;
3438 3436
             } // Smarty modifier
3439
-            elseif (function_exists('smarty_modifier_' . $name) !== false) {
3437
+            elseif (function_exists('smarty_modifier_'.$name) !== false) {
3440 3438
                 $pluginType = Core::SMARTY_MODIFIER;
3441 3439
             } // Smarty function
3442
-            elseif (function_exists('smarty_function_' . $name) !== false) {
3440
+            elseif (function_exists('smarty_function_'.$name) !== false) {
3443 3441
                 $pluginType = Core::SMARTY_FUNCTION;
3444 3442
             } // Smarty block
3445
-            elseif (function_exists('smarty_block_' . $name) !== false) {
3443
+            elseif (function_exists('smarty_block_'.$name) !== false) {
3446 3444
                 $pluginType = Core::SMARTY_BLOCK;
3447 3445
             } // Everything else
3448 3446
             else {
3449 3447
                 if ($pluginType === - 1) {
3450 3448
                     try {
3451
-                        $this->getDwoo()->getLoader()->loadPlugin('Plugin' . Core::toCamelCase($name));
3449
+                        $this->getDwoo()->getLoader()->loadPlugin('Plugin'.Core::toCamelCase($name));
3452 3450
                     }
3453 3451
                     catch (Exception $e) {
3454 3452
                         if (isset($phpFunc)) {
@@ -3461,9 +3459,9 @@  discard block
 block discarded – undo
3461 3459
                         }
3462 3460
                     }
3463 3461
                 } else {
3464
-                    throw new Exception('Plugin "' . $name . '" could not be found, type:' . $pluginType);
3462
+                    throw new Exception('Plugin "'.$name.'" could not be found, type:'.$pluginType);
3465 3463
                 }
3466
-                ++ $pluginType;
3464
+                ++$pluginType;
3467 3465
             }
3468 3466
         }
3469 3467
 
@@ -3538,9 +3536,9 @@  discard block
 block discarded – undo
3538 3536
                 if (count($ps) === 0) {
3539 3537
                     if ($v[1] === false) {
3540 3538
                         throw new CompilationException(
3541
-                            $this, 'Rest argument missing for ' . str_replace(
3539
+                            $this, 'Rest argument missing for '.str_replace(
3542 3540
                                 array(
3543
-                                    Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin',
3541
+                                    Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin',
3544 3542
                                 'Compile'
3545 3543
                                 ), '', (is_array($callback) ? $callback[0] : $callback)
3546 3544
                             )
@@ -3573,7 +3571,7 @@  discard block
 block discarded – undo
3573 3571
                 // parameter is not defined and not optional, throw error
3574 3572
                 if (is_array($callback)) {
3575 3573
                     if (is_object($callback[0])) {
3576
-                        $name = get_class($callback[0]) . '::' . $callback[1];
3574
+                        $name = get_class($callback[0]).'::'.$callback[1];
3577 3575
                     } else {
3578 3576
                         $name = $callback[0];
3579 3577
                     }
@@ -3582,9 +3580,9 @@  discard block
 block discarded – undo
3582 3580
                 }
3583 3581
 
3584 3582
                 throw new CompilationException(
3585
-                    $this, 'Argument ' . $k . '/' . $v[0] . ' missing for ' . str_replace(
3583
+                    $this, 'Argument '.$k.'/'.$v[0].' missing for '.str_replace(
3586 3584
                         array(
3587
-                            Core::NAMESPACE_PLUGINS_FUNCTIONS . 'Plugin',
3585
+                            Core::NAMESPACE_PLUGINS_FUNCTIONS.'Plugin',
3588 3586
                         'Compile'
3589 3587
                         ), '', $name
3590 3588
                     )
Please login to merge, or discard this patch.
lib/Dwoo/Loader.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@
 block discarded – undo
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
     {
Please login to merge, or discard this patch.
Indentation   +162 added lines, -162 removed lines patch added patch discarded remove patch
@@ -23,176 +23,176 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -61,14 +61,14 @@  discard block
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
         }
Please login to merge, or discard this patch.
lib/Dwoo/Plugins/Blocks/PluginDynamic.php 4 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -85,8 +85,8 @@
 block discarded – undo
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
      */
Please login to merge, or discard this patch.
Indentation   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -28,89 +28,89 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -67,18 +67,18 @@  discard block
 block discarded – undo
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
 block discarded – undo
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
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -64,8 +64,7 @@
 block discarded – undo
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) {
Please login to merge, or discard this patch.
lib/Dwoo/Plugins/Blocks/PluginStrip.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -59,7 +59,7 @@
 block discarded – undo
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
     {
Please login to merge, or discard this patch.
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -31,59 +31,59 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
Switch Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -67,12 +67,12 @@
 block discarded – undo
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/",
Please login to merge, or discard this patch.
lib/Dwoo/Plugins/Processors/PluginSmartyCompatible.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@
 block discarded – undo
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
     {
Please login to merge, or discard this patch.
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -26,69 +26,69 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
Spacing   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -38,38 +38,38 @@  discard block
 block discarded – undo
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
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
lib/Dwoo/Smarty/Adapter.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -312,7 +312,7 @@
 block discarded – undo
312 312
 
313 313
     /**
314 314
      * @param mixed $_tpl
315
-     * @param array $data
315
+     * @param Data $data
316 316
      * @param null  $_compiler
317 317
      * @param bool  $_output
318 318
      *
Please login to merge, or discard this patch.
Indentation   +657 added lines, -657 removed lines patch added patch discarded remove patch
@@ -26,14 +26,14 @@  discard block
 block discarded – undo
26 26
 use Dwoo\Smarty\Processor\Adapter as ProcessorAdapter;
27 27
 
28 28
 if (!defined('DIR_SEP')) {
29
-    define('DIR_SEP', DIRECTORY_SEPARATOR);
29
+	define('DIR_SEP', DIRECTORY_SEPARATOR);
30 30
 }
31 31
 
32 32
 if (!defined('SMARTY_PHP_PASSTHRU')) {
33
-    define('SMARTY_PHP_PASSTHRU', 0);
34
-    define('SMARTY_PHP_QUOTE', 1);
35
-    define('SMARTY_PHP_REMOVE', 2);
36
-    define('SMARTY_PHP_ALLOW', 3);
33
+	define('SMARTY_PHP_PASSTHRU', 0);
34
+	define('SMARTY_PHP_QUOTE', 1);
35
+	define('SMARTY_PHP_REMOVE', 2);
36
+	define('SMARTY_PHP_ALLOW', 3);
37 37
 }
38 38
 
39 39
 /**
@@ -43,656 +43,656 @@  discard block
 block discarded – undo
43 43
  */
44 44
 class Adapter extends Core
45 45
 {
46
-    /**
47
-     * Magic get/set/call functions that handle unsupported features
48
-     *
49
-     * @param string $p
50
-     * @param string $v
51
-     */
52
-    public function __set($p, $v)
53
-    {
54
-        if ($p === 'scope') {
55
-            $this->scope = $v;
56
-
57
-            return;
58
-        }
59
-        if ($p === 'data') {
60
-            $this->data = $v;
61
-
62
-            return;
63
-        }
64
-        if (array_key_exists($p, $this->compat['properties']) !== false) {
65
-            if ($this->show_compat_errors) {
66
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
67
-            }
68
-            $this->compat['properties'][$p] = $v;
69
-        } else {
70
-            if ($this->show_compat_errors) {
71
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
72
-            }
73
-        }
74
-    }
75
-
76
-    /**
77
-     * @param $p
78
-     *
79
-     * @return mixed
80
-     */
81
-    public function __get($p)
82
-    {
83
-        if (array_key_exists($p, $this->compat['properties']) !== false) {
84
-            if ($this->show_compat_errors) {
85
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
86
-            }
87
-
88
-            return $this->compat['properties'][$p];
89
-        } else {
90
-            if ($this->show_compat_errors) {
91
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
92
-            }
93
-        }
94
-    }
95
-
96
-    /**
97
-     * @param string $m
98
-     * @param array  $a
99
-     *
100
-     * @return mixed|void
101
-     */
102
-    public function __call($m, $a)
103
-    {
104
-        if (method_exists($this->dataProvider, $m)) {
105
-            call_user_func_array(
106
-                array(
107
-                $this->dataProvider,
108
-                $m
109
-                ), $a
110
-            );
111
-        } elseif ($this->show_compat_errors) {
112
-            if (array_search($m, $this->compat['methods']) !== false) {
113
-                $this->triggerError('Method ' . $m . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
114
-            } else {
115
-                $this->triggerError('Method ' . $m . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
116
-            }
117
-        }
118
-    }
119
-
120
-    /**
121
-     * List of unsupported properties and methods
122
-     */
123
-    protected $compat = array(
124
-        'methods'    => array(
125
-            'register_resource',
126
-            'unregister_resource',
127
-            'load_filter',
128
-            'clear_compiled_tpl',
129
-            'clear_config',
130
-            'get_config_vars',
131
-            'config_load',
132
-        ),
133
-        'properties' => array(
134
-            'cache_handler_func'            => null,
135
-            'debugging'                     => false,
136
-            'error_reporting'               => null,
137
-            'debugging_ctrl'                => 'NONE',
138
-            'request_vars_order'            => 'EGPCS',
139
-            'request_use_auto_globals'      => true,
140
-            'use_sub_dirs'                  => false,
141
-            'autoload_filters'              => array(),
142
-            'default_template_handler_func' => '',
143
-            'debug_tpl'                     => '',
144
-            'cache_modified_check'          => false,
145
-            'default_modifiers'             => array(),
146
-            'default_resource_type'         => 'file',
147
-            'config_overwrite'              => true,
148
-            'config_booleanize'             => true,
149
-            'config_read_hidden'            => false,
150
-            'config_fix_newlines'           => true,
151
-            'config_class'                  => 'Config_File',
152
-        ),
153
-    );
154
-
155
-    /**
156
-     * Security vars
157
-     */
158
-    public $security          = false;
159
-    public $trusted_dir       = array();
160
-    public $secure_dir        = array();
161
-    public $php_handling      = SMARTY_PHP_PASSTHRU;
162
-    public $security_settings = array(
163
-        'PHP_HANDLING'    => false,
164
-        'IF_FUNCS'        => array(
165
-            'list',
166
-            'empty',
167
-            'count',
168
-            'sizeof',
169
-            'in_array',
170
-            'is_array',
171
-        ),
172
-        'INCLUDE_ANY'     => false,
173
-        'PHP_TAGS'        => false,
174
-        'MODIFIER_FUNCS'  => array(),
175
-        'ALLOW_CONSTANTS' => false,
176
-    );
177
-
178
-    /**
179
-     * Paths
180
-     */
181
-    public $template_dir = 'templates';
182
-    public $compile_dir  = 'templates_c';
183
-    public $config_dir   = 'configs';
184
-    public $cache_dir    = 'cache';
185
-    public $plugins_dir  = array();
186
-
187
-    /**
188
-     * Misc options
189
-     */
190
-    public $left_delimiter  = '{';
191
-    public $right_delimiter = '}';
192
-    public $compile_check   = true;
193
-    public $force_compile   = false;
194
-    public $caching         = 0;
195
-    public $cache_lifetime  = 3600;
196
-    public $compile_id      = null;
197
-    public $compiler_file   = null;
198
-    public $compiler_class  = null;
199
-
200
-    /**
201
-     * Dwoo/Smarty compat layer
202
-     */
203
-    public           $show_compat_errors = false;
204
-    protected        $dataProvider;
205
-    protected        $_filters           = array(
206
-        'pre'    => array(),
207
-        'post'   => array(),
208
-        'output' => array()
209
-    );
210
-    protected static $tplCache           = array();
211
-    protected        $compiler           = null;
212
-
213
-    /**
214
-     * Adapter constructor.
215
-     */
216
-    public function __construct()
217
-    {
218
-        parent::__construct();
219
-        $this->charset      = 'iso-8859-1';
220
-        $this->dataProvider = new Data();
221
-        $this->compiler     = new Compiler();
222
-    }
223
-
224
-    /**
225
-     * @param      $filename
226
-     * @param null $cacheId
227
-     * @param null $compileId
228
-     */
229
-    public function display($filename, $cacheId = null, $compileId = null)
230
-    {
231
-        $this->fetch($filename, $cacheId, $compileId, true);
232
-    }
233
-
234
-    /**
235
-     * @param      $filename
236
-     * @param null $cacheId
237
-     * @param null $compileId
238
-     * @param bool $display
239
-     *
240
-     * @return string|void
241
-     */
242
-    public function fetch($filename, $cacheId = null, $compileId = null, $display = false)
243
-    {
244
-        $this->setCacheDir($this->cache_dir);
245
-        $this->setCompileDir($this->compile_dir);
246
-
247
-        if ($this->security) {
248
-            $policy = new SecurityPolicy();
249
-            $policy->addPhpFunction(array_merge($this->security_settings['IF_FUNCS'], $this->security_settings['MODIFIER_FUNCS']));
250
-
251
-            $phpTags = $this->security_settings['PHP_HANDLING'] ? SMARTY_PHP_ALLOW : $this->php_handling;
252
-            if ($this->security_settings['PHP_TAGS']) {
253
-                $phpTags = SMARTY_PHP_ALLOW;
254
-            }
255
-            switch ($phpTags) {
256
-            case SMARTY_PHP_ALLOW:
257
-            case SMARTY_PHP_PASSTHRU:
258
-                $phpTags = SecurityPolicy::PHP_ALLOW;
259
-                break;
260
-            case SMARTY_PHP_QUOTE:
261
-                $phpTags = SecurityPolicy::PHP_ENCODE;
262
-                break;
263
-            case SMARTY_PHP_REMOVE:
264
-            default:
265
-                $phpTags = SecurityPolicy::PHP_REMOVE;
266
-                break;
267
-            }
268
-            $policy->setPhpHandling($phpTags);
269
-
270
-            $policy->setConstantHandling($this->security_settings['ALLOW_CONSTANTS']);
271
-
272
-            if ($this->security_settings['INCLUDE_ANY']) {
273
-                $policy->allowDirectory(preg_replace('{^((?:[a-z]:)?[\\\\/]).*}i', '$1', __FILE__));
274
-            } else {
275
-                $policy->allowDirectory($this->secure_dir);
276
-            }
277
-
278
-            $this->setSecurityPolicy($policy);
279
-        }
280
-
281
-        if (!empty($this->plugins_dir)) {
282
-            foreach ($this->plugins_dir as $dir) {
283
-                $this->getLoader()->addDirectory(rtrim($dir, '\\/'));
284
-            }
285
-        }
286
-
287
-        $tpl = $this->makeTemplate($filename, $cacheId, $compileId);
288
-        if ($this->force_compile) {
289
-            $tpl->forceCompilation();
290
-        }
291
-
292
-        if ($this->caching > 0) {
293
-            $this->cacheTime = $this->cache_lifetime;
294
-        } else {
295
-            $this->cacheTime = 0;
296
-        }
297
-
298
-        if ($this->compiler_class !== null) {
299
-            if ($this->compiler_file !== null && !class_exists($this->compiler_class)) {
300
-                include $this->compiler_file;
301
-            }
302
-            $this->compiler = new $this->compiler_class();
303
-        } else {
304
-            $this->compiler->addPreProcessor('PluginSmartyCompatible', true);
305
-            $this->compiler->setLooseOpeningHandling(true);
306
-        }
307
-
308
-        $this->compiler->setDelimiters($this->left_delimiter, $this->right_delimiter);
309
-
310
-        return $this->get($tpl, $this->dataProvider, $this->compiler, $display === true);
311
-    }
312
-
313
-    /**
314
-     * @param mixed $_tpl
315
-     * @param array $data
316
-     * @param null  $_compiler
317
-     * @param bool  $_output
318
-     *
319
-     * @return string|void
320
-     */
321
-    public function get($_tpl, $data = array(), $_compiler = null, $_output = false)
322
-    {
323
-        if ($_compiler === null) {
324
-            $_compiler = $this->compiler;
325
-        }
326
-
327
-        return parent::get($_tpl, $data, $_compiler, $_output);
328
-    }
329
-
330
-    /**
331
-     * @param      $name
332
-     * @param      $callback
333
-     * @param bool $cacheable
334
-     * @param null $cache_attrs
335
-     *
336
-     * @throws Exception
337
-     */
338
-    public function register_function($name, $callback, $cacheable = true, $cache_attrs = null)
339
-    {
340
-        if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_FUNCTION) {
341
-            throw new Exception('Multiple plugins of different types can not share the same name');
342
-        }
343
-        $this->plugins[$name] = array(
344
-            'type'     => self::SMARTY_FUNCTION,
345
-            'callback' => $callback
346
-        );
347
-    }
348
-
349
-    /**
350
-     * @param $name
351
-     */
352
-    public function unregister_function($name)
353
-    {
354
-        unset($this->plugins[$name]);
355
-    }
356
-
357
-    /**
358
-     * @param      $name
359
-     * @param      $callback
360
-     * @param bool $cacheable
361
-     * @param null $cache_attrs
362
-     *
363
-     * @throws Exception
364
-     */
365
-    public function register_block($name, $callback, $cacheable = true, $cache_attrs = null)
366
-    {
367
-        if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_BLOCK) {
368
-            throw new Exception('Multiple plugins of different types can not share the same name');
369
-        }
370
-        $this->plugins[$name] = array(
371
-            'type'     => self::SMARTY_BLOCK,
372
-            'callback' => $callback
373
-        );
374
-    }
375
-
376
-    /**
377
-     * @param $name
378
-     */
379
-    public function unregister_block($name)
380
-    {
381
-        unset($this->plugins[$name]);
382
-    }
383
-
384
-    /**
385
-     * @param $name
386
-     * @param $callback
387
-     *
388
-     * @throws Exception
389
-     */
390
-    public function register_modifier($name, $callback)
391
-    {
392
-        if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_MODIFIER) {
393
-            throw new Exception('Multiple plugins of different types can not share the same name');
394
-        }
395
-        $this->plugins[$name] = array(
396
-            'type'     => self::SMARTY_MODIFIER,
397
-            'callback' => $callback
398
-        );
399
-    }
400
-
401
-    /**
402
-     * @param $name
403
-     */
404
-    public function unregister_modifier($name)
405
-    {
406
-        unset($this->plugins[$name]);
407
-    }
408
-
409
-    /**
410
-     * @param $callback
411
-     */
412
-    public function register_prefilter($callback)
413
-    {
414
-        $processor = new ProcessorAdapter($this->compiler);
415
-        $processor->registerCallback($callback);
416
-        $this->_filters['pre'][] = $processor;
417
-        $this->compiler->addPreProcessor($processor);
418
-    }
419
-
420
-    /**
421
-     * @param $callback
422
-     */
423
-    public function unregister_prefilter($callback)
424
-    {
425
-        foreach ($this->_filters['pre'] as $index => $processor) {
426
-            if ($processor->callback === $callback) {
427
-                $this->compiler->removePostProcessor($processor);
428
-                unset($this->_filters['pre'][$index]);
429
-            }
430
-        }
431
-    }
432
-
433
-    /**
434
-     * @param $callback
435
-     */
436
-    public function register_postfilter($callback)
437
-    {
438
-        $processor = new ProcessorAdapter($this->compiler);
439
-        $processor->registerCallback($callback);
440
-        $this->_filters['post'][] = $processor;
441
-        $this->compiler->addPostProcessor($processor);
442
-    }
443
-
444
-    /**
445
-     * @param $callback
446
-     */
447
-    public function unregister_postfilter($callback)
448
-    {
449
-        foreach ($this->_filters['post'] as $index => $processor) {
450
-            if ($processor->callback === $callback) {
451
-                $this->compiler->removePostProcessor($processor);
452
-                unset($this->_filters['post'][$index]);
453
-            }
454
-        }
455
-    }
456
-
457
-    /**
458
-     * @param $callback
459
-     */
460
-    public function register_outputfilter($callback)
461
-    {
462
-        $filter = new FilterAdapter($this);
463
-        $filter->registerCallback($callback);
464
-        $this->_filters['output'][] = $filter;
465
-        $this->addFilter($filter);
466
-    }
467
-
468
-    /**
469
-     * @param $callback
470
-     */
471
-    public function unregister_outputfilter($callback)
472
-    {
473
-        foreach ($this->_filters['output'] as $index => $filter) {
474
-            if ($filter->callback === $callback) {
475
-                $this->removeOutputFilter($filter);
476
-                unset($this->_filters['output'][$index]);
477
-            }
478
-        }
479
-    }
480
-
481
-    /**
482
-     * @param       $object
483
-     * @param       $object_impl
484
-     * @param array $allowed
485
-     * @param bool  $smarty_args
486
-     * @param array $block_methods
487
-     */
488
-    public function register_object($object, $object_impl, $allowed = array(), $smarty_args = false, $block_methods = array())
489
-    {
490
-        settype($allowed, 'array');
491
-        settype($block_methods, 'array');
492
-        settype($smarty_args, 'boolean');
493
-
494
-        if (!empty($allowed) && $this->show_compat_errors) {
495
-            $this->triggerError('You can register objects but can not restrict the method/properties used, this is PHP5, you have proper OOP access restrictions so use them.', E_USER_NOTICE);
496
-        }
497
-
498
-        if ($smarty_args) {
499
-            $this->triggerError('You can register objects but methods will be called using method($arg1, $arg2, $arg3), not as an argument array like smarty did.', E_USER_NOTICE);
500
-        }
501
-
502
-        if (!empty($block_methods)) {
503
-            $this->triggerError('You can register objects but can not use methods as being block methods, you have to build a plugin for that.', E_USER_NOTICE);
504
-        }
505
-
506
-        $this->dataProvider->assign($object, $object_impl);
507
-    }
508
-
509
-    /**
510
-     * @param $object
511
-     */
512
-    public function unregister_object($object)
513
-    {
514
-        $this->dataProvider->clear($object);
515
-    }
516
-
517
-    /**
518
-     * @param $name
519
-     *
520
-     * @return mixed
521
-     */
522
-    public function get_registered_object($name)
523
-    {
524
-        $data = $this->dataProvider->getData();
525
-        if (isset($data[$name]) && is_object($data[$name])) {
526
-            return $data[$name];
527
-        } else {
528
-            trigger_error('Dwoo_Compiler: object "' . $name . '" was not registered or is not an object', E_USER_ERROR);
529
-        }
530
-    }
531
-
532
-    /**
533
-     * @param $filename
534
-     *
535
-     * @return bool
536
-     */
537
-    public function template_exists($filename)
538
-    {
539
-        if (!is_array($this->template_dir)) {
540
-            return file_exists($this->template_dir . DIRECTORY_SEPARATOR . $filename);
541
-        } else {
542
-            foreach ($this->template_dir as $tpl_dir) {
543
-                if (file_exists($tpl_dir . DIRECTORY_SEPARATOR . $filename)) {
544
-                    return true;
545
-                }
546
-            }
547
-
548
-            return false;
549
-        }
550
-    }
551
-
552
-    /**
553
-     * @param      $tpl
554
-     * @param null $cacheId
555
-     * @param null $compileId
556
-     *
557
-     * @return bool
558
-     */
559
-    public function is_cached($tpl, $cacheId = null, $compileId = null)
560
-    {
561
-        return $this->isCached($this->makeTemplate($tpl, $cacheId, $compileId));
562
-    }
563
-
564
-    /**
565
-     * @param      $var
566
-     * @param      $value
567
-     * @param bool $merge
568
-     */
569
-    public function append_by_ref($var, &$value, $merge = false)
570
-    {
571
-        $this->dataProvider->appendByRef($var, $value, $merge);
572
-    }
573
-
574
-    /**
575
-     * @param $name
576
-     * @param $val
577
-     */
578
-    public function assign_by_ref($name, &$val)
579
-    {
580
-        $this->dataProvider->assignByRef($name, $val);
581
-    }
582
-
583
-    /**
584
-     * @param $var
585
-     */
586
-    public function clear_assign($var)
587
-    {
588
-        $this->dataProvider->clear($var);
589
-    }
590
-
591
-    /**
592
-     *
593
-     */
594
-    public function clear_all_assign()
595
-    {
596
-        $this->dataProvider->clear();
597
-    }
598
-
599
-    /**
600
-     * @param null $name
601
-     *
602
-     * @return array|null
603
-     */
604
-    public function get_template_vars($name = null)
605
-    {
606
-        if ($this->show_compat_errors) {
607
-            trigger_error('get_template_vars does not return values by reference, if you try to modify the data that way you should modify your code.', E_USER_NOTICE);
608
-        }
609
-
610
-        $data = $this->dataProvider->getData();
611
-        if ($name === null) {
612
-            return $data;
613
-        } elseif (isset($data[$name])) {
614
-            return $data[$name];
615
-        }
616
-
617
-        return null;
618
-    }
619
-
620
-    /**
621
-     * @param int $olderThan
622
-     */
623
-    public function clear_all_cache($olderThan = 0)
624
-    {
625
-        $this->clearCache($olderThan);
626
-    }
627
-
628
-    /**
629
-     * @param      $template
630
-     * @param null $cacheId
631
-     * @param null $compileId
632
-     * @param int  $olderThan
633
-     */
634
-    public function clear_cache($template, $cacheId = null, $compileId = null, $olderThan = 0)
635
-    {
636
-        $this->makeTemplate($template, $cacheId, $compileId)->clearCache($olderThan);
637
-    }
638
-
639
-    /**
640
-     * @param     $error_msg
641
-     * @param int $error_type
642
-     */
643
-    public function trigger_error($error_msg, $error_type = E_USER_WARNING)
644
-    {
645
-        $this->triggerError($error_msg, $error_type);
646
-    }
647
-
648
-    /**
649
-     *
650
-     */
651
-    protected function initGlobals()
652
-    {
653
-        parent::initGlobals();
654
-        $this->globals['ldelim'] = '{';
655
-        $this->globals['rdelim'] = '}';
656
-    }
657
-
658
-    /**
659
-     * @param $file
660
-     * @param $cacheId
661
-     * @param $compileId
662
-     *
663
-     * @return mixed
664
-     * @throws Exception
665
-     */
666
-    protected function makeTemplate($file, $cacheId, $compileId)
667
-    {
668
-        if ($compileId === null) {
669
-            $compileId = $this->compile_id;
670
-        }
671
-
672
-        $hash = bin2hex(md5($file . $cacheId . $compileId, true));
673
-        if (!isset(self::$tplCache[$hash])) {
674
-            // abs path
675
-            if (substr($file, 0, 1) === '/' || substr($file, 1, 1) === ':') {
676
-                self::$tplCache[$hash] = new TemplateFile($file, null, $cacheId, $compileId);
677
-            } elseif (is_string($this->template_dir) || is_array($this->template_dir)) {
678
-                self::$tplCache[$hash] = new TemplateFile($file, null, $cacheId, $compileId, $this->template_dir);
679
-            } else {
680
-                throw new Exception('Unable to load "' . $file . '", check the template_dir');
681
-            }
682
-        }
683
-
684
-        return self::$tplCache[$hash];
685
-    }
686
-
687
-    /**
688
-     * @param string $message
689
-     * @param int    $level
690
-     */
691
-    public function triggerError($message, $level = E_USER_NOTICE)
692
-    {
693
-        if (is_object($this->template)) {
694
-            parent::triggerError($message, $level);
695
-        }
696
-        trigger_error('Dwoo error : ' . $message, $level);
697
-    }
46
+	/**
47
+	 * Magic get/set/call functions that handle unsupported features
48
+	 *
49
+	 * @param string $p
50
+	 * @param string $v
51
+	 */
52
+	public function __set($p, $v)
53
+	{
54
+		if ($p === 'scope') {
55
+			$this->scope = $v;
56
+
57
+			return;
58
+		}
59
+		if ($p === 'data') {
60
+			$this->data = $v;
61
+
62
+			return;
63
+		}
64
+		if (array_key_exists($p, $this->compat['properties']) !== false) {
65
+			if ($this->show_compat_errors) {
66
+				$this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
67
+			}
68
+			$this->compat['properties'][$p] = $v;
69
+		} else {
70
+			if ($this->show_compat_errors) {
71
+				$this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
72
+			}
73
+		}
74
+	}
75
+
76
+	/**
77
+	 * @param $p
78
+	 *
79
+	 * @return mixed
80
+	 */
81
+	public function __get($p)
82
+	{
83
+		if (array_key_exists($p, $this->compat['properties']) !== false) {
84
+			if ($this->show_compat_errors) {
85
+				$this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
86
+			}
87
+
88
+			return $this->compat['properties'][$p];
89
+		} else {
90
+			if ($this->show_compat_errors) {
91
+				$this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
92
+			}
93
+		}
94
+	}
95
+
96
+	/**
97
+	 * @param string $m
98
+	 * @param array  $a
99
+	 *
100
+	 * @return mixed|void
101
+	 */
102
+	public function __call($m, $a)
103
+	{
104
+		if (method_exists($this->dataProvider, $m)) {
105
+			call_user_func_array(
106
+				array(
107
+				$this->dataProvider,
108
+				$m
109
+				), $a
110
+			);
111
+		} elseif ($this->show_compat_errors) {
112
+			if (array_search($m, $this->compat['methods']) !== false) {
113
+				$this->triggerError('Method ' . $m . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
114
+			} else {
115
+				$this->triggerError('Method ' . $m . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
116
+			}
117
+		}
118
+	}
119
+
120
+	/**
121
+	 * List of unsupported properties and methods
122
+	 */
123
+	protected $compat = array(
124
+		'methods'    => array(
125
+			'register_resource',
126
+			'unregister_resource',
127
+			'load_filter',
128
+			'clear_compiled_tpl',
129
+			'clear_config',
130
+			'get_config_vars',
131
+			'config_load',
132
+		),
133
+		'properties' => array(
134
+			'cache_handler_func'            => null,
135
+			'debugging'                     => false,
136
+			'error_reporting'               => null,
137
+			'debugging_ctrl'                => 'NONE',
138
+			'request_vars_order'            => 'EGPCS',
139
+			'request_use_auto_globals'      => true,
140
+			'use_sub_dirs'                  => false,
141
+			'autoload_filters'              => array(),
142
+			'default_template_handler_func' => '',
143
+			'debug_tpl'                     => '',
144
+			'cache_modified_check'          => false,
145
+			'default_modifiers'             => array(),
146
+			'default_resource_type'         => 'file',
147
+			'config_overwrite'              => true,
148
+			'config_booleanize'             => true,
149
+			'config_read_hidden'            => false,
150
+			'config_fix_newlines'           => true,
151
+			'config_class'                  => 'Config_File',
152
+		),
153
+	);
154
+
155
+	/**
156
+	 * Security vars
157
+	 */
158
+	public $security          = false;
159
+	public $trusted_dir       = array();
160
+	public $secure_dir        = array();
161
+	public $php_handling      = SMARTY_PHP_PASSTHRU;
162
+	public $security_settings = array(
163
+		'PHP_HANDLING'    => false,
164
+		'IF_FUNCS'        => array(
165
+			'list',
166
+			'empty',
167
+			'count',
168
+			'sizeof',
169
+			'in_array',
170
+			'is_array',
171
+		),
172
+		'INCLUDE_ANY'     => false,
173
+		'PHP_TAGS'        => false,
174
+		'MODIFIER_FUNCS'  => array(),
175
+		'ALLOW_CONSTANTS' => false,
176
+	);
177
+
178
+	/**
179
+	 * Paths
180
+	 */
181
+	public $template_dir = 'templates';
182
+	public $compile_dir  = 'templates_c';
183
+	public $config_dir   = 'configs';
184
+	public $cache_dir    = 'cache';
185
+	public $plugins_dir  = array();
186
+
187
+	/**
188
+	 * Misc options
189
+	 */
190
+	public $left_delimiter  = '{';
191
+	public $right_delimiter = '}';
192
+	public $compile_check   = true;
193
+	public $force_compile   = false;
194
+	public $caching         = 0;
195
+	public $cache_lifetime  = 3600;
196
+	public $compile_id      = null;
197
+	public $compiler_file   = null;
198
+	public $compiler_class  = null;
199
+
200
+	/**
201
+	 * Dwoo/Smarty compat layer
202
+	 */
203
+	public           $show_compat_errors = false;
204
+	protected        $dataProvider;
205
+	protected        $_filters           = array(
206
+		'pre'    => array(),
207
+		'post'   => array(),
208
+		'output' => array()
209
+	);
210
+	protected static $tplCache           = array();
211
+	protected        $compiler           = null;
212
+
213
+	/**
214
+	 * Adapter constructor.
215
+	 */
216
+	public function __construct()
217
+	{
218
+		parent::__construct();
219
+		$this->charset      = 'iso-8859-1';
220
+		$this->dataProvider = new Data();
221
+		$this->compiler     = new Compiler();
222
+	}
223
+
224
+	/**
225
+	 * @param      $filename
226
+	 * @param null $cacheId
227
+	 * @param null $compileId
228
+	 */
229
+	public function display($filename, $cacheId = null, $compileId = null)
230
+	{
231
+		$this->fetch($filename, $cacheId, $compileId, true);
232
+	}
233
+
234
+	/**
235
+	 * @param      $filename
236
+	 * @param null $cacheId
237
+	 * @param null $compileId
238
+	 * @param bool $display
239
+	 *
240
+	 * @return string|void
241
+	 */
242
+	public function fetch($filename, $cacheId = null, $compileId = null, $display = false)
243
+	{
244
+		$this->setCacheDir($this->cache_dir);
245
+		$this->setCompileDir($this->compile_dir);
246
+
247
+		if ($this->security) {
248
+			$policy = new SecurityPolicy();
249
+			$policy->addPhpFunction(array_merge($this->security_settings['IF_FUNCS'], $this->security_settings['MODIFIER_FUNCS']));
250
+
251
+			$phpTags = $this->security_settings['PHP_HANDLING'] ? SMARTY_PHP_ALLOW : $this->php_handling;
252
+			if ($this->security_settings['PHP_TAGS']) {
253
+				$phpTags = SMARTY_PHP_ALLOW;
254
+			}
255
+			switch ($phpTags) {
256
+			case SMARTY_PHP_ALLOW:
257
+			case SMARTY_PHP_PASSTHRU:
258
+				$phpTags = SecurityPolicy::PHP_ALLOW;
259
+				break;
260
+			case SMARTY_PHP_QUOTE:
261
+				$phpTags = SecurityPolicy::PHP_ENCODE;
262
+				break;
263
+			case SMARTY_PHP_REMOVE:
264
+			default:
265
+				$phpTags = SecurityPolicy::PHP_REMOVE;
266
+				break;
267
+			}
268
+			$policy->setPhpHandling($phpTags);
269
+
270
+			$policy->setConstantHandling($this->security_settings['ALLOW_CONSTANTS']);
271
+
272
+			if ($this->security_settings['INCLUDE_ANY']) {
273
+				$policy->allowDirectory(preg_replace('{^((?:[a-z]:)?[\\\\/]).*}i', '$1', __FILE__));
274
+			} else {
275
+				$policy->allowDirectory($this->secure_dir);
276
+			}
277
+
278
+			$this->setSecurityPolicy($policy);
279
+		}
280
+
281
+		if (!empty($this->plugins_dir)) {
282
+			foreach ($this->plugins_dir as $dir) {
283
+				$this->getLoader()->addDirectory(rtrim($dir, '\\/'));
284
+			}
285
+		}
286
+
287
+		$tpl = $this->makeTemplate($filename, $cacheId, $compileId);
288
+		if ($this->force_compile) {
289
+			$tpl->forceCompilation();
290
+		}
291
+
292
+		if ($this->caching > 0) {
293
+			$this->cacheTime = $this->cache_lifetime;
294
+		} else {
295
+			$this->cacheTime = 0;
296
+		}
297
+
298
+		if ($this->compiler_class !== null) {
299
+			if ($this->compiler_file !== null && !class_exists($this->compiler_class)) {
300
+				include $this->compiler_file;
301
+			}
302
+			$this->compiler = new $this->compiler_class();
303
+		} else {
304
+			$this->compiler->addPreProcessor('PluginSmartyCompatible', true);
305
+			$this->compiler->setLooseOpeningHandling(true);
306
+		}
307
+
308
+		$this->compiler->setDelimiters($this->left_delimiter, $this->right_delimiter);
309
+
310
+		return $this->get($tpl, $this->dataProvider, $this->compiler, $display === true);
311
+	}
312
+
313
+	/**
314
+	 * @param mixed $_tpl
315
+	 * @param array $data
316
+	 * @param null  $_compiler
317
+	 * @param bool  $_output
318
+	 *
319
+	 * @return string|void
320
+	 */
321
+	public function get($_tpl, $data = array(), $_compiler = null, $_output = false)
322
+	{
323
+		if ($_compiler === null) {
324
+			$_compiler = $this->compiler;
325
+		}
326
+
327
+		return parent::get($_tpl, $data, $_compiler, $_output);
328
+	}
329
+
330
+	/**
331
+	 * @param      $name
332
+	 * @param      $callback
333
+	 * @param bool $cacheable
334
+	 * @param null $cache_attrs
335
+	 *
336
+	 * @throws Exception
337
+	 */
338
+	public function register_function($name, $callback, $cacheable = true, $cache_attrs = null)
339
+	{
340
+		if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_FUNCTION) {
341
+			throw new Exception('Multiple plugins of different types can not share the same name');
342
+		}
343
+		$this->plugins[$name] = array(
344
+			'type'     => self::SMARTY_FUNCTION,
345
+			'callback' => $callback
346
+		);
347
+	}
348
+
349
+	/**
350
+	 * @param $name
351
+	 */
352
+	public function unregister_function($name)
353
+	{
354
+		unset($this->plugins[$name]);
355
+	}
356
+
357
+	/**
358
+	 * @param      $name
359
+	 * @param      $callback
360
+	 * @param bool $cacheable
361
+	 * @param null $cache_attrs
362
+	 *
363
+	 * @throws Exception
364
+	 */
365
+	public function register_block($name, $callback, $cacheable = true, $cache_attrs = null)
366
+	{
367
+		if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_BLOCK) {
368
+			throw new Exception('Multiple plugins of different types can not share the same name');
369
+		}
370
+		$this->plugins[$name] = array(
371
+			'type'     => self::SMARTY_BLOCK,
372
+			'callback' => $callback
373
+		);
374
+	}
375
+
376
+	/**
377
+	 * @param $name
378
+	 */
379
+	public function unregister_block($name)
380
+	{
381
+		unset($this->plugins[$name]);
382
+	}
383
+
384
+	/**
385
+	 * @param $name
386
+	 * @param $callback
387
+	 *
388
+	 * @throws Exception
389
+	 */
390
+	public function register_modifier($name, $callback)
391
+	{
392
+		if (isset($this->plugins[$name]) && $this->plugins[$name][0] !== self::SMARTY_MODIFIER) {
393
+			throw new Exception('Multiple plugins of different types can not share the same name');
394
+		}
395
+		$this->plugins[$name] = array(
396
+			'type'     => self::SMARTY_MODIFIER,
397
+			'callback' => $callback
398
+		);
399
+	}
400
+
401
+	/**
402
+	 * @param $name
403
+	 */
404
+	public function unregister_modifier($name)
405
+	{
406
+		unset($this->plugins[$name]);
407
+	}
408
+
409
+	/**
410
+	 * @param $callback
411
+	 */
412
+	public function register_prefilter($callback)
413
+	{
414
+		$processor = new ProcessorAdapter($this->compiler);
415
+		$processor->registerCallback($callback);
416
+		$this->_filters['pre'][] = $processor;
417
+		$this->compiler->addPreProcessor($processor);
418
+	}
419
+
420
+	/**
421
+	 * @param $callback
422
+	 */
423
+	public function unregister_prefilter($callback)
424
+	{
425
+		foreach ($this->_filters['pre'] as $index => $processor) {
426
+			if ($processor->callback === $callback) {
427
+				$this->compiler->removePostProcessor($processor);
428
+				unset($this->_filters['pre'][$index]);
429
+			}
430
+		}
431
+	}
432
+
433
+	/**
434
+	 * @param $callback
435
+	 */
436
+	public function register_postfilter($callback)
437
+	{
438
+		$processor = new ProcessorAdapter($this->compiler);
439
+		$processor->registerCallback($callback);
440
+		$this->_filters['post'][] = $processor;
441
+		$this->compiler->addPostProcessor($processor);
442
+	}
443
+
444
+	/**
445
+	 * @param $callback
446
+	 */
447
+	public function unregister_postfilter($callback)
448
+	{
449
+		foreach ($this->_filters['post'] as $index => $processor) {
450
+			if ($processor->callback === $callback) {
451
+				$this->compiler->removePostProcessor($processor);
452
+				unset($this->_filters['post'][$index]);
453
+			}
454
+		}
455
+	}
456
+
457
+	/**
458
+	 * @param $callback
459
+	 */
460
+	public function register_outputfilter($callback)
461
+	{
462
+		$filter = new FilterAdapter($this);
463
+		$filter->registerCallback($callback);
464
+		$this->_filters['output'][] = $filter;
465
+		$this->addFilter($filter);
466
+	}
467
+
468
+	/**
469
+	 * @param $callback
470
+	 */
471
+	public function unregister_outputfilter($callback)
472
+	{
473
+		foreach ($this->_filters['output'] as $index => $filter) {
474
+			if ($filter->callback === $callback) {
475
+				$this->removeOutputFilter($filter);
476
+				unset($this->_filters['output'][$index]);
477
+			}
478
+		}
479
+	}
480
+
481
+	/**
482
+	 * @param       $object
483
+	 * @param       $object_impl
484
+	 * @param array $allowed
485
+	 * @param bool  $smarty_args
486
+	 * @param array $block_methods
487
+	 */
488
+	public function register_object($object, $object_impl, $allowed = array(), $smarty_args = false, $block_methods = array())
489
+	{
490
+		settype($allowed, 'array');
491
+		settype($block_methods, 'array');
492
+		settype($smarty_args, 'boolean');
493
+
494
+		if (!empty($allowed) && $this->show_compat_errors) {
495
+			$this->triggerError('You can register objects but can not restrict the method/properties used, this is PHP5, you have proper OOP access restrictions so use them.', E_USER_NOTICE);
496
+		}
497
+
498
+		if ($smarty_args) {
499
+			$this->triggerError('You can register objects but methods will be called using method($arg1, $arg2, $arg3), not as an argument array like smarty did.', E_USER_NOTICE);
500
+		}
501
+
502
+		if (!empty($block_methods)) {
503
+			$this->triggerError('You can register objects but can not use methods as being block methods, you have to build a plugin for that.', E_USER_NOTICE);
504
+		}
505
+
506
+		$this->dataProvider->assign($object, $object_impl);
507
+	}
508
+
509
+	/**
510
+	 * @param $object
511
+	 */
512
+	public function unregister_object($object)
513
+	{
514
+		$this->dataProvider->clear($object);
515
+	}
516
+
517
+	/**
518
+	 * @param $name
519
+	 *
520
+	 * @return mixed
521
+	 */
522
+	public function get_registered_object($name)
523
+	{
524
+		$data = $this->dataProvider->getData();
525
+		if (isset($data[$name]) && is_object($data[$name])) {
526
+			return $data[$name];
527
+		} else {
528
+			trigger_error('Dwoo_Compiler: object "' . $name . '" was not registered or is not an object', E_USER_ERROR);
529
+		}
530
+	}
531
+
532
+	/**
533
+	 * @param $filename
534
+	 *
535
+	 * @return bool
536
+	 */
537
+	public function template_exists($filename)
538
+	{
539
+		if (!is_array($this->template_dir)) {
540
+			return file_exists($this->template_dir . DIRECTORY_SEPARATOR . $filename);
541
+		} else {
542
+			foreach ($this->template_dir as $tpl_dir) {
543
+				if (file_exists($tpl_dir . DIRECTORY_SEPARATOR . $filename)) {
544
+					return true;
545
+				}
546
+			}
547
+
548
+			return false;
549
+		}
550
+	}
551
+
552
+	/**
553
+	 * @param      $tpl
554
+	 * @param null $cacheId
555
+	 * @param null $compileId
556
+	 *
557
+	 * @return bool
558
+	 */
559
+	public function is_cached($tpl, $cacheId = null, $compileId = null)
560
+	{
561
+		return $this->isCached($this->makeTemplate($tpl, $cacheId, $compileId));
562
+	}
563
+
564
+	/**
565
+	 * @param      $var
566
+	 * @param      $value
567
+	 * @param bool $merge
568
+	 */
569
+	public function append_by_ref($var, &$value, $merge = false)
570
+	{
571
+		$this->dataProvider->appendByRef($var, $value, $merge);
572
+	}
573
+
574
+	/**
575
+	 * @param $name
576
+	 * @param $val
577
+	 */
578
+	public function assign_by_ref($name, &$val)
579
+	{
580
+		$this->dataProvider->assignByRef($name, $val);
581
+	}
582
+
583
+	/**
584
+	 * @param $var
585
+	 */
586
+	public function clear_assign($var)
587
+	{
588
+		$this->dataProvider->clear($var);
589
+	}
590
+
591
+	/**
592
+	 *
593
+	 */
594
+	public function clear_all_assign()
595
+	{
596
+		$this->dataProvider->clear();
597
+	}
598
+
599
+	/**
600
+	 * @param null $name
601
+	 *
602
+	 * @return array|null
603
+	 */
604
+	public function get_template_vars($name = null)
605
+	{
606
+		if ($this->show_compat_errors) {
607
+			trigger_error('get_template_vars does not return values by reference, if you try to modify the data that way you should modify your code.', E_USER_NOTICE);
608
+		}
609
+
610
+		$data = $this->dataProvider->getData();
611
+		if ($name === null) {
612
+			return $data;
613
+		} elseif (isset($data[$name])) {
614
+			return $data[$name];
615
+		}
616
+
617
+		return null;
618
+	}
619
+
620
+	/**
621
+	 * @param int $olderThan
622
+	 */
623
+	public function clear_all_cache($olderThan = 0)
624
+	{
625
+		$this->clearCache($olderThan);
626
+	}
627
+
628
+	/**
629
+	 * @param      $template
630
+	 * @param null $cacheId
631
+	 * @param null $compileId
632
+	 * @param int  $olderThan
633
+	 */
634
+	public function clear_cache($template, $cacheId = null, $compileId = null, $olderThan = 0)
635
+	{
636
+		$this->makeTemplate($template, $cacheId, $compileId)->clearCache($olderThan);
637
+	}
638
+
639
+	/**
640
+	 * @param     $error_msg
641
+	 * @param int $error_type
642
+	 */
643
+	public function trigger_error($error_msg, $error_type = E_USER_WARNING)
644
+	{
645
+		$this->triggerError($error_msg, $error_type);
646
+	}
647
+
648
+	/**
649
+	 *
650
+	 */
651
+	protected function initGlobals()
652
+	{
653
+		parent::initGlobals();
654
+		$this->globals['ldelim'] = '{';
655
+		$this->globals['rdelim'] = '}';
656
+	}
657
+
658
+	/**
659
+	 * @param $file
660
+	 * @param $cacheId
661
+	 * @param $compileId
662
+	 *
663
+	 * @return mixed
664
+	 * @throws Exception
665
+	 */
666
+	protected function makeTemplate($file, $cacheId, $compileId)
667
+	{
668
+		if ($compileId === null) {
669
+			$compileId = $this->compile_id;
670
+		}
671
+
672
+		$hash = bin2hex(md5($file . $cacheId . $compileId, true));
673
+		if (!isset(self::$tplCache[$hash])) {
674
+			// abs path
675
+			if (substr($file, 0, 1) === '/' || substr($file, 1, 1) === ':') {
676
+				self::$tplCache[$hash] = new TemplateFile($file, null, $cacheId, $compileId);
677
+			} elseif (is_string($this->template_dir) || is_array($this->template_dir)) {
678
+				self::$tplCache[$hash] = new TemplateFile($file, null, $cacheId, $compileId, $this->template_dir);
679
+			} else {
680
+				throw new Exception('Unable to load "' . $file . '", check the template_dir');
681
+			}
682
+		}
683
+
684
+		return self::$tplCache[$hash];
685
+	}
686
+
687
+	/**
688
+	 * @param string $message
689
+	 * @param int    $level
690
+	 */
691
+	public function triggerError($message, $level = E_USER_NOTICE)
692
+	{
693
+		if (is_object($this->template)) {
694
+			parent::triggerError($message, $level);
695
+		}
696
+		trigger_error('Dwoo error : ' . $message, $level);
697
+	}
698 698
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -63,12 +63,12 @@  discard block
 block discarded – undo
63 63
         }
64 64
         if (array_key_exists($p, $this->compat['properties']) !== false) {
65 65
             if ($this->show_compat_errors) {
66
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
66
+                $this->triggerError('Property '.$p.' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
67 67
             }
68 68
             $this->compat['properties'][$p] = $v;
69 69
         } else {
70 70
             if ($this->show_compat_errors) {
71
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
71
+                $this->triggerError('Property '.$p.' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
72 72
             }
73 73
         }
74 74
     }
@@ -82,13 +82,13 @@  discard block
 block discarded – undo
82 82
     {
83 83
         if (array_key_exists($p, $this->compat['properties']) !== false) {
84 84
             if ($this->show_compat_errors) {
85
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
85
+                $this->triggerError('Property '.$p.' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
86 86
             }
87 87
 
88 88
             return $this->compat['properties'][$p];
89 89
         } else {
90 90
             if ($this->show_compat_errors) {
91
-                $this->triggerError('Property ' . $p . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
91
+                $this->triggerError('Property '.$p.' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
92 92
             }
93 93
         }
94 94
     }
@@ -110,9 +110,9 @@  discard block
 block discarded – undo
110 110
             );
111 111
         } elseif ($this->show_compat_errors) {
112 112
             if (array_search($m, $this->compat['methods']) !== false) {
113
-                $this->triggerError('Method ' . $m . ' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
113
+                $this->triggerError('Method '.$m.' is not available in the Dwoo\Smarty\Adapter, however it might be implemented in the future, check out http://wiki.dwoo.org/index.php/SmartySupport for more details.', E_USER_NOTICE);
114 114
             } else {
115
-                $this->triggerError('Method ' . $m . ' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
115
+                $this->triggerError('Method '.$m.' is not available in the Dwoo\Smarty\Adapter, but it is not listed as such, so you might want to tell me about it at [email protected]', E_USER_NOTICE);
116 116
             }
117 117
         }
118 118
     }
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
         if (isset($data[$name]) && is_object($data[$name])) {
526 526
             return $data[$name];
527 527
         } else {
528
-            trigger_error('Dwoo_Compiler: object "' . $name . '" was not registered or is not an object', E_USER_ERROR);
528
+            trigger_error('Dwoo_Compiler: object "'.$name.'" was not registered or is not an object', E_USER_ERROR);
529 529
         }
530 530
     }
531 531
 
@@ -537,10 +537,10 @@  discard block
 block discarded – undo
537 537
     public function template_exists($filename)
538 538
     {
539 539
         if (!is_array($this->template_dir)) {
540
-            return file_exists($this->template_dir . DIRECTORY_SEPARATOR . $filename);
540
+            return file_exists($this->template_dir.DIRECTORY_SEPARATOR.$filename);
541 541
         } else {
542 542
             foreach ($this->template_dir as $tpl_dir) {
543
-                if (file_exists($tpl_dir . DIRECTORY_SEPARATOR . $filename)) {
543
+                if (file_exists($tpl_dir.DIRECTORY_SEPARATOR.$filename)) {
544 544
                     return true;
545 545
                 }
546 546
             }
@@ -669,7 +669,7 @@  discard block
 block discarded – undo
669 669
             $compileId = $this->compile_id;
670 670
         }
671 671
 
672
-        $hash = bin2hex(md5($file . $cacheId . $compileId, true));
672
+        $hash = bin2hex(md5($file.$cacheId.$compileId, true));
673 673
         if (!isset(self::$tplCache[$hash])) {
674 674
             // abs path
675 675
             if (substr($file, 0, 1) === '/' || substr($file, 1, 1) === ':') {
@@ -677,7 +677,7 @@  discard block
 block discarded – undo
677 677
             } elseif (is_string($this->template_dir) || is_array($this->template_dir)) {
678 678
                 self::$tplCache[$hash] = new TemplateFile($file, null, $cacheId, $compileId, $this->template_dir);
679 679
             } else {
680
-                throw new Exception('Unable to load "' . $file . '", check the template_dir');
680
+                throw new Exception('Unable to load "'.$file.'", check the template_dir');
681 681
             }
682 682
         }
683 683
 
@@ -693,6 +693,6 @@  discard block
 block discarded – undo
693 693
         if (is_object($this->template)) {
694 694
             parent::triggerError($message, $level);
695 695
         }
696
-        trigger_error('Dwoo error : ' . $message, $level);
696
+        trigger_error('Dwoo error : '.$message, $level);
697 697
     }
698 698
 }
Please login to merge, or discard this patch.
lib/Dwoo/Smarty/Processor/Adapter.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -23,23 +23,23 @@
 block discarded – undo
23 23
  */
24 24
 class Adapter extends Processor
25 25
 {
26
-    public $callback;
26
+	public $callback;
27 27
 
28
-    /**
29
-     * @param string $input
30
-     *
31
-     * @return mixed
32
-     */
33
-    public function process($input)
34
-    {
35
-        return call_user_func($this->callback, $input);
36
-    }
28
+	/**
29
+	 * @param string $input
30
+	 *
31
+	 * @return mixed
32
+	 */
33
+	public function process($input)
34
+	{
35
+		return call_user_func($this->callback, $input);
36
+	}
37 37
 
38
-    /**
39
-     * @param $callback
40
-     */
41
-    public function registerCallback($callback)
42
-    {
43
-        $this->callback = $callback;
44
-    }
38
+	/**
39
+	 * @param $callback
40
+	 */
41
+	public function registerCallback($callback)
42
+	{
43
+		$this->callback = $callback;
44
+	}
45 45
 }
46 46
\ No newline at end of file
Please login to merge, or discard this patch.