Completed
Branch master (e379bd)
by Pierre-Henry
33:06
created

Smarty_Internal_Template::__construct()   C

Complexity

Conditions 9
Paths 128

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 16
nc 128
nop 8
dl 0
loc 22
rs 5.8333
c 0
b 0
f 0

How to fix   Many Parameters   

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
 *
21
 * The following methods will be dynamically loaded by the extension handler when they are called.
22
 * They are located in a corresponding Smarty_Internal_Method_xxxx class
23
 *
24
 * @method bool mustCompile()
25
 */
26
class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
27
{
28
    /**
29
     * This object type (Smarty = 1, template = 2, data = 4)
30
     *
31
     * @var int
32
     */
33
    public $_objType = 2;
34
35
    /**
36
     * Global smarty instance
37
     *
38
     * @var Smarty
39
     */
40
    public $smarty = null;
41
42
    /**
43
     * Source instance
44
     *
45
     * @var Smarty_Template_Source|Smarty_Template_Config
46
     */
47
    public $source = null;
48
49
    /**
50
     * Inheritance runtime extension
51
     *
52
     * @var Smarty_Internal_Runtime_Inheritance
53
     */
54
    public $inheritance = null;
55
56
    /**
57
     * Template resource
58
     *
59
     * @var string
60
     */
61
    public $template_resource = null;
62
63
    /**
64
     * flag if compiled template is invalid and must be (re)compiled
65
     *
66
     * @var bool
67
     */
68
    public $mustCompile = null;
69
70
    /**
71
     * Template Id
72
     *
73
     * @var null|string
74
     */
75
    public $templateId = null;
76
77
    /**
78
     * Scope in which variables shall be assigned
79
     *
80
     * @var int
81
     */
82
    public $scope = 0;
83
84
    /**
85
     * Flag which is set while rending a cache file
86
     *
87
     * @var bool
88
     */
89
    public $isRenderingCache = false;
90
91
    /**
92
     * Callbacks called before rendering template
93
     *
94
     * @var callback[]
95
     */
96
    public $startRenderCallbacks = array();
97
98
    /**
99
     * Callbacks called after rendering template
100
     *
101
     * @var callback[]
102
     */
103
    public $endRenderCallbacks = array();
104
105
    /**
106
     * Template object cache
107
     *
108
     * @var Smarty_Internal_Template[]
109
     */
110
    public static $tplObjCache = array();
111
112
    /**
113
     * Template object cache for Smarty::isCached() == true
114
     *
115
     * @var Smarty_Internal_Template[]
116
     */
117
    public static $isCacheTplObj = array();
118
119
    /**
120
     * Subtemplate Info Cache
121
     *
122
     * @var string[]int[]
123
     */
124
    public static $subTplInfo = array();
125
126
    /**
127
     * Create template data object
128
     * Some of the global Smarty settings copied to template scope
129
     * It load the required template resources and caching plugins
130
     *
131
     * @param string                                                       $template_resource template resource string
132
     * @param Smarty                                                       $smarty            Smarty instance
133
     * @param null|\Smarty_Internal_Template|\Smarty|\Smarty_Internal_Data $_parent           back pointer to parent object
134
     *                                                                                        with variables or null
135
     * @param mixed                                                        $_cache_id         cache   id or null
136
     * @param mixed                                                        $_compile_id       compile id or null
137
     * @param bool|int|null                                                $_caching          use caching?
138
     * @param int|null                                                     $_cache_lifetime   cache life-time in seconds
139
     * @param bool                                                         $_isConfig
140
     *
141
     * @throws \SmartyException
142
     */
143
    public function __construct($template_resource, Smarty $smarty, Smarty_Internal_Data $_parent = null,
144
                                $_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null,
145
                                $_isConfig = false)
146
    {
147
        $this->smarty = $smarty;
148
        // Smarty parameter
149
        $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
150
        $this->compile_id = $_compile_id === null ? $this->smarty->compile_id : $_compile_id;
151
        $this->caching = $_caching === null ? $this->smarty->caching : $_caching;
0 ignored issues
show
Documentation Bug introduced by
It seems like $_caching === null ? $th...ty->caching : $_caching can also be of type integer. However, the property $caching is declared as type boolean. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
152
        if ($this->caching === true) {
153
            $this->caching = Smarty::CACHING_LIFETIME_CURRENT;
154
        }
155
        $this->cache_lifetime = $_cache_lifetime === null ? $this->smarty->cache_lifetime : $_cache_lifetime;
156
        $this->parent = $_parent;
157
        // Template resource
158
        $this->template_resource = $template_resource;
159
        $this->source = $_isConfig ? Smarty_Template_Config::load($this) : Smarty_Template_Source::load($this);
160
        parent::__construct();
161
        if ($smarty->security_policy && method_exists($smarty->security_policy, 'registerCallBacks')) {
162
            $smarty->security_policy->registerCallBacks($this);
163
        }
164
    }
165
166
    /**
167
     * render template
168
     *
169
     * @param  bool      $no_output_filter if true do not run output filter
170
     * @param  null|bool $display          true: display, false: fetch null: sub-template
171
     *
172
     * @return string
173
     * @throws \SmartyException
174
     */
175
    public function render($no_output_filter = true, $display = null)
176
    {
177
        if ($this->smarty->debugging) {
178
            if (!isset($this->smarty->_debug)) {
179
                $this->smarty->_debug = new Smarty_Internal_Debug();
180
            }
181
            $this->smarty->_debug->start_template($this, $display);
0 ignored issues
show
Bug introduced by
It seems like $display defined by parameter $display on line 175 can also be of type boolean; however, Smarty_Internal_Debug::start_template() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
182
        }
183
        // checks if template exists
184
        if (!$this->source->exists) {
185
            throw new SmartyException("Unable to load template '{$this->source->type}:{$this->source->name}'" .
186
                                      ($this->_isSubTpl() ? " in '{$this->parent->template_resource}'" : ''));
0 ignored issues
show
Bug introduced by
The property template_resource does not seem to exist in Smarty_Internal_Data.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
187
        }
188
        // disable caching for evaluated code
189
        if ($this->source->handler->recompiled) {
190
            $this->caching = false;
191
        }
192
        // read from cache or render
193
        $isCacheTpl =
194
            $this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED;
195
        if ($isCacheTpl) {
196
            if (!isset($this->cached) || $this->cached->cache_id !== $this->cache_id ||
197
                $this->cached->compile_id !== $this->compile_id
198
            ) {
199
                $this->loadCached(true);
200
            }
201
            $this->cached->render($this, $no_output_filter);
202
        } else {
203
            if (!isset($this->compiled) || $this->compiled->compile_id !== $this->compile_id) {
204
                $this->loadCompiled(true);
205
            }
206
            $this->compiled->render($this);
207
        }
208
209
        // display or fetch
210
        if ($display) {
211
            if ($this->caching && $this->smarty->cache_modified_check) {
212
                $this->smarty->ext->_cacheModify->cacheModifiedCheck($this->cached, $this,
213
                                                                     isset($content) ? $content : ob_get_clean());
0 ignored issues
show
Bug introduced by
The variable $content seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
214
            } else {
215
                if ((!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled) &&
216
                    !$no_output_filter && (isset($this->smarty->autoload_filters[ 'output' ]) ||
217
                                           isset($this->smarty->registered_filters[ 'output' ]))
218
                ) {
219
                    echo $this->smarty->ext->_filterHandler->runFilter('output', ob_get_clean(), $this);
220
                } else {
221
                    echo ob_get_clean();
222
                }
223
            }
224
            if ($this->smarty->debugging) {
225
                $this->smarty->_debug->end_template($this);
226
                // debug output
227
                $this->smarty->_debug->display_debug($this, true);
228
            }
229
            return '';
230
        } else {
231
            if ($this->smarty->debugging) {
232
                $this->smarty->_debug->end_template($this);
233
                if ($this->smarty->debugging === 2 && $display === false) {
234
                    $this->smarty->_debug->display_debug($this, true);
235
                }
236
            }
237
            if ($this->_isSubTpl()) {
238
                foreach ($this->compiled->required_plugins as $code => $tmp1) {
239
                    foreach ($tmp1 as $name => $tmp) {
240
                        foreach ($tmp as $type => $data) {
241
                            $this->parent->compiled->required_plugins[ $code ][ $name ][ $type ] = $data;
0 ignored issues
show
Bug introduced by
The property compiled does not seem to exist in Smarty_Internal_Data.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
242
                        }
243
                    }
244
                }
245
            }
246
            if (!$no_output_filter &&
247
                (!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled) &&
248
                (isset($this->smarty->autoload_filters[ 'output' ]) ||
249
                 isset($this->smarty->registered_filters[ 'output' ]))
250
            ) {
251
                return $this->smarty->ext->_filterHandler->runFilter('output', ob_get_clean(), $this);
252
            }
253
            // return cache content
254
            return null;
255
        }
256
    }
257
258
    /**
259
     * Runtime function to render sub-template
260
     *
261
     * @param string  $template       template name
262
     * @param mixed   $cache_id       cache id
263
     * @param mixed   $compile_id     compile id
264
     * @param integer $caching        cache mode
265
     * @param integer $cache_lifetime life time of cache data
266
     * @param array   $data           passed parameter template variables
267
     * @param int     $scope          scope in which {include} should execute
268
     * @param bool    $forceTplCache  cache template object
269
     * @param string  $uid            file dependency uid
270
     * @param string  $content_func   function name
271
     *
272
     */
273
    public function _subTemplateRender($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $scope,
274
                                       $forceTplCache, $uid = null, $content_func = null)
275
    {
276
        $tpl = clone $this;
277
        $tpl->parent = $this;
278
        $smarty = &$this->smarty;
279
        $_templateId = $smarty->_getTemplateId($template, $cache_id, $compile_id, $caching, $tpl);
280
        // recursive call ?
281
        if (isset($tpl->templateId) ? $tpl->templateId : $tpl->_getTemplateId() != $_templateId) {
282
            // already in template cache?
283
            if (isset(self::$tplObjCache[ $_templateId ])) {
284
                // copy data from cached object
285
                $cachedTpl = &self::$tplObjCache[ $_templateId ];
286
                $tpl->templateId = $cachedTpl->templateId;
287
                $tpl->template_resource = $cachedTpl->template_resource;
288
                $tpl->cache_id = $cachedTpl->cache_id;
289
                $tpl->compile_id = $cachedTpl->compile_id;
290
                $tpl->source = $cachedTpl->source;
291
                if (isset($cachedTpl->compiled)) {
292
                    $tpl->compiled = $cachedTpl->compiled;
293
                } else {
294
                    unset($tpl->compiled);
295
                }
296
                if ($caching != 9999 && isset($cachedTpl->cached)) {
297
                    $tpl->cached = $cachedTpl->cached;
298
                } else {
299
                    unset($tpl->cached);
300
                }
301
            } else {
302
                $tpl->templateId = $_templateId;
303
                $tpl->template_resource = $template;
304
                $tpl->cache_id = $cache_id;
305
                $tpl->compile_id = $compile_id;
306
                if (isset($uid)) {
307
                    // for inline templates we can get all resource information from file dependency
308
                    list($filepath, $timestamp, $type) = $tpl->compiled->file_dependency[ $uid ];
309
                    $tpl->source = new Smarty_Template_Source($smarty, $filepath, $type, $filepath);
310
                    $tpl->source->filepath = $filepath;
311
                    $tpl->source->timestamp = $timestamp;
312
                    $tpl->source->exists = true;
313
                    $tpl->source->uid = $uid;
314
                } else {
315
                    $tpl->source = Smarty_Template_Source::load($tpl);
316
                    unset($tpl->compiled);
317
                }
318
                if ($caching != 9999) {
319
                    unset($tpl->cached);
320
                }
321
            }
322
        } else {
323
            // on recursive calls force caching
324
            $forceTplCache = true;
325
        }
326
        $tpl->caching = $caching;
0 ignored issues
show
Documentation Bug introduced by
The property $caching was declared of type boolean, but $caching is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
327
        $tpl->cache_lifetime = $cache_lifetime;
328
        // set template scope
329
        $tpl->scope = $scope;
330
        if (!isset(self::$tplObjCache[ $tpl->templateId ]) && !$tpl->source->handler->recompiled) {
331
            // check if template object should be cached
332
            if ($forceTplCache || (isset(self::$subTplInfo[ $tpl->template_resource ]) &&
333
                                   self::$subTplInfo[ $tpl->template_resource ] > 1) ||
334
                ($tpl->_isSubTpl() &&  isset(self::$tplObjCache[ $tpl->parent->templateId ]))
335
            ) {
336
                self::$tplObjCache[ $tpl->templateId ] = $tpl;
337
            }
338
        }
339
340
        if (!empty($data)) {
341
            // set up variable values
342
            foreach ($data as $_key => $_val) {
343
                $tpl->tpl_vars[ $_key ] = new Smarty_Variable($_val, $this->isRenderingCache);
344
            }
345
        }
346
        if ($tpl->caching == 9999) {
347
            if (!isset($tpl->compiled)) {
348
                $this->loadCompiled(true);
349
            }
350
            if ($tpl->compiled->has_nocache_code) {
351
                $this->cached->hashes[ $tpl->compiled->nocache_hash ] = true;
352
            }
353
        }
354
        $tpl->_cache = array();
355
        if (isset($uid)) {
356
            if ($smarty->debugging) {
357
                if (!isset($smarty->_debug)) {
358
                    $smarty->_debug = new Smarty_Internal_Debug();
359
                }
360
                $smarty->_debug->start_template($tpl);
361
                $smarty->_debug->start_render($tpl);
362
            }
363
            $tpl->compiled->getRenderedTemplateCode($tpl, $content_func);
364
            if ($smarty->debugging) {
365
                $smarty->_debug->end_template($tpl);
366
                $smarty->_debug->end_render($tpl);
367
            }
368
        } else {
369
            if (isset($tpl->compiled)) {
370
                $tpl->compiled->render($tpl);
371
            } else {
372
                $tpl->render();
373
            }
374
        }
375
    }
376
377
    /**
378
     * Get called sub-templates and save call count
379
     *
380
     */
381
    public function _subTemplateRegister()
382
    {
383
        foreach ($this->compiled->includes as $name => $count) {
384
            if (isset(self::$subTplInfo[ $name ])) {
385
                self::$subTplInfo[ $name ] += $count;
386
            } else {
387
                self::$subTplInfo[ $name ] = $count;
388
            }
389
        }
390
    }
391
392
    /**
393
     * Check if this is a sub template
394
     *
395
     * @return bool true is sub template
396
     */
397
    public function _isSubTpl()
398
    {
399
        return isset($this->parent) && $this->parent->_isTplObj();
400
    }
401
402
    /**
403
     * Assign variable in scope
404
     *
405
     * @param string $varName variable name
406
     * @param mixed  $value   value
407
     * @param bool   $nocache nocache flag
408
     * @param int    $scope   scope into which variable shall be assigned
409
     *
410
     */
411
    public function _assignInScope($varName, $value, $nocache = false, $scope = 0)
412
    {
413
        if (isset($this->tpl_vars[ $varName ])) {
414
            $this->tpl_vars[ $varName ] = clone $this->tpl_vars[ $varName ];
415
            $this->tpl_vars[ $varName ]->value = $value;
416
            if ($nocache || $this->isRenderingCache) {
417
                $this->tpl_vars[ $varName ]->nocache = true;
418
            }
419
        } else {
420
            $this->tpl_vars[ $varName ] = new Smarty_Variable($value, $nocache || $this->isRenderingCache);
421
        }
422
        if ($scope >= 0) {
423
            if ($scope > 0 || $this->scope > 0) {
424
                $this->smarty->ext->_updateScope->_updateScope($this, $varName, $scope);
425
            }
426
        }
427
    }
428
429
    /**
430
     * This function is executed automatically when a compiled or cached template file is included
431
     * - Decode saved properties from compiled template and cache files
432
     * - Check if compiled or cache file is valid
433
     *
434
     * @param \Smarty_Internal_Template $tpl
435
     * @param  array                    $properties special template properties
436
     * @param  bool                     $cache      flag if called from cache file
437
     *
438
     * @return bool flag if compiled or cache file is valid
439
     * @throws \SmartyException
440
     */
441
    public function _decodeProperties(Smarty_Internal_Template $tpl, $properties, $cache = false)
442
    {
443
        // on cache resources other than file check version stored in cache code
444
        if (!isset($properties[ 'version' ]) || Smarty::SMARTY_VERSION !== $properties[ 'version' ]) {
445
            if ($cache) {
446
                $tpl->smarty->clearAllCache();
447
            } else {
448
                $tpl->smarty->clearCompiledTemplate();
449
            }
450
            return false;
451
        }
452
        $is_valid = true;
453
        if (!empty($properties[ 'file_dependency' ]) &&
454
                  ((!$cache && $tpl->smarty->compile_check) || $tpl->smarty->compile_check == 1)
455
        ) {
456
            // check file dependencies at compiled code
457
            foreach ($properties[ 'file_dependency' ] as $_file_to_check) {
458
                if ($_file_to_check[ 2 ] == 'file' || $_file_to_check[ 2 ] == 'php') {
459
                    if ($tpl->source->filepath == $_file_to_check[ 0 ]) {
460
                        // do not recheck current template
461
                        continue;
462
                        //$mtime = $tpl->source->getTimeStamp();
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
463
                    } else {
464
                        // file and php types can be checked without loading the respective resource handlers
465
                        $mtime = is_file($_file_to_check[ 0 ]) ? filemtime($_file_to_check[ 0 ]) : false;
466
                    }
467
                } else {
468
                    $handler = Smarty_Resource::load($tpl->smarty, $_file_to_check[ 2 ]);
469
                    if ($handler->checkTimestamps()) {
470
                        $source = Smarty_Template_Source::load($tpl, $tpl->smarty, $_file_to_check[ 0 ]);
471
                        $mtime = $source->getTimeStamp();
472
                    } else {
473
                        continue;
474
                    }
475
                }
476
                if ($mtime === false || $mtime > $_file_to_check[ 1 ]) {
477
                    $is_valid = false;
478
                    break;
479
                }
480
            }
481
        }
482
        if ($cache) {
483
            // CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
484
            if ($tpl->caching === Smarty::CACHING_LIFETIME_SAVED && $properties[ 'cache_lifetime' ] >= 0 &&
485
                (time() > ($tpl->cached->timestamp + $properties[ 'cache_lifetime' ]))
486
            ) {
487
                $is_valid = false;
488
            }
489
            $tpl->cached->cache_lifetime = $properties[ 'cache_lifetime' ];
490
            $tpl->cached->valid = $is_valid;
491
            $resource = $tpl->cached;
492
        } else {
493
            $tpl->mustCompile = !$is_valid;
494
            $resource = $tpl->compiled;
495
            $resource->includes = isset($properties[ 'includes' ]) ? $properties[ 'includes' ] : array();
496
        }
497
        if ($is_valid) {
498
            $resource->unifunc = $properties[ 'unifunc' ];
499
            $resource->has_nocache_code = $properties[ 'has_nocache_code' ];
500
            //            $tpl->compiled->nocache_hash = $properties['nocache_hash'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
501
            $resource->file_dependency = $properties[ 'file_dependency' ];
502
        }
503
        return $is_valid && !function_exists($properties[ 'unifunc' ]);
504
    }
505
506
    /**
507
     * Compiles the template
508
     * If the template is not evaluated the compiled template is saved on disk
509
     */
510
    public function compileTemplateSource()
511
    {
512
        return $this->compiled->compileTemplateSource($this);
513
    }
514
515
    /**
516
     * Writes the content to cache resource
517
     *
518
     * @param string $content
519
     *
520
     * @return bool
521
     */
522
    public function writeCachedContent($content)
523
    {
524
        return $this->smarty->ext->_updateCache->writeCachedContent($this->cached, $this, $content);
525
    }
526
527
    /**
528
     * Get unique template id
529
     *
530
     * @return string
531
     */
532
    public function _getTemplateId()
533
    {
534
        return isset($this->templateId) ? $this->templateId : $this->templateId =
535
            $this->smarty->_getTemplateId($this->template_resource, $this->cache_id, $this->compile_id);
536
    }
537
538
    /**
539
     * runtime error not matching capture tags
540
     */
541
    public function capture_error()
542
    {
543
        throw new SmartyException("Not matching {capture} open/close in \"{$this->template_resource}\"");
544
    }
545
546
    /**
547
     * Load compiled object
548
     *
549
     * @param bool $force force new compiled object
550
     */
551
    public function loadCompiled($force = false)
552
    {
553
        if ($force || !isset($this->compiled)) {
554
            $this->compiled = Smarty_Template_Compiled::load($this);
555
        }
556
    }
557
558
    /**
559
     * Load cached object
560
     *
561
     * @param bool $force force new cached object
562
     */
563
    public function loadCached($force = false)
564
    {
565
        if ($force || !isset($this->cached)) {
566
            $this->cached = Smarty_Template_Cached::load($this);
567
        }
568
    }
569
570
    /**
571
     * Load inheritance object
572
     *
573
     */
574
    public function _loadInheritance()
575
    {
576
        if (!isset($this->inheritance)) {
577
            $this->inheritance = new Smarty_Internal_Runtime_Inheritance();
578
        }
579
    }
580
581
    /**
582
     * Unload inheritance object
583
     *
584
     */
585
    public function _cleanUp()
586
    {
587
        $this->startRenderCallbacks = array();
588
        $this->endRenderCallbacks = array();
589
        $this->inheritance = null;
590
    }
591
592
    /**
593
     * Load compiler object
594
     *
595
     * @throws \SmartyException
596
     */
597
    public function loadCompiler()
598
    {
599
        if (!class_exists($this->source->compiler_class)) {
600
            $this->smarty->loadPlugin($this->source->compiler_class);
601
        }
602
        $this->compiler =
603
            new $this->source->compiler_class($this->source->template_lexer_class, $this->source->template_parser_class,
604
                                              $this->smarty);
605
    }
606
607
    /**
608
     * Handle unknown class methods
609
     *
610
     * @param string $name unknown method-name
611
     * @param array  $args argument array
612
     *
613
     * @return mixed
614
     * @throws SmartyException
615
     */
616
    public function __call($name, $args)
617
    {
618
        // method of Smarty object?
619
        if (method_exists($this->smarty, $name)) {
620
            return call_user_func_array(array($this->smarty, $name), $args);
621
        }
622
        // parent
623
        return parent::__call($name, $args);
624
    }
625
626
    /**
627
     * set Smarty property in template context
628
     *
629
     * @param string $property_name property name
630
     * @param mixed  $value         value
631
     *
632
     * @throws SmartyException
633
     */
634
    public function __set($property_name, $value)
635
    {
636
        switch ($property_name) {
637
            case 'compiled':
638
            case 'cached':
639
            case 'compiler':
640
                $this->$property_name = $value;
641
                return;
642
            default:
643
                // Smarty property ?
644
                if (property_exists($this->smarty, $property_name)) {
645
                    $this->smarty->$property_name = $value;
646
                    return;
647
                }
648
        }
649
        throw new SmartyException("invalid template property '$property_name'.");
650
    }
651
652
    /**
653
     * get Smarty property in template context
654
     *
655
     * @param string $property_name property name
656
     *
657
     * @return mixed|Smarty_Template_Cached
658
     * @throws SmartyException
659
     */
660
    public function __get($property_name)
661
    {
662
        switch ($property_name) {
663
            case 'compiled':
664
                $this->loadCompiled();
665
                return $this->compiled;
666
667
            case 'cached':
668
                $this->loadCached();
669
                return $this->cached;
670
671
            case 'compiler':
672
                $this->loadCompiler();
673
                return $this->compiler;
674
            default:
675
                // Smarty property ?
676
                if (property_exists($this->smarty, $property_name)) {
677
                    return $this->smarty->$property_name;
678
                }
679
        }
680
        throw new SmartyException("template property '$property_name' does not exist.");
681
    }
682
683
    /**
684
     * Template data object destructor
685
     */
686
    public function __destruct()
687
    {
688
        if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
689
            $this->cached->handler->releaseLock($this->smarty, $this->cached);
690
        }
691
    }
692
}
693