* $Date:: $ *
* $Tag:: 0.2.1-FINAL $ *
* $Author:: $ *
- * Needs to be in all Files and every File needs "svn propset *
- * svn:keywords Date Revision" (autoprobset!) at least!!!!!! *
* -------------------------------------------------------------------- *
* Copyright (c) 2003 - 2009 by Roland Haeder *
- * Copyright (c) 2009, 2010 by Mailer Developer Team *
- * For more information visit: http://www.mxchange.org *
+ * Copyright (c) 2009 - 2012 by Mailer Developer Team *
+ * For more information visit: http://mxchange.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
die();
} // END - if
+// Private function to replace the code
+function replaceExpressionCode ($data, $replacer) {
+ // Replace the code
+ // @TODO is escapeQuotes() enough for strings with single/double quotes?
+ return str_replace($data['matches'][0][$data['key']], $replacer, escapeQuotes($data['code']));
+}
+
+// Private function to determine whether we have a special expression function avaible
+// (mostly located in wrapper-functions.php)
+function isExpressionFunctionAvaiable ($data) {
+ // Get the enty we need and trim it
+ $entry = trim($data['matches'][4][$data['key']]);
+
+ // Is there cache?
+ if (!isset($GLOBALS['expression_function_available'][$entry])) {
+ // Init function name
+ $functionName = 'get';
+
+ // Explode it in an array
+ foreach (explode('_', $entry) as $piece) {
+ // Add non-empty parts
+ if (!empty($piece)) {
+ // Add it
+ $functionName .= capitalizeUnderscoreString($piece);
+ } // END - if
+ } // END - foreach
+
+ // Is that function there?
+ if (function_exists($functionName)) {
+ // Cache it all
+ $GLOBALS['expression_function_name'][$entry] = $functionName;
+ $GLOBALS['expression_function_available'][$entry] = TRUE;
+ } else {
+ // Not avaiable
+ logDebugMessage(__FUNCTION__, __LINE__, 'Expression function ' . $functionName . ' not found. Please consider adding it to improve execution speed.');
+
+ // And cache it
+ $GLOBALS['expression_function_available'][$entry] = FALSE;
+ }
+ } elseif (($GLOBALS['expression_function_available'][$entry] == FALSE) && (isDebugModeEnabled())) {
+ // Debug message in debug mode
+ logDebugMessage(__FUNCTION__, __LINE__, 'Expression function for entry ' . $entry . ' requested but does not exist.');
+ }
+
+ // Return cache
+ return $GLOBALS['expression_function_available'][$entry];
+}
+
+// Getter for above expression function
+function getExpressionFunction ($data) {
+ // Get the enty we need
+ $entry = trim($data['matches'][4][$data['key']]);
+
+ // Return it
+ return $GLOBALS['expression_function_name'][$entry];
+}
+
// Expression call-back function for getCode() calls
function doExpressionCode ($data) {
// Replace the code
- $code = str_replace($data['matches'][0][$data['key']], "\" . getCode('" . $data['matches'][4][$data['key']] . "') . \"", $data['code']);
+ $code = str_replace($data['matches'][0][$data['key']], "{DQUOTE} . getCode('" . $data['matches'][4][$data['key']] . "') . {DQUOTE}", $data['code']);
// Return replaced code
return $code;
}
-// Expression call-back function for URLs
+// Expression call-back function for URLs (example: {%url=foo.php?bar=bar%})
function doExpressionUrl ($data) {
- // Do we have JS-mode?
- if ($data['callback'] == 'js') $data['mode'] = 1;
+ // Is there JS-mode?
+ if ($data['callback'] == 'js') {
+ // Switch to it
+ $data['output_mode'] = '1';
+ } // END - if
// Handle an URL here
- $replacer = "\" . encodeUrl(\"" . $data['matches'][4][$data['key']] . "\", " . $data['mode'] . ") . \"";
+ $replacer = "{DQUOTE} . encodeUrl('" . $data['matches'][4][$data['key']] . "', " . $data['output_mode'] . ') . {DQUOTE}';
+
+ // Debug log
+ //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'replacer=' . $replacer . ',callback=' . $data['callback'] . ',output_mode=' . $data['output_mode']);
// Replace it
- $code = str_replace($data['matches'][0][$data['key']], $replacer, $data['code']);
+ $code = replaceExpressionCode($data, $replacer);
// Return replaced code
return $code;
// Expression call-back function for reading data from $_SERVER
function doExpressionServer ($data) {
// This will make 'foo_bar' to detectFooBar()
- $functionName = "'detect' . implode('', array_map('ucfirst', explode('_', '" . $data['callback'] . "')))";
-
- // Replace it
- $code = str_replace($data['matches'][0][$data['key']], "\" . call_user_func(" . $functionName . ") . \"", $data['code']);
+ $functionName = "'detect' . implode('', array_map('firstCharUpperCase', explode('_', '" . $data['callback'] . "')))";
- // Return replaced code
- return $code;
-}
-
-// Expression call-back function for fetching user data
-function doExpressionUser ($data) {
- // Use current userid by default
- $functionName = 'getMemberId()';
-
- // User-related data, so is there a userid?
- if (!empty($data['matches'][4][$data['key']])) {
- // Do we have a userid or $userid?
- if ($data['matches'][4][$data['key']] == '$userid') {
- // Use dynamic call
- $functionName = "getFetchedUserData('userid', \$userid, '" . $data['callback'] . "')";
- } elseif ($data['matches'][4][$data['key']] > 0) {
- // User data found
- $functionName = "getFetchedUserData('userid', " . $data['matches'][4][$data['key']] . ", " . $data['callback'] . "')";
- }
- } elseif ((!empty($data['callback'])) && (isUserDataValid())) {
- // "Call-back" alias column for current logged in user's data
- $functionName = "getUserData('" . $data['callback'] . "')";
- }
+ // Generate replacer
+ $replacer = '{DQUOTE} . call_user_func(' . $functionName . ') . {DQUOTE}';
- // Do we have another function to run (e.g. translations)
- if (!empty($data['extra_func'])) {
- // Surround the original function call with it
- $functionName = $data['extra_func'] . '(' . $functionName . ')';
- } // END - if
-
- // Now replace the code
- $code = str_replace($data['matches'][0][$data['key']], "\" . " . $functionName . " . \"", $data['code']);
+ // Replace it
+ $code = replaceExpressionCode($data, $replacer);
// Return replaced code
return $code;
// Is the extension installed?
if (isExtensionInstalled($data['matches'][4][$data['key']])) {
// Construct call-back function name
- $functionName = 'getExtension' . ucfirst(strtolower($data['callback']));
+ $functionName = 'getExtension' . capitalizeUnderscoreString($data['callback']);
// Construct call of the function
- $replacer = "\" . call_user_func_array('" . $functionName . "', array('" . $data['matches'][4][$data['key']] . "', true)) . \"";
+ $replacer = "{DQUOTE} . call_user_func_array('" . $functionName . "', array('" . $data['matches'][4][$data['key']] . "', TRUE)) . {DQUOTE}";
} // END - if
+ // Generate replacer
+ $replacer = sprintf("&ext=%s&ver=%s&rev={?CURRENT_REPOSITORY_REVISION?}", $data['matches'][4][$data['key']], $replacer);
+
// Replace it and insert parameter for GET request
- $code = str_replace($data['matches'][0][$data['key']], sprintf("&ext=%s&ver=%s&rev=\" . getConfig('CURR_SVN_REVISION') . \"", $data['matches'][4][$data['key']], $replacer), $data['code']);
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Debug message
+ //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'code=' . $code . ',replacer=' . $replacer . ',key=' . $data['key'] . ',callback=' . $data['callback']);
// Return replaced code
return $code;
// Expression call-back function for getting configuration data
// @TODO FILTER_COMPILE_CONFIG does not handle call-back functions so we handle it here again
function doExpressionConfig ($data) {
- // Read configuration
- $configValue = getConfig($data['matches'][4][$data['key']]);
+ // Is there a special expression function for it?
+ if (isExpressionFunctionAvaiable($data)) {
+ // Then use it
+ $replacer = '{DQUOTE} . ' . $data['callback'] . '(' . getExpressionFunction($data) . '()) . {DQUOTE}';
+ } elseif (!isConfigEntrySet($data['matches'][4][$data['key']])) {
+ // Config entry is not set
+ $replacer = '{DQUOTE} . ' . $data['callback'] . '(NULL) . {DQUOTE}';
+ } else {
+ // Default replacer is the config value itself
+ $replacer = '{DQUOTE} . ' . $data['callback'] . '(getConfig(' . chr(39) . $data['matches'][4][$data['key']] . chr(39) . ')) . {DQUOTE}';
+ }
+
+ // Replace the config entry
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return replaced code
+ return $code;
+}
- // Do we have a call-back?
+// Expression call-back function for piping data through functions
+function doExpressionPipe ($data) {
+ // We need callback and extra_func: callback is really the call-back function, extra_func is our value
+ $replacer = $data['extra_func'];
+
+ // Is there a call-back? Should always be there!
if (!empty($data['callback'])) {
- // Parse it through this function
- $configValue = call_user_func_array($data['callback'], array($configValue));
+ //* DEBUG: */ if ($data['callback'] == 'getMemberId') die('<pre>'.encodeEntities(print_r($data, TRUE)).'</pre>');
+ // If the value is empty, we don't add it
+ //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value[' . gettype($data['value']) . ']=' . $data['value']);
+ if ((empty($data['value'])) && ($data['value'] != '0')) {
+ // No value is set
+ $replacer = '{DQUOTE} . ' . $data['extra_func2'] . '(' . $data['extra_func'] . '(' . $data['callback'] . '())) . {DQUOTE}';
+ } elseif (isXmlTypeBool($data['value'])) {
+ // Boolean value detected
+ $replacer = '{DQUOTE} . ' . $data['extra_func2'] . '(' . $data['extra_func'] . '(' . $data['callback'] . '(' . $data['value'] . '))) . {DQUOTE}';
+ } else {
+ // Some string/integer value is set
+ $replacer = '{DQUOTE} . ' . $data['extra_func2'] . '(' . $data['extra_func'] . '(' . $data['callback'] . "('" . $data['value'] . "'))) . {DQUOTE}";
+ }
} // END - if
// Replace the config entry
- $code = str_replace($data['matches'][0][$data['key']], $configValue, $data['code']);
+ //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'replacer=' . $replacer);
+ $code = replaceExpressionCode($data, $replacer);
// Return replaced code
return $code;
// Expression call-back function for calling filters
function doExpressionFilter ($data) {
// Construct replacement
- $replacer = "\" . runFilterChain('" . $data['matches'][4][$data['key']] . "') . \"";
+ $replacer = "{DQUOTE} . runFilterChain('" . $data['matches'][4][$data['key']] . "') . {DQUOTE}";
// Run the filter and insert result
- $code = str_replace($data['matches'][0][$data['key']], $replacer, $data['code']);
+ $code = replaceExpressionCode($data, $replacer);
// Return replaced code
return $code;
}
+// Expression call-back function for validator links
+function doExpressionValidatorLinks ($data) {
+ // Default is nothing
+ $replacer = '';
+
+ // Get the code from data array for replacement/pipe-through
+ $code = $data['code'];
+
+ // Should we generally include validator links?
+ if ((isExtensionInstalled('validator')) && (getConfig('enable_validator') == 'Y') && (!in_array(getModule(), array('admin', 'login')))) {
+ // Load the validator template
+ $replacer = escapeQuotes(loadTemplate('validator_links', TRUE));
+ } // END - if
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back for dynamic messages
+function doExpressionMessage ($data) {
+ // Debug message
+ //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'callback=' . $data['callback'] . ',extra_func=' . $data['extra_func'] . ',value=' . $data['value']);
+
+ // Message string replacement depends on if message is masked
+ if ((isMessageMasked($data['callback'], FALSE)) && ((!empty($data['extra_func'])) || ($data['extra_func'] == '0'))) {
+ // Message should be masked
+ $replacer = "{DQUOTE} . getMaskedMessage('" . $data['callback'] . "', '" . $data['extra_func'] . "') . {DQUOTE}";
+ } elseif (!empty($data['value'])) {
+ // value is set, so it is masked message
+ $replacer = "{DQUOTE} . getMaskedMessage('" . $data['callback'] . "', '" . $data['value'] . "') . {DQUOTE}";
+ } else {
+ // Regular message
+ $replacer = "{DQUOTE} . getMessage('" . $data['callback'] . "') . {DQUOTE}";
+ }
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back for template functions
+function doExpressionTemplate ($data) {
+ // Construct call-back function name
+ $callbackFunction = 'doTemplate' . ucfirst($data['callback']);
+
+ // Init replacer
+ $replacer = '<!-- [' . __FUNCTION__ . ':' . __LINE__.'] Call-back function ' . $callbackFunction . ' does not exist. //-->';
+
+ // Is the function there?
+ if (!isset($GLOBALS['current_template'])) {
+ // This is very bad and needs fixing
+ reportBug(__FUNCTION__, __LINE__, 'current_template in GLOBALS not set, callbackFunction=' . $callbackFunction . ',function_exists()=' . intval(function_exists($callbackFunction)));
+ } elseif (!function_exists($callbackFunction)) {
+ // Log missing function only in debug mode
+ if (isDebugModeEnabled()) {
+ // Log it here
+ logDebugMessage(__FUNCTION__, __LINE__, 'Call-back function ' . $callbackFunction . ' does not exist.');
+ } // END - if
+ } else {
+ // Do the replacement
+ //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'template='.$GLOBALS['current_template']);
+ $replacer = '{DQUOTE} . ' . $callbackFunction . '(' . chr(39) . $GLOBALS['current_template'] . chr(39) . ', TRUE';
+
+ // Is 'value' set?
+ if (!empty($data['value'])) {
+ // Then include it as well
+ $replacer .= ', ' . chr(39) . $data['value'] . chr(39);
+ } // END - if
+
+ // Replacer is ready
+ $replacer .= ') . {DQUOTE}';
+ }
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back for math functions
+function doExpressionMath ($data) {
+ // Do the replacement
+ //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'template='.$GLOBALS['current_template']);
+ $replacer = '{DQUOTE} . doCalculate' . $data['callback'] . '(' . $data['value'] . ') . {DQUOTE}';
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Load include once
+ loadIncludeOnce('inc/math-functions.php');
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back for GET request
+function doExpressionGet ($data) {
+ // Construct the replacer:
+ // - GET request element
+ $replacer = '{%pipe,getRequestElement';
+
+ // Add more call-back functions?
+ if (!empty($data['callback'])) {
+ // - Okay, add them
+ $replacer .= ',' . $data['callback'];
+ } // END - if
+
+ // - Finalize replacer
+ $replacer .= '=' . $data['value'] . '%}';
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back for POST request
+function doExpressionPost ($data) {
+ // Construct the replacer:
+ // - POST request element
+ $replacer = '{%pipe,postRequestElement';
+
+ // Add more call-back functions?
+ if (!empty($data['callback'])) {
+ // - Okay, add them
+ $replacer .= ',' . $data['callback'];
+ } // END - if
+
+ // - Finalize replacer
+ $replacer .= '=' . $data['value'] . '%}';
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back for session data
+function doExpressionSession ($data) {
+ // Construct the replacer:
+ // - Session element
+ $replacer = '{%pipe,getSession';
+
+ // Add more call-back functions?
+ if (!empty($data['callback'])) {
+ // - Okay, add them
+ $replacer .= ',' . $data['callback'];
+ } // END - if
+
+ // - Finalize replacer
+ $replacer .= '=' . $data['value'] . '%}';
+
+ // Debug message
+ //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $data['value'] . ',replacer=' . $replacer);
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+/**
+ * Expression call-back for session piplining, this means:
+ *
+ * 1) Read session data
+ * 2) Wrap the raw data into {%pipe,fooFunction=$rawValue%}
+ */
+function doExpressionSessionPipe ($data) {
+ // Get the session data
+ $rawValue = getSession($data['value']);
+
+ // Construct the replacer
+ $replacer = '{%pipe,' . $data['callback'] . '=' . $rawValue . '%}';
+
+ // Debug message
+ //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'value=' . $data['value'] . ',rawValue=' . $rawValue . ',replacer=' . $replacer);
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back for formulars
+function doExpressionForm ($data) {
+ // Default method is GET, target is _self
+ $data['__form_method'] = 'get';
+ $data['__form_target'] = '_self';
+ $data['__form_name'] = 'form';
+ $data['__form_id'] = 'form';
+ $data['__server'] = '';
+
+ // Check which method/target is set
+ foreach (array('callback', 'extra_func', 'extra_func2') as $key) {
+ // Make lower-case
+ $value = strtolower($data[$key]);
+
+ // Is formMethodPost set?
+ if ($value == 'formmethodpost') {
+ // Use it
+ $data['__form_method'] = 'post';
+ } elseif (($value == 'formmethodpost') && (!isSpider()) && (!isSessionValid())) {
+ // Then expand 'value' with session id
+ if (strpos($data['value'], '?') !== FALSE) {
+ // '?' is set
+ $data['value'] .= '&';
+ } else {
+ // Is not set
+ $data['value'] .= '?';
+ }
+
+ // Append session's name and id
+ $data['value'] .= session_name() . '=' . session_id();
+ } elseif (substr($value, 0, 10) == 'formtarget') {
+ // Form target is found
+ $data['__form_target'] = substr($value, 10);
+ } elseif (substr($value, 0, 8) == 'formname') {
+ // Form name is found
+ $data['__form_name'] = substr($value, 8);
+ } elseif (substr($value, 0, 6) == 'formid') {
+ // Form id found
+ $data['__form_id'] = substr($value, 6);
+ } elseif (substr($value, 0, 6) == 'server') {
+ // {%server,foo%} found
+ $data['__server'] = '{%server,' . substr($value, 6) . '%}';
+ }
+ } // END - foreach
+
+ // Generate the replacement code which is the opening form tag
+ $data['__replacer'] = '<form accept-charset=\"UTF-8\"';
+ if (!empty($data['value'])) {
+ $data['__replacer'] .= ' action=\"{%url=' . $data['value'];
+ if (!empty($data['__server'])) {
+ $data['__replacer'] .= $data['__server'];
+ } // END - if
+ $data['__replacer'] .= '%}\"';
+ } // END - if
+
+ // Add rest elements
+ foreach (array('method', 'target', 'name', 'id') as $key) {
+ $data['__replacer'] .= ' ' . $key . '=\"' . $data['__form_' . $key] . '\"';
+ } // END - foreach
+
+ // Close the tag here (don't move it below the next filter)
+ $data['__replacer'] .= '>' . PHP_EOL;
+
+ /*
+ * Call a filter chain to allow more hidden fields being added. You should
+ * not remove the > char from above line to add onsubmit="" or so. Instead
+ * you should better use jquery to accomplish the same.
+ */
+ $data = runFilterChain('open_form_fields', $data);
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $data['__replacer']);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back to close form tags
+function doExpressionFormClose ($data) {
+ // Initial replacer is really easy ...
+ $data['__replacer'] = '</form>' . PHP_EOL;
+
+ /*
+ * Call a filter chain to allow more hidden fields being added at the end
+ * of the form.
+ */
+ $data = runFilterChain('close_form_fields', $data);
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $data['__replacer']);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
+// Expression call-back to handle jquery inclusion
+function doExpressionJquery ($data) {
+ // Default is compressed
+ $jquery = 'jquery';
+ $data['output_mode'] = '';
+
+ // Is there JS-mode?
+ if ($data['callback'] == 'js') {
+ // Switch to it
+ $data['output_mode'] = ',js';
+ } // END - if
+
+ // Is there a value?
+ if ($data['callback'] == 'js') {
+ // Then load special library
+ $jquery .= '-' . $data['value'];
+ } // END - if
+
+ // Is debug mode enabled?
+ if ((isGetRequestElementSet('jquery')) || (isSessionVariableSet('jquery'))) {
+ // Then use uncompressed
+ $jquery .= '.uncompressed';
+
+ // Remember it in session
+ setSession('jquery', '1');
+ } // END - if
+
+ // Add {%url%} around it
+ $replacer = '{%url' . $data['output_mode'] . '=js/' . $jquery . '.js?dummy=1%}';
+
+ // Replace the code
+ $code = replaceExpressionCode($data, $replacer);
+
+ // Return the (maybe) replaced code
+ return $code;
+}
+
// [EOF]
?>