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