Smarty_Internal_Template::_subTemplateRender()   F
last analyzed

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
class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
28
{
29
    /**
30
     * Template object cache
31
     *
32
     * @var Smarty_Internal_Template[]
33
     */
34
    public static $tplObjCache = array();
35
36
    /**
37
     * Template object cache for Smarty::isCached() === true
38
     *
39
     * @var Smarty_Internal_Template[]
40
     */
41
    public static $isCacheTplObj = array();
42
43
    /**
44
     * Sub template Info Cache
45
     * - index name
46
     * - value use count
47
     *
48
     * @var int[]
49
     */
50
    public static $subTplInfo = array();
51
52
    /**
53
     * This object type (Smarty = 1, template = 2, data = 4)
54
     *
55
     * @var int
56
     */
57
    public $_objType = 2;
58
59
    /**
60
     * Global smarty instance
61
     *
62
     * @var Smarty
63
     */
64
    public $smarty = null;
65
66
    /**
67
     * Source instance
68
     *
69
     * @var Smarty_Template_Source|Smarty_Template_Config
70
     */
71
    public $source = null;
72
73
    /**
74
     * Inheritance runtime extension
75
     *
76
     * @var Smarty_Internal_Runtime_Inheritance
77
     */
78
    public $inheritance = null;
79
80
    /**
81
     * Template resource
82
     *
83
     * @var string
84
     */
85
    public $template_resource = null;
86
87
    /**
88
     * flag if compiled template is invalid and must be (re)compiled
89
     *
90
     * @var bool
91
     */
92
    public $mustCompile = null;
93
94
    /**
95
     * Template Id
96
     *
97
     * @var null|string
98
     */
99
    public $templateId = null;
100
101
    /**
102
     * Scope in which variables shall be assigned
103
     *
104
     * @var int
105
     */
106
    public $scope = 0;
107
108
    /**
109
     * Flag which is set while rending a cache file
110
     *
111
     * @var bool
112
     */
113
    public $isRenderingCache = false;
114
115
    /**
116
     * Callbacks called before rendering template
117
     *
118
     * @var callback[]
119
     */
120
    public $startRenderCallbacks = array();
121
122
    /**
123
     * Callbacks called after rendering template
124
     *
125
     * @var callback[]
126
     */
127
    public $endRenderCallbacks = array();
128
129
    /**
130
     * Create template data object
131
     * Some of the global Smarty settings copied to template scope
132
     * It load the required template resources and caching plugins
133
     *
134
     * @param string                                                       $template_resource template resource string
135
     * @param Smarty                                                       $smarty            Smarty instance
136
     * @param null|\Smarty_Internal_Template|\Smarty|\Smarty_Internal_Data $_parent           back pointer to parent
137
     *                                                                                        object with variables or
138
     *                                                                                        null
139
     * @param mixed                                                        $_cache_id         cache   id or null
140
     * @param mixed                                                        $_compile_id       compile id or null
141
     * @param bool|int|null                                                $_caching          use caching?
142
     * @param int|null                                                     $_cache_lifetime   cache life-time in
143
     *                                                                                        seconds
144
     * @param bool                                                         $_isConfig
145
     *
146
     * @throws \SmartyException
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
        // Smarty parameter
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
        // Template resource
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
     * render template
177
     *
178
     * @param bool      $no_output_filter if true do not run output filter
179
     * @param null|bool $display          true: display, false: fetch null: sub-template
180
     *
181
     * @return string
182
     * @throws \Exception
183
     * @throws \SmartyException
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);
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

191
            $this->smarty->_debug->start_template($this, /** @scrutinizer ignore-type */ $display);
Loading history...
192
        }
193
        // checks if template exists
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}'" : '')
0 ignored issues
show
Bug introduced by
The property template_resource does not seem to exist on Smarty_Data.
Loading history...
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...
198
            );
199
        }
200
        // disable caching for evaluated code
201
        if ($this->source->handler->recompiled) {
202
            $this->caching = Smarty::CACHING_OFF;
203
        }
204
        // read from cache or render
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
        // display or fetch
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()
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...
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
                // debug output
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) {
0 ignored issues
show
introduced by
The condition $this->smarty->debugging === 2 is always false.
Loading history...
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
            // return cache content
257
            return null;
258
        }
259
    }
260
261
    /**
262
     * Runtime function to render sub-template
263
     *
264
     * @param string  $template       template name
265
     * @param mixed   $cache_id       cache id
266
     * @param mixed   $compile_id     compile id
267
     * @param integer $caching        cache mode
268
     * @param integer $cache_lifetime life time of cache data
269
     * @param array   $data           passed parameter template variables
270
     * @param int     $scope          scope in which {include} should execute
271
     * @param bool    $forceTplCache  cache template object
272
     * @param string  $uid            file dependency uid
273
     * @param string  $content_func   function name
274
     *
275
     * @throws \Exception
276
     * @throws \SmartyException
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
        // recursive call ?
295
        if (isset($tpl->templateId) ? $tpl->templateId : $tpl->_getTemplateId() !== $_templateId) {
296
            // already in template cache?
297
            if (isset(self::$tplObjCache[ $_templateId ])) {
298
                // copy data from cached object
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
                    // for inline templates we can get all resource information from file dependency
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
            // on recursive calls force caching
338
            $forceTplCache = true;
339
        }
340
        $tpl->caching = $caching;
341
        $tpl->cache_lifetime = $cache_lifetime;
342
        // set template scope
343
        $tpl->scope = $scope;
344
        if (!isset(self::$tplObjCache[ $tpl->templateId ]) && !$tpl->source->handler->recompiled) {
345
            // check if template object should be cached
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
            // set up variable values
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
     * Get called sub-templates and save call count
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
     * Check if this is a sub template
406
     *
407
     * @return bool true is sub template
408
     */
409
    public function _isSubTpl()
410
    {
411
        return isset($this->parent) && $this->parent->_isTplObj();
412
    }
413
414
    /**
415
     * Assign variable in scope
416
     *
417
     * @param string $varName variable name
418
     * @param mixed  $value   value
419
     * @param bool   $nocache nocache flag
420
     * @param int    $scope   scope into which variable shall be assigned
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
     * Check if plugins are callable require file otherwise
442
     *
443
     * @param array $plugins required plugins
444
     *
445
     * @throws \SmartyException
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
     * This function is executed automatically when a compiled or cached template file is included
476
     * - Decode saved properties from compiled template and cache files
477
     * - Check if compiled or cache file is valid
478
     *
479
     * @param \Smarty_Internal_Template $tpl
480
     * @param array                     $properties special template properties
481
     * @param bool                      $cache      flag if called from cache file
482
     *
483
     * @return bool flag if compiled or cache file is valid
484
     * @throws \SmartyException
485
     */
486
    public function _decodeProperties(Smarty_Internal_Template $tpl, $properties, $cache = false)
487
    {
488
        // on cache resources other than file check version stored in cache code
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
            // check file dependencies at compiled code
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
                        // do not recheck current template
506
                        continue;
507
                        //$mtime = $tpl->source->getTimeStamp();
508
                    } else {
509
                        // file and php types can be checked without loading the respective resource handlers
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
            // CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
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
            //            $tpl->compiled->nocache_hash = $properties['nocache_hash'];
546
            $resource->file_dependency = $properties[ 'file_dependency' ];
547
        }
548
        return $is_valid && !function_exists($properties[ 'unifunc' ]);
549
    }
550
551
    /**
552
     * Compiles the template
553
     * If the template is not evaluated the compiled template is saved on disk
554
     *
555
     * @throws \Exception
556
     */
557
    public function compileTemplateSource()
558
    {
559
        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...
560
    }
561
562
    /**
563
     * Writes the content to cache resource
564
     *
565
     * @param string $content
566
     *
567
     * @return bool
568
     */
569
    public function writeCachedContent($content)
570
    {
571
        return $this->smarty->ext->_updateCache->writeCachedContent($this, $content);
572
    }
573
574
    /**
575
     * Get unique template id
576
     *
577
     * @return string
578
     * @throws \SmartyException
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
     * runtime error not matching capture tags
588
     *
589
     * @throws \SmartyException
590
     */
591
    public function capture_error()
592
    {
593
        throw new SmartyException("Not matching {capture} open/close in '{$this->template_resource}'");
594
    }
595
596
    /**
597
     * Load compiled object
598
     *
599
     * @param bool $force force new compiled object
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
     * Load cached object
610
     *
611
     * @param bool $force force new cached object
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
     * Load inheritance object
622
     */
623
    public function _loadInheritance()
624
    {
625
        if (!isset($this->inheritance)) {
626
            $this->inheritance = new Smarty_Internal_Runtime_Inheritance();
627
        }
628
    }
629
630
    /**
631
     * Unload inheritance object
632
     */
633
    public function _cleanUp()
634
    {
635
        $this->startRenderCallbacks = array();
636
        $this->endRenderCallbacks = array();
637
        $this->inheritance = null;
638
    }
639
640
    /**
641
     * Load compiler object
642
     *
643
     * @throws \SmartyException
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
     * Handle unknown class methods
660
     *
661
     * @param string $name unknown method-name
662
     * @param array  $args argument array
663
     *
664
     * @return mixed
665
     */
666
    public function __call($name, $args)
667
    {
668
        // method of Smarty object?
669
        if (method_exists($this->smarty, $name)) {
670
            return call_user_func_array(array($this->smarty, $name), $args);
671
        }
672
        // parent
673
        return parent::__call($name, $args);
674
    }
675
676
    /**
677
     * get Smarty property in template context
678
     *
679
     * @param string $property_name property name
680
     *
681
     * @return mixed|Smarty_Template_Cached
682
     * @throws SmartyException
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
                // Smarty property ?
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
     * set Smarty property in template context
707
     *
708
     * @param string $property_name property name
709
     * @param mixed  $value         value
710
     *
711
     * @throws SmartyException
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
                // Smarty property ?
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
     * Template data object destructor
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