= 10); // Start creating password $password = ''; while (strlen($password) < $length) { $password .= $localAbc[mt_rand(0, count($localAbc) -1)]; } // END - while /* * 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 $password = scrambleString($password); } // END - if // Return the password return $password; } // Generates a human-readable timestamp from the Uni* stamp function generateDateTime ($time, $mode = '0') { // Is there cache? if (isset($GLOBALS[__FUNCTION__][$time][$mode])) { // Return it instead return $GLOBALS[__FUNCTION__][$time][$mode]; } // END - if // If the stamp is zero it mostly didn't "happen" if (($time == '0') || (is_null($time))) { // Never happend return '{--NEVER_HAPPENED--}'; } // END - if // Filter out numbers $timeSecured = bigintval($time); // Detect language switch (getLanguage()) { case 'de': // German date / time format switch ($mode) { case '0': $ret = date("d.m.Y \u\m H:i \U\h\\r", $timeSecured); break; case '1': $ret = strtolower(date('d.m.Y - H:i', $timeSecured)); break; case '2': $ret = date('d.m.Y|H:i', $timeSecured); break; case '3': $ret = date('d.m.Y', $timeSecured); break; case '4': $ret = date('d.m.Y|H:i:s', $timeSecured); break; case '5': $ret = date('d-m-Y (l-F-T)', $timeSecured); break; 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)); break; } // END - switch break; default: // Default is the US date / time format! switch ($mode) { case '0': $ret = date('r', $timeSecured); break; case '1': $ret = strtolower(date('Y-m-d - g:i A', $timeSecured)); break; case '2': $ret = date('y-m-d|H:i', $timeSecured); break; case '3': $ret = date('y-m-d', $timeSecured); break; case '4': $ret = date('d.m.Y|H:i:s', $timeSecured); break; case '5': $ret = date('d-m-Y (l-F-T)', $timeSecured); break; 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)); break; } // END - switch } // END - switch // Store it in cache $GLOBALS[__FUNCTION__][$time][$mode] = $ret; // Return result return $ret; } // Translates Y/N to yes/no function translateYesNo ($yn) { // Is it cached? if (!isset($GLOBALS[__FUNCTION__][$yn])) { // Default $GLOBALS[__FUNCTION__][$yn] = '??? (' . $yn . ')'; switch ($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 // Return it 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') { // First, cast all to double, due to PHP changes $dotted = (double) $dotted; // Default is 3 you can change this in admin area "Settings -> Misc Options" if (!isConfigEntrySet('max_comma')) { setConfigEntry('max_comma', 3); } // END - if // Use from config is default $maxComma = getConfig('max_comma'); // Use from parameter? if ($max > 0) { $maxComma = $max; } // END - if // Cut zeros off? if (($cut === TRUE) && ($max == '0')) { // Test for commata if in cut-mode $com = explode('.', $dotted); if (count($com) < 2) { // Don't display commatas even if there are none... ;-) $maxComma = '0'; } // END - if } // END - if // Debug log // Translate it now $translated = $dotted; switch (getLanguage()) { case 'de': // German language $translated = number_format($dotted, $maxComma, ',', '.'); break; default: // All others $translated = number_format($dotted, $maxComma, '.', ','); break; } // END - switch // Return translated value //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'dotted=' . $dotted . ',translated=' . $translated . ',maxComma=' . $maxComma); return $translated; } // Translate Uni*-like gender to human-readable function translateGender ($gender) { // Default $ret = '!' . $gender . '!'; // Male/female or company? switch ($gender) { case 'M': // Male case 'F': // Female case 'C': // Company // Use generic function $ret = translateGeneric('GENDER', $gender); break; default: // Please report bugs on unknown genders reportBug(__FUNCTION__, __LINE__, sprintf('Unknown gender %s detected.', $gender)); break; } // END - switch // Return translated gender return $ret; } // "Translates" the user status function translateUserStatus ($status) { // Default status is unknown if something goes through $ret = '{--ACCOUNT_STATUS_UNKNOWN--}'; // Generate message depending on status switch ($status) { case 'UNCONFIRMED': case 'CONFIRMED': case 'LOCKED': // Use generic function for all "normal" cases $ret = translateGeneric('ACCOUNT_STATUS', $status); break; case '': // Account deleted case NULL: // Account deleted $ret = '{--ACCOUNT_STATUS_DELETED--}'; break; default: // Please report all unknown status reportBug(__FUNCTION__, __LINE__, sprintf('Unknown status %s(%s) detected.', $status, gettype($status))); break; } // END - switch // Return it return $ret; } // "Translates" 'visible' and 'locked' to a CSS class function translateMenuVisibleLocked ($content, $prefix = '') { // Default is 'menu_unknown' $content['visible_css'] = $prefix . 'menu_unknown'; // Translate 'visible' and keep an eye on the prefix switch ($content['visible']) { case 'Y': // Should be visible $content['visible_css'] = $prefix . 'menu_visible'; break; case 'N': // Is invisible $content['visible_css'] = $prefix . 'menu_invisible'; break; default: // Please report this reportBug(__FUNCTION__, __LINE__, 'Unsupported visible value detected. content=
' . print_r($content, TRUE) . '
'); break; } // END - switch // Translate 'locked' and keep an eye on the prefix switch ($content['locked']) { case 'Y': // Should be locked, only admins can call this $content['locked_css'] = $prefix . 'menu_locked'; break; case 'N': // Is unlocked and visible to members/guests/sponsors $content['locked_css'] = $prefix . 'menu_unlocked'; break; default: // Please report this reportBug(__FUNCTION__, __LINE__, 'Unsupported locked value detected. content=
' . print_r($content, TRUE) . '
'); break; } // END - switch // Return the resulting array return $content; } // Generates an URL for the dereferer function generateDereferrerUrl ($url) { // Don't de-refer our own links! if ((!empty($url)) && (substr($url, 0, strlen(getUrl())) != getUrl())) { // Encode URL $encodedUrl = encodeString(compileUriCode($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($hash) . '&salt=' . substr($hash, 0, getSaltLength()) . '%}'; } // END - if // Return link return $url; } // Generates an URL for the frametester function generateFrametesterUrl ($url) { // Prepare frametester URL $frametesterUrl = sprintf('{%%url=modules.php?module=frametester&url=%s%%}', encodeString(compileUriCode($url)) ); // Return the new URL return $frametesterUrl; } // Count entries from e.g. a selection box function countSelection ($array) { // Integrity check if (!is_array($array)) { // Not an array! reportBug(__FUNCTION__, __LINE__, 'No array provided.'); } // END - if // Init count $ret = '0'; // Count all entries foreach ($array as $key => $selected) { // Is it checked? if (!empty($selected)) { // Yes, then count it $ret++; } // END - if } // END - foreach // Return counted selections return $ret; } // Generates a timestamp (some wrapper for mktime()) function makeTime ($hours, $minutes, $seconds, $stamp) { // Extract day, month and year from given timestamp $days = getDay($stamp); $months = getMonth($stamp); $years = getYear($stamp); // Create timestamp for wished time which depends on extracted date return mktime( $hours, $minutes, $seconds, $months, $days, $years ); } // Redirects to an URL and if neccessarry extends it with own base URL function redirectToUrl ($url, $allowSpider = TRUE) { // Is the output mode -2? if (isAjaxOutputMode()) { // This is always (!) an AJAX request and shall not be redirected return; } // END - if // Remove {%url= if (substr($url, 0, 6) == '{%url=') { $url = substr($url, 6, -2); } // END - if // Compile out codes eval('$url = "' . compileRawCode(encodeUrl($url)) . '";'); // Default 'rel' value is external, nofollow is evil from Google and hurts the Internet $rel = ' rel="external"'; // Is there internal or external URL? if (substr($url, 0, strlen(getUrl())) == getUrl()) { // Own (=internal) URL $rel = ''; } // END - if // Three different ways to debug... //* DEBUG: */ reportBug(__FUNCTION__, __LINE__, 'URL=' . $url); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'URL=' . $url); //* DEBUG: */ die($url); // 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)); } else { // Output error message loadPageHeader(); loadTemplate('redirect_url', FALSE, str_replace('&', '&', $url)); loadPageFooter(); } // Shut the mailer down here doShutdown(); } /************************************************************************ * * * Gaenderter Sortier-Algorythmus, $array wird nach dem Array (!) * * $a_sort sortiert: * * * * $array - Das 3-dimensionale Array, das paralell sortiert werden soll * * $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 * * * * $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) { $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) { // 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; } 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 ($match) { // We have found two different values, so let's sort whole array foreach ($temporaryArray as $sort_key => $sort_val) { $t = $temporaryArray[$sort_key][$key]; $temporaryArray[$sort_key][$key] = $temporaryArray[$sort_key][$key2]; $temporaryArray[$sort_key][$key2] = $t; unset($t); } // END - foreach } // END - if } // END - foreach } // END - foreach // Count one up $primary_key++; } // END - while // Write back sorted array $array = $temporaryArray; } // // Deprecated : $length (still has one reference in this function) // Optional : $extraData // function generateRandomCode ($length, $code, $userid, $extraData = '') { // Build server string $server = $_SERVER['PHP_SELF'] . getEncryptSeparator() . detectUserAgent() . getEncryptSeparator() . getenv('SERVER_SOFTWARE') . getEncryptSeparator() . detectRealIpAddress() . getEncryptSeparator() . detectRemoteAddr(); // Build key string $keys = getSiteKey() . getEncryptSeparator() . getDateKey(); if (isConfigEntrySet('secret_key')) { $keys .= getEncryptSeparator() . getSecretKey(); } // END - if if (isConfigEntrySet('file_hash')) { $keys .= getEncryptSeparator() . getFileHash(); } // END - if if (isConfigEntrySet('master_salt')) { $keys .= getEncryptSeparator() . getMasterSalt(); } // END - if // Build string from misc data $data = $code . getEncryptSeparator() . $userid . getEncryptSeparator() . $extraData; // Add more additional data if (isSessionVariableSet('u_hash')) { $data .= getEncryptSeparator() . getSession('u_hash'); } // END - if // Add referral id, language, theme and userid $data .= getEncryptSeparator() . determineReferralId(); $data .= getEncryptSeparator() . getLanguage(); $data .= getEncryptSeparator() . getCurrentTheme(); $data .= getEncryptSeparator() . getMemberId(); // Calculate number for generating the code $a = $code + getConfig('_ADD') - 1; if (isConfigEntrySet('master_salt')) { // Generate hash with master salt from modula of number with the prime number and other data $saltedHash = generateHash(($a % getPrime()) . getEncryptSeparator() . $server . getEncryptSeparator() . $keys . getEncryptSeparator() . $data . getEncryptSeparator() . getDateKey() . getEncryptSeparator() . $a, getMasterSalt()); } else { // Generate hash with "hash of site key" from modula of number with the prime number and other data $saltedHash = generateHash(($a % getPrime()) . getEncryptSeparator() . $server . getEncryptSeparator() . $keys . getEncryptSeparator() . $data . getEncryptSeparator() . getDateKey() . getEncryptSeparator() . $a, substr(sha1(getSiteKey()), 0, getSaltLength())); } // Create number from hash $rcode = hexdec(substr($saltedHash, getSaltLength(), 9)) / abs(getRandNo() - $a + sqrt(getConfig('_ADD'))) / pi(); // At least 10 numbers shall be secure enought! if (isExtensionActive('other')) { $len = getCodeLength(); } else { $len = $length; } // END - if // Smaller 1 is not okay if ($len < 1) { // Fix it to 10 $len = 10; } // END - if // Cut off requested counts of number, but skip first digit (which is mostly a zero) $return = substr($rcode, (strpos($rcode, '.') + 1), $len); // Done building code return $return; } // Does only allow numbers function bigintval ($num, $castValue = TRUE, $abortOnMismatch = TRUE) { //* DEBUG: */ debugOutput('[' . __FUNCTION__ . ':' . __LINE__ . '] ' . 'num=' . $num . ',castValue=' . intval($castValue) . ',abortOnMismatch=' . intval($abortOnMismatch) . ' - ENTERED!'); // Filter all non-number chars out, so only number chars will remain $ret = preg_replace('/[^0123456789]/', '', $num); // Shall we cast? 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))) { // Log the values reportBug(__FUNCTION__, __LINE__, 'Problem with number found. ret[' . gettype($ret) . ']=' . $ret . ', num[' . gettype($num) . ']='. $num); } // END - if // Return result //* DEBUG: */ debugOutput('[' . __FUNCTION__ . ':' . __LINE__ . '] ' . 'num=' . $num . ',castValue=' . intval($castValue) . ',abortOnMismatch=' . intval($abortOnMismatch) . ',ret=' . $ret . ' - EXIT!'); return $ret; } // 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(); // If so and if current time is before 02/29 and estimated time is after 02/29 then add 86400 seconds (one day) // 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 // First add years... $ret += $postData[$prefix . '_ye'] * (31536000 + $SWITCH); // Next months... 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; // Next days... $ret += $postData[$prefix . '_da'] * 86400; // Next hours... $ret += $postData[$prefix . '_ho'] * 3600; // Next minutes.. $ret += $postData[$prefix . '_mi'] * 60; // And at last seconds... $ret += $postData[$prefix . '_se']; // Return calculated value return $ret; } // 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); $ret = ''; foreach ($data as $k => $v) { if ($v > 0) { // Value is greater than 0 "eval" data to return string $ret .= ', ' . $v . ' {%pipe,translateTimeUnit=' . $k . '%}'; break; } // END - if } // END - foreach // Is something there? if (!empty($ret)) { // Remove leading commata and space $ret = substr($ret, 2); } else { // Zero seconds $ret = '0 {--TIME_UNIT_SECOND--}'; } // Return fancy time string return $ret; } // Taken from www.php.net isInStringIgnoreCase() user comments function isEmailValid ($email) { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'email=' . $email . ' - ENTERED!'); // Is there cache? if (!isset($GLOBALS[__FUNCTION__][$email])) { // Check first part of email address $first = '[-a-z0-9!#$%&\'*+/=?^_<{|}~]+(\.[-a-zA-Z0-9!#$%&\'*+/=?^_<{|}~]+)*'; // Check domain $domain = '[a-z0-9-]+(\.[a-z0-9-]{2,5})+'; // Generate pattern $regex = '@^' . $first . '\@' . $domain . '$@iU'; // Determine it $GLOBALS[__FUNCTION__][$email] = (($email != getMessage('DEFAULT_WEBMASTER')) && (preg_match($regex, $email))); } // END - if // Return check result //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'email=' . $email . ',isValid=' . intval($GLOBALS[__FUNCTION__][$email]) . ' - EXIT!'); return $GLOBALS[__FUNCTION__][$email]; } // Function taken from user comments on www.php.net / function isInStringIgnoreCase() 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); } // 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); } // END - if /* * If not installed, perform a simple test. Just make it sure there is always a * http:// or https:// in front of the URLs. */ return isUrlValidSimple($url); } // Generate a hash for extra-security for all passwords function generateHash ($plainText, $salt = '', $hash = TRUE) { // Debug output //* 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) { // Is plain password return md5($plainText); } else { // Is already a hash return $plainText; } } // END - if // Is an arry element missing here? if (!isConfigEntrySet('file_hash')) { // Stop here reportBug(__FUNCTION__, __LINE__, 'Missing file_hash in ' . __FUNCTION__ . '.'); } // END - if // 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(); // Build key string $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(); // 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: */ logDebugMessage(__FUNCTION__, __LINE__, 'SHA1=' . $sha1.' ('.strlen($sha1).')'); $sha1 = scrambleString($sha1); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Scrambled=' . $sha1.' ('.strlen($sha1).')'); //* DEBUG: */ $sha1b = descrambleString($sha1); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Descrambled=' . $sha1b.' ('.strlen($sha1b).')'); // Generate the password salt string $salt = substr($sha1, 0, getSaltLength()); //* DEBUG: */ debugOutput($salt.' ('.strlen($salt).')'); } else { // Use given salt //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'salt=' . $salt); $salt = substr($salt, 0, getSaltLength()); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'salt=' . $salt . '(' . strlen($salt) . '/' . getSaltLength() . ')'); // Sanity check on salt if (strlen($salt) != getSaltLength()) { // Not the same! reportBug(__FUNCTION__, __LINE__, 'salt length mismatch! (' . strlen($salt) . '/' . getSaltLength() . ')'); } // END - if } // Generate final hash (for debug output) $finalHash = $salt . sha1($salt . $plainText); // Debug output //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'finalHash('.strlen($finalHash).')=' . $finalHash); // Return hash return $finalHash; } // Scramble a string function scrambleString ($str) { // Init $scrambled = ''; // Final check, in case of failure it will return unscrambled string if (strlen($str) > 40) { // The string is to long return $str; } elseif ((strlen($str) == 40) && (getPassScramble() != '')) { // From database $scramble = getPassScramble(); } else { // Generate new numbers $scramble = genScrambleString(strlen($str)); } // Convert it into an array $scrambleNums = explode(':', $scramble); // Assert on both lengths assert(strlen($str) == count($scrambleNums)); // Scramble string here //* DEBUG: */ debugOutput('***Original=' . $str.'***
'); for ($idx = 0; $idx < strlen($str); $idx++) { // Get char on scrambled position $char = substr($str, $scrambleNums[$idx], 1); // Add it to final output string $scrambled .= $char; } // END - for // Return scrambled string //* DEBUG: */ debugOutput('***Scrambled=' . $scrambled.'***
'); return $scrambled; } // De-scramble a string scrambled by scrambleString() function descrambleString ($str) { // Scramble only 40 chars long strings if (strlen($str) != 40) { return $str; } // END - if // Load numbers from config $scrambleNums = explode(':', getPassScramble()); // Validate numbers if (count($scrambleNums) != 40) { return $str; } // END - if // Begin descrambling $orig = str_repeat(' ', 40); //* DEBUG: */ debugOutput('+++Scrambled=' . $str.'+++
'); for ($idx = 0; $idx < 40; $idx++) { $char = substr($str, $idx, 1); $orig = substr_replace($orig, $char, $scrambleNums[$idx], 1); } // END - for // Return scrambled string //* DEBUG: */ debugOutput('+++Original=' . $orig.'+++
'); return $orig; } // Generated a "string" for scrambling function genScrambleString ($len) { // Prepare array for the numbers $scrambleNumbers = array(); // First we need to setup randomized numbers from 0 to 31 for ($idx = 0; $idx < $len; $idx++) { // Generate number $rand = mt_rand(0, ($len - 1)); // Check for it by creating more numbers while (array_key_exists($rand, $scrambleNumbers)) { $rand = mt_rand(0, ($len - 1)); } // END - while // Add number $scrambleNumbers[$rand] = $rand; } // END - for // So let's create the string for storing it in database $scrambleString = implode(':', $scrambleNumbers); // Return it return $scrambleString; } // Generate an PGP-like encrypted hash of given hash for e.g. cookies function encodeHashForCookie ($passHash) { // Return vanilla password hash $ret = $passHash; // Is a secret key and master salt already initialized? //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, intval(isExtensionInstalled('sql_patches')) . '/' . intval(isConfigEntrySet('_PRIME')) . '/' . intval(isConfigEntrySet('secret_key')) . '/' . intval(isConfigEntrySet('master_salt'))); if ((isExtensionInstalled('sql_patches')) && (isConfigEntrySet('_PRIME')) && (isConfigEntrySet('secret_key')) && (isConfigEntrySet('master_salt'))) { // Only calculate when the secret key is generated //* 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 - EXIT!'); return $ret; } // END - if $newHash = ''; $start = 9; //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'passHash=' . $passHash . '(' . strlen($passHash) . ')'); for ($idx = 0; $idx < 20; $idx++) { // 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)); // 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__, '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 // 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 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'ret=' . $ret . ''); return $ret; } // Fix "deleted" cookies function fixDeletedCookies ($cookies) { // Is this an array with entries? if (isFilledArray($cookies)) { // Then check all cookies if they are marked as deleted! foreach ($cookies as $cookieName) { // Is the cookie set to "deleted"? if (getSession($cookieName) == 'deleted') { setSession($cookieName, ''); } // END - if } // END - foreach } // END - if } // Checks if a given apache module is loaded function isApacheModuleLoaded ($apacheModule) { // Check it and return result return (((function_exists('apache_get_modules')) && (in_array($apacheModule, apache_get_modules()))) || (!function_exists('apache_get_modules'))); } // Get current theme name function getCurrentTheme () { // The default theme is 'default'... ;-) $ret = 'default'; // Is there ext-theme installed and active or is 'theme' in URL or POST data? if (isExtensionActive('theme')) { // Call inner method $ret = getActualTheme(); } elseif ((isPostRequestElementSet('theme')) && (isThemeReadable(postRequestElement('theme')))) { // Use value from POST data $ret = postRequestElement('theme'); } elseif ((isGetRequestElementSet('theme')) && (isThemeReadable(getRequestElement('theme')))) { // Use value from GET data $ret = getRequestElement('theme'); } elseif ((isMailerThemeSet()) && (isThemeReadable(getMailerTheme()))) { // Use value from GET data $ret = getMailerTheme(); } // Return theme value return $ret; } // Generates an error code from given account status function generateErrorCodeFromUserStatus ($status = '') { // If no status is provided, use the default, cached if ((empty($status)) && (isMember())) { // Get user status $status = getUserData('status'); } // END - if // Default error code if unknown account status $errorCode = getCode('ACCOUNT_UNKNOWN'); // Generate constant name $codeName = sprintf('ACCOUNT_%s', strtoupper($status)); // Is the constant there? if (isCodeSet($codeName)) { // Then get it! $errorCode = getCode($codeName); } else { // Unknown status logDebugMessage(__FUNCTION__, __LINE__, sprintf('Unknown error status %s detected.', $status)); } // Return error code return $errorCode; } // Back-ported from the new ship-simu engine. :-) function debug_get_printable_backtrace () { // Init variable $backtrace = '
    '; // Get and prepare backtrace for output $backtraceArray = debug_backtrace(); foreach ($backtraceArray as $key => $trace) { if (!isset($trace['file'])) $trace['file'] = __FUNCTION__; if (!isset($trace['line'])) $trace['line'] = __LINE__; if (!isset($trace['args'])) $trace['args'] = array(); $backtrace .= '
  1. ' . basename($trace['file']) . ':' . $trace['line'] . ', ' . $trace['function'] . '(' . count($trace['args']) . ')
  2. '; } // END - foreach // Close it $backtrace .= '
'; // Return the backtrace return $backtrace; } // A mail-able backtrace function debug_get_mailable_backtrace () { // Init variable $backtrace = ''; // Get and prepare backtrace for output $backtraceArray = debug_backtrace(); foreach ($backtraceArray as $key => $trace) { if (!isset($trace['file'])) $trace['file'] = __FUNCTION__; if (!isset($trace['line'])) $trace['line'] = __LINE__; if (!isset($trace['args'])) $trace['args'] = array(); $backtrace .= ($key+1) . '.:' . basename($trace['file']) . ':' . $trace['line'] . ', ' . $trace['function'] . '(' . count($trace['args']) . ")\n"; } // END - foreach // Return the backtrace return $backtrace; } // Generates a ***weak*** seed function generateSeed () { return microtime(TRUE) * 100000; } // Converts a message code to a human-readable message function getMessageFromErrorCode ($code) { // Default is an unknown error code $message = '{%message,UNKNOWN_ERROR_CODE=' . $code . '%}'; // Which code is provided? switch ($code) { case '': // No error code is bad coding practice reportBug(__FUNCTION__, __LINE__, 'Empty error code supplied. Please fix your code.'); break; // All error messages case getCode('LOGOUT_DONE') : $message = '{--LOGOUT_DONE--}'; break; case getCode('LOGOUT_FAILED') : $message = '{--LOGOUT_FAILED--}'; break; case getCode('DATA_INVALID') : $message = '{--MAIL_DATA_INVALID--}'; break; case getCode('POSSIBLE_INVALID') : $message = '{--MAIL_POSSIBLE_INVALID--}'; break; case getCode('USER_404') : $message = '{--USER_404--}'; break; case getCode('STATS_404') : $message = '{--MAIL_STATS_404--}'; break; case getCode('ALREADY_CONFIRMED') : $message = '{--MAIL_ALREADY_CONFIRMED--}'; break; case getCode('BEG_SAME_AS_OWN') : $message = '{--BEG_SAME_USERID_AS_OWN--}'; break; case getCode('LOGIN_FAILED') : $message = '{--GUEST_LOGIN_FAILED_GENERAL--}'; break; case getCode('MODULE_MEMBER_ONLY') : $message = '{%message,MODULE_MEMBER_ONLY=' . getRequestElement('mod') . '%}'; break; case getCode('OVERLENGTH') : $message = '{--MEMBER_TEXT_OVERLENGTH--}'; break; case getCode('URL_FOUND') : $message = '{--MEMBER_TEXT_CONTAINS_URL--}'; break; case getCode('SUBJECT_URL') : $message = '{--MEMBER_SUBJECT_CONTAINS_URL--}'; break; case getCode('BLIST_URL') : $message = '{--MEMBER_URL_BLACK_LISTED--}
{--MEMBER_BLIST_TIME--}: ' . generateDateTime(getRequestElement('blist'), 0); break; case getCode('NO_RECS_LEFT') : $message = '{--MEMBER_SELECTED_MORE_RECS--}'; break; case getCode('INVALID_TAGS') : $message = '{--MEMBER_HTML_INVALID_TAGS--}'; break; case getCode('MORE_POINTS') : $message = '{--MEMBER_MORE_POINTS_NEEDED--}'; break; case getCode('MORE_RECEIVERS1') : $message = '{--MEMBER_ENTER_MORE_RECEIVERS--}'; break; case getCode('MORE_RECEIVERS2') : $message = '{--MEMBER_NO_MORE_RECEIVERS_FOUND--}'; break; case getCode('MORE_RECEIVERS3') : $message = '{--MEMBER_ENTER_MORE_MIN_RECEIVERS--}'; break; case getCode('INVALID_URL') : $message = '{--MEMBER_ENTER_INVALID_URL--}'; break; case getCode('NO_MAIL_TYPE') : $message = '{--MEMBER_NO_MAIL_TYPE_SELECTED--}'; break; case getCode('PROFILE_UPDATED') : $message = '{--MEMBER_PROFILE_UPDATED--}'; break; case getCode('UNKNOWN_REDIRECT') : $message = '{--UNKNOWN_REDIRECT_VALUE--}'; break; case getCode('WRONG_PASS') : $message = '{--LOGIN_WRONG_PASS--}'; break; case getCode('WRONG_ID') : $message = '{--LOGIN_WRONG_ID--}'; break; case getCode('ACCOUNT_LOCKED') : $message = '{--LOGIN_STATUS_LOCKED--}'; break; case getCode('ACCOUNT_UNCONFIRMED') : $message = '{--LOGIN_STATUS_UNCONFIRMED--}'; break; case getCode('COOKIES_DISABLED') : $message = '{--LOGIN_COOKIES_DISABLED--}'; break; case getCode('UNKNOWN_ERROR') : $message = '{--LOGIN_UNKNOWN_ERROR--}'; break; case getCode('UNKNOWN_STATUS') : $message = '{--LOGIN_UNKNOWN_STATUS--}'; break; case getCode('LOGIN_EMPTY_ID') : $message = '{--LOGIN_ID_IS_EMPTY--}'; break; case getCode('LOGIN_EMPTY_PASSWORD'): $message = '{--LOGIN_PASSWORD_IS_EMPTY--}'; break; case getCode('ERROR_MAILID'): if (isExtensionActive('mailid', TRUE)) { $message = '{--ERROR_CONFIRMING_MAIL--}'; } else { $message = '{%pipe,generateExtensionInactiveNotInstalledMessage=mailid%}'; } break; case getCode('EXTENSION_PROBLEM'): if (isGetRequestElementSet('ext')) { $message = '{%pipe,generateExtensionInactiveNotInstalledMessage=' . getRequestElement('ext') . '%}'; } else { $message = '{--EXTENSION_PROBLEM_UNSET_EXT--}'; } break; case getCode('URL_TIME_LOCK'): // Load timestamp from last order $content = getPoolDataFromId(getRequestElement('id')); // Translate it for templates $content['timestamp'] = generateDateTime($content['timestamp'], 1); // Calculate hours... $content['hours'] = round(getUrlTlock() / 60 / 60); // Minutes... $content['minutes'] = round((getUrlTlock() - $content['hours'] * 60 * 60) / 60); // And seconds $content['seconds'] = round(getUrlTlock() - $content['hours'] * 60 * 60 - $content['minutes'] * 60); // Finally contruct the message $message = loadTemplate('tlock_message', TRUE, $content); break; default: // Log missing/invalid error codes logDebugMessage(__FUNCTION__, __LINE__, getMessage('UNKNOWN_MAILID_CODE', $code)); break; } // END - switch // Return the message return $message; } // Function taken from user comments on www.php.net / function isInStringIgnoreCase() function isUrlValidSimple ($url) { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url . ' - ENTERED!'); // Prepare URL $url = secureString(str_replace(chr(92), '', compileRawCode(urldecode($url)))); // Allows http and https $http = "(http|https)+(:\/\/)"; // Test domain $domain1 = "([[:alnum:]]([-[:alnum:]])*\.)?([[:alnum:]][-[:alnum:]\.]*[[:alnum:]])(\.[[:alpha:]]{2,5})?"; // Test double-domains (e.g. .de.vu) $domain2 = "([-[:alnum:]])?(\.[[:alnum:]][-[:alnum:]\.]*[[:alnum:]])(\.[[:alpha:]]{2,5})(\.[[:alpha:]]{2,5})?"; // Test IP number $ip = "([[:digit:]]{1,3})\.([[:digit:]]{1,3})\.([[:digit:]]{1,3})\.([[:digit:]]{1,3})"; // ... directory $dir = "((/)+([-_\.[:alnum:]])+)*"; // ... page $page = "/([-_[:alnum:]][-\._[:alnum:]]*\.[[:alnum:]]{2,5})?"; // ... and the string after and including question character $getstring1 = "([\?/]([[:alnum:]][-\._%[:alnum:]]*(=)?([-\@\._:%[:alnum:]])+)(&([[:alnum:]]([-_%[:alnum:]])*(=)?([-\@\[\._:%[:alnum:]])+(\])*))*)?"; // Pattern for URLs like http://url/dir/doc.html?var=value $pattern['d1dpg1'] = $http . $domain1 . $dir . $page . $getstring1; $pattern['d2dpg1'] = $http . $domain2 . $dir . $page . $getstring1; $pattern['ipdpg1'] = $http . $ip . $dir . $page . $getstring1; // Pattern for URLs like http://url/dir/?var=value $pattern['d1dg1'] = $http . $domain1 . $dir.'/' . $getstring1; $pattern['d2dg1'] = $http . $domain2 . $dir.'/' . $getstring1; $pattern['ipdg1'] = $http . $ip . $dir.'/' . $getstring1; // Pattern for URLs like http://url/dir/page.ext $pattern['d1dp'] = $http . $domain1 . $dir . $page; $pattern['d1dp'] = $http . $domain2 . $dir . $page; $pattern['ipdp'] = $http . $ip . $dir . $page; // Pattern for URLs like http://url/dir $pattern['d1d'] = $http . $domain1 . $dir; $pattern['d2d'] = $http . $domain2 . $dir; $pattern['ipd'] = $http . $ip . $dir; // Pattern for URLs like http://url/?var=value $pattern['d1g1'] = $http . $domain1 . '/' . $getstring1; $pattern['d2g1'] = $http . $domain2 . '/' . $getstring1; $pattern['ipg1'] = $http . $ip . '/' . $getstring1; // Pattern for URLs like http://url?var=value $pattern['d1g12'] = $http . $domain1 . $getstring1; $pattern['d2g12'] = $http . $domain2 . $getstring1; $pattern['ipg12'] = $http . $ip . $getstring1; // Test all patterns $reg = FALSE; foreach ($pattern as $key => $pat) { // Debug regex? if (isDebugRegularExpressionEnabled()) { // @TODO Are these convertions still required? $pat = str_replace('.', '\.', $pat); $pat = str_replace('@', '\@', $pat); //* DEBUG: */ debugOutput($key . '= ' . $pat); } // END - if // Check if expression matches $reg = ($reg || preg_match(('^' . $pat . '^'), $url)); // Does it match? if ($reg === TRUE) { break; } // END - if } // END - foreach // Return true/false //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url . ',reg=' . intval($reg) . ' - EXIT!'); return $reg; } // 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) { // Initialize some variables $done = FALSE; $seek++; $next = -1; $found = FALSE; // Is the file there and read-/write-able? if ((isFileReadable($FQFN)) && (is_writeable($FQFN))) { $search = 'CFG: ' . $comment; $tmp = $FQFN . '.tmp'; // Open the source file $fp = fopen($FQFN, 'r') or reportBug(__FUNCTION__, __LINE__, 'Cannot read. file=' . basename($FQFN)); // Is the resource valid? if (is_resource($fp)) { // Open temporary file $fp_tmp = fopen($tmp, 'w') or reportBug(__FUNCTION__, __LINE__, 'Cannot write. tmp=' . basename($tmp) . ',file=' . $FQFN); // Is the resource again valid? if (is_resource($fp_tmp)) { // Mark temporary file as readable $GLOBALS['file_readable'][$tmp] = TRUE; // Start reading while (!feof($fp)) { // Read from source file $line = fgets($fp, 1024); if (isInString($search, $line)) { $next = '0'; $found = TRUE; } // END - if if ($next > -1) { if ($next === $seek) { $next = -1; $line = $prefix . $inserted . $suffix . PHP_EOL; } else { $next++; } } // END - if // Write to temp file fwrite($fp_tmp, $line); } // END - while // Close temp file fclose($fp_tmp); // Finished writing tmp file $done = TRUE; } // END - if // Close source file fclose($fp); if (($done === TRUE) && ($found === TRUE)) { // Copy back temporary->FQFN file and ... copyFileVerified($tmp, $FQFN, 0644); // ... delete temporay file :-) return removeFile($tmp); } 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 { // 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) . ',comment=' . $comment . ',prefix=' . $prefix . ',inserted=' . $inserted . ',seek=' . $seek); } // An error was detected! return FALSE; } // Debug message logger function logDebugMessage ($funcFile, $line, $message, $force=true) { // Is debug mode enabled? if ((isDebugModeEnabled()) || ($force === TRUE)) { // Remove CRLF $message = str_replace(array(chr(13), PHP_EOL), array('', ''), $message); // Log this message away appendLineToFile(getPath() . getCachePath() . 'debug.log', generateDateTime(time(), '4') . '|' . getModule(FALSE) . ':' . getExtraModule() . '|' . basename($funcFile) . '|' . $line . '|' . $message); } // END - if } // Handle extra values function handleExtraValues ($filterFunction, $value, $extraValue) { // Default is the value itself $ret = $value; // Is there a special filter function? 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 // Is there extra parameters here? if ((!is_null($extraValue)) && (!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 // 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 } 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; $test2 = ''; // Get last three chars $test = substr($id, -3); // Improved way of checking! :-) 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 . '_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', 'mn', 'we', 'da', 'ho', 'mi', 'se') as $rem) { unset($postData[$test . '_' . $rem]); } // END - foreach // Skip adding unset($id); $skip = TRUE; $test2 = $test; } // END - if } // END - if } // Reverts the german decimal comma into Computer decimal dot // OPPOMENT: translateComma() function convertCommaToDot ($str) { // Default float is not a float... ;-) $float = FALSE; // Which language is selected? switch (getLanguage()) { case 'de': // German language // Remove german thousand dots first $str = str_replace('.', '', $str); // Replace german commata with decimal dot and cast it $float = sprintf(getConfig('FLOAT_MASK'), str_replace(',', '.', $str)); break; default: // US and so on // Remove thousand commatas first and cast $float = sprintf(getConfig('FLOAT_MASK'), str_replace(',', '', $str)); break; } // END - switch // Return float return $float; } // Handle menu-depending failed logins and return the rendered content function handleLoginFailures ($accessLevel) { // Default output is empty ;-) $OUT = ''; // Is the session data set? if ((isSessionVariableSet('mailer_' . $accessLevel . '_failures')) && (isSessionVariableSet('mailer_' . $accessLevel . '_last_failure'))) { // Ignore zero values if (getSession('mailer_' . $accessLevel . '_failures') > 0) { // Non-guest has login failures found, get both data and prepare it for template //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'accessLevel=' . $accessLevel . '
'); $content = array( 'login_failures' => 'mailer_' . $accessLevel . '_failures', 'last_failure' => generateDateTime(getSession('mailer_' . $accessLevel . '_last_failure'), 2) ); // Load template $OUT = loadTemplate('login_failures', TRUE, $content); } // END - if // Reset session data setSession('mailer_' . $accessLevel . '_failures', ''); setSession('mailer_' . $accessLevel . '_last_failure', ''); } // END - if // Return rendered content return $OUT; } // Rebuild cache 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')) && (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); } // END - if // Include file given? if (!empty($inc)) { // Construct FQFN $inc = sprintf('inc/loader/load-%s.php', $inc); // Is the include there? if (isIncludeReadable($inc)) { // And rebuild it from scratch //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'inc=' . $inc . ' - LOADED!'); loadInclude($inc); } else { // 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) { // Default is 127.0.0.1 $address = '127.0.0.1'; // Is a proxy in use? if ((isset($_SERVER['HTTP_X_FORWARDED_FOR'])) && (!$remoteAddr)) { // Proxy was used $address = $_SERVER['HTTP_X_FORWARDED_FOR']; } elseif ((isset($_SERVER['HTTP_CLIENT_IP'])) && (!$remoteAddr)) { // Yet, another proxy $address = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['REMOTE_ADDR'])) { // The regular address when no proxy was used $address = $_SERVER['REMOTE_ADDR']; } // This strips out the real address from proxy output if (strstr($address, ',')) { $addressArray = explode(',', $address); $address = $addressArray[0]; } // END - if // Return the result return $address; } // Adds a bonus mail to the queue // This is a high-level function! 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']; } // END - if // Generate receiver list $receiver = generateReceiverList($data['cat'], $data['receiver'], $mode); // Receivers added? if (!empty($receiver)) { // Add bonus mail to queue addBonusMailToQueue( $data['subject'], $data['text'], $receiver, $data['points'], $data['seconds'], $data['url'], $data['cat'], $mode, $data['receiver'] ); // Mail inserted into bonus pool if ($output === TRUE) { displayMessage('{--ADMIN_BONUS_SEND--}'); } // END - if } elseif ($output === TRUE) { // More entered than can be reached! displayMessage('{--ADMIN_MORE_SELECTED--}'); } else { // Debug log logDebugMessage(__FUNCTION__, __LINE__, 'cat=' . $data['cat'] . ',receiver=' . $data['receiver'] . ',data=' . base64_encode(serialize($data)) . ' More selected, than available!'); } } // 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.) function doShutdown () { // Call the filter chain 'shutdown' runFilterChain('shutdown', NULL); // Check if link is up if (isSqlLinkUp()) { // Close link sqlCloseLink(__FUNCTION__, __LINE__); } elseif (!isInstaller()) { // No database link reportBug(__FUNCTION__, __LINE__, 'Database link is already down, while shutdown is running.'); } // Stop executing here exit; } // Init member id function initMemberId () { $GLOBALS['member_id'] = '0'; } // Setter for member id function setMemberId ($memberId) { // We should not set member id to zero if (!isValidId($memberId)) { reportBug(__FUNCTION__, __LINE__, 'Userid should not be set zero.'); } // END - if // Set it secured $GLOBALS['member_id'] = bigintval($memberId); } // Getter for member id or returns zero function getMemberId () { // Default member id $memberId = '0'; // Is the member id set? if (isMemberIdSet()) { // Then use it $memberId = $GLOBALS['member_id']; } // END - if // Return it return $memberId; } // Checks ether the member id is set function isMemberIdSet () { return (isset($GLOBALS['member_id'])); } // Setter for extra title function setExtraTitle ($extraTitle) { $GLOBALS['extra_title'] = $extraTitle; } // Getter for extra title function getExtraTitle () { // Is the extra title set? if (!isExtraTitleSet()) { // No, then abort here reportBug(__FUNCTION__, __LINE__, 'extra_title is not set!'); } // END - if // Return it return $GLOBALS['extra_title']; } // Checks if the extra title is set function isExtraTitleSet () { return ((isset($GLOBALS['extra_title'])) && (!empty($GLOBALS['extra_title']))); } /** * Reads a directory recursively by default and searches for files not matching * an exclusion pattern. You can now keep the exclusion pattern empty for reading * a whole directory. * * @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 $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 $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 = '', $withPrefixSuffix = TRUE) { // Add default entries we should always exclude array_unshift($excludeArray, '.', '..', '.svn', '.htaccess'); //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'baseDir=' . $baseDir . ',prefix=' . $prefix . ' - Entered!'); // Init found includes $foundMatches = array(); // Open directory $dirPointer = opendir(getPath() . $baseDir) or reportBug(__FUNCTION__, __LINE__, 'Cannot read directory ' . basename($baseDir) . '.'); // Read all entries while ($baseFile = readdir($dirPointer)) { // Exclude '.', '..' and entries in $excludeArray automatically if (in_array($baseFile, $excludeArray, TRUE)) { // Exclude them //* DEBUG: */ debugOutput('excluded=' . $baseFile); continue; } // END - if // Construct include filename and FQFN $fileName = $baseDir . $baseFile; $FQFN = getPath() . $fileName; // Remove double slashes $FQFN = str_replace('//', '/', $FQFN); // Check if the base filenname matches an exclusion pattern and if the pattern is not empty if ((!empty($excludePattern)) && (preg_match($excludePattern, $baseFile, $match))) { // Debug message //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'baseDir=' . $baseDir . ',baseFile=' . $baseFile . ',FQFN=' . $FQFN); // Exclude this one continue; } // END - if // Skip also files with non-matching prefix genericly 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)); // And skip further processing continue; } elseif (!isFilePrefixFound($baseFile, $prefix)) { // Skip this file //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Invalid prefix in file ' . $baseFile . ', prefix=' . $prefix); continue; } elseif ((!empty($suffix)) && (substr($baseFile, -(strlen($suffix . $extension)), (strlen($suffix . $extension))) != $suffix . $extension)) { // Skip wrong suffix as well //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Invalid suffix in file ' . $baseFile . ', suffix=' . $suffix); continue; } elseif (!isFileReadable($FQFN)) { // Not readable so skip it //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'File ' . $FQFN . ' is not readable!'); } elseif (filesize($FQFN) < 50) { // Might be deprecated //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'File ' . $FQFN . ' is to small (' . filesize($FQFN) . ')!'); continue; } elseif (($extension == '.php') && (filesize($FQFN) < 50)) { // This PHP script is deprecated //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'File ' . $FQFN . ' is a deprecated PHP script!'); continue; } // Get file' extension (last 4 chars) $fileExtension = substr($baseFile, -4, 4); // 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)))) { // 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) { // 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); } } else { // 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) || (empty($extension))) && (isFileReadable($FQFN))) { // Other, generic file found 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 // Close directory closedir($dirPointer); // Sort array sort($foundMatches); // Return array with include files //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, '- Left!'); return $foundMatches; } // Checks whether $prefix is found in $fileName function isFilePrefixFound ($fileName, $prefix) { // @TODO Find a way to cache this return (substr($fileName, 0, strlen($prefix)) == $prefix); } // Maps a module name into a database table name function mapModuleToTable ($moduleName) { // Map only these, still lame code... switch ($moduleName) { case 'index': // 'index' is the guest's menu $moduleName = 'guest'; break; case 'login': // ... and 'login' the member's menu $moduleName = 'member'; break; // Anything else will not be mapped, silently. } // END - switch // Return result return $moduleName; } // Add SQL debug data to array for later output 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'][$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'][$file][$line][$sqlString] = TRUE; // Generate record $record = array( 'num_rows' => sqlNumRows($result), 'affected' => sqlAffectedRows(), 'sql_str' => $sqlString, 'timing' => $timing, 'file' => basename($file), 'line' => $line ); // Add it array_push($GLOBALS['debug_sqls'], $record); } // Initializes the cache instance function initCacheInstance () { // Check for double-initialization if (isset($GLOBALS['cache_instance'])) { // This should not happen and must be fixed reportBug(__FUNCTION__, __LINE__, 'Double initialization of cache system detected. cache_instance[]=' . gettype($GLOBALS['cache_instance'])); } // END - if // Load include for CacheSystem class loadIncludeOnce('inc/classes/cachesystem.class.php'); // Initialize cache system only when it's needed $GLOBALS['cache_instance'] = new CacheSystem(); // Did it work? if ($GLOBALS['cache_instance']->getStatusCode() != 'done') { // Failed to initialize cache sustem reportBug(__FUNCTION__, __LINE__, 'Cache system returned with unexpected error. getStatusCode()=' . $GLOBALS['cache_instance']->getStatusCode()); } // END - if } // Getter for message from array or raw message function getMessageFromIndexedArray ($message, $pos, $array) { // Check if the requested message was found in array if (isset($array[$pos])) { // ... if yes then use it! $ret = $array[$pos]; } else { // ... else use default message $ret = $message; } // Return result return $ret; } // Convert ';' to ', ' for e.g. receiver list function convertReceivers ($old) { return str_replace(';', ', ', $old); } // Get a module from filename and access level function getModuleFromFileName ($file, $accessLevel) { // Default is 'invalid'; $modCheck = 'invalid'; // @TODO This is still very static, rewrite it somehow switch ($accessLevel) { case 'admin': $modCheck = 'admin'; break; case 'sponsor': case 'guest': case 'member': $modCheck = getModule(); break; default: // Unsupported file name / access level reportBug(__FUNCTION__, __LINE__, 'Unsupported file name=' . basename($file) . '/access level=' . $accessLevel); break; } // END - switch // Return result return $modCheck; } // Encodes an URL for adding session id, etc. function encodeUrl ($url, $outputMode = '0') { // Is there already have a PHPSESSID inside or view.php is called? Then abort here if ((isInStringIgnoreCase(session_name(), $url)) || (isRawOutputMode())) { // Raw output mode detected or session_name() found in URL return $url; } // END - if // Is there a valid session? if ((!isValidSession()) && (!isSpider())) { // Determine right separator $separator = '&'; if (!isInString('?', $url)) { // No question mark $separator = '?'; } // END - if // Then add it to URL $url .= $separator . session_name() . '=' . session_id(); } // 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://')) { // Add it $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()) { //* 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 //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'url=' . $url . ',outputMode=' . $outputMode); // Return the encoded URL return $url; } // Simple check for spider function isSpider () { // Get the UA and trim it down $userAgent = trim(detectUserAgent(TRUE)); // It should not be empty, if so it is better a browser if (empty($userAgent)) { // It is a browser that blocks its UA string return FALSE; } // END - if // Is it a spider? return ((isInStringIgnoreCase('spider', $userAgent)) || (isInStringIgnoreCase('slurp', $userAgent)) || (isInStringIgnoreCase('bot', $userAgent)) || (isInStringIgnoreCase('archiver', $userAgent))); } // Handles the braces [] of a field (e.g. value of 'name' attribute) function handleFieldWithBraces ($field) { // Are there braces [] at the end? if (substr($field, -2, 2) == '[]') { /* * Try to find one and replace it. I do it this way to allow easy * extending of this code. */ foreach (array('admin_list_builder_id_value') as $key) { /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key); // Is the cache entry set? if (isset($GLOBALS[$key])) { // Insert it $field = str_replace('[]', '[' . $GLOBALS[$key] . ']', $field); // And abort /* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'key=' . $key, 'field=' . $field); break; } // END - if } // END - foreach } // END - if // Return it return $field; } // Converts a zero or NULL to word 'NULL' function convertZeroToNull ($number) { // Is it a valid username? if (isValidNumber($number)) { // Always secure it $number = bigintval($number); } else { // Is not valid or zero $number = 'NULL'; } // Return it return $number; } // 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 (!isValidNumber($number)) { // Is not valid or zero $number = '0'; } // END - if // Return it return $number; } // Capitalizes a string with underscores, e.g.: some_foo_string will become SomeFooString // Note: This function is cached function capitalizeUnderscoreString ($str) { // Is there cache? if (!isset($GLOBALS[__FUNCTION__][$str])) { // Init target string $capitalized = ''; // Explode it with the underscore, but rewrite dashes to underscore before $strArray = explode('_', str_replace('-', '_', $str)); // "Walk" through all elements and make them lower-case but first upper-case foreach ($strArray as $part) { // Capitalize the string part $capitalized .= firstCharUpperCase($part); } // END - foreach // Store the converted string in cache array $GLOBALS[__FUNCTION__][$str] = $capitalized; } // END - if // Return cache return $GLOBALS[__FUNCTION__][$str]; } // Generate admin links for mail order // mailType can be: 'normal' or 'bonus' function generateAdminMailLinks ($mailType, $mailId) { // Init variables $OUT = ''; $table = ''; // Default column for mail status is 'data_type' // @TODO Rename column data_type to e.g. mail_status $statusColumn = 'data_type'; // Which mail do we have? switch ($mailType) { case 'bonus': // Bonus mail $table = 'bonus'; break; case 'normal': // Member mail $table = 'pool'; break; default: // Handle unsupported types logDebugMessage(__FUNCTION__, __LINE__, 'Unsupported mail type ' . $mailType . ' for mailId=' . $mailId . ' detected.'); $OUT = '
{%message,ADMIN_UNSUPPORTED_MAIL_TYPE_DETECTED=' . $mailType . '%}
'; break; } // END - switch // Is the mail type supported? if (!empty($table)) { // Query for the mail $result = sqlQueryEscaped("SELECT `id`, `%s` AS `mail_status` FROM `{?_MYSQL_PREFIX?}_%s` WHERE `id`=%s LIMIT 1", array( $statusColumn, $table, bigintval($mailId) ), __FILE__, __LINE__); // Is there one entry there? if (sqlNumRows($result) == 1) { // Load the entry $content = sqlFetchArray($result); // Add output and type $content['type'] = $mailType; $content['__output'] = ''; // Filter all data $content = runFilterChain('generate_admin_mail_links', $content); // Get output back $OUT = $content['__output']; } // END - if // Free result sqlFreeResult($result); } // END - if // Return generated HTML code return $OUT; } /** * Determine if a string can represent a number in hexadecimal * * @param $hex A string to check if it is hex-encoded * @return $foo True if the string is a hex, otherwise false * @author Marques Johansson * @link http://php.net/manual/en/function.http-chunked-decode.php#89786 */ function isHexadecimal ($hex) { // Make it lowercase $hex = strtolower(trim(ltrim($hex, '0'))); // Fix empty strings to zero if (empty($hex)) { $hex = 0; } // END - if // Simply compare decode->encode result with original return ($hex == dechex(hexdec($hex))); } /** * 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. * * @param $str String to overwork * @return $str Overworked string */ function replaceReturnNewLine ($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 // explode(), but appending the delimiter again function stringToArray ($delimiter, $string) { // Init array $strArray = array(); // "Walk" through all entries foreach (explode($delimiter, $string) as $split) { // Append the delimiter and add it to the array array_push($strArray, $split . $delimiter); } // END - foreach // Return array return $strArray; } // Detects the prefix 'mb_' if a multi-byte string is given function detectMultiBytePrefix ($str) { // Default is without multi-byte $mbPrefix = ''; // Detect multi-byte (strictly) if (mb_detect_encoding($str, 'auto', TRUE) !== FALSE) { // With multi-byte encoded string $mbPrefix = 'mb_'; } // END - if // Return the prefix return $mbPrefix; } // 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(); // Now check all entries 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) { // Add the found key array_push($keys, $key); } // END - if } // END - foreach // Return the array return $keys; } // Determines database column name from given subject and locked function determinePointsColumnFromSubjectLocked ($subject, $locked) { //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'subject=' . $subject . ',locked=' . intval($locked) . ' - ENTERED!'); // Default is 'normal' points $pointsColumn = 'points'; // Which points, locked or normal? if ($locked === TRUE) { $pointsColumn = 'locked_points'; } // END - if // Prepare array for filter $filterData = array( 'subject' => $subject, 'locked' => $locked, 'column' => $pointsColumn ); // Run the filter $filterData = runFilterChain('determine_points_column_name', $filterData); // Extract column name from array $pointsColumn = $filterData['column']; // Return it //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'subject=' . $subject . ',locked=' . intval($locked) . ',pointsColumn=' . $pointsColumn . ' - EXIT!'); return $pointsColumn; } // Converts a boolean variable into 'Y' for true and 'N' for false function convertBooleanToYesNo ($boolean) { // Default is 'N' $converted = 'N'; if ($boolean === TRUE) { // Set 'Y' $converted = 'Y'; } // END - if // Return it return $converted; } // "Translates" 'true' to true and 'false' to false function convertStringToBoolean ($str) { // Debug message (to measure how often this function is called) //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'str=' . $str); // Is there cache? if (!isset($GLOBALS[__FUNCTION__][$str])) { // Trim it lower-case for validation $strTrimmed = trim(strtolower($str)); // Is it valid? if (!in_array($strTrimmed, array('true', 'false'))) { // Not valid! reportBug(__FUNCTION__, __LINE__, 'str=' . $str . '(' . $strTrimmed . ') is not true/false'); } // END - if // Determine it $GLOBALS[__FUNCTION__][$str] = ($strTrimmed == 'true'); } // END - if // Return cache return $GLOBALS[__FUNCTION__][$str]; } /** * "Makes" a variable in given string parseable, this function will throw an * error if the first character is not a dollar sign. * * @param $varString String which contains a variable * @return $return String with added single quotes for better parsing */ function makeParseableVariable ($varString) { // The first character must be a dollar sign if (substr($varString, 0, 1) != '$') { // Please report this reportBug(__FUNCTION__, __LINE__, 'varString=' . $varString . ' - No dollar sign detected, will not parse it.'); } // END - if // Is there cache? if (!isset($GLOBALS[__FUNCTION__][$varString])) { // Snap them in, if [,] are there $GLOBALS[__FUNCTION__][$varString] = str_replace(array('[', ']'), array("['", "']"), $varString); } // END - if // Return cache return $GLOBALS[__FUNCTION__][$varString]; } // "Getter" for random TAN function getRandomTan () { // Generate one return mt_rand(0, 99999); } // Removes any : from subject function removeDoubleDotFromSubject ($subject) { // Remove it $subjectArray = explode(':', $subject); $subject = $subjectArray[0]; unset($subjectArray); // Return it return $subject; } // Adds a given entry to the database function memberAddEntries ($tableName, $columns = array(), $filterFunctions = array(), $extraValues = array(), $timeColumns = array(), $columnIndex = NULL) { // Is it a member? if (!isMember()) { // Then abort here return FALSE; } // END - if // Set POST data generic userid setPostRequestElement('userid', getMemberId()); // Call inner function doGenericAddEntries($tableName, $columns, $filterFunctions, $extraValues, $timeColumns, $columnIndex); // Entry has been added? if ((!ifSqlHasZeroAffectedRows()) && ($GLOBALS['__XML_PARSE_RESULT'] === TRUE)) { // Display success message displayMessage('{--MEMBER_ENTRY_ADDED--}'); } else { // Display failed message displayMessage('{--MEMBER_ENTRY_NOT_ADDED--}'); } } // 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(), $content = array()) { // $tableName must be an array if ((!is_array($tableName)) || (count($tableName) != 1)) { // No tableName specified reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn); } elseif (!is_array($idColumn)) { // $idColumn is no array reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn); } elseif (!is_array($userIdColumn)) { // $userIdColumn is no array reportBug(__FUNCTION__, __LINE__, 'userIdColumn[]=' . gettype($userIdColumn) . '!=array: userIdColumn=' . $userIdColumn); } elseif (!is_array($editNow)) { // $editNow is no array reportBug(__FUNCTION__, __LINE__, 'editNow[]=' . gettype($editNow) . '!=array: userIdColumn=' . $userIdColumn); } // END - if // Shall we change here or list for editing? if ($editNow[0] === TRUE) { // Add generic userid field setPostRequestElement('userid', getMemberId()); // Call generic change method $affected = doGenericEditEntriesConfirm($tableName, $columns, $filterFunctions, $extraValues, $timeColumns, $editNow, $idColumn, $userIdColumn, $rawUserId, $cacheFiles, 'mem_edit'); // Was this fine? if ($affected == countPostSelection($idColumn[0])) { // All deleted displayMessage('{--MEMBER_ALL_ENTRIES_EDITED--}'); } else { // Some are still there :( displayMessage(sprintf(getMessage('MEMBER_SOME_ENTRIES_NOT_EDITED'), $affected, countPostSelection($idColumn[0]))); } } else { // List for editing 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(), $content = array()) { // Do this only for members assert(isMember()); // $tableName must be an array if ((!is_array($tableName)) || (count($tableName) != 1)) { // No tableName specified reportBug(__FUNCTION__, __LINE__, 'tableName is not given. Please fix your XML,tableName[]=' . gettype($tableName) . '!=array: userIdColumn=' . $userIdColumn); } elseif (!is_array($idColumn)) { // $idColumn is no array reportBug(__FUNCTION__, __LINE__, 'idColumn[]=' . gettype($idColumn) . '!=array: userIdColumn=' . $userIdColumn); } elseif (!is_array($userIdColumn)) { // $userIdColumn is no array reportBug(__FUNCTION__, __LINE__, 'userIdColumn[]=' . gettype($userIdColumn) . '!=array: userIdColumn=' . $userIdColumn); } elseif (!is_array($deleteNow)) { // $deleteNow is no array reportBug(__FUNCTION__, __LINE__, 'deleteNow[]=' . gettype($deleteNow) . '!=array: userIdColumn=' . $userIdColumn); } // END - if // Shall we delete here or list for deletion? if ($deleteNow[0] === TRUE) { // Add generic userid field setPostRequestElement('userid', getMemberId()); // Call generic function $affected = doGenericDeleteEntriesConfirm($tableName, $columns, $filterFunctions, $extraValues, $deleteNow, $idColumn, $userIdColumn, $rawUserId, $cacheFiles, 'mem_delete'); // Was this fine? if ($affected == countPostSelection($idColumn[0])) { // All deleted displayMessage('{--MEMBER_ALL_ENTRIES_REMOVED--}'); } else { // Some are still there :( 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, $rawUSerId, $content); } } // Build a special template list // @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, $content); } // Checks whether given address is IPv4 function isIp4AddressValid ($address) { // Is there cache? if (!isset($GLOBALS[__FUNCTION__][$address])) { // Determine it ... $GLOBALS[__FUNCTION__][$address] = preg_match('/((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9]))/', $address); } // END - if // Return cache 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 // Make sure 'length modulo 2' = 0 assert((strlen($hex) % 2) == 0); // Return it return $hex; } // ---------------------------------------------------------------------------- // "Translatation" functions for points_data table // ---------------------------------------------------------------------------- // Translates generically some data into a target string function translateGeneric ($messagePrefix, $data, $messageSuffix = '') { // Is the method null or empty? if (is_null($data)) { // Is NULL $data = 'NULL'; } elseif (empty($data)) { // Is empty (string) $data = 'EMPTY'; } // END - if // Default column name is unknown $return = '{%message,' . $messagePrefix . '_UNKNOWN' . $messageSuffix . '=' . strtoupper($data) . '%}'; // Construct message id $messageId = $messagePrefix . '_' . strtoupper($data) . $messageSuffix; // Is it there? if (isMessageIdValid($messageId)) { // Then use it as message string $return = '{--' . $messageId . '--}'; } // END - if // Return the column name return $return; } // Translates points subject to human-readable function translatePointsSubject ($subject) { // Remove any :x $subject = removeDoubleDotFromSubject($subject); // Return it return translateGeneric('POINTS_SUBJECT', $subject); } // "Translates" given points account type function translatePointsAccountType ($accountType) { // Return it return translateGeneric('POINTS_ACCOUNT_TYPE', $accountType); } // "Translates" given points "locked mode" function translatePointsLockedMode ($lockedMode) { // Return it return translateGeneric('POINTS_LOCKED_MODE', $lockedMode); } // "Translates" given points payment method function translatePointsPaymentMethod ($paymentMethod) { // Return it return translateGeneric('POINTS_PAYMENT_METHOD', $paymentMethod); } // "Translates" given points account provider function translatePointsAccountProvider ($accountProvider) { // Return it return translateGeneric('POINTS_ACCOUNT_PROVIDER', $accountProvider); } // "Translates" given points notify recipient function translatePointsNotifyRecipient ($notifyRecipient) { // Return it return translateGeneric('POINTS_NOTIFY_RECIPIENT', $notifyRecipient); } // "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); } // "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) { $trans_tbl = get_html_translation_table(HTML_ENTITIES); $trans_tbl = array_flip($trans_tbl); return strtr($string, $trans_tbl); } } // 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]; } // 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) // Credits: shaunspiller at spammenot-gmail dot com ( http://de.php.net/dl#88566 ) function loadLibrary ($n, $f = NULL) { return extension_loaded($n) or 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) . '--}'; } // [EOF] ?>