Login procedure rewritten to filters (internal TODO)
[mailer.git] / inc / functions.php
index c68f9cb293ddd99be3a2435097d0a82d347cd4a4..77065f95dc90447e82733d57730b0d116ef105ad 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 /************************************************************************
- * MXChange v0.2.1                                    Start: 08/25/2003 *
- * ===============                              Last change: 11/29/2005 *
+ * Mailer v0.2.1-FINAL                                Start: 08/25/2003 *
+ * ===================                          Last change: 11/29/2005 *
  *                                                                      *
  * -------------------------------------------------------------------- *
  * File              : functions.php                                    *
@@ -77,7 +77,7 @@ function outputHtml ($htmlCode, $newLine = true) {
 
                                // The same as above... ^
                                outputRawCode($htmlCode);
-                               if ($newLine) print("\n");
+                               if ($newLine === true) print("\n");
                                break;
 
                        default:
@@ -163,7 +163,7 @@ function compileFinalOutput () {
                $newContent = '';
 
                // Compile it
-               $eval = "\$newContent = \"".compileCode(addslashes($GLOBALS['output']))."\";";
+               $eval = "\$newContent = \"".compileCode(escapeQuotes($GLOBALS['output']))."\";";
                eval($eval);
 
                // Was that eval okay?
@@ -184,7 +184,7 @@ function compileFinalOutput () {
 // Output the raw HTML code
 function outputRawCode ($htmlCode) {
        // Output stripped HTML code to avoid broken JavaScript code, etc.
-       print($htmlCode);
+       print(str_replace('{BACK}', "\\", $htmlCode));
 
        // Flush the output if only getPhpCaching() is not 'on'
        if (getPhpCaching() != 'on') {
@@ -204,7 +204,7 @@ function getFatalArray () {
 }
 
 // Add a fatal error message to the queue array
-function addFatalMessage ($F, $L, $message, $extra='') {
+function addFatalMessage ($F, $L, $message, $extra = '') {
        if (is_array($extra)) {
                // Multiple extras for a message with masks
                $message = call_user_func_array('sprintf', $extra);
@@ -218,7 +218,7 @@ function addFatalMessage ($F, $L, $message, $extra='') {
 
        // Log fatal messages away
        debug_report_bug($message);
-       logDebugMessage($F, $L, " message={$message}");
+       logDebugMessage($F, $L, 'Fatal error message: ' . $message);
 }
 
 // Getter for total fatal message count
@@ -237,7 +237,7 @@ function getTotalFatalErrors () {
 }
 
 // Load a template file and return it's content (only it's name; do not use ' or ")
-function loadTemplate ($template, $return=false, $content=array()) {
+function loadTemplate ($template, $return = false, $content = array()) {
        // @TODO Remove this sanity-check if all is fine
        if (!is_bool($return)) debug_report_bug('return is not bool (' . gettype($return) . ')');
 
@@ -255,73 +255,18 @@ function loadTemplate ($template, $return=false, $content=array()) {
                // Make all template names lowercase
                $template = strtolower($template);
 
-               // Count the template load
-               incrementConfigEntry('num_templates');
-
                // Init some data
                $ret = '';
                if (empty($GLOBALS['refid'])) $GLOBALS['refid'] = '0';
 
                // Base directory
                $basePath = sprintf("%stemplates/%s/html/", getConfig('PATH'), getLanguage());
-               $mode = '';
-
-               // Check for admin/guest/member templates
-               if (substr($template, 0, 6) == 'admin_') {
-                       // Admin template found
-                       $mode = 'admin/';
-               } elseif (substr($template, 0, 6) == 'guest_') {
-                       // Guest template found
-                       $mode = 'guest/';
-               } elseif (substr($template, 0, 7) == 'member_') {
-                       // Member template found
-                       $mode = 'member/';
-               } elseif (substr($template, 0, 8) == 'install_') {
-                       // Installation template found
-                       $mode = 'install/';
-               } elseif (substr($template, 0, 4) == 'ext_') {
-                       // Extension template found
-                       $mode = 'ext/';
-               } elseif (substr($template, 0, 3) == 'la_') {
-                       // 'Logical-area' template found
-                       $mode = 'la/';
-               } elseif (substr($template, 0, 3) == 'js_') {
-                       // JavaScript template found
-                       $mode = 'js/';
-               } elseif (substr($template, 0, 5) == 'menu_') {
-                       // Menu template found
-                       $mode = '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
-                               $mode = $test . '/';
-                       } // END - if
-               }
+               $extraPath = detectExtraTemplatePath($template);;
 
                ////////////////////////
                // Generate file name //
                ////////////////////////
-               $FQFN = $basePath . $mode . $template . '.tpl';
-
-               if ((isWhatSet()) && ((strpos($template, '_header') > 0) || (strpos($template, '_footer') > 0)) && (($mode == 'guest/') || ($mode == 'member/') || ($mode == 'admin/'))) {
-                       // Select what depended header/footer template file for admin/guest/member area
-                       $file2 = sprintf("%s%s%s_%s.tpl",
-                               $basePath,
-                               $mode,
-                               $template,
-                               getWhat()
-                       );
-
-                       // Probe for it...
-                       if (isFileReadable($file2)) $FQFN = $file2;
-
-                       // Remove variable from memory
-                       unset($file2);
-               } // END - if
+               $FQFN = $basePath . $extraPath . $template . '.tpl';
 
                // Does the special template exists?
                if (!isFileReadable($FQFN)) {
@@ -331,6 +276,9 @@ function loadTemplate ($template, $return=false, $content=array()) {
 
                // 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'] = readFromFile($FQFN);
 
@@ -340,21 +288,21 @@ function loadTemplate ($template, $return=false, $content=array()) {
                                // Normal HTML output?
                                if (getOutputMode() == '0') {
                                        // Add surrounding HTML comments to help finding bugs faster
-                                       $ret = "<!-- Template " . $template . " - Start -->\n" . $GLOBALS['tpl_content'] . "<!-- Template " . $template . " - End -->\n";
+                                       $ret = '<!-- Template ' . $template . " - Start -->\n" . $GLOBALS['tpl_content'] . '<!-- Template ' . $template . " - End -->\n";
 
                                        // Prepare eval() command
-                                       $eval = '$ret = "' . compileCode(addslashes($ret)) . '";';
+                                       $eval = '$ret = "' . compileCode(escapeQuotes($ret)) . '";';
                                } elseif (substr($template, 0, 3) == 'js_') {
                                        // JavaScripts don't like entities and timings
-                                       $eval = '$ret = decodeEntities("' . compileRawCode(addslashes($GLOBALS['tpl_content'])) . '");';
+                                       $eval = '$ret = decodeEntities("' . compileRawCode(escapeJavaScriptQuotes($GLOBALS['tpl_content'])) . '");';
                                } else {
-                                       // Prepare eval() command
-                                       $eval = '$ret = "' . compileCode(addslashes($GLOBALS['tpl_content'])) . '";';
+                                       // Prepare eval() command, other output doesn't like entities, maybe
+                                       $eval = '$ret = decodeEntities("' . compileRawCode(escapeQuotes($GLOBALS['tpl_content'])) . '");';
                                }
                        } else {
                                // Add surrounding HTML comments to help finding bugs faster
-                               $ret = "<!-- Template " . $template . " - Start -->\n" . $GLOBALS['tpl_content'] . "<!-- Template " . $template . " - End -->\n";
-                               $eval = '$ret = "' . addslashes($ret) . '";';
+                               $ret = '<!-- Template ' . $template . " - Start -->\n" . $GLOBALS['tpl_content'] . '<!-- Template ' . $template . " - End -->\n";
+                               $eval = '$ret = "' . escapeQuotes($ret) . '";';
                        } // END - if
 
                        // Cache the eval() command here
@@ -364,7 +312,7 @@ function loadTemplate ($template, $return=false, $content=array()) {
                        eval($GLOBALS['template_eval'][$template]);
                } elseif ((isAdmin()) || ((isInstalling()) && (!isInstalled()))) {
                        // Only admins shall see this warning or when installation mode is active
-                       $ret = '<br /><span class=\\"guest_failed\\">{--TEMPLATE_404--}</span><br />
+                       $ret = '<br /><span class="guest_failed">{--TEMPLATE_404--}</span><br />
 (' . $template . ')<br />
 <br />
 {--TEMPLATE_CONTENT--}
@@ -397,6 +345,60 @@ function loadTemplate ($template, $return=false, $content=array()) {
        }
 }
 
+// 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(), $UID = '0') {
        global $DATA;
@@ -446,7 +448,7 @@ function loadEmailTemplate ($template, $content = array(), $UID = '0') {
        //* DEBUG: */ outputHtml(__FUNCTION__."(<font color=\"#0000aa\">".__LINE__."</font>):UID={$UID},template={$template},content[]=".gettype($content).'<br />');
        if (($UID > 0) && (is_array($content))) {
                // If nickname extension is installed, fetch nickname as well
-               if (isNicknameUsed($UID)) {
+               if ((isExtensionActive('nickname')) && (isNicknameUsed($UID))) {
                        //* DEBUG: */ outputHtml(__FUNCTION__."(<font color=\"#0000aa\">".__LINE__."</font>):NICKNAME!<br />");
                        // Load by nickname
                        fetchUserData($UID, 'nickname');
@@ -471,37 +473,22 @@ function loadEmailTemplate ($template, $content = array(), $UID = '0') {
        if (isset($content['email'])) $email = $content['email'];
 
        // Store email for some functions in global data array
+       // @TODO Do only use $contentn, not $DATA or raw variables
        $DATA['email'] = $email;
 
        // Base directory
        $basePath = sprintf("%stemplates/%s/emails/", getConfig('PATH'), getLanguage());
 
-       // Check for admin/guest/member templates
-       if (substr($template, 0, 6) == 'admin_') {
-               // Admin template found
-               $FQFN = $basePath.'admin/' . $template.'.tpl';
-       } elseif (substr($template, 0, 6) == 'guest_') {
-               // Guest template found
-               $FQFN = $basePath.'guest/' . $template.'.tpl';
-       } elseif (substr($template, 0, 7) == 'member_') {
-               // Member template found
-               $FQFN = $basePath.'member/' . $template.'.tpl';
-       } else {
-               // Test for extension
-               $test = substr($template, 0, strpos($template, '_'));
-               if (isExtensionNameValid($test)) {
-                       // Set extra path to extension's name
-                       $FQFN = $basePath . $test.'/' . $template.'.tpl';
-               } else {
-                       // No special filename
-                       $FQFN = $basePath . $template.'.tpl';
-               }
-       }
+       // 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';
+               $FQFN = $basePath . $template . '.tpl';
        } // END - if
 
        // Now does the final template exists?
@@ -511,16 +498,16 @@ function loadEmailTemplate ($template, $content = array(), $UID = '0') {
                $GLOBALS['tpl_content'] = readFromFile($FQFN);
 
                // Run code
-               $GLOBALS['tpl_content'] = "\$newContent = decodeEntities(\"".compileRawCode(addslashes($GLOBALS['tpl_content']))."\");";
+               $GLOBALS['tpl_content'] = "\$newContent = decodeEntities(\"".compileRawCode(escapeQuotes($GLOBALS['tpl_content']))."\");";
                eval($GLOBALS['tpl_content']);
        } elseif (!empty($template)) {
                // Template file not found!
-               $newContent = "{--TEMPLATE_404--}: " . $template."<br />
+               $newContent = '{--TEMPLATE_404--}: ' . $template . '<br />
 {--TEMPLATE_CONTENT--}
-<pre>".print_r($content, true)."</pre>
+<pre>' . print_r($content, true) . '</pre>
 {--TEMPLATE_DATA--}
-<pre>".print_r($DATA, true)."</pre>
-<br /><br />";
+<pre>' . print_r($DATA, true) . '</pre>
+<br /><br />';
 
                // Debug mode not active? Then remove the HTML tags
                if (!isDebugModeEnabled()) $newContent = secureString($newContent);
@@ -533,6 +520,7 @@ function loadEmailTemplate ($template, $content = array(), $UID = '0') {
        if (empty($newContent)) {
                // Compiling failed
                $newContent = "Compiler error for template {$template}!\nUncompiled content:\n" . $GLOBALS['tpl_content'];
+
                // 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
@@ -541,10 +529,6 @@ function loadEmailTemplate ($template, $content = array(), $UID = '0') {
        unset($content);
        unset($DATA);
 
-       // Compile the code and eval it
-       $eval = '$newContent = "' . compileRawCode(addslashes($newContent)) . '";';
-       eval($eval);
-
        // Return content
        return $newContent;
 }
@@ -554,7 +538,7 @@ function sendEmail ($toEmail, $subject, $message, $isHtml = 'N', $mailHeader = '
        //* DEBUG: */ outputHtml(__FUNCTION__."(<font color=\"#0000aa\">".__LINE__."</font>):TO={$toEmail},SUBJECT={$subject}<br />");
 
        // Compile subject line (for POINTS constant etc.)
-       eval("\$subject = decodeEntities(\"".compileRawCode(addslashes($subject))."\");");
+       eval("\$subject = decodeEntities(\"".compileRawCode(escapeQuotes($subject))."\");");
 
        // Set from header
        if ((!eregi('@', $toEmail)) && ($toEmail > 0)) {
@@ -600,17 +584,17 @@ function sendEmail ($toEmail, $subject, $message, $isHtml = 'N', $mailHeader = '
        }
 
        // Compile "TO"
-       eval("\$toEmail = \"".compileRawCode(addslashes($toEmail))."\";");
+       eval("\$toEmail = \"".compileRawCode(escapeQuotes($toEmail))."\";");
 
        // Compile "MSG"
-       eval("\$message = \"".compileRawCode(addslashes($message))."\";");
+       eval("\$message = \"".compileRawCode(escapeQuotes($message))."\";");
 
        // Fix HTML parameter (default is no!)
        if (empty($isHtml)) $isHtml = 'N';
        if (isDebugModeEnabled()) {
                // In debug mode we want to display the mail instead of sending it away so we can debug this part
                outputHtml('<pre>
-Headers : ' . str_replace('<', '&lt', str_replace('>', '&gt;', htmlentities(trim($mailHeader)))) . '
+Headers : ' . str_replace('<', '&lt', str_replace('>', '&gt;', secureString(trim($mailHeader)))) . '
 To      : ' . $toEmail . '
 Subject : ' . $subject . '
 Message : ' . $message . '
@@ -627,7 +611,7 @@ Message : ' . $message . '
        }
 }
 
-// Check if legacy or PHPMailer command
+// Check to use wether legacy mail() command or PHPMailer class
 // @TODO Rewrite this to an extension 'smtp'
 // @private
 function checkPhpMailerUsage() {
@@ -636,6 +620,12 @@ function checkPhpMailerUsage() {
 
 // Send out a raw email with PHPMailer class or legacy mail() command
 function sendRawEmail ($toEmail, $subject, $message, $from) {
+       // Just compile all again, to put out all configs, etc.
+       eval('$toEmail = decodeEntities("' . compileRawCode(escapeQuotes($toEmail)) . '");');
+       eval('$subject = decodeEntities("' . compileRawCode(escapeQuotes($subject)) . '");');
+       eval('$message = decodeEntities("' . compileRawCode(escapeQuotes($message)) . '");');
+       eval('$from    = decodeEntities("' . compileRawCode(escapeQuotes($from))    . '");');
+
        // Shall we use PHPMailer class or legacy mode?
        if (checkPhpMailerUsage()) {
                // Use PHPMailer class with SMTP enabled
@@ -1016,16 +1006,16 @@ function compileCode ($code, $simple = false, $constants = true, $full = true) {
        } // END - if
 
        // Start couting
-       $startCompile = explode(' ', microtime());
+       $startCompile = microtime(true);
 
        // Comile the code
        $code = compileRawCode($code, $simple, $constants, $full);
 
        // Get timing
-       $compiled = explode(' ', microtime());
+       $compiled = microtime(true);
 
        // Add timing
-       $code .= '<!-- Compilation time: ' . ((($compiled[1] + $compiled[0]) - ($startCompile[1] + $startCompile[0])) * 1000). 'ms //-->';
+       $code .= '<!-- Compilation time: ' . (($compiled - $startCompile) * 1000). 'ms //-->';
 
        // Return compiled code
        return $code;
@@ -1040,11 +1030,11 @@ function compileRawCode ($code, $simple = false, $constants = true, $full = true
                return $code;
        } // END - if
 
-       // Init replacement-array with full security characters
-       $secChars = $GLOBALS['security_chars'];
+       // Init replacement-array with smaller set of security characters
+       $secChars = $GLOBALS['url_chars'];
 
-       // Select smaller set of chars to replace when we e.g. want to compile URLs
-       if ($full === false) $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);
@@ -1067,6 +1057,7 @@ function compileRawCode ($code, $simple = false, $constants = true, $full = true
        } // END - foreach
 
        // 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?
@@ -1100,13 +1091,13 @@ function compileRawCode ($code, $simple = false, $constants = true, $full = true
                                // Replace it in the code
                                //* DEBUG: */ outputHtml(__FUNCTION__."(<font color=\"#0000aa\">".__LINE__."</font>):key={$key},match={$match}<br />");
                                $newMatch = str_replace('[', "['", str_replace(']', "']", $match));
-                               $code = str_replace($match, "\"." . $newMatch.".\"", $code);
+                               $code = str_replace($match, '".' . $newMatch . '."', $code);
                                $matchesFound[$key . '_' . $matches[4][$key]] = 1;
                                $matchesFound[$match] = 1;
                        } elseif (!isset($matchesFound[$match])) {
                                // Not yet replaced!
                                //* DEBUG: */ outputHtml(__FUNCTION__."(<font color=\"#0000aa\">".__LINE__."</font>):match={$match}<br />");
-                               $code = str_replace($match, "\"." . $match.".\"", $code);
+                               $code = str_replace($match, '".' . $match . '."', $code);
                                $matchesFound[$match] = 1;
                        }
                } // END - foreach
@@ -1472,35 +1463,35 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
        } else {
                // Generate table
                $OUT  = "<div align=\"" . $align."\">\n";
-               $OUT .= "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"admin_table dashed\">\n";
+               $OUT .= "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"timebox_table dashed\">\n";
                $OUT .= "<tr>\n";
 
                if (ereg('Y', $display) || (empty($display))) {
-                       $OUT .= "  <td align=\"center\" class=\"admin_title bottom\"><div class=\"tiny\">{--_YEARS--}</strong></td>\n";
+                       $OUT .= "  <td align=\"center\" class=\"timebox_column bottom\"><div class=\"tiny\">{--_YEARS--}</strong></td>\n";
                }
 
                if (ereg('M', $display) || (empty($display))) {
-                       $OUT .= "  <td align=\"center\" class=\"admin_title bottom\"><div class=\"tiny\">{--_MONTHS--}</strong></td>\n";
+                       $OUT .= "  <td align=\"center\" class=\"timebox_column bottom\"><div class=\"tiny\">{--_MONTHS--}</strong></td>\n";
                }
 
-               if (ereg("W", $display) || (empty($display))) {
-                       $OUT .= "  <td align=\"center\" class=\"admin_title bottom\"><div class=\"tiny\">{--_WEEKS--}</strong></td>\n";
+               if (ereg('W', $display) || (empty($display))) {
+                       $OUT .= "  <td align=\"center\" class=\"timebox_column bottom\"><div class=\"tiny\">{--_WEEKS--}</strong></td>\n";
                }
 
-               if (ereg("D", $display) || (empty($display))) {
-                       $OUT .= "  <td align=\"center\" class=\"admin_title bottom\"><div class=\"tiny\">{--_DAYS--}</strong></td>\n";
+               if (ereg('D', $display) || (empty($display))) {
+                       $OUT .= "  <td align=\"center\" class=\"timebox_column bottom\"><div class=\"tiny\">{--_DAYS--}</strong></td>\n";
                }
 
-               if (ereg("h", $display) || (empty($display))) {
-                       $OUT .= "  <td align=\"center\" class=\"admin_title bottom\"><div class=\"tiny\">{--_HOURS--}</strong></td>\n";
+               if (ereg('h', $display) || (empty($display))) {
+                       $OUT .= "  <td align=\"center\" class=\"timebox_column bottom\"><div class=\"tiny\">{--_HOURS--}</strong></td>\n";
                }
 
                if (ereg('m', $display) || (empty($display))) {
-                       $OUT .= "  <td align=\"center\" class=\"admin_title bottom\"><div class=\"tiny\">{--_MINUTES--}</strong></td>\n";
+                       $OUT .= "  <td align=\"center\" class=\"timebox_column bottom\"><div class=\"tiny\">{--_MINUTES--}</strong></td>\n";
                }
 
-               if (ereg("s", $display) || (empty($display))) {
-                       $OUT .= "  <td align=\"center\" class=\"admin_title bottom\"><div class=\"tiny\">{--_SECONDS--}</strong></td>\n";
+               if (ereg('s', $display) || (empty($display))) {
+                       $OUT .= "  <td align=\"center\" class=\"timebox_column bottom\"><div class=\"tiny\">{--_SECONDS--}</strong></td>\n";
                }
 
                $OUT .= "</tr>\n";
@@ -1516,7 +1507,7 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
                        }
                        $OUT .= "  </select></td>\n";
                } else {
-                       $OUT .= "<INPUT type=\"hidden\" name=\"" . $prefix."_ye\" value=\"0\" />\n";
+                       $OUT .= "<input type=\"hidden\" name=\"" . $prefix."_ye\" value=\"0\" />\n";
                }
 
                if (ereg('M', $display) || (empty($display))) {
@@ -1530,10 +1521,10 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
                        }
                        $OUT .= "  </select></td>\n";
                } else {
-                       $OUT .= "<INPUT type=\"hidden\" name=\"" . $prefix."_mo\" value=\"0\" />\n";
+                       $OUT .= "<input type=\"hidden\" name=\"" . $prefix."_mo\" value=\"0\" />\n";
                }
 
-               if (ereg("W", $display) || (empty($display))) {
+               if (ereg('W', $display) || (empty($display))) {
                        // Generate week selection
                        $OUT .= "  <td align=\"center\"><select class=\"mini_select\" name=\"" . $prefix."_we\" size=\"1\">\n";
                        for ($idx = '0'; $idx <= 4; $idx++) {
@@ -1543,10 +1534,10 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
                        }
                        $OUT .= "  </select></td>\n";
                } else {
-                       $OUT .= "<INPUT type=\"hidden\" name=\"" . $prefix."_we\" value=\"0\" />\n";
+                       $OUT .= "<input type=\"hidden\" name=\"" . $prefix."_we\" value=\"0\" />\n";
                }
 
-               if (ereg("D", $display) || (empty($display))) {
+               if (ereg('D', $display) || (empty($display))) {
                        // Generate day selection
                        $OUT .= "  <td align=\"center\"><select class=\"mini_select\" name=\"" . $prefix."_da\" size=\"1\">\n";
                        for ($idx = '0'; $idx <= 31; $idx++) {
@@ -1556,10 +1547,10 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
                        }
                        $OUT .= "  </select></td>\n";
                } else {
-                       $OUT .= "<INPUT type=\"hidden\" name=\"" . $prefix."_da\" value=\"0\">\n";
+                       $OUT .= "<input type=\"hidden\" name=\"" . $prefix."_da\" value=\"0\" />\n";
                }
 
-               if (ereg("h", $display) || (empty($display))) {
+               if (ereg('h', $display) || (empty($display))) {
                        // Generate hour selection
                        $OUT .= "  <td align=\"center\"><select class=\"mini_select\" name=\"" . $prefix."_ho\" size=\"1\">\n";
                        for ($idx = '0'; $idx <= 23; $idx++)    {
@@ -1569,7 +1560,7 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
                        }
                        $OUT .= "  </select></td>\n";
                } else {
-                       $OUT .= "<INPUT type=\"hidden\" name=\"" . $prefix."_ho\" value=\"0\">\n";
+                       $OUT .= "<input type=\"hidden\" name=\"" . $prefix."_ho\" value=\"0\" />\n";
                }
 
                if (ereg('m', $display) || (empty($display))) {
@@ -1582,10 +1573,10 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
                        }
                        $OUT .= "  </select></td>\n";
                } else {
-                       $OUT .= "<INPUT type=\"hidden\" name=\"" . $prefix."_mi\" value=\"0\">\n";
+                       $OUT .= "<input type=\"hidden\" name=\"" . $prefix."_mi\" value=\"0\" />\n";
                }
 
-               if (ereg("s", $display) || (empty($display))) {
+               if (ereg('s', $display) || (empty($display))) {
                        // Generate second selection
                        $OUT .= "  <td align=\"center\"><select class=\"mini_select\" name=\"" . $prefix."_se\" size=\"1\">\n";
                        for ($idx = '0'; $idx <= 59; $idx++) {
@@ -1595,7 +1586,7 @@ function createTimeSelections ($timestamp, $prefix = '', $display = '', $align =
                        }
                        $OUT .= "  </select></td>\n";
                } else {
-                       $OUT .= "<INPUT type=\"hidden\" name=\"" . $prefix."_se\" value=\"0\">\n";
+                       $OUT .= "<input type=\"hidden\" name=\"" . $prefix."_se\" value=\"0\" />\n";
                }
                $OUT .= "</tr>\n";
                $OUT .= "</table>\n";
@@ -1664,7 +1655,7 @@ function createFancyTime ($stamp) {
 function addEmailNavigation ($PAGES, $offset, $show_form, $colspan, $return=false) {
        $SEP = ''; $TOP = '';
        if ($show_form === false) {
-               $TOP = " top2";
+               $TOP = " top";
                $SEP = "<tr><td colspan=\"" . $colspan."\" class=\"seperator\">&nbsp;</td></tr>";
        }
 
@@ -1738,7 +1729,7 @@ function extractHostnameFromUrl (&$script) {
        if (substr(strtolower($script), 0, 7) == 'http://') {
                // But only if http:// is in front!
                $script = substr($script, (strlen($url) + 7));
-       } elseif (substr(strtolower($script), 0, 8) == "https://") {
+       } elseif (substr(strtolower($script), 0, 8) == 'https://') {
                // Does this work?!
                $script = substr($script, (strlen($url) + 8));
        }
@@ -2320,89 +2311,16 @@ function getCurrentTheme () {
        // The default theme is 'default'... ;-)
        $ret = 'default';
 
-       // Load default theme if not empty from configuration
-       if ((isConfigEntrySet('default_theme')) && (getConfig('default_theme') != '')) $ret = getConfig('default_theme');
-
-       if (!isSessionVariableSet('mxchange_theme')) {
-               // Set default theme
-               setTheme($ret);
-       } elseif ((isSessionVariableSet('mxchange_theme')) && (isExtensionInstalledAndNewer('sql_patches', '0.1.4'))) {
-               //die("<pre>".print_r($GLOBALS['cache_array']['themes'], true)."</pre>");
-               // Get theme from cookie
-               $ret = getSession('mxchange_theme');
-
-               // Is it valid?
-               if (getThemeId($ret) == '0') {
-                       // Fix it to default
-                       $ret = 'default';
-               } // END - if
-       } elseif ((!isInstalled()) && ((isInstalling()) || (getOutputMode() == true)) && ((isGetRequestElementSet('theme')) || (isPostRequestElementSet('theme')))) {
-               // Prepare FQFN for checking
-               $theme = sprintf("%stheme/%s/theme.php", getConfig('PATH'), getRequestElement('theme'));
-
-               // Installation mode active
-               if ((isGetRequestElementSet('theme')) && (isFileReadable($theme))) {
-                       // Set cookie from URL data
-                       setTheme(getRequestElement('theme'));
-               } elseif (isFileReadable(sprintf("%stheme/%s/theme.php", getConfig('PATH'), SQL_ESCAPE(postRequestElement('theme'))))) {
-                       // Set cookie from posted data
-                       setTheme(SQL_ESCAPE(postRequestElement('theme')));
-               }
-
-               // Set return value
-               $ret = getSession('mxchange_theme');
-       } else {
-               // Invalid design, reset cookie
-               setTheme($ret);
-       }
+       // Do we have ext-theme installed and active?
+       if (isExtensionActive('theme')) {
+               // Call inner method
+               $ret = getActualTheme();
+       } // END - if
 
        // Return theme value
        return $ret;
 }
 
-// Setter for theme in session
-function setTheme ($newTheme) {
-       setSession('mxchange_theme', $newTheme);
-}
-
-// Get id from theme
-// @TODO Try to move this to inc/libs/theme_functions.php
-function getThemeId ($name) {
-       // Is the extension 'theme' installed?
-       if (!isExtensionActive('theme')) {
-               // Then abort here
-               return 0;
-       } // END - if
-
-       // Default id
-       $id = '0';
-
-       // Is the cache entry there?
-       if (isset($GLOBALS['cache_array']['themes']['id'][$name])) {
-               // Get the version from cache
-               $id = $GLOBALS['cache_array']['themes']['id'][$name];
-
-               // Count up
-               incrementStatsEntry('cache_hits');
-       } elseif (getExtensionVersion('cache') != '0.1.8') {
-               // Check if current theme is already imported or not
-               $result = SQL_QUERY_ESC("SELECT `id` FROM `{?_MYSQL_PREFIX?}_themes` WHERE `theme_path`='%s' LIMIT 1",
-                       array($name), __FUNCTION__, __LINE__);
-
-               // Entry found?
-               if (SQL_NUMROWS($result) == 1) {
-                       // Fetch data
-                       list($id) = SQL_FETCHROW($result);
-               } // END - if
-
-               // Free result
-               SQL_FREERESULT($result);
-       }
-
-       // Return id
-       return $id;
-}
-
 // Generates an error code from given account status
 function generateErrorCodeFromUserStatus ($status='') {
        // If no status is provided, use the default, cached
@@ -2506,7 +2424,7 @@ function getActualVersion ($type = 'Revision') {
                                        $new = true;
                                } else {
                                        // Generate fake cache entry
-                                       foreach ($mapper as $map=>$idx) {
+                                       foreach ($mapper as $map => $idx) {
                                                $GLOBALS['cache_array']['revision'][$map][0] = $ins_vers[$idx];
                                        } // END - foreach
 
@@ -2656,7 +2574,7 @@ function debug_report_bug ($message = '') {
        } // END - if
 
        // Add output
-       $debug .= "Please report this bug at <a title=\"Direct link to the bug-tracker\" href=\"http://bugs.mxchange.org\" rel=\"external\" target=\"_blank\">bugs.mxchange.org</a> and include the logfile from <strong>" . getConfig('CACHE_PATH') . "debug.log</strong> in your report (you can now attach files):<pre>";
+       $debug .= "Please report this bug at <a title=\"Direct link to the bug-tracker\" href=\"http://bugs.mxchange.org\" rel=\"external\" target=\"_blank\">bugs.mxchange.org</a> and include the logfile from <strong>" . str_replace(getConfig('PATH'), '', getConfig('CACHE_PATH')) . "debug.log</strong> in your report (you can now attach files):<pre>";
        $debug .= debug_get_printable_backtrace();
        $debug .= "</pre>\nRequest-URI: " . getRequestUri()."<br />\n";
        $debug .= "Thank you for finding bugs.";
@@ -2666,11 +2584,9 @@ function debug_report_bug ($message = '') {
        die($debug);
 }
 
-// Generates a ***weak*** seed (taken from de.php.net/mt_srand)
+// Generates a ***weak*** seed
 function generateSeed () {
-       list($usec, $sec) = explode(' ', microtime());
-       $microTime = (((float)$sec + (float)$usec)) * 100000;
-       return $microTime;
+       return microtime(true) * 100000;
 }
 
 // Converts a message code to a human-readable message
@@ -3184,7 +3100,7 @@ function determineReferalId () {
        } elseif ((isSessionVariableSet('refid')) && (getSession('refid') != 0)) {
                // Set session refid als global
                $GLOBALS['refid'] = bigintval(getSession('refid'));
-       } elseif ((isExtensionInstalledAndNewer('user', '0.3.4')) && (getConfig('select_user_zero_refid')) == 'Y') {
+       } elseif ((isExtensionInstalledAndNewer('user', '0.3.4')) && (getConfig('select_user_zero_refid') == 'Y')) {
                // Select a random user which has confirmed enougth mails
                $GLOBALS['refid'] = determineRandomReferalId();
        } elseif ((isExtensionInstalled('sql_patches')) && (getConfig('def_refid') > 0)) {
@@ -3201,7 +3117,7 @@ function determineReferalId () {
                $found = false;
 
                // Do we have nickname or userid set?
-               if (isNicknameUsed($GLOBALS['refid'])) {
+               if ((isExtensionActive('nickname')) && (isNicknameUsed($GLOBALS['refid']))) {
                        // Nickname in URL, so load the id
                        $found = fetchUserData($GLOBALS['refid'], 'nickname');
                } elseif ($GLOBALS['refid'] > 0) {
@@ -3210,7 +3126,7 @@ function determineReferalId () {
                }
 
                // Is the record valid?
-               if (($found === false) || (!isUserDataValid())) {
+               if ((($found === false) || (!isUserDataValid())) && (isConfigEntrySet('def_refid'))) {
                        // No, then reset referal id
                        $GLOBALS['refid'] = getConfig('def_refid');
                } // END - if
@@ -3628,10 +3544,10 @@ function determinePageTitle () {
                $mode = '';
                if (getModule() == 'login') $mode = 'member';
                elseif (getModule() == 'index') $mode = 'guest';
-               if ((!empty($mode)) && (getConfig('enable_what_title') == 'Y')) $TITLE .= " ".trim(getConfig('title_middle'))." ".getModuleDescription($mode, getWhat());
+               if ((!empty($mode)) && (getConfig('enable_what_title') == 'Y')) $TITLE .= ' ' . trim(getConfig('title_middle')) . ' ' . getTitleFromMenu($mode, getWhat());
 
                // Add title decorations? (right)
-               if ((getConfig('enable_title_deco') == 'Y') && (getConfig('title_right') != '')) $TITLE .= " ".trim(getConfig('title_right'));
+               if ((getConfig('enable_title_deco') == 'Y') && (getConfig('title_right') != '')) $TITLE .= ' ' . trim(getConfig('title_right'));
 
                // Remember title in constant for the template
                $pageTitle = $TITLE;
@@ -3674,7 +3590,7 @@ function isTemplateCached ($template) {
 // Flushes non-flushed template cache to disk
 function flushTemplateCache ($template, $eval) {
        // Is this cache flushed?
-       if ((!isTemplateCached($template)) && ($eval != '404')) {
+       if ((isDebuggingTemplateCache() === false) && (isTemplateCached($template) === false) && ($eval != '404')) {
                // Generate FQFN
                $FQFN = sprintf("%s_compiled/templates/%s.tpl.cache", getConfig('CACHE_PATH'), $template);
 
@@ -3689,7 +3605,7 @@ function flushTemplateCache ($template, $eval) {
 // Reads a template cache
 function readTemplateCache ($template) {
        // Check it again
-       if (isTemplateCached($template)) {
+       if ((isDebuggingTemplateCache() === false) && (isTemplateCached($template))) {
                // Generate FQFN
                $FQFN = sprintf("%s_compiled/templates/%s.tpl.cache", getConfig('CACHE_PATH'), $template);
 
@@ -3701,6 +3617,192 @@ function readTemplateCache ($template) {
        return $GLOBALS['template_eval'][$template];
 }
 
+// Escapes quotes (default is only double-quotes)
+function escapeQuotes ($str, $single = false) {
+       // Should we escape all?
+       if ($single === true) {
+               // Escape all (including null)
+               $str = addslashes($str);
+       } else {
+               // Escape only double-quotes but prevent double-quoting
+               $str = str_replace("\\\\", "\\", str_replace('"', "\\\"", $str));
+       }
+
+       // Return the escaped string
+       return $str;
+}
+
+// Escapes the JavaScript code, prevents \r and \n becoming char 10/13
+function escapeJavaScriptQuotes ($str) {
+       // Replace all double-quotes and secure back-ticks
+       $str = str_replace('"', '\"', str_replace("\\", '{BACK}', $str));
+
+       // Return it
+       return $str;
+}
+
+// Send out mails depending on the 'mod/modes' combination
+// @TODO Lame description for this function
+function sendModeMails ($mod, $modes) {
+       // Load hash
+       if (fetchUserData(getMemberId())) {
+               // Extract salt from cookie
+               $salt = substr(getSession('u_hash'), 0, -40);
+
+               // Now let's compare passwords
+               $hash = generatePassString(getUserData('password'));
+
+               // Does the hash match or should we change it?
+               if (($hash == getSession('u_hash')) || (postRequestElement('pass1') == postRequestElement('pass2'))) {
+                       // Load the data
+                       $content = getUserDataArray();
+
+                       // Translate gender
+                       $content['gender'] = translateGender($content['gender']);
+
+                       // Clear/init the content variable
+                       $content['message'] = '';
+
+                       // Which mail?
+                       // @TODO Move this in a filter
+                       switch ($mod) {
+                               case 'mydata':
+                                       foreach ($modes as $mode) {
+                                               switch ($mode) {
+                                                       case 'normal': break; // Do not add any special lines
+                                                       case 'email': // Email was changed!
+                                                               $content['message'] = getMessage('MEMBER_CHANGED_EMAIL').": ".postRequestElement('old_email')."\n";
+                                                               break;
+
+                                                       case 'pass': // Password was changed
+                                                               $content['message'] = getMessage('MEMBER_CHANGED_PASS')."\n";
+                                                               break;
+
+                                                       default:
+                                                               logDebugMessage(__FUNCTION__, __LINE__, sprintf("Unknown mode %s detected.", $mode));
+                                                               $content['message'] = getMessage('MEMBER_UNKNOWN_MODE') . ': ' . $mode . "\n\n";
+                                                               break;
+                                               } // END - switch
+                                       } // END - foreach
+
+                                       if (isExtensionActive('country')) {
+                                               // Replace code with description
+                                               $content['country'] = generateCountryInfo(postRequestElement('country_code'));
+                                       } // END - if
+
+                                       // Merge content with data from POST
+                                       $content = merge_array($content, postRequestArray());
+
+                                       // Load template
+                                       $message = loadEmailTemplate('member_mydata_notify', $content, getMemberId());
+
+                                       if (getConfig('admin_notify') == 'Y') {
+                                               // The admin needs to be notified about a profile change
+                                               $message_admin = 'admin_mydata_notify';
+                                               $sub_adm   = getMessage('ADMIN_CHANGED_DATA');
+                                       } else {
+                                               // No mail to admin
+                                               $message_admin = '';
+                                               $sub_adm   = '';
+                                       }
+
+                                       // Set subject lines
+                                       $sub_mem = getMessage('MEMBER_CHANGED_DATA');
+
+                                       // Output success message
+                                       $content = "<span class=\"member_done\">{--MYDATA_MAIL_SENT--}</span>";
+                                       break;
+
+                               default: // Unsupported module!
+                                       logDebugMessage(__FUNCTION__, __LINE__, sprintf("Unsupported module %s detected.", $mod));
+                                       $content = "<span class=\"member_failed\">{--UNKNOWN_MODULE--}</span>";
+                                       break;
+                       } // END - switch
+               } else {
+                       // Passwords mismatch
+                       $content = "<span class=\"member_failed\">{--MEMBER_PASSWORD_ERROR--}</span>";
+               }
+       } else {
+               // Could not load profile
+               $content = "<span class=\"member_failed\">{--MEMBER_CANNOT_LOAD_PROFILE--}</span>";
+       }
+
+       // Send email to user if required
+       if ((!empty($sub_mem)) && (!empty($message))) {
+               // Send member mail
+               sendEmail($content['email'], $sub_mem, $message);
+       } // END - if
+
+       // Send only if no other error has occured
+       if (empty($content)) {
+               if ((!empty($sub_adm)) && (!empty($message_admin))) {
+                       // Send admin mail
+                       sendAdminNotification($sub_adm, $message_admin, $content, getMemberId());
+               } elseif (getConfig('admin_notify') == 'Y') {
+                       // Cannot send mails to admin!
+                       $content = getMessage('CANNOT_SEND_ADMIN_MAILS');
+               } else {
+                       // No mail to admin
+                       $content = "<span class=\"member_done\">{--MYDATA_MAIL_SENT--}</span>";
+               }
+       } // END - if
+
+       // Load template
+       loadTemplate('admin_settings_saved', false, $content);
+}
+
+// Generates a 'selection box' from given array
+function generateSelectionBoxFromArray ($options, $name, $optionValue, $optionContent) {
+       // Start the output
+       $OUT = '<select name="' . $name . '" size="1" class="admin_select">
+<option value="X" disabled="disabled">{--PLEASE_SELECT--}</option>';
+
+       // Walk through all options
+       foreach ($options as $option) {
+               // Add the <option> entry
+               $OUT .= '<option value="' . $option[$optionValue] . '">' . $option[$optionContent] . '</option>';
+       } // END - foreach
+
+       // Finish selection box
+       $OUT .= '</select>';
+
+       // Prepare output
+       $content = array(
+               'selection_box' => $OUT,
+               'module'        => getModule(),
+               'what'          => getWhat()
+       );
+
+       // Load template and return it
+       return loadTemplate('select_' . $name . '_box', true, $content);
+}
+
+// Get a module from filename and access level
+function getModuleFromFileName ($file, $accessLevel) {
+       // Default is 'invalid';
+       $modCheck = 'invalid';
+
+       // @TODO This is still very static, rewrite it somehow
+       switch ($accessLevel) {
+               case 'admin':
+                       $modCheck = 'admin';
+                       break;
+
+               case 'sponsor':
+               case 'guest':
+               case 'member':
+                       $modCheck = getModule();
+                       break;
+
+               default: // Unsupported file name / access level
+                       debug_report_bug('Unsupported file name=' . basename($file) . '/access level=' . $accessLevel);
+                       break;
+       }
+
+       // Return result
+       return $modCheck;
+}
+
 //////////////////////////////////////////////////
 // AUTOMATICALLY RE-GENERATED MISSING FUNCTIONS //
 //////////////////////////////////////////////////
@@ -3716,7 +3818,7 @@ if (!function_exists('html_entity_decode')) {
 
 if (!function_exists('http_build_query')) {
        // Taken from documentation on www.php.net, credits to Marco K. (Germany)
-       function http_build_query($data, $prefix='', $sep='', $key='') {
+       function http_build_query($data, $prefix = '', $sep = '', $key = '') {
                $ret = array();
                foreach ((array)$data as $k => $v) {
                        if (is_int($k) && $prefix != null) {
@@ -3736,7 +3838,7 @@ if (!function_exists('http_build_query')) {
 
                return implode($sep, $ret);
        }
-}// // END - if
+} // END - if
 
 // [EOF]
 ?>