X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FGlobalFunctions.php;h=ddb39ffb919570b2036fd3b81e26663be36bff82;hb=c0401123da9d021f4cfe2244bbd349bddeb02be8;hp=af18dfcd83d5d0e947414218575646c6b05b661c;hpb=32c223e2a137eaf57e779796f507542cacdc51a3;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index af18dfcd83..ddb39ffb91 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -1,5 +1,4 @@ = 3) { - $end = func_get_arg(2); - return join("",array_slice($ar[0],$start,$end)); - } else { - return join("",array_slice($ar[0],$start)); + function mb_substr( $str, $start ) { + preg_match_all( '/./us', $str, $ar ); + + if( func_num_args() >= 3 ) { + $end = func_get_arg( 2 ); + return join( '', array_slice( $ar[0], $start, $end ) ); + } else { + return join( '', array_slice( $ar[0], $start ) ); } } } -/** - * html_entity_decode exists in PHP 4.3.0+ but is FATALLY BROKEN even then, - * with no UTF-8 support. - * - * @param string $string String having html entities - * @param $quote_style - * @param string $charset Encoding set to use (default 'ISO-8859-1') - */ -function do_html_entity_decode( $string, $quote_style=ENT_COMPAT, $charset='ISO-8859-1' ) { - static $trans; - if( !isset( $trans ) ) { - $trans = array_flip( get_html_translation_table( HTML_ENTITIES, $quote_style ) ); - # Assumes $charset will always be the same through a run, and only understands - # utf-8 or default. Note - mixing latin1 named entities and unicode numbered - # ones will result in a bad link. - if( strcasecmp( 'utf-8', $charset ) == 0 ) { - $trans = array_map( 'utf8_encode', $trans ); - } +if( !function_exists( 'floatval' ) ) { + /** + * First defined in PHP 4.2.0 + * @param mixed $var; + * @return float + */ + function floatval( $var ) { + return (float)$var; } - return strtr( $string, $trans ); } - /** * Where as we got a random seed * @var bool $wgTotalViews @@ -126,42 +113,19 @@ function wfSeedRandom() { } /** - * Generates a URL from a URL-encoded title and a query string - * Title::getLocalURL() is preferred in most cases + * Get a random decimal value between 0 and 1, in a way + * not likely to give duplicate values for any realistic + * number of articles. * - * @param string $a URL encoded title - * @param string $q URL (default '') - */ -function wfLocalUrl( $a, $q = '' ) { - global $wgServer, $wgScript, $wgArticlePath; - - $a = str_replace( ' ', '_', $a ); - - if ( '' == $a ) { - if( '' == $q ) { - $a = $wgScript; - } else { - $a = $wgScript.'?'.$q; - } - } else if ( '' == $q ) { - $a = str_replace( '$1', $a, $wgArticlePath ); - } else if ($wgScript != '' ) { - $a = "{$wgScript}?title={$a}&{$q}"; - } else { //XXX hackish solution for toplevel wikis - $a = "/{$a}?{$q}"; - } - return $a; -} - -/** - * @todo document - * @param string $a URL encoded title - * @param string $q URL (default '') + * @return string */ -function wfLocalUrlE( $a, $q = '' ) -{ - return htmlspecialchars( wfLocalUrl( $a, $q ) ); - # die( "Call to obsolete function wfLocalUrlE()" ); +function wfRandom() { + # The maximum random value is "only" 2^31-1, so get two random + # values to reduce the chance of dupes + $max = mt_getrandmax(); + $rand = number_format( (mt_rand() * $max + mt_rand()) + / $max / $max, 12, '.', '' ); + return $rand; } /** @@ -180,95 +144,17 @@ function wfUrlencode ( $s ) { } /** - * Return the UTF-8 sequence for a given Unicode code point. - * Currently doesn't work for values outside the Basic Multilingual Plane. - * - * @param string $codepoint UTF-8 code point. - * @return string HTML UTF-8 Entitie such as 'Ӓ'. - */ -function wfUtf8Sequence( $codepoint ) { - if($codepoint < 0x80) return chr($codepoint); - if($codepoint < 0x800) return chr($codepoint >> 6 & 0x3f | 0xc0) . - chr($codepoint & 0x3f | 0x80); - if($codepoint < 0x10000) return chr($codepoint >> 12 & 0x0f | 0xe0) . - chr($codepoint >> 6 & 0x3f | 0x80) . - chr($codepoint & 0x3f | 0x80); - if($codepoint < 0x110000) return chr($codepoint >> 18 & 0x07 | 0xf0) . - chr($codepoint >> 12 & 0x3f | 0x80) . - chr($codepoint >> 6 & 0x3f | 0x80) . - chr($codepoint & 0x3f | 0x80); - - # There should be no assigned code points outside this range, but... - return "&#$codepoint;"; -} - -/** - * Converts numeric character entities to UTF-8 - * - * @param string $string String to convert. - * @return string Converted string. - */ -function wfMungeToUtf8( $string ) { - global $wgInputEncoding; # This is debatable - #$string = iconv($wgInputEncoding, "UTF-8", $string); - $string = preg_replace ( '/&#([0-9]+);/e', 'wfUtf8Sequence($1)', $string ); - $string = preg_replace ( '/&#x([0-9a-f]+);/ie', 'wfUtf8Sequence(0x$1)', $string ); - # Should also do named entities here - return $string; -} - -/** - * Converts a single UTF-8 character into the corresponding HTML character - * entity (for use with preg_replace_callback) + * Sends a line to the debug log if enabled or, optionally, to a comment in output. + * In normal operation this is a NOP. * - * @param array $matches + * Controlling globals: + * $wgDebugLogFile - points to the log file + * $wgProfileOnly - if set, normal debug messages will not be recorded. + * $wgDebugRawPage - if false, 'action=raw' hits will not result in debug output. + * $wgDebugComments - if on, some debug items may appear in comments in the HTML output. * - */ -function wfUtf8Entity( $matches ) { - $char = $matches[0]; - # Find the length - $z = ord( $char{0} ); - if ( $z & 0x80 ) { - $length = 0; - while ( $z & 0x80 ) { - $length++; - $z <<= 1; - } - } else { - $length = 1; - } - - if ( $length != strlen( $char ) ) { - return ''; - } - if ( $length == 1 ) { - return $char; - } - - # Mask off the length-determining bits and shift back to the original location - $z &= 0xff; - $z >>= $length; - - # Add in the free bits from subsequent bytes - for ( $i=1; $i<$length; $i++ ) { - $z <<= 6; - $z |= ord( $char{$i} ) & 0x3f; - } - - # Make entity - return "&#$z;"; -} - -/** - * Converts all multi-byte characters in a UTF-8 string into the appropriate - * character entity - */ -function wfUtf8ToHTML($string) { - return preg_replace_callback( '/[\\xc0-\\xfd][\\x80-\\xbf]*/', 'wfUtf8Entity', $string ); -} - -/** - * @todo document + * @param string $text + * @param bool $logonly Set true to avoid appearing in HTML when $wgDebugComments is set */ function wfDebug( $text, $logonly = false ) { global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly, $wgDebugRawPage; @@ -282,7 +168,26 @@ function wfDebug( $text, $logonly = false ) { $wgOut->debug( $text ); } if ( '' != $wgDebugLogFile && !$wgProfileOnly ) { - error_log( $text, 3, $wgDebugLogFile ); + # Strip unprintables; they can switch terminal modes when binary data + # gets dumped, which is pretty annoying. + $text = preg_replace( '![\x00-\x08\x0b\x0c\x0e-\x1f]!', ' ', $text ); + @error_log( $text, 3, $wgDebugLogFile ); + } +} + +/** + * Send a line to a supplementary debug log file, if configured, or main debug log if not. + * $wgDebugLogGroups[$logGroup] should be set to a filename to send to a separate log. + * @param string $logGroup + * @param string $text + */ +function wfDebugLog( $logGroup, $text ) { + global $wgDebugLogGroups, $wgDBname; + if( $text{strlen( $text ) - 1} != "\n" ) $text .= "\n"; + if( isset( $wgDebugLogGroups[$logGroup] ) ) { + @error_log( "$wgDBname: $text", 3, $wgDebugLogGroups[$logGroup] ); + } else { + wfDebug( $text, true ); } } @@ -320,7 +225,7 @@ function logProfilingData() { $forward .= ' from ' . $_SERVER['HTTP_FROM']; if( $forward ) $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})"; - if($wgUser->getId() == 0) + if( $wgUser->isAnon() ) $forward .= ' anon'; $log = sprintf( "%s\t%04.3f\t%s\n", gmdate( 'YmdHis' ), $elapsed, @@ -338,57 +243,49 @@ function logProfilingData() { * @return bool */ function wfReadOnly() { - global $wgReadOnlyFile; + global $wgReadOnlyFile, $wgReadOnly; + if ( $wgReadOnly ) { + return true; + } if ( '' == $wgReadOnlyFile ) { return false; } - return is_file( $wgReadOnlyFile ); + + // Set $wgReadOnly and unset $wgReadOnlyFile, for faster access next time + if ( is_file( $wgReadOnlyFile ) ) { + $wgReadOnly = file_get_contents( $wgReadOnlyFile ); + } else { + $wgReadOnly = false; + } + $wgReadOnlyFile = ''; + return $wgReadOnly; } -/** - * Keys strings for replacement - * @global array $wgReplacementKeys - */ -$wgReplacementKeys = array( '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9' ); /** - * Get a message from anywhere, for the UI elements + * Get a message from anywhere, for the current user language + * + * @param string */ function wfMsg( $key ) { - global $wgRequest; - - if ( $wgRequest->getVal( 'debugmsg' ) ) { - if ( $key == 'linktrail' /* a special case where we want to return something specific */ ) - return "/^()(.*)$/sD"; - else - return $key; - } $args = func_get_args(); - if ( count( $args ) ) { - array_shift( $args ); - } + array_shift( $args ); return wfMsgReal( $key, $args, true ); } /** - * Get a message from anywhere, for the content + * Get a message from anywhere, for the current global language */ function wfMsgForContent( $key ) { - global $wgRequest; - if ( $wgRequest->getVal( 'debugmsg' ) ) { - if ( $key == 'linktrail' /* a special case where we want to return something specific */ ) - return "/^()(.*)$/sD"; - else - return $key; - } + global $wgForceUIMsgAsContentMsg; $args = func_get_args(); - if ( count( $args ) ) { - array_shift( $args ); - } - return wfMsgReal( $key, $args, true, true ); - - + array_shift( $args ); + $forcontent = true; + if( is_array( $wgForceUIMsgAsContentMsg ) && + in_array( $key, $wgForceUIMsgAsContentMsg ) ) + $forcontent = false; + return wfMsgReal( $key, $args, true, $forcontent ); } /** @@ -396,9 +293,7 @@ function wfMsgForContent( $key ) { */ function wfMsgNoDB( $key ) { $args = func_get_args(); - if ( count( $args ) ) { - array_shift( $args ); - } + array_shift( $args ); return wfMsgReal( $key, $args, false ); } @@ -406,12 +301,14 @@ function wfMsgNoDB( $key ) { * Get a message from the language file, for the content */ function wfMsgNoDBForContent( $key ) { - + global $wgForceUIMsgAsContentMsg; $args = func_get_args(); - if ( count( $args ) ) { - array_shift( $args ); - } - return wfMsgReal( $key, $args, false, true ); + array_shift( $args ); + $forcontent = true; + if( is_array( $wgForceUIMsgAsContentMsg ) && + in_array( $key, $wgForceUIMsgAsContentMsg ) ) + $forcontent = false; + return wfMsgReal( $key, $args, false, $forcontent ); } @@ -419,42 +316,110 @@ function wfMsgNoDBForContent( $key ) { * Really get a message */ function wfMsgReal( $key, $args, $useDB, $forContent=false ) { - global $wgReplacementKeys, $wgParser, $wgMsgParserOptions; - - if($forContent) { - global $wgMessageCache, $wgContLang; - $cache = &$wgMessageCache; - $lang = &$wgContLang; - } - else { - global $wgLang; - $cache = false; - $lang = &$wgLang; - } - - $fname = 'wfMsg'; + $fname = 'wfMsgReal'; wfProfileIn( $fname ); - if ( is_object($cache) ) { - $message = $cache->get( $key, $useDB ); - } elseif (is_object($lang)) { - $message = $lang->getMessage( $key ); + + $message = wfMsgGetKey( $key, $useDB, $forContent ); + $message = wfMsgReplaceArgs( $message, $args ); + wfProfileOut( $fname ); + return $message; +} + +/** + * Fetch a message string value, but don't replace any keys yet. + * @param string $key + * @param bool $useDB + * @param bool $forContent + * @return string + * @access private + */ +function wfMsgGetKey( $key, $useDB, $forContent = false ) { + global $wgParser, $wgMsgParserOptions; + global $wgContLang, $wgLanguageCode; + global $wgMessageCache, $wgLang; + + if( is_object( $wgMessageCache ) ) { + $message = $wgMessageCache->get( $key, $useDB, $forContent ); + } else { + if( $forContent ) { + $lang = &$wgContLang; + } else { + $lang = &$wgLang; + } + + wfSuppressWarnings(); + + if( is_object( $lang ) ) { + $message = $lang->getMessage( $key ); + } else { + $message = ''; + } + wfRestoreWarnings(); + if(!$message) + $message = Language::getMessage($key); if(strstr($message, '{{' ) !== false) { $message = $wgParser->transformMsg($message, $wgMsgParserOptions); } - } else { - wfDebug( "No language object when getting $key\n" ); - $message = "<$key>"; } + return $message; +} + +/** + * Replace message parameter keys on the given formatted output. + * + * @param string $message + * @param array $args + * @return string + * @access private + */ +function wfMsgReplaceArgs( $message, $args ) { + static $replacementKeys = array( '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9' ); + + # Fix windows line-endings + # Some messages are split with explode("\n", $msg) + $message = str_replace( "\r", '', $message ); # Replace arguments if( count( $args ) ) { - $message = str_replace( $wgReplacementKeys, $args, $message ); + $message = str_replace( $replacementKeys, $args, $message ); } - wfProfileOut( $fname ); return $message; } +/** + * Return an HTML-escaped version of a message. + * Parameter replacements, if any, are done *after* the HTML-escaping, + * so parameters may contain HTML (eg links or form controls). Be sure + * to pre-escape them if you really do want plaintext, or just wrap + * the whole thing in htmlspecialchars(). + * + * @param string $key + * @param string ... parameters + * @return string + */ +function wfMsgHtml( $key ) { + $args = func_get_args(); + array_shift( $args ); + return wfMsgReplaceArgs( htmlspecialchars( wfMsgGetKey( $key, true ) ), $args ); +} +/** + * Return an HTML version of message + * Parameter replacements, if any, are done *after* parsing the wiki-text message, + * so parameters may contain HTML (eg links or form controls). Be sure + * to pre-escape them if you really do want plaintext, or just wrap + * the whole thing in htmlspecialchars(). + * + * @param string $key + * @param string ... parameters + * @return string + */ +function wfMsgWikiHtml( $key ) { + global $wgOut; + $args = func_get_args(); + array_shift( $args ); + return wfMsgReplaceArgs( $wgOut->parse( wfMsgGetKey( $key, true ), /* can't be set to false */ true ), $args ); +} /** * Just like exit() but makes a note of it. @@ -501,32 +466,63 @@ function wfErrorExit() { function wfDebugDieBacktrace( $msg = '' ) { global $wgCommandLineMode; - if ( function_exists( 'debug_backtrace' ) ) { + $backtrace = wfBacktrace(); + if ( $backtrace !== false ) { if ( $wgCommandLineMode ) { - $msg .= "\nBacktrace:\n"; + $msg .= "\nBacktrace:\n$backtrace"; } else { - $msg .= "\n

Backtrace:

\n