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