X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FGlobalFunctions.php;h=0688d4a086b5cb1d3c4f809d45c6bca2eb70ed4d;hb=d42c91a23cf7c59a3cc1cc88438d087ca0d8bf6b;hp=81739bafef683dee053dd95cd33e15ffce7635d3;hpb=5104b9f29ce63b47b6e889543407dd6148b6502f;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 81739bafef..0688d4a086 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -1,30 +1,50 @@ = 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 ); + } + } + return strtr( $string, $trans ); +} + + +/** + * Where as we got a random seed + * @var bool $wgTotalViews + */ $wgRandomSeeded = false; -function wfSeedRandom() -{ +/** + * Seed Mersenne Twister + * Only necessary in PHP < 4.2.0 + * + * @return bool + */ +function wfSeedRandom() { global $wgRandomSeeded; - if ( ! $wgRandomSeeded ) { + if ( ! $wgRandomSeeded && version_compare( phpversion(), '4.2.0' ) < 0 ) { $seed = hexdec(substr(md5(microtime()),-8)) & 0x7fffffff; mt_srand( $seed ); $wgRandomSeeded = true; } } -# Generates a URL from a URL-encoded title and a query string -# Title::getLocalURL() is preferred in most cases -# -function wfLocalUrl( $a, $q = "" ) -{ +/** + * Generates a URL from a URL-encoded title and a query string + * Title::getLocalURL() is preferred in most cases + * + * @param string $a URL encoded title + * @param string $q URL (default '') + */ +function wfLocalUrl( $a, $q = '' ) { global $wgServer, $wgScript, $wgArticlePath; - $a = str_replace( " ", "_", $a ); + $a = str_replace( ' ', '_', $a ); - if ( "" == $a ) { - if( "" == $q ) { + if ( '' == $a ) { + if( '' == $q ) { $a = $wgScript; } else { - $a = "{$wgScript}?{$q}"; - } - } else if ( "" == $q ) { - $a = str_replace( "$1", $a, $wgArticlePath ); + $a = $wgScript.'?'.$q; + } + } else if ( '' == $q ) { + $a = str_replace( '$1', $a, $wgArticlePath ); } else if ($wgScript != '' ) { - $a = "{$wgScript}?title={$a}&{$q}"; - } else { //XXX ugly hack for toplevel wikis - $a = "/{$a}&{$q}"; + $a = "{$wgScript}?title={$a}&{$q}"; + } else { //XXX hackish solution for toplevel wikis + $a = "/{$a}?{$q}"; } return $a; } -function wfLocalUrlE( $a, $q = "" ) +/** + * @todo document + * @param string $a URL encoded title + * @param string $q URL (default '') + */ +function wfLocalUrlE( $a, $q = '' ) { - return wfEscapeHTML( wfLocalUrl( $a, $q ) ); + return htmlspecialchars( wfLocalUrl( $a, $q ) ); # die( "Call to obsolete function wfLocalUrlE()" ); } -function wfFullUrl( $a, $q = "" ) { - wfDebugDieBacktrace( "Call to obsolete function wfFullUrl(); use Title::getFullURL" ); -} - -function wfFullUrlE( $a, $q = "" ) { - wfDebugDieBacktrace( "Call to obsolete function wfFullUrlE(); use Title::getFullUrlE" ); - -} - -function wfImageUrl( $img ) -{ - global $wgUploadPath; - - $nt = Title::newFromText( $img ); - if( !$nt ) return ""; - - $name = $nt->getDBkey(); - $hash = md5( $name ); - - $url = "{$wgUploadPath}/" . $hash{0} . "/" . - substr( $hash, 0, 2 ) . "/{$name}"; - return wfUrlencode( $url ); -} - -function wfImagePath( $img ) -{ - global $wgUploadDirectory; - - $nt = Title::newFromText( $img ); - if( !$nt ) return ""; - - $name = $nt->getDBkey(); - $hash = md5( $name ); - - $path = "{$wgUploadDirectory}/" . $hash{0} . "/" . - substr( $hash, 0, 2 ) . "/{$name}"; - return $path; -} - -function wfThumbUrl( $img ) -{ - global $wgUploadPath; - - $nt = Title::newFromText( $img ); - if( !$nt ) return ""; - - $name = $nt->getDBkey(); - $hash = md5( $name ); - - $url = "{$wgUploadPath}/thumb/" . $hash{0} . "/" . - substr( $hash, 0, 2 ) . "/{$name}"; - return wfUrlencode( $url ); -} - - -function wfImageThumbUrl( $name, $subdir="thumb" ) -{ - global $wgUploadPath; - - $hash = md5( $name ); - $url = "{$wgUploadPath}/{$subdir}/" . $hash{0} . "/" . - substr( $hash, 0, 2 ) . "/{$name}"; - return wfUrlencode($url); -} - -function wfImageArchiveUrl( $name ) -{ - global $wgUploadPath; - - $hash = md5( substr( $name, 15) ); - $url = "{$wgUploadPath}/archive/" . $hash{0} . "/" . - substr( $hash, 0, 2 ) . "/{$name}"; - return wfUrlencode($url); -} - -function wfUrlencode ( $s ) -{ +/** + * We want / and : to be included as literal characters in our title URLs. + * %2F in the page titles seems to fatally break for some reason. + * + * @param string $s + * @return string +*/ +function wfUrlencode ( $s ) { $s = urlencode( $s ); - $s = preg_replace( "/%3[Aa]/", ":", $s ); - $s = preg_replace( "/%2[Ff]/", "/", $s ); + $s = preg_replace( '/%3[Aa]/', ':', $s ); + $s = preg_replace( '/%2[Ff]/', '/', $s ); return $s; } -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 < 0x100000) return chr($codepoint >> 18 & 0x07 | 0xf0) . # Double-check this - chr($codepoint >> 12 & 0x3f | 0x80) . - chr($codepoint >> 6 & 0x3f | 0x80) . - chr($codepoint & 0x3f | 0x80); - # Doesn't yet handle outside the BMP +/** + * 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;"; } -function wfMungeToUtf8($string) { +/** + * 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 ); @@ -188,60 +217,152 @@ function wfMungeToUtf8($string) { return $string; } -function wfDebug( $text, $logonly = false ) -{ - global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly; +/** + * Converts a single UTF-8 character into the corresponding HTML character + * entity (for use with preg_replace_callback) + * + * @param array $matches + * + */ +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 + */ +function wfDebug( $text, $logonly = false ) { + global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly, $wgDebugRawPage; + + # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet + if ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' && !$wgDebugRawPage ) { + return; + } if ( isset( $wgOut ) && $wgDebugComments && !$logonly ) { $wgOut->debug( $text ); } - if ( "" != $wgDebugLogFile && !$wgProfileOnly ) { + if ( '' != $wgDebugLogFile && !$wgProfileOnly ) { error_log( $text, 3, $wgDebugLogFile ); } } -function logProfilingData() -{ - global $wgRequestTime, $wgDebugLogFile; +/** + * Log for database errors + * @param string $text Database error message. + */ +function wfLogDBError( $text ) { + global $wgDBerrorLog; + if ( $wgDBerrorLog ) { + $text = date('D M j G:i:s T Y') . "\t".$text; + error_log( $text, 3, $wgDBerrorLog ); + } +} + +/** + * @todo document + */ +function logProfilingData() { + global $wgRequestTime, $wgDebugLogFile, $wgDebugRawPage, $wgRequest; global $wgProfiling, $wgProfileStack, $wgProfileLimit, $wgUser; $now = wfTime(); - list( $usec, $sec ) = explode( " ", $wgRequestTime ); + list( $usec, $sec ) = explode( ' ', $wgRequestTime ); $start = (float)$sec + (float)$usec; $elapsed = $now - $start; - if ( "" != $wgDebugLogFile ) { + if ( $wgProfiling ) { $prof = wfGetProfilingOutput( $start, $elapsed ); - $forward = ""; + $forward = ''; if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) - $forward = " forwarded for " . $_SERVER['HTTP_X_FORWARDED_FOR']; + $forward = ' forwarded for ' . $_SERVER['HTTP_X_FORWARDED_FOR']; if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) - $forward .= " client IP " . $_SERVER['HTTP_CLIENT_IP']; + $forward .= ' client IP ' . $_SERVER['HTTP_CLIENT_IP']; if( !empty( $_SERVER['HTTP_FROM'] ) ) - $forward .= " from " . $_SERVER['HTTP_FROM']; + $forward .= ' from ' . $_SERVER['HTTP_FROM']; if( $forward ) $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})"; if($wgUser->getId() == 0) - $forward .= " anon"; + $forward .= ' anon'; $log = sprintf( "%s\t%04.3f\t%s\n", - gmdate( "YmdHis" ), $elapsed, + gmdate( 'YmdHis' ), $elapsed, urldecode( $_SERVER['REQUEST_URI'] . $forward ) ); - error_log( $log . $prof, 3, $wgDebugLogFile ); + if ( '' != $wgDebugLogFile && ( $wgRequest->getVal('action') != 'raw' || $wgDebugRawPage ) ) { + error_log( $log . $prof, 3, $wgDebugLogFile ); + } } } - -function wfReadOnly() -{ +/** + * Check if the wiki read-only lock file is present. This can be used to lock + * off editing functions, but doesn't guarantee that the database will not be + * modified. + * @return bool + */ +function wfReadOnly() { global $wgReadOnlyFile; - if ( "" == $wgReadOnlyFile ) { return false; } + if ( '' == $wgReadOnlyFile ) { + return false; + } return is_file( $wgReadOnlyFile ); } -$wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" ); +/** + * Keys strings for replacement + * @global array $wgReplacementKeys + */ +$wgReplacementKeys = array( '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9' ); -# Get a message from anywhere +/** + * Get a message from anywhere + */ 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 ); @@ -249,7 +370,27 @@ function wfMsg( $key ) { return wfMsgReal( $key, $args, true ); } -# Get a message from the language file +/** + * Get a message from anywhere, but don't call Language::convert + */ +function wfMsgNoConvert( $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 ); + } + return wfMsgReal( $key, $args, true, false ); +} + +/** + * Get a message from the language file + */ function wfMsgNoDB( $key ) { $args = func_get_args(); if ( count( $args ) ) { @@ -258,11 +399,24 @@ function wfMsgNoDB( $key ) { return wfMsgReal( $key, $args, false ); } -# Really get a message -function wfMsgReal( $key, $args, $useDB ) { +/** + * Get a message from the language file, but don't call Language::convert + */ +function wfMsgNoDBNoConvert( $key ) { + $args = func_get_args(); + if ( count( $args ) ) { + array_shift( $args ); + } + return wfMsgReal( $key, $args, false, false ); +} + +/** + * Really get a message + */ +function wfMsgReal( $key, $args, $useDB, $convert=true ) { global $wgReplacementKeys, $wgMessageCache, $wgLang; - $fname = "wfMsg"; + $fname = 'wfMsg'; wfProfileIn( $fname ); if ( $wgMessageCache ) { $message = $wgMessageCache->get( $key, $useDB ); @@ -273,6 +427,10 @@ function wfMsgReal( $key, $args, $useDB ) { $message = "<$key>"; } + if ( $convert ) { + $message = $wgLang->convert($message); + } + # Replace arguments if( count( $args ) ) { $message = str_replace( $wgReplacementKeys, $args, $message ); @@ -281,320 +439,109 @@ function wfMsgReal( $key, $args, $useDB ) { return $message; } -function wfCleanFormFields( $fields ) -{ - wfDebugDieBacktrace( "Call to obsolete wfCleanFormFields(). Use wgRequest instead..." ); -} - -function wfMungeQuotes( $in ) -{ - $out = str_replace( "%", "%25", $in ); - $out = str_replace( "'", "%27", $out ); - $out = str_replace( "\"", "%22", $out ); - return $out; -} - -function wfDemungeQuotes( $in ) -{ - $out = str_replace( "%22", "\"", $in ); - $out = str_replace( "%27", "'", $out ); - $out = str_replace( "%25", "%", $out ); - return $out; -} - -function wfCleanQueryVar( $var ) -{ - wfDebugDieBacktrace( "Call to obsolete function wfCleanQueryVar(); use wgRequest instead" ); -} - -function wfSpecialPage() -{ - global $wgUser, $wgOut, $wgTitle, $wgLang; - - /* FIXME: this list probably shouldn't be language-specific, per se */ - $validSP = $wgLang->getValidSpecialPages(); - $sysopSP = $wgLang->getSysopSpecialPages(); - $devSP = $wgLang->getDeveloperSpecialPages(); - - $wgOut->setArticleRelated( false ); - $wgOut->setRobotpolicy( "noindex,follow" ); - - $bits = split( "/", $wgTitle->getDBkey(), 2 ); - $t = $bits[0]; - if( empty( $bits[1] ) ) { - $par = NULL; - } else { - $par = $bits[1]; - } - - if ( array_key_exists( $t, $validSP ) || - ( $wgUser->isSysop() && array_key_exists( $t, $sysopSP ) ) || - ( $wgUser->isDeveloper() && array_key_exists( $t, $devSP ) ) ) { - if($par !== NULL) - $wgTitle = Title::makeTitle( Namespace::getSpecial(), $t ); - - $wgOut->setPageTitle( wfMsg( strtolower( $wgTitle->getText() ) ) ); - - $inc = "Special" . $t . ".php"; - include_once( $inc ); - $call = "wfSpecial" . $t; - $call( $par ); - } else if ( array_key_exists( $t, $sysopSP ) ) { - $wgOut->sysopRequired(); - } else if ( array_key_exists( $t, $devSP ) ) { - $wgOut->developerRequired(); - } else { - $wgOut->errorpage( "nosuchspecialpage", "nospecialpagetext" ); - } -} - -function wfSearch( $s ) -{ - $se = new SearchEngine( $s ); - $se->showResults(); -} -function wfGo( $s ) -{ # pick the nearest match - $se = new SearchEngine( $s ); - $se->goResult(); -} -# Just like exit() but makes a note of it. -function wfAbruptExit(){ +/** + * Just like exit() but makes a note of it. + * Commits open transactions except if the error parameter is set + */ +function wfAbruptExit( $error = false ){ + global $wgLoadBalancer; static $called = false; if ( $called ){ exit(); } $called = true; - if( function_exists( "debug_backtrace" ) ){ // PHP >= 4.3 + if( function_exists( 'debug_backtrace' ) ){ // PHP >= 4.3 $bt = debug_backtrace(); for($i = 0; $i < count($bt) ; $i++){ - $file = $bt[$i]["file"]; - $line = $bt[$i]["line"]; + $file = $bt[$i]['file']; + $line = $bt[$i]['line']; wfDebug("WARNING: Abrupt exit in $file at line $line\n"); } - } else { - wfDebug("WARNING: Abrupt exit\n"); - } - exit(); -} - -function wfDebugDieBacktrace( $msg = "" ) { - $msg .= "\n

Backtrace:

\n