Capitalization fix in memcached setting
[lhc/web/wiklou.git] / includes / Article.php
index 5fbeb2a..b361976 100644 (file)
@@ -91,7 +91,19 @@ class Article {
                        # as pages are saved if $wgCompressRevisions is set.
                        $text = gzinflate( $text );
                }
-               
+                       
+               if( in_array( 'object', $flags ) ) {
+                       # Generic compressed storage
+                       $obj = unserialize( $text );
+
+                       # Bugger, corrupted my test database by double-serializing
+                       if ( !is_object( $obj ) ) {
+                               $obj = unserialize( $obj );
+                       }
+
+                       $text = $obj->getText();
+               }
+       
                global $wgLegacyEncoding;
                if( $wgLegacyEncoding && !in_array( 'utf-8', $flags ) ) {
                        # Old revisions kept around in a legacy encoding?
@@ -99,11 +111,6 @@ class Article {
                        global $wgInputEncoding, $wgContLang;
                        $text = $wgContLang->iconv( $wgLegacyEncoding, $wgInputEncoding, $text );
                }
-               
-               if( in_array( 'link', $flags ) ) {
-                       # Handle link type
-                       $text = Article::followLink( $text );
-               }
                return $text;
        }
 
@@ -137,131 +144,6 @@ class Article {
                return implode( ',', $flags );
        }
 
-       /**
-        * Returns the text associated with a "link" type old table row
-        * @static
-        * @param mixed $link
-        * @return string $text|false
-        */
-       function followLink( $link ) {
-               # Split the link into fields and values
-               $lines = explode( '\n', $link );
-               $hash = '';
-               $locations = array();
-               foreach ( $lines as $line ) {
-                       # Comments
-                       if ( $line{0} == '#' ) {
-                               continue;
-                       }
-                       # Field/value pairs
-                       if ( preg_match( '/^(.*?)\s*:\s*(.*)$/', $line, $matches ) ) {
-                               $field = strtolower($matches[1]);
-                               $value = $matches[2];
-                               if ( $field == 'hash' ) {
-                                       $hash = $value;
-                               } elseif ( $field == 'location' ) {
-                                       $locations[] = $value;
-                               }
-                       }
-               }
-
-               if ( $hash === '' ) {
-                       return false;
-               }
-
-               # Look in each specified location for the text
-               $text = false;
-               foreach ( $locations as $location ) {
-                       $text = Article::fetchFromLocation( $location, $hash );
-                       if ( $text !== false ) {
-                               break;
-                       }
-               }
-
-               return $text;
-       }
-
-       /**
-        * @static
-        * @param $location
-        * @param $hash
-        */
-       function fetchFromLocation( $location, $hash ) {
-               global $wgLoadBalancer;
-               $fname = 'fetchFromLocation';
-               wfProfileIn( $fname );
-
-               $p = strpos( $location, ':' );
-               if ( $p === false ) {
-                       wfProfileOut( $fname );
-                       return false;
-               }
-
-               $type = substr( $location, 0, $p );
-               $text = false;
-               switch ( $type ) {
-                       case 'mysql':
-                               # MySQL locations are specified by mysql://<machineID>/<dbname>/<tblname>/<index>
-                               # Machine ID 0 is the current connection
-                               if ( preg_match( '/^mysql:\/\/(\d+)\/([A-Za-z_]+)\/([A-Za-z_]+)\/([A-Za-z_]+)$/',
-                                 $location, $matches ) ) {
-                                       $machineID = $matches[1];
-                                       $dbName = $matches[2];
-                                       $tblName = $matches[3];
-                                       $index = $matches[4];
-                                       if ( $machineID == 0 ) {
-                                               # Current connection
-                                               $db =& $this->getDB();
-                                       } else {
-                                               # Alternate connection
-                                               $db =& $wgLoadBalancer->getConnection( $machineID );
-
-                                               if ( array_key_exists( $machineId, $wgKnownMysqlServers ) ) {
-                                                       # Try to open, return false on failure
-                                                       $params = $wgKnownDBServers[$machineId];
-                                                       $db = Database::newFromParams( $params['server'], $params['user'], $params['password'],
-                                                               $dbName, 1, DBO_IGNORE );
-                                               }
-                                       }
-                                       if ( $db->isOpen() ) {
-                                               $index = $db->strencode( $index );
-                                               $res = $db->query( "SELECT blob_data FROM $dbName.$tblName " .
-                                                       "WHERE blob_index='$index' " . $this->getSelectOptions(), $fname );
-                                               $row = $db->fetchObject( $res );
-                                               $text = $row->text_data;
-                                       }
-                               }
-                               break;
-                       case 'file':
-                               # File locations are of the form file://<filename>, relative to the current directory
-                               if ( preg_match( '/^file:\/\/(.*)$', $location, $matches ) )
-                               $filename = strstr( $location, 'file://' );
-                               $text = @file_get_contents( $matches[1] );
-               }
-               if ( $text !== false ) {
-                       # Got text, now we need to interpret it
-                       # The first line contains information about how to do this
-                       $p = strpos( $text, '\n' );
-                       $type = substr( $text, 0, $p );
-                       $text = substr( $text, $p + 1 );
-                       switch ( $type ) {
-                               case 'plain':
-                                       break;
-                               case 'gzip':
-                                       $text = gzinflate( $text );
-                                       break;
-                               case 'object':
-                                       $object = unserialize( $text );
-                                       $text = $object->getItem( $hash );
-                                       break;
-                               default:
-                                       $text = false;
-                       }
-               }
-               wfProfileOut( $fname );
-               return $text;
-       }
-
        /**
         * Note that getContent/loadContent may follow redirects if
         * not told otherwise, and so may cause a change to mTitle.
@@ -410,25 +292,21 @@ class Article {
        }
 
        /**
-        * Load the revision (including cur_text) into this object
-       */
-       function loadContent( $noredir = false ) {
-               global $wgOut, $wgRequest;
-
-               if ( $this->mContentLoaded ) return;
-               
-               $dbr =& $this->getDB();
-               # Query variables :P
-               $oldid = $wgRequest->getVal( 'oldid' );
-               $redirect = $wgRequest->getVal( 'redirect' );
-
-               $fname = 'Article::loadContent';
+        * Return the oldid of the article that is to be shown.
+        * For requests with a "direction", this is not the oldid of the
+        * query
+        */
+       function getOldID() {
+               global $wgRequest, $wgOut;
+               static $lastid;
 
-               # Pre-fill content with error message so that if something
-               # fails we'll have something telling us what we intended.
+               if ( isset( $lastid ) ) {
+                       return $lastid;
+               }
 
-               $t = $this->mTitle->getPrefixedText();
+               $oldid = $wgRequest->getVal( 'oldid' );
                if ( isset( $oldid ) ) {
+                       $dbr =& $this->getDB();
                        $oldid = IntVal( $oldid );
                        if ( $wgRequest->getVal( 'direction' ) == 'next' ) {
                                $nextid = $this->mTitle->getNextRevisionID( $oldid );
@@ -445,7 +323,32 @@ class Article {
                                        # TODO
                                }
                        }
+                       $lastid = $oldid;
                }
+               return @$oldid; # "@" to be able to return "unset" without PHP complaining
+       }
+
+
+       /**
+        * Load the revision (including cur_text) into this object
+       */
+       function loadContent( $noredir = false ) {
+               global $wgOut, $wgRequest;
+
+               if ( $this->mContentLoaded ) return;
+               
+               $dbr =& $this->getDB();
+               # Query variables :P
+               $oldid = $this->getOldID();
+               $redirect = $wgRequest->getVal( 'redirect' );
+
+               $fname = 'Article::loadContent';
+
+               # Pre-fill content with error message so that if something
+               # fails we'll have something telling us what we intended.
+
+               $t = $this->mTitle->getPrefixedText();
+
                if ( isset( $oldid ) ) {
                        $t .= ',oldid='.$oldid;
                }
@@ -507,7 +410,7 @@ class Article {
                        $this->mTitle->mRestrictions = explode( ',', trim( $s->cur_restrictions ) );
                        $this->mTitle->mRestrictionsLoaded = true;
                } else { # oldid set, retrieve historical version
-                       $s = $dbr->getArray( 'old', $this->getOldContentFields(), array( 'old_id' => $oldid ),
+                       $s = $dbr->selectRow( 'old', $this->getOldContentFields(), array( 'old_id' => $oldid ),
                                $fname, $this->getSelectOptions() );
                        if ( $s === false ) {
                                return;
@@ -698,7 +601,7 @@ class Article {
                $fname = 'Article::loadLastEdit';
 
                $dbr =& $this->getDB();
-               $s = $dbr->getArray( 'cur',
+               $s = $dbr->selectRow( 'cur',
                  array( 'cur_user','cur_user_text','cur_timestamp', 'cur_comment','cur_minor_edit' ),
                  array( 'cur_id' => $this->getID() ), $fname, $this->getSelectOptions() );
 
@@ -776,14 +679,14 @@ class Article {
         * the given title.
        */
        function view() {
-               global $wgUser, $wgOut, $wgRequest, $wgOnlySysopsCanPatrol;
+               global $wgUser, $wgOut, $wgRequest, $wgOnlySysopsCanPatrol, $wgLang;
                global $wgLinkCache, $IP, $wgEnableParserCache, $wgStylePath, $wgUseRCPatrol;
                $sk = $wgUser->getSkin();
 
                $fname = 'Article::view';
                wfProfileIn( $fname );
                # Get variables from query string
-               $oldid = $wgRequest->getVal( 'oldid' );
+               $oldid = $this->getOldID();
                $diff = $wgRequest->getVal( 'diff' );
                $rcid = $wgRequest->getVal( 'rcid' );
 
@@ -797,20 +700,22 @@ class Article {
                        $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
                        $de = new DifferenceEngine( $oldid, $diff, $rcid );
                        $de->showDiffPage();
-                       wfProfileOut( $fname );
                        if( $diff == 0 ) {
                                # Run view updates for current revision only
                                $this->viewUpdates();
                        }
+                       wfProfileOut( $fname );
                        return;
                }
                if ( empty( $oldid ) && $this->checkTouched() ) {
                        if( $wgOut->checkLastModified( $this->mTouched ) ){
+                               wfProfileOut( $fname );
                                return;
                        } else if ( $this->tryFileCache() ) {
                                # tell wgOut that output is taken care of
                                $wgOut->disable();
                                $this->viewUpdates();
+                               wfProfileOut( $fname );
                                return;
                        }
                }
@@ -869,8 +774,10 @@ class Article {
                                $targetUrl = $rt->escapeLocalURL();
                                $titleText = htmlspecialchars( $rt->getPrefixedText() );
                                $link = $sk->makeLinkObj( $rt );
-                               $wgOut->addHTML( '<img valign="center" src="'.$imageUrl.'">' .
+
+                               $wgOut->addHTML( '<img valign="center" src="'.$imageUrl.'" alt="#REDIRECT" />' .
                                  '<span class="redirectText">'.$link.'</span>' );
+
                        } else if ( $pcache ) {
                                # Display content and save to parser cache
                                $wgOut->addPrimaryWikiText( $text, $this );
@@ -883,7 +790,7 @@ class Article {
                # If we have been passed an &rcid= parameter, we want to give the user a
                # chance to mark this new article as patrolled.
                if ( $wgUseRCPatrol && !is_null ( $rcid ) && $rcid != 0 && $wgUser->getID() != 0 &&
-                    ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+                    ( $wgUser->isAllowed('patrol') || !$wgOnlySysopsCanPatrol ) )
                {
                        $wgOut->addHTML( wfMsg ( 'markaspatrolledlink',
                                $sk->makeKnownLinkObj ( $this->mTitle, wfMsg ( 'markaspatrolledtext' ),
@@ -925,14 +832,14 @@ class Article {
                $now = wfTimestampNow();
                $won = wfInvertTimestamp( $now );
                wfSeedRandom();
-               $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
+               $rand = wfRandom();
                $dbw =& wfGetDB( DB_MASTER );
 
                $cur_id = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
 
                $isminor = ( $isminor && $wgUser->getID() ) ? 1 : 0;
 
-               $dbw->insertArray( 'cur', array(
+               $dbw->insert( 'cur', array(
                        'cur_id' => $cur_id,
                        'cur_namespace' => $ns,
                        'cur_title' => $ttl,
@@ -967,7 +874,7 @@ class Article {
 
                # The talk page isn't in the regular link tables, so we need to update manually:
                $talkns = $ns ^ 1; # talk -> normal; normal -> talk
-               $dbw->updateArray( 'cur', array('cur_touched' => $dbw->timestamp($now) ),
+               $dbw->update( 'cur', array('cur_touched' => $dbw->timestamp($now) ),
                        array(  'cur_namespace' => $talkns, 'cur_title' => $ttl ), $fname );
 
                # standard deferred updates
@@ -989,7 +896,7 @@ class Article {
                        $dbw =& wfGetDB( DB_MASTER );
                        $ns = $this->mTitle->getNamespace();
                        $title = $this->mTitle->getDBkey();
-                       $obj = $dbw->getArray( 'old', 
+                       $obj = $dbw->selectRow( 'old', 
                                array( 'old_text','old_flags'), 
                                array( 'old_namespace' => $ns, 'old_title' => $title, 
                                        'old_timestamp' => $dbw->timestamp($edittime)),
@@ -1120,7 +1027,7 @@ class Article {
                        $won = wfInvertTimestamp( $now );
 
                        # First update the cur row
-                       $dbw->updateArray( 'cur',
+                       $dbw->update( 'cur',
                                array( /* SET */
                                        'cur_text' => $text,
                                        'cur_comment' => $summary,
@@ -1147,7 +1054,7 @@ class Article {
                                # This overwrites $oldtext if revision compression is on
                                $flags = Article::compressRevisionText( $oldtext );
 
-                               $dbw->insertArray( 'old',
+                               $dbw->insert( 'old',
                                        array(
                                                'old_id' => $dbw->nextSequenceValue( 'old_old_id_seq' ),
                                                'old_namespace' => $this->mTitle->getNamespace(),
@@ -1282,7 +1189,7 @@ class Article {
                        $wgOut->loginToUse();
                        return;
                }
-               if ( $wgOnlySysopsCanPatrol && !$wgUser->isSysop() )
+               if ( $wgOnlySysopsCanPatrol && !$wgUser->isAllowed('patrol') )
                {
                        $wgOut->sysopRequired();
                        return;
@@ -1353,7 +1260,7 @@ class Article {
        function protect( $limit = 'sysop' ) {
                global $wgUser, $wgOut, $wgRequest;
 
-               if ( ! $wgUser->isSysop() ) {
+               if ( ! $wgUser->isAllowed('protect') ) {
                        $wgOut->sysopRequired();
                        return;
                }
@@ -1372,7 +1279,7 @@ class Article {
 
                if ( $confirm ) {
                        $dbw =& wfGetDB( DB_MASTER );
-                       $dbw->updateArray( 'cur',
+                       $dbw->update( 'cur',
                                array( /* SET */
                                        'cur_touched' => $dbw->timestamp(),
                                        'cur_restrictions' => (string)$limit
@@ -1480,7 +1387,7 @@ class Article {
                # This code desperately needs to be totally rewritten
 
                # Check permissions
-               if ( ( ! $wgUser->isSysop() ) ) {
+               if ( ( ! $wgUser->isAllowed('delete') ) ) {
                        $wgOut->sysopRequired();
                        return;
                }
@@ -1508,7 +1415,7 @@ class Article {
                $dbr =& $this->getDB();
                $ns = $this->mTitle->getNamespace();
                $title = $this->mTitle->getDBkey();
-               $old = $dbr->getArray( 'old',
+               $old = $dbr->selectRow( 'old',
                        array( 'old_text', 'old_flags' ),
                        array(
                                'old_namespace' => $ns,
@@ -1523,7 +1430,7 @@ class Article {
                }
 
                # Fetch cur_text
-               $s = $dbr->getArray( 'cur',
+               $s = $dbr->selectRow( 'cur',
                        array( 'cur_text' ),
                        array(
                                'cur_namespace' => $ns,
@@ -1762,7 +1669,7 @@ class Article {
                        $linkID = $titleObj->getArticleID();
                        $brokenLinks[] = array( 'bl_from' => $linkID, 'bl_to' => $t );
                }
-               $dbw->insertArray( 'brokenlinks', $brokenLinks, $fname, 'IGNORE' );
+               $dbw->insert( 'brokenlinks', $brokenLinks, $fname, 'IGNORE' );
 
                # Delete live links
                $dbw->delete( 'links', array( 'l_to' => $id ) );
@@ -1788,7 +1695,7 @@ class Article {
                global $wgUser, $wgOut, $wgRequest;
                $fname = 'Article::rollback';
 
-               if ( ! $wgUser->isSysop() ) {
+               if ( ! $wgUser->isAllowed('rollback') ) {
                        $wgOut->sysopRequired();
                        return;
                }
@@ -1806,7 +1713,7 @@ class Article {
                $n = $this->mTitle->getNamespace();
 
                # Get the last editor, lock table exclusively
-               $s = $dbw->getArray( 'cur',
+               $s = $dbw->selectRow( 'cur',
                        array( 'cur_id','cur_user','cur_user_text','cur_comment' ),
                        array( 'cur_title' => $tt, 'cur_namespace' => $n ),
                        $fname, 'FOR UPDATE'
@@ -1836,7 +1743,7 @@ class Article {
                }
 
                # Get the last edit not by this guy
-               $s = $dbw->getArray( 'old',
+               $s = $dbw->selectRow( 'old',
                        array( 'old_text','old_user','old_user_text','old_timestamp','old_flags' ),
                        array(
                                'old_namespace' => $n,
@@ -1853,7 +1760,7 @@ class Article {
 
                if ( $bot ) {
                        # Mark all reverted edits as bot
-                       $dbw->updateArray( 'recentchanges',
+                       $dbw->update( 'recentchanges',
                                array( /* SET */
                                        'rc_bot' => 1
                                ), array( /* WHERE */
@@ -1867,7 +1774,7 @@ class Article {
                $newcomment = wfMsg( 'revertpage', $s->old_user_text, $from );
                $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
                $wgOut->setRobotpolicy( 'noindex,nofollow' );
-               $wgOut->addHTML( '<h2>' . $newcomment . "</h2>\n<hr />\n" );
+               $wgOut->addHTML( '<h2>' . htmlspecialchars( $newcomment ) . "</h2>\n<hr />\n" );
                $this->updateArticle( Article::getRevisionText( $s ), $newcomment, 1, $this->mTitle->userIsWatching(), $bot );
                Article::onArticleEdit( $this->mTitle );
                $wgOut->returnToMain( false );
@@ -2027,7 +1934,7 @@ class Article {
                $fname = 'Article::checkTouched';
                $id = $this->getID();
                $dbr =& $this->getDB();
-               $s = $dbr->getArray( 'cur', array( 'cur_touched', 'cur_is_redirect' ),
+               $s = $dbr->selectRow( 'cur', array( 'cur_touched', 'cur_is_redirect' ),
                        array( 'cur_id' => $id ), $fname, $this->getSelectOptions() );
                if( $s !== false ) {
                        $this->mTouched = wfTimestamp(TS_MW,$s->cur_touched);
@@ -2091,14 +1998,14 @@ class Article {
                if ( $numRows ) {
                        # Update article
                        $fields['cur_is_new'] = 0;
-                       $dbw->updateArray( 'cur', $fields, array( 'cur_namespace' => $ns, 'cur_title' => $dbkey ), $fname );
+                       $dbw->update( 'cur', $fields, array( 'cur_namespace' => $ns, 'cur_title' => $dbkey ), $fname );
                } else {
                        # Insert new article
                        $fields['cur_is_new'] = 1;
                        $fields['cur_namespace'] = $ns;
                        $fields['cur_title'] = $dbkey;
-                       $fields['cur_random'] = $rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
-                       $dbw->insertArray( 'cur', $fields, $fname );
+                       $fields['cur_random'] = $rand = wfRandom();
+                       $dbw->insert( 'cur', $fields, $fname );
                }
                wfProfileOut( $fname );
        }