X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FGlobalFunctions.php;h=005fb8e0fef6410a3b5e584d772b941ca40c5b8e;hb=74a21f3bd1692dac958ddf3e09226a72b7bc65b7;hp=53e0b8704400f95e58e5cd40ab481be7e8fe6e5d;hpb=03d5e6f93c0fb9c1e675c33d4c712318a8096396;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 53e0b87044..005fb8e0fe 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -9,7 +9,6 @@ if ( !defined( 'MEDIAWIKI' ) ) { */ require_once dirname(__FILE__) . '/normal/UtfNormalUtil.php'; -require_once dirname(__FILE__) . '/XmlFunctions.php'; // Hide compatibility functions from Doxygen /// @cond @@ -173,23 +172,6 @@ if( !function_exists( 'mb_strrpos' ) ) { } } -if ( !function_exists( 'array_diff_key' ) ) { - /** - * Exists in PHP 5.1.0+ - * Not quite compatible, two-argument version only - * Null values will cause problems due to this use of isset() - */ - function array_diff_key( $left, $right ) { - $result = $left; - foreach ( $left as $key => $unused ) { - if ( isset( $right[$key] ) ) { - unset( $result[$key] ); - } - } - return $result; - } -} - // Support for Wietse Venema's taint feature if ( !function_exists( 'istainted' ) ) { function istainted( $var ) { @@ -230,15 +212,6 @@ function wfArrayDiff2_cmp( $a, $b ) { } } -/** - * Wrapper for clone(), for compatibility with PHP4-friendly extensions. - * PHP 5 won't let you declare a 'clone' function, even conditionally, - * so it has to be a wrapper with a different name. - */ -function wfClone( $object ) { - return clone( $object ); -} - /** * Seed Mersenne Twister * No-op for compatibility; only necessary in PHP < 4.2.0 @@ -277,16 +250,27 @@ function wfRandom() { * * ;:@$!*(),/ * + * However, IIS7 redirects fail when the url contains a colon (Bug 22709), + * so no fancy : for IIS7. + * * %2F in the page titles seems to fatally break for some reason. * * @param $s String: * @return string */ function wfUrlencode( $s ) { + static $needle; + if ( is_null( $needle ) ) { + $needle = array( '%3B','%40','%24','%21','%2A','%28','%29','%2C','%2F' ); + if (! isset($_SERVER['SERVER_SOFTWARE']) || ( strpos($_SERVER['SERVER_SOFTWARE'], "Microsoft-IIS/7") === false)) { + $needle[] = '%3A'; + } + } + $s = urlencode( $s ); $s = str_ireplace( - array( '%3B','%3A','%40','%24','%21','%2A','%28','%29','%2C','%2F' ), - array( ';', ':', '@', '$', '!', '*', '(', ')', ',', '/' ), + $needle, + array( ';', '@', '$', '!', '*', '(', ')', ',', '/', ':' ), $s ); @@ -312,6 +296,7 @@ function wfDebug( $text, $logonly = false ) { static $recursion = 0; static $cache = array(); // Cache of unoutputted messages + $text = wfDebugTimer() . $text; # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet if ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' && !$wgDebugRawPage ) { @@ -337,7 +322,7 @@ function wfDebug( $text, $logonly = false ) { array_map( array( $wgOut, 'debug' ), $cache ); $cache = array(); } - if ( '' != $wgDebugLogFile && !$wgProfileOnly ) { + if ( $wgDebugLogFile != '' && !$wgProfileOnly ) { # 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 ); @@ -346,6 +331,21 @@ function wfDebug( $text, $logonly = false ) { } } +function wfDebugTimer() { + global $wgDebugTimestamps; + if ( !$wgDebugTimestamps ) return ''; + static $start = null; + + if ( $start === null ) { + $start = microtime( true ); + $prefix = "\n$start"; + } else { + $prefix = sprintf( "%6.4f", microtime( true ) - $start ); + } + + return $prefix . ' '; +} + /** * Send a line giving PHP memory usage. * @param $exact Bool: print exact values instead of kilobytes (default: false) @@ -458,7 +458,7 @@ function wfLogProfilingData() { global $wgRequestTime, $wgDebugLogFile, $wgDebugRawPage, $wgRequest; global $wgProfiler, $wgProfileLimit, $wgUser; # Profiling must actually be enabled... - if( !isset( $wgProfiler ) ) return; + if( is_null( $wgProfiler ) ) return; # Get total page request time $now = wfTime(); $elapsed = $now - $wgRequestTime; @@ -480,7 +480,7 @@ function wfLogProfilingData() { $log = sprintf( "%s\t%04.3f\t%s\n", gmdate( 'YmdHis' ), $elapsed, urldecode( $wgRequest->getRequestURL() . $forward ) ); - if ( '' != $wgDebugLogFile && ( $wgRequest->getVal('action') != 'raw' || $wgDebugRawPage ) ) { + if ( $wgDebugLogFile != '' && ( $wgRequest->getVal('action') != 'raw' || $wgDebugRawPage ) ) { wfErrorLog( $log . $prof, $wgDebugLogFile ); } } @@ -497,7 +497,7 @@ function wfReadOnly() { if ( !is_null( $wgReadOnly ) ) { return (bool)$wgReadOnly; } - if ( '' == $wgReadOnlyFile ) { + if ( $wgReadOnlyFile == '' ) { return false; } // Set $wgReadOnly for faster access next time @@ -600,8 +600,8 @@ function wfMsgNoTrans( $key ) { * * Be wary of this distinction: If you use wfMsg() where you should * use wfMsgForContent(), a user of the software may have to - * customize over 70 messages in order to, e.g., fix a link in every - * possible language. + * customize potentially hundreds of messages in + * order to, e.g., fix a link in every possible language. * * @param $key String: lookup key for the message, usually * defined in languages/Language.php @@ -660,8 +660,8 @@ function wfMsgNoDBForContent( $key ) { * @param $key String: key to get. * @param $args * @param $useDB Boolean - * @param $transform Boolean: Whether or not to transform the message. * @param $forContent Mixed: Language code, or false for user lang, true for content lang. + * @param $transform Boolean: Whether or not to transform the message. * @return String: the requested message. */ function wfMsgReal( $key, $args, $useDB = true, $forContent = false, $transform = true ) { @@ -702,7 +702,9 @@ function wfMsgGetKey( $key, $useDB, $langCode = false, $transform = true ) { # If $wgMessageCache isn't initialised yet, try to return something sensible. if( is_object( $wgMessageCache ) ) { $message = $wgMessageCache->get( $key, $useDB, $langCode ); - if ( $transform ) { + if( $message === false ){ + $message = '<' . htmlspecialchars( $key ) . '>'; + } elseif ( $transform ) { $message = $wgMessageCache->transform( $message ); } } else { @@ -793,7 +795,7 @@ function wfMsgWikiHtml( $key ) { * parseinline: parses wikitext to html and removes the surrounding * p's added by parser or tidy * escape: filters message through htmlspecialchars - * escapenoentities: same, but allows entity references like   through + * escapenoentities: same, but allows entity references like   through * replaceafter: parameters are substituted after parsing or escaping * parsemag: transform the message using magic phrases * content: fetch message for content language instead of interface @@ -1167,8 +1169,7 @@ function wfNumLink( $offset, $limit, $title, $query = '' ) { * @return bool Whereas client accept gzip compression */ function wfClientAcceptsGzip() { - global $wgUseGzip; - if( $wgUseGzip ) { + if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) { # FIXME: we may want to blacklist some broken browsers $m = array(); if( preg_match( @@ -1277,7 +1278,7 @@ function wfSetBit( &$dest, $bit, $state = true ) { * "days=7&limit=100". Options in the first array override options in the second. * Options set to "" will not be output. */ -function wfArrayToCGI( $array1, $array2 = NULL ) +function wfArrayToCGI( $array1, $array2 = null ) { if ( !is_null( $array2 ) ) { $array1 = $array1 + $array2; @@ -1285,8 +1286,8 @@ function wfArrayToCGI( $array1, $array2 = NULL ) $cgi = ''; foreach ( $array1 as $key => $value ) { - if ( '' !== $value ) { - if ( '' != $cgi ) { + if ( $value !== '' ) { + if ( $cgi != '' ) { $cgi .= '&'; } if ( is_array( $value ) ) { @@ -1362,16 +1363,19 @@ function wfAppendQuery( $url, $query ) { /** * Expand a potentially local URL to a fully-qualified URL. Assumes $wgServer - * is correct. Also doesn't handle any type of relative URL except one - * starting with a single "/": this won't work with current-path-relative URLs - * like "subdir/foo.html", protocol-relative URLs like - * "//en.wikipedia.org/wiki/", etc. TODO: improve this! + * and $wgProto are correct. + * + * @todo this won't work with current-path-relative URLs + * like "subdir/foo.html", etc. * * @param $url String: either fully-qualified or a local path + query * @return string Fully-qualified URL */ function wfExpandUrl( $url ) { - if( substr( $url, 0, 1 ) == '/' ) { + if( substr( $url, 0, 2 ) == '//' ) { + global $wgProto; + return $wgProto . ':' . $url; + } elseif( substr( $url, 0, 1 ) == '/' ) { global $wgServer; return $wgServer . $url; } else { @@ -1423,13 +1427,17 @@ function wfEscapeShellArg( ) { } $delim = !$delim; } + // Double the backslashes before the end of the string, because // we will soon add a quote $m = array(); if ( preg_match( '/^(.*?)(\\\\+)$/', $arg, $m ) ) { $arg = $m[1] . str_replace( '\\', '\\\\', $m[2] ); } - + + // The caret is also an special character + $arg = str_replace( "^", "^^", $arg ); + // Add surrounding quotes $retVal .= '"' . $arg . '"'; } else { @@ -1717,7 +1725,7 @@ function mimeTypeMatch( $type, $avail ) { } elseif( array_key_exists( '*/*', $avail ) ) { return '*/*'; } else { - return NULL; + return null; } } } @@ -1759,7 +1767,7 @@ function wfNegotiateType( $cprefs, $sprefs ) { } $bestq = 0; - $besttype = NULL; + $besttype = null; foreach( array_keys( $combine ) as $type ) { if( $combine[$type] > $bestq ) { @@ -1807,7 +1815,7 @@ function wfSuppressWarnings( $end = false ) { } } else { if ( !$suppressCount ) { - $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE ) ); + $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE ) ); } ++$suppressCount; } @@ -2089,9 +2097,10 @@ function &wfGetMimeMagic() { } /** - * Tries to get the system directory for temporary files. - * The TMPDIR, TMP, and TEMP environment variables are checked in sequence, - * and if none are set /tmp is returned as the generic Unix default. + * Tries to get the system directory for temporary files. For PHP >= 5.2.1, + * we'll use sys_get_temp_dir(). The TMPDIR, TMP, and TEMP environment + * variables are then checked in sequence, and if none are set /tmp is + * returned as the generic Unix default. * * NOTE: When possible, use the tempfile() function to create temporary * files to avoid race conditions on file creation, etc. @@ -2099,6 +2108,9 @@ function &wfGetMimeMagic() { * @return String */ function wfTempDir() { + if( function_exists( 'sys_get_temp_dir' ) ) { + return sys_get_temp_dir(); + } foreach( array( 'TMPDIR', 'TMP', 'TEMP' ) as $var ) { $tmp = getenv( $var ); if( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) { @@ -2209,12 +2221,12 @@ function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) { * looked up didn't exist but a XHTML string, this function checks for the * nonexistance of messages by looking at wfMsg() output * - * @param $msg String: the message key looked up - * @param $wfMsgOut String: the output of wfMsg*() - * @return Boolean + * @param $key String: the message key looked up + * @return Boolean True if the message *doesn't* exist. */ -function wfEmptyMsg( $msg, $wfMsgOut ) { - return $wfMsgOut === htmlspecialchars( "<$msg>" ); +function wfEmptyMsg( $key ) { + global $wgMessageCache; + return $wgMessageCache->get( $key, /*useDB*/true, /*content*/false ) === false; } /** @@ -2241,9 +2253,7 @@ function wfSpecialList( $page, $details ) { */ function wfUrlProtocols() { global $wgUrlProtocols; - - // This function is called a lot, cache its return value - // TODO: Cache this in memcached instead? + static $retval = null; if ( !is_null( $retval ) ) return $retval; @@ -2259,7 +2269,6 @@ function wfUrlProtocols() { } else { $retval = $wgUrlProtocols; } - return $retval; } @@ -2528,11 +2537,13 @@ function wfArrayMerge( $array1/* ... */ ) { * array( 'y' ) * ) */ -function wfMergeErrorArrays(/*...*/) { +function wfMergeErrorArrays( /*...*/ ) { $args = func_get_args(); $out = array(); foreach ( $args as $errors ) { foreach ( $errors as $params ) { + # FIXME: sometimes get nested arrays for $params, + # which leads to E_NOTICEs $spec = implode( "\t", $params ); $out[$spec] = $params; } @@ -2755,15 +2766,6 @@ function wfCreateObject( $name, $p ){ } } -/** - * Alias for modularized function - * @deprecated Use Http::get() instead - */ -function wfGetHTTP( $url ) { - wfDeprecated(__FUNCTION__); - return Http::get( $url ); -} - /** * Alias for modularized function * @deprecated Use Http::isLocalURL() instead @@ -2896,9 +2898,7 @@ function wfForeignMemcKey( $db, $prefix /*, ... */ ) { * This is used as a prefix in memcached keys */ function wfWikiID() { - global $wgDBprefix, $wgDBname, $wgWikiId; - if( $wgWikiId ) - return $wgWikiId; + global $wgDBprefix, $wgDBname; if ( $wgDBprefix ) { return "$wgDBname-$wgDBprefix"; } else { @@ -2957,6 +2957,7 @@ function &wfGetLBFactory() { /** * Find a file. * Shortcut for RepoGroup::singleton()->findFile() + * @param $title Either a string or Title object * @param $options Associative array of options: * time: requested time for an archived image, or false for the * current version. An image object will be returned which was @@ -2979,6 +2980,8 @@ function wfFindFile( $title, $options = array() ) { /** * Get an object referring to a locally registered file. * Returns a valid placeholder object if the file does not exist. + * @param $title Either a string or Title object + * @return File, or null if passed an invalid Title */ function wfLocalFile( $title ) { return RepoGroup::singleton()->getLocalRepo()->newFile( $title ); @@ -3044,7 +3047,7 @@ function wfBoolToStr( $value ) { /** * Load an extension messages file - * @deprecated + * @deprecated in 1.16 (warnings in 1.18, removed in ?) */ function wfLoadExtensionMessages( $extensionName, $langcode = false ) { } @@ -3081,21 +3084,6 @@ function wfMaxlagError( $host, $lag, $maxLag ) { } } -/** - * Displays a avglag error - * - * @param $lag Integer: avglag (actual) - * @param $avgLag Integer: avglag (requested) - */ -function wfAvglagError( $lag, $avgLag ) { - header( 'HTTP/1.1 503 Service Unavailable' ); - header( 'Retry-After: ' . max( intval( $avgLag ), 5 ) ); - header( 'X-Database-Lag: ' . intval( $lag ) ); - header( 'Content-Type: text/plain' ); - - echo "Lagged: $lag seconds average\n"; -} - /** * Throws a warning that $function is deprecated * @param $function String @@ -3161,7 +3149,7 @@ function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) { function wfWaitForSlaves( $maxLag, $wiki = false ) { if( $maxLag ) { $lb = wfGetLB( $wiki ); - list( $host, $lag ) = $lb->getMaxLag(); + list( $host, $lag ) = $lb->getMaxLag( $wiki ); while( $lag > $maxLag ) { $name = @gethostbyaddr( $host ); if( $name !== false ) { @@ -3338,3 +3326,14 @@ function wfBCP47( $code ) { $langCode = implode ( '-' , $codeBCP ); return $langCode; } + +function wfArrayMap( $function, $input ) { + $ret = array_map( $function, $input ); + foreach ( $ret as $key => $value ) { + $taint = istainted( $input[$key] ); + if ( $taint ) { + taint( $ret[$key], $taint ); + } + } + return $ret; +}