Passed
Push — master ( c69a4e...3c6756 )
by Michael
21:44 queued 13:20
created

Smarty_Internal_Template::_subTemplateRender()   F

Complexity

Conditions 26
Paths 2160

Size

Total Lines 108
Code Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 26
eloc 71
c 1
b 0
f 0
nc 2160
nop 10
dl 0
loc 108
rs 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
/**
12
 * Main class with template data structures and methods
13
 *
14
 * @package    Smarty
15
 * @subpackage Template
16
 *
17
 * @property Smarty_Template_Compiled             $compiled
18
 * @property Smarty_Template_Cached               $cached
19
 * @property Smarty_Internal_TemplateCompilerBase $compiler
20
 * @property mixed|\Smarty_Template_Cached        registered_plugins
21
 *
22
 * The following methods will be dynamically loaded by the extension handler when they are called.
23
 * They are located in a corresponding Smarty_Internal_Method_xxxx class
24
 *
25
 * @method bool mustCompile()
26
 */
27
#[\AllowDynamicProperties]
28
class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
29
{
30
    /**
31
     * Template object cache
32
     *
33
     * @var Smarty_Internal_Template[]
34
     */
35
    public static $tplObjCache = array();
36
37
    /**
38
     * Template object cache for Smarty::isCached() === true
39
     *
40
     * @var Smarty_Internal_Template[]
41
     */
42
    public static $isCacheTplObj = array();
43
44
    /**
45
     * Sub template Info Cache
46
     * - index name
47
     * - value use count
48
     *
49
     * @var int[]
50
     */
51
    public static $subTplInfo = array();
52
53
    /**
54
     * This object type (Smarty = 1, template = 2, data = 4)
55
     *
56
     * @var int
57
     */
58
    public $_objType = 2;
59
60
    /**
61
     * Global smarty instance
62
     *
63
     * @var Smarty
64
     */
65
    public $smarty = null;
66
67
    /**
68
     * Source instance
69
     *
70
     * @var Smarty_Template_Source|Smarty_Template_Config
71
     */
72
    public $source = null;
73
74
    /**
75
     * Inheritance runtime extension
76
     *
77
     * @var Smarty_Internal_Runtime_Inheritance
78
     */
79
    public $inheritance = null;
80
81
    /**
82
     * Template resource
83
     *
84
     * @var string
85
     */
86
    public $template_resource = null;
87
88
    /**
89
     * flag if compiled template is invalid and must be (re)compiled
90
     *
91
     * @var bool
92
     */
93
    public $mustCompile = null;
94
95
    /**
96
     * Template Id
97
     *
98
     * @var null|string
99
     */
100
    public $templateId = null;
101
102
    /**
103
     * Scope in which variables shall be assigned
104
     *
105
     * @var int
106
     */
107
    public $scope = 0;
108
109
    /**
110
     * Flag which is set while rending a cache file
111
     *
112
     * @var bool
113
     */
114
    public $isRenderingCache = false;
115
116
    /**
117
     * Callbacks called before rendering template
118
     *
119
     * @var callback[]
120
     */
121
    public $startRenderCallbacks = array();
122
123
    /**
124
     * Callbacks called after rendering template
125
     *
126
     * @var callback[]
127
     */
128
    public $endRenderCallbacks = array();
129
130
    /**
131
     * Create template data object
132
     * Some of the global Smarty settings copied to template scope
133
     * It load the required template resources and caching plugins
134
     *
135
     * @param string                                                       $template_resource template resource string
136
     * @param Smarty                                                       $smarty            Smarty instance
137
     * @param null|\Smarty_Internal_Template|\Smarty|\Smarty_Internal_Data $_parent           back pointer to parent
138
     *                                                                                        object with variables or
139
     *                                                                                        null
140
     * @param mixed                                                        $_cache_id         cache   id or null
141
     * @param mixed                                                        $_compile_id       compile id or null
142
     * @param bool|int|null                                                $_caching          use caching?
143
     * @param int|null                                                     $_cache_lifetime   cache life-time in
144
     *                                                                                        seconds
145
     * @param bool                                                         $_isConfig
146
     *
147
     * @throws \SmartyException
148
     */
149
    public function __construct(
150
        $template_resource,
151
        Smarty $smarty,
152
        ?Smarty_Internal_Data $_parent = null,
153
        $_cache_id = null,
154
        $_compile_id = null,
155
        $_caching = null,
156
        $_cache_lifetime = null,
157
        $_isConfig = false
158
    ) {
159
        $this->smarty = $smarty;
160
        // Smarty parameter
161
        $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
162
        $this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id;
163
        $this->caching = (int)($_caching === null ? $this->smarty->caching : $_caching);
164
        $this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime;
165
        $this->compile_check = (int)$smarty->compile_check;
166
        $this->parent = $_parent;
167
        // Template resource
168
        $this->template_resource = $template_resource;
169
        $this->source = $_isConfig ? Smarty_Template_Config::load($this) : Smarty_Template_Source::load($this);
170
        parent::__construct();
171
        if ($smarty->security_policy && method_exists($smarty->security_policy, 'registerCallBacks')) {
172
            $smarty->security_policy->registerCallBacks($this);
173
        }
174
    }
175
176
    /**
177
     * render template
178
     *
179
     * @param bool      $no_output_filter if true do not run output filter
180
     * @param null|bool $display          true: display, false: fetch null: sub-template
181
     *
182
     * @return string
183
     * @throws \Exception
184
     * @throws \SmartyException
185
     */
186
    public function render($no_output_filter = true, $display = null)
187
    {
188
        if ($this->smarty->debugging) {
189
            if (!isset($this->smarty->_debug)) {
190
                $this->smarty->_debug = new Smarty_Internal_Debug();
191
            }
192
            $this->smarty->_debug->start_template($this, $display);
0 ignored issues
show
Bug introduced by
It seems like $display can also be of type boolean; however, parameter $mode of Smarty_Internal_Debug::start_template() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

192
            $this->smarty->_debug->start_template($this, /** @scrutinizer ignore-type */ $display);
Loading history...
193
        }
194
        // checks if template exists
195
        if (!$this->source->exists) {
196
            throw new SmartyException(
197
                "Unable to load template '{$this->source->type}:{$this->source->name}'" .
198
                ($this->_isSubTpl() ? " in '{$this->parent->template_resource}'" : '')
0 ignored issues
show
Bug Best Practice introduced by
The property template_resource does not exist on Smarty. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug introduced by
The property template_resource does not seem to exist on Smarty_Data.
Loading history...
199
            );
200
        }
201
        // disable caching for evaluated code
202
        if ($this->source->handler->recompiled) {
203
            $this->caching = Smarty::CACHING_OFF;
204
        }
205
        // read from cache or render
206
        if ($this->caching === Smarty::CACHING_LIFETIME_CURRENT || $this->caching === Smarty::CACHING_LIFETIME_SAVED) {
207
            if (!isset($this->cached) || $this->cached->cache_id !== $this->cache_id
208
                || $this->cached->compile_id !== $this->compile_id
209
            ) {
210
                $this->loadCached(true);
211
            }
212
            $this->cached->render($this, $no_output_filter);
213
        } else {
214
            if (!isset($this->compiled) || $this->compiled->compile_id !== $this->compile_id) {
215
                $this->loadCompiled(true);
216
            }
217
            $this->compiled->render($this);
218
        }
219
        // display or fetch
220
        if ($display) {
221
            if ($this->caching && $this->smarty->cache_modified_check) {
222
                $this->smarty->ext->_cacheModify->cacheModifiedCheck(
223
                    $this->cached,
224
                    $this,
225
                    isset($content) ? $content : ob_get_clean()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $content seems to never exist and therefore isset should always be false.
Loading history...
226
                );
227
            } else {
228
                if ((!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled)
229
                    && !$no_output_filter && (isset($this->smarty->autoload_filters[ 'output' ])
230
                                              || isset($this->smarty->registered_filters[ 'output' ]))
231
                ) {
232
                    echo $this->smarty->ext->_filterHandler->runFilter('output', ob_get_clean(), $this);
233
                } else {
234
                    echo ob_get_clean();
235
                }
236
            }
237
            if ($this->smarty->debugging) {
238
                $this->smarty->_debug->end_template($this);
239
                // debug output
240
                $this->smarty->_debug->display_debug($this, true);
241
            }
242
            return '';
243
        } else {
244
            if ($this->smarty->debugging) {
245
                $this->smarty->_debug->end_template($this);
246
                if ($this->smarty->debugging === 2 && $display === false) {
0 ignored issues
show
introduced by
The condition $this->smarty->debugging === 2 is always false.
Loading history...
247
                    $this->smarty->_debug->display_debug($this, true);
248
                }
249
            }
250
            if (!$no_output_filter
251
                && (!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled)
252
                && (isset($this->smarty->autoload_filters[ 'output' ])
253
                    || isset($this->smarty->registered_filters[ 'output' ]))
254
            ) {
255
                return $this->smarty->ext->_filterHandler->runFilter('output', ob_get_clean(), $this);
256
            }
257
            // return cache content
258
            return null;
259
        }
260
    }
261
262
    /**
263
     * Runtime function to render sub-template
264
     *
265
     * @param string  $template       template name
266
     * @param mixed   $cache_id       cache id
267
     * @param mixed   $compile_id     compile id
268
     * @param integer $caching        cache mode
269
     * @param integer $cache_lifetime life time of cache data
270
     * @param array   $data           passed parameter template variables
271
     * @param int     $scope          scope in which {include} should execute
272
     * @param bool    $forceTplCache  cache template object
273
     * @param string  $uid            file dependency uid
274
     * @param string  $content_func   function name
275
     *
276
     * @throws \Exception
277
     * @throws \SmartyException
278
     */
279
    public function _subTemplateRender(
280
        $template,
281
        $cache_id,
282
        $compile_id,
283
        $caching,
284
        $cache_lifetime,
285
        $data,
286
        $scope,
287
        $forceTplCache,
288
        $uid = null,
289
        $content_func = null
290
    ) {
291
        $tpl = clone $this;
292
        $tpl->parent = $this;
293
        $smarty = &$this->smarty;
294
        $_templateId = $smarty->_getTemplateId($template, $cache_id, $compile_id, $caching, $tpl);
295
        // recursive call ?
296
        if ((isset($tpl->templateId) ? $tpl->templateId : $tpl->_getTemplateId()) !== $_templateId) {
297
            // already in template cache?
298
            if (isset(self::$tplObjCache[ $_templateId ])) {
299
                // copy data from cached object
300
                $cachedTpl = &self::$tplObjCache[ $_templateId ];
301
                $tpl->templateId = $cachedTpl->templateId;
302
                $tpl->template_resource = $cachedTpl->template_resource;
303
                $tpl->cache_id = $cachedTpl->cache_id;
304
                $tpl->compile_id = $cachedTpl->compile_id;
305
                $tpl->source = $cachedTpl->source;
306
                if (isset($cachedTpl->compiled)) {
307
                    $tpl->compiled = $cachedTpl->compiled;
308
                } else {
309
                    unset($tpl->compiled);
310
                }
311
                if ($caching !== 9999 && isset($cachedTpl->cached)) {
312
                    $tpl->cached = $cachedTpl->cached;
313
                } else {
314
                    unset($tpl->cached);
315
                }
316
            } else {
317
                $tpl->templateId = $_templateId;
318
                $tpl->template_resource = $template;
319
                $tpl->cache_id = $cache_id;
320
                $tpl->compile_id = $compile_id;
321
                if (isset($uid)) {
322
                    // for inline templates we can get all resource information from file dependency
323
                    list($filepath, $timestamp, $type) = $tpl->compiled->file_dependency[ $uid ];
324
                    $tpl->source = new Smarty_Template_Source($smarty, $filepath, $type, $filepath);
325
                    $tpl->source->filepath = $filepath;
326
                    $tpl->source->timestamp = $timestamp;
327
                    $tpl->source->exists = true;
328
                    $tpl->source->uid = $uid;
329
                } else {
330
                    $tpl->source = Smarty_Template_Source::load($tpl);
331
                    unset($tpl->compiled);
332
                }
333
                if ($caching !== 9999) {
334
                    unset($tpl->cached);
335
                }
336
            }
337
        } else {
338
            // on recursive calls force caching
339
            $forceTplCache = true;
340
        }
341
        $tpl->caching = $caching;
342
        $tpl->cache_lifetime = $cache_lifetime;
343
        // set template scope
344
        $tpl->scope = $scope;
345
        if (!isset(self::$tplObjCache[ $tpl->templateId ]) && !$tpl->source->handler->recompiled) {
346
            // check if template object should be cached
347
            if ($forceTplCache || (isset(self::$subTplInfo[ $tpl->template_resource ])
348
                                   && self::$subTplInfo[ $tpl->template_resource ] > 1)
349
                || ($tpl->_isSubTpl() && isset(self::$tplObjCache[ $tpl->parent->templateId ]))
350
            ) {
351
                self::$tplObjCache[ $tpl->templateId ] = $tpl;
352
            }
353
        }
354
        if (!empty($data)) {
355
            // set up variable values
356
            foreach ($data as $_key => $_val) {
357
                $tpl->tpl_vars[ $_key ] = new Smarty_Variable($_val, $this->isRenderingCache);
358
            }
359
        }
360
        if ($tpl->caching === 9999) {
361
            if (!isset($tpl->compiled)) {
362
                $tpl->loadCompiled(true);
363
            }
364
            if ($tpl->compiled->has_nocache_code) {
365
                $this->cached->hashes[ $tpl->compiled->nocache_hash ] = true;
366
            }
367
        }
368
        $tpl->_cache = array();
369
        if (isset($uid)) {
370
            if ($smarty->debugging) {
371
                if (!isset($smarty->_debug)) {
372
                    $smarty->_debug = new Smarty_Internal_Debug();
373
                }
374
                $smarty->_debug->start_template($tpl);
375
                $smarty->_debug->start_render($tpl);
376
            }
377
            $tpl->compiled->getRenderedTemplateCode($tpl, $content_func);
378
            if ($smarty->debugging) {
379
                $smarty->_debug->end_template($tpl);
380
                $smarty->_debug->end_render($tpl);
381
            }
382
        } else {
383
            if (isset($tpl->compiled)) {
384
                $tpl->compiled->render($tpl);
385
            } else {
386
                $tpl->render();
387
            }
388
        }
389
    }
390
391
    /**
392
     * Get called sub-templates and save call count
393
     */
394
    public function _subTemplateRegister()
395
    {
396
        foreach ($this->compiled->includes as $name => $count) {
397
            if (isset(self::$subTplInfo[ $name ])) {
398
                self::$subTplInfo[ $name ] += $count;
399
            } else {
400
                self::$subTplInfo[ $name ] = $count;
401
            }
402
        }
403
    }
404
405
    /**
406
     * Check if this is a sub template
407
     *
408
     * @return bool true is sub template
409
     */
410
    public function _isSubTpl()
411
    {
412
        return isset($this->parent) && $this->parent->_isTplObj();
413
    }
414
415
    /**
416
     * Assign variable in scope
417
     *
418
     * @param string $varName variable name
419
     * @param mixed  $value   value
420
     * @param bool   $nocache nocache flag
421
     * @param int    $scope   scope into which variable shall be assigned
422
     */
423
    public function _assignInScope($varName, $value, $nocache = false, $scope = 0)
424
    {
425
        if (isset($this->tpl_vars[ $varName ])) {
426
            $this->tpl_vars[ $varName ] = clone $this->tpl_vars[ $varName ];
427
            $this->tpl_vars[ $varName ]->value = $value;
428
            if ($nocache || $this->isRenderingCache) {
429
                $this->tpl_vars[ $varName ]->nocache = true;
430
            }
431
        } else {
432
            $this->tpl_vars[ $varName ] = new Smarty_Variable($value, $nocache || $this->isRenderingCache);
433
        }
434
        if ($scope >= 0) {
435
            if ($scope > 0 || $this->scope > 0) {
436
                $this->smarty->ext->_updateScope->_updateScope($this, $varName, $scope);
437
            }
438
        }
439
    }
440
441
    /**
442
     * Check if plugins are callable require file otherwise
443
     *
444
     * @param array $plugins required plugins
445
     *
446
     * @throws \SmartyException
447
     */
448
    public function _checkPlugins($plugins)
449
    {
450
        static $checked = array();
451
        foreach ($plugins as $plugin) {
452
            $name = join('::', (array)$plugin[ 'function' ]);
453
            if (!isset($checked[ $name ])) {
454
                if (!is_callable($plugin[ 'function' ])) {
455
                    if (is_file($plugin[ 'file' ])) {
456
                        include_once $plugin[ 'file' ];
457
                        if (is_callable($plugin[ 'function' ])) {
458
                            $checked[ $name ] = true;
459
                        }
460
                    }
461
                } else {
462
                    $checked[ $name ] = true;
463
                }
464
            }
465
            if (!isset($checked[ $name ])) {
466
                if (false !== $this->smarty->loadPlugin($name)) {
467
                    $checked[ $name ] = true;
468
                } else {
469
                    throw new SmartyException("Plugin '{$name}' not callable");
470
                }
471
            }
472
        }
473
    }
474
475
    /**
476
     * This function is executed automatically when a compiled or cached template file is included
477
     * - Decode saved properties from compiled template and cache files
478
     * - Check if compiled or cache file is valid
479
     *
480
     * @param \Smarty_Internal_Template $tpl
481
     * @param array                     $properties special template properties
482
     * @param bool                      $cache      flag if called from cache file
483
     *
484
     * @return bool flag if compiled or cache file is valid
485
     * @throws \SmartyException
486
     */
487
    public function _decodeProperties(Smarty_Internal_Template $tpl, $properties, $cache = false)
488
    {
489
        // on cache resources other than file check version stored in cache code
490
        if (!isset($properties[ 'version' ]) || Smarty::SMARTY_VERSION !== $properties[ 'version' ]) {
491
            if ($cache) {
492
                $tpl->smarty->clearAllCache();
493
            } else {
494
                $tpl->smarty->clearCompiledTemplate();
495
            }
496
            return false;
497
        }
498
        $is_valid = true;
499
        if (!empty($properties[ 'file_dependency' ])
500
            && ((!$cache && $tpl->compile_check) || $tpl->compile_check === Smarty::COMPILECHECK_ON)
501
        ) {
502
            // check file dependencies at compiled code
503
            foreach ($properties[ 'file_dependency' ] as $_file_to_check) {
504
                if ($_file_to_check[ 2 ] === 'file' || $_file_to_check[ 2 ] === 'php') {
505
                    if ($tpl->source->filepath === $_file_to_check[ 0 ]) {
506
                        // do not recheck current template
507
                        continue;
508
                        //$mtime = $tpl->source->getTimeStamp();
509
                    } else {
510
                        // file and php types can be checked without loading the respective resource handlers
511
                        $mtime = is_file($_file_to_check[ 0 ]) ? filemtime($_file_to_check[ 0 ]) : false;
512
                    }
513
                } else {
514
                    $handler = Smarty_Resource::load($tpl->smarty, $_file_to_check[ 2 ]);
515
                    if ($handler->checkTimestamps()) {
516
                        $source = Smarty_Template_Source::load($tpl, $tpl->smarty, $_file_to_check[ 0 ]);
517
                        $mtime = $source->getTimeStamp();
518
                    } else {
519
                        continue;
520
                    }
521
                }
522
                if ($mtime === false || $mtime > $_file_to_check[ 1 ]) {
523
                    $is_valid = false;
524
                    break;
525
                }
526
            }
527
        }
528
        if ($cache) {
529
            // CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
530
            if ($tpl->caching === Smarty::CACHING_LIFETIME_SAVED && $properties[ 'cache_lifetime' ] >= 0
531
                && (time() > ($tpl->cached->timestamp + $properties[ 'cache_lifetime' ]))
532
            ) {
533
                $is_valid = false;
534
            }
535
            $tpl->cached->cache_lifetime = $properties[ 'cache_lifetime' ];
536
            $tpl->cached->valid = $is_valid;
537
            $resource = $tpl->cached;
538
        } else {
539
            $tpl->mustCompile = !$is_valid;
540
            $resource = $tpl->compiled;
541
            $resource->includes = isset($properties[ 'includes' ]) ? $properties[ 'includes' ] : array();
542
        }
543
        if ($is_valid) {
544
            $resource->unifunc = $properties[ 'unifunc' ];
545
            $resource->has_nocache_code = $properties[ 'has_nocache_code' ];
546
            //            $tpl->compiled->nocache_hash = $properties['nocache_hash'];
547
            $resource->file_dependency = $properties[ 'file_dependency' ];
548
        }
549
        return $is_valid && !function_exists($properties[ 'unifunc' ]);
550
    }
551
552
    /**
553
     * Compiles the template
554
     * If the template is not evaluated the compiled template is saved on disk
555
     *
556
     * @throws \Exception
557
     */
558
    public function compileTemplateSource()
559
    {
560
        return $this->compiled->compileTemplateSource($this);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->compiled->compileTemplateSource($this) targeting Smarty_Template_Compiled::compileTemplateSource() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
561
    }
562
563
    /**
564
     * Writes the content to cache resource
565
     *
566
     * @param string $content
567
     *
568
     * @return bool
569
     */
570
    public function writeCachedContent($content)
571
    {
572
        return $this->smarty->ext->_updateCache->writeCachedContent($this, $content);
573
    }
574
575
    /**
576
     * Get unique template id
577
     *
578
     * @return string
579
     * @throws \SmartyException
580
     */
581
    public function _getTemplateId()
582
    {
583
        return isset($this->templateId) ? $this->templateId : $this->templateId =
584
            $this->smarty->_getTemplateId($this->template_resource, $this->cache_id, $this->compile_id);
585
    }
586
587
    /**
588
     * runtime error not matching capture tags
589
     *
590
     * @throws \SmartyException
591
     */
592
    public function capture_error()
593
    {
594
        throw new SmartyException("Not matching {capture} open/close in '{$this->template_resource}'");
595
    }
596
597
    /**
598
     * Load compiled object
599
     *
600
     * @param bool $force force new compiled object
601
     */
602
    public function loadCompiled($force = false)
603
    {
604
        if ($force || !isset($this->compiled)) {
605
            $this->compiled = Smarty_Template_Compiled::load($this);
606
        }
607
    }
608
609
    /**
610
     * Load cached object
611
     *
612
     * @param bool $force force new cached object
613
     */
614
    public function loadCached($force = false)
615
    {
616
        if ($force || !isset($this->cached)) {
617
            $this->cached = Smarty_Template_Cached::load($this);
618
        }
619
    }
620
621
    /**
622
     * Load inheritance object
623
     */
624
    public function _loadInheritance()
625
    {
626
        if (!isset($this->inheritance)) {
627
            $this->inheritance = new Smarty_Internal_Runtime_Inheritance();
628
        }
629
    }
630
631
    /**
632
     * Unload inheritance object
633
     */
634
    public function _cleanUp()
635
    {
636
        $this->startRenderCallbacks = array();
637
        $this->endRenderCallbacks = array();
638
        $this->inheritance = null;
639
    }
640
641
    /**
642
     * Load compiler object
643
     *
644
     * @throws \SmartyException
645
     */
646
    public function loadCompiler()
647
    {
648
        if (!class_exists($this->source->compiler_class)) {
649
            $this->smarty->loadPlugin($this->source->compiler_class);
650
        }
651
        $this->compiler =
652
            new $this->source->compiler_class(
653
                $this->source->template_lexer_class,
654
                $this->source->template_parser_class,
655
                $this->smarty
656
            );
657
    }
658
659
    /**
660
     * Handle unknown class methods
661
     *
662
     * @param string $name unknown method-name
663
     * @param array  $args argument array
664
     *
665
     * @return mixed
666
     */
667
    public function __call($name, $args)
668
    {
669
        // method of Smarty object?
670
        if (method_exists($this->smarty, $name)) {
671
            return call_user_func_array(array($this->smarty, $name), $args);
672
        }
673
        // parent
674
        return parent::__call($name, $args);
675
    }
676
677
    /**
678
     * get Smarty property in template context
679
     *
680
     * @param string $property_name property name
681
     *
682
     * @return mixed|Smarty_Template_Cached
683
     * @throws SmartyException
684
     */
685
    public function __get($property_name)
686
    {
687
        switch ($property_name) {
688
            case 'compiled':
689
                $this->loadCompiled();
690
                return $this->compiled;
691
            case 'cached':
692
                $this->loadCached();
693
                return $this->cached;
694
            case 'compiler':
695
                $this->loadCompiler();
696
                return $this->compiler;
697
            default:
698
                // Smarty property ?
699
                if (property_exists($this->smarty, $property_name)) {
700
                    return $this->smarty->$property_name;
701
                }
702
        }
703
        throw new SmartyException("template property '$property_name' does not exist.");
704
    }
705
706
    /**
707
     * set Smarty property in template context
708
     *
709
     * @param string $property_name property name
710
     * @param mixed  $value         value
711
     *
712
     * @throws SmartyException
713
     */
714
    public function __set($property_name, $value)
715
    {
716
        switch ($property_name) {
717
            case 'compiled':
718
            case 'cached':
719
            case 'compiler':
720
                $this->$property_name = $value;
721
                return;
722
            default:
723
                // Smarty property ?
724
                if (property_exists($this->smarty, $property_name)) {
725
                    $this->smarty->$property_name = $value;
726
                    return;
727
                }
728
        }
729
        throw new SmartyException("invalid template property '$property_name'.");
730
    }
731
732
    /**
733
     * Template data object destructor
734
     */
735
    public function __destruct()
736
    {
737
        if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
738
            $this->cached->handler->releaseLock($this->smarty, $this->cached);
739
        }
740
    }
741
}
742