Nov. branch merge. Various features backported from stable, various bug fixes.
authorTim Starling <tstarling@users.mediawiki.org>
Sun, 9 Nov 2003 11:45:12 +0000 (11:45 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sun, 9 Nov 2003 11:45:12 +0000 (11:45 +0000)
40 files changed:
INSTALL
LocalSettings.sample
includes/Article.php
includes/DatabaseFunctions.php
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/LinkCache.php
includes/LinksUpdate.php
includes/Math.php
includes/Namespace.php
includes/OutputPage.php
includes/Profiling.php
includes/SearchEngine.php
includes/SearchUpdate.php
includes/Setup.php
includes/Skin.php
includes/SkinCologneBlue.php
includes/SpecialAsksql.php
includes/SpecialIntl.php [deleted file]
includes/SpecialMaintenance.php
includes/SpecialMovepage.php
includes/SpecialPreferences.php
includes/SpecialUpload.php
includes/SpecialUserlogin.php
includes/SpecialUserlogout.php
includes/SpecialWatchlist.php
includes/SpecialWhatlinkshere.php
includes/Title.php
includes/User.php
includes/UserTalkUpdate.php
includes/WatchedItem.php [new file with mode: 0644]
languages/Language.php
maintenance/archives/patch-list.txt
maintenance/indexes.sql
maintenance/rebuildtextindex.inc
stylesheets/cologneblue.css
stylesheets/wikibits.js
stylesheets/wikistandard.css
update.php
wiki.phtml

diff --git a/INSTALL b/INSTALL
index 864f84d..8e4f6cd 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -75,7 +75,7 @@ Downloads:
   apc-cvs.tar.gz
 
 And for math support:
-  ocaml-3.06.tar.gz
+  ocaml-3.06.tar.gz (3.04 doesn't work)
   (TeTeX, ImageMagick, and GhostScript come with most Linux distros)
 
 1. MySQL strongly recommends using gcc 2.95 to compile MySQL.
index 0e13281..f5f05e6 100644 (file)
@@ -37,6 +37,10 @@ $wgDBsqlpassword     = "sqlpass";
 $wgDBminWordLen                = 3;     # Match this to your MySQL fulltext
 $wgDBtransactions   = false; # Set to true if using InnoDB tables
 
+# This code is still slightly experimental. Turn it off if "What links here"
+# and similar stuff does not work.
+$wgUseBetterLinksUpdate=true;
+
 # Turn this on during database maintenance
 # $wgReadOnly = true;
 
@@ -61,4 +65,31 @@ $wgOutputEncoding    = "ISO-8859-1";
 # $wgDisableCounters = true;
 # $wgMiserMode         = true;
 
+# The following three config variables are used to define
+# the rights of users in your system. 
+#
+# If wgWhitelistEdit is set to true, only logged in users
+# are allowed to edit articles.
+# If wgWhitelistRead is set to true, only logged in users
+# are allowed to read articles.
+#
+# wgWhitelistAccount lists user types that can add user accounts:
+# "key" => 1 defines permission if user has right "key".
+#
+# Typical setups are:
+#
+# Everything goes (this is the default behaviour):
+# $wgWhitelistEdit = false;
+# $wgWhitelistRead = false;
+# $wgWhitelistAccount = array ( "user" => 1, "sysop" => 1, "developer" => 1 );
+#
+# Invitation-only closed shop type of system
+# $wgWhitelistEdit = true;
+# $wgWhitelistRead = true;
+# $wgWhitelistAccount = array ( "user" => 0, "sysop" => 1, "developer" => 1 );
+#
+# Public website, closed editorial team
+# $wgWhitelistEdit = true;
+# $wgWhitelistRead = false;
+# $wgWhitelistAccount = array ( "user" => 0, "sysop" => 1, "developer" => 1 );
 ?>
index d7a8fd3..7e2188b 100644 (file)
@@ -5,6 +5,13 @@
 # Note: edit user interface and cache support functions have been
 # moved to separate EditPage and CacheManager classes.
 
+/* CHECK MERGE @@@
+   TEST THIS @@@
+
+   * s/\$wgTitle/\$this->mTitle/ performed, many replacements
+   * mTitle variable added to class
+*/
+
 include_once( "CacheManager.php" );
 
 class Article {
@@ -12,7 +19,7 @@ class Article {
        /* private */ var $mUser, $mTimestamp, $mUserText;
        /* private */ var $mCounter, $mComment, $mCountAdjustment;
        /* private */ var $mMinorEdit, $mRedirectedFrom;
-       /* private */ var $mTouched, $mFileCache;
+       /* private */ var $mTouched, $mFileCache, $mTitle;
 
        function Article( &$title ) {
                $this->mTitle =& $title;
@@ -30,7 +37,7 @@ class Article {
        }
 
        # Note that getContent/loadContent may follow redirects if
-       # not told otherwise, and so may cause a change to wgTitle.
+       # not told otherwise, and so may cause a change to mTitle.
 
        function getContent( $noredir = false )
        {
@@ -95,10 +102,15 @@ class Article {
                # fails we'll have something telling us what we intended.
 
                $t = $this->mTitle->getPrefixedText();
-               if ( $oldid ) { $t .= ",oldid={$oldid}"; }
-               if ( $redirect ) { $t .= ",redirect={$redirect}"; }
-
-               $this->mContent = str_replace( "$1", $t, wfMsg( "missingarticle" ) );
+               if ( isset( $oldid ) ) {
+                       $oldid = IntVal( $oldid );
+                       $t .= ",oldid={$oldid}";
+               }
+               if ( isset( $redirect ) ) {
+                       $redirect = ($redirect == "no") ? "no" : "yes";
+                       $t .= ",redirect={$redirect}";
+               }
+               $this->mContent = wfMsg( "missingarticle", $t );
 
                if ( ! $oldid ) {       # Retrieve current version
                        $id = $this->getID();
@@ -277,7 +289,15 @@ class Article {
                        wfProfileOut( $fname );
                        return;
                }
-               $text = $this->getContent(); # May change wgTitle!
+
+               if ( !isset( $oldid ) ) {
+                       if( $this->checkTouched() ) {
+                               $wgOut->checkLastModified( $this->mTouched );
+                               $this->tryFileCache();
+                       }
+               }
+
+               $text = $this->getContent(); # May change mTitle
                $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
                $wgOut->setHTMLTitle( $this->mTitle->getPrefixedText() .
                  " - " . wfMsg( "wikititlesuffix" ) );
@@ -304,6 +324,308 @@ class Article {
                wfProfileOut( $fname );
        }
 
+       # This is the function that gets called for "action=edit".
+
+       function edit()
+       {
+               global $wgOut, $wgUser;
+               global $wpTextbox1, $wpSummary, $wpSave, $wpPreview;
+               global $wpMinoredit, $wpEdittime, $wpTextbox2;
+
+               $fields = array( "wpTextbox1", "wpSummary", "wpTextbox2" );
+               wfCleanFormFields( $fields );
+
+               if ( ! $this->mTitle->userCanEdit() ) {
+                       $wgOut->readOnlyPage( $this->getContent(), true );
+                       return;
+               }
+               if ( $wgUser->isBlocked() ) {
+                       $this->blockedIPpage();
+                       return;
+               }
+               if ( wfReadOnly() ) {
+                       if( isset( $wpSave ) or isset( $wpPreview ) ) {
+                               $this->editForm( "preview" );
+                       } else {
+                               $wgOut->readOnlyPage( $this->getContent() );
+                       }
+                       return;
+               }
+               if ( $_SERVER['REQUEST_METHOD'] != "POST" ) unset( $wpSave );
+               if ( isset( $wpSave ) ) {
+                       $this->editForm( "save" );
+               } else if ( isset( $wpPreview ) ) {
+                       $this->editForm( "preview" );
+               } else { # First time through
+                       $this->editForm( "initial" );
+               }
+       }
+
+       # Since there is only one text field on the edit form,
+       # pressing <enter> will cause the form to be submitted, but
+       # the submit button value won't appear in the query, so we
+       # Fake it here before going back to edit().  This is kind of
+       # ugly, but it helps some old URLs to still work.
+
+       function submit()
+       {
+               global $wpSave, $wpPreview;
+               if ( ! isset( $wpPreview ) ) { $wpSave = 1; }
+
+               $this->edit();
+       }
+
+       # The edit form is self-submitting, so that when things like
+       # preview and edit conflicts occur, we get the same form back
+       # with the extra stuff added.  Only when the final submission
+       # is made and all is well do we actually save and redirect to
+       # the newly-edited page.
+
+       function editForm( $formtype )
+       {
+               global $wgOut, $wgUser;
+               global $wpTextbox1, $wpSummary, $wpWatchthis;
+               global $wpSave, $wpPreview;
+               global $wpMinoredit, $wpEdittime, $wpTextbox2, $wpSection;
+               global $oldid, $redirect, $section;
+               global $wgLang;
+
+               if(isset($wpSection)) { $section=$wpSection; } else { $wpSection=$section; }
+
+               $sk = $wgUser->getSkin();
+               $isConflict = false;
+               $wpTextbox1 = rtrim ( $wpTextbox1 ) ; # To avoid text getting longer on each preview
+
+               if(!$this->mTitle->getArticleID()) { # new article
+
+                       $wgOut->addWikiText(wfmsg("newarticletext"));
+
+               }
+
+               # Attempt submission here.  This will check for edit conflicts,
+               # and redundantly check for locked database, blocked IPs, etc.
+               # that edit() already checked just in case someone tries to sneak
+               # in the back door with a hand-edited submission URL.
+
+               if ( "save" == $formtype ) {
+                       if ( $wgUser->isBlocked() ) {
+                               $this->blockedIPpage();
+                               return;
+                       }
+                       if ( wfReadOnly() ) {
+                               $wgOut->readOnlyPage();
+                               return;
+                       }
+                       # If article is new, insert it.
+                       
+                       $aid = $this->mTitle->getArticleID();                   
+                       if ( 0 == $aid ) {
+                               # we need to strip Windoze linebreaks because some browsers 
+                               # append them and the string comparison fails
+                               if ( ( "" == $wpTextbox1 ) ||
+                                 ( wfMsg( "newarticletext" ) == rtrim( preg_replace("/\r/","",$wpTextbox1) ) ) ) {
+                                       $wgOut->redirect(  wfLocalUrl(
+                                         $this->mTitle->getPrefixedURL() ) );
+                                       return;
+                               }
+                               $this->mCountAdjustment = $this->isCountable( $wpTextbox1 );
+                               $this->insertNewArticle( $wpTextbox1, $wpSummary, $wpMinoredit, $wpWatchthis );
+                               return;
+                       }
+                       # Article exists. Check for edit conflict.
+                       # Don't check for conflict when appending a comment - this should always work
+
+                       $this->clear(); # Force reload of dates, etc.
+                       if ( $section!="new" && ( $this->getTimestamp() != $wpEdittime ) ) { 
+                               $isConflict = true;             
+                       }
+                       $u = $wgUser->getID();
+
+                       # Supress edit conflict with self
+
+                       if ( ( 0 != $u ) && ( $this->getUser() == $u ) ) {
+                               $isConflict = false;
+                       } else {
+                               # switch from section editing to normal editing in edit conflict
+                               if($isConflict) {
+                                       $section="";$wpSection="";
+                               }
+
+                       }
+                       if ( ! $isConflict ) {
+                               # All's well: update the article here
+                               if($this->updateArticle( $wpTextbox1, $wpSummary, $wpMinoredit, $wpWatchthis, $wpSection ))
+                                       return;
+                               else
+                                       $isConflict = true;
+                       }
+               }
+               # First time through: get contents, set time for conflict
+               # checking, etc.
+
+               if ( "initial" == $formtype ) {
+                       $wpEdittime = $this->getTimestamp();
+                       $wpTextbox1 = $this->getContent(true);
+                       $wpSummary = "";
+               }
+               $wgOut->setRobotpolicy( "noindex,nofollow" );
+               $wgOut->setArticleFlag( false );
+
+               if ( $isConflict ) {
+                       $s = str_replace( "$1", $this->mTitle->getPrefixedText(),
+                         wfMsg( "editconflict" ) );
+                       $wgOut->setPageTitle( $s );
+                       $wgOut->addHTML( wfMsg( "explainconflict" ) );
+
+                       $wpTextbox2 = $wpTextbox1;
+                       $wpTextbox1 = $this->getContent(true);
+                       $wpEdittime = $this->getTimestamp();
+               } else {
+                       $s = str_replace( "$1", $this->mTitle->getPrefixedText(),
+                         wfMsg( "editing" ) );
+
+                       if($section!="") { 
+                               if($section=="new") {
+                                       $s.=wfMsg("commentedit");
+                               } else {
+                                       $s.=wfMsg("sectionedit");
+                               }
+                       }
+                       $wgOut->setPageTitle( $s );
+                       if ( $oldid ) {
+                               $this->setOldSubtitle();
+                               $wgOut->addHTML( wfMsg( "editingold" ) );
+                       }
+               }
+
+               if( wfReadOnly() ) {
+                       $wgOut->addHTML( "<strong>" .
+                               wfMsg( "readonlywarning" ) .
+                               "</strong>" );
+               }
+               if( $this->mTitle->isProtected() ) {
+                       $wgOut->addHTML( "<strong>" . wfMsg( "protectedpagewarning" ) .
+                         "</strong><br />\n" );
+               }
+
+               $kblength = (int)(strlen( $wpTextbox1 ) / 1024);
+               if( $kblength > 29 ) {
+                       $wgOut->addHTML( "<strong>" . 
+                               str_replace( '$1', $kblength , wfMsg( "longpagewarning" ) )
+                               . "</strong>" );
+               }
+               
+               $rows = $wgUser->getOption( "rows" );
+               $cols = $wgUser->getOption( "cols" );
+
+               $ew = $wgUser->getOption( "editwidth" );
+               if ( $ew ) $ew = " style=\"width:100%\"";
+               else $ew = "" ;
+
+               $q = "action=submit";
+               if ( "no" == $redirect ) { $q .= "&redirect=no"; }
+               $action = wfEscapeHTML( wfLocalUrl( $this->mTitle->getPrefixedURL(), $q ) );
+
+               $summary = wfMsg( "summary" );          
+               $subject = wfMsg("subject");
+               $minor = wfMsg( "minoredit" );
+               $watchthis = wfMsg ("watchthis");
+               $save = wfMsg( "savearticle" );
+               $prev = wfMsg( "showpreview" );
+
+               $cancel = $sk->makeKnownLink( $this->mTitle->getPrefixedURL(),
+                 wfMsg( "cancel" ) );
+               $edithelp = $sk->makeKnownLink( wfMsg( "edithelppage" ),
+                 wfMsg( "edithelp" ) );
+               $copywarn = str_replace( "$1", $sk->makeKnownLink(
+                 wfMsg( "copyrightpage" ) ), wfMsg( "copyrightwarning" ) );
+
+               $wpTextbox1 = wfEscapeHTML( $wpTextbox1 );
+               $wpTextbox2 = wfEscapeHTML( $wpTextbox2 );
+               $wpSummary = wfEscapeHTML( $wpSummary );
+               
+               // activate checkboxes if user wants them to be always active
+               if (!$wpPreview && $wgUser->getOption("watchdefault")) $wpWatchthis=1;
+               if (!$wpPreview && $wgUser->getOption("minordefault")) $wpMinoredit=1;          
+               
+               // activate checkbox also if user is already watching the page,
+               // require wpWatchthis to be unset so that second condition is not
+               // checked unnecessarily
+               if (!$wpWatchthis && !$wpPreview && $this->mTitle->userIsWatching()) $wpWatchthis=1;
+               
+               if ( 0 != $wgUser->getID() ) {
+                       $checkboxhtml=
+                       "<input tabindex=3 type=checkbox value=1 name='wpMinoredit'".($wpMinoredit?" checked":"").">{$minor}".
+                       "<input tabindex=4 type=checkbox name='wpWatchthis'".($wpWatchthis?" checked":"").">{$watchthis}<br>";
+                       
+               } else {
+                       $checkboxhtml="";
+               }
+
+
+               if ( "preview" == $formtype) {
+               
+                       $previewhead="<h2>" . wfMsg( "preview" ) . "</h2>\n<p><large><center><font color=\"#cc0000\">" . 
+                       wfMsg( "note" ) . wfMsg( "previewnote" ) . "</font></center></large><P>\n";
+                       if ( $isConflict ) {
+                               $previewhead.="<h2>" . wfMsg( "previewconflict" ) .
+                                 "</h2>\n";
+                       }
+                       $previewtext = wfUnescapeHTML( $wpTextbox1 );
+                       
+                       if($wgUser->getOption("previewontop")) {
+                               $wgOut->addHTML($previewhead);
+                               $wgOut->addWikiText( $this->preSaveTransform( $previewtext ) ."\n\n");
+                       }
+                       $wgOut->addHTML( "<br clear=\"all\" />\n" );
+               }
+
+               # if this is a comment, show a subject line at the top, which is also the edit summary.
+               # Otherwise, show a summary field at the bottom
+               if($section=="new") {
+
+                       $commentsubject="{$subject}: <input tabindex=1 type=text value=\"{$wpSummary}\" name=\"wpSummary\" maxlength=200 size=60><br>";
+               } else {
+
+                       $editsummary="{$summary}: <input tabindex=3 type=text value=\"{$wpSummary}\" name=\"wpSummary\" maxlength=200 size=60><br>";
+               }
+
+               $wgOut->addHTML( "
+<form id=\"editform\" name=\"editform\" method=\"post\" action=\"$action\"
+enctype=\"application/x-www-form-urlencoded\">
+{$commentsubject}
+<textarea tabindex=2 name=\"wpTextbox1\" rows={$rows}
+cols={$cols}{$ew} wrap=\"virtual\">" .
+$wgLang->recodeForEdit( $wpTextbox1 ) .
+"
+</textarea>
+<br>{$editsummary}
+{$checkboxhtml}
+<input tabindex=5 type=submit value=\"{$save}\" name=\"wpSave\">
+<input tabindex=6 type=submit value=\"{$prev}\" name=\"wpPreview\">
+<em>{$cancel}</em> | <em>{$edithelp}</em>
+<br><br>{$copywarn}
+<input type=hidden value=\"{$section}\" name=\"wpSection\">
+<input type=hidden value=\"{$wpEdittime}\" name=\"wpEdittime\">\n" );
+
+               if ( $isConflict ) {
+                       $wgOut->addHTML( "<h2>" . wfMsg( "yourdiff" ) . "</h2>\n" );
+                       DifferenceEngine::showDiff( $wpTextbox2, $wpTextbox1,
+                         wfMsg( "yourtext" ), wfMsg( "storedversion" ) );
+
+                       $wgOut->addHTML( "<h2>" . wfMsg( "yourtext" ) . "</h2>
+<textarea tabindex=6 name=\"wpTextbox2\" rows={$rows} cols={$cols} wrap=virtual>"
+. $wgLang->recodeForEdit( $wpTextbox2 ) .
+"
+</textarea>" );
+               }
+               $wgOut->addHTML( "</form>\n" );
+               if($formtype =="preview" && !$wgUser->getOption("previewontop")) {
+                       $wgOut->addHTML($previewhead);
+                       $wgOut->addWikiText( $this->preSaveTransform( $previewtext ) );
+               }
+       }
+
        # Theoretically we could defer these whole insert and update
        # functions for after display, but that's taking a big leap
        # of faith, and we want to be able to report database
@@ -312,6 +634,8 @@ class Article {
        /* private */ function insertNewArticle( $text, $summary, $isminor, $watchthis )
        {
                global $wgOut, $wgUser, $wgLinkCache, $wgMwRedir;
+               global $wgEnablePersistentLC;
+               
                $fname = "Article::insertNewArticle";
 
                $ns = $this->mTitle->getNamespace();
@@ -338,10 +662,12 @@ class Article {
                $newid = wfInsertId();
                $this->mTitle->resetArticleID( $newid );
 
-               // Purge related entries in links cache on new page, to heal broken links
-               $ptitle = wfStrencode( $ttl );
-               wfQuery("DELETE linkscc FROM linkscc,brokenlinks ".
-                       "WHERE lcc_pageid=bl_from AND bl_to='{$ptitle}'", DB_WRITE);
+               if ( $wgEnablePersistentLC ) {
+                       // Purge related entries in links cache on new page, to heal broken links
+                       $ptitle = wfStrencode( $ttl );
+                       wfQuery("DELETE linkscc FROM linkscc,brokenlinks ".
+                               "WHERE lcc_pageid=bl_from AND bl_to='{$ptitle}'", DB_WRITE);
+               }
                
                $sql = "INSERT INTO recentchanges (rc_timestamp,rc_cur_time," .
                  "rc_namespace,rc_title,rc_new,rc_minor,rc_cur_id,rc_user," .
@@ -363,7 +689,7 @@ class Article {
                $this->showArticle( $text, wfMsg( "newarticle" ) );
        }
 
-       function updateArticle( $text, $summary, $minor, $watchthis, $section="" )
+       function updateArticle( $text, $summary, $minor, $watchthis, $section = "")
        {
                global $wgOut, $wgUser, $wgLinkCache;
                global $wgDBtransactions, $wgMwRedir;
@@ -659,10 +985,9 @@ class Article {
                global $wgUser, $wgOut;
                global $wpConfirm, $wpReason, $image, $oldimage;
 
-               # Anybody can delete old revisions of images; only sysops
-               # can delete articles and current images
-
-               if ( ( ! $oldimage ) && ( ! $wgUser->isSysop() ) ) {
+               # This code desperately needs to be totally rewritten
+               
+               if ( ( ! $wgUser->isSysop() ) ) {
                        $wgOut->sysopRequired();
                        return;
                }
@@ -968,13 +1293,15 @@ class Article {
        /* private */ function viewUpdates()
        {
                global $wgDeferredUpdateList;
-
+               
                if ( 0 != $this->getID() ) {
-                       $u = new ViewCountUpdate( $this->getID() );
-                       array_push( $wgDeferredUpdateList, $u );
-                       $u = new SiteStatsUpdate( 1, 0, 0 );
-                       array_push( $wgDeferredUpdateList, $u );
-
+                       global $wgDisableCounters;
+                       if( !$wgDisableCounters ) {
+                               $u = new ViewCountUpdate( $this->getID() );
+                               array_push( $wgDeferredUpdateList, $u );
+                               $u = new SiteStatsUpdate( 1, 0, 0 );
+                               array_push( $wgDeferredUpdateList, $u );
+                       }
                        $u = new UserTalkUpdate( 0, $this->mTitle->getNamespace(),
                          $this->mTitle->getDBkey() );
                        array_push( $wgDeferredUpdateList, $u );
@@ -1030,6 +1357,28 @@ class Article {
                $wgOut->setSubtitle( "({$r})" );
        }
 
+       function blockedIPpage()
+       {
+               global $wgOut, $wgUser, $wgLang;
+
+               $wgOut->setPageTitle( wfMsg( "blockedtitle" ) );
+               $wgOut->setRobotpolicy( "noindex,nofollow" );
+               $wgOut->setArticleFlag( false );
+
+               $id = $wgUser->blockedBy();
+               $reason = $wgUser->blockedFor();
+
+               $name = User::whoIs( $id );
+               $link = "[[" . $wgLang->getNsText( Namespace::getUser() ) .
+                 ":{$name}|{$name}]]";
+
+               $text = str_replace( "$1", $link, wfMsg( "blockedtext" ) );
+               $text = str_replace( "$2", $reason, $text );
+               $text = str_replace( "$3", getenv( "REMOTE_ADDR" ), $text );
+               $wgOut->addWikiText( $text );
+               $wgOut->returnToMain( false );
+       }
+
        # This function is called right before saving the wikitext,
        # so we can do things like signatures and links-in-context.
 
@@ -1118,8 +1467,10 @@ class Article {
                        }
                        $cache = new CacheManager( $this->mTitle );
                        if($cache->isFileCacheGood( $touched )) {
+                               global $wgOut;
                                wfDebug( " tryFileCache() - about to load\n" );
                                $cache->loadFromFileCache();
+                               $wgOut->reportTime(); # For profiling
                                exit;
                        } else {
                                wfDebug( " tryFileCache() - starting buffer\n" );                       
@@ -1152,10 +1503,19 @@ class Article {
                        and (!isset($redirect))
                        and (!isset($printable))
                        and (!$this->mRedirectedFrom);
-                       
        }
        
-
+       function checkTouched() {
+               $id = $this->getID();
+               $sql = "SELECT cur_touched,cur_is_redirect FROM cur WHERE cur_id=$id";
+               $res = wfQuery( $sql, DB_READ, "Article::checkTouched" );
+               if( $s = wfFetchObject( $res ) ) {
+                       $this->mTouched = $s->cur_touched;
+                       return !$s->cur_is_redirect;
+               } else {
+                       return false;
+               }
+       }
 }
 
 function wfReplaceSubstVar( $matches ) {
index 2d74af4..a61de96 100644 (file)
@@ -95,28 +95,31 @@ function wfEmergencyAbort( $msg = "" ) {
 # Replication is not actually implemented just yet
 function wfQuery( $sql, $db, $fname = "" )
 {
-       global $wgLastDatabaseQuery, $wgOut;
-##     wfProfileIn( "wfQuery" );
+       global $wgLastDatabaseQuery, $wgOut, $wgDebugDumpSql;
+       $profName = "wfQuery(\"" . strtr( substr($sql, 0, 80 ), "\t\n\r", "   " ) . "...\")";
+       wfProfileIn( $profName );
 
        if ( !is_numeric( $db ) ) {
                # Someone has tried to call this the old way
-               $wgOut->fatalError( wfMsgNoDB( "wrong_wfQuery_params" ) );
+               $wgOut->fatalError( wfMsgNoDB( "wrong_wfQuery_params", $db, $sql ) );
        }
        
        $wgLastDatabaseQuery = $sql;
+       
+       if( $wgDebugDumpSql ) {
+               $sqlx = substr( $sql, 0, 500 );
+               $sqlx = wordwrap(strtr($sqlx,"\t\n","  "));
+               wfDebug( "SQL: $sqlx\n" );
+       }
+
        $conn = wfGetDB();
        $ret = mysql_query( $sql, $conn );
 
-       if ( "" != $fname ) {
-#              wfDebug( "{$fname}:SQL: {$sql}\n", true );
-       } else {
-#              wfDebug( "SQL: {$sql}\n", true );
-       }
        if ( false === $ret ) {
                $wgOut->databaseError( $fname );
                exit;
        }
-##     wfProfileOut();
+       wfProfileOut( $profName );
        return $ret;
 }
 
@@ -189,4 +192,34 @@ function wfInvertTimestamp( $ts ) {
        );
 }
 
+function wfFieldExists( $table, $field )
+{
+       $fname = "wfFieldExists";
+       $res = wfQuery( "DESCRIBE $table", DB_READ, $fname );
+       $found = false;
+       
+       while ( $row = wfFetchObject( $res ) ) {
+               if ( $row->Field == $field ) {
+                       $found = true;
+                       break;
+               }
+       }
+       return $found;
+}
+
+function wfIndexExists( $table, $index ) 
+{
+       global $wgDBname;
+       $fname = "wfIndexExists";
+       $sql = "SHOW INDEXES FROM $table";
+       $res = wfQuery( $sql, DB_READ, $fname );
+       $found = false;
+       while ( $row = wfFetchObject( $res ) ) {
+               if ( $row->Key_name == $index ) {
+                       $found = true;
+                       break;
+               }
+       }
+       return $found;
+}
 ?>
index 141169e..69ad5e4 100644 (file)
@@ -6,6 +6,9 @@
 # like $wgScriptPath, you must also localize everything that
 # depends on it.
 
+$wgSitename         = "Wikipedia";
+$wgMetaNamespace    = FALSE; # will be same as you set $wgSitename
+
 $wgServer           = "http://" . getenv( "SERVER_NAME" );
 $wgScriptPath      = "/wiki";
 $wgScript           = "{$wgScriptPath}/wiki.phtml";
@@ -27,7 +30,6 @@ $wgPasswordSender     = "Wikipedia Mail <apache@www.wikipedia.org>\r\nReply-To: webm
 #
 $wgDBserver         = "localhost";
 $wgDBname           = "wikidb";
-$wgDBintlname       = "intl";
 $wgDBconnection     = "";
 $wgDBuser           = "wikiuser";
 $wgDBpassword       = "userpass";
@@ -48,7 +50,6 @@ $wgMemCachedDebug   = false;
 #
 $wgLanguageCode     = "en";
 $wgInterwikiMagic      = true; # Treat language links as magic connectors, not inline links
-$wgUseNewInterlanguage = false;
 $wgInputEncoding       = "ISO-8859-1";
 $wgOutputEncoding      = "ISO-8859-1";
 $wgEditEncoding                = "";
@@ -65,6 +66,9 @@ $wgUseDynamicDates    = true; # Allows the user to pick their preferred date format
 # Not recommended unless memcached is installed
 $wgUseDatabaseMessages = false;
 
+$wgExtraSubtitle       = "";
+$wgSiteSupportPage     = "";
+
 # Miscellaneous configuration settings
 #
 $wgReadOnlyFile         = "{$wgUploadDirectory}/lock_yBgMBwiR";
@@ -74,41 +78,17 @@ $wgReadOnly             = false;
 $wgSqlLogFile           = "{$wgUploadDirectory}/sqllog_mFhyRe6";
 $wgLogQueries           = false;
 $wgUseBetterLinksUpdate = true;
+$wgUseCategoryMagic            = false;
+$wgEnablePersistentLC  = false; # Persistent link cache, needs the linkscc table
 
-# User rights settings
+# User rights 
+$wgWhitelistEdit = false;
+$wgWhitelistRead = false;
+$wgWhitelistAccount = array ( "user" => 1, "sysop" => 1, "developer" => 1 );
 $wgSysopUserBans        = false; # Allow sysops to ban logged-in users
 $wgIPBlockExpiration    = 86400; # IP blocks expire after this many seconds, 0=infinite
 $wgUserBlockExpiration  = 0; # As above, but for logged-in users
 
-# The following three config variables are used to define
-# the rights of users in your system. 
-#
-# If wgWhitelistEdit is set to true, only logged in users
-# are allowed to edit articles.
-# If wgWhitelistRead is set to true, only logged in users
-# are allowed to read articles.
-#
-# wgWhitelistAccount lists user types that can add user accounts:
-# "key" => 1 defines permission if user has right "key".
-#
-# Typical setups are:
-#
-# Everything goes (this is the default behaviour):
-# $wgWhitelistEdit = false;
-# $wgWhitelistRead = false;
-# $wgWhitelistAccount = array ( "user" => 1, "sysop" => 1, "developer" => 1 );
-#
-# Invitation-only closed shop type of system
-# $wgWhitelistEdit = true;
-# $wgWhitelistRead = true;
-# $wgWhitelistAccount = array ( "user" => 0, "sysop" => 1, "developer" => 1 );
-#
-# Public website, closed editorial team
-# $wgWhitelistEdit = true;
-# $wgWhitelistRead = false;
-# $wgWhitelistAccount = array ( "user" => 0, "sysop" => 1, "developer" => 1 );
-
-
 # Client-side caching:
 $wgCachePages       = true; # Allow client-side caching of pages
 
@@ -128,7 +108,20 @@ $wgCookieExpiration = 2592000;
 $wgAllowExternalImages = true;
 $wgMiserMode = false; # Disable database-intensive features
 $wgUseTeX = false;
+
+# Profiling / debugging
 $wgProfiling = false; # Enable for more detailed by-function times in debug log
+$wgProfileLimit = 0.0; # Only record profiling info for pages that took longer than this
+$wgProfileOnly = false; # Don't put non-profiling info into log file
+$wgDebugProfiling = false; # Detects non-matching wfProfileIn/wfProfileOut calls
+$wgDebugFunctionEntry = 0; # Output debug message on every wfProfileIn/wfProfileOut
+
+
+$wgDisableCounters = false;
+$wgDisableTextSearch = false;
+$wgDisableSearchUpdate = false; # If you've disabled search semi-permanently, this also disables updates to the table. If you ever re-enable, be sure to rebuild the search table.
+$wgDisableUploads = false;
+$wgDisableAnonTalk = false;
 
 # We can serve pages compressed in order to save bandwidth,
 # but this will increase CPU usage.
index 42dd1a1..801bde2 100644 (file)
@@ -25,6 +25,17 @@ if ( phpversion() == "4.0.6" ) {
        }
 }
 
+if( !function_exists('iconv') ) {
+       # Assume will only ever use utf-8 and iso-8859-1.
+       # This will *not* work in all circumstances.
+       function iconv( $from, $to, $string ) {
+               if(strcasecmp( $from, to ) == 0) return $string;
+               if(strcasecmp( $from, "utf-8" ) == 0) return utf8_decode( $string );
+               if(strcasecmp( $to, "utf-8" ) == 0) return utf8_encode( $string );
+               return $string;
+       }
+}
+
 $wgRandomSeeded = false;
 
 function wfSeedRandom()
@@ -78,6 +89,8 @@ function wfImageUrl( $img )
        global $wgUploadPath;
 
        $nt = Title::newFromText( $img );
+       if( !$nt ) return "";
+
        $name = $nt->getDBkey();
        $hash = md5( $name );
 
@@ -130,12 +143,12 @@ function wfMungeToUtf8($string) {
 
 function wfDebug( $text, $logonly = false )
 {
-       global $wgOut, $wgDebugLogFile, $wgDebugComments;
+       global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly;
 
        if ( $wgDebugComments && !$logonly ) {
                $wgOut->debug( $text );
        }
-       if ( "" != $wgDebugLogFile ) {
+       if ( "" != $wgDebugLogFile && !$wgProfileOnly ) {
                error_log( $text, 3, $wgDebugLogFile );
        }
 }
@@ -462,6 +475,9 @@ function wfRecordUpload( $name, $oldver, $size, $desc )
          }
        else $textdesc = $desc ;
 
+       $now = wfTimestampNow();
+       $won = wfInvertTimestamp( $now );
+       
        if ( 0 == wfNumRows( $res ) ) {
                $sql = "INSERT INTO image (img_name,img_size,img_timestamp," .
                  "img_description,img_user,img_user_text) VALUES ('" .
index 23f5182..212b214 100644 (file)
@@ -137,24 +137,27 @@ class LinkCache {
 
        function preFill( &$fromtitle )
        {
+               global $wgEnablePersistentLC;
+
                $fname = "LinkCache::preFill";
                wfProfileIn( $fname );
                # Note -- $fromtitle is a Title *object*
                $dbkeyfrom = wfStrencode( $fromtitle->getPrefixedDBKey() );
 
-
-               $res = wfQuery("SELECT lcc_cacheobj FROM linkscc WHERE lcc_title = '{$dbkeyfrom}'", 
-                              DB_READ);
-               $row = wfFetchObject( $res );
-               if( $row != FALSE){
-                 $cacheobj = gzuncompress( $row->lcc_cacheobj );
-                 $cc = unserialize( $cacheobj );
-                 $this->mGoodLinks = $cc->mGoodLinks;
-                 $this->mBadLinks = $cc->mBadLinks;
-                 $this->mPreFilled = true;
-                 wfProfileOut( $fname );
-                 return;
-               } 
+               if ( $wgEnablePersistentLC ) {
+                       $res = wfQuery("SELECT lcc_cacheobj FROM linkscc WHERE lcc_title = '{$dbkeyfrom}'", 
+                               DB_READ);
+                       $row = wfFetchObject( $res );
+                       if( $row != FALSE){
+                               $cacheobj = gzuncompress( $row->lcc_cacheobj );
+                               $cc = unserialize( $cacheobj );
+                               $this->mGoodLinks = $cc->mGoodLinks;
+                               $this->mBadLinks = $cc->mBadLinks;
+                               $this->mPreFilled = true;
+                               wfProfileOut( $fname );
+                               return;
+                       } 
+               }
 
 
                $sql = "SELECT cur_id,cur_namespace,cur_title
@@ -183,10 +186,12 @@ class LinkCache {
                $this->mOldGoodLinks = $this->mGoodLinks;
                $this->mPreFilled = true;
 
-               // put fetched link data into cache
-               $serCachegz = wfStrencode( gzcompress( serialize( $this ), 3) );
-               wfQuery("REPLACE INTO linkscc VALUES({$id}, '{$dbkeyfrom}', '{$serCachegz}')", 
-                       DB_WRITE);
+               if ( $wgEnablePersistentLC ) {
+                       // put fetched link data into cache
+                       $serCachegz = wfStrencode( gzcompress( serialize( $this ), 3) );
+                       wfQuery("REPLACE INTO linkscc VALUES({$id}, '{$dbkeyfrom}', '{$serCachegz}')", 
+                               DB_WRITE);
+               }
 
                wfProfileOut( $fname );
        }
index b87f2c4..3666190 100644 (file)
@@ -16,12 +16,15 @@ class LinksUpdate {
        function doUpdate()
        {
                global $wgUseBetterLinksUpdate, $wgLinkCache, $wgDBtransactions;
-               
+               global $wgEnablePersistentLC;
+
                /* Update link tables with outgoing links from an updated article */
                /* Relies on the 'link cache' to be filled out */
 
-               // Make sure links cache is regenerated on next load
-               wfQuery("DELETE FROM linkscc WHERE lcc_title = '{$safeTitle}'", DB_WRITE);
+               if ( $wgEnablePersistentLC ) {
+                       // Make sure links cache is regenerated on next load
+                       wfQuery("DELETE FROM linkscc WHERE lcc_title = '{$safeTitle}'", DB_WRITE);
+               }
 
                if ( !$wgUseBetterLinksUpdate ) {
                        $this->doDumbUpdate();
@@ -121,10 +124,15 @@ class LinksUpdate {
                
                # Do the insertion
                $sql = "";
+               $image = Namespace::getImage();
                if ( 0 != count ( $add ) ) {
                        $sql = "INSERT INTO imagelinks (il_from,il_to) VALUES ";
                        $first = true;
                        foreach( $add as $iname => $val ) {
+                               # FIXME: Change all this to avoid unnecessary duplication
+                               $nt = Title::makeTitle( $image, $iname );
+                               $nt->invalidateCache();
+
                                $iname = wfStrencode( $iname );
                                if ( ! $first ) { $sql .= ","; }
                                $first = false;
index 3479a99..8554ac1 100644 (file)
@@ -2,8 +2,8 @@
 
 function linkToMathImage ( $tex, $outputhash )
 {
-    global $wgMathPath;
-    return "<img src=\"".$wgMathPath."/".$outputhash.".png\" alt=\"".wfEscapeHTML($tex)."\">";
+       global $wgMathPath;
+       return "<img src=\"".$wgMathPath."/".$outputhash.".png\" alt=\"".wfEscapeHTML($tex)."\">";
 }
 
 function renderMath( $tex )
@@ -26,8 +26,18 @@ function renderMath( $tex )
        $sql = "SELECT math_outputhash,math_html_conservativeness,math_html FROM math WHERE math_inputhash = '".$md5_sql."'";
 
     $res = wfQuery( $sql, DB_READ, $fname );
-    if ( wfNumRows( $res ) == 0 )
-    {
+
+       if( $rpage = wfFetchObject ( $res ) ) {
+               $outputhash = unpack( "H32md5", $rpage->math_outputhash . "                " );
+               $outputhash = $outputhash ['md5'];
+               if( file_exists( "$wgMathDirectory/$outputhash.png" ) ) {
+                       if (($math == 0) || ($rpage->math_html == '') || (($math == 1) && ($rpage->math_html_conservativeness != 2)) || (($math == 4) && ($rpage->math_html_conservativeness == 0)))
+                           return linkToMathImage ( $tex, $outputhash );
+                       else
+                       return $rpage->math_html;
+               }
+       }
+       
        $cmd = "./math/texvc ".escapeshellarg($wgTmpDirectory)." ".
                      escapeshellarg($wgMathDirectory)." ".escapeshellarg($tex)." ".escapeshellarg($wgInputEncoding);
        $contents = `$cmd`;
@@ -94,23 +104,13 @@ function renderMath( $tex )
 
        $sql = "REPLACE INTO math VALUES ('".$md5_sql."', '".$outmd5_sql."', ".$conservativeness.", ".$sql_html.", ".$sql_mathml.")";
        
-       $res = wfQuery( $sql, DB_WRITE, $fname );
+       $res = wfQuery( $sql, DB_READ, $fname );
        # we don't really care if it fails
 
        if (($math == 0) || ($rpage->math_html == '') || (($math == 1) && ($conservativeness != 2)) || (($math == 4) && ($conservativeness == 0)))
            return linkToMathImage($tex, $outmd5);
        else
            return $outhtml;
-    } else {
-       $rpage = wfFetchObject ( $res );
-       $outputhash = unpack( "H32md5", $rpage->math_outputhash . "                " );
-       $outputhash = $outputhash ['md5'];
-       
-       if (($math == 0) || ($rpage->math_html == '') || (($math == 1) && ($rpage->math_html_conservativeness != 2)) || (($math == 4) && ($rpage->math_html_conservativeness == 0)))
-           return linkToMathImage ( $tex, $outputhash );
-       else
-           return $rpage->math_html;
-    }
 }
 
 ?>
index 03b351f..670f880 100644 (file)
@@ -10,6 +10,7 @@ class Namespace {
        function getUser() { return 2; }
        function getWikipedia() { return 4; }
        function getImage() { return 6; }
+       function getMedia() { return -2; }
 
        function isMovable( $index )
        {
index 2681301..b743174 100644 (file)
@@ -57,7 +57,7 @@ class OutputPage {
                        max( $timestamp, $wgUser->mTouched ) ) ) . " GMT";
                
                if( $_SERVER["HTTP_IF_MODIFIED_SINCE"] != "" ) {
-                       # IE sends sizes after the date for compressed pages:
+                       # IE sends sizes after the date like this:
                        # Wed, 20 Aug 2003 06:51:19 GMT; length=5202
                        # this breaks strtotime().
                        $modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
@@ -72,6 +72,7 @@ class OutputPage {
                                header( "Cache-Control: private, must-revalidate, max-age=0" );
                                header( "Last-Modified: {$lastmod}" );                  
                                wfDebug( "CACHED client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
+                               $this->reportTime(); # For profiling
                                exit;
                        } else {
                                wfDebug( "READY  client: $ismodsince ; user: $wgUser->mTouched ; page: $timestamp\n", false );
@@ -95,30 +96,10 @@ class OutputPage {
        function isPrintable() { return $this->mPrintable; }
 
        function getLanguageLinks() {
-               global $wgUseNewInterlanguage, $wgTitle, $wgLanguageCode;
-               global $wgDBconnection, $wgDBname, $wgDBintlname;
-
-               if ( ! $wgUseNewInterlanguage )
-                       return $this->mLanguageLinks; 
-               
-               mysql_select_db( $wgDBintlname, $wgDBconnection ) or die(
-                         htmlspecialchars(mysql_error()) );
-
-               $list = array();
-               $sql = "SELECT * FROM ilinks WHERE lang_from=\"" .
-                 "{$wgLanguageCode}\" AND title_from=\"" . $wgTitle->getDBkey() . "\"";
-               $res = mysql_query( $sql, $wgDBconnection );
-
-               while ( $q = mysql_fetch_object ( $res ) ) {
-                       $list[] = $q->lang_to . ":" . $q->title_to;
-               }
-               mysql_free_result( $res );
-               mysql_select_db( $wgDBname, $wgDBconnection ) or die(
-                 htmlspecialchars(mysql_error()) );
-
-               return $list;
+               global $wgTitle, $wgLanguageCode;
+               global $wgDBconnection, $wgDBname;
+               return $this->mLanguageLinks;
        }
-
        function supressQuickbar() { $this->mSupressQuickbar = true; }
        function isQuickbarSupressed() { return $this->mSupressQuickbar; }
 
@@ -323,7 +304,7 @@ class OutputPage {
        function reportTime()
        {
                global $wgRequestTime, $wgDebugLogFile, $HTTP_SERVER_VARS;
-               global $wgProfiling, $wgProfileStack, $wgUser;
+               global $wgProfiling, $wgProfileStack, $wgProfileLimit, $wgUser;
 
                list( $usec, $sec ) = explode( " ", microtime() );
                $now = (float)$sec + (float)$usec;
@@ -334,7 +315,6 @@ class OutputPage {
 
                if ( "" != $wgDebugLogFile ) {
                        $prof = wfGetProfilingOutput( $start, $elapsed );
-               
                        if( $forward = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'] )
                                $forward = " forwarded for $forward";
                        if( $client = $HTTP_SERVER_VARS['HTTP_CLIENT_IP'] )
@@ -443,25 +423,30 @@ class OutputPage {
                exit();
        }
 
-       function readOnlyPage( $source = "" )
+       function readOnlyPage( $source = "", $protected = false )
        {
                global $wgUser, $wgReadOnlyFile;
 
-               $this->setPageTitle( wfMsg( "readonly" ) );
                $this->setRobotpolicy( "noindex,nofollow" );
                $this->setArticleFlag( false );
 
-               $reason = implode( "", file( $wgReadOnlyFile ) );
-               $text = str_replace( "$1", $reason, wfMsg( "readonlytext" ) );
+               if( $protected ) {
+                       $this->setPageTitle( wfMsg( "viewsource" ) );
+                       $this->addWikiText( wfMsg( "protectedtext" ) );
+               } else {
+                       $this->setPageTitle( wfMsg( "readonly" ) );
+                       $reason = file_get_contents( $wgReadOnlyFile );
+                       $this->addHTML( wfMsg( "readonlytext", $reason ) );
+               }
                
                if($source) {
                        $rows = $wgUser->getOption( "rows" );
                        $cols = $wgUser->getOption( "cols" );
                        $text .= "</p>\n<textarea cols='$cols' rows='$rows' readonly>" .
                                htmlspecialchars( $source ) . "\n</textarea>";
+                       $this->addHTML( $text );
                }
                
-               $this->addHTML( $text );
                $this->returnToMain( false );
        }
 
@@ -920,61 +905,67 @@ $t[] = "</table>" ;
                $s = array_shift( $a );
                $s = substr( $s, 1 );
 
-               $e1 = "/^([{$tc}]+)\\|([^]]+)]](.*)\$/sD";
-               $e2 = "/^([{$tc}]+)]](.*)\$/sD";
+               $e1 = "/^([{$tc}]+)(?:\\|([^]]+))?]](.*)\$/sD";
+
+               # Special and Media are pseudo-namespaces; no pages actually exist in them
+               $image = Namespace::getImage();
+               $special = Namespace::getSpecial();
+               $media = Namespace::getMedia();
+               $nottalk = !Namespace::isTalk( $wgTitle->getNamespace() );
                wfProfileOut( "$fname-setup" );
 
                foreach ( $a as $line ) {
-                       if ( preg_match( $e1, $line, $m ) ) { # page with alternate text
-                               
+                       if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
                                $text = $m[2];
                                $trail = $m[3];                         
-                       
-                       } else if ( preg_match( $e2, $line, $m ) ) { # page with normal text
-                       
-                               $text = "";
-                               $trail = $m[2];                 
-                       }
-                       
-                       else { # Invalid form; output directly
+                       } else { # Invalid form; output directly
                                $s .= "[[" . $line ;
                                continue;
                        }
-                       if(substr($m[1],0,1)=="/") { # subpage
+                       
+                       /* Valid link forms:
+                       Foobar -- normal
+                       :Foobar -- override special treatment of prefix (images, language links)
+                       /Foobar -- convert to CurrentPage/Foobar
+                       /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text
+                       */
+                       $c = substr($m[1],0,1);
+                       $noforce = ($c != ":");
+                       if( $c == "/" ) { # subpage
                                if(substr($m[1],-1,1)=="/") {                 # / at end means we don't want the slash to be shown
                                        $m[1]=substr($m[1],1,strlen($m[1])-2); 
                                        $noslash=$m[1];
-                                       
                                } else {
                                        $noslash=substr($m[1],1);
                                }
                                if($wgNamespacesWithSubpages[$wgTitle->getNamespace()]) { # subpages allowed here
                                        $link = $wgTitle->getPrefixedText(). "/" . trim($noslash);
-                                       if(!$text) {                                            
+                                       if(!$text) {
                                                $text= $m[1]; 
                                        } # this might be changed for ugliness reasons
                                } else {
                                        $link = $noslash; # no subpage allowed, use standard link
                                }
-                       } else { # no subpage
-                               $link = $m[1]; 
+                       } elseif( $noforce ) { # no subpage
+                               $link = $m[1];
+                       } else {
+                               $link = substr( $m[1], 1 );
                        }
-                       
-                       if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z\\x80-\\xff]+):(.*)\$/", $link,  $m ) ) {
-                               $pre = strtolower( $m[1] );
-                               $suf = trim($m[2]);
-                               if( empty( $suf ) ) {
-                                       $s .= $trail;
-                               } else if ( $wgLang->getNsIndex( $pre ) ==
-                                 Namespace::getImage() ) {
-                                       $nt = Title::newFromText( $suf );
-                                       $name = $nt->getDBkey();
-                                       if ( "" == $text ) { $text = $nt->GetText(); }
+                       if( empty( $text ) )
+                               $text = $link;
 
-                                       $wgLinkCache->addImageLink( $name );
-                                       $s .= $sk->makeImageLink( $name,
-                                         wfImageUrl( $name ), $text );
+                       $nt = Title::newFromText( $link );
+                       if( !$nt ) {
+                               $s .= "[[" . $line;
+                               continue;
+                       }
+                       $ns = $nt->getNamespace();
+                       $iw = $nt->getInterWiki();
+                       if( $noforce ) {
+                               if( $iw && $wgInterwikiMagic && $nottalk && $wgLang->getLanguageName( $iw ) ) {
+                                       array_push( $this->mLanguageLinks, $nt->getPrefixedText() );
                                        $s .= $trail;
+/* CHECK MERGE @@@
                                } else if ( "media" == $pre ) {
                                        $nt = Title::newFromText( $suf );
                                        $name = $nt->getDBkey();
@@ -999,7 +990,15 @@ $t[] = "</table>" ;
                                                array_push( $this->mLanguageLinks, "$pre:$suf" );
                                                $s .= $trail;
                                        }
+*/
+                                       continue;
                                }
+                               if( $ns == $image ) {
+                                       $s .= $sk->makeImageLinkObj( $nt, $text ) . $trail;
+                                       $wgLinkCache->addImageLinkObj( $nt );
+                                       continue;
+                               }
+/* CHECK MERGE @@@
 #                      } else if ( 0 == strcmp( "##", substr( $link, 0, 2 ) ) ) {
 #                              $link = substr( $link, 2 );
 #                              $s .= "<a name=\"{$link}\">{$text}</a>{$trail}";
@@ -1007,7 +1006,17 @@ $t[] = "</table>" ;
                                if ( "" == $text ) { $text = $link; }
                                # Hotspot: 
                                $s .= $sk->makeLink( $link, $text, "", $trail );
+*/
+                       }
+                       if( $ns == $media ) {
+                               $s .= $sk->makeMediaLinkObj( $nt, $text ) . $trail;
+                               $wgLinkCache->addImageLinkObj( $nt );
+                               continue;
+                       } elseif( $ns == $special ) {
+                               $s .= $sk->makeKnownLinkObj( $nt, $text, "", $trail );
+                               continue;
                        }
+                       $s .= $sk->makeLinkObj( $nt, $text, "", $trail );
                }
                wfProfileOut( $fname );
                return $s;
@@ -1433,7 +1442,7 @@ $t[] = "</table>" ;
                                        }
                                }
                        }
-                       
+
                        // The canonized header is a version of the header text safe to use for links
                        
                        $canonized_headline=preg_replace("/<.*?>/","",$headline); // strip out HTML
@@ -1443,8 +1452,8 @@ $t[] = "</table>" ;
                        $refer[$c]=$canonized_headline;
                        $refers[$canonized_headline]++;  // count how many in assoc. array so we can track dupes in anchors
                        $refcount[$c]=$refers[$canonized_headline];
-                       
-                       // Prepend the number to the heading text
+
+            // Prepend the number to the heading text
                        
                        if($nh||$st) {
                                $tocline=$numbering ." ". $tocline;
index 7be7028..20e1939 100755 (executable)
@@ -1,7 +1,5 @@
 <?
 # This file is only included if profiling is enabled
-$wgDebugProfiling = true;
-
 function wfProfileIn( $functionname )
 {
        global $wgProfiler;
@@ -40,12 +38,20 @@ class Profiler
        
        function profileIn( $functionname )
        {
+               global $wgDebugFunctionEntry;
+               if ( $wgDebugFunctionEntry && function_exists( "wfDebug" ) ) {
+                       wfDebug( "Entering $functionname\n" );
+               }
                array_push( $this->mWorkStack, array($functionname, count( $this->mWorkStack ), microtime() ) );
        }
 
        function profileOut( $functionname) 
        {
-               global $wgDebugProfiling;
+               global $wgDebugProfiling, $wgDebugFunctionEntry;
+               if ( $wgDebugFunctionEntry && function_exists( "wfDebug" ) ) {
+                       wfDebug( "Exiting $functionname\n" );
+               }
+               
                $bit = array_pop( $this->mWorkStack );
                
                if ( !$bit ) {
@@ -75,9 +81,9 @@ class Profiler
                if( !count( $this->mStack ) ) {
                        return "No profiling output\n";
                }
-               
-               $format = "%-49s %6d %6.3f %6.3f %6.3f%%\n";
-               $titleFormat = "%-49s %9s %9s %9s %9s\n";
+               $width = 125;
+               $format = "%-" . ($width - 28) . "s %6d %6.3f %6.3f %6.3f%%\n";
+               $titleFormat = "%-" . ($width - 28) . "s %9s %9s %9s %9s\n";
                $prof = "\nProfiling data\n";
                $prof .= sprintf( $titleFormat, "Name", "Calls", "Total", "Each", "%" );
                $this->mCollated = array();
index 6965eb7..6739bf5 100644 (file)
@@ -37,14 +37,12 @@ class SearchEngine {
                return "AND cur_is_redirect=0 ";
        }
 
-
-
        /* private */ function initNamespaceCheckbox( $i )
        {
                global $wgUser, $wgNamespacesToBeSearchedDefault;
                
 
-               if ($wgUser->getRights()) {
+               if ($wgUser->getID()) {
                        // User is logged in so we retrieve his default namespaces
                        return $wgUser->getOption( "searchNs".$i );
                }
@@ -54,59 +52,55 @@ class SearchEngine {
                }
        }
 
-
-
+       # Display the "power search" footer. Does not actually perform the search, 
+       # that is done by showResults()
        function powersearch()
        {
                global $wgUser, $wgOut, $wgLang, $wgTitle;
-               $nscb = array();
 
                $search                 = $_REQUEST['search'];
                $searchx                = $_REQUEST['searchx'];
                $listredirs             = $_REQUEST['redirs'];
-
-
-               if ( ! isset ( $searchx ) ) {   /* First time here */
-                       $listredirs = 1;
-                       for ($i = 0; ($i <= 7); $i++)
-                       {
-                               $nscb[$i] = $this->initNamespaceCheckbox($i);
+               
+               $ret = wfMsg("powersearchtext"); # Text to be returned
+               $tempText = ""; # Temporary text, for substitution into $ret    
+
+               # Do namespace checkboxes
+               $namespaces = $wgLang->getNamespaces();
+               foreach ( $namespaces as $i => $namespace ) {
+                       # Skip virtual namespaces
+                       if ( $i < 0 ) {
+                               continue;
                        }
-               } else {
-                       $nscb[0]                = $_REQUEST['ns0'];
-                       $nscb[1]                = $_REQUEST['ns1'];
-                       $nscb[2]                = $_REQUEST['ns2'];
-                       $nscb[3]                = $_REQUEST['ns3'];
-                       $nscb[4]                = $_REQUEST['ns4'];
-                       $nscb[5]                = $_REQUEST['ns5'];
-                       $nscb[6]                = $_REQUEST['ns6'];
-                       $nscb[7]                = $_REQUEST['ns7'];
-               }
 
-               $this->checkboxes["searchx"] = 1;
-               $ret = wfMsg("powersearchtext");
+                       $formVar = "ns$i";
 
-               # Determine namespace checkboxes
-
-               $ns = $wgLang->getNamespaces();
-               array_shift( $ns ); /* Skip "Special" */
+                       # Initialise checkboxValues, either from defaults or from 
+                       # a previous invocation
+                       if ( !isset( $searchx ) ) {
+                               $checkboxValue = $this->initNamespaceCheckbox( $i );
+                       } else {
+                               $checkboxValue = $_REQUEST[$formVar];
+                       }
 
-               $r1 = "";
-               for ( $i = 0; $i < count( $ns ); ++$i ) {
                        $checked = "";
-                       if ( $nscb[$i] == 1 ) {
+                       if ( $checkboxValue == 1 ) {
                                $checked = " checked";
                                $this->addtoquery["ns{$i}"] = 1;
                                array_push( $this->namespacesToSearch, $i );
                        }
-                       $name = str_replace( "_", " ", $ns[$i] );
-                       if ( "" == $name ) { $name = wfMsg( "blanknamespace" ); }
+                       $name = str_replace( "_", " ", $namespaces[$i] );
+                       if ( "" == $name ) { 
+                               $name = wfMsg( "blanknamespace" ); 
+                       }
 
-                       if ( 0 != $i ) { $r1 .= " "; }
-                       $r1 .= "<input type=checkbox value=\"1\" name=\"" .
+                       if ( $tempText !== "" ) { 
+                               $tempText .= " "; 
+                       }
+                       $tempText .= "<input type=checkbox value=\"1\" name=\"" .
                          "ns{$i}\"{$checked}>{$name}\n";
                }
-               $ret = str_replace ( "$1", $r1, $ret );
+               $ret = str_replace ( "$1", $tempText, $ret );
 
                # List redirects checkbox
 
@@ -115,30 +109,33 @@ class SearchEngine {
                        $this->addtoquery["redirs"] = 1;
                        $checked = " checked";
                }
-               $r2 = "<input type=checkbox value=1 name=\"redirs\"{$checked}>\n";
-               $ret = str_replace( "$2", $r2, $ret );
+               $tempText = "<input type=checkbox value=1 name=\"redirs\"{$checked}>\n";
+               $ret = str_replace( "$2", $tempText, $ret );
 
                # Search field
 
-               $r3 = "<input type=text name=\"search\" value=\"" .
+               $tempText = "<input type=text name=\"search\" value=\"" .
                        htmlspecialchars( $search ) ."\" width=80>\n";
-        $ret = str_replace( "$3", $r3, $ret );
+        $ret = str_replace( "$3", $tempText, $ret );
 
                # Searchx button
 
-               $r9 = "<input type=submit name=\"searchx\" value=\"" .
+               $tempText = "<input type=submit name=\"searchx\" value=\"" .
                  wfMsg("powersearch") . "\">\n";
-               $ret = str_replace( "$9", $r9, $ret );
+               $ret = str_replace( "$9", $tempText, $ret );
 
                $ret = "<br><br>\n<form id=\"powersearch\" method=\"get\" " .
                  "action=\"" . wfLocalUrl( "" ) . "\">\n{$ret}\n</form>\n";
 
                if ( isset ( $searchx ) ) {
-                       if ( ! $listredirs ) { $this->doSearchRedirects = false; }
+                       if ( ! $listredirs ) { 
+                               $this->doSearchRedirects = false; 
+                       }
                }
                return $ret;
        }
 
+       # Perform the search and construct the results page
        function showResults()
        {
                global $wgUser, $wgTitle, $wgOut, $wgLang, $wgDisableTextSearch;
@@ -180,8 +177,32 @@ class SearchEngine {
                $num = wfNumRows($res1);
 
                if ( $wgDisableTextSearch ) {
-                       $res2 = 0;
+                       $wgOut->addHTML( wfMsg( "searchdisabled", $search, $wgInputEncoding ) );
                } else {
+                       $sk = $wgUser->getSkin();
+                       $text = wfMsg( "searchresulttext", $sk->makeKnownLink(
+                         wfMsg( "searchhelppage" ), wfMsg( "searchingwikipedia" ) ) );
+                       $wgOut->addHTML( $text );
+       
+                       $this->parseQuery();
+                       if ( "" == $this->mTitlecond || "" == $this->mTextcond ) {
+                               $wgOut->addHTML( "<h2>" . wfMsg( "badquery" ) . "</h2>\n" .
+                                 "<p>" . wfMsg( "badquerytext" ) );
+                               return;
+                       }
+                       list( $limit, $offset ) = wfCheckLimits( 20, "searchlimit" );
+       
+                       $searchnamespaces = $this->queryNamespaces();
+                       $redircond = $this->searchRedirects();
+       
+                       $sql = "SELECT cur_id,cur_namespace,cur_title," .
+                         "cur_text FROM cur,searchindex " .
+                         "WHERE cur_id=si_page AND {$this->mTitlecond} " .
+                         "{$searchnamespaces} {$redircond}" .
+                         "LIMIT {$offset}, {$limit}";
+                       $res1 = wfQuery( $sql, DB_READ, $fname );
+                       $num = wfNumRows($res1);
+       
                        $sql = "SELECT cur_id,cur_namespace,cur_title," .
                          "cur_text FROM cur,searchindex " .
                          "WHERE cur_id=si_page AND {$this->mTextcond} " .
@@ -189,45 +210,45 @@ class SearchEngine {
                          "LIMIT {$offset}, {$limit}";
                        $res2 = wfQuery( $sql, DB_READ, $fname );
                        $num = $num + wfNumRows($res2);
-               }
-
-                if ( $num == $limit ) {
-                 $top = wfShowingResults( $offset, $limit);
-               } else {
-                 $top = wfShowingResultsNum( $offset, $limit, $num );
-               }
-               $wgOut->addHTML( "<p>{$top}\n" );
-
-               # For powersearch
-
-               $a2l = "" ;
-               $akk = array_keys( $this->addtoquery ) ;
-               foreach ( $akk AS $ak ) {
-                       $a2l .= "&{$ak}={$this->addtoquery[$ak]}" ;
-               }
 
-               $sl = wfViewPrevNext( $offset, $limit, "",
-                 "search=" . wfUrlencode( $this->mUsertext ) . $a2l );
-               $wgOut->addHTML( "<br>{$sl}\n" );
-
-               $foundsome = false;
-
-               if ( 0 == wfNumRows( $res1 ) ) {
-                       $wgOut->addHTML( "<h2>" . wfMsg( "notitlematches" ) .
-                         "</h2>\n" );
-               } else {
-                       $foundsome = true;
-                       $off = $offset + 1;
-                       $wgOut->addHTML( "<h2>" . wfMsg( "titlematches" ) .
-                         "</h2>\n<ol start='{$off}'>" );
-
-                       while ( $row = wfFetchObject( $res1 ) ) {
-                               $this->showHit( $row );
+                       if ( $num == $limit ) {
+                         $top = wfShowingResults( $offset, $limit);
+                       } else {
+                         $top = wfShowingResultsNum( $offset, $limit, $num );
+                       }
+                       $wgOut->addHTML( "<p>{$top}\n" );
+       
+                       # For powersearch
+       
+                       $a2l = "" ;
+                       $akk = array_keys( $this->addtoquery ) ;
+                       foreach ( $akk AS $ak ) {
+                               $a2l .= "&{$ak}={$this->addtoquery[$ak]}" ;
+                       }
+       
+                       $sl = wfViewPrevNext( $offset, $limit, "",
+                         "search=" . wfUrlencode( $this->mUsertext ) . $a2l );
+                       $wgOut->addHTML( "<br>{$sl}\n" );
+       
+                       $foundsome = false;
+       
+                       if ( 0 == wfNumRows( $res1 ) ) {
+                               $wgOut->addHTML( "<h2>" . wfMsg( "notitlematches" ) .
+                                 "</h2>\n" );
+                       } else {
+                               $foundsome = true;
+                               $off = $offset + 1;
+                               $wgOut->addHTML( "<h2>" . wfMsg( "titlematches" ) .
+                                 "</h2>\n<ol start='{$off}'>" );
+       
+                               while ( $row = wfFetchObject( $res1 ) ) {
+                                       $this->showHit( $row );
+                               }
+                               wfFreeResult( $res1 );
+                               $wgOut->addHTML( "</ol>\n" );
                        }
-                       wfFreeResult( $res1 );
-                       $wgOut->addHTML( "</ol>\n" );
                }
-
+               
                if ( $wgDisableTextSearch ) {
                        $wgOut->addHTML( wfMsg( "searchdisabled", $search, $wgInputEncoding ) );
                } else {
@@ -245,12 +266,12 @@ class SearchEngine {
                                wfFreeResult( $res2 );
                                $wgOut->addHTML( "</ol>\n" );
                        }
+                       if ( ! $foundsome ) {
+                               $wgOut->addHTML( "<p>" . wfMsg( "nonefound" ) . "\n" );
+                       }
+                       $wgOut->addHTML( "<p>{$sl}\n" );
+                       $wgOut->addHTML( $powersearch );
                }
-               if ( ! $foundsome ) {
-                       $wgOut->addHTML( "<p>" . wfMsg( "nonefound" ) . "\n" );
-               }
-               $wgOut->addHTML( "<p>{$sl}\n" );
-               $wgOut->addHTML( $powersearch );
        }
 
        function legalSearchChars()
@@ -417,19 +438,21 @@ class SearchEngine {
 
                # Try a near match
                #
-               $this->parseQuery();                                                                            
-               $sql = "SELECT cur_id,cur_title,cur_namespace,si_page FROM cur,searchindex " .
-                 "WHERE cur_id=si_page AND {$this->mTitlecond} ORDER BY cur_namespace LIMIT 1";
-
-               if ( "" != $this->mTitlecond ) {
-                       $res = wfQuery( $sql, DB_READ, $fname );
-               }                               
-               if ( isset( $res ) && 0 != wfNumRows( $res ) ) {
-                       $s = wfFetchObject( $res );
-
-                       $t = Title::makeTitle( $s->cur_namespace, $s->cur_title );
-                       $wgOut->redirect( wfLocalUrl( $t->getPrefixedURL() ) );
-                       return;
+               if( !$wgDisableTextSearch ) {
+                       $this->parseQuery();                                                                            
+                       $sql = "SELECT cur_id,cur_title,cur_namespace,si_page FROM cur,searchindex " .
+                         "WHERE cur_id=si_page AND {$this->mTitlecond} ORDER BY cur_namespace LIMIT 1";
+       
+                       if ( "" != $this->mTitlecond ) {
+                               $res = wfQuery( $sql, DB_READ, $fname );
+                       }                               
+                       if ( isset( $res ) && 0 != wfNumRows( $res ) ) {
+                               $s = wfFetchObject( $res );
+       
+                               $t = Title::makeTitle( $s->cur_namespace, $s->cur_title );
+                               $wgOut->redirect( wfLocalUrl( $t->getPrefixedURL() ) );
+                               return;
+                       }
                }
                $wgOut->addHTML( wfMsg("nogomatch", 
                  htmlspecialchars( wfLocalUrl( ucfirst($this->mUsertext), "action=edit") ) )
@@ -438,3 +461,4 @@ class SearchEngine {
        }
 }
 
+?>
index f77ba41..03978be 100644 (file)
@@ -20,9 +20,12 @@ class SearchUpdate {
 
        function doUpdate()
        {
-               global $wgDBminWordLen, $wgLang;
+               global $wgDBminWordLen, $wgLang, $wgDisableSearchUpdate;
+
+               if( $wgDisableSearchUpdate ) {
+                       return false;
+               }
                $lc = SearchEngine::legalSearchChars() . "&#;";
-               
                if( $this->mText == false ) {
                        # Just update the title
                        $sql = "UPDATE LOW_PRIORITY searchindex SET si_title='" .
@@ -31,7 +34,7 @@ class SearchUpdate {
                        wfQuery( $sql, DB_WRITE, "SearchUpdate::doUpdate" );
                        return;
                }
-               
+
                # Language-specific strip/conversion
                $text = $wgLang->stripForSearch( $this->mText );
 
@@ -67,7 +70,7 @@ class SearchUpdate {
 
                # Strip wiki '' and '''
                $text = preg_replace( "/''[']*/", " ", $text );
-
+               
                $sql = "REPLACE DELAYED INTO searchindex (si_page,si_title,si_text) VALUES ({$this->mId},'" .
                  wfStrencode( Title::indexTitle( $this->mNamespace, $this->mTitle ) ) . "','" .
                  wfStrencode( $text ) . "')";
index ee96f3d..038e117 100644 (file)
@@ -36,6 +36,7 @@ include_once( "$IP/Article.php" );
 include_once( "$IP/MagicWord.php" );
 include_once( "$IP/MemCachedClient.inc.php" );
 include_once( "$IP/Block.php" );
+include_once( "$IP/SearchEngine.php" );
 
 wfProfileOut( "$fname-includes" );
 wfProfileIn( "$fname-memcached" );
@@ -76,7 +77,6 @@ if( ! class_exists( $wgLangClass ) ) {
 }
 $wgLang = new $wgLangClass();
 
-
 $wgUser = User::loadFromSession();
 $wgDeferredUpdateList = array();
 $wgLinkCache = new LinkCache();
index 6558e81..0783fb7 100644 (file)
@@ -129,6 +129,7 @@ class Skin {
                if ( 1 == $wgUser->getOption( "underline" ) ) {
                        # Don't override browser settings
                } else {
+                       # CHECK MERGE @@@
                        # Force no underline
                        $s .= "a.stub, a.new, a.internal, a.external { " .
                          "text-decoration: none; }\n";
@@ -211,7 +212,7 @@ class Skin {
                } else if ( $broken == "yes" ) { 
                        $r = " class='new'"; 
                } else { 
-                       $r = " class='internal'"; 
+                       $r = ""; 
                }
 
                if ( 1 == $wgUser->getOption( "hover" ) ) {
@@ -223,7 +224,6 @@ class Skin {
        function getInternalLinkAttributesObj( &$nt, $text, $broken = false )
        {
                global $wgUser, $wgOut;
-               $link = $nt->getEscapedText();
 
                if ( $wgOut->isPrintable() ) { 
                        $r = " class='printable'"; 
@@ -232,7 +232,7 @@ class Skin {
                } else if ( $broken == "yes" ) { 
                        $r = " class='new'"; 
                } else { 
-                       $r = " class='internal'"; 
+                       $r = ""; 
                }
 
                if ( 1 == $wgUser->getOption( "hover" ) ) {
@@ -477,7 +477,10 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
                global $wgOut,$wgTitle,$wgNamespacesWithSubpages;
 
                $sub = $wgOut->getSubtitle();
-               if ( "" == $sub ) { $sub = wfMsg( "fromwikipedia" ); }
+               if ( "" == $sub ) {
+                       global $wgExtraSubtitle;
+                       $sub = wfMsg( "fromwikipedia" ) . $wgExtraSubtitle;
+               }
                if($wgOut->isArticle() && $wgNamespacesWithSubpages[$wgTitle->getNamespace()]) {
                        $ptext=$wgTitle->getPrefixedText();                     
                        if(preg_match("/\//",$ptext)) {                         
@@ -798,7 +801,13 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
                }
                $s .= $this->specialLink( "specialpages" )
                  . $sep . $this->bugReportsLink();
-
+               
+               global $wgSiteSupportPage;
+               if( $wgSiteSupportPage ) {
+                       $s .= "\n<br><a href=\"" . htmlspecialchars( $wgSiteSupportPage ) .
+                         "\">" . wfMsg( "sitesupport" ) . "</a>";
+               }
+       
                $s .= "\n<br></div>\n";
                wfProfileOut( $fname );
                return $s;
@@ -1015,9 +1024,10 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
 
        function otherLanguages()
        {
-               global $wgOut, $wgLang, $wgTitle , $wgUseNewInterlanguage ;
+               global $wgOut, $wgLang, $wgTitle;
 
                $a = $wgOut->getLanguageLinks();
+               # TEST THIS @@@
                if ( 0 == count( $a ) ) {
                        if ( !$wgUseNewInterlanguage ) return "";
                        $ns = $wgLang->getNsIndex ( $wgTitle->getNamespace () ) ;
@@ -1038,6 +1048,7 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
                                  wfMsg( "otherlanguages" ) , $x ) . ": " ;
                        }
 
+               $s = wfMsg( "otherlanguages" ) . ": ";
                $first = true;
                if($wgLang->isRTL()) $s .= "<span dir='LTR'>";
                foreach( $a as $l ) {
@@ -1332,28 +1343,41 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
                $s = "<img src=\"{$url}\" alt=\"{$alt}\">";
                return $s;
        }
+       
+       function makeImageLink( $name, $url, $alt = "" ) {
+               $nt = Title::makeTitle( Namespace::getImage(), $name );
+               return $this->makeImageLinkObj( $nt, $alt );
+       }
 
-       function makeImageLink( $name, $url, $alt = "" )
-       {
-               global $wgOut, $wgTitle, $wgLang;
-
-               $nt = Title::newFromText( $wgLang->getNsText(
-                 Namespace::getImage() ) . ":{$name}" );
+       function makeImageLinkObj( $nt, $alt = "" ) {
                $link = $nt->getPrefixedURL();
-               if ( "" == $alt ) { $alt = $name; }
+               $name = $nt->getDBKey();
+               $url = wfImageUrl( $name );
+               if ( empty( $alt ) ) {
+                       $alt = preg_replace( '/\.(.+?)^/', '', $name );
+               }
+               $alt = htmlspecialchars( $alt );
 
                $u = wfLocalUrlE( $link );
                $s = "<a href=\"{$u}\" class='image' title=\"{$alt}\">" .
-                 "<img border=0 src=\"{$url}\" alt=\"{$alt}\"></a>";
+                 "<img border=\"0\" src=\"{$url}\" alt=\"{$alt}\"></a>";
                return $s;
        }
 
-       function makeMediaLink( $name, $url, $alt = "" )
+       function makeMediaLink( $name, $url, $alt = "" ) {
+               $nt = Title::makeTitle( Namespace::getMedia(), $name );
+               return $this->makeMediaLinkObj( $nt, $alt );
+       }
+
+       function makeMediaLinkObj( $nt, $alt = "" )
        {
-               global $wgOut, $wgTitle;
+               $name = $nt->getDBKey();
+               $url = wfImageUrl( $name );
+               if ( empty( $alt ) ) {
+                       $alt = preg_replace( '/\.(.+?)^/', '', $name );
+               }
 
-               if ( "" == $alt ) { $alt = $name; }
-               $u = wfEscapeHTML( $url );
+               $u = htmlspecialchars( $url );
                $s = "<a href=\"{$u}\" class='internal' title=\"{$alt}\">{$alt}</a>";
                return $s;
        }
@@ -1656,9 +1680,14 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
                        $ul = $this->makeLink( $wgLang->getNsText( Namespace::getUser() ) . ":{$ut}", $ut ); 
                }
                  
-               $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
                $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
-               $utl= $this->makeLink($utns . ":{$ut}", $talkname );
+               global $wgDisableAnonTalk;
+               if( 0 == $u && $wgDisableAnonTalk ) {
+                       $utl = "";
+               } else {
+                       $utns=$wgLang->getNsText(Namespace::getTalk(Namespace::getUser()));
+                       $utl= $this->makeLink($utns . ":{$ut}", $talkname );
+               }
                $cr = wfMsg( "currentrev" );
 
                $s .= "<li> ({$dlink}) ({$hlink}) . .";
@@ -1674,12 +1703,11 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
                          "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
                        
                }
-               if(!$blink) { 
-                       $utl = "({$utl})";
-               } else {
-                       $utl = "({$utl} | {$blink})";
+               if($blink) { 
+                       if($utl) $utl .= " | ";
+                       $utl .= $blink;
                }
-               $s.=" {$utl}";
+               if($utl) $s.=" ({$utl})";
 
                if ( "" != $c && "*" != $c ) {
                        $s .= " <em>(" . wfEscapeHTML( $c ) . ")</em>";
@@ -1751,12 +1779,19 @@ if ( isset ( $wgUseApproval ) && $wgUseApproval )
                $talkname=$wgLang->getNsText(Namespace::getTalk(0)); # use the shorter name
                $utl= $this->makeLink($utns . ":{$ut}", $talkname );                                            
 
+               global $wgDisableAnonTalk;
                if ( ( 0 == $u ) && $wgUser->isSysop() ) {
                        $blink = $this->makeKnownLink( $wgLang->specialPage(
                          "Blockip" ), wfMsg( "blocklink" ), "ip={$ut}" );
-                       $rc->usertalklink= " ({$utl} | {$blink})";
+                       if( $wgDisableAnonTalk )
+                               $rc->usertalklink = " ({$blink})";
+                       else
+                               $rc->usertalklink = " ({$utl} | {$blink})";
                } else {
-                       $rc->usertalklink=" ({$utl})";
+                       if( $wgDisableAnonTalk && ($u == 0) )
+                               $rc->usertalklink = "";
+                       else
+                               $rc->usertalklink = " ({$utl})";
                }
 
                if ( !isset ( $this->rc_cache[$t] ) ) $this->rc_cache[$t] = array() ;
index 0b0d964..7978e59 100644 (file)
@@ -19,7 +19,7 @@ class SkinCologneBlue extends Skin {
                $qb = $this->qbSetting();
 
                $s .= "\n<div id='content'>\n<div id='topbar'>" .
-                 "<table width='98%' border=0 cellspacing=0 cellpadding=8><tr>";
+                 "<table width='100%' border=0 cellspacing=0 cellpadding=8><tr>";
 
                $s .= "<td class='top' align=left valign=middle nowrap>";
                $s .= "<a href=\"" . wfLocalUrlE( wfMsg( "mainpage" ) ) . "\">";
index ad3a9b4..a4ecf02 100644 (file)
@@ -77,42 +77,68 @@ class SqlQueryForm {
 
                $n = 0;
                @$n = wfNumFields( $res );
+               $titleList = false;
+
                if ( $n ) {
                        $k = array();
                        for ( $x = 0; $x < $n; ++$x ) {
                                array_push( $k, wfFieldName( $res, $x ) );
                        }
+
+                       if ( $n == 2 && in_array( "cur_title", $k ) && in_array( "cur_namespace", $k ) ) {
+                               $titleList = true;
+                       }
+
                        $a = array();
                        while ( $s = wfFetchObject( $res ) ) {
                                array_push( $a, $s );
                        }
                        wfFreeResult( $res );
 
-                       $r = "<table border=1 bordercolor=black cellspacing=0 " .
-                         "cellpadding=2><tr>\n";
-                       foreach ( $k as $x ) $r .= "<th>" . htmlspecialchars( $x ) . "</th>";
-                       $r .= "</tr>\n";
-
-                       foreach ( $a as $y ) {
-                               $r .= "<tr>";
-                               foreach ( $k as $x ) {
-                                       $o = $y->$x ;
-                                       if ( $x == "cur_title" or $x == "old_title" or $x == "rc_title") {
-                                               $namespace = 0;
-                                               if( $x == "cur_title" ) $namespace = $y->cur_namespace;
-                                               if( $x == "old_title" ) $namespace = $y->old_namespace;
-                                               if( $x == "rc_title" ) $namespace = $y->rc_namespace;
-                                               if( $namespace ) $o = $wgLang->getNsText( $namespace ) . ":" . $o;
-                                               $o = "<a href=\"" . wfLocalUrlE($o) . "\" class='internal'>" .
-                                                 htmlspecialchars( $y->$x ) . "</a>" ;
-                                               } else {
-                                               $o = htmlspecialchars( $o );
-                                               }
-                                       $r .= "<td>" . $o . "</td>\n";
+                       if ( $titleList ) {
+                               $r = "";
+                               foreach ( $a as $y ) {
+                                       $o = "<a href=\"" . wfLocalUrlE($o) . "\" class='internal'>" .
+                                         htmlspecialchars( $y->$x ) . "</a>" ;
+                                       $sTitle = htmlspecialchars( $y->cur_title );
+                                       if ( $y->cur_namespace ) {
+                                               $sNamespace = $wgLang->getNsText( $y->cur_namespace );
+                                               $link = "$sNamespace:$sTitle";
+                                       } else {
+                                               $link = "$sTitle";
+                                       }
+                                       $skin = $wgUser->getSkin();
+                                       $link = $skin->makeLink( $link );
+                                       $r .= "* [[$link]]<br>\n";      
                                }
+                       } else {
+
+                               $r = "<table border=1 bordercolor=black cellspacing=0 " .
+                                 "cellpadding=2><tr>\n";
+                               foreach ( $k as $x ) $r .= "<th>" . htmlspecialchars( $x ) . "</th>";
                                $r .= "</tr>\n";
+
+                               foreach ( $a as $y ) {
+                                       $r .= "<tr>";
+                                       foreach ( $k as $x ) {
+                                               $o = $y->$x ;
+                                               if ( $x == "cur_title" or $x == "old_title" or $x == "rc_title") {
+                                                       $namespace = 0;
+                                                       if( $x == "cur_title" ) $namespace = $y->cur_namespace;
+                                                       if( $x == "old_title" ) $namespace = $y->old_namespace;
+                                                       if( $x == "rc_title" ) $namespace = $y->rc_namespace;
+                                                       if( $namespace ) $o = $wgLang->getNsText( $namespace ) . ":" . $o;
+                                                       $o = "<a href=\"" . wfLocalUrlE($o) . "\" class='internal'>" .
+                                                         htmlspecialchars( $y->$x ) . "</a>" ;
+                                                       } else {
+                                                       $o = htmlspecialchars( $o );
+                                                       }
+                                               $r .= "<td>" . $o . "</td>\n";
+                                       }
+                                       $r .= "</tr>\n";
+                               }
+                               $r .= "</table>\n";
                        }
-                       $r .= "</table>\n";
                }
                $this->showForm( wfMsg( "querysuccessful" ) );
                $wgOut->addHTML( "<hr>{$r}\n" );
diff --git a/includes/SpecialIntl.php b/includes/SpecialIntl.php
deleted file mode 100644 (file)
index 8e36605..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-<?
-
-function wfSpecialIntl()
-{
-       global $wgUser, $wgOut, $wgLang, $wgTitle;
-       global $limit, $offset; # From query string
-       global $wgDBconnection ;
-       $fname = "wfSpecialIntl";
-       $s = "" ;
-
-       if ( ! $limit ) {
-               $limit = $wgUser->getOption( "rclimit" );
-               if ( ! $limit ) { $limit = 50; }
-       }
-       if ( ! $offset ) { $offset = 0; }
-
-       # Connecting to the wiki-intl database
-       $c = $wgDBconnection ;
-       if ( !mysql_select_db ( $wgDBIntlName, $c ) ) {
-               $wgOut->addHTML( htmlspecialchars(mysql_error()) );
-               return ;
-               }
-
-       global $mode ;
-       $mode = strtolower ( trim ( $mode ) ) ;
-       if ( $mode == "" ) $mode = "main" ;
-
-       if ( $mode == "main" ) $s .= intl_main ( $c ) ;
-       else if ( $mode == "addlink" ) $s .= intl_add ( $c ) ;
-       else if ( $mode == "zoom" ) $s .= intl_zoom ( $c ) ;
-       else if ( $mode == "incominglinks" ) $s .= intl_incoming ( $c ) ;
-       else if ( $mode == "outgoinglinks" ) $s .= intl_outgoing ( $c ) ;
-       else if ( $mode == "alllinks" ) $s .= intl_all ( $c ) ;
-       else if ( $mode == "delete" ) $s .= intl_delete ( $c ) ;
-       else if ( $mode == "recentchanges" ) $s .= intl_recentchanges ( $c ) ;
-
-       $si = "Special:Intl" ;
-       $sk = $wgUser->getSkin();
-       if ( $mode != "" && $mode != "main" )
-               $s .= $sk->makeKnownLink($si,"International issues main menu") ;
-
-       $wgOut->addHTML( $s );
-}
-
-function appendRecentChanges ( $message ) {
-       global $wgDBconnection , $wgUser , $wgLanguageCode , $wgLang ;
-       $user_name = $wgLang->getNSText(Namespace::getUser()).":".$wgUser->getName() ;
-       $user_lang = $wgLanguageCode ;
-       $message = str_replace ( '"' , '\"' , $message ) ;
-       $sql = "INSERT INTO recentchanges (user_name,user_lang,message) VALUES (
-               \"{$user_name}\",
-               \"{$user_lang}\",
-               \"{$message}\")" ;
-       $res = mysql_query ( $sql , $wgDBconnection ) ;
-       }
-
-function intl_recentchanges ( $c ) {
-       global $wgLang ;
-       $r = "<h2>Recent Link Changes</h2>\n" ;
-
-       $rc = array () ;
-       $sql = "SELECT * FROM recentchanges ORDER BY date DESC LIMIT 250" ;
-       $res = mysql_query ( $sql , $c ) ;
-       while ( $q = mysql_fetch_object ( $res ) ) $rc[] = $q ;
-       mysql_free_result ( $res ) ;
-
-       $r .= "<UL>\n" ;
-       foreach ( $rc AS $x ) {
-               $r .= "<li>" ;
-               $r .= getArticleLink ( $x->user_name , $x->user_lang ) ;
-               $h = $wgLang->time( $x->date, true );
-               $r .= " ({$h}) " ;
-               $r .= $x->message ;
-               $r .= "</li>\n" ;
-               }
-       $r .= "</UL>\n" ;
-
-       return $r ;
-       }
-
-function getArticleLink ( $title , $lang = "" ) {
-       global $wgLanguageCode ;
-       $cl = "external" ;
-       if ( $lang == "" ) $lang = $wgLanguageCode ;
-       if ( $lang == $wgLanguageCode ) $cl = "internal" ;
-       $nt = Title::newFromText ( $title ) ;
-       $link = "http://".$lang.".wikipedia.org/wiki/".$title ;
-       $link = "<a class='{$cl}' href=\"{$link}\">".$nt->getText()."</a>" ;
-       return $link ;
-       }
-
-function intl_main ( $c ) {
-       global $wgUser ;
-       $sk = $wgUser->getSkin();
-       $si = "Special:Intl" ;
-
-       $r = "<h2>International issues main menu</h2>" ;
-       $r .= "<UL>" ;
-       $r .= "<li>".$sk->makeKnownLink($si,"Add a link","mode=addlink")."</li>" ;
-       $r .= "<li>".$sk->makeKnownLink($si,"View incoming links","mode=incominglinks")."</li>" ;
-       $r .= "<li>".$sk->makeKnownLink($si,"View outgoing links","mode=outgoinglinks")."</li>" ;
-       $r .= "<li>".$sk->makeKnownLink($si,"View all links","mode=alllinks")."</li>" ;
-       $r .= "<li>".$sk->makeKnownLink($si,"Recent Link Changes","mode=recentchanges")."</li>" ;
-       $r .= "</UL>" ;
-       return $r ;
-       }
-
-function intl_add_doit ( $c ) {
-       global $wgUser , $wgLang , $wgLanguageCode , $doit ;
-       global $l_f , $l_t , $t_f , $t_t , $backlink ;
-       $sk = $wgUser->getSkin();
-       $si = "Special:Intl" ;
-
-       # checking for language link
-       $q = explode ( ":" , $t_t , 2 ) ;
-       $ln = $wgLang->getLanguageNames();
-       if ( count ( $q ) == 2 ) {
-               $nl_t = trim ( array_shift ( $q ) ) ;
-               $nt_t = trim ( array_shift ( $q ) ) ;
-               if ( $nl_t != "" AND isset ( $ln[$nl_t] ) ) {
-                       $l_t = $nl_t ;
-                       $t_t = $nt_t ;
-                       }
-               }
-
-       $nt = Title::newFromText ( $t_f ) ;
-       $t_f = $nt->getDBkey() ;
-       $nt = Title::newFromText ( $t_t ) ;
-       $t_t = $nt->getDBkey() ;
-       
-       $r = "<h2>Creating/updating language links</h2>" ;
-
-       # Deleting forward link
-       $sql = "DELETE FROM ilinks WHERE 
-lang_from='{$l_f}' AND
-lang_to='{$l_t}' AND
-title_from='{$t_f}'
-" ;
-       $res = mysql_query ( $sql , $c ) ;
-
-       $r .= "Executed {$sql}" ;
-       $r .= "<br>Result {$res}" ;
-       $r .= "<br>Error ".  htmlspecialchars(mysql_error()) ;
-       $r .= "<br><br>" ;
-
-       # Adding link
-       $sql = "INSERT INTO ilinks (lang_from,lang_to,title_from,title_to) VALUES
-('{$l_f}','{$l_t}','{$t_f}','{$t_t}')" ;
-       $res = mysql_query ( $sql , $c ) ;
-
-       $r .= "Executed {$sql}" ;
-       $r .= "<br>Result {$res}" ;
-       $r .= "<br>Error ".  htmlspecialchars(mysql_error()) ;
-
-       appendRecentChanges ( $ln[$l_f].":".getArticleLink($t_f,$l_f)." &rarr; ".
-                               $ln[$l_t].":".getArticleLink($t_t,$l_t) ) ;
-
-       if ( $backlink == "on" ) {
-               $backlink = "" ;
-               $x = $l_f ; $l_f = $l_t ; $l_t = $x ;
-               $x = $t_f ; $t_f = $t_t ; $t_t = $x ;
-               intl_add_doit ( $c ) ; # Ugly recursion
-               }
-
-       return $r ;
-       }
-
-function intl_add ( $c ) {
-       global $wgUser , $wgLang , $wgLanguageCode , $doit , $mode ;
-       global $xl , $xt , $yl , $yt ;
-       $r = "" ;
-       if ( isset ( $doit ) ) {
-               global $al_t , $at_t , $l_t , $t_t ;
-               for ( $x = 0 ; $x < 10 ; $x++ ) {
-                       if ( trim($at_t[$x]) != "" ) {
-                               $t_t = $at_t[$x] ;
-                               $l_t = $al_t[$x] ;
-                               $r .= "<font color=red size=+1>".
-                                       "The link ".
-                                       $l_f.":".$t_f." &harr; ".$l_t.":".$t_t.
-                                       " has been added.</font><br>" ;
-                               intl_add_doit ( $c ) ;
-                               }
-                       }
-               $yt = "" ;
-               $yl = "" ;
-               }
-
-       $sk = $wgUser->getSkin();
-       $si = "Special:Intl" ;
-
-       if ( $xl == "" ) $xl = $wgLanguageCode ;
-
-       $oxt = $xt ;
-       $oyt = $yt ;
-       $nt = Title::newFromText ( $xt ) ;
-       $xt = $nt->getPrefixedText () ;
-       $nt = Title::newFromText ( $yt ) ;
-       $yt = $nt->getPrefixedText () ;
-
-       $ll1 = $ll2 = "" ;
-       $a = $wgLang->getLanguageNames();
-       $ak = array_keys ( $a ) ;
-       foreach ( $ak AS $k ) {
-               $sel = "" ;
-               if ( $k == $xl ) $sel = " SELECTED" ;
-               $ll1 .= "<option{$sel} value='{$k}'>{$a[$k]}</option>\n" ;
-               $sel = "" ;
-               if ( $k == $yl ) $sel = " SELECTED" ;
-               $ll2 .= "<option{$sel} value='{$k}'>{$a[$k]}</option>\n" ;
-               }
-
-       $r .= "<h2>Add or update a link</h2>" ;
-
-       if ( $oxt != "" ) {
-               $zl = "See the group of articles interlinked for ".$a[$xl].":".$xt ;
-               $zl = $sk->makeKnownLink($si,$zl,"mode=zoom&xl={$xl}&xt={$oxt}")."<br>\n" ;
-               $al = getArticleLink ( $oxt , $xl ) ;
-               $r .= $zl.$al ;
-               }
-
-       $r .= "Note: You can also type the language code before the target (e.g., 'en:target'). The selection of the drop down box will then be ignored.<br>\n" ;
-
-       $r .= "<FORM method=post>\n" ;
-
-       $r .= "<li>Source \n" ;
-       $r .= "<select name=l_f>\n{$ll1}</select>\n " ;
-       $r .= "<input type=text name=t_f value=\"{$xt}\">\n" ;
-       $r .= "</li>\n" ;
-
-       for ( $x = 0 ; $x < 10 ; $x++ ) {
-               $r .= "<li>Destin. \n" ;
-               $r .= "<select name='al_t[{$x}]'>\n{$ll2}</select>\n " ;
-               $r .= "<input type=text name='at_t[{$x}]' value=\"{$yt}\">\n" ;
-               $r .= "</li>\n" ;
-               }
-
-       $r .= "<INPUT type=checkbox name=backlink checked>Add link in both directions<br>\n" ;
-
-       $r .= "<INPUT type=submit name=doit value='Do it'>\n" ;
-
-       $r .= "</FORM>\n" ;
-
-       return $r ;
-       }
-
-function eliminate_doubles ( &$list ) { # Real ugly
-       $ak = array_keys ( $list ) ;
-       foreach ( $ak AS $k1 ) {
-               if ( $list[$k1]->hidden ) continue ;
-               foreach ( $ak AS $k2 ) {
-                       if ( $k1 != $k2 &&
-                               $list[$k1]->title_from == $list[$k2]->title_to &&
-                               $list[$k1]->title_to == $list[$k2]->title_from &&
-                               $list[$k1]->lang_from == $list[$k2]->lang_to &&
-                               $list[$k1]->lang_to == $list[$k2]->lang_from ) {
-                               $list[$k1]->both = true ;
-                               $list[$k2]->hidden = true ;
-                               break ;
-                               }
-                       }
-               }
-       }
-
-function displayLinks ( $list , $opt = "" ) {
-       eliminate_doubles ( $list ) ;
-       global $wgLang , $wgUser , $mode ;
-       $si = "Special:Intl" ;
-       $sk = $wgUser->getSkin();
-       $ln = $wgLang->getLanguageNames();
-       $r = "" ;
-
-       if ( !isset ( $opt->showdel ) ) $opt->showdel = true ;
-
-       global $limit , $offset , $intlparam ;
-       if ( $intlparam != "" ) {
-               $r .= wfShowingResults( $offset, $limit );
-               $sl = wfViewPrevNext( $offset, $limit,
-                 $wgLang->specialPage( "Intl".$intlparam ) );
-               $r .= "<br>{$sl}\n" ;
-               }
-
-       $r .= "<table border=1 cellpadding=2 cellspacing=0>\n" ;
-       $r .= "<tr>\n" ;
-       $r .= "<th colspan=2>From</th>\n" ;
-       $r .= "<th>&nbsp;</th>\n" ;
-       $r .= "<th colspan=2>To</th>\n" ;
-       if ( $mode != "zoom" ) $r .= "<th>&nbsp;</th>\n" ;
-       if ( $opt->showdel ) $r .= "<th colspan=3>Delete</th>\n" ;
-       if ( $opt->display != "" ) $r .= "<th colspan=3>".$opt->display."</th>\n" ;
-       $r .= "</tr>\n" ;
-
-       foreach ( $list AS $q ) {
-               if ( $q->hidden ) continue ;
-               $zoom = "xl={$q->lang_from}&xt=".urlencode($q->title_from) ;
-               $zoom = $sk->makeKnownLink($si,"[&Sigma;]","mode=zoom&{$zoom}") ;
-               $del1 = "xl={$q->lang_from}&xt=".urlencode($q->title_from)."&yl={$q->lang_to}" ;
-               $del2 = $sk->makeKnownLink($si,"[&harr;]","mode=delete&{$del1}&back=yes") ;
-               $del1 = $sk->makeKnownLink($si,"[&rarr;]","mode=delete&{$del1}") ;
-               $del1a = "xl={$q->lang_to}&xt=".urlencode($q->title_to)."&yl={$q->lang_from}" ;
-               $del1a = $sk->makeKnownLink($si,"[&larr;]","mode=delete&{$del1a}") ;
-               $sign = "&rarr;" ;
-               if ( $q->both ) $sign = "&harr;" ;
-               else $del1a = "&nbsp;" ;
-
-               $r .= "<tr>\n" ;
-               $r .= "<td>".$ln[$q->lang_from]."</td>\n" ;
-               $r .= "<td>".getArticleLink($q->title_from,$q->lang_from)."</td>\n" ;
-               $r .= "<td> {$sign} </td>\n" ;
-               $r .= "<td>".$ln[$q->lang_to]."</td>\n" ;
-               $r .= "<td>".getArticleLink($q->title_to,$q->lang_to)."</td>\n" ;
-               if ( $mode != "zoom" ) $r .= "<td>{$zoom}</td>\n" ;
-               if ( $opt->showdel ) {
-                       $r .= "<td>{$del1}</td>\n" ;
-                       $r .= "<td>{$del1a}</td>\n" ;
-                       $r .= "<td>{$del2}</td>\n" ;
-                       }
-               if ( $opt->display != "" ) {
-                       if ( $q->display == "" ) $q->display = "&nbsp;" ;
-                       $r .= "<td>{$q->display}</td>\n" ;
-                       }
-               $r .= "</tr>\n" ;
-               }
-       $r .= "</table>\n" ;
-       if ( $intlparam != "" )
-               $r .= "{$sl}<br>\n" ;
-       return $r ;
-       }
-
-function intl_outgoing ( $c ) {
-       global $wgLanguageCode ;
-       global $limit , $offset , $intlparam ;
-       $intlparam = "&mode=outgoinglinks" ;
-       $list = array() ;
-       $r = "<h2>Outgoing links</h2>\n" ;
-       $sql = "SELECT * FROM ilinks WHERE lang_from='{$wgLanguageCode}' LIMIT {$offset}, {$limit}";
-       $res = mysql_query ( $sql , $c ) ;
-       while ( $q = mysql_fetch_object ( $res ) ) $list[] = $q ;
-       mysql_free_result ( $res ) ;
-       $r .= displayLinks ( $list ) ;
-       return $r ;
-       }
-
-function intl_incoming ( $c ) {
-       global $wgLanguageCode ;
-       global $limit , $offset , $intlparam ;
-       $intlparam = "&mode=incominglinks" ;
-       $list = array() ;
-       $r = "<h2>Incoming links</h2>\n" ;
-       $sql="SELECT * FROM ilinks WHERE lang_to='{$wgLanguageCode}' LIMIT {$offset}, {$limit}";
-       $res = mysql_query ( $sql , $c ) ;
-       while ( $q = mysql_fetch_object ( $res ) ) $list[] = $q ;
-       mysql_free_result ( $res ) ;
-       $r .= displayLinks ( $list ) ;
-       return $r ;
-       }
-
-function intl_all ( $c ) {
-       global $wgLanguageCode ;
-       global $limit , $offset , $intlparam ;
-       $intlparam = "&mode=alllinks" ;
-       $list = array() ;
-       $r = "<h2>All links</h2>\n" ;
-       $sql = "SELECT * FROM ilinks LIMIT {$offset}, {$limit}";
-       $res = mysql_query ( $sql , $c ) ;
-       while ( $q = mysql_fetch_object ( $res ) ) $list[] = $q ;
-       mysql_free_result ( $res ) ;
-       $r .= displayLinks ( $list ) ;
-       return $r ;
-       }
-
-
-function do_zoom ( &$found , &$list , $c ) {
-       $news = array () ;
-       foreach ( $found AS $x ) {
-               if ( $x->new ) {
-$sql = "SELECT * FROM ilinks WHERE 
-( lang_from='{$x->lang}' AND title_from='{$x->title}' ) OR 
-( lang_to='{$x->lang}'   AND title_to='{$x->title}' )
-" ;
-                       $res = mysql_query ( $sql , $c ) ;
-                       while ( $q = mysql_fetch_object ( $res ) ) {
-                               $i->orig = $q ;
-                               $i->lang = $q->lang_from ;
-                               $i->title = $q->title_from ;
-                               $news[] = $i ;
-
-                               $i->lang = $q->lang_to ;
-                               $i->title = $q->title_to ;
-                               $news[] = $i ;
-                               }
-                       mysql_free_result ( $res ) ;
-                       }
-               }
-       $ak = array_keys ( $found ) ;
-       foreach ( $ak AS $x ) $found[$x]->new = false ;
-
-       # Adding new ones
-       $isnewone = false ;
-       foreach ( $news AS $n ) {
-               $didfind = 0 ;
-               foreach ( $found AS $f ) {
-                       if($n->lang==$f->lang AND $n->title==$f->title) {
-                               $didfind=1;
-                               if ( $f->new ) $list[] = $n->orig ;
-                               }
-                       }
-               if ( $didfind == 0 ) {
-                       $i->lang = $n->lang ;
-                       $i->title = $n->title ;
-                       $i->new = true ;
-                       $found[] = $i ;
-                       $list[] = $n->orig ;
-                       $isnewone = true ;
-                       }
-               }
-
-       if ( $isnewone ) do_zoom ( $found , $list , $c ) ;
-       }
-
-function getMissingLinks ( $found , $list ) {
-       $a = $r = array () ;
-       foreach ( $found AS $f1 ) {
-               foreach ( $found AS $f2 ) {
-                       if ( $f1 != $f2 ) {
-                               $i->lang_from = $f1->lang ;
-                               $i->lang_to = $f2->lang ;
-                               $i->title_from = $f1->title ;
-                               $i->title_to = $f2->title ;
-                               $a[] = $i ;
-                               }
-                       }
-               }
-       foreach ( $a AS $x ) {
-               $f = false ;
-               foreach ( $list AS $l ) {
-                       if ( $x->lang_from == $l->lang_from &&
-                            $x->lang_to == $l->lang_to &&
-                            $x->title_from == $l->title_from &&
-                            $x->title_to == $l->title_to ) {
-                               $f = true ;
-                               break ;
-                               }
-                       }
-               if ( !$f ) $r[] = $x ;
-               }
-       return $r ;
-       }
-
-function intl_zoom2 ( $c ) {
-       global $doit , $ZLF , $ZLT , $ZTF , $ZTT , $ZCB ;
-       global $l_f , $l_t , $t_f , $t_t , $backlink ;
-       $r = "<h2>Adding selected language links</h2>\n" ;
-       $r .= "<OL>\n" ;
-       $ak = array_keys ( $ZCB ) ;
-       foreach ( $ak AS $cnt ) {
-               if ( $ZCB[$cnt] == "on" ) {
-                       $l_f = $ZLF[$cnt] ;
-                       $l_t = $ZLT[$cnt] ;
-                       $t_f = $ZTF[$cnt] ;
-                       $t_t = $ZTT[$cnt] ;
-                       $backlink = "on" ;
-                       intl_add_doit ( $c ) ;
-                       $r .= "<li>$l_f:$t_f &harr; $l_t:$t_t</li>\n" ;
-                       }
-               }
-       $r .= "</OL>\n" ;
-       return $r ;
-       }
-
-function intl_zoom ( $c ) {
-       global $doit ;
-       global $wgLanguageCode , $wgLang ;
-       global $xl , $xt ;
-       if ( isset ( $doit ) ) return intl_zoom2 ( $c ) ;
-       $ln = $wgLang->getLanguageNames();
-       $list = array() ;
-       $found = array () ;
-       $r = "<h2>Interlinked articles group</h2>\n" ;
-       $initial->lang = $xl ;
-       $initial->title = urldecode ( $xt ) ;
-       $initial->new = true ;
-       $found[] = $initial ;
-
-       do_zoom ( $found , $list , $c ) ;
-
-       $involved = array() ;
-       foreach ( $found AS $f )
-               $involved[] = $ln[$f->lang].":".getArticleLink ( $f->title , $f->lang ) ;
-       $r .= "Involved are ".implode ( ", " , $involved )."<br>\n" ;
-
-       $r .= displayLinks ( $list ) ;
-
-       $list2 = getMissingLinks ( $found , $list ) ;
-
-       if ( count ( $list2 ) > 0 ) {
-               $r .= "<h3>Missing links</h3>\n" ;
-               $opt->showdel = false ;
-               $opt->display = "Create" ;
-               $ak = array_keys ( $list2 ) ;
-               $cnt = 1 ;
-               foreach ( $ak AS $a ) {
-                       $b = $list2[$a] ;
-                       $z = "<input type=checkbox name='ZCB[{$cnt}]' checked>\n" ;
-                       $z.="<input type=hidden name='ZLF[{$cnt}]' value='{$b->lang_from}'>\n";
-                       $z.="<input type=hidden name='ZLT[{$cnt}]' value='{$b->lang_to}'>\n";
-                       $z.="<input type=hidden name='ZTF[{$cnt}]' value='{$b->title_from}'>\n";
-                       $z.="<input type=hidden name='ZTT[{$cnt}]' value='{$b->title_to}'>\n";
-                       $list2[$a]->display = $z ;
-                       $cnt++ ;
-                       }
-               $r .= "<FORM method=post>\n" ;
-               $r .= displayLinks ( $list2 , $opt ) ;
-               $r .= "<INPUT type=submit name=doit value='Create selected links'>\n" ;
-               $r .= " (Note: This is still buggy, I don't know why...)" ;
-               $r .= "</FORM>\n" ;
-               }
-
-       return $r ;
-       }
-
-function intl_delete ( $c ) {
-       global $wgLang ;
-       global $xt , $xl , $yl , $back ;
-       $title = urldecode ( $xt ) ;
-       $ln = $wgLang->getLanguageNames();
-
-       $sql = "DELETE FROM ilinks WHERE 
-lang_from='{$xl}' AND
-lang_to='{$yl}' AND
-title_from='{$title}'
-" ;
-       $res = mysql_query ( $sql , $c ) ;
-
-       $r = "<h2>Deletion</h2>" ;
-       $r .= "The link from ".$ln[$xl].":".$title." to ".$ln[$yl]." has been deleted.<br>" ;
-
-       appendRecentChanges ( "- ".$ln[$xl].":".getArticleLink($title,$xl)." &rarr;" ) ;
-
-       # Backlink?
-       if ( $back != "yes" ) return $r ;
-
-       $sql = "DELETE FROM ilinks WHERE 
-lang_to='{$xl}' AND
-lang_from='{$yl}' AND
-title_to='{$title}'
-" ;
-       $res = mysql_query ( $sql , $c ) ;
-
-       appendRecentChanges ( "- &rarr;".$ln[$xl].":".getArticleLink($title,$xl) ) ;
-
-       $r .= "As was the backlink.<br>" ;
-       return $r ;
-       }
-?>
index 37b5875..9538ed9 100644 (file)
@@ -47,7 +47,7 @@ function wfSpecialMaintenance( $par=NULL )
        $l = $l[0] ;
        $r .= $l.">\n" ;
        $r .= "<input type=submit name='submitmll' value='" ;
-       $r .= wfMsg("missinglanguagelinksbutton");
+       $r .= htmlspecialchars(wfMsg("missinglanguagelinksbutton"), ENT_QUOTES);
        $r .= "'>\n" ;
        $r .= "<select name=thelang>\n" ;
        $a = $wgLang->getLanguageNames();
index 694b3a9..81d8bdc 100644 (file)
@@ -106,6 +106,10 @@ class MovePageForm {
 
                $this->ot = Title::newFromText( $wpOldTitle );
                $this->nt = Title::newFromText( $wpNewTitle );
+               if( !$this->ot or !$this->nt ) {
+                       $this->showForm( wfMsg( "badtitletext" ) );
+                       return;
+               }
                $this->ons = $this->ot->getNamespace();
                $this->nns = $this->nt->getNamespace();
                $this->odt = wfStrencode( $this->ot->getDBkey() );
@@ -125,9 +129,11 @@ class MovePageForm {
                if ( ( ! Namespace::isMovable( $this->ons ) ) ||
                         ( "" == $this->odt ) ||
                         ( "" != $this->ot->getInterwiki() ) ||
+                        ( !$this->ot->userCanEdit() ) ||
                     ( ! Namespace::isMovable( $nns ) ) ||
                         ( "" == $this->ndt ) ||
-                        ( "" != $this->nt->getInterwiki() ) ) {
+                        ( "" != $this->nt->getInterwiki() ) ||
+                        ( !$this->nt->userCanEdit() ) ) {
                        $this->showForm( wfMsg( "badarticleerror" ) );
                        return;
                }
@@ -402,16 +408,7 @@ class MovePageForm {
                if( $oldnamespace == $newnamespace and $oldtitle == $newtitle )
                        return;
 
-               $sql = "SELECT wl_user FROM watchlist
-                       WHERE wl_namespace={$oldnamespace} AND wl_title='{$oldtitle}'";
-               $res = wfQuery( $sql, DB_READ, $fname );
-               if( $s = wfFetchObject( $res ) ) {
-                       $sql = "REPLACE INTO watchlist (wl_user,wl_namespace,wl_title)
-                               VALUES ({$s->wl_user},{$newnamespace},'{$newtitle}')";
-                       while( $s = wfFetchObject( $res ) ) {
-                               $sql .= ",({$s->wl_user},{$newnamespace},'{$newtitle}')";
-                       }
-                       wfQuery( $sql, DB_WRITE, $fname );
+               WatchedItem::duplicateEntries( $this->ot, $this->nt );
                }
        }
 
index 4e1ed33..399aa1b 100644 (file)
@@ -65,7 +65,6 @@ function wfSpecialPreferences()
        global $wpSkin, $wpMath, $wpDate, $wpEmail, $wpEmailFlag, $wpNick, $wpSearch, $wpRecent;
        global $wpSearchLines, $wpSearchChars, $wpStubs;
        global $wpRows, $wpCols, $wpHourDiff, $HTTP_POST_VARS;
-       global $wpNs0, $wpNs1, $wpNs2, $wpNs3, $wpNs4, $wpNs5, $wpNs6, $wpNs7;
 
        if ( "" != $wpNewpass ) {
                if ( $wpNewpass != $wpRetype ) {
@@ -95,16 +94,17 @@ function wfSpecialPreferences()
        $wgUser->setOption( "cols", validateInt( $wpCols, 4, 1000 ) );
        $wgUser->setOption( "stubthreshold", validateIntOrNull( $wpStubs ) );
        $wgUser->setOption( "timecorrection", validateIntOrNull( $wpHourDiff, -12, 14 ) );
-
-       $wgUser->setOption( "searchNs0", validateCheckbox( $wpNs0 ) );
-       $wgUser->setOption( "searchNs1", validateCheckbox( $wpNs1 ) );
-       $wgUser->setOption( "searchNs2", validateCheckbox( $wpNs2 ) );
-       $wgUser->setOption( "searchNs3", validateCheckbox( $wpNs3 ) );
-       $wgUser->setOption( "searchNs4", validateCheckbox( $wpNs4 ) );
-       $wgUser->setOption( "searchNs5", validateCheckbox( $wpNs5 ) );
-       $wgUser->setOption( "searchNs6", validateCheckbox( $wpNs6 ) );
-       $wgUser->setOption( "searchNs7", validateCheckbox( $wpNs7 ) );
-
+       
+       $namespaces = $wgLang->getNamespaces();
+       # Set search namespace options
+       # Note: namespaces don't necessarily have consecutive keys
+       foreach ( $namespaces as $i => $namespaces ) {
+               if ( $i >= 0 ) {
+                       $nsvar = "wpNs$i";
+                       global $$nsvar;
+                       $wgUser->setOption( "searchNs{$i}", validateCheckbox( $$nsvar ) );
+               }
+       }
 
        $wgUser->setOption( "disablemail", validateCheckbox( $wpEmailFlag ) );
 
@@ -155,37 +155,32 @@ function wfSpecialPreferences()
        }
 }
 
-
-
-
 /* private */ function namespacesCheckboxes()
 {
        global $wgLang, $wgUser;
-       $nscb = array();
-
        
-       for ($i = 0; ($i < 8); $i++)
-       {
-               $nscb[$i] = $wgUser->getOption( "searchNs".$i );
-       }
-
        # Determine namespace checkboxes
+       $namespaces = $wgLang->getNamespaces();
+       $r1 = "";
 
-       $ns = $wgLang->getNamespaces();
-       array_shift( $ns ); /* Skip "Special" */
+       foreach ( $namespaces as $i => $name ) {
+               # Skip special or anything similar
+               if ( $i >= 0 ) {
+                       $checked = "";
+                       if ( $wgUser->getOption( "searchNs$i" ) ) {
+                               $checked = " checked";
+                       }
+                       $name = str_replace( "_", " ", $namespaces[$i] );
+                       if ( "" == $name ) { 
+                               $name = wfMsg( "blanknamespace" ); 
+                       }
 
-       $r1 = "";
-       for ( $i = 0; $i < count( $ns ); ++$i ) {
-               $checked = "";
-               if ( $nscb[$i] == 1 ) {
-                       $checked = " checked";
+                       if ( 0 != $i ) { 
+                               $r1 .= " "; 
+                       }
+                       $r1 .= "<label><input type=checkbox value=\"1\" name=\"" .
+                         "wpNs$i\"{$checked}>{$name}</label>\n";
                }
-               $name = str_replace( "_", " ", $ns[$i] );
-               if ( "" == $name ) { $name = wfMsg( "blanknamespace" ); }
-
-               if ( 0 != $i ) { $r1 .= " "; }
-               $r1 .= "<label><input type=checkbox value=\"1\" name=\"" .
-                 "wpNs{$i}\"{$checked}>{$name}</label>\n";
        }
        
        return $r1;
index 98db0a1..d2b0dbf 100644 (file)
@@ -3,10 +3,15 @@
 function wfSpecialUpload()
 {
        global $wgUser, $wgOut, $wpUpload, $wpReUpload, $action;
-
+       global $wgDisableUploads;
+       
        $fields = array( "wpUploadFile", "wpUploadDescription" );
        wfCleanFormFields( $fields );
 
+    if ( $wgDisableUploads ) {
+       $wgOut->addWikiText( wfMsg( "uploaddisabled" ) );
+       return;
+    }
        if ( ( 0 == $wgUser->getID() )
                or $wgUser->isBlocked() ) {
                $wgOut->errorpage( "uploadnologin", "uploadnologintext" );
index 0cb8a2e..66f8d83 100644 (file)
@@ -92,7 +92,7 @@ function wfSpecialUserlogin()
        }
        $wpName = trim( $wpName );
        if ( ( "" == $wpName ) ||
-         preg_match( "/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/", $wpName ) ||
+         preg_match( "/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/", $wpName ) ||
          (strpos( $wpName, "/" ) !== false) ) 
        {
                mainLoginForm( wfMsg( "noname" ) );
index 0943351..808de18 100644 (file)
@@ -5,6 +5,7 @@ function wfSpecialUserlogout()
        global $wgUser, $wgOut, $returnto;
 
        $wgUser->logout();
+       $wgOut->mCookies = array();
        $wgOut->setRobotpolicy( "noindex,nofollow" );
        $wgOut->addHTML( wfMsg( "logouttext" ) . "\n<p>" );
        $wgOut->returnToMain();
index 4321c0d..d49bfd4 100644 (file)
@@ -1,6 +1,6 @@
 <?
-global $IP;
-include_once( "$IP/SpecialRecentchanges.php" );
+include_once( "SpecialRecentchanges.php" );
+include_once( "WatchedItem.php" );
 
 function wfSpecialWatchlist()
 {
@@ -25,11 +25,8 @@ function wfSpecialWatchlist()
                foreach($id as $one) {
                        $t = Title::newFromURL( $one );
                        if($t->getDBkey() != "") {
-                               $sql = "DELETE FROM watchlist WHERE wl_user=$uid AND " .
-                                       "wl_namespace=" . $t->getNamespace() . " AND " .
-                                       "wl_title='" . wfStrencode( $t->getDBkey() ) . "'";
-                               $res = wfQuery( $sql, DB_WRITE );
-                               if($res === FALSE) {
+                               $wl = WatchedItem::fromUserTitle( $wgUser, $t );
+                               if( $wl->removeWatch() === false ) {
                                        $wgOut->addHTML( "<br />\n" . wfMsg( "couldntremove", htmlspecialchars($one) ) );
                                } else {
                                        $wgOut->addHTML( " (" . htmlspecialchars($one) . ")" );
index 8d1c4ba..afdc76f 100644 (file)
@@ -87,6 +87,7 @@ function wfShowIndirectLinks( $level, $lid )
                $nt = Title::newFromDBkey( $row->l_from );
                if( !$nt ) {
                        $wgOut->addHTML( "<!-- bad backlink: " . htmlspecialchars( $row->l_from ) . " -->\n" );
+                       continue;
                }
                $ns = $nt->getNamespace();
                $t = wfStrencode( $nt->getDBkey() );
index db4e112..9159605 100644 (file)
@@ -15,7 +15,6 @@ class Title {
                $this->mNamespace = 0;
                $this->mRestrictionsLoaded = false;
                $this->mRestrictions = array();
-               $this->mPrefixedText = false;
        }
 
        # Static factory methods
@@ -28,7 +27,6 @@ class Title {
                        return $t;
                else
                        return NULL;
-               return $t;
        }
 
        function newFromText( $text )
@@ -189,7 +187,8 @@ class Title {
 
        function getPrefixedText()
        {
-               if ( $this->mPrefixedText === false ) {
+          # TEST THIS @@@
+               if ( empty( $this->mPrefixedText ) ) {
                        $s = $this->prefix( $this->mTextform );
                        $s = str_replace( "_", " ", $s );
                        $this->mPrefixedText = $s;
@@ -244,7 +243,7 @@ class Title {
        {
                return wfEscapeHTML( $this->getPrefixedText() );
        }
-
+       
        function isExternal() { return ( "" != $this->mInterwiki ); }
 
        function isProtected()
@@ -337,6 +336,14 @@ class Title {
                $this->mRestrictionsLoaded = false;
                $this->mRestrictions = array();
        }
+       
+       function invalidateCache() {
+               $now = wfTimestampNow();
+               $ns = $this->getNamespace();
+               $ti = wfStrencode( $this->getDBkey() );
+               $sql = "UPDATE cur SET cur_touched='$now' WHERE cur_namespace=$ns AND cur_title='$ti'";
+               return wfQuery( $sql, "Title::invalidateCache" );
+       }
 
        /* private */ function prefix( $name )
        {
@@ -399,7 +406,7 @@ class Title {
                if ( ":" == $t{0} ) {
                        $r = substr( $t, 1 );
                } else {
-                       if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z0-9_\\x80-\\xff]+):(.*)$/", $t, $m ) ) {
+                       if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z0-9_\\x80-\\xff]+):_*(.*)$/", $t, $m ) ) {
                                #$p = strtolower( $m[1] );
                                $p = $m[1];
                                if ( $ns = $wgLang->getNsIndex( strtolower( $p ) )) {
index e0ea292..697354f 100644 (file)
@@ -1,6 +1,8 @@
 <?
 # See user.doc
 
+include_once( "WatchedItem.php" );
+
 class User {
        /* private */ var $mId, $mName, $mPassword, $mEmail, $mNewtalk;
        /* private */ var $mRights, $mOptions;
@@ -196,10 +198,11 @@ class User {
                        }
                        wfFreeResult( $res );
                } else {
+                       # TEST THIS @@@
                        global $wgDBname, $wgMemc;
                        $key = "$wgDBname:newtalk:ip:{$this->mName}";
                        $newtalk = $wgMemc->get( $key );
-/*                     if($newtalk === false) {
+                       if($newtalk === false) {
                                $sql = "SELECT 1 FROM user_newtalk WHERE user_ip='{$this->mName}'";
                                $res = wfQuery ($sql, DB_READ, "User::loadFromDatabase" );
 
@@ -207,9 +210,9 @@ class User {
                                wfFreeResult( $res );
 
                                $wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 );
-                       } else {*/
+                       } else {
                                $this->mNewtalk = $newtalk ? 1 : 0;
-#                      }
+                       }
                }
                if(!$this->mId) {
                        $this->mDataLoaded = true;
@@ -404,45 +407,21 @@ class User {
                return $this->mSkin;
        }
 
-       function isWatched( $title )
-       {
-               # Note - $title should be a Title _object_
-               # Pages and their talk pages are considered equivalent for watching;
-               # remember that talk namespaces are numbered as page namespace+1.
-               if( $this->mId ) {
-                       $sql = "SELECT 1 FROM watchlist
-                         WHERE wl_user={$this->mId} AND
-                         wl_namespace = " . ($title->getNamespace() & ~1) . " AND
-                         wl_title='" . wfStrencode( $title->getDBkey() ) . "'";
-                       $res = wfQuery( $sql, DB_READ );
-                       return (wfNumRows( $res ) > 0);
-               } else {
-                       return false;
-               }
+       function isWatched( $title ) {
+               $wl = WatchedItem::fromUserTitle( $this, $title );
+               return $wl->isWatched();
        }
-
-       function addWatch( $title )
-       {
-               if( $this->mId ) {
-                       # REPLACE instead of INSERT because occasionally someone
-                       # accidentally reloads a watch-add operation.
-                       $sql = "REPLACE INTO watchlist (wl_user, wl_namespace,wl_title)
-                         VALUES ({$this->mId}," . (($title->getNamespace() | 1) - 1) .
-                         ",'" . wfStrencode( $title->getDBkey() ) . "')";
-                       wfQuery( $sql, DB_WRITE );
-                       $this->invalidateCache();
-               }
+       
+       function addWatch( $title ) {
+               $wl = WatchedItem::fromUserTitle( $this, $title );
+               $wl->addWatch();
+               $this->invalidateCache();
        }
-
-       function removeWatch( $title )
-       {
-               if( $this->mId ) {
-                       $sql = "DELETE FROM watchlist WHERE wl_user={$this->mId} AND
-                         wl_namespace=" . (($title->getNamespace() | 1) - 1) .
-                         " AND wl_title='" . wfStrencode( $title->getDBkey() ) . "'";
-                       wfQuery( $sql, DB_WRITE );
-            $this->invalidateCache();
-               }
+       
+       function removeWatch( $title ) {
+               $wl = WatchedItem::fromUserTitle( $this, $title );
+               $wl->removeWatch();
+               $this->invalidateCache();
        }
 
 
@@ -525,7 +504,6 @@ class User {
                  "user_touched= '" . wfStrencode( $this->mTouched ) .
                  "' WHERE user_id={$this->mId}";
                wfQuery( $sql, DB_WRITE, "User::saveSettings" );
-               #$wgMemc->replace( "$wgDBname:user:id:$this->mId", $this );
                $wgMemc->delete( "$wgDBname:user:id:$this->mId" );
        }
 
index 49ea305..53f3e98 100644 (file)
@@ -43,8 +43,7 @@ class UserTalkUpdate {
                                        #anon
                                        if(preg_match("/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/",$this->mTitle)) { #real anon (user:xxx.xxx.xxx.xxx)
                                                $sql = "INSERT INTO user_newtalk (user_id,user_ip) values (0,\"{$this->mTitle}\")";             
-                                               #$wgMemc->delete( "$wgDBname:newtalk:ip:$this->mTitle" );
-                                               $wgMemc->set( "$wgDBname:newtalk:ip:$this->mTitle", "1", time() );
+                                               $wgMemc->delete( "$wgDBname:newtalk:ip:$this->mTitle" );
                                        }
                                }
                                
diff --git a/includes/WatchedItem.php b/includes/WatchedItem.php
new file mode 100644 (file)
index 0000000..ba60d00
--- /dev/null
@@ -0,0 +1,92 @@
+<?
+
+class WatchedItem {
+
+       /* static */ function &fromUserTitle( &$user, &$title ) {
+               $wl = new WatchedItem;
+               $wl->mUser =& $user;
+               $wl->mTitle =& $title;
+               $wl->id = $user->getId();
+               $wl->ns = $title->getNamespace() & ~1;
+               $wl->ti = $title->getDBkey();
+               $wl->eti = wfStrencode( $wl->ti );
+               return $wl;
+       }
+
+       function watchKey() {
+               global $wgDBname;
+               return "$wgDBname:watchlist:user:$this->id:page:$this->ns:$this->ti";
+       }
+       
+       function isWatched()
+       {
+               # Pages and their talk pages are considered equivalent for watching;
+               # remember that talk namespaces are numbered as page namespace+1.
+               global $wgMemc;
+               $key = $this->watchKey();
+               $iswatched = $wgMemc->get( $key );
+               if( $iswatched !== false ) return $iswatched;
+               
+               $sql = "SELECT 1 FROM watchlist WHERE wl_user=$this->id AND wl_namespace=$this->ns AND wl_title='$this->eti'";
+               $res = wfQuery( $sql, DB_READ );
+               $iswatched = (wfNumRows( $res ) > 0);
+               $wgMemc->set( $key, $iswatched );
+               return $iswatched;
+       }
+
+       function addWatch()
+       {
+               # REPLACE instead of INSERT because occasionally someone
+               # accidentally reloads a watch-add operation.
+               $sql = "REPLACE INTO watchlist (wl_user, wl_namespace,wl_title) VALUES ($this->id,$this->ns,'$this->eti')";
+               $res = wfQuery( $sql, DB_WRITE );
+               if( $res === false ) return false;
+               
+               global $wgMemc;
+               $wgMemc->set( $this->watchkey(), 1 );
+               return true;
+       }
+
+       function removeWatch()
+       {
+               $sql = "DELETE FROM watchlist WHERE wl_user=$this->id AND wl_namespace=$this->ns AND wl_title='$this->eti' LIMIT 1";
+               $res = wfQuery( $sql, DB_WRITE );
+               if( $res === false ) return false;
+               
+               global $wgMemc;
+               $wgMemc->set( $this->watchkey(), 0 );
+               return true;
+       }
+
+       /* static */ function duplicateEntries( $ot, $nt ) {
+               global $wgMemc, $wgDBname;
+               $oldnamespace = $ot->getNamespace() & ~1;
+               $newnamespace = $nt->getNamespace() & ~1;
+               $oldtitle = $ot->getDBkey();
+               $newtitle = $nt->getDBkey();
+               $eoldtitle = wfStrencode( $oldtitle );
+               $enewtitle = wfStrencode( $newtitle );
+
+               $sql = "SELECT wl_user FROM watchlist
+                       WHERE wl_namespace={$oldnamespace} AND wl_title='{$oldtitle}'";
+               $res = wfQuery( $sql, DB_READ, $fname );
+               if( $s = wfFetchObject( $res ) ) {
+                       $sql = "REPLACE INTO watchlist (wl_user,wl_namespace,wl_title)
+                               VALUES ({$s->wl_user},{$newnamespace},'{$enewtitle}')";
+                       $key = "$wgDBname:watchlist:user:$s->wl_user:page:$newnamespace:$newtitle";
+                       $wgMemc->set( $key, 1 );
+                       while( $s = wfFetchObject( $res ) ) {
+                               $sql .= ",({$s->wl_user},{$newnamespace},'{$enewtitle}')";
+                               $key = "$wgDBname:watchlist:user:$s->wl_user:page:$newnamespace:$newtitle";
+                               $wgMemc->set( $key, 1 );
+                       }
+                       $res = wfQuery( $sql, DB_WRITE, $fname );
+                       if( $res === false ) return false; # db error?
+               }
+               return true;
+       }
+
+
+}
+
+?>
index 9897a81..abc8899 100644 (file)
@@ -503,7 +503,16 @@ an incorrectly linked inter-language or inter-wiki title.",
 because it slows the database down to the point that no one can use
 the wiki.",
 "perfdisabledsub" => "Here's a saved copy from $1:",
-"wrong_wfQuery_params" => "Incorrect parameters to wfQuery",
+"wrong_wfQuery_params" => "Incorrect parameters to wfQuery()<br>
+Function: $1<br>
+Query: $2
+",
+"viewsource" => "View source",
+"protectedtext" => "This page has been locked to prevent editing; there are
+a number of reasons why this may be so, please see
+[[$wgMetaNamespace:Protected page]].
+
+You can view and copy the source of this page:",
 
 # Login and logout pages
 #
@@ -576,7 +585,17 @@ Please log in again after you receive it.",
 "blockedtitle" => "User is blocked",
 "blockedtext"  => "Your user name or IP address has been blocked by $1.
 The reason given is this:<br>''$2''<p>You may contact $1 or one of the other
-[[Wikipedia:administrators|administrators]] to discuss the block.",
+[[$wgMetaNamespace:Administrators|administrators]] to discuss the block. 
+
+Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]]. 
+
+Your IP address is $3. Please include this address in any queries you make.
+
+==Note to AOL users==
+Due to continuing acts of vandalism by one particular AOL user, Wikipedia often blocks AOL proxies. Unfortunately, a single proxy server may be used by a large number of AOL users, and hence innocent AOL users are often inadvertently blocked. We apologise for any inconvenience caused. 
+
+If this happens to you, please email an administrator, using an AOL email address. Be sure to include the IP address given above.
+",
 "whitelistedittitle" => "Login required to edit",
 "whitelistedittext" => "You have to [[Special:Userlogin|login]] to edit articles.",
 "whitelistreadtitle" => "Login required to read",
@@ -841,6 +860,7 @@ or <b>[[media:file.ogg]]</b> for sounds.
 <p>Please note that as with Wikipedia pages, others may edit or
 delete your uploads if they think it serves the encyclopedia, and
 you may be blocked from uploading if you abuse the system.",
+
 "uploadlog"            => "upload log",
 "uploadlogpage" => "Upload_log",
 "uploadlogpagetext" => "Below is a list of the most recent file uploads.
index 69d5765..15bf148 100644 (file)
@@ -111,6 +111,16 @@ to be reasonably fast. (patch-oldestindex.sql)
 
 OutputPage.php User.php maintenance/buildTables.inc maintenance/patch-cache.sql maintenance/patch-list.txt
 
+* 2003-09: Ipblocks auto-expiry update
+patch-ipblocks.sql
+
+* Interwiki URL table
+Moves the interwiki prefix<->url mapping table from a static array
+into the database. If you've got a custom table, be sure to make
+your changes!
+Run patch-interwiki.sql to create the interwiki table, then the
+plain interwiki.sql to load up the default set of mappings.
 
 * 2003-05-30: File upload license fields
 Adds fields to 'image' table.
index 46dc269..565c295 100644 (file)
@@ -55,3 +55,14 @@ ALTER TABLE searchindex
   ADD FULLTEXT si_title (si_title),
   ADD FULLTEXT si_text (si_text);
 
+ALTER TABLE recentchanges
+  ADD INDEX rc_timestamp (rc_timestamp),
+  ADD INDEX rc_namespace_title (rc_namespace, rc_title),
+  ADD INDEX rc_cur_id (rc_cur_id);
+
+ALTER TABLE archive
+  ADD KEY `name_title_timestamp` (`ar_namespace`,`ar_title`,`ar_timestamp`);
+
+ALTER TABLE watchlist
+  ADD KEY namespace_title (wl_namespace,wl_title);
+
index dacec07..f0e20f0 100644 (file)
@@ -8,9 +8,11 @@
 
 function dropTextIndex()
 {
-       echo "Dropping index...\n";
-       $sql = "ALTER TABLE searchindex DROP INDEX si_title, DROP INDEX si_text";
-       $res = wfQuery($sql, DB_WRITE, "dropTextIndex" );
+       if ( wfIndexExists( "searchindex", "si_title" ) ) {
+               echo "Dropping index...\n";
+               $sql = "ALTER TABLE searchindex DROP INDEX si_title, DROP INDEX si_text";
+               $res = wfQuery($sql, DB_WRITE, "dropTextIndex" );
+       }
 }
 
 function createTextIndex()
index dba66f4..dfd5051 100644 (file)
@@ -1,7 +1,7 @@
 
 body { margin: 0px; padding: 0px; }
 #specialform { display: inline; }
-#content { position: absolute; top: 0; margin: 0; padding: 0; }
+#content { top: 0; margin: 0; padding: 0; }
 #topbar { padding: 0px; }
 #powersearch {
   background: #DDEEFF; border-style: solid; border-width: 1; padding: 2;
@@ -86,6 +86,7 @@ h1.pagetitle { padding-bottom: 0; margin-bottom: 0; }
 }
 a { color: #223366; }
 a.external { color: #336644; }
+a:visited { color: #8D0749; }
 a.printable { text-decoration: underline; }
 a.stub { color:#772233; text-decoration:none; }
 h2, h3, h4, h5, h6 { margin-bottom: 0; }
index 2d22bf3..efcd746 100644 (file)
@@ -74,7 +74,7 @@ function toggleToc() {
        }
 }
 
-
+/* CHECK MERGE @@@ */
 /* Temporary hack for Mozilla bug; revert to quirks mode handling of <hr> */
 if(navigator.userAgent &&
    navigator.userAgent.indexOf('Gecko') != -1 &&
index 14e3b81..1f33328 100644 (file)
@@ -15,6 +15,13 @@ a.stub { color:#772233; text-decoration:none; }
 a.stub { color:#772233; text-decoration:none; }
 body { margin: 0px; padding: 4px; }
 form.inline { display: inline; }
+
+/* CHECK MERGE @@@
+ * h1.pagetitle { padding-top: 0; margin-top: 0; padding-bottom: 0; margin-bottom: 0;
+ * font-size:130%; }
+ * h2 { font-size: 112.5%; }
+ */
+
 h1.pagetitle { padding-top: 0; margin-top: 0; padding-bottom: 0; margin-bottom: 0;
 font-size:150%; }
 h2 { font-size: 120%; }
index b3c04ee..a5f79b9 100644 (file)
@@ -150,7 +150,7 @@ function update_passwords() {
          "database. If you have already done this (if you've run this update\n" .
          "script once before, for example), doing so again will make all your\n" .
          "user accounts inaccessible, so be sure you only do this once.\n" .
-         "Update user passwords? (yes/no) ";
+         "Update user passwords? (yes/no)";
 
        $resp = readconsole();
     if ( ! ( "Y" == $resp{0} || "y" == $resp{0} ) ) { return; }
@@ -172,7 +172,7 @@ function update_passwords() {
 function alter_ipblocks() {
        global $wgAlterSpecs;
        
-       if ( field_exists( "ipblocks", "ipb_id" ) ) {
+       if ( wfFieldExists( "ipblocks", "ipb_id" ) ) {
                return;
        }
        
@@ -186,18 +186,4 @@ function alter_ipblocks() {
                "ADD PRIMARY KEY (ipb_id)";
 }
 
-function field_exists( $table, $field ) {
-       $fname = "Update script: field_exists";
-       $res = wfQuery( "DESCRIBE $table", DB_READ, $fname );
-       $found = false;
-       
-       while ( $row = wfFetchObject( $res ) ) {
-               if ( $row->Field == $field ) {
-                       $found = true;
-                       break;
-               }
-       }
-       return $found;
-}
-
 ?>
index 27d9e4c..1c61640 100644 (file)
@@ -40,28 +40,28 @@ if ( "" == $title && "delete" != $action ) {
 } else {
        $wgTitle = Title::newFromURL( $title );
 #      if( $wgTitle->getInterwiki() != "" or $wgTitle->getDBkey() == "" or strncmp($wgTitle->getDBkey(),"_",1) == 0 ) {
-       if( $wgTitle->getInterwiki() != "" or $wgTitle->getDBkey() == "" ) {
+       if( !$wgTitle or $wgTitle->getInterwiki() != "" or $wgTitle->getDBkey() == "" ) {
+               $wgTitle = Title::newFromText( wfMsg( "badtitle" ) );
                $wgOut->errorpage( "badtitle", "badtitletext" );
                $wgOut->output();
                exit;
        }
 }
-wfProfileOut();
-if ( -1 == $wgTitle->getNamespace() ) {
+wfProfileOut( "main-misc-setup" );
+
+if ( Namespace::getSpecial() == $wgTitle->getNamespace() ) {
        wfSpecialPage();
 } else if ( "" != $search ) {
-       include_once( "$IP/SearchEngine.php" );
        if($go) {
-       
-               wfGo ($search);
-       
+               wfGo( $search );
        } else {
-       
                wfSearch( $search );
-               
        }
-               
 } else {
+       if ( Namespace::getMedia() == $wgTitle->getNamespace() ) {
+               $wgTitle = Title::makeTitle( Namespace::getImage(), $wgTitle->getDBkey() );
+       }       
+       
        switch( $wgTitle->getNamespace() ) {
        case 6:
                include_once( "$IP/ImagePage.php" );