library/smarty/libs/sysplugins/smarty_template_compiled.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 <?php
       
     2 
       
     3 /**
       
     4  * Smarty Resource Data Object
       
     5  * Meta Data Container for Template Files
       
     6  *
       
     7  * @package    Smarty
       
     8  * @subpackage TemplateResources
       
     9  * @author     Rodney Rehm
       
    10  * @property string $content compiled content
       
    11  */
       
    12 class Smarty_Template_Compiled {
       
    13     /**
       
    14      * Compiled Filepath
       
    15      *
       
    16      * @var string
       
    17      */
       
    18     public $filepath = null;
       
    19 
       
    20     /**
       
    21      * Compiled Timestamp
       
    22      *
       
    23      * @var integer
       
    24      */
       
    25     public $timestamp = null;
       
    26 
       
    27     /**
       
    28      * Compiled Existence
       
    29      *
       
    30      * @var boolean
       
    31      */
       
    32     public $exists = false;
       
    33 
       
    34     /**
       
    35      * Compiled Content Loaded
       
    36      *
       
    37      * @var boolean
       
    38      */
       
    39     public $processed = false;
       
    40     /**
       
    41      * Code of recompiled template resource
       
    42      *
       
    43      * @var string|null
       
    44      */
       
    45     public $code = null;
       
    46 
       
    47     /**
       
    48      * create Compiled Object container
       
    49      */
       
    50     public function __construct() {
       
    51     }
       
    52 
       
    53     /**
       
    54      * get a Compiled Object of this source
       
    55      *
       
    56      * @param  Smarty_Internal_Template $_template template object
       
    57      *
       
    58      * @return Smarty_Template_Compiled compiled object
       
    59      */
       
    60     static function load($_template) {
       
    61         if (!isset($_template->source)) {
       
    62             $_template->loadSource();
       
    63         }
       
    64         // check runtime cache
       
    65         if (!$_template->source->recompiled && $_template->smarty->resource_caching) {
       
    66             $_cache_key = $_template->source->unique_resource . '#';
       
    67             if ($_template->caching) {
       
    68                 $_cache_key .= 'caching#';
       
    69             }
       
    70             $_cache_key .= $_template->compile_id;
       
    71             if (isset($_template->source->compileds[$_cache_key])) {
       
    72                 return $_template->source->compileds[$_cache_key];
       
    73             }
       
    74         }
       
    75         $compiled = new Smarty_Template_Compiled();
       
    76         if (method_exists($_template->source->handler, 'populateCompiledFilepath')) {
       
    77             $_template->source->handler->populateCompiledFilepath($compiled, $_template);
       
    78         } else {
       
    79             $compiled->populateCompiledFilepath($_template);
       
    80         }
       
    81         // runtime cache
       
    82         if (!$_template->source->recompiled && $_template->smarty->resource_caching) {
       
    83             $_template->source->compileds[$_cache_key] = $compiled;
       
    84         }
       
    85         return $compiled;
       
    86     }
       
    87 
       
    88     /**
       
    89      * populate Compiled Object with compiled filepath
       
    90      *
       
    91      * @param Smarty_Internal_Template $_template template object
       
    92      **/
       
    93     public function populateCompiledFilepath(Smarty_Internal_Template $_template) {
       
    94         $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
       
    95         if ($_template->source->isConfig) {
       
    96             $_flag = '_' . ((int)$_template->smarty->config_read_hidden + (int)$_template->smarty->config_booleanize * 2
       
    97                     + (int)$_template->smarty->config_overwrite * 4);
       
    98         } else {
       
    99             $_flag = '_' . ((int)$_template->smarty->merge_compiled_includes + (int)$_template->smarty->escape_html * 2);
       
   100         }
       
   101         $_filepath = $_template->source->uid . $_flag;
       
   102         // if use_sub_dirs, break file into directories
       
   103         if ($_template->smarty->use_sub_dirs) {
       
   104             $_filepath = substr($_filepath, 0, 2) . DS
       
   105                 . substr($_filepath, 2, 2) . DS
       
   106                 . substr($_filepath, 4, 2) . DS
       
   107                 . $_filepath;
       
   108         }
       
   109         $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
       
   110         if (isset($_compile_id)) {
       
   111             $_filepath = $_compile_id . $_compile_dir_sep . $_filepath;
       
   112         }
       
   113         // caching token
       
   114         if ($_template->caching) {
       
   115             $_cache = '.cache';
       
   116         } else {
       
   117             $_cache = '';
       
   118         }
       
   119         $_compile_dir = $_template->smarty->getCompileDir();
       
   120         // set basename if not specified
       
   121         $_basename = $_template->source->handler->getBasename($_template->source);
       
   122         if ($_basename === null) {
       
   123             $_basename = basename(preg_replace('![^\w\/]+!', '_', $_template->source->name));
       
   124         }
       
   125         // separate (optional) basename by dot
       
   126         if ($_basename) {
       
   127             $_basename = '.' . $_basename;
       
   128         }
       
   129 
       
   130         $this->filepath = $_compile_dir . $_filepath . '.' . $_template->source->type . $_basename . $_cache . '.php';
       
   131         $this->timestamp = $this->exists = is_file($this->filepath);
       
   132         if ($this->exists) {
       
   133             $this->timestamp = @filemtime($this->filepath);
       
   134         }
       
   135     }
       
   136 
       
   137     /**
       
   138      * load compiled template or compile from source
       
   139      *
       
   140      * @param Smarty_Internal_Template $_template
       
   141      *
       
   142      * @throws Exception
       
   143      */
       
   144     public function process(Smarty_Internal_Template $_template) {
       
   145         $_smarty_tpl = $_template;
       
   146         if ($_template->source->recompiled || !$_template->compiled->exists || $_template->smarty->force_compile) {
       
   147             $this->compileTemplateSource($_template);
       
   148             $compileCheck = $_template->smarty->compile_check;
       
   149             $_template->smarty->compile_check = false;
       
   150             if ($_template->source->recompiled) {
       
   151                 $level = ob_get_level();
       
   152                 ob_start();
       
   153                 try {
       
   154                     eval("?>" . $this->code);
       
   155                 } catch (Exception $e) {
       
   156                     while (ob_get_level() > $level) {
       
   157                         ob_end_clean();
       
   158                     }
       
   159                     throw $e;
       
   160                 }
       
   161                 ob_get_clean();
       
   162                 $this->code = null;
       
   163             } else {
       
   164                 include($_template->compiled->filepath);
       
   165             }
       
   166             $_template->smarty->compile_check = $compileCheck;
       
   167         } else {
       
   168             include($_template->compiled->filepath);
       
   169             if ($_template->mustCompile) {
       
   170                 $this->compileTemplateSource($_template);
       
   171                 $compileCheck = $_template->smarty->compile_check;
       
   172                 $_template->smarty->compile_check = false;
       
   173                 include($_template->compiled->filepath);
       
   174                 $_template->smarty->compile_check = $compileCheck;
       
   175             }
       
   176         }
       
   177         $this->unifunc = $_template->properties['unifunc'];
       
   178         $this->processed = true;
       
   179     }
       
   180 
       
   181     /**
       
   182      * render compiled template code
       
   183      *
       
   184      * @param Smarty_Internal_Template $_template
       
   185      *
       
   186      * @return string
       
   187      * @throws Exception
       
   188      */
       
   189     public function render(Smarty_Internal_Template $_template) {
       
   190 
       
   191         if (!$this->processed) {
       
   192             $this->process($_template);
       
   193         }
       
   194         $_template->properties['unifunc'] = $this->unifunc;
       
   195         return $_template->getRenderedTemplateCode();
       
   196     }
       
   197 
       
   198     /**
       
   199      * compile template from source
       
   200      *
       
   201      * @param Smarty_Internal_Template $_template
       
   202      *
       
   203      * @return string
       
   204      * @throws Exception
       
   205      */
       
   206     public function compileTemplateSource(Smarty_Internal_Template $_template) {
       
   207         if (!$_template->source->recompiled) {
       
   208             $_template->properties['file_dependency'] = array();
       
   209         }
       
   210         // compile locking
       
   211         if (!$_template->source->recompiled) {
       
   212             if ($saved_timestamp = $_template->compiled->timestamp) {
       
   213                 touch($_template->compiled->filepath);
       
   214             }
       
   215         }
       
   216         // call compiler
       
   217         try {
       
   218             $code = $_template->compiler->compileTemplate($_template);
       
   219         } catch (Exception $e) {
       
   220             // restore old timestamp in case of error
       
   221             if (!$_template->source->recompiled && $saved_timestamp) {
       
   222                 touch($_template->compiled->filepath, $saved_timestamp);
       
   223             }
       
   224             throw $e;
       
   225         }
       
   226         // compiling succeeded
       
   227         if ($_template->compiler->write_compiled_code) {
       
   228             // write compiled template
       
   229             $this->write($_template, $code);
       
   230             $code = '';
       
   231         }
       
   232         // release compiler object to free memory
       
   233         unset($_template->compiler);
       
   234         return $code;
       
   235     }
       
   236 
       
   237     /**
       
   238      * Write compiled code by handler
       
   239      *
       
   240      * @param Smarty_Internal_Template $_template template object
       
   241      * @param string $code compiled code
       
   242      *
       
   243      * @return boolean success
       
   244      */
       
   245     public function write(Smarty_Internal_Template $_template, $code) {
       
   246         if (!$_template->source->recompiled) {
       
   247             $obj = new Smarty_Internal_Write_File();
       
   248             if ($obj->writeFile($this->filepath, $code, $_template->smarty) === true) {
       
   249                 $this->timestamp = $this->exists = is_file($this->filepath);
       
   250                 if ($this->exists) {
       
   251                     $this->timestamp = @filemtime($this->filepath);
       
   252                     return true;
       
   253                 }
       
   254             }
       
   255             return false;
       
   256         } else {
       
   257             $this->code = $code;
       
   258         }
       
   259         $this->timestamp = time();
       
   260         $this->exists = true;
       
   261         return true;
       
   262     }
       
   263 
       
   264     /**
       
   265      * Read compiled content from handler
       
   266      *
       
   267      * @param Smarty_Internal_Template $_template template object
       
   268      *
       
   269      * @return string content
       
   270      */
       
   271     public function read(Smarty_Internal_Template $_template) {
       
   272         if (!$_template->source->recompiled) {
       
   273             return file_get_contents($this->filepath);
       
   274         }
       
   275         return isset($this->content) ? $this->content : false;
       
   276     }
       
   277 }