Completed
Push — master ( bf2930...494091 )
by David
07:08 queued 03:26
created
lib/Dwoo/Compilation/Exception.php 2 patches
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -26,35 +26,35 @@
 block discarded – undo
26 26
  */
27 27
 class Exception extends DwooException
28 28
 {
29
-    protected $compiler;
30
-    protected $template;
29
+	protected $compiler;
30
+	protected $template;
31 31
 
32
-    /**
33
-     * Exception constructor.
34
-     *
35
-     * @param DwooCompiler $compiler
36
-     * @param int          $message
37
-     */
38
-    public function __construct(DwooCompiler $compiler, $message)
39
-    {
40
-        $this->compiler = $compiler;
41
-        $this->template = $compiler->getDwoo()->getTemplate();
42
-        parent::__construct('Compilation error at line ' . $compiler->getLine() . ' in "' . $this->template->getResourceName() . ':' . $this->template->getResourceIdentifier() . '" : ' . $message);
43
-    }
32
+	/**
33
+	 * Exception constructor.
34
+	 *
35
+	 * @param DwooCompiler $compiler
36
+	 * @param int          $message
37
+	 */
38
+	public function __construct(DwooCompiler $compiler, $message)
39
+	{
40
+		$this->compiler = $compiler;
41
+		$this->template = $compiler->getDwoo()->getTemplate();
42
+		parent::__construct('Compilation error at line ' . $compiler->getLine() . ' in "' . $this->template->getResourceName() . ':' . $this->template->getResourceIdentifier() . '" : ' . $message);
43
+	}
44 44
 
45
-    /**
46
-     * @return DwooCompiler
47
-     */
48
-    public function getCompiler()
49
-    {
50
-        return $this->compiler;
51
-    }
45
+	/**
46
+	 * @return DwooCompiler
47
+	 */
48
+	public function getCompiler()
49
+	{
50
+		return $this->compiler;
51
+	}
52 52
 
53
-    /**
54
-     * @return \Dwoo\ITemplate|null
55
-     */
56
-    public function getTemplate()
57
-    {
58
-        return $this->template;
59
-    }
53
+	/**
54
+	 * @return \Dwoo\ITemplate|null
55
+	 */
56
+	public function getTemplate()
57
+	{
58
+		return $this->template;
59
+	}
60 60
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -39,7 +39,7 @@
 block discarded – undo
39 39
     {
40 40
         $this->compiler = $compiler;
41 41
         $this->template = $compiler->getDwoo()->getTemplate();
42
-        parent::__construct('Compilation error at line ' . $compiler->getLine() . ' in "' . $this->template->getResourceName() . ':' . $this->template->getResourceIdentifier() . '" : ' . $message);
42
+        parent::__construct('Compilation error at line '.$compiler->getLine().' in "'.$this->template->getResourceName().':'.$this->template->getResourceIdentifier().'" : '.$message);
43 43
     }
44 44
 
45 45
     /**
Please login to merge, or discard this patch.
lib/Dwoo/IPluginProxy.php 1 patch
Indentation   +45 added lines, -45 removed lines patch added patch discarded remove patch
@@ -23,52 +23,52 @@
 block discarded – undo
23 23
  */
24 24
 interface IPluginProxy
25 25
 {
26
-    /**
27
-     * Returns true or false to say whether the given plugin is handled by this proxy or not.
28
-     *
29
-     * @param string $name the plugin name
30
-     *
31
-     * @return bool true if the plugin is known and usable, otherwise false
32
-     */
33
-    public function handles($name);
26
+	/**
27
+	 * Returns true or false to say whether the given plugin is handled by this proxy or not.
28
+	 *
29
+	 * @param string $name the plugin name
30
+	 *
31
+	 * @return bool true if the plugin is known and usable, otherwise false
32
+	 */
33
+	public function handles($name);
34 34
 
35
-    /**
36
-     * Returns the code (as a string) to call the plugin
37
-     * (this will be executed at runtime inside the Dwoo class).
38
-     *
39
-     * @param string $name   the plugin name
40
-     * @param array  $params a parameter array, array key "*" is the rest array
41
-     *
42
-     * @return string
43
-     */
44
-    public function getCode($name, $params);
35
+	/**
36
+	 * Returns the code (as a string) to call the plugin
37
+	 * (this will be executed at runtime inside the Dwoo class).
38
+	 *
39
+	 * @param string $name   the plugin name
40
+	 * @param array  $params a parameter array, array key "*" is the rest array
41
+	 *
42
+	 * @return string
43
+	 */
44
+	public function getCode($name, $params);
45 45
 
46
-    /**
47
-     * Returns a callback to the plugin, this is used with the reflection API to
48
-     * find out about the plugin's parameter names etc.
49
-     * should you need a rest array without the possibility to edit the
50
-     * plugin's code, you can provide a callback to some
51
-     * other function with the correct parameter signature, i.e. :
52
-     * <code>
53
-     * return array($this, "callbackHelper");
54
-     * // and callbackHelper would be as such:
55
-     * public function callbackHelper(array $rest=array()){}
56
-     * </code>
57
-     *
58
-     * @param string $name the plugin name
59
-     *
60
-     * @return callback
61
-     */
62
-    public function getCallback($name);
46
+	/**
47
+	 * Returns a callback to the plugin, this is used with the reflection API to
48
+	 * find out about the plugin's parameter names etc.
49
+	 * should you need a rest array without the possibility to edit the
50
+	 * plugin's code, you can provide a callback to some
51
+	 * other function with the correct parameter signature, i.e. :
52
+	 * <code>
53
+	 * return array($this, "callbackHelper");
54
+	 * // and callbackHelper would be as such:
55
+	 * public function callbackHelper(array $rest=array()){}
56
+	 * </code>
57
+	 *
58
+	 * @param string $name the plugin name
59
+	 *
60
+	 * @return callback
61
+	 */
62
+	public function getCallback($name);
63 63
 
64
-    /**
65
-     * Returns some code that will check if the plugin is loaded and if not load it
66
-     * this is optional, if your plugins are autoloaded or whatever, just return an
67
-     * empty string.
68
-     *
69
-     * @param string $name the plugin name
70
-     *
71
-     * @return string
72
-     */
73
-    public function getLoader($name);
64
+	/**
65
+	 * Returns some code that will check if the plugin is loaded and if not load it
66
+	 * this is optional, if your plugins are autoloaded or whatever, just return an
67
+	 * empty string.
68
+	 *
69
+	 * @param string $name the plugin name
70
+	 *
71
+	 * @return string
72
+	 */
73
+	public function getLoader($name);
74 74
 }
Please login to merge, or discard this patch.
lib/Dwoo/ITemplate.php 1 patch
Indentation   +120 added lines, -120 removed lines patch added patch discarded remove patch
@@ -23,137 +23,137 @@
 block discarded – undo
23 23
  */
24 24
 interface ITemplate
25 25
 {
26
-    /**
27
-     * Returns the cache duration for this template.
28
-     * defaults to null if it was not provided
29
-     *
30
-     * @return int|null
31
-     */
32
-    public function getCacheTime();
26
+	/**
27
+	 * Returns the cache duration for this template.
28
+	 * defaults to null if it was not provided
29
+	 *
30
+	 * @return int|null
31
+	 */
32
+	public function getCacheTime();
33 33
 
34
-    /**
35
-     * Sets the cache duration for this template.
36
-     * can be used to set it after the object is created if you did not provide
37
-     * it in the constructor
38
-     *
39
-     * @param int $seconds duration of the cache validity for this template, if
40
-     *                     null it defaults to the Dwoo instance's cache time. 0 = disable and
41
-     *                     -1 = infinite cache
42
-     */
43
-    public function setCacheTime($seconds = null);
34
+	/**
35
+	 * Sets the cache duration for this template.
36
+	 * can be used to set it after the object is created if you did not provide
37
+	 * it in the constructor
38
+	 *
39
+	 * @param int $seconds duration of the cache validity for this template, if
40
+	 *                     null it defaults to the Dwoo instance's cache time. 0 = disable and
41
+	 *                     -1 = infinite cache
42
+	 */
43
+	public function setCacheTime($seconds = null);
44 44
 
45
-    /**
46
-     * Returns the cached template output file name, true if it's cache-able but not cached
47
-     * or false if it's not cached.
48
-     *
49
-     * @param Core $dwoo the dwoo instance that requests it
50
-     *
51
-     * @return string|bool
52
-     */
53
-    public function getCachedTemplate(Core $dwoo);
45
+	/**
46
+	 * Returns the cached template output file name, true if it's cache-able but not cached
47
+	 * or false if it's not cached.
48
+	 *
49
+	 * @param Core $dwoo the dwoo instance that requests it
50
+	 *
51
+	 * @return string|bool
52
+	 */
53
+	public function getCachedTemplate(Core $dwoo);
54 54
 
55
-    /**
56
-     * Caches the provided output into the cache file.
57
-     *
58
-     * @param Core   $dwoo   the dwoo instance that requests it
59
-     * @param string $output the template output
60
-     *
61
-     * @return mixed full path of the cached file or false upon failure
62
-     */
63
-    public function cache(Core $dwoo, $output);
55
+	/**
56
+	 * Caches the provided output into the cache file.
57
+	 *
58
+	 * @param Core   $dwoo   the dwoo instance that requests it
59
+	 * @param string $output the template output
60
+	 *
61
+	 * @return mixed full path of the cached file or false upon failure
62
+	 */
63
+	public function cache(Core $dwoo, $output);
64 64
 
65
-    /**
66
-     * Clears the cached template if it's older than the given time.
67
-     *
68
-     * @param Core $dwoo      the dwoo instance that was used to cache that template
69
-     * @param int  $olderThan minimum time (in seconds) required for the cache to be cleared
70
-     *
71
-     * @return bool true if the cache was not present or if it was deleted, false if it remains there
72
-     */
73
-    public function clearCache(Core $dwoo, $olderThan = - 1);
65
+	/**
66
+	 * Clears the cached template if it's older than the given time.
67
+	 *
68
+	 * @param Core $dwoo      the dwoo instance that was used to cache that template
69
+	 * @param int  $olderThan minimum time (in seconds) required for the cache to be cleared
70
+	 *
71
+	 * @return bool true if the cache was not present or if it was deleted, false if it remains there
72
+	 */
73
+	public function clearCache(Core $dwoo, $olderThan = - 1);
74 74
 
75
-    /**
76
-     * Returns the compiled template file name.
77
-     *
78
-     * @param Core      $dwoo     the dwoo instance that requests it
79
-     * @param ICompiler $compiler the compiler that must be used
80
-     *
81
-     * @return string
82
-     */
83
-    public function getCompiledTemplate(Core $dwoo, ICompiler $compiler = null);
75
+	/**
76
+	 * Returns the compiled template file name.
77
+	 *
78
+	 * @param Core      $dwoo     the dwoo instance that requests it
79
+	 * @param ICompiler $compiler the compiler that must be used
80
+	 *
81
+	 * @return string
82
+	 */
83
+	public function getCompiledTemplate(Core $dwoo, ICompiler $compiler = null);
84 84
 
85
-    /**
86
-     * Returns the template name.
87
-     *
88
-     * @return string
89
-     */
90
-    public function getName();
85
+	/**
86
+	 * Returns the template name.
87
+	 *
88
+	 * @return string
89
+	 */
90
+	public function getName();
91 91
 
92
-    /**
93
-     * Returns the resource name for this template class.
94
-     *
95
-     * @return string
96
-     */
97
-    public function getResourceName();
92
+	/**
93
+	 * Returns the resource name for this template class.
94
+	 *
95
+	 * @return string
96
+	 */
97
+	public function getResourceName();
98 98
 
99
-    /**
100
-     * Returns the resource identifier for this template or false if it has no identifier.
101
-     *
102
-     * @return string|false
103
-     */
104
-    public function getResourceIdentifier();
99
+	/**
100
+	 * Returns the resource identifier for this template or false if it has no identifier.
101
+	 *
102
+	 * @return string|false
103
+	 */
104
+	public function getResourceIdentifier();
105 105
 
106
-    /**
107
-     * Returns the template source of this template.
108
-     *
109
-     * @return string
110
-     */
111
-    public function getSource();
106
+	/**
107
+	 * Returns the template source of this template.
108
+	 *
109
+	 * @return string
110
+	 */
111
+	public function getSource();
112 112
 
113
-    /**
114
-     * Returns an unique string identifying the current version of this template,
115
-     * for example a timestamp of the last modified date or a hash of the template source.
116
-     *
117
-     * @return string
118
-     */
119
-    public function getUid();
113
+	/**
114
+	 * Returns an unique string identifying the current version of this template,
115
+	 * for example a timestamp of the last modified date or a hash of the template source.
116
+	 *
117
+	 * @return string
118
+	 */
119
+	public function getUid();
120 120
 
121
-    /**
122
-     * Returns the compiler used by this template, if it was just compiled, or null.
123
-     *
124
-     * @return ICompiler
125
-     */
126
-    public function getCompiler();
121
+	/**
122
+	 * Returns the compiler used by this template, if it was just compiled, or null.
123
+	 *
124
+	 * @return ICompiler
125
+	 */
126
+	public function getCompiler();
127 127
 
128
-    /**
129
-     * Returns some php code that will check if this template has been modified or not.
130
-     * if the function returns null, the template will be instanciated and then the Uid checked
131
-     *
132
-     * @return string
133
-     */
134
-    public function getIsModifiedCode();
128
+	/**
129
+	 * Returns some php code that will check if this template has been modified or not.
130
+	 * if the function returns null, the template will be instanciated and then the Uid checked
131
+	 *
132
+	 * @return string
133
+	 */
134
+	public function getIsModifiedCode();
135 135
 
136
-    /**
137
-     * Returns a new template object from the given resource identifier, null if no include is
138
-     * possible (resource not found), or false if include is not permitted by this resource type.
139
-     * this method should also check if $dwoo->getSecurityPolicy() is null or not and do the
140
-     * necessary permission checks if required, if the security policy prevents the template
141
-     * generation it should throw a new Security\Exception with a relevant message
142
-     *
143
-     * @param mixed     $resourceId     the resource identifier
144
-     * @param int       $cacheTime      duration of the cache validity for this template, if null it defaults to the
145
-     *                                  Dwoo instance that will render this template if null it defaults to the Dwoo
146
-     *                                  instance that will render this template
147
-     * @param string    $cacheId        the unique cache identifier of this page or anything else that makes this
148
-     *                                  template's content unique, if null it defaults to the current url makes this
149
-     *                                  template's content unique, if null it defaults to the current url
150
-     * @param string    $compileId      the unique compiled identifier, which is used to distinguish this template from
151
-     *                                  others, if null it defaults to the filename+bits of the path template from
152
-     *                                  others, if null it defaults to the filename+bits of the path
153
-     * @param ITemplate $parentTemplate the template that is requesting a new template object (through an include,
154
-     *                                  extends or any other plugin) an include, extends or any other plugin)
155
-     *
156
-     * @return ITemplate|null|false
157
-     */
158
-    public static function templateFactory(Core $dwoo, $resourceId, $cacheTime = null, $cacheId = null, $compileId = null, ITemplate $parentTemplate = null);
136
+	/**
137
+	 * Returns a new template object from the given resource identifier, null if no include is
138
+	 * possible (resource not found), or false if include is not permitted by this resource type.
139
+	 * this method should also check if $dwoo->getSecurityPolicy() is null or not and do the
140
+	 * necessary permission checks if required, if the security policy prevents the template
141
+	 * generation it should throw a new Security\Exception with a relevant message
142
+	 *
143
+	 * @param mixed     $resourceId     the resource identifier
144
+	 * @param int       $cacheTime      duration of the cache validity for this template, if null it defaults to the
145
+	 *                                  Dwoo instance that will render this template if null it defaults to the Dwoo
146
+	 *                                  instance that will render this template
147
+	 * @param string    $cacheId        the unique cache identifier of this page or anything else that makes this
148
+	 *                                  template's content unique, if null it defaults to the current url makes this
149
+	 *                                  template's content unique, if null it defaults to the current url
150
+	 * @param string    $compileId      the unique compiled identifier, which is used to distinguish this template from
151
+	 *                                  others, if null it defaults to the filename+bits of the path template from
152
+	 *                                  others, if null it defaults to the filename+bits of the path
153
+	 * @param ITemplate $parentTemplate the template that is requesting a new template object (through an include,
154
+	 *                                  extends or any other plugin) an include, extends or any other plugin)
155
+	 *
156
+	 * @return ITemplate|null|false
157
+	 */
158
+	public static function templateFactory(Core $dwoo, $resourceId, $cacheTime = null, $cacheId = null, $compileId = null, ITemplate $parentTemplate = null);
159 159
 }
Please login to merge, or discard this patch.
lib/Dwoo/Core.php 4 patches
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -549,8 +549,7 @@
 block discarded – undo
549 549
             if (!class_exists($class) && !function_exists($class)) {
550 550
                 try {
551 551
                     $this->getLoader()->loadPlugin($callback);
552
-                }
553
-                catch (Exception $e) {
552
+                } catch (Exception $e) {
554 553
                     if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) {
555 554
                         throw new Exception(
556 555
                             'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should 
Please login to merge, or discard this patch.
Doc Comments   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -426,7 +426,7 @@  discard block
 block discarded – undo
426 426
      * but after, you can only update existing globals.
427 427
      *
428 428
      * @param string $name
429
-     * @param mixed  $value
429
+     * @param string  $value
430 430
      *
431 431
      * @return $this
432 432
      * @throws Exception
@@ -576,7 +576,7 @@  discard block
 block discarded – undo
576 576
      * Adds a filter to this Dwoo instance, it will be used to filter the output of all the templates rendered by this
577 577
      * instance.
578 578
      *
579
-     * @param mixed $callback a callback or a filter name if it is autoloaded from a plugin directory
579
+     * @param Smarty\Filter\Adapter $callback a callback or a filter name if it is autoloaded from a plugin directory
580 580
      * @param bool  $autoload if true, the first parameter must be a filter name from one of the plugin directories
581 581
      *
582 582
      * @return void
@@ -1614,7 +1614,7 @@  discard block
 block discarded – undo
1614 1614
      * @param mixed  $value the value to assign
1615 1615
      * @param string $scope the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property")
1616 1616
      *
1617
-     * @return bool true if assigned correctly or false if a problem occured while parsing the var string
1617
+     * @return null|false true if assigned correctly or false if a problem occured while parsing the var string
1618 1618
      */
1619 1619
     public function assignInScope($value, $scope)
1620 1620
     {
Please login to merge, or discard this patch.
Indentation   +1738 added lines, -1738 removed lines patch added patch discarded remove patch
@@ -44,1750 +44,1750 @@
 block discarded – undo
44 44
  */
45 45
 class Core
46 46
 {
47
-    /**
48
-     * Current version number.
49
-     *
50
-     * @var string
51
-     */
52
-    const VERSION = '1.3.2';
53
-
54
-    /**
55
-     * Unique number of this dwoo release, based on version number.
56
-     * this can be used by templates classes to check whether the compiled template
57
-     * has been compiled before this release or not, so that old templates are
58
-     * recompiled automatically when Dwoo is updated
59
-     */
60
-    const RELEASE_TAG = 132;
61
-
62
-    /**
63
-     * Constants that represents all plugin types
64
-     * these are bitwise-operation-safe values to allow multiple types
65
-     * on a single plugin
66
-     *
67
-     * @var int
68
-     */
69
-    const CLASS_PLUGIN      = 1;
70
-    const FUNC_PLUGIN       = 2;
71
-    const NATIVE_PLUGIN     = 4;
72
-    const BLOCK_PLUGIN      = 8;
73
-    const COMPILABLE_PLUGIN = 16;
74
-    const CUSTOM_PLUGIN     = 32;
75
-    const SMARTY_MODIFIER   = 64;
76
-    const SMARTY_BLOCK      = 128;
77
-    const SMARTY_FUNCTION   = 256;
78
-    const PROXY_PLUGIN      = 512;
79
-    const TEMPLATE_PLUGIN   = 1024;
80
-
81
-    /**
82
-     * Constant to default namespaces of builtin plugins
83
-     *
84
-     * @var string
85
-     */
86
-    const NAMESPACE_PLUGINS_BLOCKS     = 'Dwoo\Plugins\Blocks\\';
87
-    const NAMESPACE_PLUGINS_FILTERS    = 'Dwoo\Plugins\Filters\\';
88
-    const NAMESPACE_PLUGINS_FUNCTIONS  = 'Dwoo\Plugins\Functions\\';
89
-    const NAMESPACE_PLUGINS_HELPERS    = 'Dwoo\Plugins\Helpers\\';
90
-    const NAMESPACE_PLUGINS_PROCESSORS = 'Dwoo\Plugins\Processors\\';
91
-
92
-    /**
93
-     * Character set of the template, used by string manipulation plugins.
94
-     * it must be lowercase, but setCharset() will take care of that
95
-     *
96
-     * @see setCharset
97
-     * @see getCharset
98
-     * @var string
99
-     */
100
-    protected $charset = 'UTF-8';
101
-
102
-    /**
103
-     * Global variables that are accessible through $dwoo.* in the templates.
104
-     * default values include:
105
-     * $dwoo.version - current version number
106
-     * $dwoo.ad - a Powered by Dwoo link pointing to dwoo.org
107
-     * $dwoo.now - the current time
108
-     * $dwoo.template - the current template filename
109
-     * $dwoo.charset - the character set used by the template
110
-     * on top of that, foreach and other plugins can store special values in there,
111
-     * see their documentation for more details.
112
-     *
113
-     * @var array
114
-     */
115
-    protected $globals = array();
116
-
117
-    /**
118
-     * Directory where the compiled templates are stored.
119
-     * defaults to DWOO_COMPILEDIR (= dwoo_dir/compiled by default)
120
-     *
121
-     * @var string
122
-     */
123
-    protected $compileDir;
124
-
125
-    /**
126
-     * Directory where the cached templates are stored.
127
-     * defaults to DWOO_CACHEDIR (= dwoo_dir/cache by default)
128
-     *
129
-     * @var string
130
-     */
131
-    protected $cacheDir;
132
-
133
-    /**
134
-     * Directory where the template files are stored
135
-     *
136
-     * @var array
137
-     */
138
-    protected $templateDir = array();
139
-
140
-    /**
141
-     * Defines how long (in seconds) the cached files must remain valid.
142
-     * can be overridden on a per-template basis
143
-     * -1 = never delete
144
-     * 0 = disabled
145
-     * >0 = duration in seconds
146
-     *
147
-     * @var int
148
-     */
149
-    protected $cacheTime = 0;
150
-
151
-    /**
152
-     * Security policy object.
153
-     *
154
-     * @var SecurityPolicy
155
-     */
156
-    protected $securityPolicy = null;
157
-
158
-    /**
159
-     * Stores the custom plugins callbacks.
160
-     *
161
-     * @see addPlugin
162
-     * @see removePlugin
163
-     * @var array
164
-     */
165
-    protected $plugins = array();
166
-
167
-    /**
168
-     * Stores the filter callbacks.
169
-     *
170
-     * @see addFilter
171
-     * @see removeFilter
172
-     * @var array
173
-     */
174
-    protected $filters = array();
175
-
176
-    /**
177
-     * Stores the resource types and associated
178
-     * classes / compiler classes.
179
-     *
180
-     * @var array
181
-     */
182
-    protected $resources = array(
183
-        'file'   => array(
184
-            'class'    => 'Dwoo\Template\File',
185
-            'compiler' => null,
186
-        ),
187
-        'string' => array(
188
-            'class'    => 'Dwoo\Template\Str',
189
-            'compiler' => null,
190
-        ),
191
-    );
192
-
193
-    /**
194
-     * The dwoo loader object used to load plugins by this dwoo instance.
195
-     *
196
-     * @var ILoader
197
-     */
198
-    protected $loader = null;
199
-
200
-    /**
201
-     * Currently rendered template, set to null when not-rendering.
202
-     *
203
-     * @var ITemplate
204
-     */
205
-    protected $template = null;
206
-
207
-    /**
208
-     * Stores the instances of the class plugins during template runtime.
209
-     *
210
-     * @var array
211
-     */
212
-    protected $runtimePlugins = array();
213
-
214
-    /**
215
-     * Stores the returned values during template runtime.
216
-     *
217
-     * @var array
218
-     */
219
-    protected $returnData = array();
220
-
221
-    /**
222
-     * Stores the data during template runtime.
223
-     *
224
-     * @var array
225
-     */
226
-    protected $data = array();
227
-
228
-    /**
229
-     * Stores the current scope during template runtime.
230
-     * this should ideally not be accessed directly from outside template code
231
-     *
232
-     * @var mixed
233
-     */
234
-    public $scope;
235
-
236
-    /**
237
-     * Stores the scope tree during template runtime.
238
-     *
239
-     * @var array
240
-     */
241
-    protected $scopeTree = array();
242
-
243
-    /**
244
-     * Stores the block plugins stack during template runtime.
245
-     *
246
-     * @var array
247
-     */
248
-    protected $stack = array();
249
-
250
-    /**
251
-     * Stores the current block plugin at the top of the stack during template runtime.
252
-     *
253
-     * @var BlockPlugin
254
-     */
255
-    protected $curBlock;
256
-
257
-    /**
258
-     * Stores the output buffer during template runtime.
259
-     *
260
-     * @var string
261
-     */
262
-    protected $buffer;
263
-
264
-    /**
265
-     * Stores plugin proxy.
266
-     *
267
-     * @var IPluginProxy
268
-     */
269
-    protected $pluginProxy;
270
-
271
-    /**
272
-     * Constructor, sets the cache and compile dir to the default values if not provided.
273
-     *
274
-     * @param string $compileDir path to the compiled directory, defaults to lib/compiled
275
-     * @param string $cacheDir   path to the cache directory, defaults to lib/cache
276
-     */
277
-    public function __construct($compileDir = null, $cacheDir = null)
278
-    {
279
-        if ($compileDir !== null) {
280
-            $this->setCompileDir($compileDir);
281
-        }
282
-        if ($cacheDir !== null) {
283
-            $this->setCacheDir($cacheDir);
284
-        }
285
-        $this->initGlobals();
286
-    }
287
-
288
-    /**
289
-     * Resets some runtime variables to allow a cloned object to be used to render sub-templates.
290
-     *
291
-     * @return void
292
-     */
293
-    public function __clone()
294
-    {
295
-        $this->template = null;
296
-        unset($this->data);
297
-        unset($this->returnData);
298
-    }
299
-
300
-    /**
301
-     * Returns the given template rendered using the provided data and optional compiler.
302
-     *
303
-     * @param mixed     $_tpl      template, can either be a ITemplate object (i.e. TemplateFile), a
304
-     *                             valid path to a template, or a template as a string it is recommended to
305
-     *                             provide a ITemplate as it will probably make things faster, especially if
306
-     *                             you render a template multiple times
307
-     * @param mixed     $data      the data to use, can either be a IDataProvider object (i.e. Data) or
308
-     *                             an associative array. if you're rendering the template from cache, it can be
309
-     *                             left null
310
-     * @param ICompiler $_compiler the compiler that must be used to compile the template, if left empty a default
311
-     *                             Compiler will be used
312
-     *
313
-     * @return string|void or the template output if $output is false
314
-     * @throws Exception
315
-     */
316
-    public function get($_tpl, $data = array(), $_compiler = null)
317
-    {
318
-        // a render call came from within a template, so we need a new dwoo instance in order to avoid breaking this one
319
-        if ($this->template instanceof ITemplate) {
320
-            $clone = clone $this;
321
-
322
-            return $clone->get($_tpl, $data, $_compiler);
323
-        }
324
-
325
-        // auto-create template if required
326
-        if ($_tpl instanceof ITemplate) {
327
-            // valid, skip
328
-        } elseif (is_string($_tpl)) {
329
-            $_tpl = new TemplateFile($_tpl);
330
-            $_tpl->setIncludePath($this->getTemplateDir());
331
-        } else {
332
-            throw new Exception(
333
-                'Dwoo->get\'s first argument must be a ITemplate (i.e. TemplateFile) or 
47
+	/**
48
+	 * Current version number.
49
+	 *
50
+	 * @var string
51
+	 */
52
+	const VERSION = '1.3.2';
53
+
54
+	/**
55
+	 * Unique number of this dwoo release, based on version number.
56
+	 * this can be used by templates classes to check whether the compiled template
57
+	 * has been compiled before this release or not, so that old templates are
58
+	 * recompiled automatically when Dwoo is updated
59
+	 */
60
+	const RELEASE_TAG = 132;
61
+
62
+	/**
63
+	 * Constants that represents all plugin types
64
+	 * these are bitwise-operation-safe values to allow multiple types
65
+	 * on a single plugin
66
+	 *
67
+	 * @var int
68
+	 */
69
+	const CLASS_PLUGIN      = 1;
70
+	const FUNC_PLUGIN       = 2;
71
+	const NATIVE_PLUGIN     = 4;
72
+	const BLOCK_PLUGIN      = 8;
73
+	const COMPILABLE_PLUGIN = 16;
74
+	const CUSTOM_PLUGIN     = 32;
75
+	const SMARTY_MODIFIER   = 64;
76
+	const SMARTY_BLOCK      = 128;
77
+	const SMARTY_FUNCTION   = 256;
78
+	const PROXY_PLUGIN      = 512;
79
+	const TEMPLATE_PLUGIN   = 1024;
80
+
81
+	/**
82
+	 * Constant to default namespaces of builtin plugins
83
+	 *
84
+	 * @var string
85
+	 */
86
+	const NAMESPACE_PLUGINS_BLOCKS     = 'Dwoo\Plugins\Blocks\\';
87
+	const NAMESPACE_PLUGINS_FILTERS    = 'Dwoo\Plugins\Filters\\';
88
+	const NAMESPACE_PLUGINS_FUNCTIONS  = 'Dwoo\Plugins\Functions\\';
89
+	const NAMESPACE_PLUGINS_HELPERS    = 'Dwoo\Plugins\Helpers\\';
90
+	const NAMESPACE_PLUGINS_PROCESSORS = 'Dwoo\Plugins\Processors\\';
91
+
92
+	/**
93
+	 * Character set of the template, used by string manipulation plugins.
94
+	 * it must be lowercase, but setCharset() will take care of that
95
+	 *
96
+	 * @see setCharset
97
+	 * @see getCharset
98
+	 * @var string
99
+	 */
100
+	protected $charset = 'UTF-8';
101
+
102
+	/**
103
+	 * Global variables that are accessible through $dwoo.* in the templates.
104
+	 * default values include:
105
+	 * $dwoo.version - current version number
106
+	 * $dwoo.ad - a Powered by Dwoo link pointing to dwoo.org
107
+	 * $dwoo.now - the current time
108
+	 * $dwoo.template - the current template filename
109
+	 * $dwoo.charset - the character set used by the template
110
+	 * on top of that, foreach and other plugins can store special values in there,
111
+	 * see their documentation for more details.
112
+	 *
113
+	 * @var array
114
+	 */
115
+	protected $globals = array();
116
+
117
+	/**
118
+	 * Directory where the compiled templates are stored.
119
+	 * defaults to DWOO_COMPILEDIR (= dwoo_dir/compiled by default)
120
+	 *
121
+	 * @var string
122
+	 */
123
+	protected $compileDir;
124
+
125
+	/**
126
+	 * Directory where the cached templates are stored.
127
+	 * defaults to DWOO_CACHEDIR (= dwoo_dir/cache by default)
128
+	 *
129
+	 * @var string
130
+	 */
131
+	protected $cacheDir;
132
+
133
+	/**
134
+	 * Directory where the template files are stored
135
+	 *
136
+	 * @var array
137
+	 */
138
+	protected $templateDir = array();
139
+
140
+	/**
141
+	 * Defines how long (in seconds) the cached files must remain valid.
142
+	 * can be overridden on a per-template basis
143
+	 * -1 = never delete
144
+	 * 0 = disabled
145
+	 * >0 = duration in seconds
146
+	 *
147
+	 * @var int
148
+	 */
149
+	protected $cacheTime = 0;
150
+
151
+	/**
152
+	 * Security policy object.
153
+	 *
154
+	 * @var SecurityPolicy
155
+	 */
156
+	protected $securityPolicy = null;
157
+
158
+	/**
159
+	 * Stores the custom plugins callbacks.
160
+	 *
161
+	 * @see addPlugin
162
+	 * @see removePlugin
163
+	 * @var array
164
+	 */
165
+	protected $plugins = array();
166
+
167
+	/**
168
+	 * Stores the filter callbacks.
169
+	 *
170
+	 * @see addFilter
171
+	 * @see removeFilter
172
+	 * @var array
173
+	 */
174
+	protected $filters = array();
175
+
176
+	/**
177
+	 * Stores the resource types and associated
178
+	 * classes / compiler classes.
179
+	 *
180
+	 * @var array
181
+	 */
182
+	protected $resources = array(
183
+		'file'   => array(
184
+			'class'    => 'Dwoo\Template\File',
185
+			'compiler' => null,
186
+		),
187
+		'string' => array(
188
+			'class'    => 'Dwoo\Template\Str',
189
+			'compiler' => null,
190
+		),
191
+	);
192
+
193
+	/**
194
+	 * The dwoo loader object used to load plugins by this dwoo instance.
195
+	 *
196
+	 * @var ILoader
197
+	 */
198
+	protected $loader = null;
199
+
200
+	/**
201
+	 * Currently rendered template, set to null when not-rendering.
202
+	 *
203
+	 * @var ITemplate
204
+	 */
205
+	protected $template = null;
206
+
207
+	/**
208
+	 * Stores the instances of the class plugins during template runtime.
209
+	 *
210
+	 * @var array
211
+	 */
212
+	protected $runtimePlugins = array();
213
+
214
+	/**
215
+	 * Stores the returned values during template runtime.
216
+	 *
217
+	 * @var array
218
+	 */
219
+	protected $returnData = array();
220
+
221
+	/**
222
+	 * Stores the data during template runtime.
223
+	 *
224
+	 * @var array
225
+	 */
226
+	protected $data = array();
227
+
228
+	/**
229
+	 * Stores the current scope during template runtime.
230
+	 * this should ideally not be accessed directly from outside template code
231
+	 *
232
+	 * @var mixed
233
+	 */
234
+	public $scope;
235
+
236
+	/**
237
+	 * Stores the scope tree during template runtime.
238
+	 *
239
+	 * @var array
240
+	 */
241
+	protected $scopeTree = array();
242
+
243
+	/**
244
+	 * Stores the block plugins stack during template runtime.
245
+	 *
246
+	 * @var array
247
+	 */
248
+	protected $stack = array();
249
+
250
+	/**
251
+	 * Stores the current block plugin at the top of the stack during template runtime.
252
+	 *
253
+	 * @var BlockPlugin
254
+	 */
255
+	protected $curBlock;
256
+
257
+	/**
258
+	 * Stores the output buffer during template runtime.
259
+	 *
260
+	 * @var string
261
+	 */
262
+	protected $buffer;
263
+
264
+	/**
265
+	 * Stores plugin proxy.
266
+	 *
267
+	 * @var IPluginProxy
268
+	 */
269
+	protected $pluginProxy;
270
+
271
+	/**
272
+	 * Constructor, sets the cache and compile dir to the default values if not provided.
273
+	 *
274
+	 * @param string $compileDir path to the compiled directory, defaults to lib/compiled
275
+	 * @param string $cacheDir   path to the cache directory, defaults to lib/cache
276
+	 */
277
+	public function __construct($compileDir = null, $cacheDir = null)
278
+	{
279
+		if ($compileDir !== null) {
280
+			$this->setCompileDir($compileDir);
281
+		}
282
+		if ($cacheDir !== null) {
283
+			$this->setCacheDir($cacheDir);
284
+		}
285
+		$this->initGlobals();
286
+	}
287
+
288
+	/**
289
+	 * Resets some runtime variables to allow a cloned object to be used to render sub-templates.
290
+	 *
291
+	 * @return void
292
+	 */
293
+	public function __clone()
294
+	{
295
+		$this->template = null;
296
+		unset($this->data);
297
+		unset($this->returnData);
298
+	}
299
+
300
+	/**
301
+	 * Returns the given template rendered using the provided data and optional compiler.
302
+	 *
303
+	 * @param mixed     $_tpl      template, can either be a ITemplate object (i.e. TemplateFile), a
304
+	 *                             valid path to a template, or a template as a string it is recommended to
305
+	 *                             provide a ITemplate as it will probably make things faster, especially if
306
+	 *                             you render a template multiple times
307
+	 * @param mixed     $data      the data to use, can either be a IDataProvider object (i.e. Data) or
308
+	 *                             an associative array. if you're rendering the template from cache, it can be
309
+	 *                             left null
310
+	 * @param ICompiler $_compiler the compiler that must be used to compile the template, if left empty a default
311
+	 *                             Compiler will be used
312
+	 *
313
+	 * @return string|void or the template output if $output is false
314
+	 * @throws Exception
315
+	 */
316
+	public function get($_tpl, $data = array(), $_compiler = null)
317
+	{
318
+		// a render call came from within a template, so we need a new dwoo instance in order to avoid breaking this one
319
+		if ($this->template instanceof ITemplate) {
320
+			$clone = clone $this;
321
+
322
+			return $clone->get($_tpl, $data, $_compiler);
323
+		}
324
+
325
+		// auto-create template if required
326
+		if ($_tpl instanceof ITemplate) {
327
+			// valid, skip
328
+		} elseif (is_string($_tpl)) {
329
+			$_tpl = new TemplateFile($_tpl);
330
+			$_tpl->setIncludePath($this->getTemplateDir());
331
+		} else {
332
+			throw new Exception(
333
+				'Dwoo->get\'s first argument must be a ITemplate (i.e. TemplateFile) or 
334 334
             a valid path to a template file', E_USER_NOTICE
335
-            );
336
-        }
337
-
338
-        // save the current template, enters render mode at the same time
339
-        // if another rendering is requested it will be proxied to a new Core(instance
340
-        $this->template = $_tpl;
341
-
342
-        // load data
343
-        if ($data instanceof IDataProvider) {
344
-            $this->data = $data->getData();
345
-        } elseif (is_array($data)) {
346
-            $this->data = $data;
347
-        } elseif ($data instanceof ArrayAccess) {
348
-            $this->data = $data;
349
-        } else {
350
-            throw new Exception(
351
-                'Dwoo->get/Dwoo->output\'s data argument must be a IDataProvider object (i.e. Data) or
335
+			);
336
+		}
337
+
338
+		// save the current template, enters render mode at the same time
339
+		// if another rendering is requested it will be proxied to a new Core(instance
340
+		$this->template = $_tpl;
341
+
342
+		// load data
343
+		if ($data instanceof IDataProvider) {
344
+			$this->data = $data->getData();
345
+		} elseif (is_array($data)) {
346
+			$this->data = $data;
347
+		} elseif ($data instanceof ArrayAccess) {
348
+			$this->data = $data;
349
+		} else {
350
+			throw new Exception(
351
+				'Dwoo->get/Dwoo->output\'s data argument must be a IDataProvider object (i.e. Data) or
352 352
             an associative array', E_USER_NOTICE
353
-            );
354
-        }
355
-
356
-        $this->addGlobal('template', $_tpl->getName());
357
-        $this->initRuntimeVars($_tpl);
358
-
359
-        // try to get cached template
360
-        $file        = $_tpl->getCachedTemplate($this);
361
-        $doCache     = $file === true;
362
-        $cacheLoaded = is_string($file);
363
-
364
-        if ($cacheLoaded === true) {
365
-            // cache is present, run it
366
-            ob_start();
367
-            include $file;
368
-            $this->template = null;
369
-
370
-            return ob_get_clean();
371
-        } else {
372
-            $dynamicId = uniqid();
373
-
374
-            // render template
375
-            $compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler);
376
-            $out              = include $compiledTemplate;
377
-
378
-            // template returned false so it needs to be recompiled
379
-            if ($out === false) {
380
-                $_tpl->forceCompilation();
381
-                $compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler);
382
-                $out              = include $compiledTemplate;
383
-            }
384
-
385
-            if ($doCache === true) {
386
-                $out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*' . $dynamicId . '*/ echo \'$1\'; ?>', $out);
387
-                if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS . 'PluginDynamic')) {
388
-                    $this->getLoader()->loadPlugin('PluginDynamic');
389
-                }
390
-                $out = PluginDynamic::unescape($out, $dynamicId, $compiledTemplate);
391
-            }
392
-
393
-            // process filters
394
-            foreach ($this->filters as $filter) {
395
-                if (is_array($filter) && $filter[0] instanceof Filter) {
396
-                    $out = call_user_func($filter, $out);
397
-                } else {
398
-                    $out = call_user_func($filter, $this, $out);
399
-                }
400
-            }
401
-
402
-            if ($doCache === true) {
403
-                // building cache
404
-                $file = $_tpl->cache($this, $out);
405
-
406
-                // run it from the cache to be sure dynamics are rendered
407
-                ob_start();
408
-                include $file;
409
-                // exit render mode
410
-                $this->template = null;
411
-
412
-                return ob_get_clean();
413
-            } else {
414
-                // no need to build cache
415
-                // exit render mode
416
-                $this->template = null;
417
-
418
-                return $out;
419
-            }
420
-        }
421
-    }
422
-
423
-    /**
424
-     * Registers a Global.
425
-     * New globals can be added before compiling or rendering a template
426
-     * but after, you can only update existing globals.
427
-     *
428
-     * @param string $name
429
-     * @param mixed  $value
430
-     *
431
-     * @return $this
432
-     * @throws Exception
433
-     */
434
-    public function addGlobal($name, $value)
435
-    {
436
-        if (null === $this->globals) {
437
-            $this->initGlobals();
438
-        }
439
-
440
-        $this->globals[$name] = $value;
441
-
442
-        return $this;
443
-    }
444
-
445
-    /**
446
-     * Gets the registered Globals.
447
-     *
448
-     * @return array
449
-     */
450
-    public function getGlobals()
451
-    {
452
-        return $this->globals;
453
-    }
454
-
455
-    /**
456
-     * Re-initializes the globals array before each template run.
457
-     * this method is only callede once when the Dwoo object is created
458
-     *
459
-     * @return void
460
-     */
461
-    protected function initGlobals()
462
-    {
463
-        $this->globals = array(
464
-            'version' => self::VERSION,
465
-            'ad'      => '<a href="http://dwoo.org/">Powered by Dwoo</a>',
466
-            'now'     => $_SERVER['REQUEST_TIME'],
467
-            'charset' => $this->getCharset(),
468
-        );
469
-    }
470
-
471
-    /**
472
-     * Re-initializes the runtime variables before each template run.
473
-     * override this method to inject data in the globals array if needed, this
474
-     * method is called before each template execution
475
-     *
476
-     * @param ITemplate $tpl the template that is going to be rendered
477
-     *
478
-     * @return void
479
-     */
480
-    protected function initRuntimeVars(ITemplate $tpl)
481
-    {
482
-        $this->runtimePlugins = array();
483
-        $this->scope          = &$this->data;
484
-        $this->scopeTree      = array();
485
-        $this->stack          = array();
486
-        $this->curBlock       = null;
487
-        $this->buffer         = '';
488
-        $this->returnData     = array();
489
-    }
490
-
491
-    /**
492
-     * Adds a custom plugin that is not in one of the plugin directories.
493
-     *
494
-     * @param string   $name       the plugin name to be used in the templates
495
-     * @param callback $callback   the plugin callback, either a function name,
496
-     *                             a class name or an array containing an object
497
-     *                             or class name and a method name
498
-     * @param bool     $compilable if set to true, the plugin is assumed to be compilable
499
-     *
500
-     * @return void
501
-     * @throws Exception
502
-     */
503
-    public function addPlugin($name, $callback, $compilable = false)
504
-    {
505
-        $compilable = $compilable ? self::COMPILABLE_PLUGIN : 0;
506
-        if (is_array($callback)) {
507
-            if (is_subclass_of(is_object($callback[0]) ? get_class($callback[0]) : $callback[0], 'Dwoo\Block\Plugin')) {
508
-                $this->plugins[$name] = array(
509
-                    'type'     => self::BLOCK_PLUGIN | $compilable,
510
-                    'callback' => $callback,
511
-                    'class'    => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0])
512
-                );
513
-            } else {
514
-                $this->plugins[$name] = array(
515
-                    'type'     => self::CLASS_PLUGIN | $compilable,
516
-                    'callback' => $callback,
517
-                    'class'    => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0]),
518
-                    'function' => $callback[1]
519
-                );
520
-            }
521
-        } elseif (is_string($callback)) {
522
-            if (class_exists($callback)) {
523
-                if (is_subclass_of($callback, 'Dwoo\Block\Plugin')) {
524
-                    $this->plugins[$name] = array(
525
-                        'type'     => self::BLOCK_PLUGIN | $compilable,
526
-                        'callback' => $callback,
527
-                        'class'    => $callback
528
-                    );
529
-                } else {
530
-                    $this->plugins[$name] = array(
531
-                        'type'     => self::CLASS_PLUGIN | $compilable,
532
-                        'callback' => $callback,
533
-                        'class'    => $callback,
534
-                        'function' => ($compilable ? 'compile' : 'process')
535
-                    );
536
-                }
537
-            } elseif (function_exists($callback)) {
538
-                $this->plugins[$name] = array(
539
-                    'type'     => self::FUNC_PLUGIN | $compilable,
540
-                    'callback' => $callback
541
-                );
542
-            } else {
543
-                throw new Exception(
544
-                    'Callback could not be processed correctly, please check that the function/class 
353
+			);
354
+		}
355
+
356
+		$this->addGlobal('template', $_tpl->getName());
357
+		$this->initRuntimeVars($_tpl);
358
+
359
+		// try to get cached template
360
+		$file        = $_tpl->getCachedTemplate($this);
361
+		$doCache     = $file === true;
362
+		$cacheLoaded = is_string($file);
363
+
364
+		if ($cacheLoaded === true) {
365
+			// cache is present, run it
366
+			ob_start();
367
+			include $file;
368
+			$this->template = null;
369
+
370
+			return ob_get_clean();
371
+		} else {
372
+			$dynamicId = uniqid();
373
+
374
+			// render template
375
+			$compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler);
376
+			$out              = include $compiledTemplate;
377
+
378
+			// template returned false so it needs to be recompiled
379
+			if ($out === false) {
380
+				$_tpl->forceCompilation();
381
+				$compiledTemplate = $_tpl->getCompiledTemplate($this, $_compiler);
382
+				$out              = include $compiledTemplate;
383
+			}
384
+
385
+			if ($doCache === true) {
386
+				$out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*' . $dynamicId . '*/ echo \'$1\'; ?>', $out);
387
+				if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS . 'PluginDynamic')) {
388
+					$this->getLoader()->loadPlugin('PluginDynamic');
389
+				}
390
+				$out = PluginDynamic::unescape($out, $dynamicId, $compiledTemplate);
391
+			}
392
+
393
+			// process filters
394
+			foreach ($this->filters as $filter) {
395
+				if (is_array($filter) && $filter[0] instanceof Filter) {
396
+					$out = call_user_func($filter, $out);
397
+				} else {
398
+					$out = call_user_func($filter, $this, $out);
399
+				}
400
+			}
401
+
402
+			if ($doCache === true) {
403
+				// building cache
404
+				$file = $_tpl->cache($this, $out);
405
+
406
+				// run it from the cache to be sure dynamics are rendered
407
+				ob_start();
408
+				include $file;
409
+				// exit render mode
410
+				$this->template = null;
411
+
412
+				return ob_get_clean();
413
+			} else {
414
+				// no need to build cache
415
+				// exit render mode
416
+				$this->template = null;
417
+
418
+				return $out;
419
+			}
420
+		}
421
+	}
422
+
423
+	/**
424
+	 * Registers a Global.
425
+	 * New globals can be added before compiling or rendering a template
426
+	 * but after, you can only update existing globals.
427
+	 *
428
+	 * @param string $name
429
+	 * @param mixed  $value
430
+	 *
431
+	 * @return $this
432
+	 * @throws Exception
433
+	 */
434
+	public function addGlobal($name, $value)
435
+	{
436
+		if (null === $this->globals) {
437
+			$this->initGlobals();
438
+		}
439
+
440
+		$this->globals[$name] = $value;
441
+
442
+		return $this;
443
+	}
444
+
445
+	/**
446
+	 * Gets the registered Globals.
447
+	 *
448
+	 * @return array
449
+	 */
450
+	public function getGlobals()
451
+	{
452
+		return $this->globals;
453
+	}
454
+
455
+	/**
456
+	 * Re-initializes the globals array before each template run.
457
+	 * this method is only callede once when the Dwoo object is created
458
+	 *
459
+	 * @return void
460
+	 */
461
+	protected function initGlobals()
462
+	{
463
+		$this->globals = array(
464
+			'version' => self::VERSION,
465
+			'ad'      => '<a href="http://dwoo.org/">Powered by Dwoo</a>',
466
+			'now'     => $_SERVER['REQUEST_TIME'],
467
+			'charset' => $this->getCharset(),
468
+		);
469
+	}
470
+
471
+	/**
472
+	 * Re-initializes the runtime variables before each template run.
473
+	 * override this method to inject data in the globals array if needed, this
474
+	 * method is called before each template execution
475
+	 *
476
+	 * @param ITemplate $tpl the template that is going to be rendered
477
+	 *
478
+	 * @return void
479
+	 */
480
+	protected function initRuntimeVars(ITemplate $tpl)
481
+	{
482
+		$this->runtimePlugins = array();
483
+		$this->scope          = &$this->data;
484
+		$this->scopeTree      = array();
485
+		$this->stack          = array();
486
+		$this->curBlock       = null;
487
+		$this->buffer         = '';
488
+		$this->returnData     = array();
489
+	}
490
+
491
+	/**
492
+	 * Adds a custom plugin that is not in one of the plugin directories.
493
+	 *
494
+	 * @param string   $name       the plugin name to be used in the templates
495
+	 * @param callback $callback   the plugin callback, either a function name,
496
+	 *                             a class name or an array containing an object
497
+	 *                             or class name and a method name
498
+	 * @param bool     $compilable if set to true, the plugin is assumed to be compilable
499
+	 *
500
+	 * @return void
501
+	 * @throws Exception
502
+	 */
503
+	public function addPlugin($name, $callback, $compilable = false)
504
+	{
505
+		$compilable = $compilable ? self::COMPILABLE_PLUGIN : 0;
506
+		if (is_array($callback)) {
507
+			if (is_subclass_of(is_object($callback[0]) ? get_class($callback[0]) : $callback[0], 'Dwoo\Block\Plugin')) {
508
+				$this->plugins[$name] = array(
509
+					'type'     => self::BLOCK_PLUGIN | $compilable,
510
+					'callback' => $callback,
511
+					'class'    => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0])
512
+				);
513
+			} else {
514
+				$this->plugins[$name] = array(
515
+					'type'     => self::CLASS_PLUGIN | $compilable,
516
+					'callback' => $callback,
517
+					'class'    => (is_object($callback[0]) ? get_class($callback[0]) : $callback[0]),
518
+					'function' => $callback[1]
519
+				);
520
+			}
521
+		} elseif (is_string($callback)) {
522
+			if (class_exists($callback)) {
523
+				if (is_subclass_of($callback, 'Dwoo\Block\Plugin')) {
524
+					$this->plugins[$name] = array(
525
+						'type'     => self::BLOCK_PLUGIN | $compilable,
526
+						'callback' => $callback,
527
+						'class'    => $callback
528
+					);
529
+				} else {
530
+					$this->plugins[$name] = array(
531
+						'type'     => self::CLASS_PLUGIN | $compilable,
532
+						'callback' => $callback,
533
+						'class'    => $callback,
534
+						'function' => ($compilable ? 'compile' : 'process')
535
+					);
536
+				}
537
+			} elseif (function_exists($callback)) {
538
+				$this->plugins[$name] = array(
539
+					'type'     => self::FUNC_PLUGIN | $compilable,
540
+					'callback' => $callback
541
+				);
542
+			} else {
543
+				throw new Exception(
544
+					'Callback could not be processed correctly, please check that the function/class 
545 545
                 you used exists'
546
-                );
547
-            }
548
-        } elseif ($callback instanceof Closure) {
549
-            $this->plugins[$name] = array(
550
-                'type'     => self::FUNC_PLUGIN | $compilable,
551
-                'callback' => $callback
552
-            );
553
-        } else {
554
-            throw new Exception(
555
-                'Callback could not be processed correctly, please check that the function/class you 
546
+				);
547
+			}
548
+		} elseif ($callback instanceof Closure) {
549
+			$this->plugins[$name] = array(
550
+				'type'     => self::FUNC_PLUGIN | $compilable,
551
+				'callback' => $callback
552
+			);
553
+		} else {
554
+			throw new Exception(
555
+				'Callback could not be processed correctly, please check that the function/class you 
556 556
             used exists'
557
-            );
558
-        }
559
-    }
560
-
561
-    /**
562
-     * Removes a custom plugin.
563
-     *
564
-     * @param string $name the plugin name
565
-     *
566
-     * @return void
567
-     */
568
-    public function removePlugin($name)
569
-    {
570
-        if (isset($this->plugins[$name])) {
571
-            unset($this->plugins[$name]);
572
-        }
573
-    }
574
-
575
-    /**
576
-     * Adds a filter to this Dwoo instance, it will be used to filter the output of all the templates rendered by this
577
-     * instance.
578
-     *
579
-     * @param mixed $callback a callback or a filter name if it is autoloaded from a plugin directory
580
-     * @param bool  $autoload if true, the first parameter must be a filter name from one of the plugin directories
581
-     *
582
-     * @return void
583
-     * @throws Exception
584
-     */
585
-    public function addFilter($callback, $autoload = false)
586
-    {
587
-        if ($autoload) {
588
-            $class = self::NAMESPACE_PLUGINS_FILTERS . self::toCamelCase($callback);
589
-            if (!class_exists($class) && !function_exists($class)) {
590
-                try {
591
-                    $this->getLoader()->loadPlugin($callback);
592
-                }
593
-                catch (Exception $e) {
594
-                    if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) {
595
-                        throw new Exception(
596
-                            'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should 
557
+			);
558
+		}
559
+	}
560
+
561
+	/**
562
+	 * Removes a custom plugin.
563
+	 *
564
+	 * @param string $name the plugin name
565
+	 *
566
+	 * @return void
567
+	 */
568
+	public function removePlugin($name)
569
+	{
570
+		if (isset($this->plugins[$name])) {
571
+			unset($this->plugins[$name]);
572
+		}
573
+	}
574
+
575
+	/**
576
+	 * Adds a filter to this Dwoo instance, it will be used to filter the output of all the templates rendered by this
577
+	 * instance.
578
+	 *
579
+	 * @param mixed $callback a callback or a filter name if it is autoloaded from a plugin directory
580
+	 * @param bool  $autoload if true, the first parameter must be a filter name from one of the plugin directories
581
+	 *
582
+	 * @return void
583
+	 * @throws Exception
584
+	 */
585
+	public function addFilter($callback, $autoload = false)
586
+	{
587
+		if ($autoload) {
588
+			$class = self::NAMESPACE_PLUGINS_FILTERS . self::toCamelCase($callback);
589
+			if (!class_exists($class) && !function_exists($class)) {
590
+				try {
591
+					$this->getLoader()->loadPlugin($callback);
592
+				}
593
+				catch (Exception $e) {
594
+					if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) {
595
+						throw new Exception(
596
+							'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should 
597 597
                         not be used, please only use "' . str_replace('Dwoo_Filter_', '', $callback) . '"'
598
-                        );
599
-                    } else {
600
-                        throw new Exception(
601
-                            'Wrong filter name : ' . $callback . ', when using autoload the filter must
598
+						);
599
+					} else {
600
+						throw new Exception(
601
+							'Wrong filter name : ' . $callback . ', when using autoload the filter must
602 602
                          be in one of your plugin dir as "name.php" containig a class or function named
603 603
                          "Dwoo_Filter_name"'
604
-                        );
605
-                    }
606
-                }
607
-            }
608
-
609
-            if (class_exists($class)) {
610
-                $callback = array(new $class($this), 'process');
611
-            } elseif (function_exists($class)) {
612
-                $callback = $class;
613
-            } else {
614
-                throw new Exception(
615
-                    'Wrong filter name : ' . $callback . ', when using autoload the filter must be in
604
+						);
605
+					}
606
+				}
607
+			}
608
+
609
+			if (class_exists($class)) {
610
+				$callback = array(new $class($this), 'process');
611
+			} elseif (function_exists($class)) {
612
+				$callback = $class;
613
+			} else {
614
+				throw new Exception(
615
+					'Wrong filter name : ' . $callback . ', when using autoload the filter must be in
616 616
                 one of your plugin dir as "name.php" containig a class or function named "Dwoo_Filter_name"'
617
-                );
618
-            }
619
-
620
-            $this->filters[] = $callback;
621
-        } else {
622
-            $this->filters[] = $callback;
623
-        }
624
-    }
625
-
626
-    /**
627
-     * Removes a filter.
628
-     *
629
-     * @param mixed $callback callback or filter name if it was autoloaded
630
-     *
631
-     * @return void
632
-     */
633
-    public function removeFilter($callback)
634
-    {
635
-        if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS. 'Filter' . self::toCamelCase($callback), $this->filters,
636
-                true)) !==
637
-            false) {
638
-            unset($this->filters[$index]);
639
-        } elseif (($index = array_search($callback, $this->filters, true)) !== false) {
640
-            unset($this->filters[$index]);
641
-        } else {
642
-            $class = self::NAMESPACE_PLUGINS_FILTERS . 'Filter' . $callback;
643
-            foreach ($this->filters as $index => $filter) {
644
-                if (is_array($filter) && $filter[0] instanceof $class) {
645
-                    unset($this->filters[$index]);
646
-                    break;
647
-                }
648
-            }
649
-        }
650
-    }
651
-
652
-    /**
653
-     * Adds a resource or overrides a default one.
654
-     *
655
-     * @param string   $name            the resource name
656
-     * @param string   $class           the resource class (which must implement ITemplate)
657
-     * @param callback $compilerFactory the compiler factory callback, a function that must return a compiler instance
658
-     *                                  used to compile this resource, if none is provided. by default it will produce
659
-     *                                  a Compiler object
660
-     *
661
-     * @return void
662
-     * @throws Exception
663
-     */
664
-    public function addResource($name, $class, $compilerFactory = null)
665
-    {
666
-        if (strlen($name) < 2) {
667
-            throw new Exception('Resource names must be at least two-character long to avoid conflicts with Windows paths');
668
-        }
669
-
670
-        if (!class_exists($class)) {
671
-            throw new Exception(sprintf('Resource class %s does not exist', $class));
672
-        }
673
-
674
-        $interfaces = class_implements($class);
675
-        if (in_array('Dwoo\ITemplate', $interfaces) === false) {
676
-            throw new Exception('Resource class must implement ITemplate');
677
-        }
678
-
679
-        $this->resources[$name] = array(
680
-            'class'    => $class,
681
-            'compiler' => $compilerFactory
682
-        );
683
-    }
684
-
685
-    /**
686
-     * Removes a custom resource.
687
-     *
688
-     * @param string $name the resource name
689
-     *
690
-     * @return void
691
-     */
692
-    public function removeResource($name)
693
-    {
694
-        unset($this->resources[$name]);
695
-        if ($name === 'file') {
696
-            $this->resources['file'] = array(
697
-                'class'    => 'Dwoo\Template\File',
698
-                'compiler' => null
699
-            );
700
-        }
701
-    }
702
-
703
-    /**
704
-     * Sets the loader object to use to load plugins.
705
-     *
706
-     * @param ILoader $loader loader
707
-     *
708
-     * @return void
709
-     */
710
-    public function setLoader(ILoader $loader)
711
-    {
712
-        $this->loader = $loader;
713
-    }
714
-
715
-    /**
716
-     * Returns the current loader object or a default one if none is currently found.
717
-     *
718
-     * @return ILoader|Loader
719
-     */
720
-    public function getLoader()
721
-    {
722
-        if ($this->loader === null) {
723
-            $this->loader = new Loader($this->getCompileDir());
724
-        }
725
-
726
-        return $this->loader;
727
-    }
728
-
729
-    /**
730
-     * Returns the custom plugins loaded.
731
-     * Used by the ITemplate classes to pass the custom plugins to their ICompiler instance.
732
-     *
733
-     * @return array
734
-     */
735
-    public function getCustomPlugins()
736
-    {
737
-        return $this->plugins;
738
-    }
739
-
740
-    /**
741
-     * Return a specified custom plugin loaded by his name.
742
-     * Used by the compiler, for executing a Closure.
743
-     *
744
-     * @param string $name
745
-     *
746
-     * @return mixed|null
747
-     */
748
-    public function getCustomPlugin($name)
749
-    {
750
-        if (isset($this->plugins[$name])) {
751
-            return $this->plugins[$name]['callback'];
752
-        }
753
-
754
-        return null;
755
-    }
756
-
757
-    /**
758
-     * Returns the cache directory with a trailing DIRECTORY_SEPARATOR.
759
-     *
760
-     * @return string
761
-     */
762
-    public function getCacheDir()
763
-    {
764
-        if ($this->cacheDir === null) {
765
-            $this->setCacheDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR);
766
-        }
767
-
768
-        return $this->cacheDir;
769
-    }
770
-
771
-    /**
772
-     * Sets the cache directory and automatically appends a DIRECTORY_SEPARATOR.
773
-     *
774
-     * @param string $dir the cache directory
775
-     *
776
-     * @return void
777
-     * @throws Exception
778
-     */
779
-    public function setCacheDir($dir)
780
-    {
781
-        $this->cacheDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
782
-        if (is_writable($this->cacheDir) === false) {
783
-            throw new Exception('The cache directory must be writable, chmod "' . $this->cacheDir . '" to make it writable');
784
-        }
785
-    }
786
-
787
-    /**
788
-     * Returns the compile directory with a trailing DIRECTORY_SEPARATOR.
789
-     *
790
-     * @return string
791
-     */
792
-    public function getCompileDir()
793
-    {
794
-        if ($this->compileDir === null) {
795
-            $this->setCompileDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'compiled' . DIRECTORY_SEPARATOR);
796
-        }
797
-
798
-        return $this->compileDir;
799
-    }
800
-
801
-    /**
802
-     * Sets the compile directory and automatically appends a DIRECTORY_SEPARATOR.
803
-     *
804
-     * @param string $dir the compile directory
805
-     *
806
-     * @return void
807
-     * @throws Exception
808
-     */
809
-    public function setCompileDir($dir)
810
-    {
811
-        $this->compileDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
812
-        if (is_writable($this->compileDir) === false) {
813
-            throw new Exception('The compile directory must be writable, chmod "' . $this->compileDir . '" to make it writable');
814
-        }
815
-    }
816
-
817
-    /**
818
-     * Returns an array of the template directory with a trailing DIRECTORY_SEPARATOR
819
-     *
820
-     * @return array
821
-     */
822
-    public function getTemplateDir()
823
-    {
824
-        return $this->templateDir;
825
-    }
826
-
827
-    /**
828
-     * sets the template directory and automatically appends a DIRECTORY_SEPARATOR
829
-     * template directory is stored in an array
830
-     *
831
-     * @param string $dir
832
-     *
833
-     * @throws Exception
834
-     */
835
-    public function setTemplateDir($dir)
836
-    {
837
-        $tmpDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
838
-        if (is_dir($tmpDir) === false) {
839
-            throw new Exception('The template directory: "' . $tmpDir . '" does not exists, create the directory or specify an other location !');
840
-        }
841
-        $this->templateDir[] = $tmpDir;
842
-    }
843
-
844
-    /**
845
-     * Returns the default cache time that is used with templates that do not have a cache time set.
846
-     *
847
-     * @return int the duration in seconds
848
-     */
849
-    public function getCacheTime()
850
-    {
851
-        return $this->cacheTime;
852
-    }
853
-
854
-    /**
855
-     * Sets the default cache time to use with templates that do not have a cache time set.
856
-     *
857
-     * @param int $seconds the duration in seconds
858
-     *
859
-     * @return void
860
-     */
861
-    public function setCacheTime($seconds)
862
-    {
863
-        $this->cacheTime = (int)$seconds;
864
-    }
865
-
866
-    /**
867
-     * Returns the character set used by the string manipulation plugins.
868
-     * the charset is automatically lowercased
869
-     *
870
-     * @return string
871
-     */
872
-    public function getCharset()
873
-    {
874
-        return $this->charset;
875
-    }
876
-
877
-    /**
878
-     * Sets the character set used by the string manipulation plugins.
879
-     * the charset will be automatically lowercased
880
-     *
881
-     * @param string $charset the character set
882
-     *
883
-     * @return void
884
-     */
885
-    public function setCharset($charset)
886
-    {
887
-        $this->charset = strtolower((string)$charset);
888
-    }
889
-
890
-    /**
891
-     * Returns the current template being rendered, when applicable, or null.
892
-     *
893
-     * @return ITemplate|null
894
-     */
895
-    public function getTemplate()
896
-    {
897
-        return $this->template;
898
-    }
899
-
900
-    /**
901
-     * Sets the current template being rendered.
902
-     *
903
-     * @param ITemplate $tpl template object
904
-     *
905
-     * @return void
906
-     */
907
-    public function setTemplate(ITemplate $tpl)
908
-    {
909
-        $this->template = $tpl;
910
-    }
911
-
912
-    /**
913
-     * Sets the default compiler factory function for the given resource name.
914
-     * a compiler factory must return a ICompiler object pre-configured to fit your needs
915
-     *
916
-     * @param string   $resourceName    the resource name (i.e. file, string)
917
-     * @param callback $compilerFactory the compiler factory callback
918
-     *
919
-     * @return void
920
-     */
921
-    public function setDefaultCompilerFactory($resourceName, $compilerFactory)
922
-    {
923
-        $this->resources[$resourceName]['compiler'] = $compilerFactory;
924
-    }
925
-
926
-    /**
927
-     * Returns the default compiler factory function for the given resource name.
928
-     *
929
-     * @param string $resourceName the resource name
930
-     *
931
-     * @return callback the compiler factory callback
932
-     */
933
-    public function getDefaultCompilerFactory($resourceName)
934
-    {
935
-        return $this->resources[$resourceName]['compiler'];
936
-    }
937
-
938
-    /**
939
-     * Sets the security policy object to enforce some php security settings.
940
-     * use this if untrusted persons can modify templates
941
-     *
942
-     * @param SecurityPolicy $policy the security policy object
943
-     *
944
-     * @return void
945
-     */
946
-    public function setSecurityPolicy(SecurityPolicy $policy = null)
947
-    {
948
-        $this->securityPolicy = $policy;
949
-    }
950
-
951
-    /**
952
-     * Returns the current security policy object or null by default.
953
-     *
954
-     * @return SecurityPolicy|null the security policy object if any
955
-     */
956
-    public function getSecurityPolicy()
957
-    {
958
-        return $this->securityPolicy;
959
-    }
960
-
961
-    /**
962
-     * Sets the object that must be used as a plugin proxy when plugin can't be found
963
-     * by dwoo's loader.
964
-     *
965
-     * @param IPluginProxy $pluginProxy the proxy object
966
-     *
967
-     * @return void
968
-     */
969
-    public function setPluginProxy(IPluginProxy $pluginProxy)
970
-    {
971
-        $this->pluginProxy = $pluginProxy;
972
-    }
973
-
974
-    /**
975
-     * Returns the current plugin proxy object or null by default.
976
-     *
977
-     * @return IPluginProxy
978
-     */
979
-    public function getPluginProxy()
980
-    {
981
-        return $this->pluginProxy;
982
-    }
983
-
984
-    /**
985
-     * Checks whether the given template is cached or not.
986
-     *
987
-     * @param ITemplate $tpl the template object
988
-     *
989
-     * @return bool
990
-     */
991
-    public function isCached(ITemplate $tpl)
992
-    {
993
-        return is_string($tpl->getCachedTemplate($this));
994
-    }
995
-
996
-    /**
997
-     * Clear templates inside the compiled directory.
998
-     *
999
-     * @return int
1000
-     */
1001
-    public function clearCompiled()
1002
-    {
1003
-        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCompileDir()), \RecursiveIteratorIterator::SELF_FIRST);
1004
-        $count    = 0;
1005
-        foreach ($iterator as $file) {
1006
-            if ($file->isFile()) {
1007
-                $count += unlink($file->__toString()) ? 1 : 0;
1008
-            }
1009
-        }
1010
-
1011
-        return $count;
1012
-    }
1013
-
1014
-    /**
1015
-     * Clears the cached templates if they are older than the given time.
1016
-     *
1017
-     * @param int $olderThan minimum time (in seconds) required for a cached template to be cleared
1018
-     *
1019
-     * @return int the amount of templates cleared
1020
-     */
1021
-    public function clearCache($olderThan = - 1)
1022
-    {
1023
-        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCacheDir()), \RecursiveIteratorIterator::SELF_FIRST);
1024
-        $expired  = time() - $olderThan;
1025
-        $count    = 0;
1026
-        foreach ($iterator as $file) {
1027
-            if ($file->isFile() && $file->getCTime() < $expired) {
1028
-                $count += unlink((string)$file) ? 1 : 0;
1029
-            }
1030
-        }
1031
-
1032
-        return $count;
1033
-    }
1034
-
1035
-    /**
1036
-     * Fetches a template object of the given resource.
1037
-     *
1038
-     * @param string    $resourceName   the resource name (i.e. file, string)
1039
-     * @param string    $resourceId     the resource identifier (i.e. file path)
1040
-     * @param int       $cacheTime      the cache time setting for this resource
1041
-     * @param string    $cacheId        the unique cache identifier
1042
-     * @param string    $compileId      the unique compiler identifier
1043
-     * @param ITemplate $parentTemplate the parent template
1044
-     *
1045
-     * @return ITemplate
1046
-     * @throws Exception
1047
-     */
1048
-    public function templateFactory($resourceName, $resourceId, $cacheTime = null, $cacheId = null, $compileId = null, ITemplate $parentTemplate = null)
1049
-    {
1050
-        if (isset($this->resources[$resourceName])) {
1051
-            /**
1052
-             * Interface ITemplate
1053
-             *
1054
-             * @var ITemplate $class
1055
-             */
1056
-            $class = $this->resources[$resourceName]['class'];
1057
-
1058
-            return $class::templateFactory($this, $resourceId, $cacheTime, $cacheId, $compileId, $parentTemplate);
1059
-        }
1060
-
1061
-        throw new Exception('Unknown resource type : ' . $resourceName);
1062
-    }
1063
-
1064
-    /**
1065
-     * Checks if the input is an array or arrayaccess object, optionally it can also check if it's
1066
-     * empty.
1067
-     *
1068
-     * @param mixed $value        the variable to check
1069
-     * @param bool  $checkIsEmpty if true, the function will also check if the array|arrayaccess is empty,
1070
-     *                            and return true only if it's not empty
1071
-     *
1072
-     * @return int|bool true if it's an array|arrayaccess (or the item count if $checkIsEmpty is true) or false if it's
1073
-     *                  not an array|arrayaccess (or 0 if $checkIsEmpty is true)
1074
-     */
1075
-    public function isArray($value, $checkIsEmpty = false)
1076
-    {
1077
-        if (is_array($value) === true || $value instanceof ArrayAccess) {
1078
-            if ($checkIsEmpty === false) {
1079
-                return true;
1080
-            }
1081
-
1082
-            return $this->count($value);
1083
-        }
1084
-
1085
-        return false;
1086
-    }
1087
-
1088
-    /**
1089
-     * Checks if the input is an array or a traversable object, optionally it can also check if it's
1090
-     * empty.
1091
-     *
1092
-     * @param mixed $value        the variable to check
1093
-     * @param bool  $checkIsEmpty if true, the function will also check if the array|traversable is empty,
1094
-     *                            and return true only if it's not empty
1095
-     *
1096
-     * @return int|bool true if it's an array|traversable (or the item count if $checkIsEmpty is true) or false if it's
1097
-     *                  not an array|traversable (or 0 if $checkIsEmpty is true)
1098
-     */
1099
-    public function isTraversable($value, $checkIsEmpty = false)
1100
-    {
1101
-        if (is_array($value) === true) {
1102
-            if ($checkIsEmpty === false) {
1103
-                return true;
1104
-            } else {
1105
-                return count($value) > 0;
1106
-            }
1107
-        } elseif ($value instanceof Traversable) {
1108
-            if ($checkIsEmpty === false) {
1109
-                return true;
1110
-            } else {
1111
-                return $this->count($value);
1112
-            }
1113
-        }
1114
-
1115
-        return false;
1116
-    }
1117
-
1118
-    /**
1119
-     * Counts an array or arrayaccess/traversable object.
1120
-     *
1121
-     * @param mixed $value the value to count
1122
-     *
1123
-     * @return int|bool the count for arrays and objects that implement countable, true for other objects that don't,
1124
-     *                  and 0 for empty elements
1125
-     */
1126
-    public function count($value)
1127
-    {
1128
-        if (is_array($value) === true || $value instanceof Countable) {
1129
-            return count($value);
1130
-        } elseif ($value instanceof ArrayAccess) {
1131
-            if ($value->offsetExists(0)) {
1132
-                return true;
1133
-            }
1134
-        } elseif ($value instanceof Iterator) {
1135
-            $value->rewind();
1136
-            if ($value->valid()) {
1137
-                return true;
1138
-            }
1139
-        } elseif ($value instanceof Traversable) {
1140
-            foreach ($value as $dummy) {
1141
-                return true;
1142
-            }
1143
-        }
1144
-
1145
-        return 0;
1146
-    }
1147
-
1148
-    /**
1149
-     * Triggers a dwoo error.
1150
-     *
1151
-     * @param string $message the error message
1152
-     * @param int    $level   the error level, one of the PHP's E_* constants
1153
-     *
1154
-     * @return void
1155
-     */
1156
-    public function triggerError($message, $level = E_USER_NOTICE)
1157
-    {
1158
-        if (!($tplIdentifier = $this->template->getResourceIdentifier())) {
1159
-            $tplIdentifier = $this->template->getResourceName();
1160
-        }
1161
-        trigger_error('Dwoo error (in ' . $tplIdentifier . ') : ' . $message, $level);
1162
-    }
1163
-
1164
-    /**
1165
-     * Adds a block to the block stack.
1166
-     *
1167
-     * @param string $blockName the block name (without Dwoo_Plugin_ prefix)
1168
-     * @param array  $args      the arguments to be passed to the block's init() function
1169
-     *
1170
-     * @return BlockPlugin the newly created block
1171
-     */
1172
-    public function addStack($blockName, array $args = array())
1173
-    {
1174
-        if (isset($this->plugins[$blockName])) {
1175
-            $class = $this->plugins[$blockName]['class'];
1176
-        } else {
1177
-            $class = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . self::toCamelCase($blockName);
1178
-        }
1179
-
1180
-        if ($this->curBlock !== null) {
1181
-            $this->curBlock->buffer(ob_get_contents());
1182
-            ob_clean();
1183
-        } else {
1184
-            $this->buffer .= ob_get_contents();
1185
-            ob_clean();
1186
-        }
1187
-
1188
-        $block = new $class($this);
1189
-
1190
-        call_user_func_array(array($block, 'init'), $args);
1191
-
1192
-        $this->stack[] = $this->curBlock = $block;
1193
-
1194
-        return $block;
1195
-    }
1196
-
1197
-    /**
1198
-     * Removes the plugin at the top of the block stack.
1199
-     * Calls the block buffer() function, followed by a call to end() and finally a call to process()
1200
-     *
1201
-     * @return void
1202
-     */
1203
-    public function delStack()
1204
-    {
1205
-        $args = func_get_args();
1206
-
1207
-        $this->curBlock->buffer(ob_get_contents());
1208
-        ob_clean();
1209
-
1210
-        call_user_func_array(array($this->curBlock, 'end'), $args);
1211
-
1212
-        $tmp = array_pop($this->stack);
1213
-
1214
-        if (count($this->stack) > 0) {
1215
-            $this->curBlock = end($this->stack);
1216
-            $this->curBlock->buffer($tmp->process());
1217
-        } else {
1218
-            if ($this->buffer !== '') {
1219
-                echo $this->buffer;
1220
-                $this->buffer = '';
1221
-            }
1222
-            $this->curBlock = null;
1223
-            echo $tmp->process();
1224
-        }
1225
-
1226
-        unset($tmp);
1227
-    }
1228
-
1229
-    /**
1230
-     * Returns the parent block of the given block.
1231
-     *
1232
-     * @param BlockPlugin $block the block class plugin
1233
-     *
1234
-     * @return BlockPlugin|false if the given block isn't in the stack
1235
-     */
1236
-    public function getParentBlock(BlockPlugin $block)
1237
-    {
1238
-        $index = array_search($block, $this->stack, true);
1239
-        if ($index !== false && $index > 0) {
1240
-            return $this->stack[$index - 1];
1241
-        }
1242
-
1243
-        return false;
1244
-    }
1245
-
1246
-    /**
1247
-     * Finds the closest block of the given type, starting at the top of the stack.
1248
-     *
1249
-     * @param string $type the type of plugin you want to find
1250
-     *
1251
-     * @return BlockPlugin|false if no plugin of such type is in the stack
1252
-     */
1253
-    public function findBlock($type)
1254
-    {
1255
-        if (isset($this->plugins[$type])) {
1256
-            $type = $this->plugins[$type]['class'];
1257
-        } else {
1258
-            $type = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin_' . str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin',
1259
-                    '', $type);
1260
-        }
1261
-
1262
-        $keys = array_keys($this->stack);
1263
-        while (($key = array_pop($keys)) !== false) {
1264
-            if ($this->stack[$key] instanceof $type) {
1265
-                return $this->stack[$key];
1266
-            }
1267
-        }
1268
-
1269
-        return false;
1270
-    }
1271
-
1272
-    /**
1273
-     * Returns a Plugin of the given class.
1274
-     * this is so a single instance of every class plugin is created at each template run,
1275
-     * allowing class plugins to have "per-template-run" static variables
1276
-     *
1277
-     * @param string $class the class name
1278
-     *
1279
-     * @return mixed an object of the given class
1280
-     */
1281
-    public function getObjectPlugin($class)
1282
-    {
1283
-        if (isset($this->runtimePlugins[$class])) {
1284
-            return $this->runtimePlugins[$class];
1285
-        }
1286
-
1287
-        return $this->runtimePlugins[$class] = new $class($this);
1288
-    }
1289
-
1290
-    /**
1291
-     * Calls the process() method of the given class-plugin name.
1292
-     *
1293
-     * @param string $plugName the class plugin name (without Dwoo_Plugin_ prefix)
1294
-     * @param array  $params   an array of parameters to send to the process() method
1295
-     *
1296
-     * @return string the process() return value
1297
-     */
1298
-    public function classCall($plugName, array $params = array())
1299
-    {
1300
-        $class  = self::toCamelCase($plugName);
1301
-        $plugin = $this->getObjectPlugin($class);
1302
-
1303
-        return call_user_func_array(array($plugin, 'process'), $params);
1304
-    }
1305
-
1306
-    /**
1307
-     * Calls a php function.
1308
-     *
1309
-     * @param string $callback the function to call
1310
-     * @param array  $params   an array of parameters to send to the function
1311
-     *
1312
-     * @return mixed the return value of the called function
1313
-     */
1314
-    public function arrayMap($callback, array $params)
1315
-    {
1316
-        if ($params[0] === $this) {
1317
-            $addThis = true;
1318
-            array_shift($params);
1319
-        }
1320
-        if ((is_array($params[0]) || ($params[0] instanceof Iterator && $params[0] instanceof ArrayAccess))) {
1321
-            if (empty($params[0])) {
1322
-                return $params[0];
1323
-            }
1324
-
1325
-            // array map
1326
-            $out = array();
1327
-            $cnt = count($params);
1328
-
1329
-            if (isset($addThis)) {
1330
-                array_unshift($params, $this);
1331
-                $items = $params[1];
1332
-                $keys  = array_keys($items);
1333
-
1334
-                if (is_string($callback) === false) {
1335
-                    while (($i = array_shift($keys)) !== null) {
1336
-                        $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params);
1337
-                    }
1338
-                } elseif ($cnt === 1) {
1339
-                    while (($i = array_shift($keys)) !== null) {
1340
-                        $out[] = $callback($this, $items[$i]);
1341
-                    }
1342
-                } elseif ($cnt === 2) {
1343
-                    while (($i = array_shift($keys)) !== null) {
1344
-                        $out[] = $callback($this, $items[$i], $params[2]);
1345
-                    }
1346
-                } elseif ($cnt === 3) {
1347
-                    while (($i = array_shift($keys)) !== null) {
1348
-                        $out[] = $callback($this, $items[$i], $params[2], $params[3]);
1349
-                    }
1350
-                } else {
1351
-                    while (($i = array_shift($keys)) !== null) {
1352
-                        $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params);
1353
-                    }
1354
-                }
1355
-            } else {
1356
-                $items = $params[0];
1357
-                $keys  = array_keys($items);
1358
-
1359
-                if (is_string($callback) === false) {
1360
-                    while (($i = array_shift($keys)) !== null) {
1361
-                        $out[] = call_user_func_array($callback, array($items[$i]) + $params);
1362
-                    }
1363
-                } elseif ($cnt === 1) {
1364
-                    while (($i = array_shift($keys)) !== null) {
1365
-                        $out[] = $callback($items[$i]);
1366
-                    }
1367
-                } elseif ($cnt === 2) {
1368
-                    while (($i = array_shift($keys)) !== null) {
1369
-                        $out[] = $callback($items[$i], $params[1]);
1370
-                    }
1371
-                } elseif ($cnt === 3) {
1372
-                    while (($i = array_shift($keys)) !== null) {
1373
-                        $out[] = $callback($items[$i], $params[1], $params[2]);
1374
-                    }
1375
-                } elseif ($cnt === 4) {
1376
-                    while (($i = array_shift($keys)) !== null) {
1377
-                        $out[] = $callback($items[$i], $params[1], $params[2], $params[3]);
1378
-                    }
1379
-                } else {
1380
-                    while (($i = array_shift($keys)) !== null) {
1381
-                        $out[] = call_user_func_array($callback, array($items[$i]) + $params);
1382
-                    }
1383
-                }
1384
-            }
1385
-
1386
-            return $out;
1387
-        } else {
1388
-            return $params[0];
1389
-        }
1390
-    }
1391
-
1392
-    /**
1393
-     * Reads a variable into the given data array.
1394
-     *
1395
-     * @param string $varstr   the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property")
1396
-     * @param mixed  $data     the data array or object to read from
1397
-     * @param bool   $safeRead if true, the function will check whether the index exists to prevent any notices from
1398
-     *                         being output
1399
-     *
1400
-     * @return mixed
1401
-     */
1402
-    public function readVarInto($varstr, $data, $safeRead = false)
1403
-    {
1404
-        if ($data === null) {
1405
-            return null;
1406
-        }
1407
-
1408
-        if (is_array($varstr) === false) {
1409
-            preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m);
1410
-        } else {
1411
-            $m = $varstr;
1412
-        }
1413
-        unset($varstr);
1414
-
1415
-        while (list($k, $sep) = each($m[1])) {
1416
-            if ($sep === '.' || $sep === '[' || $sep === '') {
1417
-                // strip enclosing quotes if present
1418
-                $m[2][$k] = preg_replace('#^(["\']?)(.*?)\1$#', '$2', $m[2][$k]);
1419
-
1420
-                if ((is_array($data) || $data instanceof ArrayAccess) && ($safeRead === false || isset($data[$m[2][$k]]))) {
1421
-                    $data = $data[$m[2][$k]];
1422
-                } else {
1423
-                    return null;
1424
-                }
1425
-            } else {
1426
-                if (is_object($data) && ($safeRead === false || isset($data->{$m[2][$k]}))) {
1427
-                    $data = $data->{$m[2][$k]};
1428
-                } else {
1429
-                    return null;
1430
-                }
1431
-            }
1432
-        }
1433
-
1434
-        return $data;
1435
-    }
1436
-
1437
-    /**
1438
-     * Reads a variable into the parent scope.
1439
-     *
1440
-     * @param int    $parentLevels the amount of parent levels to go from the current scope
1441
-     * @param string $varstr       the variable string, using dwoo variable syntax (i.e.
1442
-     *                             "var.subvar[subsubvar]->property")
1443
-     *
1444
-     * @return mixed
1445
-     */
1446
-    public function readParentVar($parentLevels, $varstr = null)
1447
-    {
1448
-        $tree = $this->scopeTree;
1449
-        $cur  = $this->data;
1450
-
1451
-        while ($parentLevels -- !== 0) {
1452
-            array_pop($tree);
1453
-        }
1454
-
1455
-        while (($i = array_shift($tree)) !== null) {
1456
-            if (is_object($cur)) {
1457
-                $cur = $cur->{$i};
1458
-            } else {
1459
-                $cur = $cur[$i];
1460
-            }
1461
-        }
1462
-
1463
-        if ($varstr !== null) {
1464
-            return $this->readVarInto($varstr, $cur);
1465
-        } else {
1466
-            return $cur;
1467
-        }
1468
-    }
1469
-
1470
-    /**
1471
-     * Reads a variable into the current scope.
1472
-     *
1473
-     * @param string $varstr the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property")
1474
-     *
1475
-     * @return mixed
1476
-     */
1477
-    public function readVar($varstr)
1478
-    {
1479
-        if (is_array($varstr) === true) {
1480
-            $m = $varstr;
1481
-            unset($varstr);
1482
-        } else {
1483
-            if (strstr($varstr, '.') === false && strstr($varstr, '[') === false && strstr($varstr, '->') === false) {
1484
-                if ($varstr === 'dwoo') {
1485
-                    return $this->getGlobals();
1486
-                } elseif ($varstr === '__' || $varstr === '_root') {
1487
-                    return $this->data;
1488
-                } elseif ($varstr === '_' || $varstr === '_parent') {
1489
-                    $varstr = '.' . $varstr;
1490
-                    $tree   = $this->scopeTree;
1491
-                    $cur    = $this->data;
1492
-                    array_pop($tree);
1493
-
1494
-                    while (($i = array_shift($tree)) !== null) {
1495
-                        if (is_object($cur)) {
1496
-                            $cur = $cur->{$i};
1497
-                        } else {
1498
-                            $cur = $cur[$i];
1499
-                        }
1500
-                    }
1501
-
1502
-                    return $cur;
1503
-                }
1504
-
1505
-                $cur = $this->scope;
1506
-
1507
-                if (isset($cur[$varstr])) {
1508
-                    return $cur[$varstr];
1509
-                } else {
1510
-                    return null;
1511
-                }
1512
-            }
1513
-
1514
-            if (substr($varstr, 0, 1) === '.') {
1515
-                $varstr = 'dwoo' . $varstr;
1516
-            }
1517
-
1518
-            preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m);
1519
-        }
1520
-
1521
-        $i = $m[2][0];
1522
-        if ($i === 'dwoo') {
1523
-            $cur = $this->getGlobals();
1524
-            array_shift($m[2]);
1525
-            array_shift($m[1]);
1526
-            switch ($m[2][0]) {
1527
-            case 'get':
1528
-                $cur = $_GET;
1529
-                break;
1530
-            case 'post':
1531
-                $cur = $_POST;
1532
-                break;
1533
-            case 'session':
1534
-                $cur = $_SESSION;
1535
-                break;
1536
-            case 'cookies':
1537
-            case 'cookie':
1538
-                $cur = $_COOKIE;
1539
-                break;
1540
-            case 'server':
1541
-                $cur = $_SERVER;
1542
-                break;
1543
-            case 'env':
1544
-                $cur = $_ENV;
1545
-                break;
1546
-            case 'request':
1547
-                $cur = $_REQUEST;
1548
-                break;
1549
-            case 'const':
1550
-                array_shift($m[2]);
1551
-                if (defined($m[2][0])) {
1552
-                    return constant($m[2][0]);
1553
-                } else {
1554
-                    return null;
1555
-                }
1556
-            }
1557
-            if ($cur !== $this->getGlobals()) {
1558
-                array_shift($m[2]);
1559
-                array_shift($m[1]);
1560
-            }
1561
-        } elseif ($i === '__' || $i === '_root') {
1562
-            $cur = $this->data;
1563
-            array_shift($m[2]);
1564
-            array_shift($m[1]);
1565
-        } elseif ($i === '_' || $i === '_parent') {
1566
-            $tree = $this->scopeTree;
1567
-            $cur  = $this->data;
1568
-
1569
-            while (true) {
1570
-                array_pop($tree);
1571
-                array_shift($m[2]);
1572
-                array_shift($m[1]);
1573
-                if (current($m[2]) === '_' || current($m[2]) === '_parent') {
1574
-                    continue;
1575
-                }
1576
-
1577
-                while (($i = array_shift($tree)) !== null) {
1578
-                    if (is_object($cur)) {
1579
-                        $cur = $cur->{$i};
1580
-                    } else {
1581
-                        $cur = $cur[$i];
1582
-                    }
1583
-                }
1584
-                break;
1585
-            }
1586
-        } else {
1587
-            $cur = $this->scope;
1588
-        }
1589
-
1590
-        while (list($k, $sep) = each($m[1])) {
1591
-            if ($sep === '.' || $sep === '[' || $sep === '') {
1592
-                if ((is_array($cur) || $cur instanceof ArrayAccess) && isset($cur[$m[2][$k]])) {
1593
-                    $cur = $cur[$m[2][$k]];
1594
-                } else {
1595
-                    return null;
1596
-                }
1597
-            } elseif ($sep === '->') {
1598
-                if (is_object($cur)) {
1599
-                    $cur = $cur->{$m[2][$k]};
1600
-                } else {
1601
-                    return null;
1602
-                }
1603
-            } else {
1604
-                return null;
1605
-            }
1606
-        }
1607
-
1608
-        return $cur;
1609
-    }
1610
-
1611
-    /**
1612
-     * Assign the value to the given variable.
1613
-     *
1614
-     * @param mixed  $value the value to assign
1615
-     * @param string $scope the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property")
1616
-     *
1617
-     * @return bool true if assigned correctly or false if a problem occured while parsing the var string
1618
-     */
1619
-    public function assignInScope($value, $scope)
1620
-    {
1621
-        if (!is_string($scope)) {
1622
-            $this->triggerError('Assignments must be done into strings, (' . gettype($scope) . ') ' . var_export($scope, true) . ' given', E_USER_ERROR);
1623
-        }
1624
-        if (strstr($scope, '.') === false && strstr($scope, '->') === false) {
1625
-            $this->scope[$scope] = $value;
1626
-        } else {
1627
-            // TODO handle _root/_parent scopes ?
1628
-            preg_match_all('#(\[|->|\.)?([^.[\]-]+)\]?#i', $scope, $m);
1629
-
1630
-            $cur  = &$this->scope;
1631
-            $last = array(
1632
-                array_pop($m[1]),
1633
-                array_pop($m[2])
1634
-            );
1635
-
1636
-            while (list($k, $sep) = each($m[1])) {
1637
-                if ($sep === '.' || $sep === '[' || $sep === '') {
1638
-                    if (is_array($cur) === false) {
1639
-                        $cur = array();
1640
-                    }
1641
-                    $cur = &$cur[$m[2][$k]];
1642
-                } elseif ($sep === '->') {
1643
-                    if (is_object($cur) === false) {
1644
-                        $cur = new stdClass();
1645
-                    }
1646
-                    $cur = &$cur->{$m[2][$k]};
1647
-                } else {
1648
-                    return false;
1649
-                }
1650
-            }
1651
-
1652
-            if ($last[0] === '.' || $last[0] === '[' || $last[0] === '') {
1653
-                if (is_array($cur) === false) {
1654
-                    $cur = array();
1655
-                }
1656
-                $cur[$last[1]] = $value;
1657
-            } elseif ($last[0] === '->') {
1658
-                if (is_object($cur) === false) {
1659
-                    $cur = new stdClass();
1660
-                }
1661
-                $cur->{$last[1]} = $value;
1662
-            } else {
1663
-                return false;
1664
-            }
1665
-        }
1666
-    }
1667
-
1668
-    /**
1669
-     * Sets the scope to the given scope string or array.
1670
-     *
1671
-     * @param mixed $scope    a string i.e. "level1.level2" or an array i.e. array("level1", "level2")
1672
-     * @param bool  $absolute if true, the scope is set from the top level scope and not from the current scope
1673
-     *
1674
-     * @return array the current scope tree
1675
-     */
1676
-    public function setScope($scope, $absolute = false)
1677
-    {
1678
-        $old = $this->scopeTree;
1679
-
1680
-        if (is_string($scope) === true) {
1681
-            $scope = explode('.', $scope);
1682
-        }
1683
-
1684
-        if ($absolute === true) {
1685
-            $this->scope     = &$this->data;
1686
-            $this->scopeTree = array();
1687
-        }
1688
-
1689
-        while (($bit = array_shift($scope)) !== null) {
1690
-            if ($bit === '_' || $bit === '_parent') {
1691
-                array_pop($this->scopeTree);
1692
-                $this->scope = &$this->data;
1693
-                $cnt         = count($this->scopeTree);
1694
-                for ($i = 0; $i < $cnt; ++ $i) {
1695
-                    $this->scope = &$this->scope[$this->scopeTree[$i]];
1696
-                }
1697
-            } elseif ($bit === '__' || $bit === '_root') {
1698
-                $this->scope     = &$this->data;
1699
-                $this->scopeTree = array();
1700
-            } elseif (isset($this->scope[$bit])) {
1701
-                if ($this->scope instanceof ArrayAccess) {
1702
-                    $tmp         = $this->scope[$bit];
1703
-                    $this->scope = &$tmp;
1704
-                } else {
1705
-                    $this->scope = &$this->scope[$bit];
1706
-                }
1707
-                $this->scopeTree[] = $bit;
1708
-            } else {
1709
-                unset($this->scope);
1710
-                $this->scope = null;
1711
-            }
1712
-        }
1713
-
1714
-        return $old;
1715
-    }
1716
-
1717
-    /**
1718
-     * Returns the entire data array.
1719
-     *
1720
-     * @return array
1721
-     */
1722
-    public function getData()
1723
-    {
1724
-        return $this->data;
1725
-    }
1726
-
1727
-    /**
1728
-     * Sets a return value for the currently running template.
1729
-     *
1730
-     * @param string $name  var name
1731
-     * @param mixed  $value var value
1732
-     *
1733
-     * @return void
1734
-     */
1735
-    public function setReturnValue($name, $value)
1736
-    {
1737
-        $this->returnData[$name] = $value;
1738
-    }
1739
-
1740
-    /**
1741
-     * Retrieves the return values set by the template.
1742
-     *
1743
-     * @return array
1744
-     */
1745
-    public function getReturnValues()
1746
-    {
1747
-        return $this->returnData;
1748
-    }
1749
-
1750
-    /**
1751
-     * Returns a reference to the current scope.
1752
-     *
1753
-     * @return mixed
1754
-     */
1755
-    public function &getScope()
1756
-    {
1757
-        return $this->scope;
1758
-    }
1759
-
1760
-    /**
1761
-     * Redirects all calls to unexisting to plugin proxy.
1762
-     *
1763
-     * @param string $method the method name
1764
-     * @param array  $args   array of arguments
1765
-     *
1766
-     * @return mixed
1767
-     * @throws Exception
1768
-     */
1769
-    public function __call($method, $args)
1770
-    {
1771
-        $proxy = $this->getPluginProxy();
1772
-        if (!$proxy) {
1773
-            throw new Exception('Call to undefined method ' . __CLASS__ . '::' . $method . '()');
1774
-        }
1775
-
1776
-        return call_user_func_array($proxy->getCallback($method), $args);
1777
-    }
1778
-
1779
-    /**
1780
-     * Convert plugin name from `auto_escape` to `AutoEscape`.
1781
-     * @param string $input
1782
-     * @param string $separator
1783
-     *
1784
-     * @return mixed
1785
-     */
1786
-    public static function toCamelCase($input, $separator = '_')
1787
-    {
1788
-        return join(array_map('ucfirst', explode($separator, $input)));
1789
-
1790
-        // TODO >= PHP5.4.32
1791
-        //return str_replace($separator, '', ucwords($input, $separator));
1792
-    }
617
+				);
618
+			}
619
+
620
+			$this->filters[] = $callback;
621
+		} else {
622
+			$this->filters[] = $callback;
623
+		}
624
+	}
625
+
626
+	/**
627
+	 * Removes a filter.
628
+	 *
629
+	 * @param mixed $callback callback or filter name if it was autoloaded
630
+	 *
631
+	 * @return void
632
+	 */
633
+	public function removeFilter($callback)
634
+	{
635
+		if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS. 'Filter' . self::toCamelCase($callback), $this->filters,
636
+				true)) !==
637
+			false) {
638
+			unset($this->filters[$index]);
639
+		} elseif (($index = array_search($callback, $this->filters, true)) !== false) {
640
+			unset($this->filters[$index]);
641
+		} else {
642
+			$class = self::NAMESPACE_PLUGINS_FILTERS . 'Filter' . $callback;
643
+			foreach ($this->filters as $index => $filter) {
644
+				if (is_array($filter) && $filter[0] instanceof $class) {
645
+					unset($this->filters[$index]);
646
+					break;
647
+				}
648
+			}
649
+		}
650
+	}
651
+
652
+	/**
653
+	 * Adds a resource or overrides a default one.
654
+	 *
655
+	 * @param string   $name            the resource name
656
+	 * @param string   $class           the resource class (which must implement ITemplate)
657
+	 * @param callback $compilerFactory the compiler factory callback, a function that must return a compiler instance
658
+	 *                                  used to compile this resource, if none is provided. by default it will produce
659
+	 *                                  a Compiler object
660
+	 *
661
+	 * @return void
662
+	 * @throws Exception
663
+	 */
664
+	public function addResource($name, $class, $compilerFactory = null)
665
+	{
666
+		if (strlen($name) < 2) {
667
+			throw new Exception('Resource names must be at least two-character long to avoid conflicts with Windows paths');
668
+		}
669
+
670
+		if (!class_exists($class)) {
671
+			throw new Exception(sprintf('Resource class %s does not exist', $class));
672
+		}
673
+
674
+		$interfaces = class_implements($class);
675
+		if (in_array('Dwoo\ITemplate', $interfaces) === false) {
676
+			throw new Exception('Resource class must implement ITemplate');
677
+		}
678
+
679
+		$this->resources[$name] = array(
680
+			'class'    => $class,
681
+			'compiler' => $compilerFactory
682
+		);
683
+	}
684
+
685
+	/**
686
+	 * Removes a custom resource.
687
+	 *
688
+	 * @param string $name the resource name
689
+	 *
690
+	 * @return void
691
+	 */
692
+	public function removeResource($name)
693
+	{
694
+		unset($this->resources[$name]);
695
+		if ($name === 'file') {
696
+			$this->resources['file'] = array(
697
+				'class'    => 'Dwoo\Template\File',
698
+				'compiler' => null
699
+			);
700
+		}
701
+	}
702
+
703
+	/**
704
+	 * Sets the loader object to use to load plugins.
705
+	 *
706
+	 * @param ILoader $loader loader
707
+	 *
708
+	 * @return void
709
+	 */
710
+	public function setLoader(ILoader $loader)
711
+	{
712
+		$this->loader = $loader;
713
+	}
714
+
715
+	/**
716
+	 * Returns the current loader object or a default one if none is currently found.
717
+	 *
718
+	 * @return ILoader|Loader
719
+	 */
720
+	public function getLoader()
721
+	{
722
+		if ($this->loader === null) {
723
+			$this->loader = new Loader($this->getCompileDir());
724
+		}
725
+
726
+		return $this->loader;
727
+	}
728
+
729
+	/**
730
+	 * Returns the custom plugins loaded.
731
+	 * Used by the ITemplate classes to pass the custom plugins to their ICompiler instance.
732
+	 *
733
+	 * @return array
734
+	 */
735
+	public function getCustomPlugins()
736
+	{
737
+		return $this->plugins;
738
+	}
739
+
740
+	/**
741
+	 * Return a specified custom plugin loaded by his name.
742
+	 * Used by the compiler, for executing a Closure.
743
+	 *
744
+	 * @param string $name
745
+	 *
746
+	 * @return mixed|null
747
+	 */
748
+	public function getCustomPlugin($name)
749
+	{
750
+		if (isset($this->plugins[$name])) {
751
+			return $this->plugins[$name]['callback'];
752
+		}
753
+
754
+		return null;
755
+	}
756
+
757
+	/**
758
+	 * Returns the cache directory with a trailing DIRECTORY_SEPARATOR.
759
+	 *
760
+	 * @return string
761
+	 */
762
+	public function getCacheDir()
763
+	{
764
+		if ($this->cacheDir === null) {
765
+			$this->setCacheDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR);
766
+		}
767
+
768
+		return $this->cacheDir;
769
+	}
770
+
771
+	/**
772
+	 * Sets the cache directory and automatically appends a DIRECTORY_SEPARATOR.
773
+	 *
774
+	 * @param string $dir the cache directory
775
+	 *
776
+	 * @return void
777
+	 * @throws Exception
778
+	 */
779
+	public function setCacheDir($dir)
780
+	{
781
+		$this->cacheDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
782
+		if (is_writable($this->cacheDir) === false) {
783
+			throw new Exception('The cache directory must be writable, chmod "' . $this->cacheDir . '" to make it writable');
784
+		}
785
+	}
786
+
787
+	/**
788
+	 * Returns the compile directory with a trailing DIRECTORY_SEPARATOR.
789
+	 *
790
+	 * @return string
791
+	 */
792
+	public function getCompileDir()
793
+	{
794
+		if ($this->compileDir === null) {
795
+			$this->setCompileDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'compiled' . DIRECTORY_SEPARATOR);
796
+		}
797
+
798
+		return $this->compileDir;
799
+	}
800
+
801
+	/**
802
+	 * Sets the compile directory and automatically appends a DIRECTORY_SEPARATOR.
803
+	 *
804
+	 * @param string $dir the compile directory
805
+	 *
806
+	 * @return void
807
+	 * @throws Exception
808
+	 */
809
+	public function setCompileDir($dir)
810
+	{
811
+		$this->compileDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
812
+		if (is_writable($this->compileDir) === false) {
813
+			throw new Exception('The compile directory must be writable, chmod "' . $this->compileDir . '" to make it writable');
814
+		}
815
+	}
816
+
817
+	/**
818
+	 * Returns an array of the template directory with a trailing DIRECTORY_SEPARATOR
819
+	 *
820
+	 * @return array
821
+	 */
822
+	public function getTemplateDir()
823
+	{
824
+		return $this->templateDir;
825
+	}
826
+
827
+	/**
828
+	 * sets the template directory and automatically appends a DIRECTORY_SEPARATOR
829
+	 * template directory is stored in an array
830
+	 *
831
+	 * @param string $dir
832
+	 *
833
+	 * @throws Exception
834
+	 */
835
+	public function setTemplateDir($dir)
836
+	{
837
+		$tmpDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
838
+		if (is_dir($tmpDir) === false) {
839
+			throw new Exception('The template directory: "' . $tmpDir . '" does not exists, create the directory or specify an other location !');
840
+		}
841
+		$this->templateDir[] = $tmpDir;
842
+	}
843
+
844
+	/**
845
+	 * Returns the default cache time that is used with templates that do not have a cache time set.
846
+	 *
847
+	 * @return int the duration in seconds
848
+	 */
849
+	public function getCacheTime()
850
+	{
851
+		return $this->cacheTime;
852
+	}
853
+
854
+	/**
855
+	 * Sets the default cache time to use with templates that do not have a cache time set.
856
+	 *
857
+	 * @param int $seconds the duration in seconds
858
+	 *
859
+	 * @return void
860
+	 */
861
+	public function setCacheTime($seconds)
862
+	{
863
+		$this->cacheTime = (int)$seconds;
864
+	}
865
+
866
+	/**
867
+	 * Returns the character set used by the string manipulation plugins.
868
+	 * the charset is automatically lowercased
869
+	 *
870
+	 * @return string
871
+	 */
872
+	public function getCharset()
873
+	{
874
+		return $this->charset;
875
+	}
876
+
877
+	/**
878
+	 * Sets the character set used by the string manipulation plugins.
879
+	 * the charset will be automatically lowercased
880
+	 *
881
+	 * @param string $charset the character set
882
+	 *
883
+	 * @return void
884
+	 */
885
+	public function setCharset($charset)
886
+	{
887
+		$this->charset = strtolower((string)$charset);
888
+	}
889
+
890
+	/**
891
+	 * Returns the current template being rendered, when applicable, or null.
892
+	 *
893
+	 * @return ITemplate|null
894
+	 */
895
+	public function getTemplate()
896
+	{
897
+		return $this->template;
898
+	}
899
+
900
+	/**
901
+	 * Sets the current template being rendered.
902
+	 *
903
+	 * @param ITemplate $tpl template object
904
+	 *
905
+	 * @return void
906
+	 */
907
+	public function setTemplate(ITemplate $tpl)
908
+	{
909
+		$this->template = $tpl;
910
+	}
911
+
912
+	/**
913
+	 * Sets the default compiler factory function for the given resource name.
914
+	 * a compiler factory must return a ICompiler object pre-configured to fit your needs
915
+	 *
916
+	 * @param string   $resourceName    the resource name (i.e. file, string)
917
+	 * @param callback $compilerFactory the compiler factory callback
918
+	 *
919
+	 * @return void
920
+	 */
921
+	public function setDefaultCompilerFactory($resourceName, $compilerFactory)
922
+	{
923
+		$this->resources[$resourceName]['compiler'] = $compilerFactory;
924
+	}
925
+
926
+	/**
927
+	 * Returns the default compiler factory function for the given resource name.
928
+	 *
929
+	 * @param string $resourceName the resource name
930
+	 *
931
+	 * @return callback the compiler factory callback
932
+	 */
933
+	public function getDefaultCompilerFactory($resourceName)
934
+	{
935
+		return $this->resources[$resourceName]['compiler'];
936
+	}
937
+
938
+	/**
939
+	 * Sets the security policy object to enforce some php security settings.
940
+	 * use this if untrusted persons can modify templates
941
+	 *
942
+	 * @param SecurityPolicy $policy the security policy object
943
+	 *
944
+	 * @return void
945
+	 */
946
+	public function setSecurityPolicy(SecurityPolicy $policy = null)
947
+	{
948
+		$this->securityPolicy = $policy;
949
+	}
950
+
951
+	/**
952
+	 * Returns the current security policy object or null by default.
953
+	 *
954
+	 * @return SecurityPolicy|null the security policy object if any
955
+	 */
956
+	public function getSecurityPolicy()
957
+	{
958
+		return $this->securityPolicy;
959
+	}
960
+
961
+	/**
962
+	 * Sets the object that must be used as a plugin proxy when plugin can't be found
963
+	 * by dwoo's loader.
964
+	 *
965
+	 * @param IPluginProxy $pluginProxy the proxy object
966
+	 *
967
+	 * @return void
968
+	 */
969
+	public function setPluginProxy(IPluginProxy $pluginProxy)
970
+	{
971
+		$this->pluginProxy = $pluginProxy;
972
+	}
973
+
974
+	/**
975
+	 * Returns the current plugin proxy object or null by default.
976
+	 *
977
+	 * @return IPluginProxy
978
+	 */
979
+	public function getPluginProxy()
980
+	{
981
+		return $this->pluginProxy;
982
+	}
983
+
984
+	/**
985
+	 * Checks whether the given template is cached or not.
986
+	 *
987
+	 * @param ITemplate $tpl the template object
988
+	 *
989
+	 * @return bool
990
+	 */
991
+	public function isCached(ITemplate $tpl)
992
+	{
993
+		return is_string($tpl->getCachedTemplate($this));
994
+	}
995
+
996
+	/**
997
+	 * Clear templates inside the compiled directory.
998
+	 *
999
+	 * @return int
1000
+	 */
1001
+	public function clearCompiled()
1002
+	{
1003
+		$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCompileDir()), \RecursiveIteratorIterator::SELF_FIRST);
1004
+		$count    = 0;
1005
+		foreach ($iterator as $file) {
1006
+			if ($file->isFile()) {
1007
+				$count += unlink($file->__toString()) ? 1 : 0;
1008
+			}
1009
+		}
1010
+
1011
+		return $count;
1012
+	}
1013
+
1014
+	/**
1015
+	 * Clears the cached templates if they are older than the given time.
1016
+	 *
1017
+	 * @param int $olderThan minimum time (in seconds) required for a cached template to be cleared
1018
+	 *
1019
+	 * @return int the amount of templates cleared
1020
+	 */
1021
+	public function clearCache($olderThan = - 1)
1022
+	{
1023
+		$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCacheDir()), \RecursiveIteratorIterator::SELF_FIRST);
1024
+		$expired  = time() - $olderThan;
1025
+		$count    = 0;
1026
+		foreach ($iterator as $file) {
1027
+			if ($file->isFile() && $file->getCTime() < $expired) {
1028
+				$count += unlink((string)$file) ? 1 : 0;
1029
+			}
1030
+		}
1031
+
1032
+		return $count;
1033
+	}
1034
+
1035
+	/**
1036
+	 * Fetches a template object of the given resource.
1037
+	 *
1038
+	 * @param string    $resourceName   the resource name (i.e. file, string)
1039
+	 * @param string    $resourceId     the resource identifier (i.e. file path)
1040
+	 * @param int       $cacheTime      the cache time setting for this resource
1041
+	 * @param string    $cacheId        the unique cache identifier
1042
+	 * @param string    $compileId      the unique compiler identifier
1043
+	 * @param ITemplate $parentTemplate the parent template
1044
+	 *
1045
+	 * @return ITemplate
1046
+	 * @throws Exception
1047
+	 */
1048
+	public function templateFactory($resourceName, $resourceId, $cacheTime = null, $cacheId = null, $compileId = null, ITemplate $parentTemplate = null)
1049
+	{
1050
+		if (isset($this->resources[$resourceName])) {
1051
+			/**
1052
+			 * Interface ITemplate
1053
+			 *
1054
+			 * @var ITemplate $class
1055
+			 */
1056
+			$class = $this->resources[$resourceName]['class'];
1057
+
1058
+			return $class::templateFactory($this, $resourceId, $cacheTime, $cacheId, $compileId, $parentTemplate);
1059
+		}
1060
+
1061
+		throw new Exception('Unknown resource type : ' . $resourceName);
1062
+	}
1063
+
1064
+	/**
1065
+	 * Checks if the input is an array or arrayaccess object, optionally it can also check if it's
1066
+	 * empty.
1067
+	 *
1068
+	 * @param mixed $value        the variable to check
1069
+	 * @param bool  $checkIsEmpty if true, the function will also check if the array|arrayaccess is empty,
1070
+	 *                            and return true only if it's not empty
1071
+	 *
1072
+	 * @return int|bool true if it's an array|arrayaccess (or the item count if $checkIsEmpty is true) or false if it's
1073
+	 *                  not an array|arrayaccess (or 0 if $checkIsEmpty is true)
1074
+	 */
1075
+	public function isArray($value, $checkIsEmpty = false)
1076
+	{
1077
+		if (is_array($value) === true || $value instanceof ArrayAccess) {
1078
+			if ($checkIsEmpty === false) {
1079
+				return true;
1080
+			}
1081
+
1082
+			return $this->count($value);
1083
+		}
1084
+
1085
+		return false;
1086
+	}
1087
+
1088
+	/**
1089
+	 * Checks if the input is an array or a traversable object, optionally it can also check if it's
1090
+	 * empty.
1091
+	 *
1092
+	 * @param mixed $value        the variable to check
1093
+	 * @param bool  $checkIsEmpty if true, the function will also check if the array|traversable is empty,
1094
+	 *                            and return true only if it's not empty
1095
+	 *
1096
+	 * @return int|bool true if it's an array|traversable (or the item count if $checkIsEmpty is true) or false if it's
1097
+	 *                  not an array|traversable (or 0 if $checkIsEmpty is true)
1098
+	 */
1099
+	public function isTraversable($value, $checkIsEmpty = false)
1100
+	{
1101
+		if (is_array($value) === true) {
1102
+			if ($checkIsEmpty === false) {
1103
+				return true;
1104
+			} else {
1105
+				return count($value) > 0;
1106
+			}
1107
+		} elseif ($value instanceof Traversable) {
1108
+			if ($checkIsEmpty === false) {
1109
+				return true;
1110
+			} else {
1111
+				return $this->count($value);
1112
+			}
1113
+		}
1114
+
1115
+		return false;
1116
+	}
1117
+
1118
+	/**
1119
+	 * Counts an array or arrayaccess/traversable object.
1120
+	 *
1121
+	 * @param mixed $value the value to count
1122
+	 *
1123
+	 * @return int|bool the count for arrays and objects that implement countable, true for other objects that don't,
1124
+	 *                  and 0 for empty elements
1125
+	 */
1126
+	public function count($value)
1127
+	{
1128
+		if (is_array($value) === true || $value instanceof Countable) {
1129
+			return count($value);
1130
+		} elseif ($value instanceof ArrayAccess) {
1131
+			if ($value->offsetExists(0)) {
1132
+				return true;
1133
+			}
1134
+		} elseif ($value instanceof Iterator) {
1135
+			$value->rewind();
1136
+			if ($value->valid()) {
1137
+				return true;
1138
+			}
1139
+		} elseif ($value instanceof Traversable) {
1140
+			foreach ($value as $dummy) {
1141
+				return true;
1142
+			}
1143
+		}
1144
+
1145
+		return 0;
1146
+	}
1147
+
1148
+	/**
1149
+	 * Triggers a dwoo error.
1150
+	 *
1151
+	 * @param string $message the error message
1152
+	 * @param int    $level   the error level, one of the PHP's E_* constants
1153
+	 *
1154
+	 * @return void
1155
+	 */
1156
+	public function triggerError($message, $level = E_USER_NOTICE)
1157
+	{
1158
+		if (!($tplIdentifier = $this->template->getResourceIdentifier())) {
1159
+			$tplIdentifier = $this->template->getResourceName();
1160
+		}
1161
+		trigger_error('Dwoo error (in ' . $tplIdentifier . ') : ' . $message, $level);
1162
+	}
1163
+
1164
+	/**
1165
+	 * Adds a block to the block stack.
1166
+	 *
1167
+	 * @param string $blockName the block name (without Dwoo_Plugin_ prefix)
1168
+	 * @param array  $args      the arguments to be passed to the block's init() function
1169
+	 *
1170
+	 * @return BlockPlugin the newly created block
1171
+	 */
1172
+	public function addStack($blockName, array $args = array())
1173
+	{
1174
+		if (isset($this->plugins[$blockName])) {
1175
+			$class = $this->plugins[$blockName]['class'];
1176
+		} else {
1177
+			$class = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . self::toCamelCase($blockName);
1178
+		}
1179
+
1180
+		if ($this->curBlock !== null) {
1181
+			$this->curBlock->buffer(ob_get_contents());
1182
+			ob_clean();
1183
+		} else {
1184
+			$this->buffer .= ob_get_contents();
1185
+			ob_clean();
1186
+		}
1187
+
1188
+		$block = new $class($this);
1189
+
1190
+		call_user_func_array(array($block, 'init'), $args);
1191
+
1192
+		$this->stack[] = $this->curBlock = $block;
1193
+
1194
+		return $block;
1195
+	}
1196
+
1197
+	/**
1198
+	 * Removes the plugin at the top of the block stack.
1199
+	 * Calls the block buffer() function, followed by a call to end() and finally a call to process()
1200
+	 *
1201
+	 * @return void
1202
+	 */
1203
+	public function delStack()
1204
+	{
1205
+		$args = func_get_args();
1206
+
1207
+		$this->curBlock->buffer(ob_get_contents());
1208
+		ob_clean();
1209
+
1210
+		call_user_func_array(array($this->curBlock, 'end'), $args);
1211
+
1212
+		$tmp = array_pop($this->stack);
1213
+
1214
+		if (count($this->stack) > 0) {
1215
+			$this->curBlock = end($this->stack);
1216
+			$this->curBlock->buffer($tmp->process());
1217
+		} else {
1218
+			if ($this->buffer !== '') {
1219
+				echo $this->buffer;
1220
+				$this->buffer = '';
1221
+			}
1222
+			$this->curBlock = null;
1223
+			echo $tmp->process();
1224
+		}
1225
+
1226
+		unset($tmp);
1227
+	}
1228
+
1229
+	/**
1230
+	 * Returns the parent block of the given block.
1231
+	 *
1232
+	 * @param BlockPlugin $block the block class plugin
1233
+	 *
1234
+	 * @return BlockPlugin|false if the given block isn't in the stack
1235
+	 */
1236
+	public function getParentBlock(BlockPlugin $block)
1237
+	{
1238
+		$index = array_search($block, $this->stack, true);
1239
+		if ($index !== false && $index > 0) {
1240
+			return $this->stack[$index - 1];
1241
+		}
1242
+
1243
+		return false;
1244
+	}
1245
+
1246
+	/**
1247
+	 * Finds the closest block of the given type, starting at the top of the stack.
1248
+	 *
1249
+	 * @param string $type the type of plugin you want to find
1250
+	 *
1251
+	 * @return BlockPlugin|false if no plugin of such type is in the stack
1252
+	 */
1253
+	public function findBlock($type)
1254
+	{
1255
+		if (isset($this->plugins[$type])) {
1256
+			$type = $this->plugins[$type]['class'];
1257
+		} else {
1258
+			$type = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin_' . str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin',
1259
+					'', $type);
1260
+		}
1261
+
1262
+		$keys = array_keys($this->stack);
1263
+		while (($key = array_pop($keys)) !== false) {
1264
+			if ($this->stack[$key] instanceof $type) {
1265
+				return $this->stack[$key];
1266
+			}
1267
+		}
1268
+
1269
+		return false;
1270
+	}
1271
+
1272
+	/**
1273
+	 * Returns a Plugin of the given class.
1274
+	 * this is so a single instance of every class plugin is created at each template run,
1275
+	 * allowing class plugins to have "per-template-run" static variables
1276
+	 *
1277
+	 * @param string $class the class name
1278
+	 *
1279
+	 * @return mixed an object of the given class
1280
+	 */
1281
+	public function getObjectPlugin($class)
1282
+	{
1283
+		if (isset($this->runtimePlugins[$class])) {
1284
+			return $this->runtimePlugins[$class];
1285
+		}
1286
+
1287
+		return $this->runtimePlugins[$class] = new $class($this);
1288
+	}
1289
+
1290
+	/**
1291
+	 * Calls the process() method of the given class-plugin name.
1292
+	 *
1293
+	 * @param string $plugName the class plugin name (without Dwoo_Plugin_ prefix)
1294
+	 * @param array  $params   an array of parameters to send to the process() method
1295
+	 *
1296
+	 * @return string the process() return value
1297
+	 */
1298
+	public function classCall($plugName, array $params = array())
1299
+	{
1300
+		$class  = self::toCamelCase($plugName);
1301
+		$plugin = $this->getObjectPlugin($class);
1302
+
1303
+		return call_user_func_array(array($plugin, 'process'), $params);
1304
+	}
1305
+
1306
+	/**
1307
+	 * Calls a php function.
1308
+	 *
1309
+	 * @param string $callback the function to call
1310
+	 * @param array  $params   an array of parameters to send to the function
1311
+	 *
1312
+	 * @return mixed the return value of the called function
1313
+	 */
1314
+	public function arrayMap($callback, array $params)
1315
+	{
1316
+		if ($params[0] === $this) {
1317
+			$addThis = true;
1318
+			array_shift($params);
1319
+		}
1320
+		if ((is_array($params[0]) || ($params[0] instanceof Iterator && $params[0] instanceof ArrayAccess))) {
1321
+			if (empty($params[0])) {
1322
+				return $params[0];
1323
+			}
1324
+
1325
+			// array map
1326
+			$out = array();
1327
+			$cnt = count($params);
1328
+
1329
+			if (isset($addThis)) {
1330
+				array_unshift($params, $this);
1331
+				$items = $params[1];
1332
+				$keys  = array_keys($items);
1333
+
1334
+				if (is_string($callback) === false) {
1335
+					while (($i = array_shift($keys)) !== null) {
1336
+						$out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params);
1337
+					}
1338
+				} elseif ($cnt === 1) {
1339
+					while (($i = array_shift($keys)) !== null) {
1340
+						$out[] = $callback($this, $items[$i]);
1341
+					}
1342
+				} elseif ($cnt === 2) {
1343
+					while (($i = array_shift($keys)) !== null) {
1344
+						$out[] = $callback($this, $items[$i], $params[2]);
1345
+					}
1346
+				} elseif ($cnt === 3) {
1347
+					while (($i = array_shift($keys)) !== null) {
1348
+						$out[] = $callback($this, $items[$i], $params[2], $params[3]);
1349
+					}
1350
+				} else {
1351
+					while (($i = array_shift($keys)) !== null) {
1352
+						$out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params);
1353
+					}
1354
+				}
1355
+			} else {
1356
+				$items = $params[0];
1357
+				$keys  = array_keys($items);
1358
+
1359
+				if (is_string($callback) === false) {
1360
+					while (($i = array_shift($keys)) !== null) {
1361
+						$out[] = call_user_func_array($callback, array($items[$i]) + $params);
1362
+					}
1363
+				} elseif ($cnt === 1) {
1364
+					while (($i = array_shift($keys)) !== null) {
1365
+						$out[] = $callback($items[$i]);
1366
+					}
1367
+				} elseif ($cnt === 2) {
1368
+					while (($i = array_shift($keys)) !== null) {
1369
+						$out[] = $callback($items[$i], $params[1]);
1370
+					}
1371
+				} elseif ($cnt === 3) {
1372
+					while (($i = array_shift($keys)) !== null) {
1373
+						$out[] = $callback($items[$i], $params[1], $params[2]);
1374
+					}
1375
+				} elseif ($cnt === 4) {
1376
+					while (($i = array_shift($keys)) !== null) {
1377
+						$out[] = $callback($items[$i], $params[1], $params[2], $params[3]);
1378
+					}
1379
+				} else {
1380
+					while (($i = array_shift($keys)) !== null) {
1381
+						$out[] = call_user_func_array($callback, array($items[$i]) + $params);
1382
+					}
1383
+				}
1384
+			}
1385
+
1386
+			return $out;
1387
+		} else {
1388
+			return $params[0];
1389
+		}
1390
+	}
1391
+
1392
+	/**
1393
+	 * Reads a variable into the given data array.
1394
+	 *
1395
+	 * @param string $varstr   the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property")
1396
+	 * @param mixed  $data     the data array or object to read from
1397
+	 * @param bool   $safeRead if true, the function will check whether the index exists to prevent any notices from
1398
+	 *                         being output
1399
+	 *
1400
+	 * @return mixed
1401
+	 */
1402
+	public function readVarInto($varstr, $data, $safeRead = false)
1403
+	{
1404
+		if ($data === null) {
1405
+			return null;
1406
+		}
1407
+
1408
+		if (is_array($varstr) === false) {
1409
+			preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m);
1410
+		} else {
1411
+			$m = $varstr;
1412
+		}
1413
+		unset($varstr);
1414
+
1415
+		while (list($k, $sep) = each($m[1])) {
1416
+			if ($sep === '.' || $sep === '[' || $sep === '') {
1417
+				// strip enclosing quotes if present
1418
+				$m[2][$k] = preg_replace('#^(["\']?)(.*?)\1$#', '$2', $m[2][$k]);
1419
+
1420
+				if ((is_array($data) || $data instanceof ArrayAccess) && ($safeRead === false || isset($data[$m[2][$k]]))) {
1421
+					$data = $data[$m[2][$k]];
1422
+				} else {
1423
+					return null;
1424
+				}
1425
+			} else {
1426
+				if (is_object($data) && ($safeRead === false || isset($data->{$m[2][$k]}))) {
1427
+					$data = $data->{$m[2][$k]};
1428
+				} else {
1429
+					return null;
1430
+				}
1431
+			}
1432
+		}
1433
+
1434
+		return $data;
1435
+	}
1436
+
1437
+	/**
1438
+	 * Reads a variable into the parent scope.
1439
+	 *
1440
+	 * @param int    $parentLevels the amount of parent levels to go from the current scope
1441
+	 * @param string $varstr       the variable string, using dwoo variable syntax (i.e.
1442
+	 *                             "var.subvar[subsubvar]->property")
1443
+	 *
1444
+	 * @return mixed
1445
+	 */
1446
+	public function readParentVar($parentLevels, $varstr = null)
1447
+	{
1448
+		$tree = $this->scopeTree;
1449
+		$cur  = $this->data;
1450
+
1451
+		while ($parentLevels -- !== 0) {
1452
+			array_pop($tree);
1453
+		}
1454
+
1455
+		while (($i = array_shift($tree)) !== null) {
1456
+			if (is_object($cur)) {
1457
+				$cur = $cur->{$i};
1458
+			} else {
1459
+				$cur = $cur[$i];
1460
+			}
1461
+		}
1462
+
1463
+		if ($varstr !== null) {
1464
+			return $this->readVarInto($varstr, $cur);
1465
+		} else {
1466
+			return $cur;
1467
+		}
1468
+	}
1469
+
1470
+	/**
1471
+	 * Reads a variable into the current scope.
1472
+	 *
1473
+	 * @param string $varstr the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property")
1474
+	 *
1475
+	 * @return mixed
1476
+	 */
1477
+	public function readVar($varstr)
1478
+	{
1479
+		if (is_array($varstr) === true) {
1480
+			$m = $varstr;
1481
+			unset($varstr);
1482
+		} else {
1483
+			if (strstr($varstr, '.') === false && strstr($varstr, '[') === false && strstr($varstr, '->') === false) {
1484
+				if ($varstr === 'dwoo') {
1485
+					return $this->getGlobals();
1486
+				} elseif ($varstr === '__' || $varstr === '_root') {
1487
+					return $this->data;
1488
+				} elseif ($varstr === '_' || $varstr === '_parent') {
1489
+					$varstr = '.' . $varstr;
1490
+					$tree   = $this->scopeTree;
1491
+					$cur    = $this->data;
1492
+					array_pop($tree);
1493
+
1494
+					while (($i = array_shift($tree)) !== null) {
1495
+						if (is_object($cur)) {
1496
+							$cur = $cur->{$i};
1497
+						} else {
1498
+							$cur = $cur[$i];
1499
+						}
1500
+					}
1501
+
1502
+					return $cur;
1503
+				}
1504
+
1505
+				$cur = $this->scope;
1506
+
1507
+				if (isset($cur[$varstr])) {
1508
+					return $cur[$varstr];
1509
+				} else {
1510
+					return null;
1511
+				}
1512
+			}
1513
+
1514
+			if (substr($varstr, 0, 1) === '.') {
1515
+				$varstr = 'dwoo' . $varstr;
1516
+			}
1517
+
1518
+			preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m);
1519
+		}
1520
+
1521
+		$i = $m[2][0];
1522
+		if ($i === 'dwoo') {
1523
+			$cur = $this->getGlobals();
1524
+			array_shift($m[2]);
1525
+			array_shift($m[1]);
1526
+			switch ($m[2][0]) {
1527
+			case 'get':
1528
+				$cur = $_GET;
1529
+				break;
1530
+			case 'post':
1531
+				$cur = $_POST;
1532
+				break;
1533
+			case 'session':
1534
+				$cur = $_SESSION;
1535
+				break;
1536
+			case 'cookies':
1537
+			case 'cookie':
1538
+				$cur = $_COOKIE;
1539
+				break;
1540
+			case 'server':
1541
+				$cur = $_SERVER;
1542
+				break;
1543
+			case 'env':
1544
+				$cur = $_ENV;
1545
+				break;
1546
+			case 'request':
1547
+				$cur = $_REQUEST;
1548
+				break;
1549
+			case 'const':
1550
+				array_shift($m[2]);
1551
+				if (defined($m[2][0])) {
1552
+					return constant($m[2][0]);
1553
+				} else {
1554
+					return null;
1555
+				}
1556
+			}
1557
+			if ($cur !== $this->getGlobals()) {
1558
+				array_shift($m[2]);
1559
+				array_shift($m[1]);
1560
+			}
1561
+		} elseif ($i === '__' || $i === '_root') {
1562
+			$cur = $this->data;
1563
+			array_shift($m[2]);
1564
+			array_shift($m[1]);
1565
+		} elseif ($i === '_' || $i === '_parent') {
1566
+			$tree = $this->scopeTree;
1567
+			$cur  = $this->data;
1568
+
1569
+			while (true) {
1570
+				array_pop($tree);
1571
+				array_shift($m[2]);
1572
+				array_shift($m[1]);
1573
+				if (current($m[2]) === '_' || current($m[2]) === '_parent') {
1574
+					continue;
1575
+				}
1576
+
1577
+				while (($i = array_shift($tree)) !== null) {
1578
+					if (is_object($cur)) {
1579
+						$cur = $cur->{$i};
1580
+					} else {
1581
+						$cur = $cur[$i];
1582
+					}
1583
+				}
1584
+				break;
1585
+			}
1586
+		} else {
1587
+			$cur = $this->scope;
1588
+		}
1589
+
1590
+		while (list($k, $sep) = each($m[1])) {
1591
+			if ($sep === '.' || $sep === '[' || $sep === '') {
1592
+				if ((is_array($cur) || $cur instanceof ArrayAccess) && isset($cur[$m[2][$k]])) {
1593
+					$cur = $cur[$m[2][$k]];
1594
+				} else {
1595
+					return null;
1596
+				}
1597
+			} elseif ($sep === '->') {
1598
+				if (is_object($cur)) {
1599
+					$cur = $cur->{$m[2][$k]};
1600
+				} else {
1601
+					return null;
1602
+				}
1603
+			} else {
1604
+				return null;
1605
+			}
1606
+		}
1607
+
1608
+		return $cur;
1609
+	}
1610
+
1611
+	/**
1612
+	 * Assign the value to the given variable.
1613
+	 *
1614
+	 * @param mixed  $value the value to assign
1615
+	 * @param string $scope the variable string, using dwoo variable syntax (i.e. "var.subvar[subsubvar]->property")
1616
+	 *
1617
+	 * @return bool true if assigned correctly or false if a problem occured while parsing the var string
1618
+	 */
1619
+	public function assignInScope($value, $scope)
1620
+	{
1621
+		if (!is_string($scope)) {
1622
+			$this->triggerError('Assignments must be done into strings, (' . gettype($scope) . ') ' . var_export($scope, true) . ' given', E_USER_ERROR);
1623
+		}
1624
+		if (strstr($scope, '.') === false && strstr($scope, '->') === false) {
1625
+			$this->scope[$scope] = $value;
1626
+		} else {
1627
+			// TODO handle _root/_parent scopes ?
1628
+			preg_match_all('#(\[|->|\.)?([^.[\]-]+)\]?#i', $scope, $m);
1629
+
1630
+			$cur  = &$this->scope;
1631
+			$last = array(
1632
+				array_pop($m[1]),
1633
+				array_pop($m[2])
1634
+			);
1635
+
1636
+			while (list($k, $sep) = each($m[1])) {
1637
+				if ($sep === '.' || $sep === '[' || $sep === '') {
1638
+					if (is_array($cur) === false) {
1639
+						$cur = array();
1640
+					}
1641
+					$cur = &$cur[$m[2][$k]];
1642
+				} elseif ($sep === '->') {
1643
+					if (is_object($cur) === false) {
1644
+						$cur = new stdClass();
1645
+					}
1646
+					$cur = &$cur->{$m[2][$k]};
1647
+				} else {
1648
+					return false;
1649
+				}
1650
+			}
1651
+
1652
+			if ($last[0] === '.' || $last[0] === '[' || $last[0] === '') {
1653
+				if (is_array($cur) === false) {
1654
+					$cur = array();
1655
+				}
1656
+				$cur[$last[1]] = $value;
1657
+			} elseif ($last[0] === '->') {
1658
+				if (is_object($cur) === false) {
1659
+					$cur = new stdClass();
1660
+				}
1661
+				$cur->{$last[1]} = $value;
1662
+			} else {
1663
+				return false;
1664
+			}
1665
+		}
1666
+	}
1667
+
1668
+	/**
1669
+	 * Sets the scope to the given scope string or array.
1670
+	 *
1671
+	 * @param mixed $scope    a string i.e. "level1.level2" or an array i.e. array("level1", "level2")
1672
+	 * @param bool  $absolute if true, the scope is set from the top level scope and not from the current scope
1673
+	 *
1674
+	 * @return array the current scope tree
1675
+	 */
1676
+	public function setScope($scope, $absolute = false)
1677
+	{
1678
+		$old = $this->scopeTree;
1679
+
1680
+		if (is_string($scope) === true) {
1681
+			$scope = explode('.', $scope);
1682
+		}
1683
+
1684
+		if ($absolute === true) {
1685
+			$this->scope     = &$this->data;
1686
+			$this->scopeTree = array();
1687
+		}
1688
+
1689
+		while (($bit = array_shift($scope)) !== null) {
1690
+			if ($bit === '_' || $bit === '_parent') {
1691
+				array_pop($this->scopeTree);
1692
+				$this->scope = &$this->data;
1693
+				$cnt         = count($this->scopeTree);
1694
+				for ($i = 0; $i < $cnt; ++ $i) {
1695
+					$this->scope = &$this->scope[$this->scopeTree[$i]];
1696
+				}
1697
+			} elseif ($bit === '__' || $bit === '_root') {
1698
+				$this->scope     = &$this->data;
1699
+				$this->scopeTree = array();
1700
+			} elseif (isset($this->scope[$bit])) {
1701
+				if ($this->scope instanceof ArrayAccess) {
1702
+					$tmp         = $this->scope[$bit];
1703
+					$this->scope = &$tmp;
1704
+				} else {
1705
+					$this->scope = &$this->scope[$bit];
1706
+				}
1707
+				$this->scopeTree[] = $bit;
1708
+			} else {
1709
+				unset($this->scope);
1710
+				$this->scope = null;
1711
+			}
1712
+		}
1713
+
1714
+		return $old;
1715
+	}
1716
+
1717
+	/**
1718
+	 * Returns the entire data array.
1719
+	 *
1720
+	 * @return array
1721
+	 */
1722
+	public function getData()
1723
+	{
1724
+		return $this->data;
1725
+	}
1726
+
1727
+	/**
1728
+	 * Sets a return value for the currently running template.
1729
+	 *
1730
+	 * @param string $name  var name
1731
+	 * @param mixed  $value var value
1732
+	 *
1733
+	 * @return void
1734
+	 */
1735
+	public function setReturnValue($name, $value)
1736
+	{
1737
+		$this->returnData[$name] = $value;
1738
+	}
1739
+
1740
+	/**
1741
+	 * Retrieves the return values set by the template.
1742
+	 *
1743
+	 * @return array
1744
+	 */
1745
+	public function getReturnValues()
1746
+	{
1747
+		return $this->returnData;
1748
+	}
1749
+
1750
+	/**
1751
+	 * Returns a reference to the current scope.
1752
+	 *
1753
+	 * @return mixed
1754
+	 */
1755
+	public function &getScope()
1756
+	{
1757
+		return $this->scope;
1758
+	}
1759
+
1760
+	/**
1761
+	 * Redirects all calls to unexisting to plugin proxy.
1762
+	 *
1763
+	 * @param string $method the method name
1764
+	 * @param array  $args   array of arguments
1765
+	 *
1766
+	 * @return mixed
1767
+	 * @throws Exception
1768
+	 */
1769
+	public function __call($method, $args)
1770
+	{
1771
+		$proxy = $this->getPluginProxy();
1772
+		if (!$proxy) {
1773
+			throw new Exception('Call to undefined method ' . __CLASS__ . '::' . $method . '()');
1774
+		}
1775
+
1776
+		return call_user_func_array($proxy->getCallback($method), $args);
1777
+	}
1778
+
1779
+	/**
1780
+	 * Convert plugin name from `auto_escape` to `AutoEscape`.
1781
+	 * @param string $input
1782
+	 * @param string $separator
1783
+	 *
1784
+	 * @return mixed
1785
+	 */
1786
+	public static function toCamelCase($input, $separator = '_')
1787
+	{
1788
+		return join(array_map('ucfirst', explode($separator, $input)));
1789
+
1790
+		// TODO >= PHP5.4.32
1791
+		//return str_replace($separator, '', ucwords($input, $separator));
1792
+	}
1793 1793
 }
Please login to merge, or discard this patch.
Spacing   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -383,8 +383,8 @@  discard block
 block discarded – undo
383 383
             }
384 384
 
385 385
             if ($doCache === true) {
386
-                $out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*' . $dynamicId . '*/ echo \'$1\'; ?>', $out);
387
-                if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS . 'PluginDynamic')) {
386
+                $out = preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php /*'.$dynamicId.'*/ echo \'$1\'; ?>', $out);
387
+                if (!class_exists(self::NAMESPACE_PLUGINS_BLOCKS.'PluginDynamic')) {
388 388
                     $this->getLoader()->loadPlugin('PluginDynamic');
389 389
                 }
390 390
                 $out = PluginDynamic::unescape($out, $dynamicId, $compiledTemplate);
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
     public function addFilter($callback, $autoload = false)
586 586
     {
587 587
         if ($autoload) {
588
-            $class = self::NAMESPACE_PLUGINS_FILTERS . self::toCamelCase($callback);
588
+            $class = self::NAMESPACE_PLUGINS_FILTERS.self::toCamelCase($callback);
589 589
             if (!class_exists($class) && !function_exists($class)) {
590 590
                 try {
591 591
                     $this->getLoader()->loadPlugin($callback);
@@ -593,12 +593,12 @@  discard block
 block discarded – undo
593 593
                 catch (Exception $e) {
594 594
                     if (strstr($callback, self::NAMESPACE_PLUGINS_FILTERS)) {
595 595
                         throw new Exception(
596
-                            'Wrong filter name : ' . $callback . ', the "Dwoo_Filter_" prefix should 
597
-                        not be used, please only use "' . str_replace('Dwoo_Filter_', '', $callback) . '"'
596
+                            'Wrong filter name : '.$callback.', the "Dwoo_Filter_" prefix should 
597
+                        not be used, please only use "' . str_replace('Dwoo_Filter_', '', $callback).'"'
598 598
                         );
599 599
                     } else {
600 600
                         throw new Exception(
601
-                            'Wrong filter name : ' . $callback . ', when using autoload the filter must
601
+                            'Wrong filter name : '.$callback.', when using autoload the filter must
602 602
                          be in one of your plugin dir as "name.php" containig a class or function named
603 603
                          "Dwoo_Filter_name"'
604 604
                         );
@@ -612,7 +612,7 @@  discard block
 block discarded – undo
612 612
                 $callback = $class;
613 613
             } else {
614 614
                 throw new Exception(
615
-                    'Wrong filter name : ' . $callback . ', when using autoload the filter must be in
615
+                    'Wrong filter name : '.$callback.', when using autoload the filter must be in
616 616
                 one of your plugin dir as "name.php" containig a class or function named "Dwoo_Filter_name"'
617 617
                 );
618 618
             }
@@ -632,14 +632,14 @@  discard block
 block discarded – undo
632 632
      */
633 633
     public function removeFilter($callback)
634 634
     {
635
-        if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS. 'Filter' . self::toCamelCase($callback), $this->filters,
635
+        if (($index = array_search(self::NAMESPACE_PLUGINS_FILTERS.'Filter'.self::toCamelCase($callback), $this->filters,
636 636
                 true)) !==
637 637
             false) {
638 638
             unset($this->filters[$index]);
639 639
         } elseif (($index = array_search($callback, $this->filters, true)) !== false) {
640 640
             unset($this->filters[$index]);
641 641
         } else {
642
-            $class = self::NAMESPACE_PLUGINS_FILTERS . 'Filter' . $callback;
642
+            $class = self::NAMESPACE_PLUGINS_FILTERS.'Filter'.$callback;
643 643
             foreach ($this->filters as $index => $filter) {
644 644
                 if (is_array($filter) && $filter[0] instanceof $class) {
645 645
                     unset($this->filters[$index]);
@@ -762,7 +762,7 @@  discard block
 block discarded – undo
762 762
     public function getCacheDir()
763 763
     {
764 764
         if ($this->cacheDir === null) {
765
-            $this->setCacheDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR);
765
+            $this->setCacheDir(dirname(__DIR__).DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR);
766 766
         }
767 767
 
768 768
         return $this->cacheDir;
@@ -778,9 +778,9 @@  discard block
 block discarded – undo
778 778
      */
779 779
     public function setCacheDir($dir)
780 780
     {
781
-        $this->cacheDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
781
+        $this->cacheDir = rtrim($dir, '/\\').DIRECTORY_SEPARATOR;
782 782
         if (is_writable($this->cacheDir) === false) {
783
-            throw new Exception('The cache directory must be writable, chmod "' . $this->cacheDir . '" to make it writable');
783
+            throw new Exception('The cache directory must be writable, chmod "'.$this->cacheDir.'" to make it writable');
784 784
         }
785 785
     }
786 786
 
@@ -792,7 +792,7 @@  discard block
 block discarded – undo
792 792
     public function getCompileDir()
793 793
     {
794 794
         if ($this->compileDir === null) {
795
-            $this->setCompileDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'compiled' . DIRECTORY_SEPARATOR);
795
+            $this->setCompileDir(dirname(__DIR__).DIRECTORY_SEPARATOR.'compiled'.DIRECTORY_SEPARATOR);
796 796
         }
797 797
 
798 798
         return $this->compileDir;
@@ -808,9 +808,9 @@  discard block
 block discarded – undo
808 808
      */
809 809
     public function setCompileDir($dir)
810 810
     {
811
-        $this->compileDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
811
+        $this->compileDir = rtrim($dir, '/\\').DIRECTORY_SEPARATOR;
812 812
         if (is_writable($this->compileDir) === false) {
813
-            throw new Exception('The compile directory must be writable, chmod "' . $this->compileDir . '" to make it writable');
813
+            throw new Exception('The compile directory must be writable, chmod "'.$this->compileDir.'" to make it writable');
814 814
         }
815 815
     }
816 816
 
@@ -834,9 +834,9 @@  discard block
 block discarded – undo
834 834
      */
835 835
     public function setTemplateDir($dir)
836 836
     {
837
-        $tmpDir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
837
+        $tmpDir = rtrim($dir, '/\\').DIRECTORY_SEPARATOR;
838 838
         if (is_dir($tmpDir) === false) {
839
-            throw new Exception('The template directory: "' . $tmpDir . '" does not exists, create the directory or specify an other location !');
839
+            throw new Exception('The template directory: "'.$tmpDir.'" does not exists, create the directory or specify an other location !');
840 840
         }
841 841
         $this->templateDir[] = $tmpDir;
842 842
     }
@@ -860,7 +860,7 @@  discard block
 block discarded – undo
860 860
      */
861 861
     public function setCacheTime($seconds)
862 862
     {
863
-        $this->cacheTime = (int)$seconds;
863
+        $this->cacheTime = (int) $seconds;
864 864
     }
865 865
 
866 866
     /**
@@ -884,7 +884,7 @@  discard block
 block discarded – undo
884 884
      */
885 885
     public function setCharset($charset)
886 886
     {
887
-        $this->charset = strtolower((string)$charset);
887
+        $this->charset = strtolower((string) $charset);
888 888
     }
889 889
 
890 890
     /**
@@ -1021,11 +1021,11 @@  discard block
 block discarded – undo
1021 1021
     public function clearCache($olderThan = - 1)
1022 1022
     {
1023 1023
         $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->getCacheDir()), \RecursiveIteratorIterator::SELF_FIRST);
1024
-        $expired  = time() - $olderThan;
1024
+        $expired  = time()-$olderThan;
1025 1025
         $count    = 0;
1026 1026
         foreach ($iterator as $file) {
1027 1027
             if ($file->isFile() && $file->getCTime() < $expired) {
1028
-                $count += unlink((string)$file) ? 1 : 0;
1028
+                $count += unlink((string) $file) ? 1 : 0;
1029 1029
             }
1030 1030
         }
1031 1031
 
@@ -1058,7 +1058,7 @@  discard block
 block discarded – undo
1058 1058
             return $class::templateFactory($this, $resourceId, $cacheTime, $cacheId, $compileId, $parentTemplate);
1059 1059
         }
1060 1060
 
1061
-        throw new Exception('Unknown resource type : ' . $resourceName);
1061
+        throw new Exception('Unknown resource type : '.$resourceName);
1062 1062
     }
1063 1063
 
1064 1064
     /**
@@ -1158,7 +1158,7 @@  discard block
 block discarded – undo
1158 1158
         if (!($tplIdentifier = $this->template->getResourceIdentifier())) {
1159 1159
             $tplIdentifier = $this->template->getResourceName();
1160 1160
         }
1161
-        trigger_error('Dwoo error (in ' . $tplIdentifier . ') : ' . $message, $level);
1161
+        trigger_error('Dwoo error (in '.$tplIdentifier.') : '.$message, $level);
1162 1162
     }
1163 1163
 
1164 1164
     /**
@@ -1174,7 +1174,7 @@  discard block
 block discarded – undo
1174 1174
         if (isset($this->plugins[$blockName])) {
1175 1175
             $class = $this->plugins[$blockName]['class'];
1176 1176
         } else {
1177
-            $class = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin' . self::toCamelCase($blockName);
1177
+            $class = self::NAMESPACE_PLUGINS_BLOCKS.'Plugin'.self::toCamelCase($blockName);
1178 1178
         }
1179 1179
 
1180 1180
         if ($this->curBlock !== null) {
@@ -1237,7 +1237,7 @@  discard block
 block discarded – undo
1237 1237
     {
1238 1238
         $index = array_search($block, $this->stack, true);
1239 1239
         if ($index !== false && $index > 0) {
1240
-            return $this->stack[$index - 1];
1240
+            return $this->stack[$index-1];
1241 1241
         }
1242 1242
 
1243 1243
         return false;
@@ -1255,7 +1255,7 @@  discard block
 block discarded – undo
1255 1255
         if (isset($this->plugins[$type])) {
1256 1256
             $type = $this->plugins[$type]['class'];
1257 1257
         } else {
1258
-            $type = self::NAMESPACE_PLUGINS_BLOCKS . 'Plugin_' . str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin',
1258
+            $type = self::NAMESPACE_PLUGINS_BLOCKS.'Plugin_'.str_replace(self::NAMESPACE_PLUGINS_BLOCKS.'Plugin',
1259 1259
                     '', $type);
1260 1260
         }
1261 1261
 
@@ -1333,7 +1333,7 @@  discard block
 block discarded – undo
1333 1333
 
1334 1334
                 if (is_string($callback) === false) {
1335 1335
                     while (($i = array_shift($keys)) !== null) {
1336
-                        $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params);
1336
+                        $out[] = call_user_func_array($callback, array(1 => $items[$i])+$params);
1337 1337
                     }
1338 1338
                 } elseif ($cnt === 1) {
1339 1339
                     while (($i = array_shift($keys)) !== null) {
@@ -1349,7 +1349,7 @@  discard block
 block discarded – undo
1349 1349
                     }
1350 1350
                 } else {
1351 1351
                     while (($i = array_shift($keys)) !== null) {
1352
-                        $out[] = call_user_func_array($callback, array(1 => $items[$i]) + $params);
1352
+                        $out[] = call_user_func_array($callback, array(1 => $items[$i])+$params);
1353 1353
                     }
1354 1354
                 }
1355 1355
             } else {
@@ -1358,7 +1358,7 @@  discard block
 block discarded – undo
1358 1358
 
1359 1359
                 if (is_string($callback) === false) {
1360 1360
                     while (($i = array_shift($keys)) !== null) {
1361
-                        $out[] = call_user_func_array($callback, array($items[$i]) + $params);
1361
+                        $out[] = call_user_func_array($callback, array($items[$i])+$params);
1362 1362
                     }
1363 1363
                 } elseif ($cnt === 1) {
1364 1364
                     while (($i = array_shift($keys)) !== null) {
@@ -1378,7 +1378,7 @@  discard block
 block discarded – undo
1378 1378
                     }
1379 1379
                 } else {
1380 1380
                     while (($i = array_shift($keys)) !== null) {
1381
-                        $out[] = call_user_func_array($callback, array($items[$i]) + $params);
1381
+                        $out[] = call_user_func_array($callback, array($items[$i])+$params);
1382 1382
                     }
1383 1383
                 }
1384 1384
             }
@@ -1448,7 +1448,7 @@  discard block
 block discarded – undo
1448 1448
         $tree = $this->scopeTree;
1449 1449
         $cur  = $this->data;
1450 1450
 
1451
-        while ($parentLevels -- !== 0) {
1451
+        while ($parentLevels-- !== 0) {
1452 1452
             array_pop($tree);
1453 1453
         }
1454 1454
 
@@ -1486,7 +1486,7 @@  discard block
 block discarded – undo
1486 1486
                 } elseif ($varstr === '__' || $varstr === '_root') {
1487 1487
                     return $this->data;
1488 1488
                 } elseif ($varstr === '_' || $varstr === '_parent') {
1489
-                    $varstr = '.' . $varstr;
1489
+                    $varstr = '.'.$varstr;
1490 1490
                     $tree   = $this->scopeTree;
1491 1491
                     $cur    = $this->data;
1492 1492
                     array_pop($tree);
@@ -1512,7 +1512,7 @@  discard block
 block discarded – undo
1512 1512
             }
1513 1513
 
1514 1514
             if (substr($varstr, 0, 1) === '.') {
1515
-                $varstr = 'dwoo' . $varstr;
1515
+                $varstr = 'dwoo'.$varstr;
1516 1516
             }
1517 1517
 
1518 1518
             preg_match_all('#(\[|->|\.)?((?:[^.[\]-]|-(?!>))+)\]?#i', $varstr, $m);
@@ -1619,7 +1619,7 @@  discard block
 block discarded – undo
1619 1619
     public function assignInScope($value, $scope)
1620 1620
     {
1621 1621
         if (!is_string($scope)) {
1622
-            $this->triggerError('Assignments must be done into strings, (' . gettype($scope) . ') ' . var_export($scope, true) . ' given', E_USER_ERROR);
1622
+            $this->triggerError('Assignments must be done into strings, ('.gettype($scope).') '.var_export($scope, true).' given', E_USER_ERROR);
1623 1623
         }
1624 1624
         if (strstr($scope, '.') === false && strstr($scope, '->') === false) {
1625 1625
             $this->scope[$scope] = $value;
@@ -1770,7 +1770,7 @@  discard block
 block discarded – undo
1770 1770
     {
1771 1771
         $proxy = $this->getPluginProxy();
1772 1772
         if (!$proxy) {
1773
-            throw new Exception('Call to undefined method ' . __CLASS__ . '::' . $method . '()');
1773
+            throw new Exception('Call to undefined method '.__CLASS__.'::'.$method.'()');
1774 1774
         }
1775 1775
 
1776 1776
         return call_user_func_array($proxy->getCallback($method), $args);
Please login to merge, or discard this patch.
lib/Dwoo/Filter.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -23,30 +23,30 @@
 block discarded – undo
23 23
  */
24 24
 abstract class Filter
25 25
 {
26
-    /**
27
-     * The dwoo instance that runs this filter.
28
-     *
29
-     * @var Core
30
-     */
31
-    protected $dwoo;
26
+	/**
27
+	 * The dwoo instance that runs this filter.
28
+	 *
29
+	 * @var Core
30
+	 */
31
+	protected $dwoo;
32 32
 
33
-    /**
34
-     * Constructor, if you override it, call parent::__construct($dwoo); or assign
35
-     * the dwoo instance yourself if you need it.
36
-     *
37
-     * @param Core $dwoo the dwoo instance that runs this plugin
38
-     */
39
-    public function __construct(Core $dwoo)
40
-    {
41
-        $this->dwoo = $dwoo;
42
-    }
33
+	/**
34
+	 * Constructor, if you override it, call parent::__construct($dwoo); or assign
35
+	 * the dwoo instance yourself if you need it.
36
+	 *
37
+	 * @param Core $dwoo the dwoo instance that runs this plugin
38
+	 */
39
+	public function __construct(Core $dwoo)
40
+	{
41
+		$this->dwoo = $dwoo;
42
+	}
43 43
 
44
-    /**
45
-     * Processes the input and returns it filtered.
46
-     *
47
-     * @param string $input the template to process
48
-     *
49
-     * @return string
50
-     */
51
-    abstract public function process($input);
44
+	/**
45
+	 * Processes the input and returns it filtered.
46
+	 *
47
+	 * @param string $input the template to process
48
+	 *
49
+	 * @return string
50
+	 */
51
+	abstract public function process($input);
52 52
 }
Please login to merge, or discard this patch.
lib/Dwoo/ILoader.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -23,15 +23,15 @@
 block discarded – undo
23 23
  */
24 24
 interface ILoader
25 25
 {
26
-    /**
27
-     * Loads a plugin file.
28
-     * the second parameter is used to avoid permanent rehashing when using php functions,
29
-     * however this means that if you have add a plugin that overrides a php function you have
30
-     * to delete the classpath.cache file(s) by hand to force a rehash of the plugins
31
-     *
32
-     * @param string $class       the plugin name, without the `Plugin` prefix
33
-     * @param bool   $forceRehash if true, the class path caches will be rebuilt if the plugin is not found, in case it
34
-     *                            has just been added, defaults to true
35
-     */
36
-    public function loadPlugin($class, $forceRehash = true);
26
+	/**
27
+	 * Loads a plugin file.
28
+	 * the second parameter is used to avoid permanent rehashing when using php functions,
29
+	 * however this means that if you have add a plugin that overrides a php function you have
30
+	 * to delete the classpath.cache file(s) by hand to force a rehash of the plugins
31
+	 *
32
+	 * @param string $class       the plugin name, without the `Plugin` prefix
33
+	 * @param bool   $forceRehash if true, the class path caches will be rebuilt if the plugin is not found, in case it
34
+	 *                            has just been added, defaults to true
35
+	 */
36
+	public function loadPlugin($class, $forceRehash = true);
37 37
 }
Please login to merge, or discard this patch.
lib/Dwoo/ICompilable.php 1 patch
Indentation   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -26,6 +26,6 @@
 block discarded – undo
26 26
  */
27 27
 interface ICompilable
28 28
 {
29
-    // this replaces the process function
30
-    //public static function compile(Compiler $compiler, $arg, $arg, ...);
29
+	// this replaces the process function
30
+	//public static function compile(Compiler $compiler, $arg, $arg, ...);
31 31
 }
Please login to merge, or discard this patch.
lib/Dwoo/Adapters/CakePHP/dwoo.php 1 patch
Indentation   +113 added lines, -113 removed lines patch added patch discarded remove patch
@@ -42,118 +42,118 @@
 block discarded – undo
42 42
  */
43 43
 class DwooView extends View
44 44
 {
45
-    protected $_sv_template_dir;
46
-    protected $_sv_layout_dir;
47
-    protected $_sv_compile_dir;
48
-    protected $_sv_cache_dir;
49
-    protected $_sv_compile_id;
50
-
51
-    protected $_dwoo;
52
-
53
-    public $sv_processedTpl;
45
+	protected $_sv_template_dir;
46
+	protected $_sv_layout_dir;
47
+	protected $_sv_compile_dir;
48
+	protected $_sv_cache_dir;
49
+	protected $_sv_compile_id;
50
+
51
+	protected $_dwoo;
52
+
53
+	public $sv_processedTpl;
54 54
 
55
-    public function __construct(&$controller)
56
-    {
57
-        parent::__construct($controller);
58
-
59
-        $this->ext = '.tpl';
60
-
61
-        $this->_sv_template_dir = array(
62
-            VIEWS.$this->viewPath.DS.$this->subDir,
63
-            VIEWS.$this->viewPath,
64
-            VIEWS,
65
-        );
66
-
67
-        $this->_sv_layout_dir = array(
68
-            LAYOUTS.$this->subDir,
69
-            VIEWS,
70
-        );
71
-
72
-        $this->_sv_compile_dir = TMP.'dwoo'.DS.'compile';
73
-        $this->_sv_cache_dir = TMP.'dwoo'.DS.'cache';
74
-
75
-        $this->_dwoo = new Dwoo_Core($this->_sv_compile_dir, $this->_sv_cache_dir);
76
-
77
-        $this->_sv_compile_id = $controller->name;
78
-
79
-        $this->_dwoo->sv_this = $this;
80
-        $this->_dwoo->setSecurityPolicy();
81
-
82
-        return;
83
-    }
84
-
85
-    /**
86
-     * changes the template directory.
87
-     */
88
-    public function setTemplateDir($path = VIEW)
89
-    {
90
-        $old = $this->_sv_template_dir;
91
-        $this->_sv_template_dir = $path;
92
-
93
-        return $old;
94
-    }
95
-
96
-    public function getTemplateDir()
97
-    {
98
-        return $this->_sv_template_dir;
99
-    }
100
-
101
-    public function _render($___viewFn, $___data_for_view, $___play_safe = true, $loadHelpers = true)
102
-    {
103
-        // let's determine if this is a layout call or a template call
104
-        // and change the template dir accordingly
105
-        $layout = false;
106
-        if (isset($___data_for_view['content_for_layout'])) {
107
-            $this->_sv_template_dir = $this->_sv_layout_dir;
108
-            $layout = true;
109
-        }
110
-
111
-        $tpl = new Dwoo_Template_File($___viewFn);
112
-        $data = $___data_for_view;
113
-
114
-        $data['view'] = $this;
115
-
116
-        if ($this->helpers != false && $loadHelpers === true) {
117
-            $loadedHelpers = array();
118
-            $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
119
-
120
-            foreach (array_keys($loadedHelpers) as $helper) {
121
-                $camelBackedHelper = strtolower(substr($helper, 0, 1)).substr($helper, 1);
122
-
123
-                ${$camelBackedHelper} = $loadedHelpers[$helper];
124
-
125
-                if (is_array(${$camelBackedHelper}->helpers) && !empty(${$camelBackedHelper}->helpers)) {
126
-                    $subHelpers = ${$camelBackedHelper}->helpers;
127
-                    foreach ($subHelpers as $subHelper) {
128
-                        ${$camelBackedHelper}->{$subHelper} = $loadedHelpers[$subHelper];
129
-                    }
130
-                }
131
-
132
-                if (isset($this->passedArgs)) {
133
-                    ${$camelBackedHelper}->passedArgs = $this->passedArgs;
134
-                }
135
-
136
-                $this->loaded[$camelBackedHelper] = ${$camelBackedHelper};
137
-
138
-                $data[$camelBackedHelper] = ${$camelBackedHelper};
139
-            }
140
-        }
141
-
142
-        if ($this->helpers != false && $loadHelpers === true) {
143
-            foreach ($loadedHelpers as $helper) {
144
-                if (is_object($helper)) {
145
-                    if (is_subclass_of($helper, 'Helper') || is_subclass_of($helper, 'helper')) {
146
-                        $helper->beforeRender();
147
-                    }
148
-                }
149
-            }
150
-        }
151
-
152
-        return $this->_dwoo->get($tpl, $data);
153
-    }
154
-
155
-    public function get()
156
-    {
157
-        return $this->_dwoo;
158
-    }
55
+	public function __construct(&$controller)
56
+	{
57
+		parent::__construct($controller);
58
+
59
+		$this->ext = '.tpl';
60
+
61
+		$this->_sv_template_dir = array(
62
+			VIEWS.$this->viewPath.DS.$this->subDir,
63
+			VIEWS.$this->viewPath,
64
+			VIEWS,
65
+		);
66
+
67
+		$this->_sv_layout_dir = array(
68
+			LAYOUTS.$this->subDir,
69
+			VIEWS,
70
+		);
71
+
72
+		$this->_sv_compile_dir = TMP.'dwoo'.DS.'compile';
73
+		$this->_sv_cache_dir = TMP.'dwoo'.DS.'cache';
74
+
75
+		$this->_dwoo = new Dwoo_Core($this->_sv_compile_dir, $this->_sv_cache_dir);
76
+
77
+		$this->_sv_compile_id = $controller->name;
78
+
79
+		$this->_dwoo->sv_this = $this;
80
+		$this->_dwoo->setSecurityPolicy();
81
+
82
+		return;
83
+	}
84
+
85
+	/**
86
+	 * changes the template directory.
87
+	 */
88
+	public function setTemplateDir($path = VIEW)
89
+	{
90
+		$old = $this->_sv_template_dir;
91
+		$this->_sv_template_dir = $path;
92
+
93
+		return $old;
94
+	}
95
+
96
+	public function getTemplateDir()
97
+	{
98
+		return $this->_sv_template_dir;
99
+	}
100
+
101
+	public function _render($___viewFn, $___data_for_view, $___play_safe = true, $loadHelpers = true)
102
+	{
103
+		// let's determine if this is a layout call or a template call
104
+		// and change the template dir accordingly
105
+		$layout = false;
106
+		if (isset($___data_for_view['content_for_layout'])) {
107
+			$this->_sv_template_dir = $this->_sv_layout_dir;
108
+			$layout = true;
109
+		}
110
+
111
+		$tpl = new Dwoo_Template_File($___viewFn);
112
+		$data = $___data_for_view;
113
+
114
+		$data['view'] = $this;
115
+
116
+		if ($this->helpers != false && $loadHelpers === true) {
117
+			$loadedHelpers = array();
118
+			$loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
119
+
120
+			foreach (array_keys($loadedHelpers) as $helper) {
121
+				$camelBackedHelper = strtolower(substr($helper, 0, 1)).substr($helper, 1);
122
+
123
+				${$camelBackedHelper} = $loadedHelpers[$helper];
124
+
125
+				if (is_array(${$camelBackedHelper}->helpers) && !empty(${$camelBackedHelper}->helpers)) {
126
+					$subHelpers = ${$camelBackedHelper}->helpers;
127
+					foreach ($subHelpers as $subHelper) {
128
+						${$camelBackedHelper}->{$subHelper} = $loadedHelpers[$subHelper];
129
+					}
130
+				}
131
+
132
+				if (isset($this->passedArgs)) {
133
+					${$camelBackedHelper}->passedArgs = $this->passedArgs;
134
+				}
135
+
136
+				$this->loaded[$camelBackedHelper] = ${$camelBackedHelper};
137
+
138
+				$data[$camelBackedHelper] = ${$camelBackedHelper};
139
+			}
140
+		}
141
+
142
+		if ($this->helpers != false && $loadHelpers === true) {
143
+			foreach ($loadedHelpers as $helper) {
144
+				if (is_object($helper)) {
145
+					if (is_subclass_of($helper, 'Helper') || is_subclass_of($helper, 'helper')) {
146
+						$helper->beforeRender();
147
+					}
148
+				}
149
+			}
150
+		}
151
+
152
+		return $this->_dwoo->get($tpl, $data);
153
+	}
154
+
155
+	public function get()
156
+	{
157
+		return $this->_dwoo;
158
+	}
159 159
 }
Please login to merge, or discard this patch.
lib/Dwoo/Adapters/Agavi/DwooRenderer.php 1 patch
Indentation   +153 added lines, -153 removed lines patch added patch discarded remove patch
@@ -16,157 +16,157 @@
 block discarded – undo
16 16
  */
17 17
 class DwooRenderer extends AgaviRenderer implements AgaviIReusableRenderer
18 18
 {
19
-    /**
20
-     * @constant   string The directory inside the cache dir where templates will
21
-     *                    be stored in compiled form.
22
-     */
23
-    const COMPILE_DIR = 'templates';
24
-
25
-    /**
26
-     * @constant   string The subdirectory inside the compile dir where templates
27
-     *                    will be stored in compiled form.
28
-     */
29
-    const COMPILE_SUBDIR = 'dwoo';
30
-
31
-    /**
32
-     * @constant   string The directory inside the cache dir where cached content
33
-     *                    will be stored.
34
-     */
35
-    const CACHE_DIR = 'dwoo';
36
-
37
-    /**
38
-     * @var Dwoo Dwoo template engine
39
-     */
40
-    protected $dwoo = null;
41
-
42
-    /**
43
-     * @var string A string with the default template file extension,
44
-     *             including the dot
45
-     */
46
-    protected $defaultExtension = '.html';
47
-
48
-    /**
49
-     * stores the (optional) plugin directories to add to the Dwoo_Loader.
50
-     */
51
-    protected $plugin_dir = null;
52
-
53
-    /**
54
-     * Pre-serialization callback.
55
-     *
56
-     * Excludes the Dwoo instance to prevent excessive serialization load.
57
-     */
58
-    public function __sleep()
59
-    {
60
-        $keys = parent::__sleep();
61
-        unset($keys[array_search('dwoo', $keys)]);
62
-
63
-        return $keys;
64
-    }
65
-
66
-    /**
67
-     * Initialize this Renderer.
68
-     *
69
-     * @param AgaviContext The current application context
70
-     * @param array        An associative array of initialization parameters
71
-     */
72
-    public function initialize(AgaviContext $context, array $parameters = array())
73
-    {
74
-        parent::initialize($context, $parameters);
75
-
76
-        $this->plugin_dir = $this->getParameter('plugin_dir', $this->plugin_dir);
77
-    }
78
-
79
-    /**
80
-     * provides a custom compiler to the dwoo renderer with optional settings
81
-     * you can set in the agavi output_types.xml config file.
82
-     *
83
-     * @return Dwoo_Compiler
84
-     */
85
-    public function compilerFactory()
86
-    {
87
-        $compiler = Dwoo_Compiler::compilerFactory();
88
-        $compiler->setAutoEscape((bool) $this->getParameter('auto_escape', false));
89
-
90
-        return $compiler;
91
-    }
92
-
93
-    /**
94
-     * Grab a cleaned up dwoo instance.
95
-     *
96
-     * @return Dwoo A Dwoo instance
97
-     */
98
-    protected function getEngine()
99
-    {
100
-        if ($this->dwoo) {
101
-            return $this->dwoo;
102
-        }
103
-
104
-        // this triggers Agavi autoload
105
-        if (!class_exists('Dwoo')) {
106
-            if (file_exists(dirname(__FILE__).'/../../../dwooAutoload.php')) {
107
-                // file was dropped with the entire dwoo package
108
-                include dirname(__FILE__).'/../../../dwooAutoload.php';
109
-            } else {
110
-                // assume the dwoo package is in the include path
111
-                include 'dwooAutoload.php';
112
-            }
113
-        }
114
-
115
-        $parentMode = fileperms(AgaviConfig::get('core.cache_dir'));
116
-
117
-        $compileDir = AgaviConfig::get('core.cache_dir').DIRECTORY_SEPARATOR.self::COMPILE_DIR.DIRECTORY_SEPARATOR.self::COMPILE_SUBDIR;
118
-        AgaviToolkit::mkdir($compileDir, $parentMode, true);
119
-
120
-        $cacheDir = AgaviConfig::get('core.cache_dir').DIRECTORY_SEPARATOR.self::CACHE_DIR;
121
-        AgaviToolkit::mkdir($cacheDir, $parentMode, true);
122
-
123
-        $this->dwoo = new Dwoo_Core($compileDir, $cacheDir);
124
-
125
-        if (!empty($this->plugin_dir)) {
126
-            foreach ((array) $this->plugin_dir as $dir) {
127
-                $this->dwoo->getLoader()->addDirectory($dir);
128
-            }
129
-        }
130
-
131
-        $this->dwoo->setDefaultCompilerFactory('file', array($this, 'compilerFactory'));
132
-
133
-        return $this->dwoo;
134
-    }
135
-
136
-    /**
137
-     * Render the presentation and return the result.
138
-     *
139
-     * @param AgaviTemplateLayer The template layer to render
140
-     * @param array              The template variables
141
-     * @param array              The slots
142
-     * @param array              Associative array of additional assigns
143
-     *
144
-     * @return string A rendered result
145
-     */
146
-    public function render(AgaviTemplateLayer $layer, array &$attributes = array(), array &$slots = array(), array &$moreAssigns = array())
147
-    {
148
-        $engine = $this->getEngine();
149
-
150
-        $data = array();
151
-        if ($this->extractVars) {
152
-            $data = $attributes;
153
-        } else {
154
-            $data[$this->varName] = &$attributes;
155
-        }
156
-
157
-        $data[$this->slotsVarName] = &$slots;
158
-
159
-        foreach ($this->assigns as $key => $getter) {
160
-            $data[$key] = $this->getContext()->$getter();
161
-        }
162
-
163
-        foreach ($moreAssigns as $key => &$value) {
164
-            if (isset($this->moreAssignNames[$key])) {
165
-                $key = $this->moreAssignNames[$key];
166
-            }
167
-            $data[$key] = &$value;
168
-        }
169
-
170
-        return $engine->get($layer->getResourceStreamIdentifier(), $data);
171
-    }
19
+	/**
20
+	 * @constant   string The directory inside the cache dir where templates will
21
+	 *                    be stored in compiled form.
22
+	 */
23
+	const COMPILE_DIR = 'templates';
24
+
25
+	/**
26
+	 * @constant   string The subdirectory inside the compile dir where templates
27
+	 *                    will be stored in compiled form.
28
+	 */
29
+	const COMPILE_SUBDIR = 'dwoo';
30
+
31
+	/**
32
+	 * @constant   string The directory inside the cache dir where cached content
33
+	 *                    will be stored.
34
+	 */
35
+	const CACHE_DIR = 'dwoo';
36
+
37
+	/**
38
+	 * @var Dwoo Dwoo template engine
39
+	 */
40
+	protected $dwoo = null;
41
+
42
+	/**
43
+	 * @var string A string with the default template file extension,
44
+	 *             including the dot
45
+	 */
46
+	protected $defaultExtension = '.html';
47
+
48
+	/**
49
+	 * stores the (optional) plugin directories to add to the Dwoo_Loader.
50
+	 */
51
+	protected $plugin_dir = null;
52
+
53
+	/**
54
+	 * Pre-serialization callback.
55
+	 *
56
+	 * Excludes the Dwoo instance to prevent excessive serialization load.
57
+	 */
58
+	public function __sleep()
59
+	{
60
+		$keys = parent::__sleep();
61
+		unset($keys[array_search('dwoo', $keys)]);
62
+
63
+		return $keys;
64
+	}
65
+
66
+	/**
67
+	 * Initialize this Renderer.
68
+	 *
69
+	 * @param AgaviContext The current application context
70
+	 * @param array        An associative array of initialization parameters
71
+	 */
72
+	public function initialize(AgaviContext $context, array $parameters = array())
73
+	{
74
+		parent::initialize($context, $parameters);
75
+
76
+		$this->plugin_dir = $this->getParameter('plugin_dir', $this->plugin_dir);
77
+	}
78
+
79
+	/**
80
+	 * provides a custom compiler to the dwoo renderer with optional settings
81
+	 * you can set in the agavi output_types.xml config file.
82
+	 *
83
+	 * @return Dwoo_Compiler
84
+	 */
85
+	public function compilerFactory()
86
+	{
87
+		$compiler = Dwoo_Compiler::compilerFactory();
88
+		$compiler->setAutoEscape((bool) $this->getParameter('auto_escape', false));
89
+
90
+		return $compiler;
91
+	}
92
+
93
+	/**
94
+	 * Grab a cleaned up dwoo instance.
95
+	 *
96
+	 * @return Dwoo A Dwoo instance
97
+	 */
98
+	protected function getEngine()
99
+	{
100
+		if ($this->dwoo) {
101
+			return $this->dwoo;
102
+		}
103
+
104
+		// this triggers Agavi autoload
105
+		if (!class_exists('Dwoo')) {
106
+			if (file_exists(dirname(__FILE__).'/../../../dwooAutoload.php')) {
107
+				// file was dropped with the entire dwoo package
108
+				include dirname(__FILE__).'/../../../dwooAutoload.php';
109
+			} else {
110
+				// assume the dwoo package is in the include path
111
+				include 'dwooAutoload.php';
112
+			}
113
+		}
114
+
115
+		$parentMode = fileperms(AgaviConfig::get('core.cache_dir'));
116
+
117
+		$compileDir = AgaviConfig::get('core.cache_dir').DIRECTORY_SEPARATOR.self::COMPILE_DIR.DIRECTORY_SEPARATOR.self::COMPILE_SUBDIR;
118
+		AgaviToolkit::mkdir($compileDir, $parentMode, true);
119
+
120
+		$cacheDir = AgaviConfig::get('core.cache_dir').DIRECTORY_SEPARATOR.self::CACHE_DIR;
121
+		AgaviToolkit::mkdir($cacheDir, $parentMode, true);
122
+
123
+		$this->dwoo = new Dwoo_Core($compileDir, $cacheDir);
124
+
125
+		if (!empty($this->plugin_dir)) {
126
+			foreach ((array) $this->plugin_dir as $dir) {
127
+				$this->dwoo->getLoader()->addDirectory($dir);
128
+			}
129
+		}
130
+
131
+		$this->dwoo->setDefaultCompilerFactory('file', array($this, 'compilerFactory'));
132
+
133
+		return $this->dwoo;
134
+	}
135
+
136
+	/**
137
+	 * Render the presentation and return the result.
138
+	 *
139
+	 * @param AgaviTemplateLayer The template layer to render
140
+	 * @param array              The template variables
141
+	 * @param array              The slots
142
+	 * @param array              Associative array of additional assigns
143
+	 *
144
+	 * @return string A rendered result
145
+	 */
146
+	public function render(AgaviTemplateLayer $layer, array &$attributes = array(), array &$slots = array(), array &$moreAssigns = array())
147
+	{
148
+		$engine = $this->getEngine();
149
+
150
+		$data = array();
151
+		if ($this->extractVars) {
152
+			$data = $attributes;
153
+		} else {
154
+			$data[$this->varName] = &$attributes;
155
+		}
156
+
157
+		$data[$this->slotsVarName] = &$slots;
158
+
159
+		foreach ($this->assigns as $key => $getter) {
160
+			$data[$key] = $this->getContext()->$getter();
161
+		}
162
+
163
+		foreach ($moreAssigns as $key => &$value) {
164
+			if (isset($this->moreAssignNames[$key])) {
165
+				$key = $this->moreAssignNames[$key];
166
+			}
167
+			$data[$key] = &$value;
168
+		}
169
+
170
+		return $engine->get($layer->getResourceStreamIdentifier(), $data);
171
+	}
172 172
 }
Please login to merge, or discard this patch.