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();
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 0 : $this->smarty = &$smarty;
119 : // Smarty parameter
120 0 : $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
121 0 : $this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id;
122 0 : $this->caching = $_caching === null ? $this->smarty->caching : $_caching;
123 0 : if ($this->caching === true)
124 0 : $this->caching = Smarty::CACHING_LIFETIME_CURRENT;
125 0 : $this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime;
126 0 : $this->parent = $_parent;
127 : // Template resource
128 0 : $this->template_resource = $template_resource;
129 : // copy block data of template inheritance
130 0 : if ($this->parent instanceof Smarty_Internal_Template) {
131 0 : $this->block_data = $this->parent->block_data;
132 0 : }
133 0 : }
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 0 : if (!$this->source->exists) {
145 0 : if ($this->parent instanceof Smarty_Internal_Template) {
146 0 : $parent_resource = " in '$this->parent->template_resource}'";
147 0 : } else {
148 0 : $parent_resource = '';
149 : }
150 0 : throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
151 : }
152 0 : if ($this->mustCompile === null) {
153 0 : $this->mustCompile = (!$this->source->uncompiled && ($this->smarty->force_compile || $this->source->recompiled || $this->compiled->timestamp === false ||
154 0 : ($this->smarty->compile_check && $this->compiled->timestamp < $this->source->timestamp)));
155 0 : }
156 0 : 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 0 : if (!$this->source->recompiled) {
167 0 : $this->properties['file_dependency'] = array();
168 0 : if ($this->source->components) {
169 : // uses real resource for file dependency
170 0 : $source = end($this->source->components);
171 0 : $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $source->type);
172 0 : } else {
173 0 : $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type);
174 : }
175 0 : }
176 0 : if ($this->smarty->debugging) {
177 0 : Smarty_Internal_Debug::start_compile($this);
178 0 : }
179 : // compile locking
180 0 : if ($this->smarty->compile_locking && !$this->source->recompiled) {
181 0 : if ($saved_timestamp = $this->compiled->timestamp) {
182 0 : touch($this->compiled->filepath);
183 0 : }
184 0 : }
185 : // call compiler
186 : try {
187 0 : $code = $this->compiler->compileTemplate($this);
188 0 : } catch (Exception $e) {
189 : // restore old timestamp in case of error
190 0 : if ($this->smarty->compile_locking && !$this->source->recompiled && $saved_timestamp) {
191 0 : touch($this->compiled->filepath, $saved_timestamp);
192 0 : }
193 0 : throw $e;
194 : }
195 : // compiling succeded
196 0 : if (!$this->source->recompiled && $this->compiler->write_compiled_code) {
197 : // write compiled template
198 0 : $_filepath = $this->compiled->filepath;
199 0 : if ($_filepath === false)
200 0 : throw new SmartyException('getCompiledFilepath() did not return a destination to save the compiled template to');
201 0 : Smarty_Internal_Write_File::writeFile($_filepath, $code, $this->smarty);
202 0 : $this->compiled->exists = true;
203 0 : $this->compiled->isCompiled = true;
204 0 : }
205 0 : if ($this->smarty->debugging) {
206 0 : Smarty_Internal_Debug::end_compile($this);
207 0 : }
208 : // release compiler object to free memory
209 0 : unset($this->compiler);
210 0 : }
211 :
212 : /**
213 : * Writes the cached template output
214 : *
215 : * @return bool
216 : */
217 : public function writeCachedContent($content)
218 : {
219 0 : if ($this->source->recompiled || !($this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED)) {
220 : // don't write cache file
221 0 : return false;
222 : }
223 0 : $this->properties['cache_lifetime'] = $this->cache_lifetime;
224 0 : $this->properties['unifunc'] = 'content_' . uniqid();
225 0 : $content = $this->createTemplateCodeFrame($content, true);
226 0 : $_smarty_tpl = $this;
227 0 : eval("?>" . $content);
228 0 : $this->cached->valid = true;
229 0 : $this->cached->processed = true;
230 0 : 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 0 : $unique_template_name = Smarty_Resource::getUniqueTemplateName($this->smarty, $template);
249 0 : $_templateId = sha1($unique_template_name . $cache_id . $compile_id);
250 0 : if (isset($this->smarty->template_objects[$_templateId])) {
251 : // clone cached template object because of possible recursive call
252 0 : $tpl = clone $this->smarty->template_objects[$_templateId];
253 0 : $tpl->parent = $this;
254 0 : $tpl->caching = $caching;
255 0 : $tpl->cache_lifetime = $cache_lifetime;
256 0 : } else {
257 0 : $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
258 : }
259 : // get variables from calling scope
260 0 : if ($parent_scope == Smarty::SCOPE_LOCAL) {
261 0 : $tpl->tpl_vars = $this->tpl_vars;
262 0 : } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
263 0 : $tpl->tpl_vars = &$this->tpl_vars;
264 0 : } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
265 0 : $tpl->tpl_vars = &Smarty::$global_tpl_vars;
266 0 : } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
267 0 : $tpl->tpl_vars = &$this->tpl_vars;
268 0 : } else {
269 0 : $tpl->tpl_vars = &$scope_ptr->tpl_vars;
270 : }
271 0 : $tpl->config_vars = $this->config_vars;
272 0 : if (!empty($data)) {
273 : // set up variable values
274 0 : foreach ($data as $_key => $_val) {
275 0 : $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
276 0 : }
277 0 : }
278 0 : return $tpl->fetch(null, null, null, null, false, false, true);
279 : }
280 :
281 : /**
282 : * Template code runtime function to set up an inline subtemplate
283 : *
284 : * @param string $template the resource handle of the template file
285 : * @param mixed $cache_id cache id to be used with this template
286 : * @param mixed $compile_id compile id to be used with this template
287 : * @param integer $caching cache mode
288 : * @param integer $cache_lifetime life time of cache data
289 : * @param array $vars optional variables to assign
290 : * @param int $parent_scope scope in which {include} should execute
291 : * @param string $hash nocache hash code
292 : * @returns string template content
293 : */
294 : public function setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash)
295 : {
296 0 : $tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
297 0 : $tpl->properties['nocache_hash'] = $hash;
298 : // get variables from calling scope
299 0 : if ($parent_scope == Smarty::SCOPE_LOCAL ) {
300 0 : $tpl->tpl_vars = $this->tpl_vars;
301 0 : } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
302 0 : $tpl->tpl_vars = &$this->tpl_vars;
303 0 : } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
304 0 : $tpl->tpl_vars = &Smarty::$global_tpl_vars;
305 0 : } elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
306 0 : $tpl->tpl_vars = &$this->tpl_vars;
307 0 : } else {
308 0 : $tpl->tpl_vars = &$scope_ptr->tpl_vars;
309 : }
310 0 : $tpl->config_vars = $this->config_vars;
311 0 : if (!empty($data)) {
312 : // set up variable values
313 0 : foreach ($data as $_key => $_val) {
314 0 : $tpl->tpl_vars[$_key] = new Smarty_variable($_val);
315 0 : }
316 0 : }
317 0 : return $tpl;
318 : }
319 :
320 :
321 : /**
322 : * Create code frame for compiled and cached templates
323 : *
324 : * @param string $content optional template content
325 : * @param bool $cache flag for cache file
326 : * @return string
327 : */
328 : public function createTemplateCodeFrame($content = '', $cache = false)
329 : {
330 0 : $plugins_string = '';
331 : // include code for plugins
332 0 : if (!$cache) {
333 0 : if (!empty($this->required_plugins['compiled'])) {
334 0 : $plugins_string = '<?php ';
335 0 : foreach ($this->required_plugins['compiled'] as $tmp) {
336 0 : foreach ($tmp as $data) {
337 0 : $plugins_string .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n";
338 0 : }
339 0 : }
340 0 : $plugins_string .= '?>';
341 0 : }
342 0 : if (!empty($this->required_plugins['nocache'])) {
343 0 : $this->has_nocache_code = true;
344 0 : $plugins_string .= "<?php echo '/*%%SmartyNocache:{$this->properties['nocache_hash']}%%*/<?php \$_smarty = \$_smarty_tpl->smarty; ";
345 0 : foreach ($this->required_plugins['nocache'] as $tmp) {
346 0 : foreach ($tmp as $data) {
347 0 : $plugins_string .= "if (!is_callable(\'{$data['function']}\')) include \'{$data['file']}\';\n";
348 0 : }
349 0 : }
350 0 : $plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n";
351 0 : }
352 0 : }
353 : // build property code
354 0 : $this->properties['has_nocache_code'] = $this->has_nocache_code;
355 0 : $output = '';
356 0 : if (!$this->source->recompiled) {
357 0 : $output = "<?php /*%%SmartyHeaderCode:{$this->properties['nocache_hash']}%%*/";
358 0 : if ($this->smarty->direct_access_security) {
359 0 : $output .= "if(!defined('SMARTY_DIR')) exit('no direct access allowed');\n";
360 0 : }
361 0 : }
362 0 : if ($cache) {
363 : // remove compiled code of{function} definition
364 0 : unset($this->properties['function']);
365 0 : if (!empty($this->smarty->template_functions)) {
366 : // copy code of {function} tags called in nocache mode
367 0 : foreach ($this->smarty->template_functions as $name => $function_data) {
368 0 : if (isset($function_data['called_nocache'])) {
369 0 : foreach ($function_data['called_functions'] as $func_name) {
370 0 : $this->smarty->template_functions[$func_name]['called_nocache'] = true;
371 0 : }
372 0 : }
373 0 : }
374 0 : foreach ($this->smarty->template_functions as $name => $function_data) {
375 0 : if (isset($function_data['called_nocache'])) {
376 0 : unset($function_data['called_nocache'], $function_data['called_functions'], $this->smarty->template_functions[$name]['called_nocache']);
377 0 : $this->properties['function'][$name] = $function_data;
378 0 : }
379 0 : }
380 0 : }
381 0 : }
382 0 : $this->properties['version'] = Smarty::SMARTY_VERSION;
383 0 : if (!isset($this->properties['unifunc'])) {
384 0 : $this->properties['unifunc'] = 'content_' . uniqid();
385 0 : }
386 0 : if (!$this->source->recompiled) {
387 0 : $output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . ',' . ($cache ? 'true' : 'false') . "); /*/%%SmartyHeaderCode%%*/?>\n";
388 0 : }
389 0 : if (!$this->source->recompiled) {
390 0 : $output .= '<?php if ($_valid && !is_callable(\'' . $this->properties['unifunc'] . '\')) {function ' . $this->properties['unifunc'] . '($_smarty_tpl) {?>';
391 0 : }
392 0 : $output .= $plugins_string;
393 0 : $output .= $content;
394 0 : if (!$this->source->recompiled) {
395 0 : $output .= '<?php }} ?>';
396 0 : }
397 0 : return $output;
398 : }
399 :
400 : /**
401 : * This function is executed automatically when a compiled or cached template file is included
402 : *
403 : * - Decode saved properties from compiled template and cache files
404 : * - Check if compiled or cache file is valid
405 : *
406 : * @param array $properties special template properties
407 : * @param bool $cache flag if called from cache file
408 : * @return bool flag if compiled or cache file is valid
409 : */
410 : public function decodeProperties($properties, $cache = false)
411 : {
412 0 : $this->has_nocache_code = $properties['has_nocache_code'];
413 0 : $this->properties['nocache_hash'] = $properties['nocache_hash'];
414 0 : if (isset($properties['cache_lifetime'])) {
415 0 : $this->properties['cache_lifetime'] = $properties['cache_lifetime'];
416 0 : }
417 0 : if (isset($properties['file_dependency'])) {
418 0 : $this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']);
419 0 : }
420 0 : if (!empty($properties['function'])) {
421 0 : $this->properties['function'] = array_merge($this->properties['function'], $properties['function']);
422 0 : $this->smarty->template_functions = array_merge($this->smarty->template_functions, $properties['function']);
423 0 : }
424 0 : $this->properties['version'] = (isset($properties['version'])) ? $properties['version'] : '';
425 0 : $this->properties['unifunc'] = $properties['unifunc'];
426 : // check file dependencies at compiled code
427 0 : $is_valid = true;
428 0 : if ($this->properties['version'] != Smarty::SMARTY_VERSION) {
429 0 : $is_valid = false;
430 0 : } 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'])) {
431 0 : foreach ($this->properties['file_dependency'] as $_file_to_check) {
432 0 : if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') {
433 0 : if ($this->source->filepath == $_file_to_check[0] && isset($this->source->timestamp)) {
434 : // do not recheck current template
435 0 : $mtime = $this->source->timestamp;
436 0 : } else {
437 : // file and php types can be checked without loading the respective resource handlers
438 0 : $mtime = filemtime($_file_to_check[0]);
439 : }
440 0 : } elseif ($_file_to_check[2] == 'string') {
441 0 : continue;
442 : } else {
443 0 : $source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]);
444 0 : $mtime = $source->timestamp;
445 : }
446 0 : if ($mtime > $_file_to_check[1]) {
447 0 : $is_valid = false;
448 0 : break;
449 : }
450 0 : }
451 0 : }
452 0 : if ($cache) {
453 0 : $this->cached->valid = $is_valid;
454 0 : } else {
455 0 : $this->mustCompile = !$is_valid;
456 : }
457 : // store data in reusable Smarty_Template_Compiled
458 0 : if (!$cache) {
459 0 : $this->compiled->_properties = $properties;
460 0 : }
461 0 : return $is_valid;
462 : }
463 :
464 : /**
465 : * Template code runtime function to create a local Smarty variable for array assignments
466 : *
467 : * @param string $tpl_var tempate variable name
468 : * @param bool $nocache cache mode of variable
469 : * @param int $scope scope of variable
470 : */
471 : public function createLocalArrayVariable($tpl_var, $nocache = false, $scope = Smarty::SCOPE_LOCAL)
472 : {
473 0 : if (!isset($this->tpl_vars[$tpl_var])) {
474 0 : $this->tpl_vars[$tpl_var] = new Smarty_variable(array(), $nocache, $scope);
475 0 : } else {
476 0 : $this->tpl_vars[$tpl_var] = clone $this->tpl_vars[$tpl_var];
477 0 : if ($scope != Smarty::SCOPE_LOCAL) {
478 0 : $this->tpl_vars[$tpl_var]->scope = $scope;
479 0 : }
480 0 : if (!(is_array($this->tpl_vars[$tpl_var]->value) || $this->tpl_vars[$tpl_var]->value instanceof ArrayAccess)) {
481 0 : settype($this->tpl_vars[$tpl_var]->value, 'array');
482 0 : }
483 : }
484 0 : }
485 :
486 : /**
487 : * Template code runtime function to get pointer to template variable array of requested scope
488 : *
489 : * @param int $scope requested variable scope
490 : * @return array array of template variables
491 : */
492 : public function &getScope($scope)
493 : {
494 0 : if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
495 0 : return $this->parent->tpl_vars;
496 0 : } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
497 0 : $ptr = $this->parent;
498 0 : while (!empty($ptr->parent)) {
499 0 : $ptr = $ptr->parent;
500 0 : }
501 0 : return $ptr->tpl_vars;
502 0 : } elseif ($scope == Smarty::SCOPE_GLOBAL) {
503 0 : return Smarty::$global_tpl_vars;
504 : }
505 0 : $null = null;
506 0 : return $null;
507 : }
508 :
509 : /**
510 : * Get parent or root of template parent chain
511 : *
512 : * @param int $scope pqrent or root scope
513 : * @return mixed object
514 : */
515 : public function getScopePointer($scope)
516 : {
517 0 : if ($scope == Smarty::SCOPE_PARENT && !empty($this->parent)) {
518 0 : return $this->parent;
519 0 : } elseif ($scope == Smarty::SCOPE_ROOT && !empty($this->parent)) {
520 0 : $ptr = $this->parent;
521 0 : while (!empty($ptr->parent)) {
522 0 : $ptr = $ptr->parent;
523 0 : }
524 0 : return $ptr;
525 : }
526 0 : return null;
527 : }
528 :
529 : /**
530 : * [util function] counts an array, arrayaccess/traversable or PDOStatement object
531 : *
532 : * @param mixed $value
533 : * @return int the count for arrays and objects that implement countable, 1 for other objects that don't, and 0 for empty elements
534 : */
535 : public function _count($value)
536 : {
537 0 : if (is_array($value) === true || $value instanceof Countable) {
538 0 : return count($value);
539 0 : } elseif ($value instanceof IteratorAggregate) {
540 : // Note: getIterator() returns a Traversable, not an Iterator
541 : // thus rewind() and valid() methods may not be present
542 0 : return iterator_count($value->getIterator());
543 0 : } elseif ($value instanceof Iterator) {
544 0 : return iterator_count($value);
545 0 : } elseif ($value instanceof PDOStatement) {
546 0 : return $value->rowCount();
547 0 : } elseif ($value instanceof Traversable) {
548 0 : return iterator_count($value);
549 0 : } elseif ($value instanceof ArrayAccess) {
550 0 : if ($value->offsetExists(0)) {
551 0 : return 1;
552 : }
553 0 : } elseif (is_object($value)) {
554 0 : return count($value);
555 : }
556 0 : return 0;
557 : }
558 :
559 : /**
560 : * runtime error not matching capture tags
561 : *
562 : */
563 : public function capture_error()
564 : {
565 0 : throw new SmartyException("Not matching {capture} open/close in \"{$this->template_resource}\"");
566 : }
567 :
568 : /**
569 : * Empty cache for this template
570 : *
571 : * @param integer $exp_time expiration time
572 : * @return integer number of cache files deleted
573 : */
574 : public function clearCache($exp_time=null)
575 : {
576 0 : Smarty_CacheResource::invalidLoadedCache($this->smarty);
577 0 : return $this->cached->handler->clear($this->smarty, $this->template_name, $this->cache_id, $this->compile_id, $exp_time);
578 : }
579 :
580 : /**
581 : * set Smarty property in template context
582 : *
583 : * @param string $property_name property name
584 : * @param mixed $value value
585 : */
586 : public function __set($property_name, $value)
587 : {
588 : switch ($property_name) {
589 0 : case 'source':
590 0 : case 'compiled':
591 0 : case 'cached':
592 0 : case 'compiler':
593 0 : $this->$property_name = $value;
594 0 : return;
595 :
596 : // FIXME: routing of template -> smarty attributes
597 0 : default:
598 0 : if (property_exists($this->smarty, $property_name)) {
599 0 : $this->smarty->$property_name = $value;
600 0 : return;
601 : }
602 0 : }
603 :
604 0 : throw new SmartyException("invalid template property '$property_name'.");
605 : }
606 :
607 : /**
608 : * get Smarty property in template context
609 : *
610 : * @param string $property_name property name
611 : */
612 : public function __get($property_name)
613 : {
614 : switch ($property_name) {
615 0 : case 'source':
616 0 : if (empty($this->template_resource)) {
617 0 : throw new SmartyException("Unable to parse resource name \"{$this->template_resource}\"");
618 : }
619 0 : $this->source = Smarty_Resource::source($this);
620 : // cache template object under a unique ID
621 : // do not cache eval resources
622 0 : if ($this->source->type != 'eval') {
623 0 : $_templateId = sha1($this->source->unique_resource . $this->cache_id . $this->compile_id);
624 0 : $this->smarty->template_objects[$_templateId] = $this;
625 0 : }
626 0 : return $this->source;
627 :
628 0 : case 'compiled':
629 0 : $this->compiled = $this->source->getCompiled($this);
630 0 : return $this->compiled;
631 :
632 0 : case 'cached':
633 0 : if (!class_exists('Smarty_Template_Cached')) {
634 0 : include SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php';
635 0 : }
636 0 : $this->cached = new Smarty_Template_Cached($this);
637 0 : return $this->cached;
638 :
639 0 : case 'compiler':
640 0 : $this->smarty->loadPlugin($this->source->compiler_class);
641 0 : $this->compiler = new $this->source->compiler_class($this->source->template_lexer_class, $this->source->template_parser_class, $this->smarty);
642 0 : return $this->compiler;
643 :
644 : // FIXME: routing of template -> smarty attributes
645 0 : default:
646 0 : if (property_exists($this->smarty, $property_name)) {
647 0 : return $this->smarty->$property_name;
648 : }
649 0 : }
650 :
651 0 : throw new SmartyException("template property '$property_name' does not exist.");
652 : }
653 :
654 : /**
655 : * Template data object destrutor
656 : *
657 : */
658 : public function __destruct()
659 : {
660 0 : if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
661 0 : $this->cached->handler->releaseLock($this->smarty, $this->cached);
662 0 : }
663 0 : }
664 :
665 : }
666 :
|