packages/ssoinabox-webui/root/usr/local/share/ssoinabox/htdocs/includes/smarty/sysplugins/smarty_internal_template.php
changeset 0 3906ca745819
equal deleted inserted replaced
-1:000000000000 0:3906ca745819
       
     1 <?php
       
     2 /**
       
     3  * Smarty Internal Plugin Template
       
     4  *
       
     5  * This file contains the Smarty template engine
       
     6  *
       
     7  * @package Smarty
       
     8  * @subpackage Template
       
     9  * @author Uwe Tews
       
    10  */
       
    11 
       
    12 /**
       
    13  * Main class with template data structures and methods
       
    14  *
       
    15  * @package Smarty
       
    16  * @subpackage Template
       
    17  *
       
    18  * @property Smarty_Template_Source   $source
       
    19  * @property Smarty_Template_Compiled $compiled
       
    20  * @property Smarty_Template_Cached   $cached
       
    21  */
       
    22 class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
       
    23 
       
    24     /**
       
    25      * cache_id
       
    26      * @var string
       
    27      */
       
    28     public $cache_id = null;
       
    29     /**
       
    30      * $compile_id
       
    31      * @var string
       
    32      */
       
    33     public $compile_id = null;
       
    34     /**
       
    35      * caching enabled
       
    36      * @var boolean
       
    37      */
       
    38     public $caching = null;
       
    39     /**
       
    40      * cache lifetime in seconds
       
    41      * @var integer
       
    42      */
       
    43     public $cache_lifetime = null;
       
    44     /**
       
    45      * Template resource
       
    46      * @var string
       
    47      */
       
    48     public $template_resource = null;
       
    49     /**
       
    50      * flag if compiled template is invalid and must be (re)compiled
       
    51      * @var bool
       
    52      */
       
    53     public $mustCompile = null;
       
    54     /**
       
    55      * flag if template does contain nocache code sections
       
    56      * @var bool
       
    57      */
       
    58     public $has_nocache_code = false;
       
    59     /**
       
    60      * special compiled and cached template properties
       
    61      * @var array
       
    62      */
       
    63     public $properties = array('file_dependency' => array(),
       
    64         'nocache_hash' => '',
       
    65         'function' => array());
       
    66     /**
       
    67      * required plugins
       
    68      * @var array
       
    69      */
       
    70     public $required_plugins = array('compiled' => array(), 'nocache' => array());
       
    71     /**
       
    72      * Global smarty instance
       
    73      * @var Smarty
       
    74      */
       
    75     public $smarty = null;
       
    76     /**
       
    77      * blocks for template inheritance
       
    78      * @var array
       
    79      */
       
    80     public $block_data = array();
       
    81     /**
       
    82      * variable filters
       
    83      * @var array
       
    84      */
       
    85     public $variable_filters = array();
       
    86     /**
       
    87      * optional log of tag/attributes
       
    88      * @var array
       
    89      */
       
    90     public $used_tags = array();
       
    91     /**
       
    92      * internal flag to allow relative path in child template blocks
       
    93      * @var bool
       
    94      */
       
    95     public $allow_relative_path = false;
       
    96     /**
       
    97      * internal capture runtime stack
       
    98      * @var array
       
    99      */
       
   100     public $_capture_stack = array(0 => array());
       
   101 
       
   102     /**
       
   103      * Create template data object
       
   104      *
       
   105      * Some of the global Smarty settings copied to template scope
       
   106      * It load the required template resources and cacher plugins
       
   107      *
       
   108      * @param string                   $template_resource template resource string
       
   109      * @param Smarty                   $smarty            Smarty instance
       
   110      * @param Smarty_Internal_Template $_parent           back pointer to parent object with variables or null
       
   111      * @param mixed                    $_cache_id cache   id or null
       
   112      * @param mixed                    $_compile_id       compile id or null
       
   113      * @param bool                     $_caching          use caching?
       
   114      * @param int                      $_cache_lifetime   cache life-time in seconds
       
   115      */
       
   116     public function __construct($template_resource, $smarty, $_parent = null, $_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null)
       
   117     {
       
   118         $this->smarty = &$smarty;
       
   119         // Smarty parameter
       
   120         $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
       
   121         $this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id;
       
   122         $this->caching = $_caching === null ? $this->smarty->caching : $_caching;
       
   123         if ($this->caching === true)
       
   124             $this->caching = Smarty::CACHING_LIFETIME_CURRENT;
       
   125         $this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime;
       
   126         $this->parent = $_parent;
       
   127         // Template resource
       
   128         $this->template_resource = $template_resource;
       
   129         // copy block data of template inheritance
       
   130         if ($this->parent instanceof Smarty_Internal_Template) {
       
   131             $this->block_data = $this->parent->block_data;
       
   132         }
       
   133     }
       
   134 
       
   135     /**
       
   136      * Returns if the current template must be compiled by the Smarty compiler
       
   137      *
       
   138      * It does compare the timestamps of template source and the compiled templates and checks the force compile configuration
       
   139      *
       
   140      * @return boolean true if the template must be compiled
       
   141      */
       
   142     public function mustCompile()
       
   143     {
       
   144         if (!$this->source->exists) {
       
   145             if ($this->parent instanceof Smarty_Internal_Template) {
       
   146                 $parent_resource = " in '$this->parent->template_resource}'";
       
   147             } else {
       
   148                 $parent_resource = '';
       
   149             }
       
   150             throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
       
   151         }
       
   152         if ($this->mustCompile === null) {
       
   153             $this->mustCompile = (!$this->source->uncompiled && ($this->smarty->force_compile || $this->source->recompiled || $this->compiled->timestamp === false ||
       
   154                     ($this->smarty->compile_check && $this->compiled->timestamp < $this->source->timestamp)));
       
   155         }
       
   156         return $this->mustCompile;
       
   157     }
       
   158 
       
   159     /**
       
   160      * Compiles the template
       
   161      *
       
   162      * If the template is not evaluated the compiled template is saved on disk
       
   163      */
       
   164     public function compileTemplateSource()
       
   165     {
       
   166         if (!$this->source->recompiled) {
       
   167             $this->properties['file_dependency'] = array();
       
   168             if ($this->source->components) {
       
   169                 // uses real resource for file dependency
       
   170                 $source = end($this->source->components);
       
   171                 $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $source->type);
       
   172             } else {
       
   173                 $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type);
       
   174             }
       
   175         }
       
   176         if ($this->smarty->debugging) {
       
   177             Smarty_Internal_Debug::start_compile($this);
       
   178         }
       
   179         // compile locking
       
   180         if ($this->smarty->compile_locking && !$this->source->recompiled) {
       
   181             if ($saved_timestamp = $this->compiled->timestamp) {
       
   182                 touch($this->compiled->filepath);
       
   183             }
       
   184         }
       
   185         // call compiler
       
   186         try {
       
   187             $code = $this->compiler->compileTemplate($this);
       
   188         } catch (Exception $e) {
       
   189             // restore old timestamp in case of error
       
   190             if ($this->smarty->compile_locking && !$this->source->recompiled && $saved_timestamp) {
       
   191                 touch($this->compiled->filepath, $saved_timestamp);
       
   192             }
       
   193             throw $e;
       
   194         }
       
   195         // compiling succeded
       
   196         if (!$this->source->recompiled && $this->compiler->write_compiled_code) {
       
   197             // write compiled template
       
   198             $_filepath = $this->compiled->filepath;
       
   199             if ($_filepath === false)
       
   200                 throw new SmartyException('getCompiledFilepath() did not return a destination to save the compiled template to');
       
   201             Smarty_Internal_Write_File::writeFile($_filepath, $code, $this->smarty);
       
   202             $this->compiled->exists = true;
       
   203             $this->compiled->isCompiled = true;
       
   204         }
       
   205         if ($this->smarty->debugging) {
       
   206             Smarty_Internal_Debug::end_compile($this);
       
   207         }
       
   208         // release compiler object to free memory
       
   209         unset($this->compiler);
       
   210     }
       
   211 
       
   212     /**
       
   213      * Writes the cached template output
       
   214      *
       
   215      * @return bool
       
   216      */
       
   217     public function writeCachedContent($content)
       
   218     {
       
   219         if ($this->source->recompiled || !($this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED)) {
       
   220             // don't write cache file
       
   221             return false;
       
   222         }
       
   223         $this->properties['cache_lifetime'] = $this->cache_lifetime;
       
   224         $this->properties['unifunc'] = 'content_' . str_replace('.', '_', uniqid('', true));
       
   225         $content = $this->createTemplateCodeFrame($content, true);
       
   226         $_smarty_tpl = $this;
       
   227         eval("?>" . $content);
       
   228         $this->cached->valid = true;
       
   229         $this->cached->processed = true;
       
   230         return $this->cached->write($this, $content);
       
   231     }
       
   232 
       
   233     /**
       
   234      * Template code runtime function to get subtemplate content
       
   235      *
       
   236      * @param string  $template       the resource handle of the template file
       
   237      * @param mixed   $cache_id       cache id to be used with this template
       
   238      * @param mixed   $compile_id     compile id to be used with this template
       
   239      * @param integer $caching        cache mode
       
   240      * @param integer $cache_lifetime life time of cache data
       
   241      * @param array   $vars optional  variables to assign
       
   242      * @param int     $parent_scope   scope in which {include} should execute
       
   243      * @returns string template content
       
   244      */
       
   245     public function getSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope)
       
   246     {
       
   247         // already in template cache?
       
   248         if ($this->smarty->allow_ambiguous_resources) {
       
   249             $_templateId = Smarty_Resource::getUniqueTemplateName($this->smarty, $template) . $cache_id . $compile_id;
       
   250         } else {
       
   251             $_templateId = $this->smarty->joined_template_dir . '#' . $template . $cache_id . $compile_id;
       
   252         }
       
   253 
       
   254         if (isset($_templateId[150])) {
       
   255             $_templateId = sha1($_templateId);
       
   256         }
       
   257         if (isset($this->smarty->template_objects[$_templateId])) {
       
   258             // clone cached template object because of possible recursive call
       
   259             $tpl = clone $this->smarty->template_objects[$_templateId];
       
   260             $tpl->parent = $this;
       
   261             $tpl->caching = $caching;
       
   262             $tpl->cache_lifetime = $cache_lifetime;
       
   263         } else {
       
   264             $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
       
   265         }
       
   266         // get variables from calling scope
       
   267         if ($parent_scope == Smarty::SCOPE_LOCAL) {
       
   268             $tpl->tpl_vars = $this->tpl_vars;
       
   269             $tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
       
   270         } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
       
   271             $tpl->tpl_vars = &$this->tpl_vars;
       
   272         } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
       
   273             $tpl->tpl_vars = &Smarty::$global_tpl_vars;
       
   274         } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
       
   275             $tpl->tpl_vars = &$this->tpl_vars;
       
   276         } else {
       
   277             $tpl->tpl_vars = &$scope_ptr->tpl_vars;
       
   278         }
       
   279         $tpl->config_vars = $this->config_vars;
       
   280         if (!empty($data)) {
       
   281             // set up variable values
       
   282             foreach ($data as $_key => $_val) {
       
   283                 $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
       
   284             }
       
   285         }
       
   286         return $tpl->fetch(null, null, null, null, false, false, true);
       
   287     }
       
   288 
       
   289     /**
       
   290      * Template code runtime function to set up an inline subtemplate
       
   291      *
       
   292      * @param string  $template       the resource handle of the template file
       
   293      * @param mixed   $cache_id       cache id to be used with this template
       
   294      * @param mixed   $compile_id     compile id to be used with this template
       
   295      * @param integer $caching        cache mode
       
   296      * @param integer $cache_lifetime life time of cache data
       
   297      * @param array   $vars optional  variables to assign
       
   298      * @param int     $parent_scope   scope in which {include} should execute
       
   299      * @param string  $hash           nocache hash code
       
   300      * @returns string template content
       
   301      */
       
   302     public function setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash)
       
   303     {
       
   304         $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
       
   305         $tpl->properties['nocache_hash']  = $hash;
       
   306         // get variables from calling scope
       
   307         if ($parent_scope == Smarty::SCOPE_LOCAL ) {
       
   308             $tpl->tpl_vars = $this->tpl_vars;
       
   309             $tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
       
   310         } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
       
   311             $tpl->tpl_vars = &$this->tpl_vars;
       
   312         } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
       
   313             $tpl->tpl_vars = &Smarty::$global_tpl_vars;
       
   314         } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
       
   315             $tpl->tpl_vars = &$this->tpl_vars;
       
   316         } else {
       
   317             $tpl->tpl_vars = &$scope_ptr->tpl_vars;
       
   318         }
       
   319         $tpl->config_vars = $this->config_vars;
       
   320         if (!empty($data)) {
       
   321             // set up variable values
       
   322             foreach ($data as $_key => $_val) {
       
   323                 $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
       
   324             }
       
   325         }
       
   326         return $tpl;
       
   327     }
       
   328 
       
   329 
       
   330     /**
       
   331      * Create code frame for compiled and cached templates
       
   332      *
       
   333      * @param string $content   optional template content
       
   334      * @param bool   $cache     flag for cache file
       
   335      * @return string
       
   336      */
       
   337     public function createTemplateCodeFrame($content = '', $cache = false)
       
   338     {
       
   339         $plugins_string = '';
       
   340         // include code for plugins
       
   341         if (!$cache) {
       
   342             if (!empty($this->required_plugins['compiled'])) {
       
   343                 $plugins_string = '<?php ';
       
   344                 foreach ($this->required_plugins['compiled'] as $tmp) {
       
   345                     foreach ($tmp as $data) {
       
   346                         $file = addslashes($data['file']);
       
   347                         if (is_Array($data['function'])){
       
   348                             $plugins_string .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n";
       
   349                         } else {
       
   350                             $plugins_string .= "if (!is_callable('{$data['function']}')) include '{$file}';\n";
       
   351                         }
       
   352                     }
       
   353                 }
       
   354                 $plugins_string .= '?>';
       
   355             }
       
   356             if (!empty($this->required_plugins['nocache'])) {
       
   357                 $this->has_nocache_code = true;
       
   358                 $plugins_string .= "<?php echo '/*%%SmartyNocache:{$this->properties['nocache_hash']}%%*/<?php \$_smarty = \$_smarty_tpl->smarty; ";
       
   359                 foreach ($this->required_plugins['nocache'] as $tmp) {
       
   360                     foreach ($tmp as $data) {
       
   361                         $file = addslashes($data['file']);
       
   362                         if (is_Array($data['function'])){
       
   363                             $plugins_string .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n");
       
   364                         } else {
       
   365                             $plugins_string .= addslashes("if (!is_callable('{$data['function']}')) include '{$file}';\n");
       
   366                         }
       
   367                     }
       
   368                 }
       
   369                 $plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n";
       
   370             }
       
   371         }
       
   372         // build property code
       
   373         $this->properties['has_nocache_code'] = $this->has_nocache_code;
       
   374         $output = '';
       
   375         if (!$this->source->recompiled) {
       
   376             $output = "<?php /*%%SmartyHeaderCode:{$this->properties['nocache_hash']}%%*/";
       
   377             if ($this->smarty->direct_access_security) {
       
   378                 $output .= "if(!defined('SMARTY_DIR')) exit('no direct access allowed');\n";
       
   379             }
       
   380         }
       
   381         if ($cache) {
       
   382             // remove compiled code of{function} definition
       
   383             unset($this->properties['function']);
       
   384             if (!empty($this->smarty->template_functions)) {
       
   385                 // copy code of {function} tags called in nocache mode
       
   386                 foreach ($this->smarty->template_functions as $name => $function_data) {
       
   387                     if (isset($function_data['called_nocache'])) {
       
   388                         foreach ($function_data['called_functions'] as $func_name) {
       
   389                             $this->smarty->template_functions[$func_name]['called_nocache'] = true;
       
   390                         }
       
   391                     }
       
   392                 }
       
   393                  foreach ($this->smarty->template_functions as $name => $function_data) {
       
   394                     if (isset($function_data['called_nocache'])) {
       
   395                         unset($function_data['called_nocache'], $function_data['called_functions'], $this->smarty->template_functions[$name]['called_nocache']);
       
   396                         $this->properties['function'][$name] = $function_data;
       
   397                     }
       
   398                 }
       
   399             }
       
   400         }
       
   401         $this->properties['version'] = Smarty::SMARTY_VERSION;
       
   402         if (!isset($this->properties['unifunc'])) {
       
   403             $this->properties['unifunc'] = 'content_' . str_replace('.', '_', uniqid('', true));
       
   404         }
       
   405         if (!$this->source->recompiled) {
       
   406             $output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . ',' . ($cache ? 'true' : 'false') . "); /*/%%SmartyHeaderCode%%*/?>\n";
       
   407             $output .= '<?php if ($_valid && !is_callable(\'' . $this->properties['unifunc'] . '\')) {function ' . $this->properties['unifunc'] . '($_smarty_tpl) {?>';
       
   408         }
       
   409         $output .= $plugins_string;
       
   410         $output .= $content;
       
   411         if (!$this->source->recompiled) {
       
   412             $output .= '<?php }} ?>';
       
   413         }
       
   414         return $output;
       
   415     }
       
   416 
       
   417     /**
       
   418      * This function is executed automatically when a compiled or cached template file is included
       
   419      *
       
   420      * - Decode saved properties from compiled template and cache files
       
   421      * - Check if compiled or cache file is valid
       
   422      *
       
   423      * @param array $properties     special template properties
       
   424      * @param bool  $cache          flag if called from cache file
       
   425      * @return bool                 flag if compiled or cache file is valid
       
   426      */
       
   427     public function decodeProperties($properties, $cache = false)
       
   428     {
       
   429         $this->has_nocache_code = $properties['has_nocache_code'];
       
   430         $this->properties['nocache_hash'] = $properties['nocache_hash'];
       
   431         if (isset($properties['cache_lifetime'])) {
       
   432             $this->properties['cache_lifetime'] = $properties['cache_lifetime'];
       
   433         }
       
   434         if (isset($properties['file_dependency'])) {
       
   435             $this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']);
       
   436         }
       
   437         if (!empty($properties['function'])) {
       
   438             $this->properties['function'] = array_merge($this->properties['function'], $properties['function']);
       
   439             $this->smarty->template_functions = array_merge($this->smarty->template_functions, $properties['function']);
       
   440         }
       
   441         $this->properties['version'] = (isset($properties['version'])) ? $properties['version'] : '';
       
   442         $this->properties['unifunc'] = $properties['unifunc'];
       
   443         // check file dependencies at compiled code
       
   444         $is_valid = true;
       
   445         if ($this->properties['version'] != Smarty::SMARTY_VERSION) {
       
   446             $is_valid = false;
       
   447         } else if (((!$cache && $this->smarty->compile_check && empty($this->compiled->_properties) && !$this->compiled->isCompiled) || $cache && ($this->smarty->compile_check === true || $this->smarty->compile_check === Smarty::COMPILECHECK_ON)) && !empty($this->properties['file_dependency'])) {
       
   448             foreach ($this->properties['file_dependency'] as $_file_to_check) {
       
   449                 if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') {
       
   450                     if ($this->source->filepath == $_file_to_check[0] && isset($this->source->timestamp)) {
       
   451                         // do not recheck current template
       
   452                         $mtime = $this->source->timestamp;
       
   453                     } else {
       
   454                         // file and php types can be checked without loading the respective resource handlers
       
   455                         $mtime = @filemtime($_file_to_check[0]);
       
   456                     }
       
   457                 } elseif ($_file_to_check[2] == 'string') {
       
   458                     continue;
       
   459                 } else {
       
   460                     $source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]);
       
   461                     $mtime = $source->timestamp;
       
   462                 }
       
   463                 if (!$mtime || $mtime > $_file_to_check[1]) {
       
   464                     $is_valid = false;
       
   465                     break;
       
   466                 }
       
   467             }
       
   468         }
       
   469         if ($cache) {
       
   470             $this->cached->valid = $is_valid;
       
   471         } else {
       
   472             $this->mustCompile = !$is_valid;
       
   473         }
       
   474         // store data in reusable Smarty_Template_Compiled
       
   475         if (!$cache) {
       
   476             $this->compiled->_properties = $properties;
       
   477         }
       
   478         return $is_valid;
       
   479     }
       
   480 
       
   481     /**
       
   482      * Template code runtime function to create a local Smarty variable for array assignments
       
   483      *
       
   484      * @param string $tpl_var   tempate variable name
       
   485      * @param bool   $nocache   cache mode of variable
       
   486      * @param int    $scope     scope of variable
       
   487      */
       
   488     public function createLocalArrayVariable($tpl_var, $nocache = false, $scope = Smarty::SCOPE_LOCAL)
       
   489     {
       
   490         if (!isset($this->tpl_vars[$tpl_var])) {
       
   491             $this->tpl_vars[$tpl_var] = new Smarty_variable(array(), $nocache, $scope);
       
   492         } else {
       
   493             $this->tpl_vars[$tpl_var] = clone $this->tpl_vars[$tpl_var];
       
   494             if ($scope != Smarty::SCOPE_LOCAL) {
       
   495                 $this->tpl_vars[$tpl_var]->scope = $scope;
       
   496             }
       
   497             if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
       
   498                 settype($this->tpl_vars[$tpl_var]->value, 'array');
       
   499             }
       
   500         }
       
   501     }
       
   502 
       
   503     /**
       
   504      * Template code runtime function to get pointer to template variable array of requested scope
       
   505      *
       
   506      * @param int $scope    requested variable scope
       
   507      * @return array        array of template variables
       
   508      */
       
   509     public function &getScope($scope)
       
   510     {
       
   511         if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
       
   512             return $this->parent->tpl_vars;
       
   513         } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
       
   514             $ptr = $this->parent;
       
   515             while (!empty($ptr->parent)) {
       
   516                 $ptr = $ptr->parent;
       
   517             }
       
   518             return $ptr->tpl_vars;
       
   519         } elseif ($scope == Smarty::SCOPE_GLOBAL) {
       
   520             return Smarty::$global_tpl_vars;
       
   521         }
       
   522         $null = null;
       
   523         return $null;
       
   524     }
       
   525 
       
   526     /**
       
   527      * Get parent or root of template parent chain
       
   528      *
       
   529      * @param int $scope    pqrent or root scope
       
   530      * @return mixed object
       
   531      */
       
   532     public function getScopePointer($scope)
       
   533     {
       
   534         if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
       
   535             return $this->parent;
       
   536         } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
       
   537             $ptr = $this->parent;
       
   538             while (!empty($ptr->parent)) {
       
   539                 $ptr = $ptr->parent;
       
   540             }
       
   541             return $ptr;
       
   542         }
       
   543         return null;
       
   544     }
       
   545 
       
   546     /**
       
   547      * [util function] counts an array, arrayaccess/traversable or PDOStatement object
       
   548      *
       
   549      * @param mixed $value
       
   550      * @return int the count for arrays and objects that implement countable, 1 for other objects that don't, and 0 for empty elements
       
   551      */
       
   552     public function _count($value)
       
   553     {
       
   554         if (is_array($value) === true || $value instanceof Countable) {
       
   555             return count($value);
       
   556         } elseif ($value instanceof IteratorAggregate) {
       
   557             // Note: getIterator() returns a Traversable, not an Iterator
       
   558             // thus rewind() and valid() methods may not be present
       
   559             return iterator_count($value->getIterator());
       
   560         } elseif ($value instanceof Iterator) {
       
   561             return iterator_count($value);
       
   562         } elseif ($value instanceof PDOStatement) {
       
   563             return $value->rowCount();
       
   564         } elseif ($value instanceof Traversable) {
       
   565             return iterator_count($value);
       
   566         } elseif ($value instanceof ArrayAccess) {
       
   567             if ($value->offsetExists(0)) {
       
   568                 return 1;
       
   569             }
       
   570         } elseif (is_object($value)) {
       
   571             return count($value);
       
   572         }
       
   573         return 0;
       
   574     }
       
   575 
       
   576     /**
       
   577      * runtime error not matching capture tags
       
   578      *
       
   579      */
       
   580     public function capture_error()
       
   581     {
       
   582         throw new SmartyException("Not matching {capture} open/close in \"{$this->template_resource}\"");
       
   583     }
       
   584 
       
   585     /**
       
   586     * Empty cache for this template
       
   587     *
       
   588     * @param integer $exp_time      expiration time
       
   589     * @return integer number of cache files deleted
       
   590     */
       
   591     public function clearCache($exp_time=null)
       
   592     {
       
   593         Smarty_CacheResource::invalidLoadedCache($this->smarty);
       
   594         return $this->cached->handler->clear($this->smarty, $this->template_name, $this->cache_id, $this->compile_id, $exp_time);
       
   595     }
       
   596 
       
   597      /**
       
   598      * set Smarty property in template context
       
   599      *
       
   600      * @param string $property_name property name
       
   601      * @param mixed  $value         value
       
   602      */
       
   603     public function __set($property_name, $value)
       
   604     {
       
   605         switch ($property_name) {
       
   606             case 'source':
       
   607             case 'compiled':
       
   608             case 'cached':
       
   609             case 'compiler':
       
   610                 $this->$property_name = $value;
       
   611                 return;
       
   612 
       
   613             // FIXME: routing of template -> smarty attributes
       
   614             default:
       
   615                 if (property_exists($this->smarty, $property_name)) {
       
   616                     $this->smarty->$property_name = $value;
       
   617                     return;
       
   618                 }
       
   619         }
       
   620 
       
   621         throw new SmartyException("invalid template property '$property_name'.");
       
   622     }
       
   623 
       
   624     /**
       
   625      * get Smarty property in template context
       
   626      *
       
   627      * @param string $property_name property name
       
   628      */
       
   629     public function __get($property_name)
       
   630     {
       
   631         switch ($property_name) {
       
   632             case 'source':
       
   633                 if (strlen($this->template_resource) == 0) {
       
   634                     throw new SmartyException('Missing template name');
       
   635                 }
       
   636                 $this->source = Smarty_Resource::source($this);
       
   637                 // cache template object under a unique ID
       
   638                 // do not cache eval resources
       
   639                 if ($this->source->type != 'eval') {
       
   640                     if ($this->smarty->allow_ambiguous_resources) {
       
   641                         $_templateId = $this->source->unique_resource . $this->cache_id . $this->compile_id;
       
   642                     } else {
       
   643                         $_templateId = $this->smarty->joined_template_dir . '#' . $this->template_resource . $this->cache_id . $this->compile_id;
       
   644                     }
       
   645 
       
   646                     if (isset($_templateId[150])) {
       
   647                         $_templateId = sha1($_templateId);
       
   648                     }
       
   649                     $this->smarty->template_objects[$_templateId] = $this;
       
   650                 }
       
   651                 return $this->source;
       
   652 
       
   653             case 'compiled':
       
   654                 $this->compiled = $this->source->getCompiled($this);
       
   655                 return $this->compiled;
       
   656 
       
   657             case 'cached':
       
   658                 if (!class_exists('Smarty_Template_Cached')) {
       
   659                     include SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php';
       
   660                 }
       
   661                 $this->cached = new Smarty_Template_Cached($this);
       
   662                 return $this->cached;
       
   663 
       
   664             case 'compiler':
       
   665                 $this->smarty->loadPlugin($this->source->compiler_class);
       
   666                 $this->compiler = new $this->source->compiler_class($this->source->template_lexer_class, $this->source->template_parser_class, $this->smarty);
       
   667                 return $this->compiler;
       
   668 
       
   669             // FIXME: routing of template -> smarty attributes
       
   670             default:
       
   671                 if (property_exists($this->smarty, $property_name)) {
       
   672                     return $this->smarty->$property_name;
       
   673                 }
       
   674         }
       
   675 
       
   676         throw new SmartyException("template property '$property_name' does not exist.");
       
   677     }
       
   678 
       
   679     /**
       
   680      * Template data object destrutor
       
   681      *
       
   682      */
       
   683     public function __destruct()
       
   684     {
       
   685         if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
       
   686             $this->cached->handler->releaseLock($this->smarty, $this->cached);
       
   687         }
       
   688     }
       
   689 
       
   690 }
       
   691 
       
   692 ?>