Commit | Line | Data |
---|---|---|
2aa91ff2 S |
1 | <?php |
2 | /** | |
3 | * Smarty Internal Plugin Compile Function | |
4 | * Compiles the {function} {/function} tags | |
5 | * | |
6 | * @package Smarty | |
7 | * @subpackage Compiler | |
8 | * @author Uwe Tews | |
9 | */ | |
10 | ||
11 | /** | |
12 | * Smarty Internal Plugin Compile Function Class | |
13 | * | |
14 | * @package Smarty | |
15 | * @subpackage Compiler | |
16 | */ | |
17 | class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase | |
18 | { | |
cd8826ea | 19 | |
2aa91ff2 S |
20 | /** |
21 | * Attribute definition: Overwrites base class. | |
22 | * | |
23 | * @var array | |
24 | * @see Smarty_Internal_CompileBase | |
25 | */ | |
26 | public $required_attributes = array('name'); | |
cd8826ea | 27 | |
2aa91ff2 S |
28 | /** |
29 | * Attribute definition: Overwrites base class. | |
30 | * | |
31 | * @var array | |
32 | * @see Smarty_Internal_CompileBase | |
33 | */ | |
34 | public $shorttag_order = array('name'); | |
cd8826ea | 35 | |
2aa91ff2 S |
36 | /** |
37 | * Attribute definition: Overwrites base class. | |
38 | * | |
39 | * @var array | |
40 | * @see Smarty_Internal_CompileBase | |
41 | */ | |
42 | public $optional_attributes = array('_any'); | |
43 | ||
44 | /** | |
45 | * Compiles code for the {function} tag | |
46 | * | |
47 | * @param array $args array with attributes from parser | |
48 | * @param object $compiler compiler object | |
49 | * @param array $parameter array with compilation parameter | |
50 | * | |
51 | * @return boolean true | |
52 | */ | |
53 | public function compile($args, $compiler, $parameter) | |
54 | { | |
55 | // check and get attributes | |
56 | $_attr = $this->getAttributes($compiler, $args); | |
57 | ||
58 | if ($_attr['nocache'] === true) { | |
59 | $compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno); | |
60 | } | |
61 | unset($_attr['nocache']); | |
ccd27f54 | 62 | $_name = trim($_attr['name'], "'\""); |
cd8826ea S |
63 | $compiler->parent_compiler->templateProperties['tpl_function'][$_name] = array(); |
64 | $save = array($_attr, $compiler->parser->current_buffer, $compiler->template->has_nocache_code, $compiler->template->required_plugins, $compiler->template->caching); | |
2aa91ff2 | 65 | $this->openTag($compiler, 'function', $save); |
2aa91ff2 S |
66 | // set flag that we are compiling a template function |
67 | $compiler->compiles_template_function = true; | |
2aa91ff2 S |
68 | // Init temporary context |
69 | $compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array()); | |
ccd27f54 | 70 | $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template($compiler->parser); |
2aa91ff2 | 71 | $compiler->template->has_nocache_code = false; |
ccd27f54 | 72 | $compiler->template->caching = true; |
2aa91ff2 S |
73 | return true; |
74 | } | |
75 | } | |
76 | ||
77 | /** | |
78 | * Smarty Internal Plugin Compile Functionclose Class | |
79 | * | |
80 | * @package Smarty | |
81 | * @subpackage Compiler | |
82 | */ | |
83 | class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase | |
84 | { | |
cd8826ea | 85 | |
ccd27f54 S |
86 | /** |
87 | * Compiler object | |
88 | * | |
89 | * @var object | |
90 | */ | |
91 | private $compiler = null; | |
92 | ||
2aa91ff2 S |
93 | /** |
94 | * Compiles code for the {/function} tag | |
95 | * | |
cd8826ea S |
96 | * @param array $args array with attributes from parser |
97 | * @param object|\Smarty_Internal_TemplateCompilerBase $compiler compiler object | |
98 | * @param array $parameter array with compilation parameter | |
2aa91ff2 | 99 | * |
cd8826ea | 100 | * @return bool true |
2aa91ff2 | 101 | */ |
ccd27f54 | 102 | public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) |
2aa91ff2 | 103 | { |
ccd27f54 | 104 | $this->compiler = $compiler; |
2aa91ff2 | 105 | $saved_data = $this->closeTag($compiler, array('function')); |
ccd27f54 S |
106 | $_attr = $saved_data[0]; |
107 | $_name = trim($_attr['name'], "'\""); | |
108 | // reset flag that we are compiling a template function | |
109 | $compiler->compiles_template_function = false; | |
110 | $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['called_functions'] = $compiler->called_functions; | |
111 | $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['compiled_filepath'] = $compiler->parent_compiler->template->compiled->filepath; | |
112 | $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['uid'] = $compiler->template->source->uid; | |
113 | $compiler->called_functions = array(); | |
114 | $_parameter = $_attr; | |
115 | unset($_parameter['name']); | |
116 | // default parameter | |
117 | $_paramsArray = array(); | |
118 | foreach ($_parameter as $_key => $_value) { | |
119 | if (is_int($_key)) { | |
120 | $_paramsArray[] = "$_key=>$_value"; | |
121 | } else { | |
122 | $_paramsArray[] = "'$_key'=>$_value"; | |
123 | } | |
124 | } | |
125 | if (!empty($_paramsArray)) { | |
126 | $_params = 'array(' . implode(",", $_paramsArray) . ')'; | |
127 | $_paramsCode = "\$params = array_merge($_params, \$params);\n"; | |
128 | } else { | |
129 | $_paramsCode = ''; | |
130 | } | |
131 | $_functionCode = $compiler->parser->current_buffer; | |
132 | // setup buffer for template function code | |
133 | $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template($compiler->parser); | |
134 | ||
135 | $_funcName = "smarty_template_function_{$_name}_{$compiler->template->properties['nocache_hash']}"; | |
136 | $_funcNameCaching = $_funcName . '_nocache'; | |
137 | if ($compiler->template->has_nocache_code) { | |
138 | $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['call_name_caching'] = $_funcNameCaching; | |
139 | $output = "<?php\n"; | |
140 | $output .= "/* {$_funcNameCaching} */\n"; | |
141 | $output .= "if (!function_exists('{$_funcNameCaching}')) {\n"; | |
142 | $output .= "function {$_funcNameCaching} (\$_smarty_tpl,\$params) {\n"; | |
143 | // build plugin include code | |
144 | if (!empty($compiler->template->required_plugins['compiled'])) { | |
145 | foreach ($compiler->template->required_plugins['compiled'] as $tmp) { | |
146 | foreach ($tmp as $data) { | |
147 | $output .= "if (!is_callable('{$data['function']}')) require_once '{$data['file']}';\n"; | |
148 | } | |
149 | } | |
150 | } | |
151 | if (!empty($compiler->template->required_plugins['nocache'])) { | |
152 | $output .= "echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php "; | |
153 | foreach ($compiler->template->required_plugins['nocache'] as $tmp) { | |
154 | foreach ($tmp as $data) { | |
155 | $output .= "if (!is_callable(\'{$data['function']}\')) require_once \'{$data['file']}\';\n"; | |
156 | } | |
2aa91ff2 | 157 | } |
ccd27f54 | 158 | $output .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';\n"; |
2aa91ff2 | 159 | } |
ccd27f54 S |
160 | $output .= "ob_start();\n"; |
161 | $output .= $_paramsCode; | |
162 | $output .= "\$_smarty_tpl->properties['saved_tpl_vars'][] = \$_smarty_tpl->tpl_vars;\n"; | |
163 | $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}"; | |
164 | $output .= "\$params = var_export(\$params, true);\n"; | |
165 | $output .= "echo \"/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php "; | |
166 | $output .= "\\\$saved_tpl_vars = \\\$_smarty_tpl->tpl_vars;\nforeach (\$params as \\\$key => \\\$value) {\n\\\$_smarty_tpl->tpl_vars[\\\$key] = new Smarty_Variable(\\\$value);\n}\n?>"; | |
167 | $output .= "/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/\n\";?>"; | |
168 | $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); | |
169 | $compiler->parser->current_buffer->append_subtree($_functionCode); | |
170 | $output = "<?php echo \"/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php "; | |
171 | $output .= "foreach (Smarty::\\\$global_tpl_vars as \\\$key => \\\$value){\n"; | |
172 | $output .= "if (\\\$_smarty_tpl->tpl_vars[\\\$key] === \\\$value) \\\$saved_tpl_vars[\\\$key] = \\\$value;\n}\n"; | |
173 | $output .= "\\\$_smarty_tpl->tpl_vars = \\\$saved_tpl_vars;?>\n"; | |
174 | $output .= "/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/\";\n?>"; | |
175 | $output .= "<?php echo str_replace('{$compiler->template->properties['nocache_hash']}', \$_smarty_tpl->properties['nocache_hash'], ob_get_clean());\n"; | |
176 | $output .= "\$_smarty_tpl->tpl_vars = array_pop(\$_smarty_tpl->properties['saved_tpl_vars']);\n}\n}\n"; | |
177 | $output .= "/*/ {$_funcName}_nocache */\n\n"; | |
178 | $output .= "?>\n"; | |
179 | $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); | |
180 | $_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser, preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%\*\/';(\?>\n)?)/", array($this, 'removeNocache'), $_functionCode->to_smarty_php())); | |
2aa91ff2 | 181 | } |
ccd27f54 S |
182 | $compiler->parent_compiler->templateProperties['tpl_function'][$_name]['call_name'] = $_funcName; |
183 | $output = "<?php\n"; | |
184 | $output .= "/* {$_funcName} */\n"; | |
185 | $output .= "if (!function_exists('{$_funcName}')) {\n"; | |
186 | $output .= "function {$_funcName}(\$_smarty_tpl,\$params) {\n"; | |
187 | // build plugin include code | |
2aa91ff2 | 188 | if (!empty($compiler->template->required_plugins['nocache'])) { |
ccd27f54 S |
189 | $compiler->template->required_plugins['compiled'] = array_merge($compiler->template->required_plugins['compiled'], $compiler->template->required_plugins['nocache']); |
190 | } | |
191 | if (!empty($compiler->template->required_plugins['compiled'])) { | |
192 | foreach ($compiler->template->required_plugins['compiled'] as $tmp) { | |
2aa91ff2 | 193 | foreach ($tmp as $data) { |
ccd27f54 | 194 | $output .= "if (!is_callable('{$data['function']}')) require_once '{$data['file']}';\n"; |
2aa91ff2 S |
195 | } |
196 | } | |
2aa91ff2 | 197 | } |
ccd27f54 S |
198 | $output .= "\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;\n"; |
199 | $output .= $_paramsCode; | |
200 | $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value);\n}?>"; | |
201 | $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); | |
202 | $compiler->parser->current_buffer->append_subtree($_functionCode); | |
203 | $output = "<?php foreach (Smarty::\$global_tpl_vars as \$key => \$value){\n"; | |
204 | $output .= "if (\$_smarty_tpl->tpl_vars[\$key] === \$value) \$saved_tpl_vars[\$key] = \$value;\n}\n"; | |
205 | $output .= "\$_smarty_tpl->tpl_vars = \$saved_tpl_vars;\n}\n}\n"; | |
206 | $output .= "/*/ {$_funcName} */\n\n"; | |
207 | $output .= "?>\n"; | |
208 | $compiler->parser->current_buffer->append_subtree(new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); | |
209 | $compiler->parent_compiler->templateFunctionCode .= $compiler->parser->current_buffer->to_smarty_php(); | |
210 | // restore old buffer | |
2aa91ff2 | 211 | $compiler->parser->current_buffer = $saved_data[1]; |
ccd27f54 S |
212 | // restore old status |
213 | $compiler->template->has_nocache_code = $saved_data[2]; | |
2aa91ff2 | 214 | $compiler->template->required_plugins = $saved_data[3]; |
ccd27f54 S |
215 | $compiler->template->caching = $saved_data[4]; |
216 | return true; | |
217 | } | |
2aa91ff2 | 218 | |
ccd27f54 S |
219 | /** |
220 | * @param $match | |
221 | * | |
222 | * @return mixed | |
223 | */ | |
224 | function removeNocache($match) | |
225 | { | |
226 | $code = preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->properties['nocache_hash']}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->properties['nocache_hash']}%%\*\/';(\?>\n)?)/", '', $match[0]); | |
227 | $code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code); | |
228 | return $code; | |
2aa91ff2 S |
229 | } |
230 | } |