Smarty_Internal_TemplateBase   A
last analyzed

Complexity

Total Complexity 38

Size/Duplication

Total Lines 338
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 338
rs 9.36
c 0
b 0
f 0
wmc 38
lcom 2
cbo 5

13 Methods

Rating   Name   Duplication   Size   Complexity  
A fetch() 0 5 2
A display() 0 5 1
A isCached() 0 4 1
F _execute() 0 88 25
A registerPlugin() 0 4 1
A loadFilter() 0 4 1
A registerFilter() 0 4 1
A registerObject() 0 16 1
A setCompileCheck() 0 4 1
A setCaching() 0 4 1
A setCacheLifetime() 0 4 1
A setCompileId() 0 4 1
A setCacheId() 0 4 1
1
<?php
2
/**
3
 * Smarty Internal Plugin Smarty Template  Base
4
 * This file contains the basic shared methods for template handling
5
 *
6
 * @package    Smarty
7
 * @subpackage Template
8
 * @author     Uwe Tews
9
 */
10
11
/**
12
 * Class with shared smarty/template methods
13
 *
14
 * @package    Smarty
15
 * @subpackage Template
16
 *
17
 * @property int $_objType
18
 *
19
 * The following methods will be dynamically loaded by the extension handler when they are called.
20
 * They are located in a corresponding Smarty_Internal_Method_xxxx class
21
 *
22
 * @method Smarty_Internal_TemplateBase addAutoloadFilters(mixed $filters, string $type = null)
23
 * @method Smarty_Internal_TemplateBase addDefaultModifiers(mixed $modifiers)
24
 * @method Smarty_Internal_TemplateBase addLiterals(mixed $literals)
25
 * @method Smarty_Internal_TemplateBase createData(Smarty_Internal_Data $parent = null, string $name = null)
26
 * @method array getAutoloadFilters(string $type = null)
27
 * @method string getDebugTemplate()
28
 * @method array getDefaultModifier()
29
 * @method array getLiterals()
30
 * @method array getTags(mixed $template = null)
31
 * @method object getRegisteredObject(string $object_name)
32
 * @method Smarty_Internal_TemplateBase registerCacheResource(string $name, Smarty_CacheResource $resource_handler)
33
 * @method Smarty_Internal_TemplateBase registerClass(string $class_name, string $class_impl)
34
 * @method Smarty_Internal_TemplateBase registerDefaultConfigHandler(callback $callback)
35
 * @method Smarty_Internal_TemplateBase registerDefaultPluginHandler(callback $callback)
36
 * @method Smarty_Internal_TemplateBase registerDefaultTemplateHandler(callback $callback)
37
 * @method Smarty_Internal_TemplateBase registerResource(string $name, mixed $resource_handler)
38
 * @method Smarty_Internal_TemplateBase setAutoloadFilters(mixed $filters, string $type = null)
39
 * @method Smarty_Internal_TemplateBase setDebugTemplate(string $tpl_name)
40
 * @method Smarty_Internal_TemplateBase setDefaultModifiers(mixed $modifiers)
41
 * @method Smarty_Internal_TemplateBase setLiterals(mixed $literals)
42
 * @method Smarty_Internal_TemplateBase unloadFilter(string $type, string $name)
43
 * @method Smarty_Internal_TemplateBase unregisterCacheResource(string $name)
44
 * @method Smarty_Internal_TemplateBase unregisterObject(string $object_name)
45
 * @method Smarty_Internal_TemplateBase unregisterPlugin(string $type, string $name)
46
 * @method Smarty_Internal_TemplateBase unregisterFilter(string $type, mixed $callback)
47
 * @method Smarty_Internal_TemplateBase unregisterResource(string $name)
48
 */
49
abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
50
{
51
    /**
52
     * Set this if you want different sets of cache files for the same
53
     * templates.
54
     *
55
     * @var string
56
     */
57
    public $cache_id = null;
58
59
    /**
60
     * Set this if you want different sets of compiled files for the same
61
     * templates.
62
     *
63
     * @var string
64
     */
65
    public $compile_id = null;
66
67
    /**
68
     * caching enabled
69
     *
70
     * @var int
71
     */
72
    public $caching = Smarty::CACHING_OFF;
73
74
    /**
75
     * check template for modifications?
76
     *
77
     * @var int
78
     */
79
    public $compile_check = Smarty::COMPILECHECK_ON;
80
81
    /**
82
     * cache lifetime in seconds
83
     *
84
     * @var integer
85
     */
86
    public $cache_lifetime = 3600;
87
88
    /**
89
     * Array of source information for known template functions
90
     *
91
     * @var array
92
     */
93
    public $tplFunctions = array();
94
95
    /**
96
     * universal cache
97
     *
98
     * @var array()
99
     */
100
    public $_cache = array();
101
102
    /**
103
     * fetches a rendered Smarty template
104
     *
105
     * @param string $template   the resource handle of the template file or template object
106
     * @param mixed  $cache_id   cache id to be used with this template
107
     * @param mixed  $compile_id compile id to be used with this template
108
     * @param object $parent     next higher level of Smarty variables
109
     *
110
     * @throws Exception
111
     * @throws SmartyException
112
     * @return string rendered template output
113
     */
114
    public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null)
115
    {
116
        $result = $this->_execute($template, $cache_id, $compile_id, $parent, 0);
0 ignored issues
show
Bug introduced by
It seems like $parent defined by parameter $parent on line 114 can also be of type null; however, Smarty_Internal_TemplateBase::_execute() does only seem to accept object, 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...
117
        return $result === null ? ob_get_clean() : $result;
118
    }
119
120
    /**
121
     * displays a Smarty template
122
     *
123
     * @param string $template   the resource handle of the template file or template object
124
     * @param mixed  $cache_id   cache id to be used with this template
125
     * @param mixed  $compile_id compile id to be used with this template
126
     * @param object $parent     next higher level of Smarty variables
127
     *
128
     * @throws \Exception
129
     * @throws \SmartyException
130
     */
131
    public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
132
    {
133
        // display template
134
        $this->_execute($template, $cache_id, $compile_id, $parent, 1);
0 ignored issues
show
Bug introduced by
It seems like $parent defined by parameter $parent on line 131 can also be of type null; however, Smarty_Internal_TemplateBase::_execute() does only seem to accept object, 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...
135
    }
136
137
    /**
138
     * test if cache is valid
139
     *
140
     * @api  Smarty::isCached()
141
     * @link http://www.smarty.net/docs/en/api.is.cached.tpl
142
     *
143
     * @param null|string|\Smarty_Internal_Template $template   the resource handle of the template file or template
144
     *                                                          object
145
     * @param mixed                                 $cache_id   cache id to be used with this template
146
     * @param mixed                                 $compile_id compile id to be used with this template
147
     * @param object                                $parent     next higher level of Smarty variables
148
     *
149
     * @return bool cache status
150
     * @throws \Exception
151
     * @throws \SmartyException
152
     */
153
    public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null)
154
    {
155
        return $this->_execute($template, $cache_id, $compile_id, $parent, 2);
0 ignored issues
show
Bug introduced by
It seems like $template defined by parameter $template on line 153 can also be of type null or object<Smarty_Internal_Template>; however, Smarty_Internal_TemplateBase::_execute() does only seem to accept string, 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...
Bug introduced by
It seems like $parent defined by parameter $parent on line 153 can also be of type null; however, Smarty_Internal_TemplateBase::_execute() does only seem to accept object, 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...
156
    }
157
158
    /**
159
     * fetches a rendered Smarty template
160
     *
161
     * @param string $template   the resource handle of the template file or template object
162
     * @param mixed  $cache_id   cache id to be used with this template
163
     * @param mixed  $compile_id compile id to be used with this template
164
     * @param object $parent     next higher level of Smarty variables
165
     * @param string $function   function type 0 = fetch,  1 = display, 2 = isCache
166
     *
167
     * @return mixed
168
     * @throws \Exception
169
     * @throws \SmartyException
170
     */
171
    private function _execute($template, $cache_id, $compile_id, $parent, $function)
172
    {
173
        $smarty = $this->_getSmartyObj();
174
        $saveVars = true;
175
        if ($template === null) {
176
            if (!$this->_isTplObj()) {
177
                throw new SmartyException($function . '():Missing \'$template\' parameter');
178
            } else {
179
                $template = $this;
180
            }
181
        } elseif (is_object($template)) {
182
            /* @var Smarty_Internal_Template $template */
183
            if (!isset($template->_objType) || !$template->_isTplObj()) {
184
                throw new SmartyException($function . '():Template object expected');
185
            }
186
        } else {
187
            // get template object
188
            $saveVars = false;
189
            $template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent ? $parent : $this, false);
190
            if ($this->_objType === 1) {
191
                // set caching in template object
192
                $template->caching = $this->caching;
193
            }
194
        }
195
        // make sure we have integer values
196
        $template->caching = (int)$template->caching;
197
        // fetch template content
198
        $level = ob_get_level();
199
        try {
200
            $_smarty_old_error_level =
201
                isset($smarty->error_reporting) ? error_reporting($smarty->error_reporting) : null;
202
            if ($this->_objType === 2) {
203
                /* @var Smarty_Internal_Template $this */
204
                $template->tplFunctions = $this->tplFunctions;
205
                $template->inheritance = $this->inheritance;
206
            }
207
            /* @var Smarty_Internal_Template $parent */
208
            if (isset($parent->_objType) && ($parent->_objType === 2) && !empty($parent->tplFunctions)) {
209
                $template->tplFunctions = array_merge($parent->tplFunctions, $template->tplFunctions);
210
            }
211
            if ($function === 2) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $function (string) and 2 (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
212
                if ($template->caching) {
213
                    // return cache status of template
214
                    if (!isset($template->cached)) {
215
                        $template->loadCached();
0 ignored issues
show
Documentation Bug introduced by
The method loadCached does not exist on object<Smarty_Internal_TemplateBase>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
216
                    }
217
                    $result = $template->cached->isCached($template);
218
                    Smarty_Internal_Template::$isCacheTplObj[ $template->_getTemplateId() ] = $template;
0 ignored issues
show
Documentation Bug introduced by
The method _getTemplateId does not exist on object<Smarty_Internal_TemplateBase>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
219
                } else {
220
                    return false;
221
                }
222
            } else {
223
                if ($saveVars) {
224
                    $savedTplVars = $template->tpl_vars;
225
                    $savedConfigVars = $template->config_vars;
226
                }
227
                ob_start();
228
                $template->_mergeVars();
229
                if (!empty(Smarty::$global_tpl_vars)) {
230
                    $template->tpl_vars = array_merge(Smarty::$global_tpl_vars, $template->tpl_vars);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge(\Smarty::$gl...s, $template->tpl_vars) of type array is incompatible with the declared type array<integer,object<Smarty_Variable>> of property $tpl_vars.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
231
                }
232
                $result = $template->render(false, $function);
0 ignored issues
show
Documentation Bug introduced by
The method render does not exist on object<Smarty_Internal_TemplateBase>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
233
                $template->_cleanUp();
0 ignored issues
show
Documentation Bug introduced by
The method _cleanUp does not exist on object<Smarty_Internal_TemplateBase>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
234
                if ($saveVars) {
235
                    $template->tpl_vars = $savedTplVars;
0 ignored issues
show
Bug introduced by
The variable $savedTplVars does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
236
                    $template->config_vars = $savedConfigVars;
0 ignored issues
show
Bug introduced by
The variable $savedConfigVars does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
237
                } else {
238
                    if (!$function && !isset(Smarty_Internal_Template::$tplObjCache[ $template->templateId ])) {
239
                        $template->parent = null;
240
                        $template->tpl_vars = $template->config_vars = array();
241
                        Smarty_Internal_Template::$tplObjCache[ $template->templateId ] = $template;
242
                    }
243
                }
244
            }
245
            if (isset($_smarty_old_error_level)) {
246
                error_reporting($_smarty_old_error_level);
247
            }
248
            return $result;
249
        } catch (Exception $e) {
250
            while (ob_get_level() > $level) {
251
                ob_end_clean();
252
            }
253
            if (isset($_smarty_old_error_level)) {
254
                error_reporting($_smarty_old_error_level);
255
            }
256
            throw $e;
257
        }
258
    }
259
260
    /**
261
     * Registers plugin to be used in templates
262
     *
263
     * @api  Smarty::registerPlugin()
264
     * @link http://www.smarty.net/docs/en/api.register.plugin.tpl
265
     *
266
     * @param string   $type       plugin type
267
     * @param string   $name       name of template tag
268
     * @param callback $callback   PHP callback to register
269
     * @param bool     $cacheable  if true (default) this function is cache able
270
     * @param mixed    $cache_attr caching attributes if any
271
     *
272
     * @return \Smarty|\Smarty_Internal_Template
273
     * @throws \SmartyException
274
     */
275
    public function registerPlugin($type, $name, $callback, $cacheable = true, $cache_attr = null)
276
    {
277
        return $this->ext->registerPlugin->registerPlugin($this, $type, $name, $callback, $cacheable, $cache_attr);
278
    }
279
280
    /**
281
     * load a filter of specified type and name
282
     *
283
     * @api  Smarty::loadFilter()
284
     * @link http://www.smarty.net/docs/en/api.load.filter.tpl
285
     *
286
     * @param string $type filter type
287
     * @param string $name filter name
288
     *
289
     * @return bool
290
     * @throws \SmartyException
291
     */
292
    public function loadFilter($type, $name)
293
    {
294
        return $this->ext->loadFilter->loadFilter($this, $type, $name);
295
    }
296
297
    /**
298
     * Registers a filter function
299
     *
300
     * @api  Smarty::registerFilter()
301
     * @link http://www.smarty.net/docs/en/api.register.filter.tpl
302
     *
303
     * @param string      $type filter type
304
     * @param callback    $callback
305
     * @param string|null $name optional filter name
306
     *
307
     * @return \Smarty|\Smarty_Internal_Template
308
     * @throws \SmartyException
309
     */
310
    public function registerFilter($type, $callback, $name = null)
311
    {
312
        return $this->ext->registerFilter->registerFilter($this, $type, $callback, $name);
313
    }
314
315
    /**
316
     * Registers object to be used in templates
317
     *
318
     * @api  Smarty::registerObject()
319
     * @link http://www.smarty.net/docs/en/api.register.object.tpl
320
     *
321
     * @param string $object_name
322
     * @param object $object                     the referenced PHP object to register
323
     * @param array  $allowed_methods_properties list of allowed methods (empty = all)
324
     * @param bool   $format                     smarty argument format, else traditional
325
     * @param array  $block_methods              list of block-methods
326
     *
327
     * @return \Smarty|\Smarty_Internal_Template
328
     * @throws \SmartyException
329
     */
330
    public function registerObject(
331
        $object_name,
332
        $object,
333
        $allowed_methods_properties = array(),
334
        $format = true,
335
        $block_methods = array()
336
    ) {
337
        return $this->ext->registerObject->registerObject(
338
            $this,
339
            $object_name,
340
            $object,
341
            $allowed_methods_properties,
342
            $format,
343
            $block_methods
344
        );
345
    }
346
347
    /**
348
     * @param int $compile_check
349
     */
350
    public function setCompileCheck($compile_check)
351
    {
352
        $this->compile_check = (int)$compile_check;
353
    }
354
355
    /**
356
     * @param int $caching
357
     */
358
    public function setCaching($caching)
359
    {
360
        $this->caching = (int)$caching;
361
    }
362
363
    /**
364
     * @param int $cache_lifetime
365
     */
366
    public function setCacheLifetime($cache_lifetime)
367
    {
368
        $this->cache_lifetime = $cache_lifetime;
369
    }
370
371
    /**
372
     * @param string $compile_id
373
     */
374
    public function setCompileId($compile_id)
375
    {
376
        $this->compile_id = $compile_id;
377
    }
378
379
    /**
380
     * @param string $cache_id
381
     */
382
    public function setCacheId($cache_id)
383
    {
384
        $this->cache_id = $cache_id;
385
    }
386
}
387