X-Git-Url: https://git.mxchange.org/?p=mailer.git;a=blobdiff_plain;f=inc%2Ffunctions.php;h=f7c2247656835dd9c582791c8f158c5b67629422;hp=951f7e0e18285968e922fe0cdf65fa1a2b20af41;hb=a00ad7dd8c36a5322e28f38d8d641efb90c00c92;hpb=517ed50cc4e716f1d34fbfc3a1befcba591eb698 diff --git a/inc/functions.php b/inc/functions.php index 951f7e0e18..f7c2247656 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -16,7 +16,7 @@ * $Author:: $ * * -------------------------------------------------------------------- * * Copyright (c) 2003 - 2009 by Roland Haeder * - * Copyright (c) 2009 - 2012 by Mailer Developer Team * + * Copyright (c) 2009 - 2013 by Mailer Developer Team * * For more information visit: http://mxchange.org * * * * This program is free software; you can redistribute it and/or modify * @@ -51,7 +51,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,52 +64,57 @@ 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 function getTotalFatalErrors () { // Init count - $count = '0'; + $count = 0; // Is there at least the first entry? if (!empty($GLOBALS['fatal_messages'][0])) { // Get total count $count = count($GLOBALS['fatal_messages']); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'count=' . $count . ' - FROM ARRAY'); } // END - if // Return value + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'count=' . $count . ' - EXIT!'); return $count; } // 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 - // Initialize array with all allowed chars - $ABC = explode(',', 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,0,1,2,3,4,5,6,7,8,9,-,+,_,/,.'); - // Exclude some entries - $ABC = array_diff($ABC, $exclude); + $localAbc = array_diff($GLOBALS['_abc'], $exclude); + + // $localAbc must have at least 10 entries + assert(count($localAbc) >= 10); // Start creating password - $PASS = ''; - for ($i = '0'; $i < $length; $i++) { - $PASS .= $ABC[mt_rand(0, count($ABC) -1)]; - } // END - for + $password = ''; + while (strlen($password) < $length) { + $password .= $localAbc[mt_rand(0, count($localAbc) -1)]; + } // END - while - // When the size is below 40 we can also add additional security by scrambling - // it. Otherwise we may corrupt hashes - if (strlen($PASS) <= 40) { + /* + * 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 - $PASS = scrambleString($PASS); + $password = scrambleString($password); } // END - if // Return the password - return $PASS; + return $password; } // Generates a human-readable timestamp from the Uni* stamp @@ -142,7 +147,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; @@ -158,7 +163,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 @@ -177,11 +182,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 @@ -190,9 +200,34 @@ 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') { +function translateComma ($dotted, $cut = TRUE, $max = '0') { // First, cast all to double, due to PHP changes $dotted = (double) $dotted; @@ -210,7 +245,7 @@ function translateComma ($dotted, $cut = true, $max = '0') { } // END - if // Cut zeros off? - if (($cut === true) && ($max == '0')) { + if (($cut === TRUE) && ($max == '0')) { // Test for commata if in cut-mode $com = explode('.', $dotted); if (count($com) < 2) { @@ -254,7 +289,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 @@ -272,7 +307,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; @@ -282,7 +317,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 @@ -306,7 +341,7 @@ function translateMenuVisibleLocked ($content, $prefix = '') { break; default: // Please report this - reportBug(__FUNCTION__, __LINE__, 'Unsupported visible value detected. content=
' . print_r($content, true) . '
'); + reportBug(__FUNCTION__, __LINE__, 'Unsupported visible value detected. content=
' . print_r($content, TRUE) . '
'); break; } // END - switch @@ -321,7 +356,7 @@ function translateMenuVisibleLocked ($content, $prefix = '') { break; default: // Please report this - reportBug(__FUNCTION__, __LINE__, 'Unsupported locked value detected. content=
' . print_r($content, true) . '
'); + reportBug(__FUNCTION__, __LINE__, 'Unsupported locked value detected. content=
' . print_r($content, TRUE) . '
'); break; } // END - switch @@ -332,15 +367,18 @@ function translateMenuVisibleLocked ($content, $prefix = '') { // Generates an URL for the dereferer function generateDereferrerUrl ($url) { // Don't de-refer our own links! - if (substr($url, 0, strlen(getUrl())) != getUrl()) { + if ((!empty($url)) && (substr($url, 0, strlen(getUrl())) != getUrl())) { // Encode URL $encodedUrl = encodeString(compileUriCode($url)); - // Log plain URL - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url); + // Generate hash + $hash = generateHash($url . getSiteKey() . getDateKey()); + + // Log plain URL and hash + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url . ',hash=' . $hash . '(' . strlen($hash) . ')'); // De-refer this URL - $url = '{%url=modules.php?module=loader&url=' . $encodedUrl . '&hash=' . encodeHashForCookie(generateHash($url)) . '%}'; + $url = '{%url=modules.php?module=loader&url=' . $encodedUrl . '&hash=' . encodeHashForCookie($hash) . '&salt=' . substr($hash, 0, getSaltLength()) . '%}'; } // END - if // Return link @@ -350,7 +388,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)) ); @@ -401,7 +439,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) { // Is the output mode -2? if (isAjaxOutputMode()) { // This is always (!) an AJAX request and shall not be redirected @@ -433,11 +471,11 @@ function redirectToUrl ($url, $allowSpider = true) { // We should not sent a redirect if headers are already sent if (!headers_sent()) { // Load URL when headers are not sent - sendRawRedirect(doFinalCompilation(str_replace('&', '&', $url), false)); + sendRawRedirect(doFinalCompilation(str_replace('&', '&', $url), FALSE)); } else { // Output error message loadInclude('inc/header.php'); - loadTemplate('redirect_url', false, str_replace('&', '&', $url)); + loadTemplate('redirect_url', FALSE, str_replace('&', '&', $url)); loadInclude('inc/footer.php'); } @@ -454,26 +492,26 @@ function redirectToUrl ($url, $allowSpider = true) { * $a_sort - Array, das die Sortiereihenfolge der ersten Elementeben * * $primary_key - Primaerschl.ssel aus $a_sort, nach dem sortiert wird * * $order - Sortiereihenfolge: -1 = a-Z, 0 = keine, 1 = Z-a * - * $nums - true = Als Zahlen sortieren, false = Als Zeichen sortieren * + * $nums - TRUE = Als Zahlen sortieren, FALSE = Als Zeichen sortieren * * * * $a_sort muss Elemente enthalten, deren Wert Schluessel von $array * * sind... Klingt kompliziert, suchen Sie mal mein Beispiel, dann sehen * * Sie, dass es doch nicht so schwer ist! :-) * * * ************************************************************************/ -function array_pk_sort (&$array, $a_sort, $primary_key = '0', $order = -1, $nums = false) { +function array_pk_sort (&$array, $a_sort, $primary_key = '0', $order = -1, $nums = FALSE) { $temporaryArray = $array; while ($primary_key < count($a_sort)) { foreach ($temporaryArray[$a_sort[$primary_key]] as $key => $value) { foreach ($temporaryArray[$a_sort[$primary_key]] as $key2 => $value2) { - $match = false; - if ($nums === false) { + $match = FALSE; + if ($nums === FALSE) { // Sort byte-by-byte (also numbers will be interpreted as chars! E.g.: "9" > "10") - if (($key != $key2) && (strcmp(strtolower($temporaryArray[$a_sort[$primary_key]][$key]), strtolower($temporaryArray[$a_sort[$primary_key]][$key2])) == $order)) $match = true; + if (($key != $key2) && (strcmp(strtolower($temporaryArray[$a_sort[$primary_key]][$key]), strtolower($temporaryArray[$a_sort[$primary_key]][$key2])) == $order)) $match = TRUE; } 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 (($temporaryArray[$a_sort[$primary_key]][$key] > $temporaryArray[$a_sort[$primary_key]][$key2]) && ($order == 1)) $match = TRUE; } if ($match) { @@ -567,19 +605,19 @@ function generateRandomCode ($length, $code, $userid, $extraData = '') { } // Does only allow numbers -function bigintval ($num, $castValue = true, $abortOnMismatch = true) { +function bigintval ($num, $castValue = TRUE, $abortOnMismatch = TRUE) { //* DEBUG: */ debugOutput('[' . __FUNCTION__ . ':' . __LINE__ . '] ' . 'num=' . $num . ',castValue=' . intval($castValue) . ',abortOnMismatch=' . intval($abortOnMismatch) . ' - ENTERED!'); - // Filter all numbers out + // Filter all non-number chars out, so only number chars will remain $ret = preg_replace('/[^0123456789]/', '', $num); // Shall we cast? - if ($castValue === true) { + if ($castValue === TRUE) { // Cast to biggest numeric type $ret = (double) $ret; } // END - if // Has the whole value changed? - if (('' . $ret . '' != '' . $num . '') && ($abortOnMismatch === true) && (!is_null($num))) { + if (('' . $ret . '' != '' . $num . '') && ($abortOnMismatch === TRUE) && (!is_null($num))) { // Log the values reportBug(__FUNCTION__, __LINE__, 'Problem with number found. ret[' . gettype($ret) . ']=' . $ret . ', num[' . gettype($num) . ']='. $num); } // END - if @@ -591,16 +629,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 @@ -608,7 +650,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; @@ -632,7 +678,7 @@ function createEpocheTimeFromSelections ($prefix, $postData) { // Creates a 'fancy' human-readable timestamp from a Uni* stamp function createFancyTime ($stamp) { // Get data array with years/months/weeks/days/... - $data = createTimeSelections($stamp, '', '', '', true); + $data = createTimeSelections($stamp, '', '', '', TRUE); $ret = ''; foreach ($data as $k => $v) { if ($v > 0) { @@ -643,7 +689,7 @@ function createFancyTime ($stamp) { } // END - foreach // Is something there? - if (strlen($ret) > 0) { + if (!empty($ret)) { // Remove leading commata and space $ret = substr($ret, 2); } else { @@ -676,25 +722,25 @@ 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() -function isUrlValid ($url, $compile = true) { +function isUrlValid ($url, $compile = TRUE) { // Trim URL a little $url = trim(urldecode($url)); //* DEBUG: */ debugOutput($url); // Compile some chars out... - if ($compile === true) { - $url = compileUriCode($url, false, false, false); + if ($compile === TRUE) { + $url = compileUriCode($url, FALSE, FALSE, FALSE); } // END - if //* DEBUG: */ debugOutput($url); // Check for the extension filter if (isExtensionActive('filter')) { // Use the extension's filter set - return FILTER_VALIDATE_URL($url, false); + return FILTER_VALIDATE_URL($url, FALSE); } // END - if /* @@ -705,15 +751,15 @@ function isUrlValid ($url, $compile = true) { } // Generate a hash for extra-security for all passwords -function generateHash ($plainText, $salt = '', $hash = true) { +function generateHash ($plainText, $salt = '', $hash = TRUE) { // Debug output - //* DEBUG: */ debugOutput('plainText('.strlen($plainText).')=' . $plainText . ',salt('.strlen($salt).')=' . $salt . ',hash=' . intval($hash)); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'plainText('.strlen($plainText).')=' . $plainText . ',salt('.strlen($salt).')=' . $salt . ',hash=' . intval($hash)); // Is the required extension 'sql_patches' there and a salt is not given? // 123 4 43 3 4 432 2 3 32 2 3 32 2 3 3 21 if (((isExtensionInstalledAndOlder('sql_patches', '0.3.6')) && (empty($salt))) || (!isExtensionActive('sql_patches')) || (!isExtensionInstalledAndNewer('other', '0.2.5')) || (strlen($salt) == 32)) { // Extension ext-sql_patches is missing/outdated so we hash the plain text with MD5 - if ($hash === true) { + if ($hash === TRUE) { // Is plain password return md5($plainText); } else { @@ -734,30 +780,36 @@ function generateHash ($plainText, $salt = '', $hash = true) { $server = $_SERVER['PHP_SELF'] . 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() . getDateFromRepository() . 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(); + $data = $plainText . getEncryptSeparator() . uniqid(mt_rand(), TRUE) . getEncryptSeparator() . time(); // Calculate number for generating the code $a = time() + getConfig('_ADD') - 1; // Generate SHA1 sum from modula of number and the prime number $sha1 = sha1(($a % getPrime()) . $server . getEncryptSeparator() . $keys . getEncryptSeparator() . $data . getEncryptSeparator() . getDateKey() . getEncryptSeparator() . $a); - //* DEBUG: */ debugOutput('SHA1=' . $sha1.' ('.strlen($sha1).')
'); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'SHA1=' . $sha1.' ('.strlen($sha1).')'); $sha1 = scrambleString($sha1); - //* DEBUG: */ debugOutput('Scrambled=' . $sha1.' ('.strlen($sha1).')
'); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Scrambled=' . $sha1.' ('.strlen($sha1).')'); //* DEBUG: */ $sha1b = descrambleString($sha1); - //* DEBUG: */ debugOutput('Descrambled=' . $sha1b.' ('.strlen($sha1b).')
'); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Descrambled=' . $sha1b.' ('.strlen($sha1b).')'); // Generate the password salt string $salt = substr($sha1, 0, getSaltLength()); - //* DEBUG: */ debugOutput($salt.' ('.strlen($salt).')
'); + //* DEBUG: */ debugOutput($salt.' ('.strlen($salt).')'); } else { // Use given salt - //* DEBUG: */ debugOutput('salt=' . $salt); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'salt=' . $salt); $salt = substr($salt, 0, getSaltLength()); - //* DEBUG: */ debugOutput('salt=' . $salt . '(' . strlen($salt) . '/' . getSaltLength() . ')
'); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'salt=' . $salt . '(' . strlen($salt) . '/' . getSaltLength() . ')'); // Sanity check on salt if (strlen($salt) != getSaltLength()) { @@ -770,7 +822,7 @@ function generateHash ($plainText, $salt = '', $hash = true) { $finalHash = $salt . sha1($salt . $plainText); // Debug output - //* DEBUG: */ debugOutput('finalHash('.strlen($finalHash).')=' . $finalHash); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'finalHash('.strlen($finalHash).')=' . $finalHash); // Return hash return $finalHash; @@ -793,8 +845,8 @@ function scrambleString ($str) { $scrambleNums = explode(':', genScrambleString(strlen($str))); } - // Compare both lengths and abort if different - if (strlen($str) != count($scrambleNums)) return $str; + // Assert on both lengths + assert(strlen($str) == count($scrambleNums)); // Scramble string here //* DEBUG: */ debugOutput('***Original=' . $str.'***
'); @@ -860,6 +912,8 @@ function genScrambleString ($len) { // So let's create the string for storing it in database $scrambleString = implode(':', $scrambleNumbers); + + // Return it return $scrambleString; } @@ -875,32 +929,40 @@ function encodeHashForCookie ($passHash) { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, strlen($passHash) . '/' . strlen(getSecretKey())); if ((strlen($passHash) != 49) || (strlen(getSecretKey()) != 40)) { // Both keys must have same length so return unencrypted - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, strlen($passHash) . '!=49/' . strlen(getSecretKey()) . '!=40'); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, strlen($passHash) . '!=49/' . strlen(getSecretKey()) . '!=40 - EXIT!'); return $ret; } // END - if $newHash = ''; $start = 9; //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'passHash=' . $passHash . '(' . strlen($passHash) . ')'); for ($idx = 0; $idx < 20; $idx++) { - $part1 = hexdec(substr($passHash, ($idx * 2) + (strlen($passHash) - strlen(getSecretKey())), 2)); + // Get hash parts and convert them (00-FF) to matching ASCII value (0-255) + $part1 = hexdec(substr($passHash , $start, 2)); $part2 = hexdec(substr(getSecretKey(), $start, 2)); - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'part1=' . $part1 . '/part2=' . $part2); + + // 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 $mod = dechex(sqrt(($part1 - $part2) * getPrime() / pi())); } elseif ($part2 > $part1) { + // part2 is larger $mod = dechex(sqrt(($part2 - $part1) * getPrime() / pi())); } + $mod = substr($mod, 0, 2); - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'part1=' . $part1 . '/part2=' . $part2 . '/mod=' . $mod . '(' . strlen($mod) . ')'); - $mod = str_repeat(0, (2 - strlen($mod))) . $mod; + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'idx=' . $idx . ',part1=' . $part1 . '/part2=' . $part2 . '/mod=' . $mod . '(' . strlen($mod) . ')'); + $mod = padLeftZero($mod, 2); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'mod(' . ($idx * 2) . ')=' . $mod . '*'); $start += 2; $newHash .= $mod; } // END - for - //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, $passHash . ',' . $newHash . ' (' . strlen($newHash) . ')'); - $ret = generateHash($newHash, getMasterSalt()); + // Just copy it over, as the master salt is not really helpful here + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, $passHash . '(' . strlen($passHash) . '),' . $newHash . ' (' . strlen($newHash) . ')'); + $ret = $newHash; } // END - if // Return result @@ -911,7 +973,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"? @@ -937,13 +999,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(); } @@ -964,7 +1026,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)) { @@ -972,7 +1034,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 @@ -1020,7 +1082,7 @@ function debug_get_mailable_backtrace () { // Generates a ***weak*** seed function generateSeed () { - return microtime(true) * 100000; + return microtime(TRUE) * 100000; } // Converts a message code to a human-readable message @@ -1071,7 +1133,7 @@ function getMessageFromErrorCode ($code) { case getCode('LOGIN_EMPTY_PASSWORD'): $message = '{--LOGIN_PASSWORD_IS_EMPTY--}'; break; case getCode('ERROR_MAILID'): - if (isExtensionActive('mailid', true)) { + if (isExtensionActive('mailid', TRUE)) { $message = '{--ERROR_CONFIRMING_MAIL--}'; } else { $message = '{%pipe,generateExtensionInactiveNotInstalledMessage=mailid%}'; @@ -1087,15 +1149,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); @@ -1110,7 +1165,7 @@ function getMessageFromErrorCode ($code) { $content['seconds'] = round(getUrlTlock() - $content['hours'] * 60 * 60 - $content['minutes'] * 60); // Finally contruct the message - $message = loadTemplate('tlock_message', true, $content); + $message = loadTemplate('tlock_message', TRUE, $content); break; default: @@ -1169,7 +1224,7 @@ function isUrlValidSimple ($url) { $pattern['ipg12'] = $http . $ip . $getstring1; // Test all patterns - $reg = false; + $reg = FALSE; foreach ($pattern as $key => $pat) { // Debug regex? if (isDebugRegularExpressionEnabled()) { @@ -1183,7 +1238,7 @@ function isUrlValidSimple ($url) { $reg = ($reg || preg_match(('^' . $pat . '^'), $url)); // Does it match? - if ($reg === true) { + if ($reg === TRUE) { break; } // END - if } // END - foreach @@ -1195,12 +1250,12 @@ function isUrlValidSimple ($url) { // Wtites data to a config.php-style file // @TODO Rewrite this function to use readFromFile() and writeToFile() -function changeDataInFile ($FQFN, $comment, $prefix, $suffix, $inserted, $seek=0) { +function changeDataInFile ($FQFN, $comment, $prefix, $suffix, $inserted, $seek = 0) { // Initialize some variables - $done = false; + $done = FALSE; $seek++; $next = -1; - $found = false; + $found = FALSE; // Is the file there and read-/write-able? if ((isFileReadable($FQFN)) && (is_writeable($FQFN))) { @@ -1218,22 +1273,22 @@ function changeDataInFile ($FQFN, $comment, $prefix, $suffix, $inserted, $seek=0 // Is the resource again valid? if (is_resource($fp_tmp)) { // Mark temporary file as readable - $GLOBALS['file_readable'][$tmp] = true; + $GLOBALS['file_readable'][$tmp] = TRUE; // Start reading while (!feof($fp)) { // Read from source file - $line = fgets ($fp, 1024); + $line = fgets($fp, 1024); if (isInString($search, $line)) { $next = '0'; - $found = true; + $found = TRUE; } // END - if if ($next > -1) { if ($next === $seek) { $next = -1; - $line = $prefix . $inserted . $suffix . chr(10); + $line = $prefix . $inserted . $suffix . PHP_EOL; } else { $next++; } @@ -1247,40 +1302,44 @@ function changeDataInFile ($FQFN, $comment, $prefix, $suffix, $inserted, $seek=0 fclose($fp_tmp); // Finished writing tmp file - $done = true; + $done = TRUE; } // END - if // Close source file fclose($fp); - if (($done === true) && ($found === true)) { - // Copy back tmp file and delete tmp :-) + if (($done === TRUE) && ($found === TRUE)) { + // Copy back temporary->FQFN file and ... copyFileVerified($tmp, $FQFN, 0644); + + // ... delete temporay file :-) return removeFile($tmp); - } elseif ($found === false) { - outputHtml('CHANGE: 404!'); + } elseif ($found === FALSE) { + // Entry not found + logDebugMessage(__FUNCTION__, __LINE__, 'File ' . basename($FQFN) . ' cannot be changed: comment=' . $comment . ',prefix=' . $prefix . ',inserted=' . $inserted . ',seek=' . $seek . ' - 404!'); } else { - outputHtml('TMP: UNDONE!'); + // Temporary file not fully written + logDebugMessage(__FUNCTION__, __LINE__, 'File ' . basename($FQFN) . ' cannot be changed: comment=' . $comment . ',prefix=' . $prefix . ',inserted=' . $inserted . ',seek=' . $seek . ' - Temporary file unfinished!'); } } } else { // File not found, not readable or writeable - reportBug(__FUNCTION__, __LINE__, 'File not readable/writeable. file=' . basename($FQFN)); + reportBug(__FUNCTION__, __LINE__, 'File not readable/writeable. file=' . basename($FQFN) . ',comment=' . $comment . ',prefix=' . $prefix . ',inserted=' . $inserted . ',seek=' . $seek); } // An error was detected! - return false; + return FALSE; } // Debug message logger function logDebugMessage ($funcFile, $line, $message, $force=true) { // Is debug mode enabled? - if ((isDebugModeEnabled()) || ($force === true)) { + if ((isDebugModeEnabled()) || ($force === TRUE)) { // Remove CRLF - $message = str_replace(array(chr(13), chr(10)), array('', ''), $message); + $message = str_replace(array(chr(13), PHP_EOL), array('', ''), $message); // Log this message away - appendLineToFile(getPath() . getCachePath() . 'debug.log', generateDateTime(time(), '4') . '|' . getModule(false) . '|' . basename($funcFile) . '|' . $line . '|' . $message); + appendLineToFile(getPath() . getCachePath() . 'debug.log', generateDateTime(time(), '4') . '|' . getModule(FALSE) . ':' . getExtraModule() . '|' . basename($funcFile) . '|' . $line . '|' . $message); } // END - if } @@ -1290,72 +1349,142 @@ function handleExtraValues ($filterFunction, $value, $extraValue) { $ret = $value; // Is there a special filter function? - if (!empty($filterFunction)) { - // Does the filter function exist? - if (function_exists($filterFunction)) { - // Is there extra parameters here? - if (!empty($extraValue)) { - // Put both parameters in one new array by default - $args = array($value, $extraValue); - - // If we have an array simply use it and pre-extend it with our value - if (is_array($extraValue)) { - // Make the new args array - $args = merge_array(array($value), $extraValue); - } // END - if + if ((empty($filterFunction)) || (!function_exists($filterFunction))) { + // Call-back function does not exist or is empty + reportBug(__FUNCTION__, __LINE__, 'Filter function ' . $filterFunction . ' does not exist or is empty: value[' . gettype($value) . ']=' . $value . ',extraValue[' . gettype($extraValue) . ']=' . $extraValue); + } // END - if - // Call the multi-parameter call-back - $ret = call_user_func_array($filterFunction, $args); + // Is there extra parameters here? + if ((!is_null($extraValue)) && (!empty($extraValue))) { + // Put both parameters in one new array by default + $args = array($value, $extraValue); - // Is $ret 'true'? - if ($ret === true) { - // Test passed, so write direct value - $ret = $args; - } // END - if - } else { - // One parameter call - $ret = call_user_func($filterFunction, $value); + // If we have an array simply use it and pre-extend it with our value + if (is_array($extraValue)) { + // Make the new args array + $args = merge_array(array($value), $extraValue); + } // END - if - // Is $ret 'true'? - if ($ret === true) { - // Test passed, so write direct value - $ret = $value; - } // END - if - } + // Call the multi-parameter call-back + $ret = call_user_func_array($filterFunction, $args); + + // Is $ret 'true'? + if ($ret === TRUE) { + // Test passed, so write direct value + $ret = $args; } // END - if - } // END - if + } else { + // One parameter call + $ret = call_user_func($filterFunction, $value); + //* BUG */ die('ret['.gettype($ret).']=' . $ret . ',value=' . $value.',filterFunction=' . $filterFunction); + + // Is $ret 'true'? + if ($ret === TRUE) { + // Test passed, so write direct value + $ret = $value; + } // END - if + } // Return the value return $ret; } +// Tries to determine if call-back functions and/or extra values shall be parsed +function doHandleExtraValues ($filterFunctions, $extraValues, $key, $entries, $userIdColumn, $search, $id = NULL) { + // Debug mode enabled? + if (isDebugModeEnabled()) { + // Debug message + /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key . ',entries=' . $entries . ',userIdColumn=' . $userIdColumn[0] . ',search=' . $search . ',filterFunctions=' . print_r($filterFunctions, TRUE) . ',extraValues=' . print_r($extraValues, TRUE)); + } // END - if + + // Send data through the filter function if found + if ($key === $userIdColumn[0]) { + // Is the userid, we have to process it with convertZeroToNull() + $entries = convertZeroToNull($entries); + } elseif ((!empty($filterFunctions[$key])) && (isset($extraValues[$key]))) { + // Debug mode enabled? + if (isDebugModeEnabled()) { + // Then log it + /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'search=' . $search . ',filterFunctions=' . $filterFunctions[$key] . ',extraValues=' . $extraValues[$key] . ',key=' . $key . ',id=' . $id . ',entries[' . gettype($entries) . ']=' . $entries . ' - BEFORE!'); + } // END - if + + // Filter function + extra value set + $entries = handleExtraValues($filterFunctions[$key], $entries, $extraValues[$key]); + + // Debug mode enabled? + if (isDebugModeEnabled()) { + // Then log it + /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'search=' . $search . ',filterFunctions=' . $filterFunctions[$key] . ',extraValues=' . $extraValues[$key] . ',key=' . $key . ',id=' . $id . ',entries[' . gettype($entries) . ']=' . $entries . ' - AFTER!'); + } // END - if + } elseif ((!empty($filterFunctions[$search])) && (!empty($extraValues[$search]))) { + // Debug mode enabled? + if (isDebugModeEnabled()) { + // Then log it + /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'search=' . $search . ',filterFunctions=' . $filterFunctions[$search] . ',key=' . $key . ',search=' . $search . ',entries[' . gettype($entries) . ']=' . $entries . ' - BEFORE!'); + } // END - if + + // Handle extra values + $entries = handleExtraValues($filterFunctions[$search], $entries, $extraValues[$search]); + + // Debug mode enabled? + if (isDebugModeEnabled()) { + // Then log it + /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'search=' . $search . ',filterFunctions=' . $filterFunctions[$search] . ',key=' . $key . ',search=' . $search . ',entries[' . gettype($entries) . ']=' . $entries . ' - AFTER!'); + } // END - if + + // Make sure entries is not bool, then something went wrong + assert(!is_bool($entries)); + } elseif (!empty($filterFunctions[$search])) { + // Debug mode enabled? + if (isDebugModeEnabled()) { + // Then log it + /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'search=' . $search . ',filterFunctions=' . $filterFunctions[$search] . ',key=' . $key . ',search=' . $search . ',entries[' . gettype($entries) . ']=' . $entries . ' - BEFORE!'); + } // END - if + + // Handle extra values + $entries = handleExtraValues($filterFunctions[$search], $entries, NULL); + + // Debug mode enabled? + if (isDebugModeEnabled()) { + // Then log it + /* NOISY-DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'search=' . $search . ',filterFunctions=' . $filterFunctions[$search] . ',key=' . $key . ',search=' . $search . ',entries[' . gettype($entries) . ']=' . $entries . ' - AFTER!'); + } // END - if + + // Make sure entries is not bool, then something went wrong + assert(!is_bool($entries)); + } + + // Return value + return $entries; +} + // Converts timestamp selections into a timestamp function convertSelectionsToEpocheTime (array &$postData, array &$content, &$id, &$skip) { // Init test variable - $skip = false; + $skip = FALSE; $test2 = ''; // Get last three chars $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; + $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 // Skip adding unset($id); - $skip = true; + $skip = TRUE; $test2 = $test; } // END - if } // END - if @@ -1365,7 +1494,7 @@ function convertSelectionsToEpocheTime (array &$postData, array &$content, &$id, // OPPOMENT: translateComma() function convertCommaToDot ($str) { // Default float is not a float... ;-) - $float = false; + $float = FALSE; // Which language is selected? switch (getLanguage()) { @@ -1374,12 +1503,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 @@ -1404,7 +1533,7 @@ function handleLoginFailures ($accessLevel) { ); // Load template - $OUT = loadTemplate('login_failures', true, $content); + $OUT = loadTemplate('login_failures', TRUE, $content); } // END - if // Reset session data @@ -1417,13 +1546,14 @@ function handleLoginFailures ($accessLevel) { } // Rebuild cache -function rebuildCache ($cache, $inc = '', $force = false) { +function rebuildCache ($cache, $inc = '', $force = FALSE) { // Debug message //* 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())) { - // Rebuild cache + 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); @@ -1432,7 +1562,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)) { @@ -1440,15 +1570,15 @@ 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 } // Determines the real remote address -function determineRealRemoteAddress ($remoteAddr = false) { +function determineRealRemoteAddress ($remoteAddr = FALSE) { // Default is 127.0.0.1 $address = '127.0.0.1'; @@ -1476,7 +1606,7 @@ function determineRealRemoteAddress ($remoteAddr = false) { // Adds a bonus mail to the queue // This is a high-level function! -function addNewBonusMail ($data, $mode = '', $output = true) { +function addNewBonusMail ($data, $mode = '', $output = TRUE) { // Use mode from data if not set and availble ;-) if ((empty($mode)) && (isset($data['mail_mode']))) { $mode = $data['mail_mode']; @@ -1501,10 +1631,10 @@ function addNewBonusMail ($data, $mode = '', $output = true) { ); // Mail inserted into bonus pool - if ($output === true) { + if ($output === TRUE) { displayMessage('{--ADMIN_BONUS_SEND--}'); } // END - if - } elseif ($output === true) { + } elseif ($output === TRUE) { // More entered than can be reached! displayMessage('{--ADMIN_MORE_SELECTED--}'); } else { @@ -1513,22 +1643,79 @@ function addNewBonusMail ($data, $mode = '', $output = true) { } } -// Enables the reset mode and runs it -function doReset () { +// 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['reset_enabled'] = true; + $GLOBALS['daily_enabled'] = TRUE; // Run filters - runFilterChain('reset'); + runFilterChain('daily'); + + // Do not update in daily debug mode + if ((!isConfigEntrySet('DEBUG_DAILY')) || (!isDebugDailyEnabled())) { + // Update database + updateConfiguration('last_daily', getDay()); + } // END - if } -// Enables the reset mode (hourly, weekly and monthly) and runs it -function doHourly () { - // Enable the hourly reset mode - $GLOBALS['hourly_enabled'] = true; +// Enables the weekly reset mode and runs it +function doWeekly () { + // Enable the reset mode + $GLOBALS['weekly_enabled'] = TRUE; - // Run filters (one always!) - runFilterChain('hourly'); + // 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.) @@ -1536,11 +1723,11 @@ function doShutdown () { // Call the filter chain 'shutdown' runFilterChain('shutdown', NULL); - // Check if not in installation phase and the link is up - if ((!isInstallationPhase()) && (SQL_IS_LINK_UP())) { + // Check if link is 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.'); } @@ -1555,29 +1742,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 @@ -1621,9 +1808,10 @@ function isExtraTitleSet () { * @param $excludePattern Regular expression to exclude more files (preg_match()) * @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'); @@ -1637,7 +1825,7 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = false, $ad // Read all entries while ($baseFile = readdir($dirPointer)) { // Exclude '.', '..' and entries in $excludeArray automatically - if (in_array($baseFile, $excludeArray, true)) { + if (in_array($baseFile, $excludeArray, TRUE)) { // Exclude them //* DEBUG: */ debugOutput('excluded=' . $baseFile); continue; @@ -1660,7 +1848,7 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = false, $ad } // END - if // Skip also files with non-matching prefix genericly - if (($recursive === true) && (isDirectory($FQFN))) { + if (($recursive === TRUE) && (isDirectory($FQFN))) { // Is a redirectory so read it as well $foundMatches = merge_array($foundMatches, getArrayFromDirectory($baseDir . $baseFile . '/', $prefix, $fileIncludeDirs, $addBaseDir, $excludeArray, $extension, $excludePattern, $recursive)); @@ -1692,16 +1880,19 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = false, $ad // Is the file a PHP script or other? //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'baseDir=' . $baseDir . ',prefix=' . $prefix . ',baseFile=' . $baseFile); - if (($fileExtension == '.php') || (($fileIncludeDirs === true) && (isDirectory($FQFN)))) { + if (($fileExtension == '.php') || (($fileIncludeDirs === TRUE) && (isDirectory($FQFN)))) { // Is this a valid include file? if ($extension == '.php') { // Remove both for extension name $extName = substr($baseFile, strlen($prefix), -4); // Add file with or without base path - if ($addBaseDir === true) { + 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); @@ -1710,9 +1901,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 @@ -1738,13 +1938,12 @@ 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 $moduleName = 'member'; break; - // Anything else will not be mapped, silently. } // END - switch @@ -1753,35 +1952,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) { + 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 @@ -1864,7 +2063,7 @@ function encodeUrl ($url, $outputMode = '0') { } // END - if // Is there a valid session? - if (((!isset($GLOBALS['valid_session'])) || ($GLOBALS['valid_session'] === false) || (!isset($_COOKIE[session_name()]))) && (isSpider() === false)) { + if ((!isValidSession()) && (!isSpider())) { // Determine right separator $separator = '&'; if (!isInString('?', $url)) { @@ -1872,10 +2071,8 @@ function encodeUrl ($url, $outputMode = '0') { $separator = '?'; } // END - if - // Add it to URL - if (session_id() != '') { - $url .= $separator . session_name() . '=' . session_id(); - } // END - if + // Then add it to URL + $url .= $separator . session_name() . '=' . session_id(); } // END - if // Add {?URL?} ? @@ -1884,10 +2081,15 @@ function encodeUrl ($url, $outputMode = '0') { $url = '{?URL?}/' . $url; } // END - if + // Debug message + //* 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); + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url . ' - AFTER DECODING'); } // END - if // Debug log @@ -1900,12 +2102,12 @@ function encodeUrl ($url, $outputMode = '0') { // Simple check for spider function isSpider () { // Get the UA and trim it down - $userAgent = trim(detectUserAgent(true)); + $userAgent = trim(detectUserAgent(TRUE)); - // It should not be empty, if so it is better a spider/bot + // It should not be empty, if so it is better a browser if (empty($userAgent)) { - // It is a spider/bot - return true; + // It is a browser that blocks its UA string + return FALSE; } // END - if // Is it a spider? @@ -1920,7 +2122,7 @@ function searchDirsRecursive ($dir, &$last_changed, $lookFor = 'Date') { // 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); + $ds = getArrayFromDirectory($dir, '', FALSE, TRUE, array(), '.php', $excludePattern); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'count(ds)='.count($ds)); // Walk through all entries @@ -1978,7 +2180,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 { @@ -1990,16 +2192,13 @@ function convertZeroToNull ($number) { return $number; } -// Converts a NULL to zero +// Converts a NULL|empty string|< 1 to zero function convertNullToZero ($number) { // Is it a valid username? - if ((!is_null($number)) && (!empty($number)) && ($number > 0)) { - // Always secure it - $number = bigintval($number); - } else { + if (!isValidNumber($number)) { // Is not valid or zero $number = '0'; - } + } // END - if // Return it return $number; @@ -2031,7 +2230,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 = ''; @@ -2043,11 +2242,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; @@ -2060,7 +2259,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, @@ -2068,9 +2267,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; @@ -2084,7 +2283,7 @@ function generateAdminMailLinks ($mailType, $mailId) { } // END - if // Free result - SQL_FREERESULT($result); + sqlFreeResult($result); } // END - if // Return generated HTML code @@ -2114,7 +2313,7 @@ function isHexadecimal ($hex) { } /** - * Replace chr(13) with "[r]" and chr(10) with "[n]" and add a final new-line to make + * Replace chr(13) with "[r]" and PHP_EOL with "[n]" and add a final new-line to make * them visible to the developer. Use this function to debug e.g. buggy HTTP * response handler functions. * @@ -2147,7 +2346,7 @@ function detectMultiBytePrefix ($str) { $mbPrefix = ''; // Detect multi-byte (strictly) - if (mb_detect_encoding($str, 'auto', true) !== false) { + if (mb_detect_encoding($str, 'auto', TRUE) !== FALSE) { // With multi-byte encoded string $mbPrefix = 'mb_'; } // END - if @@ -2156,7 +2355,7 @@ function detectMultiBytePrefix ($str) { return $mbPrefix; } -// Searches the given array for a sub-string match and returns all found keys in an array +// Searches given array for a sub-string match and returns all found keys in an array function getArrayKeysFromSubStrArray ($heystack, $needles, $offset = 0) { // Init array for all found keys $keys = array(); @@ -2165,7 +2364,7 @@ function getArrayKeysFromSubStrArray ($heystack, $needles, $offset = 0) { foreach ($needles as $key => $needle) { // Is there found a partial string? //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'heystack='.$heystack.',key='.$key.',needle='.$needle.',offset='.$offset); - if (strpos($heystack, $needle, $offset) !== false) { + if (strpos($heystack, $needle, $offset) !== FALSE) { // Add the found key array_push($keys, $key); } // END - if @@ -2182,7 +2381,7 @@ function determinePointsColumnFromSubjectLocked ($subject, $locked) { $pointsColumn = 'points'; // Which points, locked or normal? - if ($locked === true) { + if ($locked === TRUE) { $pointsColumn = 'locked_points'; } // END - if @@ -2208,7 +2407,7 @@ function determinePointsColumnFromSubjectLocked ($subject, $locked) { function convertBooleanToYesNo ($boolean) { // Default is 'N' $converted = 'N'; - if ($boolean === true) { + if ($boolean === TRUE) { // Set 'Y' $converted = 'Y'; } // END - if @@ -2234,7 +2433,7 @@ function convertStringToBoolean ($str) { } // END - if // Determine it - $GLOBALS[__FUNCTION__][$str] = (($strTrimmed == 'true') ? true : false); + $GLOBALS[__FUNCTION__][$str] = ($strTrimmed == 'true'); } // END - if // Return cache @@ -2287,7 +2486,7 @@ function memberAddEntries ($tableName, $columns = array(), $filterFunctions = ar // Is it a member? if (!isMember()) { // Then abort here - return false; + return FALSE; } // END - if // Set POST data generic userid @@ -2297,7 +2496,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 { @@ -2307,7 +2506,7 @@ function memberAddEntries ($tableName, $columns = array(), $filterFunctions = ar } // Edit rows by given id numbers -function memberEditEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $timeColumns = array(), $editNow = array(false), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array()) { +function memberEditEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $timeColumns = array(), $editNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array(), $content = array()) { // $tableName must be an array if ((!is_array($tableName)) || (count($tableName) != 1)) { // No tableName specified @@ -2324,7 +2523,7 @@ function memberEditEntriesConfirm ($tableName, $columns = array(), $filterFuncti } // END - if // Shall we change here or list for editing? - if ($editNow[0] === true) { + if ($editNow[0] === TRUE) { // Add generic userid field setPostRequestElement('userid', getMemberId()); @@ -2341,12 +2540,12 @@ function memberEditEntriesConfirm ($tableName, $columns = array(), $filterFuncti } } else { // List for editing - memberListBuilder('edit', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn); + memberListBuilder('edit', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId, $content); } } // Delete rows by given id numbers -function memberDeleteEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $deleteNow = array(false), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array()) { +function memberDeleteEntriesConfirm ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $deleteNow = array(FALSE), $idColumn = array('id'), $userIdColumn = array('userid'), $rawUserId = array('userid'), $cacheFiles = array(), $content = array()) { // Do this only for members assert(isMember()); @@ -2366,7 +2565,7 @@ function memberDeleteEntriesConfirm ($tableName, $columns = array(), $filterFunc } // END - if // Shall we delete here or list for deletion? - if ($deleteNow[0] === true) { + if ($deleteNow[0] === TRUE) { // Add generic userid field setPostRequestElement('userid', getMemberId()); @@ -2379,21 +2578,22 @@ 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 - memberListBuilder('delete', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn); + memberListBuilder('delete', $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUSerId, $content); } } // Build a special template list -function memberListBuilder ($listType, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId = array('userid')) { +// @TODO cacheFiles is not yet supported +function memberListBuilder ($listType, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId = array('userid'), $content = array()) { // Do this only for logged in member assert(isMember()); // Call inner (general) function - doGenericListBuilder('member', $listType, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId); + doGenericListBuilder('member', $listType, $tableName, $columns, $filterFunctions, $extraValues, $idColumn, $userIdColumn, $rawUserId, $content); } // Checks whether given address is IPv4 @@ -2408,12 +2608,150 @@ function isIp4AddressValid ($address) { return $GLOBALS[__FUNCTION__][$address]; } +// Returns the string if not empty or FALSE if empty +function validateIsEmpty ($str) { + // Trim it + $trimmed = trim($str); + + // Is the string empty? + if (empty($trimmed)) { + // Then set FALSE + $str = FALSE; + } // END - if + + // Return it + 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; +} + +// Hash string with SHA256 and encode it to hex +function hashSha256 ($str) { + /// Hash string + $hash = mhash(MHASH_SHA256, $str); + + // Encode it to hexadecimal + $hex = ''; + for ($i = 0; $i < strlen($hash); $i++) { + // Encode char to decimal, pad it with zero, add it + $hex .= padLeftZero(dechex(ord(substr($hash, $i, 1))), 2); + } // END - if + + // Return it + return $hex; +} + // ---------------------------------------------------------------------------- // "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 @@ -2424,10 +2762,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)) { @@ -2448,45 +2786,60 @@ function translatePointsSubject ($subject) { return translateGeneric('POINTS_SUBJECT', $subject); } -// "Translates" the given points account type +// "Translates" given points account type function translatePointsAccountType ($accountType) { // Return it return translateGeneric('POINTS_ACCOUNT_TYPE', $accountType); } -// "Translates" the given points "locked mode" +// "Translates" given points "locked mode" function translatePointsLockedMode ($lockedMode) { // Return it return translateGeneric('POINTS_LOCKED_MODE', $lockedMode); } -// "Translates" the given points payment method +// "Translates" given points payment method function translatePointsPaymentMethod ($paymentMethod) { // Return it return translateGeneric('POINTS_PAYMENT_METHOD', $paymentMethod); } -// "Translates" the given points account provider +// "Translates" given points account provider function translatePointsAccountProvider ($accountProvider) { // Return it return translateGeneric('POINTS_ACCOUNT_PROVIDER', $accountProvider); } -// "Translates" the given points notify recipient +// "Translates" given points notify recipient function translatePointsNotifyRecipient ($notifyRecipient) { // Return it return translateGeneric('POINTS_NOTIFY_RECIPIENT', $notifyRecipient); } -// Translates task type to a human-readable version +// "Translates" given mode to a human-readable version +function translatePointsMode ($pointsMode) { + // Return it + return translateGeneric('POINTS_MODE', $pointsMode); +} + +// "Translates" task type to a human-readable version function translateTaskType ($taskType) { // Return it 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) { @@ -2496,5 +2849,78 @@ if (!function_exists('html_entity_decode')) { } } // END - if +// "Calculates" password strength +function calculatePasswordStrength ($password, $configEntry = 'min_password_length') { + // Default score + $score = 1; + + if ((strlen($password) < 1) || (strlen($password) < getConfig($configEntry))) { + // Is to weak + return 0; + } // END - if + + // At least 8 chars long? + if (strlen($password) >= 8) { + // Add score + $score++; + } // END - if + + // At least 10 chars long? + if (strlen($password) >= 10) { + // Add score + $score++; + } // END - if + + // Lower and upper cases? + if ((preg_match('/[a-z]/', $password)) && (preg_match('/[A-Z]/', $password))) { + // Add score + $score++; + } // END - if + + // Also numbers? + if (preg_match('/[0-9]/', $password)) { + // Add score + $score++; + } // END - if + + // Special characters? + if (preg_match('/.[!,@,#,$,%,^,&,*,?,\/,_,~,+,-,(,)]/', $password)) { + // Add score + $score++; + } // END - if + + // Return password score + return $score; +} + +// "Translates" password strength/score +function translatePasswordStrength ($strength) { + // Return it translated + return '{--PASSWORD_SCORE_' . bigintval($strength) . '--}'; +} + +// Checks whether given password is strong enough +function isStrongPassword ($password) { + // Determine it + return (calculatePasswordStrength($password) >= getConfig('min_password_score')); +} + +// "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]; +} + // [EOF] ?>