vendor/smarty/smarty/libs/sysplugins/smarty_internal_template.php line 216

  1. <?php
  2. /**
  3.  * Smarty Internal Plugin Template
  4.  * This file contains the Smarty template engine
  5.  *
  6.  * @package    Smarty
  7.  * @subpackage Template
  8.  * @author     Uwe Tews
  9.  */
  10. /**
  11.  * Main class with template data structures and methods
  12.  *
  13.  * @package    Smarty
  14.  * @subpackage Template
  15.  *
  16.  * @property Smarty_Template_Compiled             $compiled
  17.  * @property Smarty_Template_Cached               $cached
  18.  * @property Smarty_Internal_TemplateCompilerBase $compiler
  19.  * @property mixed|\Smarty_Template_Cached        registered_plugins
  20.  *
  21.  * The following methods will be dynamically loaded by the extension handler when they are called.
  22.  * They are located in a corresponding Smarty_Internal_Method_xxxx class
  23.  *
  24.  * @method bool mustCompile()
  25.  */
  26. class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
  27. {
  28.     /**
  29.      * Template object cache
  30.      *
  31.      * @var Smarty_Internal_Template[]
  32.      */
  33.     public static $tplObjCache = array();
  34.     /**
  35.      * Template object cache for Smarty::isCached() === true
  36.      *
  37.      * @var Smarty_Internal_Template[]
  38.      */
  39.     public static $isCacheTplObj = array();
  40.     /**
  41.      * Sub template Info Cache
  42.      * - index name
  43.      * - value use count
  44.      *
  45.      * @var int[]
  46.      */
  47.     public static $subTplInfo = array();
  48.     /**
  49.      * This object type (Smarty = 1, template = 2, data = 4)
  50.      *
  51.      * @var int
  52.      */
  53.     public $_objType 2;
  54.     /**
  55.      * Global smarty instance
  56.      *
  57.      * @var Smarty
  58.      */
  59.     public $smarty null;
  60.     /**
  61.      * Source instance
  62.      *
  63.      * @var Smarty_Template_Source|Smarty_Template_Config
  64.      */
  65.     public $source null;
  66.     /**
  67.      * Inheritance runtime extension
  68.      *
  69.      * @var Smarty_Internal_Runtime_Inheritance
  70.      */
  71.     public $inheritance null;
  72.     /**
  73.      * Template resource
  74.      *
  75.      * @var string
  76.      */
  77.     public $template_resource null;
  78.     /**
  79.      * flag if compiled template is invalid and must be (re)compiled
  80.      *
  81.      * @var bool
  82.      */
  83.     public $mustCompile null;
  84.     /**
  85.      * Template Id
  86.      *
  87.      * @var null|string
  88.      */
  89.     public $templateId null;
  90.     /**
  91.      * Scope in which variables shall be assigned
  92.      *
  93.      * @var int
  94.      */
  95.     public $scope 0;
  96.     /**
  97.      * Flag which is set while rending a cache file
  98.      *
  99.      * @var bool
  100.      */
  101.     public $isRenderingCache false;
  102.     /**
  103.      * Callbacks called before rendering template
  104.      *
  105.      * @var callback[]
  106.      */
  107.     public $startRenderCallbacks = array();
  108.     /**
  109.      * Callbacks called after rendering template
  110.      *
  111.      * @var callback[]
  112.      */
  113.     public $endRenderCallbacks = array();
  114.     /**
  115.      * Create template data object
  116.      * Some of the global Smarty settings copied to template scope
  117.      * It load the required template resources and caching plugins
  118.      *
  119.      * @param string                                                       $template_resource template resource string
  120.      * @param Smarty                                                       $smarty            Smarty instance
  121.      * @param null|\Smarty_Internal_Template|\Smarty|\Smarty_Internal_Data $_parent           back pointer to parent
  122.      *                                                                                        object with variables or
  123.      *                                                                                        null
  124.      * @param mixed                                                        $_cache_id         cache   id or null
  125.      * @param mixed                                                        $_compile_id       compile id or null
  126.      * @param bool|int|null                                                $_caching          use caching?
  127.      * @param int|null                                                     $_cache_lifetime   cache life-time in
  128.      *                                                                                        seconds
  129.      * @param bool                                                         $_isConfig
  130.      *
  131.      * @throws \SmartyException
  132.      */
  133.     public function __construct(
  134.         $template_resource,
  135.         Smarty $smarty,
  136.         Smarty_Internal_Data $_parent null,
  137.         $_cache_id null,
  138.         $_compile_id null,
  139.         $_caching null,
  140.         $_cache_lifetime null,
  141.         $_isConfig false
  142.     ) {
  143.         $this->smarty $smarty;
  144.         // Smarty parameter
  145.         $this->cache_id $_cache_id === null $this->smarty->cache_id $_cache_id;
  146.         $this->compile_id $_compile_id === null $this->smarty->compile_id $_compile_id;
  147.         $this->caching = (int)($_caching === null $this->smarty->caching $_caching);
  148.         $this->cache_lifetime $_cache_lifetime === null $this->smarty->cache_lifetime $_cache_lifetime;
  149.         $this->compile_check = (int)$smarty->compile_check;
  150.         $this->parent $_parent;
  151.         // Template resource
  152.         $this->template_resource $template_resource;
  153.         $this->source $_isConfig Smarty_Template_Config::load($this) : Smarty_Template_Source::load($this);
  154.         parent::__construct();
  155.         if ($smarty->security_policy && method_exists($smarty->security_policy'registerCallBacks')) {
  156.             $smarty->security_policy->registerCallBacks($this);
  157.         }
  158.     }
  159.     /**
  160.      * render template
  161.      *
  162.      * @param bool      $no_output_filter if true do not run output filter
  163.      * @param null|bool $display          true: display, false: fetch null: sub-template
  164.      *
  165.      * @return string
  166.      * @throws \Exception
  167.      * @throws \SmartyException
  168.      */
  169.     public function render($no_output_filter true$display null)
  170.     {
  171.         if ($this->smarty->debugging) {
  172.             if (!isset($this->smarty->_debug)) {
  173.                 $this->smarty->_debug = new Smarty_Internal_Debug();
  174.             }
  175.             $this->smarty->_debug->start_template($this$display);
  176.         }
  177.         // checks if template exists
  178.         if (!$this->source->exists) {
  179.             throw new SmartyException(
  180.                 "Unable to load template '{$this->source->type}:{$this->source->name}'" .
  181.                 ($this->_isSubTpl() ? " in '{$this->parent->template_resource}'" '')
  182.             );
  183.         }
  184.         // disable caching for evaluated code
  185.         if ($this->source->handler->recompiled) {
  186.             $this->caching Smarty::CACHING_OFF;
  187.         }
  188.         // read from cache or render
  189.         if ($this->caching === Smarty::CACHING_LIFETIME_CURRENT || $this->caching === Smarty::CACHING_LIFETIME_SAVED) {
  190.             if (!isset($this->cached) || $this->cached->cache_id !== $this->cache_id
  191.                 || $this->cached->compile_id !== $this->compile_id
  192.             ) {
  193.                 $this->loadCached(true);
  194.             }
  195.             $this->cached->render($this$no_output_filter);
  196.         } else {
  197.             if (!isset($this->compiled) || $this->compiled->compile_id !== $this->compile_id) {
  198.                 $this->loadCompiled(true);
  199.             }
  200.             $this->compiled->render($this);
  201.         }
  202.         // display or fetch
  203.         if ($display) {
  204.             if ($this->caching && $this->smarty->cache_modified_check) {
  205.                 $this->smarty->ext->_cacheModify->cacheModifiedCheck(
  206.                     $this->cached,
  207.                     $this,
  208.                     isset($content) ? $content ob_get_clean()
  209.                 );
  210.             } else {
  211.                 if ((!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled)
  212.                     && !$no_output_filter && (isset($this->smarty->autoload_filters'output' ])
  213.                                               || isset($this->smarty->registered_filters'output' ]))
  214.                 ) {
  215.                     echo $this->smarty->ext->_filterHandler->runFilter('output'ob_get_clean(), $this);
  216.                 } else {
  217.                     echo ob_get_clean();
  218.                 }
  219.             }
  220.             if ($this->smarty->debugging) {
  221.                 $this->smarty->_debug->end_template($this);
  222.                 // debug output
  223.                 $this->smarty->_debug->display_debug($thistrue);
  224.             }
  225.             return '';
  226.         } else {
  227.             if ($this->smarty->debugging) {
  228.                 $this->smarty->_debug->end_template($this);
  229.                 if ($this->smarty->debugging === && $display === false) {
  230.                     $this->smarty->_debug->display_debug($thistrue);
  231.                 }
  232.             }
  233.             if (!$no_output_filter
  234.                 && (!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled)
  235.                 && (isset($this->smarty->autoload_filters'output' ])
  236.                     || isset($this->smarty->registered_filters'output' ]))
  237.             ) {
  238.                 return $this->smarty->ext->_filterHandler->runFilter('output'ob_get_clean(), $this);
  239.             }
  240.             // return cache content
  241.             return null;
  242.         }
  243.     }
  244.     /**
  245.      * Runtime function to render sub-template
  246.      *
  247.      * @param string  $template       template name
  248.      * @param mixed   $cache_id       cache id
  249.      * @param mixed   $compile_id     compile id
  250.      * @param integer $caching        cache mode
  251.      * @param integer $cache_lifetime life time of cache data
  252.      * @param array   $data           passed parameter template variables
  253.      * @param int     $scope          scope in which {include} should execute
  254.      * @param bool    $forceTplCache  cache template object
  255.      * @param string  $uid            file dependency uid
  256.      * @param string  $content_func   function name
  257.      *
  258.      * @throws \Exception
  259.      * @throws \SmartyException
  260.      */
  261.     public function _subTemplateRender(
  262.         $template,
  263.         $cache_id,
  264.         $compile_id,
  265.         $caching,
  266.         $cache_lifetime,
  267.         $data,
  268.         $scope,
  269.         $forceTplCache,
  270.         $uid null,
  271.         $content_func null
  272.     ) {
  273.         $tpl = clone $this;
  274.         $tpl->parent $this;
  275.         $smarty = &$this->smarty;
  276.         $_templateId $smarty->_getTemplateId($template$cache_id$compile_id$caching$tpl);
  277.         // recursive call ?
  278.         if (isset($tpl->templateId) ? $tpl->templateId $tpl->_getTemplateId() !== $_templateId) {
  279.             // already in template cache?
  280.             if (isset(self::$tplObjCache$_templateId ])) {
  281.                 // copy data from cached object
  282.                 $cachedTpl = &self::$tplObjCache$_templateId ];
  283.                 $tpl->templateId $cachedTpl->templateId;
  284.                 $tpl->template_resource $cachedTpl->template_resource;
  285.                 $tpl->cache_id $cachedTpl->cache_id;
  286.                 $tpl->compile_id $cachedTpl->compile_id;
  287.                 $tpl->source $cachedTpl->source;
  288.                 if (isset($cachedTpl->compiled)) {
  289.                     $tpl->compiled $cachedTpl->compiled;
  290.                 } else {
  291.                     unset($tpl->compiled);
  292.                 }
  293.                 if ($caching !== 9999 && isset($cachedTpl->cached)) {
  294.                     $tpl->cached $cachedTpl->cached;
  295.                 } else {
  296.                     unset($tpl->cached);
  297.                 }
  298.             } else {
  299.                 $tpl->templateId $_templateId;
  300.                 $tpl->template_resource $template;
  301.                 $tpl->cache_id $cache_id;
  302.                 $tpl->compile_id $compile_id;
  303.                 if (isset($uid)) {
  304.                     // for inline templates we can get all resource information from file dependency
  305.                     list($filepath$timestamp$type) = $tpl->compiled->file_dependency$uid ];
  306.                     $tpl->source = new Smarty_Template_Source($smarty$filepath$type$filepath);
  307.                     $tpl->source->filepath $filepath;
  308.                     $tpl->source->timestamp $timestamp;
  309.                     $tpl->source->exists true;
  310.                     $tpl->source->uid $uid;
  311.                 } else {
  312.                     $tpl->source Smarty_Template_Source::load($tpl);
  313.                     unset($tpl->compiled);
  314.                 }
  315.                 if ($caching !== 9999) {
  316.                     unset($tpl->cached);
  317.                 }
  318.             }
  319.         } else {
  320.             // on recursive calls force caching
  321.             $forceTplCache true;
  322.         }
  323.         $tpl->caching $caching;
  324.         $tpl->cache_lifetime $cache_lifetime;
  325.         // set template scope
  326.         $tpl->scope $scope;
  327.         if (!isset(self::$tplObjCache$tpl->templateId ]) && !$tpl->source->handler->recompiled) {
  328.             // check if template object should be cached
  329.             if ($forceTplCache || (isset(self::$subTplInfo$tpl->template_resource ])
  330.                                    && self::$subTplInfo$tpl->template_resource ] > 1)
  331.                 || ($tpl->_isSubTpl() && isset(self::$tplObjCache$tpl->parent->templateId ]))
  332.             ) {
  333.                 self::$tplObjCache$tpl->templateId ] = $tpl;
  334.             }
  335.         }
  336.         if (!empty($data)) {
  337.             // set up variable values
  338.             foreach ($data as $_key => $_val) {
  339.                 $tpl->tpl_vars$_key ] = new Smarty_Variable($_val$this->isRenderingCache);
  340.             }
  341.         }
  342.         if ($tpl->caching === 9999) {
  343.             if (!isset($tpl->compiled)) {
  344.                 $this->loadCompiled(true);
  345.             }
  346.             if ($tpl->compiled->has_nocache_code) {
  347.                 $this->cached->hashes$tpl->compiled->nocache_hash ] = true;
  348.             }
  349.         }
  350.         $tpl->_cache = array();
  351.         if (isset($uid)) {
  352.             if ($smarty->debugging) {
  353.                 if (!isset($smarty->_debug)) {
  354.                     $smarty->_debug = new Smarty_Internal_Debug();
  355.                 }
  356.                 $smarty->_debug->start_template($tpl);
  357.                 $smarty->_debug->start_render($tpl);
  358.             }
  359.             $tpl->compiled->getRenderedTemplateCode($tpl$content_func);
  360.             if ($smarty->debugging) {
  361.                 $smarty->_debug->end_template($tpl);
  362.                 $smarty->_debug->end_render($tpl);
  363.             }
  364.         } else {
  365.             if (isset($tpl->compiled)) {
  366.                 $tpl->compiled->render($tpl);
  367.             } else {
  368.                 $tpl->render();
  369.             }
  370.         }
  371.     }
  372.     /**
  373.      * Get called sub-templates and save call count
  374.      */
  375.     public function _subTemplateRegister()
  376.     {
  377.         foreach ($this->compiled->includes as $name => $count) {
  378.             if (isset(self::$subTplInfo$name ])) {
  379.                 self::$subTplInfo$name ] += $count;
  380.             } else {
  381.                 self::$subTplInfo$name ] = $count;
  382.             }
  383.         }
  384.     }
  385.     /**
  386.      * Check if this is a sub template
  387.      *
  388.      * @return bool true is sub template
  389.      */
  390.     public function _isSubTpl()
  391.     {
  392.         return isset($this->parent) && $this->parent->_isTplObj();
  393.     }
  394.     /**
  395.      * Assign variable in scope
  396.      *
  397.      * @param string $varName variable name
  398.      * @param mixed  $value   value
  399.      * @param bool   $nocache nocache flag
  400.      * @param int    $scope   scope into which variable shall be assigned
  401.      */
  402.     public function _assignInScope($varName$value$nocache false$scope 0)
  403.     {
  404.         if (isset($this->tpl_vars$varName ])) {
  405.             $this->tpl_vars$varName ] = clone $this->tpl_vars$varName ];
  406.             $this->tpl_vars$varName ]->value $value;
  407.             if ($nocache || $this->isRenderingCache) {
  408.                 $this->tpl_vars$varName ]->nocache true;
  409.             }
  410.         } else {
  411.             $this->tpl_vars$varName ] = new Smarty_Variable($value$nocache || $this->isRenderingCache);
  412.         }
  413.         if ($scope >= 0) {
  414.             if ($scope || $this->scope 0) {
  415.                 $this->smarty->ext->_updateScope->_updateScope($this$varName$scope);
  416.             }
  417.         }
  418.     }
  419.     /**
  420.      * Check if plugins are callable require file otherwise
  421.      *
  422.      * @param array $plugins required plugins
  423.      *
  424.      * @throws \SmartyException
  425.      */
  426.     public function _checkPlugins($plugins)
  427.     {
  428.         static $checked = array();
  429.         foreach ($plugins as $plugin) {
  430.             $name join('::', (array)$plugin'function' ]);
  431.             if (!isset($checked$name ])) {
  432.                 if (!is_callable($plugin'function' ])) {
  433.                     if (is_file($plugin'file' ])) {
  434.                         include_once $plugin'file' ];
  435.                         if (is_callable($plugin'function' ])) {
  436.                             $checked$name ] = true;
  437.                         }
  438.                     }
  439.                 } else {
  440.                     $checked$name ] = true;
  441.                 }
  442.             }
  443.             if (!isset($checked$name ])) {
  444.                 if (false !== $this->smarty->loadPlugin($name)) {
  445.                     $checked$name ] = true;
  446.                 } else {
  447.                     throw new SmartyException("Plugin '{$name}' not callable");
  448.                 }
  449.             }
  450.         }
  451.     }
  452.     /**
  453.      * This function is executed automatically when a compiled or cached template file is included
  454.      * - Decode saved properties from compiled template and cache files
  455.      * - Check if compiled or cache file is valid
  456.      *
  457.      * @param \Smarty_Internal_Template $tpl
  458.      * @param array                     $properties special template properties
  459.      * @param bool                      $cache      flag if called from cache file
  460.      *
  461.      * @return bool flag if compiled or cache file is valid
  462.      * @throws \SmartyException
  463.      */
  464.     public function _decodeProperties(Smarty_Internal_Template $tpl$properties$cache false)
  465.     {
  466.         // on cache resources other than file check version stored in cache code
  467.         if (!isset($properties'version' ]) || Smarty::SMARTY_VERSION !== $properties'version' ]) {
  468.             if ($cache) {
  469.                 $tpl->smarty->clearAllCache();
  470.             } else {
  471.                 $tpl->smarty->clearCompiledTemplate();
  472.             }
  473.             return false;
  474.         }
  475.         $is_valid true;
  476.         if (!empty($properties'file_dependency' ])
  477.             && ((!$cache && $tpl->compile_check) || $tpl->compile_check === Smarty::COMPILECHECK_ON)
  478.         ) {
  479.             // check file dependencies at compiled code
  480.             foreach ($properties'file_dependency' ] as $_file_to_check) {
  481.                 if ($_file_to_check] === 'file' || $_file_to_check] === 'php') {
  482.                     if ($tpl->source->filepath === $_file_to_check]) {
  483.                         // do not recheck current template
  484.                         continue;
  485.                         //$mtime = $tpl->source->getTimeStamp();
  486.                     } else {
  487.                         // file and php types can be checked without loading the respective resource handlers
  488.                         $mtime is_file($_file_to_check]) ? filemtime($_file_to_check]) : false;
  489.                     }
  490.                 } else {
  491.                     $handler Smarty_Resource::load($tpl->smarty$_file_to_check]);
  492.                     if ($handler->checkTimestamps()) {
  493.                         $source Smarty_Template_Source::load($tpl$tpl->smarty$_file_to_check]);
  494.                         $mtime $source->getTimeStamp();
  495.                     } else {
  496.                         continue;
  497.                     }
  498.                 }
  499.                 if ($mtime === false || $mtime $_file_to_check]) {
  500.                     $is_valid false;
  501.                     break;
  502.                 }
  503.             }
  504.         }
  505.         if ($cache) {
  506.             // CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
  507.             if ($tpl->caching === Smarty::CACHING_LIFETIME_SAVED && $properties'cache_lifetime' ] >= 0
  508.                 && (time() > ($tpl->cached->timestamp $properties'cache_lifetime' ]))
  509.             ) {
  510.                 $is_valid false;
  511.             }
  512.             $tpl->cached->cache_lifetime $properties'cache_lifetime' ];
  513.             $tpl->cached->valid $is_valid;
  514.             $resource $tpl->cached;
  515.         } else {
  516.             $tpl->mustCompile = !$is_valid;
  517.             $resource $tpl->compiled;
  518.             $resource->includes = isset($properties'includes' ]) ? $properties'includes' ] : array();
  519.         }
  520.         if ($is_valid) {
  521.             $resource->unifunc $properties'unifunc' ];
  522.             $resource->has_nocache_code $properties'has_nocache_code' ];
  523.             //            $tpl->compiled->nocache_hash = $properties['nocache_hash'];
  524.             $resource->file_dependency $properties'file_dependency' ];
  525.         }
  526.         return $is_valid && !function_exists($properties'unifunc' ]);
  527.     }
  528.     /**
  529.      * Compiles the template
  530.      * If the template is not evaluated the compiled template is saved on disk
  531.      *
  532.      * @throws \Exception
  533.      */
  534.     public function compileTemplateSource()
  535.     {
  536.         return $this->compiled->compileTemplateSource($this);
  537.     }
  538.     /**
  539.      * Writes the content to cache resource
  540.      *
  541.      * @param string $content
  542.      *
  543.      * @return bool
  544.      */
  545.     public function writeCachedContent($content)
  546.     {
  547.         return $this->smarty->ext->_updateCache->writeCachedContent($this$content);
  548.     }
  549.     /**
  550.      * Get unique template id
  551.      *
  552.      * @return string
  553.      * @throws \SmartyException
  554.      */
  555.     public function _getTemplateId()
  556.     {
  557.         return isset($this->templateId) ? $this->templateId $this->templateId =
  558.             $this->smarty->_getTemplateId($this->template_resource$this->cache_id$this->compile_id);
  559.     }
  560.     /**
  561.      * runtime error not matching capture tags
  562.      *
  563.      * @throws \SmartyException
  564.      */
  565.     public function capture_error()
  566.     {
  567.         throw new SmartyException("Not matching {capture} open/close in '{$this->template_resource}'");
  568.     }
  569.     /**
  570.      * Load compiled object
  571.      *
  572.      * @param bool $force force new compiled object
  573.      */
  574.     public function loadCompiled($force false)
  575.     {
  576.         if ($force || !isset($this->compiled)) {
  577.             $this->compiled Smarty_Template_Compiled::load($this);
  578.         }
  579.     }
  580.     /**
  581.      * Load cached object
  582.      *
  583.      * @param bool $force force new cached object
  584.      */
  585.     public function loadCached($force false)
  586.     {
  587.         if ($force || !isset($this->cached)) {
  588.             $this->cached Smarty_Template_Cached::load($this);
  589.         }
  590.     }
  591.     /**
  592.      * Load inheritance object
  593.      */
  594.     public function _loadInheritance()
  595.     {
  596.         if (!isset($this->inheritance)) {
  597.             $this->inheritance = new Smarty_Internal_Runtime_Inheritance();
  598.         }
  599.     }
  600.     /**
  601.      * Unload inheritance object
  602.      */
  603.     public function _cleanUp()
  604.     {
  605.         $this->startRenderCallbacks = array();
  606.         $this->endRenderCallbacks = array();
  607.         $this->inheritance null;
  608.     }
  609.     /**
  610.      * Load compiler object
  611.      *
  612.      * @throws \SmartyException
  613.      */
  614.     public function loadCompiler()
  615.     {
  616.         if (!class_exists($this->source->compiler_class)) {
  617.             $this->smarty->loadPlugin($this->source->compiler_class);
  618.         }
  619.         $this->compiler =
  620.             new $this->source->compiler_class(
  621.                 $this->source->template_lexer_class,
  622.                 $this->source->template_parser_class,
  623.                 $this->smarty
  624.             );
  625.     }
  626.     /**
  627.      * Handle unknown class methods
  628.      *
  629.      * @param string $name unknown method-name
  630.      * @param array  $args argument array
  631.      *
  632.      * @return mixed
  633.      */
  634.     public function __call($name$args)
  635.     {
  636.         // method of Smarty object?
  637.         if (method_exists($this->smarty$name)) {
  638.             return call_user_func_array(array($this->smarty$name), $args);
  639.         }
  640.         // parent
  641.         return parent::__call($name$args);
  642.     }
  643.     /**
  644.      * get Smarty property in template context
  645.      *
  646.      * @param string $property_name property name
  647.      *
  648.      * @return mixed|Smarty_Template_Cached
  649.      * @throws SmartyException
  650.      */
  651.     public function __get($property_name)
  652.     {
  653.         switch ($property_name) {
  654.             case 'compiled':
  655.                 $this->loadCompiled();
  656.                 return $this->compiled;
  657.             case 'cached':
  658.                 $this->loadCached();
  659.                 return $this->cached;
  660.             case 'compiler':
  661.                 $this->loadCompiler();
  662.                 return $this->compiler;
  663.             default:
  664.                 // Smarty property ?
  665.                 if (property_exists($this->smarty$property_name)) {
  666.                     return $this->smarty->$property_name;
  667.                 }
  668.         }
  669.         throw new SmartyException("template property '$property_name' does not exist.");
  670.     }
  671.     /**
  672.      * set Smarty property in template context
  673.      *
  674.      * @param string $property_name property name
  675.      * @param mixed  $value         value
  676.      *
  677.      * @throws SmartyException
  678.      */
  679.     public function __set($property_name$value)
  680.     {
  681.         switch ($property_name) {
  682.             case 'compiled':
  683.             case 'cached':
  684.             case 'compiler':
  685.                 $this->$property_name $value;
  686.                 return;
  687.             default:
  688.                 // Smarty property ?
  689.                 if (property_exists($this->smarty$property_name)) {
  690.                     $this->smarty->$property_name $value;
  691.                     return;
  692.                 }
  693.         }
  694.         throw new SmartyException("invalid template property '$property_name'.");
  695.     }
  696.     /**
  697.      * Template data object destructor
  698.      */
  699.     public function __destruct()
  700.     {
  701.         if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
  702.             $this->cached->handler->releaseLock($this->smarty$this->cached);
  703.         }
  704.     }
  705. }