Various fixes, see the version of [[m:Development status]] before this commit for...
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index 124711b..42dd1a1 100644 (file)
@@ -130,9 +130,9 @@ function wfMungeToUtf8($string) {
 
 function wfDebug( $text, $logonly = false )
 {
-       global $wgOut, $wgDebugLogFile;
+       global $wgOut, $wgDebugLogFile, $wgDebugComments;
 
-       if ( $logonly ) {
+       if ( $wgDebugComments && !$logonly ) {
                $wgOut->debug( $text );
        }
        if ( "" != $wgDebugLogFile ) {
@@ -140,30 +140,6 @@ function wfDebug( $text, $logonly = false )
        }
 }
 
-if( !isset( $wgProfiling ) )
-       $wgProfiling = false;
-$wgProfileStack = array();
-$wgProfileWorkStack = array();
-
-if( $wgProfiling ) {
-       function wfProfileIn( $functionname )
-       {
-               global $wgProfileStack, $wgProfileWorkStack;
-               array_push( $wgProfileWorkStack, "$functionname " .
-                       count( $wgProfileWorkStack ) . " " . microtime() );
-       }
-
-       function wfProfileOut() {
-               global $wgProfileStack, $wgProfileWorkStack;
-               $bit = array_pop( $wgProfileWorkStack );
-               $bit .= " " . microtime();
-               array_push( $wgProfileStack, $bit );
-       }
-} else {
-       function wfProfileIn( $functionname ) { }
-       function wfProfileOut( ) { }
-}
-
 function wfReadOnly()
 {
        global $wgReadOnlyFile;
@@ -173,21 +149,105 @@ function wfReadOnly()
 }
 
 $wgReplacementKeys = array( "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9" );
-function wfMsg( $key )
-{
-       global $wgLang, $wgReplacementKeys;
-       $ret = $wgLang->getMessage( $key );
+
+# Get a message from anywhere
+function wfMsg( $key ) {
+       $args = func_get_args();
+       if ( count( $args ) ) {
+               array_shift( $args );
+       }
+       return wfMsgReal( $key, $args, true );
+}
+
+# Get a message from the language file
+function wfMsgNoDB( $key ) {
+       $args = func_get_args();
+       if ( count( $args ) ) {
+               array_shift( $args );
+       }
+       return wfMsgReal( $key, $args, false );
+}
+
+# Really get a message
+function wfMsgReal( $key, $args, $useDB ) {
+       global $wgLang, $wgReplacementKeys, $wgMemc, $wgDBname;
+       global $wgUseDatabaseMessages, $wgUseMemCached, $wgOut;
+       global $wgAllMessagesEn, $wgLanguageCode;
+
+       $fname = "wfMsg";
+       wfProfileIn( $fname );
        
-       if( func_num_args() > 1 ) {
-               $reps = func_get_args();
-               array_shift( $reps );
-               $ret = str_replace( $wgReplacementKeys, $reps, $ret );
+       static $messageCache = false;
+       $memcKey = "$wgDBname:messages";
+       $fname = "wfMsg";
+       $message = false;
+
+       # newFromText is too slow!
+       $title = ucfirst( $key );
+       if ( $messageCache ) {
+               $message = $messageCache[$title];
+       } elseif ( !$wgUseDatabaseMessages || !$useDB ) {
+               $message = $wgLang->getMessage( $key );
+       }
+
+       if ( !$message && $wgUseMemCached ) {
+               # Try memcached
+               if ( !$messageCache ) {
+                       $messageCache = $wgMemc->get( $memcKey );
+               }
+               
+               # If there's nothing in memcached, load all the messages from the database
+               # This should only happen on server reset -- ordinary changes should update
+               # memcached in editUpdates()
+               if ( !$messageCache ) {
+                       # Other threads don't need to load the messages if another thread is doing it.
+                       $wgMemc->set( $memcKey, "loading", time() + 60 );
+                       $messageCache = wfLoadAllMessages();
+                       # Save in memcached
+                       $wgMemc->set( $memcKey, $messageCache, time() + 3600 );
+                       
+                       
+               }
+               if ( is_array( $messageCache ) && array_key_exists( $title, $messageCache ) ) {
+                       $message = $messageCache[$title];
+               } 
        }
 
-       if ( "" == $ret ) {
-               user_error( "Couldn't find text for message \"{$key}\"." );
+       # If there was no MemCached, load each message from the DB individually
+       if ( !$message ) {
+               if ( $useDB ) {
+                       $sql = "SELECT cur_text FROM cur WHERE cur_namespace=" . NS_MEDIAWIKI . 
+                               " AND cur_title='$title'";
+                       $res = wfQuery( $sql, DB_READ, $fname );
+
+                       if ( wfNumRows( $res ) ) {
+                               $obj = wfFetchObject( $res );
+                               $message = $obj->cur_text;
+                               wfFreeResult( $res );
+                       }
+               }
        }
-       return $ret;
+
+       # Try the array in $wgLang
+       if ( !$message ) {
+               $message = $wgLang->getMessage( $key );
+       } 
+
+       # Try the English array
+       if ( !$message && $wgLanguageCode != "en" ) {
+               $message = Language::getMessage( $key );
+       }
+       
+       # Replace arguments
+       if( count( $args ) ) {
+               $message = str_replace( $wgReplacementKeys, $args, $message );
+       }
+       wfProfileOut( $fname );
+       if ( !$message ) {
+               # Failed, message does not exist
+               return "<$key>";
+       }
+       return $message;
 }
 
 function wfCleanFormFields( $fields )
@@ -254,6 +314,7 @@ 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();
@@ -261,16 +322,21 @@ function wfSpecialPage()
        $wgOut->setArticleFlag( false );
        $wgOut->setRobotpolicy( "noindex,follow" );
 
-       $t = $wgTitle->getDBkey();
+       $par = NULL;
+       list($t, $par) = split( "/", $wgTitle->getDBkey(), 2 );
+       
        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();
+               $call( $par );
        } else if ( array_key_exists( $t, $sysopSP ) ) {
                $wgOut->sysopRequired();
        } else if ( array_key_exists( $t, $devSP ) ) {
@@ -307,7 +373,7 @@ function wfNumberOfArticles()
 
        $sql = "SELECT ss_total_views, ss_total_edits, ss_good_articles " .
          "FROM site_stats WHERE ss_row_id=1";
-       $res = wfQuery( $sql, "wfLoadSiteStats" );
+       $res = wfQuery( $sql, DB_READ, "wfLoadSiteStats" );
 
        if ( 0 == wfNumRows( $res ) ) { return; }
        else {
@@ -377,27 +443,38 @@ function wfImageArchiveDir( $fname )
 function wfRecordUpload( $name, $oldver, $size, $desc )
 {
        global $wgUser, $wgLang, $wgTitle, $wgOut, $wgDeferredUpdateList;
+       global $wgUseCopyrightUpload , $wpUploadCopyStatus , $wpUploadSource ;
+       
        $fname = "wfRecordUpload";
 
        $sql = "SELECT img_name,img_size,img_timestamp,img_description,img_user," .
          "img_user_text FROM image WHERE img_name='" . wfStrencode( $name ) . "'";
-       $res = wfQuery( $sql, $fname );
+       $res = wfQuery( $sql, DB_READ, $fname );
+
+       $now = wfTimestampNow();
+       $won = wfInvertTimestamp( $now );
+       
+       if ( $wgUseCopyrightUpload )
+         {
+           $textdesc = "== " . wfMsg ( "filedesc" ) . " ==\n" . $desc . "\n" .
+             "== " . wfMsg ( "filestatus" ) . " ==\n" . $wpUploadCopyStatus . "\n" .
+             "== " . wfMsg ( "filesource" ) . " ==\n" . $wpUploadSource ;
+         }
+       else $textdesc = $desc ;
 
        if ( 0 == wfNumRows( $res ) ) {
                $sql = "INSERT INTO image (img_name,img_size,img_timestamp," .
                  "img_description,img_user,img_user_text) VALUES ('" .
-                 wfStrencode( $name ) . "',{$size},'" . date( "YmdHis" ) . "','" .
+                 wfStrencode( $name ) . "',{$size},'{$now}','" .
                  wfStrencode( $desc ) . "', '" . $wgUser->getID() .
                  "', '" . wfStrencode( $wgUser->getName() ) . "')";
-               wfQuery( $sql, $fname );
+               wfQuery( $sql, DB_WRITE, $fname );
 
                $sql = "SELECT cur_id,cur_text FROM cur WHERE cur_namespace=" .
                  Namespace::getImage() . " AND cur_title='" .
                  wfStrencode( $name ) . "'";
-               $res = wfQuery( $sql, $fname );
+               $res = wfQuery( $sql, DB_READ, $fname );
                if ( 0 == wfNumRows( $res ) ) {
-                       $now = wfTimestampNow();
-                       $won = wfInvertTimestamp( $now );
             $common =
                          Namespace::getImage() . ",'" .
                          wfStrencode( $name ) . "','" .
@@ -406,15 +483,15 @@ function wfRecordUpload( $name, $oldver, $size, $desc )
                          "',1";
                        $sql = "INSERT INTO cur (cur_namespace,cur_title," .
                          "cur_comment,cur_user,cur_user_text,cur_timestamp,cur_is_new," .
-                         "cur_text,inverse_timestamp) VALUES (" .
+                         "cur_text,inverse_timestamp,cur_touched) VALUES (" .
                          $common .
-                         ",'" . wfStrencode( $desc ) . "','{$won}')";
-                       wfQuery( $sql, $fname );
+                         ",'" . wfStrencode( $textdesc ) . "','{$won}','{$now}')";
+                       wfQuery( $sql, DB_WRITE, $fname );
                        $id = wfInsertId() or 0; # We should throw an error instead
                        $sql = "INSERT INTO recentchanges (rc_namespace,rc_title,
                                rc_comment,rc_user,rc_user_text,rc_timestamp,rc_new,
                                rc_cur_id,rc_cur_time) VALUES ({$common},{$id},'{$now}')";
-            wfQuery( $sql, $fname );
+            wfQuery( $sql, DB_WRITE, $fname );
                        $u = new SearchUpdate( $id, $name, $desc );
                        $u->doUpdate();
                }
@@ -429,15 +506,20 @@ function wfRecordUpload( $name, $oldver, $size, $desc )
                  wfStrencode( $s->img_description ) . "','" .
                  wfStrencode( $s->img_user ) . "','" .
                  wfStrencode( $s->img_user_text) . "')";
-               wfQuery( $sql, $fname );
+               wfQuery( $sql, DB_WRITE, $fname );
 
                $sql = "UPDATE image SET img_size={$size}," .
-                 "img_timestamp='" . date( "YmdHis" ) . "',img_user='" .
+                 "img_timestamp='" . wfTimestampNow() . "',img_user='" .
                  $wgUser->getID() . "',img_user_text='" .
                  wfStrencode( $wgUser->getName() ) . "', img_description='" .
                  wfStrencode( $desc ) . "' WHERE img_name='" .
                  wfStrencode( $name ) . "'";
-               wfQuery( $sql, $fname );
+               wfQuery( $sql, DB_WRITE, $fname );
+               
+               $sql = "UPDATE cur SET cur_touched='{$now}' WHERE cur_namespace=" .
+                 Namespace::getImage() . " AND cur_title='" .
+                 wfStrencode( $name ) . "'";
+               wfQuery( $sql, DB_WRITE, $fname );
        }
 
        $log = new LogPage( wfMsg( "uploadlogpage" ), wfMsg( "uploadlogpagetext" ) );
@@ -545,4 +627,32 @@ function wfCheckLimits( $deflimit = 50, $optionname = "rclimit" ) {
        return array( $limit, $offset );
 }
 
+# Escapes the given text so that it may be output using addWikiText() 
+# without any linking, formatting, etc. making its way through. This 
+# is achieved by substituting certain characters with HTML entities.
+# As required by the callers, <nowiki> is not used. It currently does
+# not filter out characters which have special meaning only at the
+# start of a line, such as "*".
+function wfEscapeWikiText( $text )
+{
+       $text = str_replace( 
+               array( '[',     "'",     'ISBN '    , '://'),
+               array( '&#91;', '&#39;', 'ISBN&#32;', '&#58;//'),
+               htmlspecialchars($text) );
+       return $text;
+}
+
+# Loads the entire MediaWiki namespace, retuns the array
+function wfLoadAllMessages()
+{
+       $sql = "SELECT cur_title,cur_text FROM cur WHERE cur_namespace=" . NS_MEDIAWIKI;
+       $res = wfQuery( $sql, DB_READ, $fname );
+       
+       $messages = array();
+       for ( $row = wfFetchObject( $res ); $row; $row = wfFetchObject( $res ) ) {
+               $messages[$row->cur_title] = $row->cur_text;
+       }
+       wfFreeResult( $res );
+       return $messages;
+}
 ?>