Fix bug in prefixing scheme
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index 31c5f88..d0c3a42 100644 (file)
@@ -528,34 +528,44 @@ function wfReadOnlyReason() {
  *                    functionality), or if it is true then use the wikis
  * @return Language object
  */
-function wfGetLangObj( $langcode = false ){
+function wfGetLangObj( $langcode = false ) {
        # Identify which language to get or create a language object for.
-       if( $langcode instanceof Language )
-               # Great, we already have the object!
+       # Using is_object here due to Stub objects.
+       if( is_object( $langcode ) ) {
+               # Great, we already have the object (hopefully)!
                return $langcode;
+       }
                
-       global $wgContLang;
-       if( $langcode === $wgContLang->getCode() || $langcode === true )
+       global $wgContLang, $wgLanguageCode;
+       if( $langcode === true || $langcode === $wgLanguageCode ) {
                # $langcode is the language code of the wikis content language object.
                # or it is a boolean and value is true
                return $wgContLang;
+       }
        
        global $wgLang;
-       if( $langcode === $wgLang->getCode() || $langcode === false )
+       if( $langcode === false || $langcode === $wgLang->getCode() ) {
                # $langcode is the language code of user language object.
                # or it was a boolean and value is false
                return $wgLang;
+       }
 
        $validCodes = array_keys( Language::getLanguageNames() );
-       if( in_array( $langcode, $validCodes ) )
+       if( in_array( $langcode, $validCodes ) ) {
                # $langcode corresponds to a valid language.
                return Language::factory( $langcode );
+       }
 
        # $langcode is a string, but not a valid language code; use content language.
        wfDebug( "Invalid language code passed to wfGetLangObj, falling back to content language.\n" );
        return $wgContLang;
 }
 
+function wfUILang() {
+       global $wgBetterDirectionality;
+       return wfGetLangObj( $wgBetterDirectionality ? false: true );
+}
+
 /**
  * Get a message from anywhere, for the current user language.
  *
@@ -692,35 +702,22 @@ function wfMsgWeirdKey( $key ) {
  *                  behaves as a content language switch if it is a boolean.
  * @param $transform Boolean: whether to parse magic words, etc.
  * @return string
- * @private
  */
 function wfMsgGetKey( $key, $useDB, $langCode = false, $transform = true ) {
-       global $wgContLang, $wgMessageCache;
+       global $wgMessageCache;
 
        wfRunHooks('NormalizeMessageKey', array(&$key, &$useDB, &$langCode, &$transform));
        
-       # If $wgMessageCache isn't initialised yet, try to return something sensible.
-       if( is_object( $wgMessageCache ) ) {
-               $message = $wgMessageCache->get( $key, $useDB, $langCode );
-               if( $message === false ){
-                       $message = '<' . htmlspecialchars( $key ) . '>';
-               } elseif ( $transform ) {
-                       $message = $wgMessageCache->transform( $message );
-               }
-       } else {
-               $lang = wfGetLangObj( $langCode );
-
-               # MessageCache::get() does this already, Language::getMessage() doesn't
-               # ISSUE: Should we try to handle "message/lang" here too?
-               $key = str_replace( ' ' , '_' , $wgContLang->lcfirst( $key ) );
-
-               if( is_object( $lang ) ) {
-                       $message = $lang->getMessage( $key );
-               } else {
-                       $message = false;
-               }
+       if ( !is_object( $wgMessageCache ) ) {
+               throw new MWException( "Trying to get message before message cache is initialised" );
        }
 
+       $message = $wgMessageCache->get( $key, $useDB, $langCode );
+       if( $message === false ){
+               $message = '<' . htmlspecialchars( $key ) . '>';
+       } elseif ( $transform ) {
+               $message = $wgMessageCache->transform( $message );
+       }
        return $message;
 }
 
@@ -795,7 +792,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
@@ -1418,26 +1415,27 @@ function wfEscapeShellArg( ) {
                        // Double the backslashes before any double quotes. Escape the double quotes.
                        $tokens = preg_split( '/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
                        $arg = '';
-                       $delim = false;
+                       $iteration = 0;
                        foreach ( $tokens as $token ) {
-                               if ( $delim ) {
+                               if ( $iteration % 2 == 1 ) {
+                                       // Delimiter, a double quote preceded by zero or more slashes
                                        $arg .= str_replace( '\\', '\\\\', substr( $token, 0, -1 ) ) . '\\"';
-                               } else {
+                               } else if ( $iteration % 4 == 2 ) {
+                                       // ^ in $token will be outside quotes, need to be escaped
+                                       $arg .= str_replace( '^', '^^', $token );
+                               } else { // $iteration % 4 == 0
+                                       // ^ in $token will appear inside double quotes, so leave as is
                                        $arg .= $token;
                                }
-                               $delim = !$delim;
+                               $iteration++;
                        }
-                       
                        // 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 {
@@ -1500,7 +1498,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;
        }
@@ -1899,7 +1897,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
                # TS_EXIF
        } elseif (preg_match('/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D',$ts,$da)) {
                # TS_MW
-       } elseif (preg_match('/^\d{1,13}$/D',$ts)) {
+       } elseif (preg_match('/^-?\d{1,13}$/D',$ts)) {
                # TS_UNIX
                $uts = $ts;
        } elseif (preg_match('/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts)) {
@@ -2034,7 +2032,7 @@ function wfGetCachedNotice( $name ) {
                        $notice = '';
                }
        }
-
+       $notice = '<div id="localNotice">'.$notice.'</div>';
        wfProfileOut( $fname );
        return $notice;
 }
@@ -2062,7 +2060,7 @@ function wfGetNamespaceNotice() {
 }
 
 function wfGetSiteNotice() {
-       global $wgUser, $wgSiteNotice;
+       global $wgUser;
        $fname = 'wfGetSiteNotice';
        wfProfileIn( $fname );
        $siteNotice = '';
@@ -2093,6 +2091,7 @@ function wfGetSiteNotice() {
  * @deprecated
  */
 function &wfGetMimeMagic() {
+       wfDeprecated( __FUNCTION__ );
        return MimeMagic::singleton();
 }
 
@@ -2101,9 +2100,10 @@ function &wfGetMimeMagic() {
  * 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.
+ * It is common to call it with tempnam().
+ * 
+ * NOTE: When possible, use instead the tmpfile() function to create 
+ * temporary files to avoid race conditions on file creation, etc.
  *
  * @return String
  */
@@ -2144,7 +2144,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 );
@@ -2304,6 +2308,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.
@@ -2427,13 +2455,6 @@ function wfUseMW( $req_ver ) {
                throw new MWException( "MediaWiki $req_ver required--this is only $wgVersion" );
 }
 
-/**
- * @deprecated use StringUtils::escapeRegexReplacement
- */
-function wfRegexReplacement( $string ) {
-       return StringUtils::escapeRegexReplacement( $string );
-}
-
 /**
  * Return the final portion of a pathname.
  * Reimplemented because PHP5's basename() is buggy with multibyte text.
@@ -2645,13 +2666,6 @@ function wfDoUpdates()
        $wgPostCommitUpdateList = array();
 }
 
-/**
- * @deprecated use StringUtils::explodeMarkup
- */
-function wfExplodeMarkup( $separator, $text ) {
-       return StringUtils::explodeMarkup( $separator, $text );
-}
-
 /**
  * Convert an arbitrarily-long digit string from one numeric base
  * to another, optionally zero-padding to a minimum column width.
@@ -2766,15 +2780,6 @@ function wfCreateObject( $name, $p ){
        }
 }
 
-/**
- * Alias for modularized function
- * @deprecated Use Http::isLocalURL() instead
- */
-function wfIsLocalURL( $url ) {
-       wfDeprecated(__FUNCTION__);
-       return Http::isLocalURL( $url );
-}
-
 function wfHttpOnlySafe() {
        global $wgHttpOnlyBlacklist;
        if( !version_compare("5.2", PHP_VERSION, "<") )
@@ -2854,11 +2859,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 ) );
 }
 
 /**