More rewrites to make use of (cached) wrapper functions
[mailer.git] / inc / expression-functions.php
1 <?php
2 /************************************************************************
3  * Mailer v0.2.1-FINAL                                Start: 04/12/2009 *
4  * ===================                          Last change: 04/12/2009 *
5  *                                                                      *
6  * -------------------------------------------------------------------- *
7  * File              : expression-functions.php                         *
8  * -------------------------------------------------------------------- *
9  * Short description : Expression callback functions                    *
10  * -------------------------------------------------------------------- *
11  * Kurzbeschreibung  : Expression-Callback-Funktionen                   *
12  * -------------------------------------------------------------------- *
13  * $Revision::                                                        $ *
14  * $Date::                                                            $ *
15  * $Tag:: 0.2.1-FINAL                                                 $ *
16  * $Author::                                                          $ *
17  * Needs to be in all Files and every File needs "svn propset           *
18  * svn:keywords Date Revision" (autoprobset!) at least!!!!!!            *
19  * -------------------------------------------------------------------- *
20  * Copyright (c) 2003 - 2009 by Roland Haeder                           *
21  * Copyright (c) 2009, 2010 by Mailer Developer Team                    *
22  * For more information visit: http://www.mxchange.org                  *
23  *                                                                      *
24  * This program is free software; you can redistribute it and/or modify *
25  * it under the terms of the GNU General Public License as published by *
26  * the Free Software Foundation; either version 2 of the License, or    *
27  * (at your option) any later version.                                  *
28  *                                                                      *
29  * This program is distributed in the hope that it will be useful,      *
30  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
32  * GNU General Public License for more details.                         *
33  *                                                                      *
34  * You should have received a copy of the GNU General Public License    *
35  * along with this program; if not, write to the Free Software          *
36  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,               *
37  * MA  02110-1301  USA                                                  *
38  ************************************************************************/
39
40 // Some security stuff...
41 if (!defined('__SECURITY')) {
42         die();
43 } // END - if
44
45 // Private function to replace the code
46 function replaceExpressionCode ($data, $replacer) {
47         // Replace the code
48         // @TODO is escapeQuotes() enougth for strings with single/double quotes?
49         return str_replace($data['matches'][0][$data['key']], $replacer, escapeQuotes($data['code']));
50 }
51
52 // Private function to determine wether we have a special expression function avaible
53 // (mostly located in wrapper-functions.php)
54 function isExpressionFunctionAvaiable ($data) {
55         // Get the enty we need
56         $entry = $data['matches'][4][$data['key']];
57
58         // Do we have cache?
59         if (!isset($GLOBALS['expression_function_available'][$entry])) {
60                 // Init function name
61                 $functionName = 'get';
62
63                 // Explode it in an array
64                 foreach (explode('_', $entry) as $piece) {
65                         // Add non-empty parts
66                         if (!empty($piece)) {
67                                 // Add it
68                                 $functionName .= ucfirst(strtolower($piece));
69                         } // END - if
70                 } // END - foreach
71
72                 // Is that function there?
73                 if (function_exists($functionName)) {
74                         // Cache it all
75                         $GLOBALS['expression_function_name'][$entry] = $functionName;
76                         $GLOBALS['expression_function_available'][$entry] = true;
77                 } else {
78                         // Not avaiable
79                         logDebugMessage(__FUNCTION__, __LINE__, 'Expression function ' . $functionName . ' not found. Please consider adding it to improve execution speed.');
80
81                         // And cache it
82                         $GLOBALS['expression_function_available'][$entry] = false;
83                 }
84         } elseif ($GLOBALS['expression_function_available'][$entry] == false) {
85                 // Debug message
86                 logDebugMessage(__FUNCTION__, __LINE__, 'Expression function for entry ' . $entry . ' requested but not found.');
87         }
88
89         // Return cache
90         return $GLOBALS['expression_function_available'][$entry];
91 }
92
93 // Getter for above expression function
94 function getExpressionFunction ($data) {
95         // Get the enty we need
96         $entry = $data['matches'][4][$data['key']];
97
98         // Return it
99         return $GLOBALS['expression_function_name'][$entry];
100 }
101
102 // Expression call-back function for getCode() calls
103 function doExpressionCode ($data) {
104         // Replace the code
105         $code = str_replace($data['matches'][0][$data['key']], "{DQUOTE} . getCode('" . $data['matches'][4][$data['key']] . "') . {DQUOTE}", $data['code']);
106
107         // Return replaced code
108         return $code;
109 }
110
111 // Expression call-back function for URLs
112 function doExpressionUrl ($data) {
113         // Do we have JS-mode?
114         if ($data['callback'] == 'js') $data['mode'] = 1;
115
116         // Handle an URL here
117         $replacer = "{DQUOTE} . encodeUrl('" . $data['matches'][4][$data['key']] . "', " . $data['mode'] . ') . {DQUOTE}';
118
119         // Replace it
120         $code = replaceExpressionCode($data, $replacer);
121
122         // Return replaced code
123         return $code;
124 }
125
126 // Expression call-back function for reading data from $_SERVER
127 function doExpressionServer ($data) {
128         // This will make 'foo_bar' to detectFooBar()
129         $functionName = "'detect' . implode('', array_map('ucfirst', explode('_', '" . $data['callback'] . "')))";
130
131         // Generate replacer
132         $replacer = '{DQUOTE} . call_user_func(' . $functionName . ') . {DQUOTE}';
133
134         // Replace it
135         $code = replaceExpressionCode($data, $replacer);
136
137         // Return replaced code
138         return $code;
139 }
140
141 // Expression call-back function for fetching user data
142 function doExpressionUser ($data) {
143         // Use current userid by default
144         $functionName = 'getMemberId()';
145
146         // User-related data, so is there a userid?
147         if (!empty($data['matches'][4][$data['key']])) {
148                 // Do we have a userid or $userid?
149                 if ($data['matches'][4][$data['key']] == '$userid') {
150                         // Use dynamic call
151                         $functionName = "getFetchedUserData('userid', \$userid, '" . $data['callback'] . "')";
152                 } elseif (!empty($data['matches'][4][$data['key']])) {
153                         // User data found
154                         $functionName = "getFetchedUserData('userid', " . $data['matches'][4][$data['key']] . ", '" . $data['callback'] . "')";
155                 }
156         } elseif ((!empty($data['callback'])) && (isUserDataValid())) {
157                 // "Call-back" alias column for current logged in user's data
158                 $functionName = "getUserData('" . $data['callback'] . "')";
159         }
160
161         // Do we have another function to run (e.g. translations)
162         if (!empty($data['extra_func'])) {
163                 // Surround the original function call with it
164                 $functionName = $data['extra_func'] . '(' . $functionName . ')';
165         } // END - if
166
167         // Generate replacer
168         $replacer = '{DQUOTE} . ' . $functionName . ' . {DQUOTE}';
169
170         // Now replace the code
171         $code = replaceExpressionCode($data, $replacer);
172
173         // Return replaced code
174         return $code;
175 }
176
177 // Expression call-back function for getting extension data
178 function doExpressionExt ($data) {
179         // Not installed is default
180         $replacer = 'false';
181
182         // Is the extension installed?
183         if (isExtensionInstalled($data['matches'][4][$data['key']])) {
184                 // Construct call-back function name
185                 $functionName = 'getExtension' . ucfirst(strtolower($data['callback']));
186
187                 // Construct call of the function
188                 $replacer = "{DQUOTE} . call_user_func_array('" . $functionName . "', array('" . $data['matches'][4][$data['key']] . "', true)) . {DQUOTE}";
189         } // END - if
190
191         // Generate replacer
192         $replacer = sprintf("&amp;ext=%s&amp;ver=%s&amp;rev={?CURR_SVN_REVISION?}", $data['matches'][4][$data['key']], $replacer);
193
194         // Replace it and insert parameter for GET request
195         $code = replaceExpressionCode($data, $replacer);
196
197         // Return replaced code
198         return $code;
199 }
200
201 // Expression call-back function for getting configuration data
202 // @TODO FILTER_COMPILE_CONFIG does not handle call-back functions so we handle it here again
203 function doExpressionConfig ($data) {
204         // Do we have a special expression function for it?
205         if (isExpressionFunctionAvaiable($data)) {
206                 // Then use it
207                 $replacer = '{DQUOTE}  . ' . $data['callback'] . '('.getExpressionFunction($data).'(' . "'" . $data['matches'][4][$data['key']] . "'" . ')) . {DQUOTE}';
208         } else {
209                 // Default replacer is the config value itself
210                 $replacer = '{DQUOTE}  . ' . $data['callback'] . '(getConfig(' . "'" . $data['matches'][4][$data['key']] . "'" . ')) . {DQUOTE}';
211         }
212
213         // Replace the config entry
214         $code = replaceExpressionCode($data, $replacer);
215
216         // Return replaced code
217         return $code;
218 }
219
220 // Expression call-back function for piping data through functions
221 function doExpressionPipe ($data) {
222         // We need callback and extra_func: callback is really the call-back function, extra_func is our value
223         $replacer = $data['extra_func'];
224
225         // Is the extra_func empty and value set?
226         if ((empty($replacer)) && (isset($data['value']))) {
227                 // Then use this
228                 $replacer = $data['value'];
229         } // END - if
230
231         // Do we have a call-back? Should always be there!
232         if (!empty($data['callback'])) {
233                 // Parse it through this function
234                 $replacer = '{DQUOTE} . ' . $data['extra_func'] . '(' . $data['callback'] . "('" . $replacer . "')) . {DQUOTE}";
235         } // END - if
236
237         // Replace the config entry
238         $code = replaceExpressionCode($data, $replacer);
239
240         // Return replaced code
241         return $code;
242 }
243
244 // Expression call-back function for calling filters
245 function doExpressionFilter ($data) {
246         // Construct replacement
247         $replacer = "{DQUOTE} . runFilterChain('" . $data['matches'][4][$data['key']] . "') . {DQUOTE}";
248
249         // Run the filter and insert result
250         $code = replaceExpressionCode($data, $replacer);
251
252         // Return replaced code
253         return $code;
254 }
255
256 // Expression call-back function for validator links
257 function doExpressionValidatorLinks ($data) {
258         // Default is nothing
259         $replacer = '';
260
261         // Get the code from data array for replacement/pipe-through
262         $code = $data['code'];
263
264         // Should we generally include validator links?
265         if ((isExtensionInstalled('validator')) && (getConfig('enable_validator') == 'Y') && (!in_array(getModule(), array('admin', 'login')))) {
266                 // Load the validator template
267                 $replacer = escapeQuotes(loadTemplate('validator_links', true));
268         } // END - if
269
270         // Replace the code
271         $code = replaceExpressionCode($data, $replacer);
272
273         // Return the (maybe) replaced code
274         return $code;
275 }
276
277 // Expression call-back for dynamic messages
278 function doExpressionMessage ($data) {
279         // Debug message
280         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'callback=' . $data['callback'] . ',extra_func=' . $data['extra_func'] . ',value=' . $data['value']);
281
282         // Message string replacement depends on if message is masked
283         if ((isMessageMasked($data['callback'])) && ((!empty($data['extra_func'])) || ($data['extra_func'] == '0'))) {
284                 // Message should be masked
285                 $replacer = "{DQUOTE} . getMaskedMessage('" . $data['callback'] . "', '" . $data['extra_func'] . "') . {DQUOTE}";
286         } elseif (!empty($data['value'])) {
287                 // value is set, so it is masked message
288                 $replacer = "{DQUOTE} . getMaskedMessage('" . $data['callback'] . "', '" . $data['value'] . "') . {DQUOTE}";
289         } else {
290                 // Regular message
291                 $replacer = "{DQUOTE} . getMessage('" . $data['callback'] . "') . {DQUOTE}";
292         }
293
294         // Replace the code
295         $code = replaceExpressionCode($data, $replacer);
296
297         // Return the (maybe) replaced code
298         return $code;
299 }
300
301 // Expression call-back for template functions
302 function doExpressionTemplate ($data) {
303         // Do the replacement
304         //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'template='.$GLOBALS['current_template']);
305         $replacer = '{DQUOTE} . doTemplate' . $data['callback'] . "('" . $GLOBALS['current_template'] . "', true) . {DQUOTE}";
306
307         // Replace the code
308         $code = replaceExpressionCode($data, $replacer);
309
310         // Return the (maybe) replaced code
311         return $code;
312 }
313
314 // [EOF]
315 ?>