library/smarty/libs/sysplugins/smarty_internal_templatebase.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 <?php
       
     2 /**
       
     3  * Smarty Internal Plugin Smarty Template  Base
       
     4  * This file contains the basic shared methods for template handling
       
     5  *
       
     6  * @package    Smarty
       
     7  * @subpackage Template
       
     8  * @author     Uwe Tews
       
     9  */
       
    10 
       
    11 /**
       
    12  * Class with shared template methods
       
    13  *
       
    14  * @package    Smarty
       
    15  * @subpackage Template
       
    16  */
       
    17 abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
       
    18     /**
       
    19      * Set this if you want different sets of cache files for the same
       
    20      * templates.
       
    21      *
       
    22      * @var string
       
    23      */
       
    24     public $cache_id = null;
       
    25     /**
       
    26      * Set this if you want different sets of compiled files for the same
       
    27      * templates.
       
    28      *
       
    29      * @var string
       
    30      */
       
    31     public $compile_id = null;
       
    32     /**
       
    33      * caching enabled
       
    34      *
       
    35      * @var boolean
       
    36      */
       
    37     public $caching = false;
       
    38     /**
       
    39      * cache lifetime in seconds
       
    40      *
       
    41      * @var integer
       
    42      */
       
    43     public $cache_lifetime = 3600;
       
    44 
       
    45     /**
       
    46      * test if cache is valid
       
    47      *
       
    48      * @param  string|object $template the resource handle of the template file or template object
       
    49      * @param  mixed $cache_id cache id to be used with this template
       
    50      * @param  mixed $compile_id compile id to be used with this template
       
    51      * @param  object $parent next higher level of Smarty variables
       
    52      *
       
    53      * @return boolean       cache status
       
    54      */
       
    55     public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null) {
       
    56         if ($template === null && $this instanceof $this->template_class) {
       
    57             $template = $this;
       
    58         } else {
       
    59             if (!($template instanceof $this->template_class)) {
       
    60                 if ($parent === null) {
       
    61                     $parent = $this;
       
    62                 }
       
    63                 $smarty = isset($this->smarty) ? $this->smarty : $this;
       
    64                 $template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
       
    65             }
       
    66         }
       
    67         // return cache status of template
       
    68         if (!isset($template->cached)) {
       
    69             $template->loadCached();
       
    70         }
       
    71         return $template->cached->isCached($template);
       
    72     }
       
    73 
       
    74     /**
       
    75      * creates a data object
       
    76      *
       
    77      * @param object $parent next higher level of Smarty variables
       
    78      * @param string $name optional data block name
       
    79      *
       
    80      * @returns Smarty_Data data object
       
    81      */
       
    82     public function createData($parent = null, $name = null) {
       
    83         $dataObj = new Smarty_Data($parent, $this, $name);
       
    84         if ($this->debugging) {
       
    85             Smarty_Internal_Debug::register_data($dataObj);
       
    86         }
       
    87         return $dataObj;
       
    88     }
       
    89 
       
    90     /**
       
    91      * Get unique template id
       
    92      *
       
    93      * @param string $template_name
       
    94      * @param null|mixed $cache_id
       
    95      * @param null|mixed $compile_id
       
    96      *
       
    97      * @return string
       
    98      */
       
    99     public function getTemplateId($template_name, $cache_id = null, $compile_id = null) {
       
   100         $cache_id = isset($cache_id) ? $cache_id : $this->cache_id;
       
   101         $compile_id = isset($compile_id) ? $compile_id : $this->compile_id;
       
   102         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   103         if ($smarty->allow_ambiguous_resources) {
       
   104             $_templateId = Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}";
       
   105         } else {
       
   106             $_templateId = $smarty->joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}";
       
   107         }
       
   108         if (isset($_templateId[150])) {
       
   109             $_templateId = sha1($_templateId);
       
   110         }
       
   111         return $_templateId;
       
   112     }
       
   113 
       
   114     /**
       
   115      * Registers plugin to be used in templates
       
   116      *
       
   117      * @param  string $type plugin type
       
   118      * @param  string $tag name of template tag
       
   119      * @param  callback $callback PHP callback to register
       
   120      * @param  boolean $cacheable if true (default) this fuction is cachable
       
   121      * @param  array $cache_attr caching attributes if any
       
   122      *
       
   123      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   124      *                                      Smarty_Internal_Template) instance for chaining
       
   125      * @throws SmartyException              when the plugin tag is invalid
       
   126      */
       
   127     public function registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = null) {
       
   128         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   129         if (isset($smarty->registered_plugins[$type][$tag])) {
       
   130             throw new SmartyException("Plugin tag \"{$tag}\" already registered");
       
   131         } elseif (!is_callable($callback)) {
       
   132             throw new SmartyException("Plugin \"{$tag}\" not callable");
       
   133         } else {
       
   134             $smarty->registered_plugins[$type][$tag] = array($callback, (bool)$cacheable, (array)$cache_attr);
       
   135         }
       
   136 
       
   137         return $this;
       
   138     }
       
   139 
       
   140     /**
       
   141      * Unregister Plugin
       
   142      *
       
   143      * @param  string $type of plugin
       
   144      * @param  string $tag name of plugin
       
   145      *
       
   146      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   147      *                                      Smarty_Internal_Template) instance for chaining
       
   148      */
       
   149     public function unregisterPlugin($type, $tag) {
       
   150         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   151         if (isset($smarty->registered_plugins[$type][$tag])) {
       
   152             unset($smarty->registered_plugins[$type][$tag]);
       
   153         }
       
   154 
       
   155         return $this;
       
   156     }
       
   157 
       
   158     /**
       
   159      * Registers a resource to fetch a template
       
   160      *
       
   161      * @param  string $type name of resource type
       
   162      * @param  Smarty_Resource|array $callback or instance of Smarty_Resource, or array of callbacks to handle resource
       
   163      *                                         (deprecated)
       
   164      *
       
   165      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   166      *                                      Smarty_Internal_Template) instance for chaining
       
   167      */
       
   168     public function registerResource($type, $callback) {
       
   169         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   170         $smarty->registered_resources[$type] = $callback instanceof Smarty_Resource ? $callback : array($callback, false);
       
   171 
       
   172         return $this;
       
   173     }
       
   174 
       
   175     /**
       
   176      * Unregisters a resource
       
   177      *
       
   178      * @param  string $type name of resource type
       
   179      *
       
   180      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   181      *                                      Smarty_Internal_Template) instance for chaining
       
   182      */
       
   183     public function unregisterResource($type) {
       
   184         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   185         if (isset($smarty->registered_resources[$type])) {
       
   186             unset($smarty->registered_resources[$type]);
       
   187         }
       
   188 
       
   189         return $this;
       
   190     }
       
   191 
       
   192     /**
       
   193      * Registers a cache resource to cache a template's output
       
   194      *
       
   195      * @param  string $type name of cache resource type
       
   196      * @param  Smarty_CacheResource $callback instance of Smarty_CacheResource to handle output caching
       
   197      *
       
   198      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   199      *                                      Smarty_Internal_Template) instance for chaining
       
   200      */
       
   201     public function registerCacheResource($type, Smarty_CacheResource $callback) {
       
   202         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   203         $smarty->registered_cache_resources[$type] = $callback;
       
   204 
       
   205         return $this;
       
   206     }
       
   207 
       
   208     /**
       
   209      * Unregisters a cache resource
       
   210      *
       
   211      * @param  string $type name of cache resource type
       
   212      *
       
   213      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   214      *                                      Smarty_Internal_Template) instance for chaining
       
   215      */
       
   216     public function unregisterCacheResource($type) {
       
   217         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   218         if (isset($smarty->registered_cache_resources[$type])) {
       
   219             unset($smarty->registered_cache_resources[$type]);
       
   220         }
       
   221 
       
   222         return $this;
       
   223     }
       
   224 
       
   225     /**
       
   226      * Registers object to be used in templates
       
   227      *
       
   228      * @param          $object_name
       
   229      * @param  object $object_impl the referenced PHP object to register
       
   230      * @param  array $allowed list of allowed methods (empty = all)
       
   231      * @param  boolean $smarty_args smarty argument format, else traditional
       
   232      * @param  array $block_methods list of block-methods
       
   233      *
       
   234      * @throws SmartyException
       
   235      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   236      *                                      Smarty_Internal_Template) instance for chaining
       
   237      */
       
   238     public function registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) {
       
   239         // test if allowed methods callable
       
   240         if (!empty($allowed)) {
       
   241             foreach ((array)$allowed as $method) {
       
   242                 if (!is_callable(array($object_impl, $method)) && !property_exists($object_impl, $method)) {
       
   243                     throw new SmartyException("Undefined method or property '$method' in registered object");
       
   244                 }
       
   245             }
       
   246         }
       
   247         // test if block methods callable
       
   248         if (!empty($block_methods)) {
       
   249             foreach ((array)$block_methods as $method) {
       
   250                 if (!is_callable(array($object_impl, $method))) {
       
   251                     throw new SmartyException("Undefined method '$method' in registered object");
       
   252                 }
       
   253             }
       
   254         }
       
   255         // register the object
       
   256         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   257         $smarty->registered_objects[$object_name] =
       
   258             array($object_impl, (array)$allowed, (boolean)$smarty_args, (array)$block_methods);
       
   259 
       
   260         return $this;
       
   261     }
       
   262 
       
   263     /**
       
   264      * return a reference to a registered object
       
   265      *
       
   266      * @param  string $name object name
       
   267      *
       
   268      * @return object
       
   269      * @throws SmartyException if no such object is found
       
   270      */
       
   271     public function getRegisteredObject($name) {
       
   272         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   273         if (!isset($smarty->registered_objects[$name])) {
       
   274             throw new SmartyException("'$name' is not a registered object");
       
   275         }
       
   276         if (!is_object($smarty->registered_objects[$name][0])) {
       
   277             throw new SmartyException("registered '$name' is not an object");
       
   278         }
       
   279 
       
   280         return $smarty->registered_objects[$name][0];
       
   281     }
       
   282 
       
   283     /**
       
   284      * unregister an object
       
   285      *
       
   286      * @param  string $name object name
       
   287      *
       
   288      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   289      *                                      Smarty_Internal_Template) instance for chaining
       
   290      */
       
   291     public function unregisterObject($name) {
       
   292         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   293         if (isset($smarty->registered_objects[$name])) {
       
   294             unset($smarty->registered_objects[$name]);
       
   295         }
       
   296 
       
   297         return $this;
       
   298     }
       
   299 
       
   300     /**
       
   301      * Registers static classes to be used in templates
       
   302      *
       
   303      * @param         $class_name
       
   304      * @param  string $class_impl the referenced PHP class to register
       
   305      *
       
   306      * @throws SmartyException
       
   307      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   308      *                                      Smarty_Internal_Template) instance for chaining
       
   309      */
       
   310     public function registerClass($class_name, $class_impl) {
       
   311         // test if exists
       
   312         if (!class_exists($class_impl)) {
       
   313             throw new SmartyException("Undefined class '$class_impl' in register template class");
       
   314         }
       
   315         // register the class
       
   316         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   317         $smarty->registered_classes[$class_name] = $class_impl;
       
   318 
       
   319         return $this;
       
   320     }
       
   321 
       
   322     /**
       
   323      * Registers a default plugin handler
       
   324      *
       
   325      * @param  callable $callback class/method name
       
   326      *
       
   327      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   328      *                                      Smarty_Internal_Template) instance for chaining
       
   329      * @throws SmartyException              if $callback is not callable
       
   330      */
       
   331     public function registerDefaultPluginHandler($callback) {
       
   332         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   333         if (is_callable($callback)) {
       
   334             $smarty->default_plugin_handler_func = $callback;
       
   335         } else {
       
   336             throw new SmartyException("Default plugin handler '$callback' not callable");
       
   337         }
       
   338 
       
   339         return $this;
       
   340     }
       
   341 
       
   342     /**
       
   343      * Registers a default template handler
       
   344      *
       
   345      * @param  callable $callback class/method name
       
   346      *
       
   347      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   348      *                                      Smarty_Internal_Template) instance for chaining
       
   349      * @throws SmartyException              if $callback is not callable
       
   350      */
       
   351     public function registerDefaultTemplateHandler($callback) {
       
   352         Smarty_Internal_Extension_DefaultTemplateHandler::registerDefaultTemplateHandler($this, $callback);
       
   353         return $this;
       
   354     }
       
   355 
       
   356     /**
       
   357      * Registers a default template handler
       
   358      *
       
   359      * @param  callable $callback class/method name
       
   360      *
       
   361      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   362      *                                      Smarty_Internal_Template) instance for chaining
       
   363      * @throws SmartyException              if $callback is not callable
       
   364      */
       
   365     public function registerDefaultConfigHandler($callback) {
       
   366         Smarty_Internal_Extension_DefaultTemplateHandler::registerDefaultConfigHandler($this, $callback);
       
   367         return $this;
       
   368     }
       
   369 
       
   370     /**
       
   371      * Registers a filter function
       
   372      *
       
   373      * @param  string $type filter type
       
   374      * @param  callback $callback
       
   375      *
       
   376      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   377      *                                      Smarty_Internal_Template) instance for chaining
       
   378      */
       
   379     public function registerFilter($type, $callback) {
       
   380         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   381         $smarty->registered_filters[$type][$this->_get_filter_name($callback)] = $callback;
       
   382 
       
   383         return $this;
       
   384     }
       
   385 
       
   386     /**
       
   387      * Unregisters a filter function
       
   388      *
       
   389      * @param  string $type filter type
       
   390      * @param  callback $callback
       
   391      *
       
   392      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   393      *                                      Smarty_Internal_Template) instance for chaining
       
   394      */
       
   395     public function unregisterFilter($type, $callback) {
       
   396         $name = $this->_get_filter_name($callback);
       
   397         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   398         if (isset($smarty->registered_filters[$type][$name])) {
       
   399             unset($smarty->registered_filters[$type][$name]);
       
   400         }
       
   401 
       
   402         return $this;
       
   403     }
       
   404 
       
   405     /**
       
   406      * Return internal filter name
       
   407      *
       
   408      * @param  callback $function_name
       
   409      *
       
   410      * @return string   internal filter name
       
   411      */
       
   412     public function _get_filter_name($function_name) {
       
   413         if (is_array($function_name)) {
       
   414             $_class_name = (is_object($function_name[0]) ?
       
   415                 get_class($function_name[0]) : $function_name[0]);
       
   416 
       
   417             return $_class_name . '_' . $function_name[1];
       
   418         } else {
       
   419             return $function_name;
       
   420         }
       
   421     }
       
   422 
       
   423     /**
       
   424      * load a filter of specified type and name
       
   425      *
       
   426      * @param  string $type filter type
       
   427      * @param  string $name filter name
       
   428      *
       
   429      * @throws SmartyException if filter could not be loaded
       
   430      */
       
   431     public function loadFilter($type, $name) {
       
   432         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   433         $_plugin = "smarty_{$type}filter_{$name}";
       
   434         $_filter_name = $_plugin;
       
   435         if ($smarty->loadPlugin($_plugin)) {
       
   436             if (class_exists($_plugin, false)) {
       
   437                 $_plugin = array($_plugin, 'execute');
       
   438             }
       
   439             if (is_callable($_plugin)) {
       
   440                 $smarty->registered_filters[$type][$_filter_name] = $_plugin;
       
   441 
       
   442                 return true;
       
   443             }
       
   444         }
       
   445         throw new SmartyException("{$type}filter \"{$name}\" not callable");
       
   446     }
       
   447 
       
   448     /**
       
   449      * unload a filter of specified type and name
       
   450      *
       
   451      * @param  string $type filter type
       
   452      * @param  string $name filter name
       
   453      *
       
   454      * @return Smarty_Internal_Templatebase current Smarty_Internal_Templatebase (or Smarty or
       
   455      *                                      Smarty_Internal_Template) instance for chaining
       
   456      */
       
   457     public function unloadFilter($type, $name) {
       
   458         $smarty = isset($this->smarty) ? $this->smarty : $this;
       
   459         $_filter_name = "smarty_{$type}filter_{$name}";
       
   460         if (isset($smarty->registered_filters[$type][$_filter_name])) {
       
   461             unset ($smarty->registered_filters[$type][$_filter_name]);
       
   462         }
       
   463 
       
   464         return $this;
       
   465     }
       
   466 
       
   467     /**
       
   468      * preg_replace callback to convert camelcase getter/setter to underscore property names
       
   469      *
       
   470      * @param  string $match match string
       
   471      *
       
   472      * @return string replacemant
       
   473      */
       
   474     private function replaceCamelcase($match) {
       
   475         return "_" . strtolower($match[1]);
       
   476     }
       
   477 
       
   478     /**
       
   479      * Handle unknown class methods
       
   480      *
       
   481      * @param string $name unknown method-name
       
   482      * @param array $args argument array
       
   483      *
       
   484      * @throws SmartyException
       
   485      */
       
   486     public function __call($name, $args) {
       
   487         static $_prefixes = array('set' => true, 'get' => true);
       
   488         static $_resolved_property_name = array();
       
   489         static $_resolved_property_source = array();
       
   490 
       
   491         // see if this is a set/get for a property
       
   492         $first3 = strtolower(substr($name, 0, 3));
       
   493         if (isset($_prefixes[$first3]) && isset($name[3]) && $name[3] !== '_') {
       
   494             if (isset($_resolved_property_name[$name])) {
       
   495                 $property_name = $_resolved_property_name[$name];
       
   496             } else {
       
   497                 // try to keep case correct for future PHP 6.0 case-sensitive class methods
       
   498                 // lcfirst() not available < PHP 5.3.0, so improvise
       
   499                 $property_name = strtolower(substr($name, 3, 1)) . substr($name, 4);
       
   500                 // convert camel case to underscored name
       
   501                 $property_name = preg_replace_callback('/([A-Z])/', array($this, 'replaceCamelcase'), $property_name);
       
   502                 $_resolved_property_name[$name] = $property_name;
       
   503             }
       
   504             if (isset($_resolved_property_source[$property_name])) {
       
   505                 $status = $_resolved_property_source[$property_name];
       
   506             } else {
       
   507                 $status = null;
       
   508                 if (property_exists($this, $property_name)) {
       
   509                     $status = true;
       
   510                 } elseif (property_exists($this->smarty, $property_name)) {
       
   511                     $status = false;
       
   512                 }
       
   513                 $_resolved_property_source[$property_name] = $status;
       
   514             }
       
   515             $smarty = null;
       
   516             if ($status === true) {
       
   517                 $smarty = $this;
       
   518             } elseif ($status === false) {
       
   519                 $smarty = $this->smarty;
       
   520             }
       
   521             if ($smarty) {
       
   522                 if ($first3 == 'get') {
       
   523                     return $smarty->$property_name;
       
   524                 } else {
       
   525                     return $smarty->$property_name = $args[0];
       
   526                 }
       
   527             }
       
   528             throw new SmartyException("property '$property_name' does not exist.");
       
   529         }
       
   530         throw new SmartyException("Call of unknown method '$name'.");
       
   531     }
       
   532 }
       
   533