source: pro-violet-viettel/sourcecode/application/third_party/Smarty/sysplugins/smarty_internal_templatebase.php @ 345

Last change on this file since 345 was 345, checked in by quyenla, 11 years ago

collaborator page

File size: 34.1 KB
Line 
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 */
18abstract 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?>
Note: See TracBrowser for help on using the repository browser.