1 | <?php |
---|
2 | /** |
---|
3 | * Smarty Internal Plugin Smarty Template Base |
---|
4 | * |
---|
5 | * This file contains the basic shared methodes for template handling |
---|
6 | * |
---|
7 | * @package Smarty |
---|
8 | * @subpackage Template |
---|
9 | * @author Uwe Tews |
---|
10 | */ |
---|
11 | |
---|
12 | /** |
---|
13 | * Class with shared template methodes |
---|
14 | * |
---|
15 | * @package Smarty |
---|
16 | * @subpackage Template |
---|
17 | */ |
---|
18 | abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data { |
---|
19 | |
---|
20 | /** |
---|
21 | * fetches a rendered Smarty template |
---|
22 | * |
---|
23 | * @param string $template the resource handle of the template file or template object |
---|
24 | * @param mixed $cache_id cache id to be used with this template |
---|
25 | * @param mixed $compile_id compile id to be used with this template |
---|
26 | * @param object $parent next higher level of Smarty variables |
---|
27 | * @param bool $display true: display, false: fetch |
---|
28 | * @param bool $merge_tpl_vars if true parent template variables merged in to local scope |
---|
29 | * @param bool $no_output_filter if true do not run output filter |
---|
30 | * @return string rendered template output |
---|
31 | */ |
---|
32 | public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false) |
---|
33 | { |
---|
34 | if ($template === null && $this instanceof $this->template_class) { |
---|
35 | $template = $this; |
---|
36 | } |
---|
37 | if (!empty($cache_id) && is_object($cache_id)) { |
---|
38 | $parent = $cache_id; |
---|
39 | $cache_id = null; |
---|
40 | } |
---|
41 | if ($parent === null && ($this instanceof Smarty || is_string($template))) { |
---|
42 | $parent = $this; |
---|
43 | } |
---|
44 | // create template object if necessary |
---|
45 | $_template = ($template instanceof $this->template_class) |
---|
46 | ? $template |
---|
47 | : $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false); |
---|
48 | // if called by Smarty object make sure we use current caching status |
---|
49 | if ($this instanceof Smarty) { |
---|
50 | $_template->caching = $this->caching; |
---|
51 | } |
---|
52 | // merge all variable scopes into template |
---|
53 | if ($merge_tpl_vars) { |
---|
54 | // save local variables |
---|
55 | $save_tpl_vars = $_template->tpl_vars; |
---|
56 | $save_config_vars = $_template->config_vars; |
---|
57 | $ptr_array = array($_template); |
---|
58 | $ptr = $_template; |
---|
59 | while (isset($ptr->parent)) { |
---|
60 | $ptr_array[] = $ptr = $ptr->parent; |
---|
61 | } |
---|
62 | $ptr_array = array_reverse($ptr_array); |
---|
63 | $parent_ptr = reset($ptr_array); |
---|
64 | $tpl_vars = $parent_ptr->tpl_vars; |
---|
65 | $config_vars = $parent_ptr->config_vars; |
---|
66 | while ($parent_ptr = next($ptr_array)) { |
---|
67 | if (!empty($parent_ptr->tpl_vars)) { |
---|
68 | $tpl_vars = array_merge($tpl_vars, $parent_ptr->tpl_vars); |
---|
69 | } |
---|
70 | if (!empty($parent_ptr->config_vars)) { |
---|
71 | $config_vars = array_merge($config_vars, $parent_ptr->config_vars); |
---|
72 | } |
---|
73 | } |
---|
74 | if (!empty(Smarty::$global_tpl_vars)) { |
---|
75 | $tpl_vars = array_merge(Smarty::$global_tpl_vars, $tpl_vars); |
---|
76 | } |
---|
77 | $_template->tpl_vars = $tpl_vars; |
---|
78 | $_template->config_vars = $config_vars; |
---|
79 | } |
---|
80 | // dummy local smarty variable |
---|
81 | if (!isset($_template->tpl_vars['smarty'])) { |
---|
82 | $_template->tpl_vars['smarty'] = new Smarty_Variable; |
---|
83 | } |
---|
84 | if (isset($this->smarty->error_reporting)) { |
---|
85 | $_smarty_old_error_level = error_reporting($this->smarty->error_reporting); |
---|
86 | } |
---|
87 | // check URL debugging control |
---|
88 | if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') { |
---|
89 | if (isset($_SERVER['QUERY_STRING'])) { |
---|
90 | $_query_string = $_SERVER['QUERY_STRING']; |
---|
91 | } else { |
---|
92 | $_query_string = ''; |
---|
93 | } |
---|
94 | if (false !== strpos($_query_string, $this->smarty->smarty_debug_id)) { |
---|
95 | if (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=on')) { |
---|
96 | // enable debugging for this browser session |
---|
97 | setcookie('SMARTY_DEBUG', true); |
---|
98 | $this->smarty->debugging = true; |
---|
99 | } elseif (false !== strpos($_query_string, $this->smarty->smarty_debug_id . '=off')) { |
---|
100 | // disable debugging for this browser session |
---|
101 | setcookie('SMARTY_DEBUG', false); |
---|
102 | $this->smarty->debugging = false; |
---|
103 | } else { |
---|
104 | // enable debugging for this page |
---|
105 | $this->smarty->debugging = true; |
---|
106 | } |
---|
107 | } else { |
---|
108 | if (isset($_COOKIE['SMARTY_DEBUG'])) { |
---|
109 | $this->smarty->debugging = true; |
---|
110 | } |
---|
111 | } |
---|
112 | } |
---|
113 | // must reset merge template date |
---|
114 | $_template->smarty->merged_templates_func = array(); |
---|
115 | // get rendered template |
---|
116 | // disable caching for evaluated code |
---|
117 | if ($_template->source->recompiled) { |
---|
118 | $_template->caching = false; |
---|
119 | } |
---|
120 | // checks if template exists |
---|
121 | if (!$_template->source->exists) { |
---|
122 | if ($_template->parent instanceof Smarty_Internal_Template) { |
---|
123 | $parent_resource = " in '{$_template->parent->template_resource}'"; |
---|
124 | } else { |
---|
125 | $parent_resource = ''; |
---|
126 | } |
---|
127 | throw new SmartyException("Unable to load template {$_template->source->type} '{$_template->source->name}'{$parent_resource}"); |
---|
128 | } |
---|
129 | // read from cache or render |
---|
130 | if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || !$_template->cached->valid) { |
---|
131 | // render template (not loaded and not in cache) |
---|
132 | if (!$_template->source->uncompiled) { |
---|
133 | $_smarty_tpl = $_template; |
---|
134 | if ($_template->source->recompiled) { |
---|
135 | if ($this->smarty->debugging) { |
---|
136 | Smarty_Internal_Debug::start_compile($_template); |
---|
137 | } |
---|
138 | $code = $_template->compiler->compileTemplate($_template); |
---|
139 | if ($this->smarty->debugging) { |
---|
140 | Smarty_Internal_Debug::end_compile($_template); |
---|
141 | } |
---|
142 | if ($this->smarty->debugging) { |
---|
143 | Smarty_Internal_Debug::start_render($_template); |
---|
144 | } |
---|
145 | try { |
---|
146 | ob_start(); |
---|
147 | eval("?>" . $code); |
---|
148 | unset($code); |
---|
149 | } catch (Exception $e) { |
---|
150 | ob_get_clean(); |
---|
151 | throw $e; |
---|
152 | } |
---|
153 | } else { |
---|
154 | if (!$_template->compiled->exists || ($_template->smarty->force_compile && !$_template->compiled->isCompiled)) { |
---|
155 | $_template->compileTemplateSource(); |
---|
156 | } |
---|
157 | if ($this->smarty->debugging) { |
---|
158 | Smarty_Internal_Debug::start_render($_template); |
---|
159 | } |
---|
160 | if (!$_template->compiled->loaded) { |
---|
161 | include($_template->compiled->filepath); |
---|
162 | if ($_template->mustCompile) { |
---|
163 | // recompile and load again |
---|
164 | $_template->compileTemplateSource(); |
---|
165 | include($_template->compiled->filepath); |
---|
166 | } |
---|
167 | $_template->compiled->loaded = true; |
---|
168 | } else { |
---|
169 | $_template->decodeProperties($_template->compiled->_properties, false); |
---|
170 | } |
---|
171 | try { |
---|
172 | ob_start(); |
---|
173 | if (empty($_template->properties['unifunc']) || !is_callable($_template->properties['unifunc'])) { |
---|
174 | throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'"); |
---|
175 | } |
---|
176 | array_unshift($_template->_capture_stack,array()); |
---|
177 | // |
---|
178 | // render compiled template |
---|
179 | // |
---|
180 | $_template->properties['unifunc']($_template); |
---|
181 | // any unclosed {capture} tags ? |
---|
182 | if (isset($_template->_capture_stack[0][0])) { |
---|
183 | $_template->capture_error(); |
---|
184 | } |
---|
185 | array_shift($_template->_capture_stack); |
---|
186 | } catch (Exception $e) { |
---|
187 | ob_get_clean(); |
---|
188 | throw $e; |
---|
189 | } |
---|
190 | } |
---|
191 | } else { |
---|
192 | if ($_template->source->uncompiled) { |
---|
193 | if ($this->smarty->debugging) { |
---|
194 | Smarty_Internal_Debug::start_render($_template); |
---|
195 | } |
---|
196 | try { |
---|
197 | ob_start(); |
---|
198 | $_template->source->renderUncompiled($_template); |
---|
199 | } catch (Exception $e) { |
---|
200 | ob_get_clean(); |
---|
201 | throw $e; |
---|
202 | } |
---|
203 | } else { |
---|
204 | throw new SmartyException("Resource '$_template->source->type' must have 'renderUncompiled' method"); |
---|
205 | } |
---|
206 | } |
---|
207 | $_output = ob_get_clean(); |
---|
208 | if (!$_template->source->recompiled && empty($_template->properties['file_dependency'][$_template->source->uid])) { |
---|
209 | $_template->properties['file_dependency'][$_template->source->uid] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type); |
---|
210 | } |
---|
211 | if ($_template->parent instanceof Smarty_Internal_Template) { |
---|
212 | $_template->parent->properties['file_dependency'] = array_merge($_template->parent->properties['file_dependency'], $_template->properties['file_dependency']); |
---|
213 | foreach ($_template->required_plugins as $code => $tmp1) { |
---|
214 | foreach ($tmp1 as $name => $tmp) { |
---|
215 | foreach ($tmp as $type => $data) { |
---|
216 | $_template->parent->required_plugins[$code][$name][$type] = $data; |
---|
217 | } |
---|
218 | } |
---|
219 | } |
---|
220 | } |
---|
221 | if ($this->smarty->debugging) { |
---|
222 | Smarty_Internal_Debug::end_render($_template); |
---|
223 | } |
---|
224 | // write to cache when nessecary |
---|
225 | if (!$_template->source->recompiled && ($_template->caching == Smarty::CACHING_LIFETIME_SAVED || $_template->caching == Smarty::CACHING_LIFETIME_CURRENT)) { |
---|
226 | if ($this->smarty->debugging) { |
---|
227 | Smarty_Internal_Debug::start_cache($_template); |
---|
228 | } |
---|
229 | $_template->properties['has_nocache_code'] = false; |
---|
230 | // get text between non-cached items |
---|
231 | $cache_split = preg_split("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output); |
---|
232 | // get non-cached items |
---|
233 | preg_match_all("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output, $cache_parts); |
---|
234 | $output = ''; |
---|
235 | // loop over items, stitch back together |
---|
236 | foreach ($cache_split as $curr_idx => $curr_split) { |
---|
237 | // escape PHP tags in template content |
---|
238 | $output .= preg_replace('/(<%|%>|<\?php|<\?|\?>)/', '<?php echo \'$1\'; ?>', $curr_split); |
---|
239 | if (isset($cache_parts[0][$curr_idx])) { |
---|
240 | $_template->properties['has_nocache_code'] = true; |
---|
241 | // remove nocache tags from cache output |
---|
242 | $output .= preg_replace("!/\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!", '', $cache_parts[0][$curr_idx]); |
---|
243 | } |
---|
244 | } |
---|
245 | if (!$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { |
---|
246 | $output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template); |
---|
247 | } |
---|
248 | // rendering (must be done before writing cache file because of {function} nocache handling) |
---|
249 | $_smarty_tpl = $_template; |
---|
250 | try { |
---|
251 | ob_start(); |
---|
252 | eval("?>" . $output); |
---|
253 | $_output = ob_get_clean(); |
---|
254 | } catch (Exception $e) { |
---|
255 | ob_get_clean(); |
---|
256 | throw $e; |
---|
257 | } |
---|
258 | // write cache file content |
---|
259 | $_template->writeCachedContent($output); |
---|
260 | if ($this->smarty->debugging) { |
---|
261 | Smarty_Internal_Debug::end_cache($_template); |
---|
262 | } |
---|
263 | } else { |
---|
264 | // var_dump('renderTemplate', $_template->has_nocache_code, $_template->template_resource, $_template->properties['nocache_hash'], $_template->parent->properties['nocache_hash'], $_output); |
---|
265 | if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) { |
---|
266 | // replace nocache_hash |
---|
267 | $_output = preg_replace("/{$_template->properties['nocache_hash']}/", $_template->parent->properties['nocache_hash'], $_output); |
---|
268 | $_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code; |
---|
269 | } |
---|
270 | } |
---|
271 | } else { |
---|
272 | if ($this->smarty->debugging) { |
---|
273 | Smarty_Internal_Debug::start_cache($_template); |
---|
274 | } |
---|
275 | try { |
---|
276 | ob_start(); |
---|
277 | array_unshift($_template->_capture_stack,array()); |
---|
278 | // |
---|
279 | // render cached template |
---|
280 | // |
---|
281 | $_template->properties['unifunc']($_template); |
---|
282 | // any unclosed {capture} tags ? |
---|
283 | if (isset($_template->_capture_stack[0][0])) { |
---|
284 | $_template->capture_error(); |
---|
285 | } |
---|
286 | array_shift($_template->_capture_stack); |
---|
287 | $_output = ob_get_clean(); |
---|
288 | } catch (Exception $e) { |
---|
289 | ob_get_clean(); |
---|
290 | throw $e; |
---|
291 | } |
---|
292 | if ($this->smarty->debugging) { |
---|
293 | Smarty_Internal_Debug::end_cache($_template); |
---|
294 | } |
---|
295 | } |
---|
296 | if ((!$this->caching || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) { |
---|
297 | $_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template); |
---|
298 | } |
---|
299 | if (isset($this->error_reporting)) { |
---|
300 | error_reporting($_smarty_old_error_level); |
---|
301 | } |
---|
302 | // display or fetch |
---|
303 | if ($display) { |
---|
304 | if ($this->caching && $this->cache_modified_check) { |
---|
305 | $_isCached = $_template->isCached() && !$_template->has_nocache_code; |
---|
306 | $_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); |
---|
307 | if ($_isCached && $_template->cached->timestamp <= strtotime($_last_modified_date)) { |
---|
308 | switch (PHP_SAPI) { |
---|
309 | case 'cgi': // php-cgi < 5.3 |
---|
310 | case 'cgi-fcgi': // php-cgi >= 5.3 |
---|
311 | case 'fpm-fcgi': // php-fpm >= 5.3.3 |
---|
312 | header('Status: 304 Not Modified'); |
---|
313 | break; |
---|
314 | |
---|
315 | case 'cli': |
---|
316 | if (/* ^phpunit */!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])/* phpunit$ */) { |
---|
317 | $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; |
---|
318 | } |
---|
319 | break; |
---|
320 | |
---|
321 | default: |
---|
322 | header('HTTP/1.1 304 Not Modified'); |
---|
323 | break; |
---|
324 | } |
---|
325 | } else { |
---|
326 | switch (PHP_SAPI) { |
---|
327 | case 'cli': |
---|
328 | if (/* ^phpunit */!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS'])/* phpunit$ */) { |
---|
329 | $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'; |
---|
330 | } |
---|
331 | break; |
---|
332 | |
---|
333 | default: |
---|
334 | header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT'); |
---|
335 | break; |
---|
336 | } |
---|
337 | echo $_output; |
---|
338 | } |
---|
339 | } else { |
---|
340 | echo $_output; |
---|
341 | } |
---|
342 | // debug output |
---|
343 | if ($this->smarty->debugging) { |
---|
344 | Smarty_Internal_Debug::display_debug($this); |
---|
345 | } |
---|
346 | if ($merge_tpl_vars) { |
---|
347 | // restore local variables |
---|
348 | $_template->tpl_vars = $save_tpl_vars; |
---|
349 | $_template->config_vars = $save_config_vars; |
---|
350 | } |
---|
351 | return; |
---|
352 | } else { |
---|
353 | if ($merge_tpl_vars) { |
---|
354 | // restore local variables |
---|
355 | $_template->tpl_vars = $save_tpl_vars; |
---|
356 | $_template->config_vars = $save_config_vars; |
---|
357 | } |
---|
358 | // return fetched content |
---|
359 | return $_output; |
---|
360 | } |
---|
361 | } |
---|
362 | |
---|
363 | /** |
---|
364 | * displays a Smarty template |
---|
365 | * |
---|
366 | * @param string $template the resource handle of the template file or template object |
---|
367 | * @param mixed $cache_id cache id to be used with this template |
---|
368 | * @param mixed $compile_id compile id to be used with this template |
---|
369 | * @param object $parent next higher level of Smarty variables |
---|
370 | */ |
---|
371 | public function display($template = null, $cache_id = null, $compile_id = null, $parent = null) |
---|
372 | { |
---|
373 | // display template |
---|
374 | $this->fetch($template, $cache_id, $compile_id, $parent, true); |
---|
375 | } |
---|
376 | |
---|
377 | /** |
---|
378 | * test if cache is valid |
---|
379 | * |
---|
380 | * @param string|object $template the resource handle of the template file or template object |
---|
381 | * @param mixed $cache_id cache id to be used with this template |
---|
382 | * @param mixed $compile_id compile id to be used with this template |
---|
383 | * @param object $parent next higher level of Smarty variables |
---|
384 | * @return boolean cache status |
---|
385 | */ |
---|
386 | public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null) |
---|
387 | { |
---|
388 | if ($template === null && $this instanceof $this->template_class) { |
---|
389 | return $this->cached->valid; |
---|
390 | } |
---|
391 | if (!($template instanceof $this->template_class)) { |
---|
392 | if ($parent === null) { |
---|
393 | $parent = $this; |
---|
394 | } |
---|
395 | $template = $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false); |
---|
396 | } |
---|
397 | // return cache status of template |
---|
398 | return $template->cached->valid; |
---|
399 | } |
---|
400 | |
---|
401 | /** |
---|
402 | * creates a data object |
---|
403 | * |
---|
404 | * @param object $parent next higher level of Smarty variables |
---|
405 | * @returns Smarty_Data data object |
---|
406 | */ |
---|
407 | public function createData($parent = null) |
---|
408 | { |
---|
409 | return new Smarty_Data($parent, $this); |
---|
410 | } |
---|
411 | |
---|
412 | /** |
---|
413 | * Registers plugin to be used in templates |
---|
414 | * |
---|
415 | * @param string $type plugin type |
---|
416 | * @param string $tag name of template tag |
---|
417 | * @param callback $callback PHP callback to register |
---|
418 | * @param boolean $cacheable if true (default) this fuction is cachable |
---|
419 | * @param array $cache_attr caching attributes if any |
---|
420 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
421 | * @throws SmartyException when the plugin tag is invalid |
---|
422 | */ |
---|
423 | public function registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = null) |
---|
424 | { |
---|
425 | if (isset($this->smarty->registered_plugins[$type][$tag])) { |
---|
426 | throw new SmartyException("Plugin tag \"{$tag}\" already registered"); |
---|
427 | } elseif (!is_callable($callback)) { |
---|
428 | throw new SmartyException("Plugin \"{$tag}\" not callable"); |
---|
429 | } else { |
---|
430 | $this->smarty->registered_plugins[$type][$tag] = array($callback, (bool) $cacheable, (array) $cache_attr); |
---|
431 | } |
---|
432 | |
---|
433 | return $this; |
---|
434 | } |
---|
435 | |
---|
436 | /** |
---|
437 | * Unregister Plugin |
---|
438 | * |
---|
439 | * @param string $type of plugin |
---|
440 | * @param string $tag name of plugin |
---|
441 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
442 | */ |
---|
443 | public function unregisterPlugin($type, $tag) |
---|
444 | { |
---|
445 | if (isset($this->smarty->registered_plugins[$type][$tag])) { |
---|
446 | unset($this->smarty->registered_plugins[$type][$tag]); |
---|
447 | } |
---|
448 | |
---|
449 | return $this; |
---|
450 | } |
---|
451 | |
---|
452 | /** |
---|
453 | * Registers a resource to fetch a template |
---|
454 | * |
---|
455 | * @param string $type name of resource type |
---|
456 | * @param Smarty_Resource|array $callback or instance of Smarty_Resource, or array of callbacks to handle resource (deprecated) |
---|
457 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
458 | */ |
---|
459 | public function registerResource($type, $callback) |
---|
460 | { |
---|
461 | $this->smarty->registered_resources[$type] = $callback instanceof Smarty_Resource ? $callback : array($callback, false); |
---|
462 | return $this; |
---|
463 | } |
---|
464 | |
---|
465 | /** |
---|
466 | * Unregisters a resource |
---|
467 | * |
---|
468 | * @param string $type name of resource type |
---|
469 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
470 | */ |
---|
471 | public function unregisterResource($type) |
---|
472 | { |
---|
473 | if (isset($this->smarty->registered_resources[$type])) { |
---|
474 | unset($this->smarty->registered_resources[$type]); |
---|
475 | } |
---|
476 | |
---|
477 | return $this; |
---|
478 | } |
---|
479 | |
---|
480 | /** |
---|
481 | * Registers a cache resource to cache a template's output |
---|
482 | * |
---|
483 | * @param string $type name of cache resource type |
---|
484 | * @param Smarty_CacheResource $callback instance of Smarty_CacheResource to handle output caching |
---|
485 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
486 | */ |
---|
487 | public function registerCacheResource($type, Smarty_CacheResource $callback) |
---|
488 | { |
---|
489 | $this->smarty->registered_cache_resources[$type] = $callback; |
---|
490 | return $this; |
---|
491 | } |
---|
492 | |
---|
493 | /** |
---|
494 | * Unregisters a cache resource |
---|
495 | * |
---|
496 | * @param string $type name of cache resource type |
---|
497 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
498 | */ |
---|
499 | public function unregisterCacheResource($type) |
---|
500 | { |
---|
501 | if (isset($this->smarty->registered_cache_resources[$type])) { |
---|
502 | unset($this->smarty->registered_cache_resources[$type]); |
---|
503 | } |
---|
504 | |
---|
505 | return $this; |
---|
506 | } |
---|
507 | |
---|
508 | /** |
---|
509 | * Registers object to be used in templates |
---|
510 | * |
---|
511 | * @param string $object name of template object |
---|
512 | * @param object $object_impl the referenced PHP object to register |
---|
513 | * @param array $allowed list of allowed methods (empty = all) |
---|
514 | * @param boolean $smarty_args smarty argument format, else traditional |
---|
515 | * @param array $block_methods list of block-methods |
---|
516 | * @param array $block_functs list of methods that are block format |
---|
517 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
518 | * @throws SmartyException if any of the methods in $allowed or $block_methods are invalid |
---|
519 | */ |
---|
520 | public function registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) |
---|
521 | { |
---|
522 | // test if allowed methodes callable |
---|
523 | if (!empty($allowed)) { |
---|
524 | foreach ((array) $allowed as $method) { |
---|
525 | if (!is_callable(array($object_impl, $method))) { |
---|
526 | throw new SmartyException("Undefined method '$method' in registered object"); |
---|
527 | } |
---|
528 | } |
---|
529 | } |
---|
530 | // test if block methodes callable |
---|
531 | if (!empty($block_methods)) { |
---|
532 | foreach ((array) $block_methods as $method) { |
---|
533 | if (!is_callable(array($object_impl, $method))) { |
---|
534 | throw new SmartyException("Undefined method '$method' in registered object"); |
---|
535 | } |
---|
536 | } |
---|
537 | } |
---|
538 | // register the object |
---|
539 | $this->smarty->registered_objects[$object_name] = |
---|
540 | array($object_impl, (array) $allowed, (boolean) $smarty_args, (array) $block_methods); |
---|
541 | return $this; |
---|
542 | } |
---|
543 | |
---|
544 | /** |
---|
545 | * return a reference to a registered object |
---|
546 | * |
---|
547 | * @param string $name object name |
---|
548 | * @return object |
---|
549 | * @throws SmartyException if no such object is found |
---|
550 | */ |
---|
551 | public function getRegisteredObject($name) |
---|
552 | { |
---|
553 | if (!isset($this->smarty->registered_objects[$name])) { |
---|
554 | throw new SmartyException("'$name' is not a registered object"); |
---|
555 | } |
---|
556 | if (!is_object($this->smarty->registered_objects[$name][0])) { |
---|
557 | throw new SmartyException("registered '$name' is not an object"); |
---|
558 | } |
---|
559 | return $this->smarty->registered_objects[$name][0]; |
---|
560 | } |
---|
561 | |
---|
562 | /** |
---|
563 | * unregister an object |
---|
564 | * |
---|
565 | * @param string $name object name |
---|
566 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
567 | */ |
---|
568 | public function unregisterObject($name) |
---|
569 | { |
---|
570 | if (isset($this->smarty->registered_objects[$name])) { |
---|
571 | unset($this->smarty->registered_objects[$name]); |
---|
572 | } |
---|
573 | |
---|
574 | return $this; |
---|
575 | } |
---|
576 | |
---|
577 | /** |
---|
578 | * Registers static classes to be used in templates |
---|
579 | * |
---|
580 | * @param string $class name of template class |
---|
581 | * @param string $class_impl the referenced PHP class to register |
---|
582 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
583 | * @throws SmartyException if $class_impl does not refer to an existing class |
---|
584 | */ |
---|
585 | public function registerClass($class_name, $class_impl) |
---|
586 | { |
---|
587 | // test if exists |
---|
588 | if (!class_exists($class_impl)) { |
---|
589 | throw new SmartyException("Undefined class '$class_impl' in register template class"); |
---|
590 | } |
---|
591 | // register the class |
---|
592 | $this->smarty->registered_classes[$class_name] = $class_impl; |
---|
593 | return $this; |
---|
594 | } |
---|
595 | |
---|
596 | /** |
---|
597 | * Registers a default plugin handler |
---|
598 | * |
---|
599 | * @param callable $callback class/method name |
---|
600 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
601 | * @throws SmartyException if $callback is not callable |
---|
602 | */ |
---|
603 | public function registerDefaultPluginHandler($callback) |
---|
604 | { |
---|
605 | if (is_callable($callback)) { |
---|
606 | $this->smarty->default_plugin_handler_func = $callback; |
---|
607 | } else { |
---|
608 | throw new SmartyException("Default plugin handler '$callback' not callable"); |
---|
609 | } |
---|
610 | |
---|
611 | return $this; |
---|
612 | } |
---|
613 | |
---|
614 | /** |
---|
615 | * Registers a default template handler |
---|
616 | * |
---|
617 | * @param callable $callback class/method name |
---|
618 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
619 | * @throws SmartyException if $callback is not callable |
---|
620 | */ |
---|
621 | public function registerDefaultTemplateHandler($callback) |
---|
622 | { |
---|
623 | if (is_callable($callback)) { |
---|
624 | $this->smarty->default_template_handler_func = $callback; |
---|
625 | } else { |
---|
626 | throw new SmartyException("Default template handler '$callback' not callable"); |
---|
627 | } |
---|
628 | |
---|
629 | return $this; |
---|
630 | } |
---|
631 | |
---|
632 | /** |
---|
633 | * Registers a default template handler |
---|
634 | * |
---|
635 | * @param callable $callback class/method name |
---|
636 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
637 | * @throws SmartyException if $callback is not callable |
---|
638 | */ |
---|
639 | public function registerDefaultConfigHandler($callback) |
---|
640 | { |
---|
641 | if (is_callable($callback)) { |
---|
642 | $this->smarty->default_config_handler_func = $callback; |
---|
643 | } else { |
---|
644 | throw new SmartyException("Default config handler '$callback' not callable"); |
---|
645 | } |
---|
646 | |
---|
647 | return $this; |
---|
648 | } |
---|
649 | |
---|
650 | /** |
---|
651 | * Registers a filter function |
---|
652 | * |
---|
653 | * @param string $type filter type |
---|
654 | * @param callback $callback |
---|
655 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
656 | */ |
---|
657 | public function registerFilter($type, $callback) |
---|
658 | { |
---|
659 | $this->smarty->registered_filters[$type][$this->_get_filter_name($callback)] = $callback; |
---|
660 | return $this; |
---|
661 | } |
---|
662 | |
---|
663 | /** |
---|
664 | * Unregisters a filter function |
---|
665 | * |
---|
666 | * @param string $type filter type |
---|
667 | * @param callback $callback |
---|
668 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
669 | */ |
---|
670 | public function unregisterFilter($type, $callback) |
---|
671 | { |
---|
672 | $name = $this->_get_filter_name($callback); |
---|
673 | if (isset($this->smarty->registered_filters[$type][$name])) { |
---|
674 | unset($this->smarty->registered_filters[$type][$name]); |
---|
675 | } |
---|
676 | |
---|
677 | return $this; |
---|
678 | } |
---|
679 | |
---|
680 | /** |
---|
681 | * Return internal filter name |
---|
682 | * |
---|
683 | * @param callback $function_name |
---|
684 | * @return string internal filter name |
---|
685 | */ |
---|
686 | public function _get_filter_name($function_name) |
---|
687 | { |
---|
688 | if (is_array($function_name)) { |
---|
689 | $_class_name = (is_object($function_name[0]) ? |
---|
690 | get_class($function_name[0]) : $function_name[0]); |
---|
691 | return $_class_name . '_' . $function_name[1]; |
---|
692 | } else { |
---|
693 | return $function_name; |
---|
694 | } |
---|
695 | } |
---|
696 | |
---|
697 | /** |
---|
698 | * load a filter of specified type and name |
---|
699 | * |
---|
700 | * @param string $type filter type |
---|
701 | * @param string $name filter name |
---|
702 | * @throws SmartyException if filter could not be loaded |
---|
703 | */ |
---|
704 | public function loadFilter($type, $name) |
---|
705 | { |
---|
706 | $_plugin = "smarty_{$type}filter_{$name}"; |
---|
707 | $_filter_name = $_plugin; |
---|
708 | if ($this->smarty->loadPlugin($_plugin)) { |
---|
709 | if (class_exists($_plugin, false)) { |
---|
710 | $_plugin = array($_plugin, 'execute'); |
---|
711 | } |
---|
712 | if (is_callable($_plugin)) { |
---|
713 | $this->smarty->registered_filters[$type][$_filter_name] = $_plugin; |
---|
714 | return true; |
---|
715 | } |
---|
716 | } |
---|
717 | throw new SmartyException("{$type}filter \"{$name}\" not callable"); |
---|
718 | } |
---|
719 | |
---|
720 | /** |
---|
721 | * unload a filter of specified type and name |
---|
722 | * |
---|
723 | * @param string $type filter type |
---|
724 | * @param string $name filter name |
---|
725 | * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or Smarty_Internal_Template) instance for chaining |
---|
726 | */ |
---|
727 | public function unloadFilter($type, $name) |
---|
728 | { |
---|
729 | $_filter_name = "smarty_{$type}filter_{$name}"; |
---|
730 | if (isset($this->smarty->registered_filters[$type][$_filter_name])) { |
---|
731 | unset ($this->smarty->registered_filters[$type][$_filter_name]); |
---|
732 | } |
---|
733 | |
---|
734 | return $this; |
---|
735 | } |
---|
736 | |
---|
737 | /** |
---|
738 | * preg_replace callback to convert camelcase getter/setter to underscore property names |
---|
739 | * |
---|
740 | * @param string $match match string |
---|
741 | * @return string replacemant |
---|
742 | */ |
---|
743 | private function replaceCamelcase($match) { |
---|
744 | return "_" . strtolower($match[1]); |
---|
745 | } |
---|
746 | |
---|
747 | /** |
---|
748 | * Handle unknown class methods |
---|
749 | * |
---|
750 | * @param string $name unknown method-name |
---|
751 | * @param array $args argument array |
---|
752 | */ |
---|
753 | public function __call($name, $args) |
---|
754 | { |
---|
755 | static $_prefixes = array('set' => true, 'get' => true); |
---|
756 | static $_resolved_property_name = array(); |
---|
757 | static $_resolved_property_source = array(); |
---|
758 | |
---|
759 | // method of Smarty object? |
---|
760 | if (method_exists($this->smarty, $name)) { |
---|
761 | return call_user_func_array(array($this->smarty, $name), $args); |
---|
762 | } |
---|
763 | // see if this is a set/get for a property |
---|
764 | $first3 = strtolower(substr($name, 0, 3)); |
---|
765 | if (isset($_prefixes[$first3]) && isset($name[3]) && $name[3] !== '_') { |
---|
766 | if (isset($_resolved_property_name[$name])) { |
---|
767 | $property_name = $_resolved_property_name[$name]; |
---|
768 | } else { |
---|
769 | // try to keep case correct for future PHP 6.0 case-sensitive class methods |
---|
770 | // lcfirst() not available < PHP 5.3.0, so improvise |
---|
771 | $property_name = strtolower(substr($name, 3, 1)) . substr($name, 4); |
---|
772 | // convert camel case to underscored name |
---|
773 | $property_name = preg_replace_callback('/([A-Z])/', array($this,'replaceCamelcase'), $property_name); |
---|
774 | $_resolved_property_name[$name] = $property_name; |
---|
775 | } |
---|
776 | if (isset($_resolved_property_source[$property_name])) { |
---|
777 | $_is_this = $_resolved_property_source[$property_name]; |
---|
778 | } else { |
---|
779 | $_is_this = null; |
---|
780 | if (property_exists($this, $property_name)) { |
---|
781 | $_is_this = true; |
---|
782 | } else if (property_exists($this->smarty, $property_name)) { |
---|
783 | $_is_this = false; |
---|
784 | } |
---|
785 | $_resolved_property_source[$property_name] = $_is_this; |
---|
786 | } |
---|
787 | if ($_is_this) { |
---|
788 | if ($first3 == 'get') |
---|
789 | return $this->$property_name; |
---|
790 | else |
---|
791 | return $this->$property_name = $args[0]; |
---|
792 | } else if ($_is_this === false) { |
---|
793 | if ($first3 == 'get') |
---|
794 | return $this->smarty->$property_name; |
---|
795 | else |
---|
796 | return $this->smarty->$property_name = $args[0]; |
---|
797 | } else { |
---|
798 | throw new SmartyException("property '$property_name' does not exist."); |
---|
799 | return false; |
---|
800 | } |
---|
801 | } |
---|
802 | if ($name == 'Smarty') { |
---|
803 | throw new SmartyException("PHP5 requires you to call __construct() instead of Smarty()"); |
---|
804 | } |
---|
805 | // must be unknown |
---|
806 | throw new SmartyException("Call of unknown method '$name'."); |
---|
807 | } |
---|
808 | |
---|
809 | } |
---|
810 | |
---|
811 | ?> |
---|