Smarty_Internal_Runtime_TplFunction   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 67
c 1
b 0
f 0
dl 0
loc 165
rs 9.92
wmc 31

6 Methods

Rating   Name   Duplication   Size   Complexity  
A saveTemplateVariables() 0 4 1
B addTplFuncToCache() 0 46 9
A restoreTemplateVariables() 0 6 2
A getTplFunction() 0 7 5
A registerTplFunctions() 0 10 4
B callTemplateFunction() 0 29 10
1
<?php
2
3
/**
4
 * TplFunction Runtime Methods callTemplateFunction
5
 *
6
 * @package    Smarty
7
 * @subpackage PluginsInternal
8
 * @author     Uwe Tews
9
 **/
10
class Smarty_Internal_Runtime_TplFunction
11
{
12
    /**
13
     * Call template function
14
     *
15
     * @param \Smarty_Internal_Template $tpl     template object
16
     * @param string                    $name    template function name
17
     * @param array                     $params  parameter array
18
     * @param bool                      $nocache true if called nocache
19
     *
20
     * @throws \SmartyException
21
     */
22
    public function callTemplateFunction(Smarty_Internal_Template $tpl, $name, $params, $nocache)
23
    {
24
        $funcParam = isset($tpl->tplFunctions[ $name ]) ? $tpl->tplFunctions[ $name ] :
25
            (isset($tpl->smarty->tplFunctions[ $name ]) ? $tpl->smarty->tplFunctions[ $name ] : null);
26
        if (isset($funcParam)) {
27
            if (!$tpl->caching || ($tpl->caching && $nocache)) {
28
                $function = $funcParam[ 'call_name' ];
29
            } else {
30
                if (isset($funcParam[ 'call_name_caching' ])) {
31
                    $function = $funcParam[ 'call_name_caching' ];
32
                } else {
33
                    $function = $funcParam[ 'call_name' ];
34
                }
35
            }
36
            if (function_exists($function)) {
37
                $this->saveTemplateVariables($tpl, $name);
38
                $function($tpl, $params);
39
                $this->restoreTemplateVariables($tpl, $name);
40
                return;
41
            }
42
            // try to load template function dynamically
43
            if ($this->addTplFuncToCache($tpl, $name, $function)) {
44
                $this->saveTemplateVariables($tpl, $name);
45
                $function($tpl, $params);
46
                $this->restoreTemplateVariables($tpl, $name);
47
                return;
48
            }
49
        }
50
        throw new SmartyException("Unable to find template function '{$name}'");
51
    }
52
53
    /**
54
     * Register template functions defined by template
55
     *
56
     * @param \Smarty|\Smarty_Internal_Template|\Smarty_Internal_TemplateBase $obj
57
     * @param array                                                           $tplFunctions source information array of
58
     *                                                                                      template functions defined
59
     *                                                                                      in template
60
     * @param bool                                                            $override     if true replace existing
61
     *                                                                                      functions with same name
62
     */
63
    public function registerTplFunctions(Smarty_Internal_TemplateBase $obj, $tplFunctions, $override = true)
64
    {
65
        $obj->tplFunctions =
66
            $override ? array_merge($obj->tplFunctions, $tplFunctions) : array_merge($tplFunctions, $obj->tplFunctions);
67
        // make sure that the template functions are known in parent templates
68
        if ($obj->_isSubTpl()) {
0 ignored issues
show
Bug introduced by
The method _isSubTpl() does not exist on Smarty_Internal_TemplateBase. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

68
        if ($obj->/** @scrutinizer ignore-call */ _isSubTpl()) {
Loading history...
69
            $obj->smarty->ext->_tplFunction->registerTplFunctions($obj->parent, $tplFunctions, false);
0 ignored issues
show
Bug introduced by
It seems like $obj->parent can also be of type Smarty_Data; however, parameter $obj of Smarty_Internal_Runtime_...:registerTplFunctions() does only seem to accept Smarty_Internal_TemplateBase, 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

69
            $obj->smarty->ext->_tplFunction->registerTplFunctions(/** @scrutinizer ignore-type */ $obj->parent, $tplFunctions, false);
Loading history...
70
        } else {
71
            $obj->smarty->tplFunctions = $override ? array_merge($obj->smarty->tplFunctions, $tplFunctions) :
72
                array_merge($tplFunctions, $obj->smarty->tplFunctions);
73
        }
74
    }
75
76
    /**
77
     * Return source parameter array for single or all template functions
78
     *
79
     * @param \Smarty_Internal_Template $tpl  template object
80
     * @param null|string               $name template function name
81
     *
82
     * @return array|bool|mixed
83
     */
84
    public function getTplFunction(Smarty_Internal_Template $tpl, $name = null)
85
    {
86
        if (isset($name)) {
87
            return isset($tpl->tplFunctions[ $name ]) ? $tpl->tplFunctions[ $name ] :
88
                (isset($tpl->smarty->tplFunctions[ $name ]) ? $tpl->smarty->tplFunctions[ $name ] : false);
89
        } else {
90
            return empty($tpl->tplFunctions) ? $tpl->smarty->tplFunctions : $tpl->tplFunctions;
91
        }
92
    }
93
94
    /**
95
     * Add template function to cache file for nocache calls
96
     *
97
     * @param Smarty_Internal_Template $tpl
98
     * @param string                   $_name     template function name
99
     * @param string                   $_function PHP function name
100
     *
101
     * @return bool
102
     */
103
    public function addTplFuncToCache(Smarty_Internal_Template $tpl, $_name, $_function)
104
    {
105
        $funcParam = $tpl->tplFunctions[ $_name ];
106
        if (is_file($funcParam[ 'compiled_filepath' ])) {
107
            // read compiled file
108
            $code = file_get_contents($funcParam[ 'compiled_filepath' ]);
109
            // grab template function
110
            if (preg_match("/\/\* {$_function} \*\/([\S\s]*?)\/\*\/ {$_function} \*\//", $code, $match)) {
111
                // grab source info from file dependency
112
                preg_match("/\s*'{$funcParam['uid']}'([\S\s]*?)\),/", $code, $match1);
113
                unset($code);
114
                // make PHP function known
115
                eval($match[ 0 ]);
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
116
                if (function_exists($_function)) {
117
                    // search cache file template
118
                    $tplPtr = $tpl;
119
                    while (!isset($tplPtr->cached) && isset($tplPtr->parent)) {
120
                        $tplPtr = $tplPtr->parent;
121
                    }
122
                    // add template function code to cache file
123
                    if (isset($tplPtr->cached)) {
0 ignored issues
show
Bug Best Practice introduced by
The property cached does not exist on Smarty. Since you implemented __get, consider adding a @property annotation.
Loading history...
124
                        $content = $tplPtr->cached->read($tplPtr);
0 ignored issues
show
Bug introduced by
The method read() does not exist on null. ( Ignorable by Annotation )

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

124
                        /** @scrutinizer ignore-call */ 
125
                        $content = $tplPtr->cached->read($tplPtr);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
125
                        if ($content) {
126
                            // check if we must update file dependency
127
                            if (!preg_match("/'{$funcParam['uid']}'(.*?)'nocache_hash'/", $content, $match2)) {
128
                                $content = preg_replace("/('file_dependency'(.*?)\()/", "\\1{$match1[0]}", $content);
129
                            }
130
                            $tplPtr->smarty->ext->_updateCache->write(
131
                                $tplPtr,
132
                                preg_replace('/\s*\?>\s*$/', "\n", $content) .
133
                                "\n" . preg_replace(
134
                                    array(
135
                                        '/^\s*<\?php\s+/',
136
                                        '/\s*\?>\s*$/',
137
                                    ),
138
                                    "\n",
139
                                    $match[ 0 ]
140
                                )
141
                            );
142
                        }
143
                    }
144
                    return true;
145
                }
146
            }
147
        }
148
        return false;
149
    }
150
151
    /**
152
     * Save current template variables on stack
153
     *
154
     * @param \Smarty_Internal_Template $tpl
155
     * @param string                    $name stack name
156
     */
157
    public function saveTemplateVariables(Smarty_Internal_Template $tpl, $name)
158
    {
159
        $tpl->_cache[ 'varStack' ][] =
160
            array('tpl' => $tpl->tpl_vars, 'config' => $tpl->config_vars, 'name' => "_tplFunction_{$name}");
161
    }
162
163
    /**
164
     * Restore saved variables into template objects
165
     *
166
     * @param \Smarty_Internal_Template $tpl
167
     * @param string                    $name stack name
168
     */
169
    public function restoreTemplateVariables(Smarty_Internal_Template $tpl, $name)
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed. ( Ignorable by Annotation )

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

169
    public function restoreTemplateVariables(Smarty_Internal_Template $tpl, /** @scrutinizer ignore-unused */ $name)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
170
    {
171
        if (isset($tpl->_cache[ 'varStack' ])) {
172
            $vars = array_pop($tpl->_cache[ 'varStack' ]);
173
            $tpl->tpl_vars = $vars[ 'tpl' ];
174
            $tpl->config_vars = $vars[ 'config' ];
175
        }
176
    }
177
}
178