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

Smarty_Internal_TemplateBase   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 308
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 308
rs 8.6
c 0
b 0
f 0
wmc 37
lcom 2
cbo 5

12 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 6 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 addDefaultModifier(mixed $modifiers)
24
 * @method Smarty_Internal_TemplateBase createData(Smarty_Internal_Data $parent = null, string $name = null)
25
 * @method array getAutoloadFilters(string $type = null)
26
 * @method string getDebugTemplate()
27
 * @method array getDefaultModifier()
28
 * @method array getTags(mixed $template = null)
29
 * @method object getRegisteredObject(string $object_name)
30
 * @method Smarty_Internal_TemplateBase registerCacheResource(string $name, Smarty_CacheResource $resource_handler)
31
 * @method Smarty_Internal_TemplateBase registerClass(string $class_name, string $class_impl)
32
 * @method Smarty_Internal_TemplateBase registerDefaultConfigHandler(callback $callback)
33
 * @method Smarty_Internal_TemplateBase registerDefaultPluginHandler(callback $callback)
34
 * @method Smarty_Internal_TemplateBase registerDefaultTemplateHandler(callback $callback)
35
 * @method Smarty_Internal_TemplateBase registerResource(string $name, mixed $resource_handler)
36
 * @method Smarty_Internal_TemplateBase setAutoloadFilters(mixed $filters, string $type = null)
37
 * @method Smarty_Internal_TemplateBase setDebugTemplate(string $tpl_name)
38
 * @method Smarty_Internal_TemplateBase setDefaultModifier(mixed $modifiers)
39
 * @method Smarty_Internal_TemplateBase unloadFilter(string $type, string $name)
40
 * @method Smarty_Internal_TemplateBase unregisterCacheResource(string $name)
41
 * @method Smarty_Internal_TemplateBase unregisterObject(string $object_name)
42
 * @method Smarty_Internal_TemplateBase unregisterPlugin(string $type, string $name)
43
 * @method Smarty_Internal_TemplateBase unregisterFilter(string $type, mixed $callback)
44
 * @method Smarty_Internal_TemplateBase unregisterResource(string $name)
45
 * @method Smarty _getSmartyObj()
46
 */
47
abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
48
{
49
    /**
50
     * Set this if you want different sets of cache files for the same
51
     * templates.
52
     *
53
     * @var string
54
     */
55
    public $cache_id = null;
56
57
    /**
58
     * Set this if you want different sets of compiled files for the same
59
     * templates.
60
     *
61
     * @var string
62
     */
63
    public $compile_id = null;
64
65
    /**
66
     * caching enabled
67
     *
68
     * @var boolean
69
     */
70
    public $caching = false;
71
72
    /**
73
     * cache lifetime in seconds
74
     *
75
     * @var integer
76
     */
77
    public $cache_lifetime = 3600;
78
79
    /**
80
     * Array of source information for known template functions
81
     *
82
     * @var array
83
     */
84
    public $tplFunctions = array();
85
86
    /**
87
     * universal cache
88
     *
89
     * @var array()
90
     */
91
    public $_cache = array();
92
93
    /**
94
     * fetches a rendered Smarty template
95
     *
96
     * @param  string $template   the resource handle of the template file or template object
97
     * @param  mixed  $cache_id   cache id to be used with this template
98
     * @param  mixed  $compile_id compile id to be used with this template
99
     * @param  object $parent     next higher level of Smarty variables
100
     *
101
     * @throws Exception
102
     * @throws SmartyException
103
     * @return string rendered template output
104
     */
105
    public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null)
106
    {
107
        $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 105 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...
108
        return $result === null ? ob_get_clean() : $result;
109
    }
110
111
    /**
112
     * displays a Smarty template
113
     *
114
     * @param string $template   the resource handle of the template file or template object
115
     * @param mixed  $cache_id   cache id to be used with this template
116
     * @param mixed  $compile_id compile id to be used with this template
117
     * @param object $parent     next higher level of Smarty variables
118
     */
119
    public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
120
    {
121
        // display template
122
        $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 119 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...
123
    }
124
125
    /**
126
     * test if cache is valid
127
     *
128
     * @api  Smarty::isCached()
129
     * @link http://www.smarty.net/docs/en/api.is.cached.tpl
130
     *
131
     * @param  null|string|\Smarty_Internal_Template $template   the resource handle of the template file or template object
132
     * @param  mixed                                 $cache_id   cache id to be used with this template
133
     * @param  mixed                                 $compile_id compile id to be used with this template
134
     * @param  object                                $parent     next higher level of Smarty variables
135
     *
136
     * @return boolean       cache status
137
     */
138
    public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null)
139
    {
140
        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 138 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 138 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...
141
    }
142
143
    /**
144
     * fetches a rendered Smarty template
145
     *
146
     * @param  string $template   the resource handle of the template file or template object
147
     * @param  mixed  $cache_id   cache id to be used with this template
148
     * @param  mixed  $compile_id compile id to be used with this template
149
     * @param  object $parent     next higher level of Smarty variables
150
     * @param  string $function   function type 0 = fetch,  1 = display, 2 = isCache
151
     *
152
     * @return mixed
153
     * @throws \Exception
154
     * @throws \SmartyException
155
     */
156
    private function _execute($template, $cache_id, $compile_id, $parent, $function)
157
    {
158
        $smarty = $this->_getSmartyObj();
159
        $saveVars = true;
160
        if ($template === null) {
161
            if (!$this->_isTplObj()) {
162
                throw new SmartyException($function . '():Missing \'$template\' parameter');
163
            } else {
164
                $template = $this;
165
            }
166
        } elseif (is_object($template)) {
167
            /* @var Smarty_Internal_Template $template */
168
            if (!isset($template->_objType) || !$template->_isTplObj()) {
169
                throw new SmartyException($function . '():Template object expected');
170
            }
171
        } else {
172
            // get template object
173
            $saveVars = false;
174
175
            $template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent ? $parent : $this, false);
176
            if ($this->_objType == 1) {
177
                // set caching in template object
178
                $template->caching = $this->caching;
179
            }
180
        }
181
        // fetch template content
182
        $level = ob_get_level();
183
        try {
184
            $_smarty_old_error_level =
185
                isset($smarty->error_reporting) ? error_reporting($smarty->error_reporting) : null;
186
            if ($this->_objType == 2) {
187
                /* @var Smarty_Internal_Template $this */
188
                $template->tplFunctions = $this->tplFunctions;
189
                $template->inheritance = $this->inheritance;
190
            }
191
            /* @var Smarty_Internal_Template $parent */
192
            if (isset($parent->_objType) && ($parent->_objType == 2) && !empty($parent->tplFunctions)) {
193
                $template->tplFunctions = array_merge($parent->tplFunctions, $template->tplFunctions);
194
            }
195
            if ($function == 2) {
196
                if ($template->caching) {
197
                    // return cache status of template
198
                    if (!isset($template->cached)) {
199
                        $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...
200
                    }
201
                    $result = $template->cached->isCached($template);
202
                    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...
203
                } else {
204
                    return false;
205
                }
206
            } else {
207
                if ($saveVars) {
208
                    $savedTplVars = $template->tpl_vars;
209
                    $savedConfigVars = $template->config_vars;
210
                }
211
                ob_start();
212
                $template->_mergeVars();
213
                if (!empty(Smarty::$global_tpl_vars)) {
214
                    $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...
215
                }
216
                $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...
217
                $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...
218
                if ($saveVars) {
219
                    $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...
220
                    $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...
221
                } else {
222
                    if (!$function && !isset(Smarty_Internal_Template::$tplObjCache[ $template->templateId ])) {
223
                        $template->parent = null;
224
                        $template->tpl_vars = $template->config_vars = array();
225
                        Smarty_Internal_Template::$tplObjCache[ $template->templateId ] = $template;
226
                    }
227
                }
228
            }
229
            if (isset($_smarty_old_error_level)) {
230
                error_reporting($_smarty_old_error_level);
231
            }
232
            return $result;
233
        }
234
        catch (Exception $e) {
235
            while (ob_get_level() > $level) {
236
                ob_end_clean();
237
            }
238
            if (isset($_smarty_old_error_level)) {
239
                error_reporting($_smarty_old_error_level);
240
            }
241
            throw $e;
242
        }
243
    }
244
245
    /**
246
     * Registers plugin to be used in templates
247
     *
248
     * @api  Smarty::registerPlugin()
249
     * @link http://www.smarty.net/docs/en/api.register.plugin.tpl
250
     *
251
     * @param  string   $type       plugin type
252
     * @param  string   $name       name of template tag
253
     * @param  callback $callback   PHP callback to register
254
     * @param  bool     $cacheable  if true (default) this function is cache able
255
     * @param  mixed    $cache_attr caching attributes if any
256
     *
257
     * @return \Smarty|\Smarty_Internal_Template
258
     * @throws SmartyException              when the plugin tag is invalid
259
     */
260
    public function registerPlugin($type, $name, $callback, $cacheable = true, $cache_attr = null)
261
    {
262
        return $this->ext->registerPlugin->registerPlugin($this, $type, $name, $callback, $cacheable, $cache_attr);
263
    }
264
265
    /**
266
     * load a filter of specified type and name
267
     *
268
     * @api  Smarty::loadFilter()
269
     * @link http://www.smarty.net/docs/en/api.load.filter.tpl
270
     *
271
     * @param  string $type filter type
272
     * @param  string $name filter name
273
     *
274
     * @return bool
275
     * @throws SmartyException if filter could not be loaded
276
     */
277
    public function loadFilter($type, $name)
278
    {
279
        return $this->ext->loadFilter->loadFilter($this, $type, $name);
280
    }
281
282
    /**
283
     * Registers a filter function
284
     *
285
     * @api  Smarty::registerFilter()
286
     * @link http://www.smarty.net/docs/en/api.register.filter.tpl
287
     *
288
     * @param  string      $type filter type
289
     * @param  callback    $callback
290
     * @param  string|null $name optional filter name
291
     *
292
     * @return \Smarty|\Smarty_Internal_Template
293
     * @throws \SmartyException
294
     */
295
    public function registerFilter($type, $callback, $name = null)
296
    {
297
        return $this->ext->registerFilter->registerFilter($this, $type, $callback, $name);
298
    }
299
300
    /**
301
     * Registers object to be used in templates
302
     *
303
     * @api  Smarty::registerObject()
304
     * @link http://www.smarty.net/docs/en/api.register.object.tpl
305
     *
306
     * @param  string $object_name
307
     * @param  object $object                     the referenced PHP object to register
308
     * @param  array  $allowed_methods_properties list of allowed methods (empty = all)
309
     * @param  bool   $format                     smarty argument format, else traditional
310
     * @param  array  $block_methods              list of block-methods
311
     *
312
     * @return \Smarty|\Smarty_Internal_Template
313
     * @throws \SmartyException
314
     */
315
    public function registerObject($object_name, $object, $allowed_methods_properties = array(), $format = true,
316
                                   $block_methods = array())
317
    {
318
        return $this->ext->registerObject->registerObject($this, $object_name, $object, $allowed_methods_properties,
319
                                                          $format, $block_methods);
320
    }
321
322
    /**
323
     * @param boolean $caching
324
     */
325
    public function setCaching($caching)
326
    {
327
        $this->caching = $caching;
328
    }
329
330
    /**
331
     * @param int $cache_lifetime
332
     */
333
    public function setCacheLifetime($cache_lifetime)
334
    {
335
        $this->cache_lifetime = $cache_lifetime;
336
    }
337
338
    /**
339
     * @param string $compile_id
340
     */
341
    public function setCompileId($compile_id)
342
    {
343
        $this->compile_id = $compile_id;
344
    }
345
346
    /**
347
     * @param string $cache_id
348
     */
349
    public function setCacheId($cache_id)
350
    {
351
        $this->cache_id = $cache_id;
352
    }
353
354
}
355
356