Use Doxygen @addtogroup instead of phpdoc @package && @subpackage
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index db05e08..4b73d5a 100644 (file)
@@ -2,27 +2,19 @@
 
 /**
  * Global functions used everywhere
- * @package MediaWiki
  */
 
 /**
  * Some globals and requires needed
  */
 
-/**
- * Total number of articles
- * @global integer $wgNumberOfArticles
- */
+/** Total number of articles */
 $wgNumberOfArticles = -1; # Unset
-/**
- * Total number of views
- * @global integer $wgTotalViews
- */
+
+/** Total number of views */
 $wgTotalViews = -1;
-/**
- * Total number of edits
- * @global integer $wgTotalEdits
- */
+
+/** Total number of edits */
 $wgTotalEdits = -1;
 
 
@@ -237,7 +229,7 @@ function wfLogProfilingData() {
                        $forward .= ' anon';
                $log = sprintf( "%s\t%04.3f\t%s\n",
                  gmdate( 'YmdHis' ), $elapsed,
-                 urldecode( $_SERVER['REQUEST_URI'] . $forward ) );
+                 urldecode( $wgRequest->getRequestURL() . $forward ) );
                if ( '' != $wgDebugLogFile && ( $wgRequest->getVal('action') != 'raw' || $wgDebugRawPage ) ) {
                        error_log( $log . $prof, 3, $wgDebugLogFile );
                }
@@ -299,7 +291,7 @@ function wfMsg( $key ) {
 function wfMsgNoTrans( $key ) {
        $args = func_get_args();
        array_shift( $args );
-       return wfMsgReal( $key, $args, true, false );
+       return wfMsgReal( $key, $args, true, false, false );
 }
 
 /**
@@ -383,8 +375,11 @@ function wfMsgNoDBForContent( $key ) {
  * @return String: the requested message.
  */
 function wfMsgReal( $key, $args, $useDB = true, $forContent=false, $transform = true ) {
+       $fname = 'wfMsgReal';
+       wfProfileIn( $fname );
        $message = wfMsgGetKey( $key, $useDB, $forContent, $transform );
        $message = wfMsgReplaceArgs( $message, $args );
+       wfProfileOut( $fname );
        return $message;
 }
 
@@ -554,12 +549,10 @@ function wfMsgExt( $key, $options ) {
                        $string = $m[1];
                }
        } elseif ( in_array('parsemag', $options) ) {
-               global $wgTitle;
-               $parser = new Parser();
-               $parserOptions = new ParserOptions();
-               $parserOptions->setInterfaceMessage( true );
-               $parser->startExternalParse( $wgTitle, $parserOptions, OT_MSG );
-               $string = $parser->transformMsg( $string, $parserOptions );
+               global $wgMessageCache;
+               if ( isset( $wgMessageCache ) ) {
+                       $string = $wgMessageCache->transform( $string );
+               }
        }
 
        if ( in_array('escape', $options) ) {
@@ -588,8 +581,8 @@ function wfAbruptExit( $error = false ){
        }
        $called = true;
 
-       if( function_exists( 'debug_backtrace' ) ){ // PHP >= 4.3
-               $bt = debug_backtrace();
+       $bt = wfDebugBacktrace();
+       if( $bt ) {
                for($i = 0; $i < count($bt) ; $i++){
                        $file = isset($bt[$i]['file']) ? $bt[$i]['file'] : "unknown";
                        $line = isset($bt[$i]['line']) ? $bt[$i]['line'] : "unknown";
@@ -671,18 +664,36 @@ function wfHostname() {
                return $com;
        }
 
+/**
+ * Safety wrapper for debug_backtrace().
+ *
+ * With Zend Optimizer 3.2.0 loaded, this causes segfaults under somewhat
+ * murky circumstances, which may be triggered in part by stub objects
+ * or other fancy talkin'.
+ *
+ * Will return an empty array if Zend Optimizer is detected, otherwise
+ * the output from debug_backtrace() (trimmed).
+ *
+ * @return array of backtrace information
+ */
+function wfDebugBacktrace() {
+       if( extension_loaded( 'Zend Optimizer' ) ) {
+               wfDebug( "Zend Optimizer detected; skipping debug_backtrace for safety.\n" );
+               return array();
+       } else {
+               return array_slice( debug_backtrace(), 1 );
+       }
+}
+
 function wfBacktrace() {
        global $wgCommandLineMode;
-       if ( !function_exists( 'debug_backtrace' ) ) {
-               return false;
-       }
 
        if ( $wgCommandLineMode ) {
                $msg = '';
        } else {
                $msg = "<ul>\n";
        }
-       $backtrace = debug_backtrace();
+       $backtrace = wfDebugBacktrace();
        foreach( $backtrace as $call ) {
                if( isset( $call['file'] ) ) {
                        $f = explode( DIRECTORY_SEPARATOR, $call['file'] );
@@ -1070,12 +1081,13 @@ function wfHttpError( $code, $label, $desc ) {
        $wgOut->sendCacheControl();
 
        header( 'Content-type: text/html' );
-       print "<html><head><title>" .
+       print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">".
+               "<html><head><title>" .
                htmlspecialchars( $label ) .
                "</title></head><body><h1>" .
                htmlspecialchars( $label ) .
                "</h1><p>" .
-               htmlspecialchars( $desc ) .
+               nl2br( htmlspecialchars( $desc ) ) .
                "</p></body></html>\n";
 }
 
@@ -1453,10 +1465,21 @@ function wfGetCachedNotice( $name ) {
        wfProfileIn( $fname );
        
        $needParse = false;
-       $notice = wfMsgForContent( $name );
-       if( wfEmptyMsg( $name, $notice ) || $notice == '-' ) {
-               wfProfileOut( $fname );
-               return( false );
+       
+       if( $name === 'default' ) {
+               // special case
+               global $wgSiteNotice;
+               $notice = $wgSiteNotice;
+               if( empty( $notice ) ) {
+                       wfProfileOut( $fname );
+                       return false;
+               }
+       } else {
+               $notice = wfMsgForContentNoTrans( $name );
+               if( wfEmptyMsg( $name, $notice ) || $notice == '-' ) {
+                       wfProfileOut( $fname );
+                       return( false );
+               }
        }
        
        $cachedNotice = $parserMemc->get( wfMemcKey( $name ) );
@@ -1516,16 +1539,17 @@ function wfGetSiteNotice() {
        if( wfRunHooks( 'SiteNoticeBefore', array( &$siteNotice ) ) ) {
                if( is_object( $wgUser ) && $wgUser->isLoggedIn() ) {
                        $siteNotice = wfGetCachedNotice( 'sitenotice' );
-                       $siteNotice = !$siteNotice ? $wgSiteNotice : $siteNotice;
                } else {
                        $anonNotice = wfGetCachedNotice( 'anonnotice' );
                        if( !$anonNotice ) {
                                $siteNotice = wfGetCachedNotice( 'sitenotice' );
-                               $siteNotice = !$siteNotice ? $wgSiteNotice : $siteNotice;
                        } else {
                                $siteNotice = $anonNotice;
                        }
                }
+               if( !$siteNotice ) {
+                       $siteNotice = wfGetCachedNotice( 'default' );
+               }
        }
 
        wfRunHooks( 'SiteNoticeAfter', array( &$siteNotice ) );
@@ -1602,6 +1626,7 @@ function wfMkdirParents( $fullDir, $mode = 0777 ) {
        foreach ( $createList as $dir ) {
                # use chmod to override the umask, as suggested by the PHP manual
                if ( !mkdir( $dir, $mode ) || !chmod( $dir, $mode ) ) {
+                       wfDebugLog( 'mkdir', "Unable to create directory $dir\n" );
                        return false;
                } 
        }
@@ -1821,6 +1846,41 @@ function wfBaseName( $path ) {
        }
 }
 
+/**
+ * Generate a relative path name to the given file.
+ * May explode on non-matching case-insensitive paths,
+ * funky symlinks, etc.
+ *
+ * @param string $path Absolute destination path including target filename
+ * @param string $from Absolute source path, directory only
+ * @return string
+ */
+function wfRelativePath( $path, $from ) {
+       // Normalize mixed input on Windows...
+       $path = str_replace( '/', DIRECTORY_SEPARATOR, $path );
+       $from = str_replace( '/', DIRECTORY_SEPARATOR, $from );
+       
+       $pieces  = explode( DIRECTORY_SEPARATOR, dirname( $path ) );
+       $against = explode( DIRECTORY_SEPARATOR, $from );
+
+       // Trim off common prefix
+       while( count( $pieces ) && count( $against )
+               && $pieces[0] == $against[0] ) {
+               array_shift( $pieces );
+               array_shift( $against );
+       }
+
+       // relative dots to bump us to the parent
+       while( count( $against ) ) {
+               array_unshift( $pieces, '..' );
+               array_shift( $against );
+       }
+
+       array_push( $pieces, wfBaseName( $path ) );
+
+       return implode( DIRECTORY_SEPARATOR, $pieces );
+}
+
 /**
  * Make a URL index, appropriate for the el_index field of externallinks.
  */
@@ -2034,7 +2094,7 @@ function wfGetPrecompiledData( $name ) {
 }
 
 function wfGetCaller( $level = 2 ) {
-       $backtrace = debug_backtrace();
+       $backtrace = wfDebugBacktrace();
        if ( isset( $backtrace[$level] ) ) {
                if ( isset( $backtrace[$level]['class'] ) ) {
                        $caller = $backtrace[$level]['class'] . '::' . $backtrace[$level]['function'];
@@ -2055,7 +2115,7 @@ function wfGetAllCallers() {
                                $frame["class"]."::".$frame["function"]:
                                $frame["function"]; 
                        '),
-               array_reverse(debug_backtrace())));
+               array_reverse(wfDebugBacktrace())));
 }
 
 /**
@@ -2104,8 +2164,9 @@ function wfWikiID() {
  *                master (for write queries), DB_SLAVE for potentially lagged 
  *                read queries, or an integer >= 0 for a particular server.
  *
- * @param array $groups Query groups. A list of group names that this query 
- *              belongs to.
+ * @param mixed $groups Query groups. An array of group names that this query 
+ *              belongs to. May contain a single string if the query is only 
+ *              in one group.
  */
 function &wfGetDB( $db = DB_LAST, $groups = array() ) {
        global $wgLoadBalancer;