Localisation updates for core and extension messages from translatewiki.net (2010...
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index d6e0f5b..fa52854 100644 (file)
@@ -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,54 +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;
-       }
-}
-
-if ( !function_exists( 'array_intersect_key' ) ) {
-       /**
-       * Exists in 5.1.0+
-       * Define our own array_intersect_key function
-       */
-       function array_intersect_key( $isec, $keys ) {
-               $argc = func_num_args();
-
-               if ( $argc > 2 ) {
-                       for ( $i = 1; $isec && $i < $argc; $i++ ) {
-                               $arr = func_get_arg( $i );
-
-                               foreach ( array_keys( $isec ) as $key ) {
-                                       if ( !isset( $arr[$key] ) )
-                                               unset( $isec[$key] );
-                               }
-                       }
-
-                       return $isec;
-               } else {
-                       $res = array();
-                       foreach ( array_keys( $isec ) as $key ) {
-                               if ( isset( $keys[$key] ) )
-                                       $res[$key] = $isec[$key];
-                       }
-
-                       return $res;
-               }
-       }
-}
-
 // Support for Wietse Venema's taint feature
 if ( !function_exists( 'istainted' ) ) {
        function istainted( $var ) {
@@ -299,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
        );
 
@@ -496,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;
@@ -638,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
@@ -698,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 ) {
@@ -740,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 = '&lt;' . htmlspecialchars( $key ) . '&gt;';
+               } elseif ( $transform ) {
                        $message = $wgMessageCache->transform( $message );
                }
        } else {
@@ -831,7 +795,7 @@ function wfMsgWikiHtml( $key ) {
  *   <i>parseinline</i>: parses wikitext to html and removes the surrounding
  *       p's added by parser or tidy
  *   <i>escape</i>: filters message through htmlspecialchars
- *   <i>escapenoentities</i>: same, but allows entity references like &nbsp; through
+ *   <i>escapenoentities</i>: same, but allows entity references like &#160; through
  *   <i>replaceafter</i>: parameters are substituted after parsing or escaping
  *   <i>parsemag</i>: transform the message using magic phrases
  *   <i>content</i>: fetch message for content language instead of interface
@@ -1399,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 {
@@ -1460,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 {
@@ -1529,7 +1500,7 @@ function wfMerge( $old, $mine, $yours, &$result ){
        pclose( $handle );
        unlink( $mytextName ); unlink( $oldtextName ); unlink( $yourtextName );
 
-       if ( $result === '' && $old !== '' && $conflict == false ) {
+       if ( $result === '' && $old !== '' && !$conflict ) {
                wfDebug( "Unexpected null result from diff3. Command: $cmd\n" );
                $conflict = true;
        }
@@ -1844,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;
        }
@@ -2063,7 +2034,7 @@ function wfGetCachedNotice( $name ) {
                        $notice = '';
                }
        }
-
+       $notice = '<div id="localNotice">'.$notice.'</div>';
        wfProfileOut( $fname );
        return $notice;
 }
@@ -2122,6 +2093,7 @@ function wfGetSiteNotice() {
  * @deprecated
  */
 function &wfGetMimeMagic() {
+       wfDeprecated( __FUNCTION__ );
        return MimeMagic::singleton();
 }
 
@@ -2173,7 +2145,11 @@ function wfMkdirParents( $dir, $mode = null, $caller = null ) {
        if ( is_null( $mode ) )
                $mode = $wgDirectoryMode;
 
+       // Turn off the normal warning, we're doing our own below
+       wfSuppressWarnings();
        $ok = mkdir( $dir, $mode, true );  // PHP5 <3
+       wfRestoreWarnings();
+
        if( !$ok ) {
                // PHP doesn't report the path in its warning message, so add our own to aid in diagnosis.
                trigger_error( __FUNCTION__ . ": failed to mkdir \"$dir\" mode $mode", E_USER_WARNING );
@@ -2250,12 +2226,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;
 }
 
 /**
@@ -2333,6 +2309,30 @@ function wfIniGetBool( $setting ) {
                || preg_match( "/^\s*[+-]?0*[1-9]/", $val ); // approx C atoi() function
 }
 
+/**
+ * Wrapper function for PHP's dl(). This doesn't work in most situations from
+ * PHP 5.3 onward, and is usually disabled in shared environments anyway.
+ *
+ * @param $extension String A PHP extension. The file suffix (.so or .dll)
+ *                          should be omitted
+ * @return Bool - Whether or not the extension is loaded
+ */
+function wfDl( $extension ) {
+       if( extension_loaded( $extension ) ) {
+               return true;
+       }
+
+       $canDl = ( function_exists( 'dl' ) && is_callable( 'dl' )
+               && wfIniGetBool( 'enable_dl' ) && !wfIniGetBool( 'safe_mode' ) );
+
+       if( $canDl ) {
+               wfSuppressWarnings();
+               dl( $extension . '.' . PHP_SHLIB_SUFFIX );
+               wfRestoreWarnings();
+       }
+       return extension_loaded( $extension );
+}
+
 /**
  * Execute a shell command, with time and memory limits mirrored from the PHP
  * configuration if supported.
@@ -2566,11 +2566,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;
                }
@@ -2793,15 +2795,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
@@ -2890,11 +2883,19 @@ function wfGetCaller( $level = 2 ) {
 }
 
 /**
- * Return a string consisting all callers in stack, somewhat useful sometimes
- * for profiling specific points
+ * Return a string consisting of callers in the stack. Useful sometimes
+ * for profiling specific points.
+ *
+ * @param $limit The maximum depth of the stack frame to return, or false for
+ *               the entire stack.
  */
-function wfGetAllCallers() {
-       return implode('/', array_map('wfFormatStackFrame',array_reverse(wfDebugBacktrace())));
+function wfGetAllCallers( $limit = 3 ) {
+       $trace = array_reverse( wfDebugBacktrace() );
+       if ( !$limit || $limit > count( $trace ) - 1 ) {
+               $limit = count( $trace ) - 1;
+       }
+       $trace = array_slice( $trace, -$limit - 1, $limit );
+       return implode( '/', array_map( 'wfFormatStackFrame', $trace ) );
 }
 
 /**
@@ -3083,7 +3084,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 ) {
 }
@@ -3362,3 +3363,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;
+}