X-Git-Url: https://git.mxchange.org/?p=mailer.git;a=blobdiff_plain;f=inc%2Ffunctions.php;h=d5d9226e38b4b6980eefed23818ef2d9daa41882;hp=faecd19e7d1811d8ed10f2eacb03232503f0e332;hb=f40ee6b3fe47308625f3490dedb1c52174ddf9f1;hpb=b6a6d0a2c0a0f274b937eb75c413db8fa9b44f9c diff --git a/inc/functions.php b/inc/functions.php index faecd19e7d..d5d9226e38 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -10,13 +10,8 @@ * -------------------------------------------------------------------- * * Kurzbeschreibung : Viele Nicht-Datenbank-Funktionen * * -------------------------------------------------------------------- * - * $Revision:: $ * - * $Date:: $ * - * $Tag:: 0.2.1-FINAL $ * - * $Author:: $ * - * -------------------------------------------------------------------- * * Copyright (c) 2003 - 2009 by Roland Haeder * - * Copyright (c) 2009 - 2012 by Mailer Developer Team * + * Copyright (c) 2009 - 2016 by Mailer Developer Team * * For more information visit: http://mxchange.org * * * * This program is free software; you can redistribute it and/or modify * @@ -51,7 +46,7 @@ function getFatalArray () { } // Add a fatal error message to the queue array -function addFatalMessage ($F, $L, $message, $extra = '') { +function addFatalMessage ($file, $line, $message, $extra = '') { if (is_array($extra)) { // Multiple extras for a message with masks $message = call_user_func_array('sprintf', $extra); @@ -64,7 +59,7 @@ function addFatalMessage ($F, $L, $message, $extra = '') { array_push($GLOBALS['fatal_messages'], $message); // Log fatal messages away - logDebugMessage($F, $L, 'Fatal error message: ' . compileCode($message)); + logDebugMessage($file, $line, 'Fatal error message: ' . compileCode($message)); } // Getter for total fatal message count @@ -85,10 +80,10 @@ function getTotalFatalErrors () { } // Generate a password in a specified length or use default password length -function generatePassword ($length = '0', $exclude = array()) { +function generatePassword ($length = '0', $exclude = array()) { // Auto-fix invalid length of zero if ($length == '0') { - $length = getPassLen(); + $length = getMinPasswordLength(); } // END - if // Exclude some entries @@ -104,8 +99,9 @@ function generatePassword ($length = '0', $exclude = array()) { } // END - while /* - * When the size is below 40 we can also add additional security by - * scrambling it. Otherwise the hash may corrupted.. + * When the length of the password is below 40 characters additional + * security can be added by scrambling it. Otherwise the hash may + * corrupted. */ if (strlen($password) <= 40) { // Also scramble the password @@ -146,7 +142,7 @@ function generateDateTime ($time, $mode = '0') { case '6': $ret = date('Ymd', $timeSecured); break; case '7': $ret = date('Y-m-d H:i:s', $timeSecured); break; // Compatible with MySQL TIMESTAMP default: - logDebugMessage(__FUNCTION__, __LINE__, sprintf("Invalid date mode %s detected.", $mode)); + logDebugMessage(__FUNCTION__, __LINE__, sprintf('Invalid date mode %s detected.', $mode)); break; } // END - switch break; @@ -162,7 +158,7 @@ function generateDateTime ($time, $mode = '0') { case '6': $ret = date('Ymd', $timeSecured); break; case '7': $ret = date('Y-m-d H:i:s', $timeSecured); break; // Compatible with MySQL TIMESTAMP default: - logDebugMessage(__FUNCTION__, __LINE__, sprintf("Invalid date mode %s detected.", $mode)); + logDebugMessage(__FUNCTION__, __LINE__, sprintf('Invalid date mode %s detected.', $mode)); break; } // END - switch } // END - switch @@ -181,11 +177,16 @@ function translateYesNo ($yn) { // Default $GLOBALS[__FUNCTION__][$yn] = '??? (' . $yn . ')'; switch ($yn) { - case 'Y': $GLOBALS[__FUNCTION__][$yn] = '{--YES--}'; break; - case 'N': $GLOBALS[__FUNCTION__][$yn] = '{--NO--}'; break; - default: - // Log unknown value - logDebugMessage(__FUNCTION__, __LINE__, sprintf("Unknown value %s. Expected: Y/N", $yn)); + case 'Y': // Yes + $GLOBALS[__FUNCTION__][$yn] = '{--YES--}'; + break; + + case 'N': // No + $GLOBALS[__FUNCTION__][$yn] = '{--NO--}'; + break; + + default: // Log unknown value + logDebugMessage(__FUNCTION__, __LINE__, sprintf('Unknown value %s. Expected: Y/N', $yn)); break; } // END - switch } // END - if @@ -194,6 +195,31 @@ function translateYesNo ($yn) { return $GLOBALS[__FUNCTION__][$yn]; } +// "Translates" Y/N into "de-/active" +function translateActivationStatus ($status) { + // Is it cached? + if (!isset($GLOBALS[__FUNCTION__][$status])) { + // Default + $GLOBALS[__FUNCTION__][$status] = '??? (' . $status . ')'; + switch ($status) { + case 'Y': // Activated + $GLOBALS[__FUNCTION__][$status] = '{--ACTIVATED--}'; + break; + + case 'N': // Deactivated + $GLOBALS[__FUNCTION__][$status] = '{--DEACTIVATED--}'; + break; + + default: // Log unknown value + logDebugMessage(__FUNCTION__, __LINE__, sprintf('Unknown value %s. Expected: Y/N', $status)); + break; + } // END - switch + } // END - if + + // Return it + return $GLOBALS[__FUNCTION__][$status]; +} + // Translates the american decimal dot into a german comma // OPPOMENT: convertCommaToDot() function translateComma ($dotted, $cut = TRUE, $max = '0') { @@ -258,7 +284,7 @@ function translateGender ($gender) { default: // Please report bugs on unknown genders - reportBug(__FUNCTION__, __LINE__, sprintf("Unknown gender %s detected.", $gender)); + reportBug(__FUNCTION__, __LINE__, sprintf('Unknown gender %s detected.', $gender)); break; } // END - switch @@ -276,7 +302,7 @@ function translateUserStatus ($status) { case 'UNCONFIRMED': case 'CONFIRMED': case 'LOCKED': - // Use generic function for all "normal" cases" + // Use generic function for all "normal" cases $ret = translateGeneric('ACCOUNT_STATUS', $status); break; @@ -286,7 +312,7 @@ function translateUserStatus ($status) { break; default: // Please report all unknown status - reportBug(__FUNCTION__, __LINE__, sprintf("Unknown status %s(%s) detected.", $status, gettype($status))); + reportBug(__FUNCTION__, __LINE__, sprintf('Unknown status %s(%s) detected.', $status, gettype($status))); break; } // END - switch @@ -357,7 +383,7 @@ function generateDereferrerUrl ($url) { // Generates an URL for the frametester function generateFrametesterUrl ($url) { // Prepare frametester URL - $frametesterUrl = sprintf("{%%url=modules.php?module=frametester&url=%s%%}", + $frametesterUrl = sprintf('{%%url=modules.php?module=frametester&url=%s%%}', encodeString(compileUriCode($url)) ); @@ -408,7 +434,7 @@ function makeTime ($hours, $minutes, $seconds, $stamp) { } // Redirects to an URL and if neccessarry extends it with own base URL -function redirectToUrl ($url, $allowSpider = TRUE) { +function redirectToUrl ($url, $allowSpider = TRUE, $compileCode = TRUE) { // Is the output mode -2? if (isAjaxOutputMode()) { // This is always (!) an AJAX request and shall not be redirected @@ -420,8 +446,11 @@ function redirectToUrl ($url, $allowSpider = TRUE) { $url = substr($url, 6, -2); } // END - if - // Compile out codes - eval('$url = "' . compileRawCode(encodeUrl($url)) . '";'); + // Compile codes out? + if ($compileCode === TRUE) { + // Compile out codes + eval('$url = "' . compileRawCode(encodeUrl($url)) . '";'); + } // END - if // Default 'rel' value is external, nofollow is evil from Google and hurts the Internet $rel = ' rel="external"'; @@ -435,17 +464,23 @@ function redirectToUrl ($url, $allowSpider = TRUE) { // Three different ways to debug... //* DEBUG: */ reportBug(__FUNCTION__, __LINE__, 'URL=' . $url); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'URL=' . $url); - //* DEBUG: */ die($url); + //* DEBUG-DIE: */ die(__METHOD__ . ':url=' . $url . '
compileCode=' . intval($compileCode)); // We should not sent a redirect if headers are already sent if (!headers_sent()) { + // Compile again? + if ($compileCode === TRUE) { + // Do final compilation + $url = doFinalCompilation(str_replace('&', '&', $url), FALSE); + } // END - if + // Load URL when headers are not sent - sendRawRedirect(doFinalCompilation(str_replace('&', '&', $url), FALSE)); + sendRawRedirect($url); } else { // Output error message - loadInclude('inc/header.php'); + loadPageHeader(); loadTemplate('redirect_url', FALSE, str_replace('&', '&', $url)); - loadInclude('inc/footer.php'); + loadPageFooter(); } // Shut the mailer down here @@ -480,7 +515,7 @@ function array_pk_sort (&$array, $a_sort, $primary_key = '0', $order = -1, $nums } elseif ($key != $key2) { // Sort numbers (E.g.: 9 < 10) if (($temporaryArray[$a_sort[$primary_key]][$key] < $temporaryArray[$a_sort[$primary_key]][$key2]) && ($order == -1)) $match = TRUE; - if (($temporaryArray[$a_sort[$primary_key]][$key] > $temporaryArray[$a_sort[$primary_key]][$key2]) && ($order == 1)) $match = TRUE; + if (($temporaryArray[$a_sort[$primary_key]][$key] > $temporaryArray[$a_sort[$primary_key]][$key2]) && ($order == 1)) $match = TRUE; } if ($match) { @@ -510,7 +545,7 @@ function array_pk_sort (&$array, $a_sort, $primary_key = '0', $order = -1, $nums // function generateRandomCode ($length, $code, $userid, $extraData = '') { // Build server string - $server = $_SERVER['PHP_SELF'] . getEncryptSeparator() . detectUserAgent() . getEncryptSeparator() . getenv('SERVER_SOFTWARE') . getEncryptSeparator() . detectRealIpAddress() . getEncryptSeparator() . detectRemoteAddr(); + $server = $_SERVER['REQUEST_URI'] . getEncryptSeparator() . detectUserAgent() . getEncryptSeparator() . getenv('SERVER_SOFTWARE') . getEncryptSeparator() . detectRealIpAddress() . getEncryptSeparator() . detectRemoteAddr(); // Build key string $keys = getSiteKey() . getEncryptSeparator() . getDateKey(); @@ -520,7 +555,7 @@ function generateRandomCode ($length, $code, $userid, $extraData = '') { if (isConfigEntrySet('file_hash')) { $keys .= getEncryptSeparator() . getFileHash(); } // END - if - $keys .= getEncryptSeparator() . getDateFromRepository(); + if (isConfigEntrySet('master_salt')) { $keys .= getEncryptSeparator() . getMasterSalt(); } // END - if @@ -598,16 +633,20 @@ function bigintval ($num, $castValue = TRUE, $abortOnMismatch = TRUE) { // Creates a Uni* timestamp from given selection data and prefix function createEpocheTimeFromSelections ($prefix, $postData) { + // Assert on typical array element (maybe all?) + assert(isset($postData[$prefix . '_ye'])); + // Initial return value $ret = '0'; // Is there a leap year? $SWITCH = '0'; - $TEST = getYear() / 4; - $M1 = getMonth(); + $TEST = getYear() / 4; + $M1 = getMonth(); // If so and if current time is before 02/29 and estimated time is after 02/29 then add 86400 seconds (one day) - if ((floor($TEST) == $TEST) && ($M1 == '02') && ($postData[$prefix . '_mo'] > '02')) { + // 01 2 2 1 1 1 123 4 43 3 32 233 4 43 3 3210 + if ((floor($TEST) == $TEST) && ($M1 == '02') && (((isset($postData[$prefix . '_mo'])) && ($postData[$prefix . '_mo'] > '02')) || ((isset($postData[$prefix . '_mn'])) && ($postData[$prefix . '_mn'] > '02')))) { $SWITCH = getOneDay(); } // END - if @@ -615,7 +654,11 @@ function createEpocheTimeFromSelections ($prefix, $postData) { $ret += $postData[$prefix . '_ye'] * (31536000 + $SWITCH); // Next months... - $ret += $postData[$prefix . '_mo'] * 2628000; + if (isset($postData[$prefix . '_mo'])) { + $ret += $postData[$prefix . '_mo'] * 2628000; + } elseif (isset($postData[$prefix . '_mn'])) { + $ret += $postData[$prefix . '_mn'] * 2628000; + } // Next weeks $ret += $postData[$prefix . '_we'] * 604800; @@ -683,7 +726,7 @@ function isEmailValid ($email) { // Return check result //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'email=' . $email . ',isValid=' . intval($GLOBALS[__FUNCTION__][$email]) . ' - EXIT!'); - return $GLOBALS[__FUNCTION__][$email];; + return $GLOBALS[__FUNCTION__][$email]; } // Function taken from user comments on www.php.net / function isInStringIgnoreCase() @@ -738,10 +781,16 @@ function generateHash ($plainText, $salt = '', $hash = TRUE) { // When the salt is empty build a new one, else use the first x configured characters as the salt if (empty($salt)) { // Build server string for more entropy - $server = $_SERVER['PHP_SELF'] . getEncryptSeparator() . detectUserAgent() . getEncryptSeparator() . getenv('SERVER_SOFTWARE') . getEncryptSeparator() . detectRealIpAddress() . getEncryptSeparator() . detectRemoteAddr(); + $server = $_SERVER['REQUEST_URI'] . getEncryptSeparator() . detectUserAgent() . getEncryptSeparator() . getenv('SERVER_SOFTWARE') . getEncryptSeparator() . detectRealIpAddress() . getEncryptSeparator() . detectRemoteAddr(); // Build key string - $keys = getSiteKey() . getEncryptSeparator() . getDateKey() . getEncryptSeparator() . getSecretKey() . getEncryptSeparator() . getFileHash() . getEncryptSeparator() . getDateFromRepository() . getEncryptSeparator() . getMasterSalt(); + $keys = getSiteKey() . getEncryptSeparator() . getDateKey() . getEncryptSeparator() . getFileHash() . getEncryptSeparator() . getMasterSalt(); + + // Is the secret_key config entry set? + if (isConfigEntrySet('secret_key')) { + // Add it + $keys .= getEncryptSeparator() . getSecretKey(); + } // END - if // Additional data $data = $plainText . getEncryptSeparator() . uniqid(mt_rand(), TRUE) . getEncryptSeparator() . time(); @@ -792,18 +841,19 @@ function scrambleString ($str) { if (strlen($str) > 40) { // The string is to long return $str; - } elseif (strlen($str) == 40) { + } elseif ((strlen($str) == 40) && (getPassScramble() != '')) { // From database - $scrambleNums = explode(':', getPassScramble()); + $scramble = getPassScramble(); } else { // Generate new numbers - $scrambleNums = explode(':', genScrambleString(strlen($str))); + $scramble = genScrambleString(strlen($str)); } - // Compare both lengths and abort if different - if (strlen($str) != count($scrambleNums)) { - return $str; - } // END - if + // Convert it into an array + $scrambleNums = explode(':', $scramble); + + // Assert on both lengths + assert(strlen($str) == count($scrambleNums)); // Scramble string here //* DEBUG: */ debugOutput('***Original=' . $str.'***
'); @@ -869,6 +919,8 @@ function genScrambleString ($len) { // So let's create the string for storing it in database $scrambleString = implode(':', $scrambleNumbers); + + // Return it return $scrambleString; } @@ -897,6 +949,7 @@ function encodeHashForCookie ($passHash) { // Default is hexadecimal of index if both are same $mod = dechex($idx); + // Is part1 larger or part2 than its counter part? if ($part1 > $part2) { // part1 is larger @@ -908,7 +961,7 @@ function encodeHashForCookie ($passHash) { $mod = substr($mod, 0, 2); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'idx=' . $idx . ',part1=' . $part1 . '/part2=' . $part2 . '/mod=' . $mod . '(' . strlen($mod) . ')'); - $mod = str_pad($mod, 2, '0', STR_PAD_LEFT); + $mod = padLeftZero($mod, 2); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'mod(' . ($idx * 2) . ')=' . $mod . '*'); $start += 2; $newHash .= $mod; @@ -927,7 +980,7 @@ function encodeHashForCookie ($passHash) { // Fix "deleted" cookies function fixDeletedCookies ($cookies) { // Is this an array with entries? - if ((is_array($cookies)) && (count($cookies) > 0)) { + if (isFilledArray($cookies)) { // Then check all cookies if they are marked as deleted! foreach ($cookies as $cookieName) { // Is the cookie set to "deleted"? @@ -953,13 +1006,13 @@ function getCurrentTheme () { if (isExtensionActive('theme')) { // Call inner method $ret = getActualTheme(); - } elseif ((isPostRequestElementSet('theme')) && (isIncludeReadable(sprintf("theme/%s/theme.php", postRequestElement('theme'))))) { + } elseif ((isPostRequestElementSet('theme')) && (isThemeReadable(postRequestElement('theme')))) { // Use value from POST data $ret = postRequestElement('theme'); - } elseif ((isGetRequestElementSet('theme')) && (isIncludeReadable(sprintf("theme/%s/theme.php", getRequestElement('theme'))))) { + } elseif ((isGetRequestElementSet('theme')) && (isThemeReadable(getRequestElement('theme')))) { // Use value from GET data $ret = getRequestElement('theme'); - } elseif ((isMailerThemeSet()) && (isIncludeReadable(sprintf("theme/%s/theme.php", getMailerTheme())))) { + } elseif ((isMailerThemeSet()) && (isThemeReadable(getMailerTheme()))) { // Use value from GET data $ret = getMailerTheme(); } @@ -980,7 +1033,7 @@ function generateErrorCodeFromUserStatus ($status = '') { $errorCode = getCode('ACCOUNT_UNKNOWN'); // Generate constant name - $codeName = sprintf("ACCOUNT_%s", strtoupper($status)); + $codeName = sprintf('ACCOUNT_%s', strtoupper($status)); // Is the constant there? if (isCodeSet($codeName)) { @@ -988,7 +1041,7 @@ function generateErrorCodeFromUserStatus ($status = '') { $errorCode = getCode($codeName); } else { // Unknown status - logDebugMessage(__FUNCTION__, __LINE__, sprintf("Unknown error status %s detected.", $status)); + logDebugMessage(__FUNCTION__, __LINE__, sprintf('Unknown error status %s detected.', $status)); } // Return error code @@ -1103,15 +1156,8 @@ function getMessageFromErrorCode ($code) { break; case getCode('URL_TIME_LOCK'): - // @TODO Move this SQL code into a function, let's say 'getTimestampFromPoolId($id) ? - $result = SQL_QUERY_ESC("SELECT `timestamp` FROM `{?_MYSQL_PREFIX?}_pool` WHERE `id`=%s LIMIT 1", - array(bigintval(getRequestElement('id'))), __FUNCTION__, __LINE__); - // Load timestamp from last order - $content = SQL_FETCHARRAY($result); - - // Free memory - SQL_FREERESULT($result); + $content = getPoolDataFromId(getRequestElement('id')); // Translate it for templates $content['timestamp'] = generateDateTime($content['timestamp'], 1); @@ -1429,17 +1475,17 @@ function convertSelectionsToEpocheTime (array &$postData, array &$content, &$id, $test = substr($id, -3); // Improved way of checking! :-) - if (in_array($test, array('_ye', '_mo', '_we', '_da', '_ho', '_mi', '_se'))) { + if (in_array($test, array('_ye', '_mo', '_mn', '_we', '_da', '_ho', '_mi', '_se'))) { // Found a multi-selection for timings? $test = substr($id, 0, -3); - if ((isset($postData[$test . '_ye'])) && (isset($postData[$test . '_mo'])) && (isset($postData[$test . '_we'])) && (isset($postData[$test . '_da'])) && (isset($postData[$test . '_ho'])) && (isset($postData[$test . '_mi'])) && (isset($postData[$test . '_se'])) && ($test != $test2)) { + if ((isset($postData[$test . '_ye'])) && ((isset($postData[$test . '_mo'])) || (isset($postData[$test . '_mn']))) && (isset($postData[$test . '_we'])) && (isset($postData[$test . '_da'])) && (isset($postData[$test . '_ho'])) && (isset($postData[$test . '_mi'])) && (isset($postData[$test . '_se'])) && ($test != $test2)) { // Generate timestamp $postData[$test] = createEpocheTimeFromSelections($test, $postData); array_push($content, sprintf("`%s`='%s'", $test, $postData[$test])); $GLOBALS['skip_config'][$test] = TRUE; // Remove data from array - foreach (array('ye', 'mo', 'we', 'da', 'ho', 'mi', 'se') as $rem) { + foreach (array('ye', 'mo', 'mn', 'we', 'da', 'ho', 'mi', 'se') as $rem) { unset($postData[$test . '_' . $rem]); } // END - foreach @@ -1464,12 +1510,12 @@ function convertCommaToDot ($str) { $str = str_replace('.', '', $str); // Replace german commata with decimal dot and cast it - $float = (float) str_replace(',', '.', $str); + $float = sprintf(getConfig('FLOAT_MASK'), str_replace(',', '.', $str)); break; default: // US and so on // Remove thousand commatas first and cast - $float = (float) str_replace(',', '', $str); + $float = sprintf(getConfig('FLOAT_MASK'), str_replace(',', '', $str)); break; } // END - switch @@ -1512,8 +1558,9 @@ function rebuildCache ($cache, $inc = '', $force = FALSE) { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, sprintf("cache=%s, inc=%s, force=%s", $cache, $inc, intval($force))); // Shall I remove the cache file? - if ((isExtensionInstalled('cache')) && (isCacheInstanceValid()) && (isHtmlOutputMode())) { + if ((isExtensionInstalled('cache')) && (isValidCacheInstance()) && (isHtmlOutputMode())) { // Rebuild cache only in HTML output-mode + // @TODO This should be rewritten not to load the cache file for just checking if it is there for save removal. if ($GLOBALS['cache_instance']->loadCacheFile($cache)) { // Destroy it $GLOBALS['cache_instance']->removeCacheFile($force); @@ -1522,7 +1569,7 @@ function rebuildCache ($cache, $inc = '', $force = FALSE) { // Include file given? if (!empty($inc)) { // Construct FQFN - $inc = sprintf("inc/loader/load-%s.php", $inc); + $inc = sprintf('inc/loader/load-%s.php', $inc); // Is the include there? if (isIncludeReadable($inc)) { @@ -1530,8 +1577,8 @@ function rebuildCache ($cache, $inc = '', $force = FALSE) { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'inc=' . $inc . ' - LOADED!'); loadInclude($inc); } else { - // Include not found - logDebugMessage(__FUNCTION__, __LINE__, 'Include ' . $inc . ' not found. cache=' . $cache); + // Include not found, which needs now tracing + reportBug(__FUNCTION__, __LINE__, 'Include ' . $inc . ' not found. cache=' . $cache); } } // END - if } // END - if @@ -1603,22 +1650,79 @@ function addNewBonusMail ($data, $mode = '', $output = TRUE) { } } -// Enables the reset mode and runs it -function doReset () { - // Enable the reset mode - $GLOBALS['reset_enabled'] = TRUE; - - // Run filters - runFilterChain('reset'); -} - -// Enables the reset mode (hourly, weekly and monthly) and runs it +// Enables the hourly reset mode and runs it function doHourly () { // Enable the hourly reset mode $GLOBALS['hourly_enabled'] = TRUE; // Run filters (one always!) runFilterChain('hourly'); + + // Do not update in hourly debug mode + if ((!isConfigEntrySet('DEBUG_HOURLY')) || (!isDebugHourlyEnabled())) { + // Update database + updateConfiguration('last_hourly', getHour()); + } // END - if +} + +// Enables the daily reset mode and runs it +function doDaily () { + // Enable the reset mode + $GLOBALS['daily_enabled'] = TRUE; + + // Run filters + runFilterChain('daily'); + + // Do not update in daily debug mode + if ((!isConfigEntrySet('DEBUG_DAILY')) || (!isDebugDailyEnabled())) { + // Update database + updateConfiguration('last_daily', getDay()); + } // END - if +} + +// Enables the weekly reset mode and runs it +function doWeekly () { + // Enable the reset mode + $GLOBALS['weekly_enabled'] = TRUE; + + // Run filters + runFilterChain('weekly'); + + // Do not update in weekly debug mode + if ((!isConfigEntrySet('DEBUG_WEEKLY')) || (!isDebugWeeklyEnabled())) { + // Update database + updateConfiguration('last_weekly', getWeek()); + } // END - if +} + +// Enables the monthly reset mode and runs it +function doMonthly () { + // Enable the reset mode + $GLOBALS['monthly_enabled'] = TRUE; + + // Run filters + runFilterChain('monthly'); + + // Do not update in monthly debug mode + if ((!isConfigEntrySet('DEBUG_MONTHLY')) || (!isDebugMonthlyEnabled())) { + // Update database + updateConfiguration('last_monthly', getMonth()); + } // END - if +} + +// Enables the yearly reset mode and runs it +function doYearly () { + // Enable the reset mode + $GLOBALS['yearly_enabled'] = TRUE; + + // Run filters + runFilterChain('yearly'); + + // Do not update in yearly debug mode + if ((!isConfigEntrySet('DEBUG_YEARLY')) || (!isDebugYearlyEnabled())) { + // Update database + updateConfiguration('last_yearly', getYear()); + } // END - if } // Shuts down the mailer (e.g. closing database link, flushing output/filters, etc.) @@ -1627,10 +1731,10 @@ function doShutdown () { runFilterChain('shutdown', NULL); // Check if link is up - if (SQL_IS_LINK_UP()) { + if (isSqlLinkUp()) { // Close link - SQL_CLOSE(__FUNCTION__, __LINE__); - } elseif (!isInstallationPhase()) { + sqlCloseLink(__FUNCTION__, __LINE__); + } elseif (!isInstaller()) { // No database link reportBug(__FUNCTION__, __LINE__, 'Database link is already down, while shutdown is running.'); } @@ -1645,29 +1749,29 @@ function initMemberId () { } // Setter for member id -function setMemberId ($memberid) { +function setMemberId ($memberId) { // We should not set member id to zero - if ($memberid == '0') { + if (!isValidId($memberId)) { reportBug(__FUNCTION__, __LINE__, 'Userid should not be set zero.'); } // END - if // Set it secured - $GLOBALS['member_id'] = bigintval($memberid); + $GLOBALS['member_id'] = bigintval($memberId); } // Getter for member id or returns zero function getMemberId () { // Default member id - $memberid = '0'; + $memberId = '0'; // Is the member id set? if (isMemberIdSet()) { // Then use it - $memberid = $GLOBALS['member_id']; + $memberId = $GLOBALS['member_id']; } // END - if // Return it - return $memberid; + return $memberId; } // Checks ether the member id is set @@ -1704,16 +1808,17 @@ function isExtraTitleSet () { * * @param $baseDir Relative base directory to PATH to scan from * @param $prefix Prefix for all positive matches (which files should be found) - * @param $fileIncludeDirs whether to include directories in the final output array - * @param $addBaseDir whether to add $baseDir to all array entries + * @param $fileIncludeDirs Whether to include directories in the final output array + * @param $addBaseDir Whether to add $baseDir to all array entries * @param $excludeArray Excluded files and directories, these must be full files names, e.g. 'what-' will exclude all files named 'what-' but won't exclude 'what-foo.php' * @param $extension File extension for all positive matches * @param $excludePattern Regular expression to exclude more files (preg_match()) - * @param $recursive whether to scan recursively + * @param $recursive Whether to scan recursively * @param $suffix Suffix for positive matches ($extension will be appended, too) + * @param $withPrefixSuffix Whether to include prefix/suffix in found entries * @return $foundMatches All found positive matches for above criteria */ -function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = FALSE, $addBaseDir = TRUE, $excludeArray = array(), $extension = '.php', $excludePattern = '@(\.|\.\.)$@', $recursive = TRUE, $suffix = '') { +function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = FALSE, $addBaseDir = TRUE, $excludeArray = array(), $extension = '.php', $excludePattern = '@(\.|\.\.)$@', $recursive = TRUE, $suffix = '', $withPrefixSuffix = TRUE) { // Add default entries we should always exclude array_unshift($excludeArray, '.', '..', '.svn', '.htaccess'); @@ -1792,6 +1897,9 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = FALSE, $ad if ($addBaseDir === TRUE) { // With base path array_push($foundMatches, $fileName); + } elseif (($withPrefixSuffix === FALSE) && (!empty($extension))) { + // No prefix/suffix + array_push($foundMatches, substr($baseFile, strlen($prefix), -strlen($suffix . $extension))); } else { // No base path array_push($foundMatches, $baseFile); @@ -1800,9 +1908,18 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = FALSE, $ad // We found .php file but should not search for them, why? reportBug(__FUNCTION__, __LINE__, 'We should find files with extension=' . $extension . ', but we found a PHP script. (baseFile=' . $baseFile . ')'); } - } elseif ($fileExtension == $extension) { + } elseif ((($fileExtension == $extension) || (empty($extension))) && (isFileReadable($FQFN))) { // Other, generic file found - array_push($foundMatches, $fileName); + if ($addBaseDir === TRUE) { + // With base path + array_push($foundMatches, $fileName); + } elseif (($withPrefixSuffix === FALSE) && (!empty($extension))) { + // No prefix/suffix + array_push($foundMatches, substr($baseFile, strlen($prefix), -strlen($suffix . $extension))); + } else { + // No base path + array_push($foundMatches, $baseFile); + } } } // END - while @@ -1828,7 +1945,7 @@ function mapModuleToTable ($moduleName) { // Map only these, still lame code... switch ($moduleName) { case 'index': // 'index' is the guest's menu - $moduleName = 'guest'; + $moduleName = 'guest'; break; case 'login': // ... and 'login' the member's menu @@ -1842,35 +1959,35 @@ function mapModuleToTable ($moduleName) { } // Add SQL debug data to array for later output -function addSqlToDebug ($result, $sqlString, $timing, $F, $L) { +function addSqlToDebug ($result, $sqlString, $timing, $file, $line) { // Is there cache? if (!isset($GLOBALS['debug_sql_available'])) { // Check it and cache it in $GLOBALS $GLOBALS['debug_sql_available'] = ((isConfigurationLoaded()) && (isDisplayDebugSqlEnabled())); } // END - if - + // Don't execute anything here if we don't need or ext-other is missing if ($GLOBALS['debug_sql_available'] === FALSE) { return; } // END - if // Already executed? - if (isset($GLOBALS['debug_sqls'][$F][$L][$sqlString])) { + if (isset($GLOBALS['debug_sqls'][$file][$line][$sqlString])) { // Then abort here, we don't need to profile a query twice return; } // END - if // Remeber this as profiled (or not, but we don't care here) - $GLOBALS['debug_sqls'][$F][$L][$sqlString] = TRUE; + $GLOBALS['debug_sqls'][$file][$line][$sqlString] = TRUE; // Generate record $record = array( - 'num_rows' => SQL_NUMROWS($result), - 'affected' => SQL_AFFECTEDROWS(), + 'num_rows' => sqlNumRows($result), + 'affected' => sqlAffectedRows(), 'sql_str' => $sqlString, 'timing' => $timing, - 'file' => basename($F), - 'line' => $L + 'file' => basename($file), + 'line' => $line ); // Add it @@ -1953,7 +2070,7 @@ function encodeUrl ($url, $outputMode = '0') { } // END - if // Is there a valid session? - if ((!isSessionValid()) && (!isSpider())) { + if ((!isValidSession()) && (!isSpider())) { // Determine right separator $separator = '&'; if (!isInString('?', $url)) { @@ -1966,7 +2083,7 @@ function encodeUrl ($url, $outputMode = '0') { } // END - if // Add {?URL?} ? - if ((substr($url, 0, strlen(getUrl())) != getUrl()) && (substr($url, 0, 7) != '{?URL?}') && (substr($url, 0, 7) != 'http://') && (substr($url, 0, 8) != 'https://')) { + if ((substr($url, 0, strlen(getUrl())) != getUrl()) && (substr($url, 0, 7) != '{?URL?}') && (!isFullQualifiedUrl($url))) { // Add it $url = '{?URL?}/' . $url; } // END - if @@ -1975,7 +2092,7 @@ function encodeUrl ($url, $outputMode = '0') { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url . ',isHtmlOutputMode()=' . intval(isHtmlOutputMode()) . ',outputMode=' . $outputMode); // Is there to decode entities? - if ((!isHtmlOutputMode()) || ($outputMode != '0')) { + if (!isHtmlOutputMode()) { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url . ' - BEFORE DECODING'); // Decode them for e.g. JavaScript parts $url = decodeEntities($url); @@ -2004,43 +2121,6 @@ function isSpider () { return ((isInStringIgnoreCase('spider', $userAgent)) || (isInStringIgnoreCase('slurp', $userAgent)) || (isInStringIgnoreCase('bot', $userAgent)) || (isInStringIgnoreCase('archiver', $userAgent))); } -// Function to search for the last modified file -function searchDirsRecursive ($dir, &$last_changed, $lookFor = 'Date') { - // Get dir as array - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'dir=' . $dir); - // Does it match what we are looking for? (We skip a lot files already!) - // RegexPattern to exclude ., .., .revision, .svn, debug.log or .cache in the filenames - $excludePattern = '@(\.revision|\.svn|debug\.log|\.cache|config\.php)$@'; - - $ds = getArrayFromDirectory($dir, '', FALSE, TRUE, array(), '.php', $excludePattern); - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'count(ds)='.count($ds)); - - // Walk through all entries - foreach ($ds as $d) { - // Generate proper FQFN - $FQFN = str_replace('//', '/', getPath() . $dir . '/' . $d); - - // Is it a file and readable? - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'dir=' . $dir . ',d=' . $d); - if (isFileReadable($FQFN)) { - // $FQFN is a readable file so extract the requested data from it - $check = extractRevisionInfoFromFile($FQFN, $lookFor); - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'File: ' . $d . ' found. check=' . $check); - - // Is the file more recent? - if ((!isset($last_changed[$lookFor])) || ($last_changed[$lookFor] < $check)) { - // This file is newer as the file before - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'NEWER!'); - $last_changed['path_name'] = $FQFN; - $last_changed[$lookFor] = $check; - } // END - if - } else { - // Not readable - /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'File: ' . $d . ' not readable or directory.'); - } - } // END - foreach -} - // Handles the braces [] of a field (e.g. value of 'name' attribute) function handleFieldWithBraces ($field) { // Are there braces [] at the end? @@ -2070,7 +2150,7 @@ function handleFieldWithBraces ($field) { // Converts a zero or NULL to word 'NULL' function convertZeroToNull ($number) { // Is it a valid username? - if ((!is_null($number)) && (!empty($number)) && ($number > 0)) { + if (isValidNumber($number)) { // Always secure it $number = bigintval($number); } else { @@ -2082,10 +2162,22 @@ function convertZeroToNull ($number) { return $number; } -// Converts a NULL to zero +// Converts an empty string to NULL, else leaves it untouched +function convertEmptyToNull ($str) { + // Is the string empty? + if (strlen($str) == 0) { + // Is really empty + $str = NULL; + } // END - if + + // Return it + return $str; +} + +// Converts a NULL|empty string|< 1 to zero function convertNullToZero ($number) { // Is it a valid username? - if ((is_null($number)) || (empty($number)) || ($number < 1)) { + if (!isValidNumber($number)) { // Is not valid or zero $number = '0'; } // END - if @@ -2120,7 +2212,7 @@ function capitalizeUnderscoreString ($str) { } // Generate admin links for mail order -// mailType can be: 'mid' or 'bid' +// mailType can be: 'normal' or 'bonus' function generateAdminMailLinks ($mailType, $mailId) { // Init variables $OUT = ''; @@ -2132,11 +2224,11 @@ function generateAdminMailLinks ($mailType, $mailId) { // Which mail do we have? switch ($mailType) { - case 'bid': // Bonus mail + case 'bonus': // Bonus mail $table = 'bonus'; break; - case 'mid': // Member mail + case 'normal': // Member mail $table = 'pool'; break; @@ -2149,7 +2241,7 @@ function generateAdminMailLinks ($mailType, $mailId) { // Is the mail type supported? if (!empty($table)) { // Query for the mail - $result = SQL_QUERY_ESC("SELECT `id`, `%s` AS `mail_status` FROM `{?_MYSQL_PREFIX?}_%s` WHERE `id`=%s LIMIT 1", + $result = sqlQueryEscaped("SELECT `id`, `%s` AS `mail_status` FROM `{?_MYSQL_PREFIX?}_%s` WHERE `id`=%s LIMIT 1", array( $statusColumn, $table, @@ -2157,9 +2249,9 @@ function generateAdminMailLinks ($mailType, $mailId) { ), __FILE__, __LINE__); // Is there one entry there? - if (SQL_NUMROWS($result) == 1) { + if (sqlNumRows($result) == 1) { // Load the entry - $content = SQL_FETCHARRAY($result); + $content = sqlFetchArray($result); // Add output and type $content['type'] = $mailType; @@ -2173,7 +2265,7 @@ function generateAdminMailLinks ($mailType, $mailId) { } // END - if // Free result - SQL_FREERESULT($result); + sqlFreeResult($result); } // END - if // Return generated HTML code @@ -2211,7 +2303,7 @@ function isHexadecimal ($hex) { * @return $str Overworked string */ function replaceReturnNewLine ($str) { - return str_replace(array(chr(13), PHP_EOL), array('[r]', '[n]'), $str); + return str_replace(array(chr(13), chr(10)), array('[r]', '[n]'), $str); } // Converts a given string by splitting it up with given delimiter similar to @@ -2386,7 +2478,7 @@ function memberAddEntries ($tableName, $columns = array(), $filterFunctions = ar doGenericAddEntries($tableName, $columns, $filterFunctions, $extraValues, $timeColumns, $columnIndex); // Entry has been added? - if ((!SQL_HASZEROAFFECTED()) && ($GLOBALS['__XML_PARSE_RESULT'] === TRUE)) { + if ((!ifSqlHasZeroAffectedRows()) && ($GLOBALS['__XML_PARSE_RESULT'] === TRUE)) { // Display success message displayMessage('{--MEMBER_ENTRY_ADDED--}'); } else { @@ -2468,7 +2560,7 @@ function memberDeleteEntriesConfirm ($tableName, $columns = array(), $filterFunc displayMessage('{--MEMBER_ALL_ENTRIES_REMOVED--}'); } else { // Some are still there :( - displayMessage(sprintf(getMessage('MEMBER_SOME_ENTRIES_NOT_DELETED'), SQL_AFFECTEDROWS(), countPostSelection($idColumn[0]))); + displayMessage(sprintf(getMessage('MEMBER_SOME_ENTRIES_NOT_DELETED'), sqlAffectedRows(), countPostSelection($idColumn[0]))); } } else { // List for deletion confirmation @@ -2513,12 +2605,119 @@ function validateIsEmpty ($str) { return $str; } +// "Getter" for seconds from given time unit +function getSecondsFromTimeUnit ($timeUnit) { + // Default is not found + $seconds = NULL; + + // "Detect" it + switch ($timeUnit) { + case 's': // Seconds = 1 + $seconds = 1; + break; + + case 'm': // Minutes + $seconds = 60; + break; + + case 'h': // Hours + $seconds = 60*60; + break; + + case 'D': // Days + $seconds = 60*60*24; + break; + + case 'W': // Weeks + $seconds = 60*60*24*7; + break; + + default: // Unsupported + reportBug(__FUNCTION__, __LINE__, 'Unsupported time unit ' . $timeUnit . ' detected.'); + break; + } // END - switch + + // Return value + return $seconds; +} + +// Calulates value for given seconds and time unit +function caluculateTimeUnitValue ($seconds, $timeUnit) { + // Calculate it + return ($seconds / getSecondsFromTimeUnit($timeUnit)); +} + +// "Getter" for an array from given one but only one index of it +function getArrayFromArrayIndex ($array, $key) { + // Some simple validation + assert(isset($array[0][$key])); + + // Init new array + $newArray = array(); + + // "Walk" through all elements + foreach ($array as $element) { + $newArray[] = $element[$key]; + } // END - if + + // Return it + return $newArray; +} + +/** + * Compress given data and encodes it into BASE64 to be stored in database with + * sqlQueryEscaped() + * + * @param $data Data to be compressed and encoded + * @return $data Compressed+encoded data + */ +function compress ($data) { + // Compress it + return base64_encode(gzcompress($data)); +} + +/** + * Decompress given data previously compressed with compress(). + * + * @param $data Data compressed with compress() + * @reurn $data Uncompressed data + */ +function decompress ($data) { + // Decompress it + return gzuncompress(base64_decode($data)); +} + +/** + * Converts given charset in given string to UTF-8 if not UTF-8. This function + * is currently limited to iconv(). + * + * @param $str String to convert charset in + * @param $charset Charset to convert from + * @return $str Converted string + */ +function convertCharsetToUtf8 ($str, $charset) { + // Is iconv() available? + if (!function_exists('iconv')) { + // Please make it sure + reportBug(__FUNCTION__, __LINE__, 'PHP function iconv() is currently required to do charset convertion.'); + } // END - if + + // Is the charset not UTF-8? + if (strtoupper($charset) != 'UTF-8') { + // Convert it to UTF-8 + $str = iconv(strtoupper($charset), 'UTF-8//TRANSLIT', $str); + } // END - if + + // Return converted string + return $str; +} + // ---------------------------------------------------------------------------- // "Translatation" functions for points_data table // ---------------------------------------------------------------------------- // Translates generically some data into a target string -function translateGeneric ($messagePrefix, $data) { +function translateGeneric ($messagePrefix, $data, $messageSuffix = '') { // Is the method null or empty? if (is_null($data)) { // Is NULL @@ -2529,10 +2728,10 @@ function translateGeneric ($messagePrefix, $data) { } // END - if // Default column name is unknown - $return = '{%message,' . $messagePrefix . '_UNKNOWN=' . strtoupper($data) . '%}'; + $return = '{%message,' . $messagePrefix . '_UNKNOWN' . $messageSuffix . '=' . strtoupper($data) . '%}'; // Construct message id - $messageId = $messagePrefix . '_' . strtoupper($data); + $messageId = $messagePrefix . '_' . strtoupper($data) . $messageSuffix; // Is it there? if (isMessageIdValid($messageId)) { @@ -2595,9 +2794,18 @@ function translateTaskType ($taskType) { return translateGeneric('ADMIN_TASK_TYPE', $taskType); } -//----------------------------------------------------------------------------- -// Automatically re-created functions, all taken from user comments on www.php.net -//----------------------------------------------------------------------------- +// "Translates" task status to a human-readable version +function translateTaskStatus ($taskStatus) { + // Return it + return translateGeneric('ADMIN_TASK_STATUS', $taskStatus); +} + +/* + *----------------------------------------------------------------------------- + * Automatically re-created functions, all taken from user comments on + * www.php.net + *----------------------------------------------------------------------------- + */ if (!function_exists('html_entity_decode')) { // Taken from documentation on www.php.net function html_entity_decode ($string) { @@ -2607,5 +2815,151 @@ if (!function_exists('html_entity_decode')) { } } // END - if +// "Getter" for base path from theme +function getBasePathFromTheme ($theme) { + return sprintf('%stheme/%s/css/', getPath(), $theme); +} + +// Wrapper to check whether given theme is readable +function isThemeReadable ($theme) { + // Is there cache? + if (!isset($GLOBALS[__FUNCTION__][$theme])) { + // Determine it + $GLOBALS[__FUNCTION__][$theme] = (isIncludeReadable(sprintf('theme/%s/theme.php', $theme))); + } // END - if + + // Return cache + return $GLOBALS[__FUNCTION__][$theme]; +} + +// Checks whether a given PHP extension is loaded or can be loaded at runtime +// +// Supported OS: Windows, Linux, (Mac?) +function isPhpExtensionLoaded ($extension) { + // Is the extension loaded? + if (extension_loaded($extension)) { + // All fine + return TRUE; + } // END - if + + // Try to load the extension + return loadLibrary($extension); +} + +// Loads given library (aka. PHP extension) +function loadLibrary ($n, $f = NULL) { + // Is the actual function dl() available? (Not on all SAPIs since 5.3) + if (!is_callable('dl')) { + // Not callable + /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'dl() is not callable for n=' . $n . ',f[' . gettype($f) . ']=' . $f); + return FALSE; + } // END - if + + // Try to load PHP library + return dl(((PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '') . ($f ? $f : $n) . '.' . PHP_SHLIB_SUFFIX); +} + +// "Translates" given PHP extension name into a readable version +function translatePhpExtension ($extension) { + // Return the language element + return '{--PHP_EXTENSION_' . strtoupper($extension) . '--}'; +} + +// Loads stylesheet files in different ways, depending on output mode +function loadStyleSheets () { + // Default styles + $stylesList = array( + 'general.css', + 'ajax.css', + ); + + // Add stylesheet for installation + if ((isInstaller())) { + array_push($stylesList, 'install.css'); + } // END - if + + // When no CSS output-mode is set, set it to file-output + if (!isConfigEntrySet('css_php')) { + setConfigEntry('css_php', 'FILE'); + } // END - if + + // Get current theme + $currentTheme = getCurrentTheme(); + + // Has the theme changed? + if ($currentTheme != getSession('mailer_theme')) { + // Then set it + setMailerTheme($currentTheme); + } // END - if + + // Output CSS files or content or link to css.php ? + if ((isCssOutputMode()) || (getCssPhp() == 'DIRECT')) { + // Load CSS files + $stylesList = merge_array($stylesList, getExtensionCssFiles()); + + // Generate base path + $basePath = getBasePathFromTheme($currentTheme); + + // Output inclusion lines + foreach ($stylesList as $value) { + // Only include found CSS files (to reduce 404 requests) + $FQFN = $basePath . '/' . $value; + + // Do include only existing files and whose are not empty + if ((isFileReadable($FQFN)) && (filesize($FQFN) > 0)) { + switch (getCssPhp()) { + case 'DIRECT': // Just link them (unsupported) + $GLOBALS['__page_header'] .= ''; + break; + + case 'FILE': // Output contents + $GLOBALS['__page_header'] .= removeDeprecatedComment(readFromFile($FQFN)); + break; + + default: // Invalid mode! + reportBug(__FILE__, __LINE__, sprintf('Invalid css_php value %s detected.', getCssPhp())); + break; + } // END - switch + } // END - if + } // END - foreach + } elseif ((isHtmlOutputMode()) || (getCssPhp() == 'INLINE')) { + // Load CSS files + $stylesList = merge_array($stylesList, getExtensionCssFiles()); + + // Generate base path + $basePath = getBasePathFromTheme(getCurrentTheme()); + + // Output inclusion lines + $OUT = ''; + foreach ($stylesList as $value) { + // Only include found CSS files (to reduce 404 requests) + $FQFN = $basePath . '/' . $value; + + // Do include only existing files and whose are not empty + if ((isFileReadable($FQFN)) && (filesize($FQFN) > 0)) { + // Load CSS content + $OUT .= readFromFile($FQFN); + } // END - if + } // END - foreach + + // Load template + $GLOBALS['__page_header'] .= loadTemplate('css_inline', TRUE, removeDeprecatedComment($OUT)); + } else { + // Now we load all CSS files from css.php! + $OUT = ''; + } +} + // [EOF] ?>