' . $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
// Return string
return $str;
}
// Init color switch
function initTemplateColorSwitch ($template) {
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'INIT:' . $template);
$GLOBALS['color_switch'][$template] = 2;
}
// "Getter" for color switch code
function getColorSwitchCode ($template) {
// Prepare the code
$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) {
// Init output
if (!isset($GLOBALS['output'])) {
$GLOBALS['output'] = '';
} // END - if
// Do we have HTML-Code here?
if (!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... :-)
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");
} else {
// Render mode for old or lame servers...
$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";
}
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'] = ''; }
// The same as above... ^
outputRawCode($htmlCode);
if ($newLine === true) print("\n");
break;
default:
// Huh, something goes wrong or maybe you have edited config.php ???
debug_report_bug(__FUNCTION__, __LINE__, '{--FATAL_ERROR--}: {--NO_RENDER_DIRECT--}');
break;
} // END - switch
} elseif ((getPhpCaching() == 'on') && ((!isset($GLOBALS['header'])) || (count($GLOBALS['header']) == 0))) {
// Output cached HTML code
$GLOBALS['output'] = ob_get_contents();
// Clear output buffer for later output if output is found
if (!empty($GLOBALS['output'])) {
clearOutputBuffer();
} // END - if
// Send all HTTP headers
sendHttpHeaders();
// Compile and run finished rendered HTML code
compileFinalOutput();
// Output code here, DO NOT REMOVE! ;-)
outputRawCode($GLOBALS['output']);
} elseif ((getOutputMode() == 'render') && (!empty($GLOBALS['output']))) {
// Send all HTTP headers
sendHttpHeaders();
// Compile and run finished rendered HTML code
compileFinalOutput();
// Output code here, DO NOT REMOVE! ;-)
outputRawCode($GLOBALS['output']);
} else {
// And flush all headers
flushHeaders();
}
}
// Compiles the final output
function compileFinalOutput () {
// Add page header and footer
addPageHeaderFooter();
// Do the final compilation
$GLOBALS['output'] = doFinalCompilation($GLOBALS['output']);
// Extension 'rewrite' installed?
if ((isExtensionActive('rewrite')) && (!isCssOutputMode())) {
$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)) {
// Compress it for HTTP gzip
$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)) {
// Compress it for HTTP deflate
$GLOBALS['output'] = gzcompress($GLOBALS['output'], 9);
// Add header
sendHeader('Content-Encoding: deflate');
}
*/
// Add final length
sendHeader('Content-Length: ' . strlen($GLOBALS['output']));
// Flush all headers
flushHeaders();
}
// Main compilation loop
function doFinalCompilation ($code, $insertComments = true, $enableCodes = true) {
// Insert comments? (Only valid with HTML templates, of course)
enableTemplateHtml($insertComments);
// Init counter
$count = 0;
// Compile all out
while (((strpos($code, '{--') !== false) || (strpos($code, '{DQUOTE}') !== false) || (strpos($code, '{?') !== false) || (strpos($code, '{%') !== false)) && ($count < 5)) {
// Init common variables
$content = array();
$newContent = '';
// Compile it
//* DEBUG: */ debugOutput('
');
eval($eval);
//* 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);
} // END - if
// Use it again
$code = $newContent;
// Count round
$count++;
} // END - while
// Return the compiled code
return $code;
}
// Output the raw HTML code
function outputRawCode ($htmlCode) {
// Output stripped HTML code to avoid broken JavaScript code, etc.
print(str_replace('{BACK}', "\\", $htmlCode));
// Flush the output if only getPhpCaching() is not 'on'
if (getPhpCaching() != 'on') {
// Flush it
flush();
} // END - if
}
// Load a template file and return it's content (only it's name; do not use ' or ")
function loadTemplate ($template, $return = false, $content = array()) {
// @TODO Remove this sanity-check if all is fine
if (!is_bool($return)) debug_report_bug(__FUNCTION__, __LINE__, 'return is not bool (' . gettype($return) . ')');
// Set current template
$GLOBALS['current_template'] = $template;
// Do we have cache?
if ((isDebuggingTemplateCache() === false) && (isTemplateCached($template))) {
// Evaluate the cache
eval(readTemplateCache($template));
} elseif (!isset($GLOBALS['template_eval'][$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);
// Generate FQFN
$FQFN = $basePath . $extraPath . $template . '.tpl';
// Does the special template exists?
if (!isFileReadable($FQFN)) {
// Reset to default template
$FQFN = $basePath . $template . '.tpl';
} // END - if
// Now does the final template exists?
if (isFileReadable($FQFN)) {
// Count the template load
incrementConfigEntry('num_templates');
// The local file does exists so we load it. :)
$GLOBALS['tpl_content'][$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)) {
// Normal HTML output?
if (isHtmlOutputMode()) {
// Add surrounding HTML comments to help finding bugs faster
$ret = '' . $GLOBALS['tpl_content'][$template] . '';
// Prepare eval() command
$GLOBALS['template_eval'][$template] = '$ret = "' . getColorSwitchCode($template) . compileCode(escapeQuotes($ret)) . '";';
} 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])) . '");';
} else {
// Prepare eval() command, other output doesn't like entities, maybe
$GLOBALS['template_eval'][$template] = '$ret = decodeEntities("' . compileRawCode(escapeQuotes($GLOBALS['tpl_content'][$template])) . '");';
}
} else {
// Add surrounding HTML comments to help finding bugs faster
$ret = '' . $GLOBALS['tpl_content'][$template] . '';
$GLOBALS['template_eval'][$template] = '$ret = "' . getColorSwitchCode($template) . compileRawCode(escapeQuotes($ret)) . '";';
} // END - if
} elseif ((isAdmin()) || ((isInstalling()) && (!isInstalled()))) {
// Only admins shall see this warning or when installation mode is active
$ret = '
{--TEMPLATE_404--}
(' . $template . ')
{--TEMPLATE_CONTENT--}
' . print_r($content, true) . '
';
} else {
// No file!
$GLOBALS['template_eval'][$template] = '404';
}
}
// Code set?
if ((isset($GLOBALS['template_eval'][$template])) && ($GLOBALS['template_eval'][$template] != '404')) {
// Eval the code
eval($GLOBALS['template_eval'][$template]);
} // 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()) {
// Warning, empty output!
return 'E:' . $template . ',content=
' . print_r($content, true) . '
';
}
}
// Detects the extra template path from given template name
function detectExtraTemplatePath ($template) {
// Default is empty
$extraPath = '';
// Do we have cache?
if (!isset($GLOBALS['extra_path'][$template])) {
// Check for admin/guest/member/etc. templates
if (substr($template, 0, 6) == 'admin_') {
// Admin template found
$extraPath = 'admin/';
} elseif (substr($template, 0, 6) == 'guest_') {
// Guest template found
$extraPath = 'guest/';
} elseif (substr($template, 0, 7) == 'member_') {
// Member template found
$extraPath = 'member/';
} elseif (substr($template, 0, 7) == 'select_') {
// Selection template found
$extraPath = 'select/';
} elseif (substr($template, 0, 8) == 'install_') {
// Installation template found
$extraPath = 'install/';
} elseif (substr($template, 0, 4) == 'ext_') {
// Extension template found
$extraPath = 'ext/';
} elseif (substr($template, 0, 3) == 'la_') {
// 'Logical-area' template found
$extraPath = 'la/';
} elseif (substr($template, 0, 3) == 'js_') {
// JavaScript template found
$extraPath = 'js/';
} elseif (substr($template, 0, 5) == 'menu_') {
// Menu template found
$extraPath = 'menu/';
} else {
// Test for extension
$test = substr($template, 0, strpos($template, '_'));
// Probe for valid extension name
if (isExtensionNameValid($test)) {
// Set extra path to extension's name
$extraPath = $test . '/';
} // END - if
}
// Store it in cache
$GLOBALS['extra_path'][$template] = $extraPath;
} // END - if
// Return result
return $GLOBALS['extra_path'][$template];
}
// Loads an email template and compiles it
function loadEmailTemplate ($template, $content = array(), $userid = '0', $loadUserData = true) {
global $DATA;
// Make sure all template names are lowercase!
$template = strtolower($template);
// Is content an array?
if (is_array($content)) {
// Add expiration to array
if ((isConfigEntrySet('auto_purge')) && (getAutoPurge() == '0')) {
// Will never expire!
$content['expiration'] = '{--MAIL_WILL_NEVER_EXPIRE--}';
} elseif (isConfigEntrySet('auto_purge')) {
// Create nice date string
$content['expiration'] = '{%pipe,getAutoPurge,createFancyTime%}';
} else {
// Missing entry
$content['expiration'] = '{--MAIL_NO_CONFIG_AUTO_PURGE--}';
}
} // 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))) {
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "NICKNAME! ");
// Load by nickname
fetchUserData($userid, 'nickname');
} else {
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "NO-NICK! ");
/// Load by userid
fetchUserData($userid);
}
// Merge data if valid
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "content()=".count($content)." - PRE ");
if ((isUserDataValid()) && ($loadUserData === true)) {
$content = merge_array($content, getUserDataArray());
} // END - if
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "content()=".count($content)." - AFTER ");
} // END - if
// Base directory
$basePath = sprintf("%stemplates/%s/emails/", getPath(), getLanguage());
// Detect extra path
$extraPath = detectExtraTemplatePath($template);
// 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
// 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 = '
{--TEMPLATE_404--}: ' . $template . '
{--TEMPLATE_CONTENT--}
' . print_r($content, true) . '
{--TEMPLATE_DATA--}
' . print_r($DATA, 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--}';
}
// Is there some content?
if (empty($newContent)) {
// Compiling failed
$newContent = "Compiler error for template " . $template . " !\nUncompiled content:\n" . $GLOBALS['tpl_content'][$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.";
} // END - if
// Remove content and data
unset($content);
unset($DATA);
// Return content
return $newContent;
}
// "Getter" for menu CSS classes, mainly used in templates
function getMenuCssClasses ($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] = '';
// 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]);
// Return CSS classes
return ($content['visible_css'] . ' ' . $content['locked_css']);
}
// Generate XHTML code for the CAPTCHA
function generateCaptchaCode ($code, $type, $DATA, $userid) {
return '';
}
// Compiles the given HTML/mail code
function compileCode ($code, $simple = false, $constants = true, $full = true) {
// Is the code a string?
if (!is_string($code)) {
// Silently return it
return $code;
} // END - if
// Start couting
$startCompile = microtime(true);
// Comile the code
$code = compileRawCode($code, $simple, $constants, $full);
// Get timing
$compiled = microtime(true);
// Add timing if enabled
if (isTemplateHtml()) {
// Add timing, this should be disabled in
$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) {
// Is the code a string?
if (!is_string($code)) {
// Silently return it
return $code;
} // END - if
// Init replacement-array with smaller set of security characters
$secChars = $GLOBALS['url_chars'];
// Select full set of chars to replace when we e.g. want to compile URLs
if ($full === true) $secChars = $GLOBALS['security_chars'];
// Compile more through a filter
$code = runFilterChain('compile_code', $code);
// Compile message strings
$code = str_replace('{--', '{%message,', str_replace('--}', '%}', $code));
// 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 $GLOBALS and $DATA in templates
preg_match_all('/\$(content|GLOBALS|DATA)((\[([a-zA-Z0-9-_]+)\])*)/', $code, $matches);
// Are some matches found?
if ((count($matches) > 0) && (count($matches[0]) > 0)) {
// Replace all matches
$matchesFound = array();
foreach ($matches[0] as $key => $match) {
// Fuzzy look has failed by default
$fuzzyFound = false;
// Fuzzy look on match if already found
foreach ($matchesFound as $found => $set) {
// Get test part
$test = substr($found, 0, strlen($match));
// Does this entry exist?
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "found={$found},match={$match},set={$set} ");
if ($test == $match) {
// Match found
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "fuzzyFound! ");
$fuzzyFound = true;
break;
} // END - if
} // END - foreach
// Skip this entry?
if ($fuzzyFound === true) continue;
// 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));
$code = str_replace($match, '".' . $newMatch . '."', $code);
$matchesFound[$key . '_' . $matches[4][$key]] = 1;
$matchesFound[$match] = 1;
} elseif (!isset($matchesFound[$match])) {
// Not yet replaced!
//* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "match={$match} ");
$code = str_replace($match, '".' . $match . '."', $code);
$matchesFound[$match] = 1;
}
} // END - foreach
} // END - if
// Return it
return $code;
}
//
function addSelectionBox ($type, $default, $prefix = '', $id = '0', $class = 'form_select') {
$OUT = '';
if ($type == 'yn') {
// This is a yes/no selection only!
if ($id > 0) $prefix .= '[' . $id . ']';
$OUT .= '