X-Git-Url: https://git.mxchange.org/?p=mailer.git;a=blobdiff_plain;f=inc%2Ftemplate-functions.php;h=4b6420a59f013706ed0e545a6329842f5762200a;hp=29e3e092db01218a48b7830291dd3de344f83786;hb=b5e396d81912f97a5752b4a4e61ae08f7c1efbd5;hpb=e1cf98e08d4d92edf492396b82c67efa97a0ece8 diff --git a/inc/template-functions.php b/inc/template-functions.php index 29e3e092db..4b6420a59f 100644 --- a/inc/template-functions.php +++ b/inc/template-functions.php @@ -16,8 +16,8 @@ * $Author:: $ * * -------------------------------------------------------------------- * * Copyright (c) 2003 - 2009 by Roland Haeder * - * Copyright (c) 2009 - 2011 by Mailer Developer Team * - * For more information visit: http://www.mxchange.org * + * Copyright (c) 2009 - 2013 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 * @@ -41,22 +41,22 @@ if (!defined('__SECURITY')) { } // END - if // Wrapper until we merged to the EL branch -function preCompileCode ($code, $template = '', $compiled = false, $full = true, $overwrite = false) { - return compileCode($code, false, true, $full); +function preCompileCode ($code, $full = TRUE) { + return compileCode($code, $full); } // Setter for 'is_template_html' -function enableTemplateHtml ($enable = true) { +function enableTemplateHtml ($enable = TRUE) { $GLOBALS['is_template_html'] = (bool) $enable; } -// Checks wether the template is HTML or not by previously set flag +// Checks whether the template is HTML or not by previously set flag // Default: true function isTemplateHtml () { // Is the output_mode other than 0 (HTML), then no comments are enabled if (!isHtmlOutputMode()) { // No HTML - return false; + return FALSE; } else { // Maybe HTML? return $GLOBALS['is_template_html']; @@ -70,13 +70,8 @@ function debugOutput ($message) { // "Fixes" an empty string into three dashes (use for templates) function fixEmptyContentToDashes ($str) { - // Trim the string - $str = trim($str); - - // Is the string empty? - if (empty($str)) { - $str = '---'; - } // END - if + // Call inner function + $str = fixNullEmptyToDashes($str, 3); // Return string return $str; @@ -91,60 +86,71 @@ function initTemplateColorSwitch ($template) { // "Getter" for color switch code function getColorSwitchCode ($template) { // Prepare the code - $code = "{DQUOTE} . doTemplateColorSwitch('" . $template . "', false, false) . {DQUOTE}"; + $code = "{DQUOTE} . doTemplateColorSwitch('" . $template . "', FALSE, FALSE) . {DQUOTE}"; // And return it return $code; } // Output HTML code directly or 'render' it. You addionally switch the new-line character off -function outputHtml ($htmlCode, $newLine = true) { +function outputHtml ($htmlCode = NULL, $newLine = TRUE) { // Init output - if (!isset($GLOBALS['output'])) { - $GLOBALS['output'] = ''; + if (!isset($GLOBALS['__output'])) { + $GLOBALS['__output'] = ''; } // END - if - // Do we have HTML-Code here? - if (!empty($htmlCode)) { + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'getOutputMode()=' . getOutputMode() . ',htmlCode(length)=' . strlen($htmlCode) . ',output(length)=' . strlen($GLOBALS['__output'])); + // Is there HTML-Code here? + if ((!is_null($htmlCode)) && (!empty($htmlCode))) { // Yes, so we handle it as you have configured switch (getOutputMode()) { case 'render': - // That's why you don't need any \n at the end of your HTML code... :-) + // But if PHP is caching, then we don't need to do that if (getPhpCaching() == 'on') { // Output into PHP's internal buffer outputRawCode($htmlCode); // That's why you don't need any \n at the end of your HTML code... :-) - if ($newLine === true) print("\n"); + if ($newLine === TRUE) { + outputRawCode(PHP_EOL); + } // END - if } else { // Render mode for old or lame servers... - $GLOBALS['output'] .= $htmlCode; + $GLOBALS['__output'] .= $htmlCode; // That's why you don't need any \n at the end of your HTML code... :-) - if ($newLine === true) $GLOBALS['output'] .= "\n"; + if ($newLine === TRUE) { + $GLOBALS['__output'] .= PHP_EOL; + } // END - if } break; case 'direct': - // If we are switching from render to direct output rendered code - if ((!empty($GLOBALS['output'])) && (getPhpCaching() != 'on')) { outputRawCode($GLOBALS['output']); $GLOBALS['output'] = ''; } + // If we are switching from 'render' to 'direct' mode, all data in '__output' must be flushed and cleared + if ((!empty($GLOBALS['__output'])) && (getPhpCaching() != 'on')) { + outputRawCode($GLOBALS['__output']); + $GLOBALS['__output'] = ''; + } // END - if // The same as above... ^ outputRawCode($htmlCode); - if ($newLine === true) print("\n"); + if ($newLine === TRUE) { + outputRawCode(PHP_EOL); + } // END - if break; default: // Huh, something goes wrong or maybe you have edited config.php ??? - debug_report_bug(__FUNCTION__, __LINE__, '{--FATAL_ERROR--}: {--NO_RENDER_DIRECT--}'); + reportBug(__FUNCTION__, __LINE__, '{--FATAL_ERROR--}: {--NO_RENDER_DIRECT--}'); break; } // END - switch - } elseif ((getPhpCaching() == 'on') && ((!isset($GLOBALS['header'])) || (count($GLOBALS['header']) == 0))) { + } elseif ((getPhpCaching() == 'on') && ((!isset($GLOBALS['http_header'])) || (count($GLOBALS['http_header']) == 0)) && (!isRawOutputMode())) { + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'getPhpCaching()=' . getPhpCaching() . ',isset(http_header)=' . intval(isset($GLOBALS['http_header'])) . ',getScriptOutputMode()=' . getScriptOutputMode() . ''); // Output cached HTML code - $GLOBALS['output'] = ob_get_contents(); + $GLOBALS['__output'] = ob_get_contents(); // Clear output buffer for later output if output is found - if (!empty($GLOBALS['output'])) { + if (!empty($GLOBALS['__output'])) { clearOutputBuffer(); } // END - if @@ -155,8 +161,8 @@ function outputHtml ($htmlCode, $newLine = true) { compileFinalOutput(); // Output code here, DO NOT REMOVE! ;-) - outputRawCode($GLOBALS['output']); - } elseif ((getOutputMode() == 'render') && (!empty($GLOBALS['output']))) { + outputRawCode($GLOBALS['__output']); + } elseif ((getOutputMode() == 'render') && (!empty($GLOBALS['__output'])) && (!isRawOutputMode())) { // Send all HTTP headers sendHttpHeaders(); @@ -164,89 +170,113 @@ function outputHtml ($htmlCode, $newLine = true) { compileFinalOutput(); // Output code here, DO NOT REMOVE! ;-) - outputRawCode($GLOBALS['output']); + outputRawCode($GLOBALS['__output']); } else { // And flush all headers - flushHeaders(); + flushHttpHeaders(); } } // Compiles the final output function compileFinalOutput () { + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, '__output(length)=' . strlen($GLOBALS['__output']) . ',getScriptOutputMode()=' . getScriptOutputMode() . ' - ENTERED!'); + // Is this function called? + if (isset($GLOBALS[__FUNCTION__])) { + // Abort here + reportBug(__FUNCTION__, __LINE__, 'Double call of ' . __FUNCTION__ . ' causes problems with sent headers.'); + } // END - if + + // Mark this function as called + $GLOBALS[__FUNCTION__] = TRUE; + // Add page header and footer addPageHeaderFooter(); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, '__output(length)=' . strlen($GLOBALS['__output']) . ' - After addPageHeaderFooter() call.'); - // Do the final compilation - $GLOBALS['output'] = doFinalCompilation($GLOBALS['output']); + // Do the final (general) compilation + $GLOBALS['__output'] = doFinalCompilation($GLOBALS['__output']); + + // Compile any other things out + $GLOBALS['__output'] = compileUriCode($GLOBALS['__output']); // Extension 'rewrite' installed? if ((isExtensionActive('rewrite')) && (!isCssOutputMode())) { - $GLOBALS['output'] = rewriteLinksInCode($GLOBALS['output']); + $GLOBALS['__output'] = rewriteLinksInCode($GLOBALS['__output']); } // END - if // Compress it? /** * @TODO On some pages this is buggy - if (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos('gzip', $_SERVER['HTTP_ACCEPT_ENCODING']) !== null)) { + if (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && (isInStringIgnoreCase('gzip', $_SERVER['HTTP_ACCEPT_ENCODING']))) { // Compress it for HTTP gzip - $GLOBALS['output'] = gzencode($GLOBALS['output'], 9); + $GLOBALS['__output'] = gzencode($GLOBALS['__output'], 9); // Add header - sendHeader('Content-Encoding: gzip'); - } elseif (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && (strpos('deflate', $_SERVER['HTTP_ACCEPT_ENCODING']) !== null)) { + addHttpHeader('Content-Encoding: gzip'); + } elseif (!empty($_SERVER['HTTP_ACCEPT_ENCODING']) && (isInStringIgnoreCase('deflate', $_SERVER['HTTP_ACCEPT_ENCODING']))) { // Compress it for HTTP deflate - $GLOBALS['output'] = gzcompress($GLOBALS['output'], 9); + $GLOBALS['__output'] = gzcompress($GLOBALS['__output'], 9); // Add header - sendHeader('Content-Encoding: deflate'); + addHttpHeader('Content-Encoding: deflate'); } */ // Add final length - sendHeader('Content-Length: ' . strlen($GLOBALS['output'])); + addHttpHeader('Content-Length: ' . strlen($GLOBALS['__output'])); // Flush all headers - flushHeaders(); + flushHttpHeaders(); } // Main compilation loop -function doFinalCompilation ($code, $insertComments = true, $enableCodes = true) { +function doFinalCompilation ($code, $insertComments = TRUE, $enableCodes = TRUE) { // Insert comments? (Only valid with HTML templates, of course) enableTemplateHtml($insertComments); // Init counter - $count = 0; - - // Compile the raw code - $code = compileRawCode($code); + $totalCompilations = 0; // Compile all out - while (((strpos($code, '{--') !== false) || (strpos($code, '{DQUOTE}') !== false) || (strpos($code, '{?') !== false) || (strpos($code, '{%') !== false)) && ($count < 7)) { + while (((isInString('{--', $code)) || (isInString('{DQUOTE}', $code)) || (isInString('{?', $code)) || (isInString('{%', $code) !== FALSE)) && ($totalCompilations < 7)) { // Init common variables $content = array(); $newContent = ''; // Compile it - //* DEBUG: */ debugOutput('
'.linenumberCode($code).'
'); - $eval = '$newContent = "' . str_replace('{DQUOTE}', '"', compileCode(escapeQuotes($code), false, true, $enableCodes)) . '";'; - //* DEBUG: */ if (!$insertComments) print('EVAL=
'.linenumberCode($eval).'
'); + //* DEBUG: */ debugOutput('
'.lineNumberCode($code).'
'); + $eval = '$newContent = "' . str_replace('{DQUOTE}', '"', compileCode(escapeQuotes($code), $enableCodes)) . '";'; + //* DEBUG: */ if (!$insertComments) print('EVAL=
'.lineNumberCode($eval).'
'); eval($eval); - //* DEBUG: */ if (!$insertComments) print('NEW=
'.linenumberCode($newContent).'
'); + //* DEBUG: */ if (!$insertComments) print('NEW=
'.lineNumberCode($newContent).'
'); //* DEBUG: */ die('
'.encodeEntities($newContent).'
'); // Was that eval okay? if (empty($newContent)) { // Something went wrong! - debug_report_bug(__FUNCTION__, __LINE__, 'Evaluation error:
' . linenumberCode($eval) . '
', false); + reportBug(__FUNCTION__, __LINE__, 'Evaluation error:
' . lineNumberCode($eval) . '
', FALSE); } // END - if // Use it again $code = $newContent; + // Compile the final code if insertComments is true + if ($insertComments == TRUE) { + // ... because SQL queries shall keep OPEN_CONFIG and such in + $code = compileRawCode($code); + } // END - if + // Count round - $count++; + $totalCompilations++; } // END - while + // Add debugging data in HTML code, if mode is enabled + if ((isDebugModeEnabled()) && ($insertComments === TRUE) && (isHtmlOutputMode())) { + // Add loop count + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'isDebugModeEnabled()=' . intval(isDebugModeEnabled()) . ',insertComments=' . intval($insertComments) . ',isHtmlOutputMode()=' . intval(isHtmlOutputMode())); + $code .= ''; + } // END - if + // Return the compiled code return $code; } @@ -254,7 +284,7 @@ function doFinalCompilation ($code, $insertComments = true, $enableCodes = true) // Output the raw HTML code function outputRawCode ($htmlCode) { // Output stripped HTML code to avoid broken JavaScript code, etc. - print(str_replace('{BACK}', "\\", $htmlCode)); + print(str_replace('{BACK}', chr(92), $htmlCode)); // Flush the output if only getPhpCaching() is not 'on' if (getPhpCaching() != 'on') { @@ -264,35 +294,40 @@ function outputRawCode ($htmlCode) { } // Load a template file and return it's content (only it's name; do not use ' or ") -function loadTemplate ($template, $return = false, $content = array(), $compileCode = true) { +function loadTemplate ($template, $return = FALSE, $content = array(), $compileCode = TRUE) { + // @TODO Remove these sanity checks if all is fine if (!is_bool($return)) { - // @TODO Remove this sanity-check if all is fine - debug_report_bug(__FUNCTION__, __LINE__, 'return[] is not bool (' . gettype($return) . ')'); + // $return has to be boolean + reportBug(__FUNCTION__, __LINE__, 'return[] is not bool (' . gettype($return) . ')'); } elseif (!is_string($template)) { // $template has to be string - debug_report_bug(__FUNCTION__, __LINE__, 'template[] is not string (' . gettype($template) . ')'); + reportBug(__FUNCTION__, __LINE__, 'template[] is not string (' . gettype($template) . ')'); } + // Init returned content + $ret = ''; + // Set current template $GLOBALS['current_template'] = $template; - // Do we have cache? - if ((!isDebuggingTemplateCache()) && (isTemplateCached($template))) { + // Is there cache? + if ((!isDebugTemplateCacheEnabled()) && (isTemplateCached('html', $template))) { // Evaluate the cache - eval(readTemplateCache($template)); - } elseif (!isset($GLOBALS['template_eval'][$template])) { + $templateContent = readTemplateCache('html', $template, $content); + + // Better remove array element which is only needed in uncached mode + unset($GLOBALS['template_eval']['html'][$template]); + } elseif (!isset($GLOBALS['template_eval']['html'][$template])) { // Make all template names lowercase $template = strtolower($template); - // Init some data - $ret = ''; - // Base directory $basePath = sprintf("%stemplates/%s/html/", getPath(), getLanguage()); - $extraPath = detectExtraTemplatePath($template); + $extraPath = detectExtraTemplatePath('html', $template); // Generate FQFN $FQFN = $basePath . $extraPath . $template . '.tpl'; + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Template ' . $template . ' is solved to FQFN=' . $FQFN); // Does the special template exists? if (!isFileReadable($FQFN)) { @@ -306,80 +341,95 @@ function loadTemplate ($template, $return = false, $content = array(), $compileC incrementConfigEntry('num_templates'); // The local file does exists so we load it. :) - $GLOBALS['tpl_content'][$template] = readFromFile($FQFN); + $GLOBALS['template_content']['html'][$template] = readFromFile($FQFN); - // Do we have to compile the code? - $ret = ''; - if ((strpos($GLOBALS['tpl_content'][$template], '$') !== false) || (strpos($GLOBALS['tpl_content'][$template], '{--') !== false) || (strpos($GLOBALS['tpl_content'][$template], '{?') !== false) || (strpos($GLOBALS['tpl_content'][$template], '{%') !== false)) { + // Is there to compile the code? + if ((isInString('$', $GLOBALS['template_content']['html'][$template])) || (isInString('{--', $GLOBALS['template_content']['html'][$template])) || (isInString('{?', $GLOBALS['template_content']['html'][$template])) || (isInString('{%', $GLOBALS['template_content']['html'][$template]))) { // Normal HTML output? - if (isHtmlOutputMode()) { + if ((isHtmlOutputMode()) && (substr($template, 0, 3) != 'js_')) { // Add surrounding HTML comments to help finding bugs faster - $ret = '' . $GLOBALS['tpl_content'][$template] . ''; + $code = '' . $GLOBALS['template_content']['html'][$template] . ''; // Prepare eval() command - $GLOBALS['template_eval'][$template] = '$ret = "' . getColorSwitchCode($template) . compileCode(escapeQuotes($ret), false, true, true, $compileCode) . '";'; + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['html'][$template] = '$templateContent = "' . getColorSwitchCode($template) . compileCode(escapeQuotes($code), TRUE, $compileCode) . '";'; } elseif (substr($template, 0, 3) == 'js_') { - // JavaScripts don't like entities and timings - $GLOBALS['template_eval'][$template] = '$ret = decodeEntities("' . compileRawCode(escapeJavaScriptQuotes($GLOBALS['tpl_content'][$template]), false, true, true, $compileCode) . '");'; + // JavaScripts don't like entities, dollar signs and timings + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['html'][$template] = '$templateContent = decodeEntities("' . compileRawCode(escapeJavaScriptQuotes($GLOBALS['template_content']['html'][$template]), TRUE, $compileCode) . '");'; + } elseif (isAjaxOutputMode()) { + // AJAX (JSON content) + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['html'][$template] = '$templateContent = "' . compileRawCode(escapeJavaScriptQuotes($GLOBALS['template_content']['html'][$template]), TRUE, $compileCode) . '";'; } else { // Prepare eval() command, other output doesn't like entities, maybe - $GLOBALS['template_eval'][$template] = '$ret = decodeEntities("' . compileRawCode(escapeQuotes($GLOBALS['tpl_content'][$template]), false, true, true, $compileCode) . '");'; + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['html'][$template] = '$templateContent = decodeEntities("' . compileRawCode(escapeQuotes($GLOBALS['template_content']['html'][$template]), TRUE, $compileCode) . '");'; } } elseif (isHtmlOutputMode()) { // Add surrounding HTML comments to help finding bugs faster - $ret = '' . $GLOBALS['tpl_content'][$template] . ''; - $GLOBALS['template_eval'][$template] = '$ret = "' . getColorSwitchCode($template) . compileRawCode(escapeQuotes($ret), false, true, true, $compileCode) . '";'; + $templateContent = '' . $GLOBALS['template_content']['html'][$template] . ''; + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['html'][$template] = '$templateContent = "' . getColorSwitchCode($template) . compileRawCode(escapeQuotes($templateContent), TRUE, $compileCode) . '";'; + } elseif (isAjaxOutputMode()) { + // AJAX (JSON content) + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['html'][$template] = '$templateContent = "' . compileRawCode(escapeJavaScriptQuotes($GLOBALS['template_content']['html'][$template]), TRUE, $compileCode) . '";'; } else { // JavaScript again - $GLOBALS['template_eval'][$template] = '$ret = decodeEntities("' . compileRawCode(escapeJavaScriptQuotes($GLOBALS['tpl_content'][$template]), false, true, true, $compileCode) . '");'; + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['html'][$template] = '$templateContent = decodeEntities("' . compileRawCode(escapeJavaScriptQuotes($GLOBALS['template_content']['html'][$template]), TRUE, $compileCode) . '");'; } // END - if } elseif ((isAdmin()) || ((isInstalling()) && (!isInstalled()))) { // Only admins shall see this warning or when installation mode is active - $ret = '
- {--TEMPLATE_404--} + $templateContent = '
+ {--TEMPLATE_404--}
(' . $template . ')
{--TEMPLATE_CONTENT--}: -
' . print_r($content, true) . '
+
' . print_r($content, TRUE) . '
'; } else { // No file! - $GLOBALS['template_eval'][$template] = '404'; + $GLOBALS['template_eval']['html'][$template] = '404'; } } // Code set? - if ((isset($GLOBALS['template_eval'][$template])) && ($GLOBALS['template_eval'][$template] != '404')) { + if ((isset($GLOBALS['template_eval']['html'][$template])) && ($GLOBALS['template_eval']['html'][$template] != '404')) { // Eval the code - eval($GLOBALS['template_eval'][$template]); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'template=' . $template . ' - BEFORE EVAL'); + ///* DEBUG: */ print('
'.htmlentities($GLOBALS['template_eval']['html'][$template]).'
'); + eval($GLOBALS['template_eval']['html'][$template]); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'template=' . $template . ' - AFTER EVAL'); } // END - if - // Do we have some content to output or return? - if (!empty($ret)) { - // Not empty so let's put it out! ;) - if ($return === true) { - // Return the HTML code - return $ret; - } else { - // Output directly - outputHtml($ret); - } - } elseif (isDebugModeEnabled()) { + // Is there some content to output or return? + if ((empty($templateContent)) && (isDebugModeEnabled())) { // Warning, empty output! - return 'E:' . $template . ',content=
' . print_r($content, true) . '
'; + return 'E:' . $template . ',content=
' . print_r($content, TRUE) . '
'; + } // END - if + + // Not empty so let's put it out! ;) + if ($return === TRUE) { + // Return the HTML code + return $templateContent; + } else { + // Output directly + outputHtml($templateContent); } } // Detects the extra template path from given template name -function detectExtraTemplatePath ($template) { +function detectExtraTemplatePath ($prefix, $template) { // Default is empty $extraPath = ''; - // Do we have cache? - if (!isset($GLOBALS['extra_path'][$template])) { + // Is there cache? + if (!isset($GLOBALS['extra_path'][$prefix][$template])) { // Check for admin/guest/member/etc. templates if (substr($template, 0, 6) == 'admin_') { // Admin template found @@ -420,28 +470,28 @@ function detectExtraTemplatePath ($template) { } // Store it in cache - $GLOBALS['extra_path'][$template] = $extraPath; + $GLOBALS['extra_path'][$prefix][$template] = $extraPath; } // END - if // Return result - return $GLOBALS['extra_path'][$template]; + return $GLOBALS['extra_path'][$prefix][$template]; } // Loads an email template and compiles it -function loadEmailTemplate ($template, $content = array(), $userid = '0', $loadUserData = true) { - // @TODO $DATA is deprecated and should be avoided and replaced with $content - global $DATA; - +function loadEmailTemplate ($template, $content = array(), $userid = NULL, $loadUserData = TRUE) { // Make sure all template names are lowercase! $template = strtolower($template); + // Set current template + $GLOBALS['current_template'] = $template; + // Is content an array? if (is_array($content)) { // Add expiration to array - if ((isConfigEntrySet('auto_purge')) && (getAutoPurge() == '0')) { + if ((isExtensionInstalled('autopurge')) && (isConfigEntrySet('auto_purge')) && (getAutoPurge() == '0')) { // Will never expire! $content['expiration'] = '{--MAIL_WILL_NEVER_EXPIRE--}'; - } elseif (isConfigEntrySet('auto_purge')) { + } elseif ((isExtensionInstalled('autopurge')) && (isConfigEntrySet('auto_purge'))) { // Create nice date string $content['expiration'] = '{%config,createFancyTime=auto_purge%}'; } else { @@ -450,155 +500,156 @@ function loadEmailTemplate ($template, $content = array(), $userid = '0', $loadU } } // END - if - // Load user's data - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'UID=' . $userid . ',template=' . $template . ',content[]=' . gettype($content)); - if ((isValidUserId($userid)) && (is_array($content))) { - // If nickname extension is installed, fetch nickname as well - if ((isExtensionActive('nickname')) && (isNicknameUsed($userid))) { - // Load by nickname - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'userid=' . $userid . ' - NICKNAME!'); - fetchUserData($userid, 'nickname'); - } elseif (isNicknameUsed($userid)) { - // Non-number characters entered but no ext-nickname found - debug_report_bug(__FUNCTION__, __LINE__, 'userid=' . $userid . ': is no id number and ext-nickname is gone.'); - } else { - // Load by userid - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'userid=' . $userid . ' - USERID!'); - fetchUserData($userid); - } - - // Merge data if valid - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'content()=' . count($content) . ' - PRE!'); - if ((isUserDataValid()) && ($loadUserData === true)) { - // It is valid - $content = merge_array($content, getUserDataArray()); - - // But we don't like hashed passwords be mailed - unset($content['password']); - } // END - if - - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'content()=' . count($content) . ' - AFTER!'); - } // END - if + // Is there cache? + if ((!isDebugTemplateCacheEnabled()) && (isTemplateCached('email', $template))) { + // Evaluate the cache + $templateContent = readTemplateCache('email', $template, $content); - // Base directory - $basePath = sprintf("%stemplates/%s/emails/", getPath(), getLanguage()); + // Better remove array element which is need only in uncached mode + unset($GLOBALS['template_eval']['email'][$template]); + } elseif (!isset($GLOBALS['template_eval']['email'][$template])) { + // Base directory + $basePath = sprintf("%stemplates/%s/emails/", getPath(), getLanguage()); - // Detect extra path - $extraPath = detectExtraTemplatePath($template); + // Detect extra path + $extraPath = detectExtraTemplatePath('email', $template); - // Generate full FQFN - $FQFN = $basePath . $extraPath . $template . '.tpl'; + // Generate full FQFN + $FQFN = $basePath . $extraPath . $template . '.tpl'; - // Does the special template exists? - if (!isFileReadable($FQFN)) { - // Reset to default template - $FQFN = $basePath . $template . '.tpl'; - } // END - if + // Does the special template exists? + if (!isFileReadable($FQFN)) { + // Reset to default template + $FQFN = $basePath . $template . '.tpl'; + } // END - if - // Now does the final template exists? - $newContent = ''; - if (isFileReadable($FQFN)) { - // The local file does exists so we load it. :) - $GLOBALS['tpl_content'][$template] = readFromFile($FQFN); - - // Run code - $GLOBALS['tpl_content'][$template] = '$newContent = decodeEntities("' . compileRawCode(escapeQuotes($GLOBALS['tpl_content'][$template])) . '");'; - eval($GLOBALS['tpl_content'][$template]); - } elseif (!empty($template)) { - // Template file not found - $newContent = '
+ // Now does the final template exists? + $templateContent = ''; + if (isFileReadable($FQFN)) { + // The local file does exists so we load it. :) + $GLOBALS['template_content']['email'][$template] = readFromFile($FQFN); + + // Run code + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Reached!'); + $GLOBALS['template_eval']['email'][$template] = '$templateContent = decodeEntities("' . compileRawCode(escapeQuotes($GLOBALS['template_content']['email'][$template])) . '");'; + } elseif (!empty($template)) { + // Template file not found + $templateContent = '
{--TEMPLATE_404--}: ' . $template . '
{--TEMPLATE_CONTENT--}: -
' . print_r($content, true) . '
- {--TEMPLATE_DATA--}: -
' . print_r($DATA, true) . '
+
' . print_r($content, TRUE) . '
'; - // Debug mode not active? Then remove the HTML tags - if (!isDebugModeEnabled()) { - // Remove HTML tags - $newContent = secureString($newContent); - } // END - if - } else { - // No template name supplied! - $newContent = '{--NO_TEMPLATE_SUPPLIED--}'; + // Don't cache this, as there is no template to cache + $GLOBALS['template_eval']['email'][$template] = '404'; + + // Debug mode not active? Then remove the HTML tags + if (!isDebugModeEnabled()) { + // Remove HTML tags + $templateContent = secureString($templateContent); + } // END - if + } else { + // No template name supplied! + $templateContent = '{--NO_TEMPLATE_SUPPLIED--}'; + $GLOBALS['template_eval']['email'][$template] = '404'; + } } - // Is there some content? - if (empty($newContent)) { + // Is there something to eval? + if ((isset($GLOBALS['template_eval']['email'][$template])) && ($GLOBALS['template_eval']['email'][$template] != '404')) { + // Eval the code + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'template=' . $template . ' - BEFORE EVAL'); + //* DEBUG: */ print('
'.htmlentities($GLOBALS['template_eval']['email'][$template]).'
'); + eval($GLOBALS['template_eval']['email'][$template]); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'template=' . $template . ' - AFTER EVAL'); + } // END - if + + // Are there some content? + if (empty($templateContent)) { // Compiling failed - $newContent = "Compiler error for template " . $template . " !\nUncompiled content:\n" . $GLOBALS['tpl_content'][$template]; + $templateContent = "Compiler error for template " . $template . " !\nUncompiled content:\n" . $GLOBALS['template_eval']['email'][$template]; // Add last error if the required function exists - if (function_exists('error_get_last')) $newContent .= "\n--------------------------------------\nDebug:\n".print_r(error_get_last(), true)."--------------------------------------\nPlease don't alter these informations!\nThanx."; + if (function_exists('error_get_last')) { + // Add last error and some lines for better overview + $templateContent .= "\n--------------------------------------\nDebug:\n" . print_r(error_get_last(), TRUE) . "--------------------------------------\nPlease don't alter these informations!\nThanx."; + } // END - if } // END - if // Remove content and data unset($content); - unset($DATA); // Return content - return $newContent; + return $templateContent; } // "Getter" for menu CSS classes, mainly used in templates function getMenuCssClasses ($data) { - // $data needs to be converted into an array - $content = explode('|', $data); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'data=' . $data); + + // Is there cache? + if (!isset($GLOBALS[__FUNCTION__][$data])) { + // $data needs to be converted into an array + $content = explode('|', $data); - // Non-existent index 2 will happen in menu blocks - if (!isset($content[2])) $content[2] = ''; + // Non-existent index 2 will happen in menu blocks + if (!isset($content[2])) { + $content[2] = ''; + } // END - if - // Re-construct the array: 0=visible,1=locked,2=prefix - $content['visible'] = $content[0]; - $content['locked'] = $content[1]; + // Re-construct the array: 0=visible,1=locked,2=prefix + $content['visible'] = $content[0]; + $content['locked'] = $content[1]; - // Call our "translator" function - $content = translateMenuVisibleLocked($content, $content[2]); + // Call our "translator" function + $content = translateMenuVisibleLocked($content, $content[2]); - // Return CSS classes - return ($content['visible_css'] . ' ' . $content['locked_css']); + // Set it in cache + $GLOBALS[__FUNCTION__][$data] = ($content['visible_css'] . ' ' . $content['locked_css']); + } // END - if + + // Return cache + return $GLOBALS[__FUNCTION__][$data]; } // Generate XHTML code for the CAPTCHA -function generateCaptchaCode ($code, $type, $type, $userid) { - return 'Code ' . $code . ''; +function generateCaptchaCode ($code, $type, $urlId, $userid) { + return 'Code ' . $code . ''; } // Compiles the given HTML/mail code -function compileCode ($code, $simple = false, $constants = true, $full = true, $compileCode = true) { +function compileCode ($code, $full = TRUE, $compileCode = TRUE) { // Is the code a string or should we not compile? - if ((!is_string($code)) || ($compileCode === false)) { + if ((!is_string($code)) || ($compileCode === FALSE)) { // Silently return it return $code; } // END - if // Start couting - $startCompile = microtime(true); + $startCompile = microtime(TRUE); // Comile the code - $code = compileRawCode($code, $simple, $constants, $full); + $code = compileRawCode($code, $full, $compileCode); // Get timing - $compiled = microtime(true); + $compilationTime = $startCompile - microtime(TRUE); // Add timing if enabled if (isTemplateHtml()) { // Add timing, this should be disabled in - $code .= ''; + $code .= ''; } // END - if // Return compiled code return $code; } -// Compiles the code (use compileCode() only for HTML because of the comments) -// @TODO $simple/$constants are deprecated -function compileRawCode ($code, $simple = false, $constants = true, $full = true, $compileCode = true) { +// Compiles the code +function compileRawCode ($code, $full = TRUE, $compileCode = TRUE) { // Is the code a string or shall we not compile? - if ((!is_string($code)) || ($compileCode === false)) { + if ((!is_string($code)) || ($compileCode === FALSE)) { // Silently return it return $code; } // END - if @@ -607,22 +658,23 @@ function compileRawCode ($code, $simple = false, $constants = true, $full = true $secChars = $GLOBALS['url_chars']; // Select full set of chars to replace when we e.g. want to compile URLs - if ($full === true) { + if ($full === TRUE) { $secChars = $GLOBALS['security_chars']; } // END - if // Compile more through a filter $code = runFilterChain('compile_code', $code); - // Compile message strings - $code = str_replace('{--', '{%message,', str_replace('--}', '%}', $code)); + // First compile these chars + array_unshift($secChars['to'] , '{--' , '--}'); + array_unshift($secChars['from'], '{%message,', '%}' ); // Compile QUOT and other non-HTML codes $code = str_replace($secChars['to'], $secChars['from'], $code); // Find $content[bla][blub] entries - // @TODO Do only use $content and deprecate $DATA in templates - preg_match_all('/\$(content|DATA)((\[([a-zA-Z0-9-_]+)\])*)/', $code, $matches); + preg_match_all('/\$content((\[([a-zA-Z0-9-_]+)\])*)/', $code, $matches); + //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Second regex gave ' . count($matches[0]) . ' matches.'); // Are some matches found? if ((count($matches) > 0) && (count($matches[0]) > 0)) { @@ -630,7 +682,7 @@ function compileRawCode ($code, $simple = false, $constants = true, $full = true $matchesFound = array(); foreach ($matches[0] as $key => $match) { // Fuzzy look has failed by default - $fuzzyFound = false; + $fuzzyFound = FALSE; // Fuzzy look on match if already found foreach ($matchesFound as $found => $set) { @@ -638,82 +690,104 @@ function compileRawCode ($code, $simple = false, $constants = true, $full = true $test = substr($found, 0, strlen($match)); // Does this entry exist? - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'found=' . $found . ',match=' . $match . ',set=' . $set); + //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'found=' . $found . ',match=' . $match . ',set=' . $set); if ($test == $match) { // Match found - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'fuzzyFound!'); - $fuzzyFound = true; + //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'fuzzyFound!'); + $fuzzyFound = TRUE; break; } // END - if } // END - foreach // Skip this entry? - if ($fuzzyFound === true) { + if ($fuzzyFound === TRUE) { continue; } // END - if // Take all string elements - if ((is_string($matches[4][$key])) && (!isset($matchesFound[$match])) && (!isset($matchesFound[$key.'_' . $matches[4][$key]]))) { - // Replace it in the code - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',match=' . $match); - $newMatch = str_replace('[', "['", str_replace(']', "']", $match)); + if ((is_string($matches[3][$key])) && (!isset($matchesFound[$match])) && (!isset($matchesFound[$key.'_' . $matches[3][$key]]))) { + // Replace it in the code, replace dollar sign so it won't be detected by next regex (see there) + //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',match=' . $match); + $newMatch = str_replace(array('[', ']', '$'), array("['", "']", '{COMPILE_DOLLAR}'), $match); $code = str_replace($match, '".' . $newMatch . '."', $code); - $matchesFound[$key . '_' . $matches[4][$key]] = 1; - $matchesFound[$match] = 1; + $matchesFound[$key . '_' . $matches[3][$key]] = 1; + $matchesFound[$match] = TRUE; } elseif (!isset($matchesFound[$match])) { // Not yet replaced! - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'match=' . $match); + //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'match=' . $match); $code = str_replace($match, '".' . $match . '."', $code); $matchesFound[$match] = 1; + } else { + // Everthing else should be a least logged + logDebugMessage(__FUNCTION__, __LINE__, 'match=' . $match . ',key=' . $key); } } // END - foreach } // END - if - // Return it + /* + * Find $foobar, $foo_bar and $fooBar entries. This regex would also find + * $content[foo_bar] which would result in {DOLLAR}content[foo_bar] and + * therefore the variable's value won't be inserted. This is why + * {COMPILE_DOLLAR} is being used in above loop and at the end of this + * function being replace with the original dollar sign again. + */ + preg_match_all('/\$([a-z_A-Z\[\]]){0,}/', $code, $matches); + + // Are some matches found? + if ((count($matches) > 0) && (count($matches[0]) > 0)) { + // Scan all matches for not $content + foreach ($matches[0] as $match) { + // Trim match + $match = trim($match); + + // Debug message + //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'match=' . $match); + + // Is the first part not $content/$userid and not empty? + // @TODO $userid is deprecated and should be removed from loadEmailTemplate() and replaced with $content[userid] in all templates + if ((!empty($match)) && (substr($match, 0, 8) != '$content') && ($match != '$userid')) { + //* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'match=' . $match . ' - SECURED!'); + // Then replace $ with {DOLLAR} + $matchSecured = str_replace('$', '{DOLLAR}', $match); + + // And in $code as well + $code = str_replace($match, $matchSecured, $code); + } // END - if + } // END - if + } // END - if + + // Replace {COMPILE_DOLLAR} back to dollar sign + $code = str_replace('{COMPILE_DOLLAR}', '$', $code); + + // Finally return it return $code; } // -function addSelectionBox ($type, $default, $prefix = '', $id = '0', $class = 'form_select') { +function addSelectionBox ($type, $default, $prefix = '', $id = NULL, $class = 'form_select') { $OUT = ''; if ($type == 'yn') { // This is a yes/no selection only! - if ($id > 0) $prefix .= '[' . $id . ']'; + if (isValidId($id)) $prefix .= '[' . $id . ']'; $OUT .= ''; } switch ($type) { - case 'day': // Day - for ($idx = 1; $idx < 32; $idx++) { - $OUT .= ''; - // Calculate earliest year depending on extension version - if (isExtensionInstalledAndNewer('other', '0.2.1')) { - // Use configured minimum age - $year = getYear() - getConfig('min_age'); - } else { - // Use fixed 16 years age - $year = getYear() - 16; - } // Construct year selection list - for ($idx = $minYear; $idx <= $year; $idx++) { + for ($idx = $minYear; $idx <= $startYear; $idx++) { $OUT .= '