phpunit testcases on the plural rules for am, ar, be, be_tarask, bh, bs and hi languages
[lhc/web/wiklou.git] / includes / WikiPage.php
index c03078d..57fb7d5 100644 (file)
@@ -24,7 +24,8 @@ class WikiPage extends Page {
        public $mDataLoaded = false;         // !< Boolean
        public $mIsRedirect = false;         // !< Boolean
        public $mLatest = false;             // !< Integer (false means "not loaded")
-       public $mPreparedEdit = false;           // !< Array
+       public $mPreparedEdit = false;       // !< Array
+       /**@}}*/
 
        /**
         * @var Title
@@ -36,9 +37,20 @@ class WikiPage extends Page {
         */
        protected $mLastRevision = null;
 
-       protected $mTimestamp = '';             // !< String
-       protected $mTouched = '19700101000000'; // !< String
-       /**@}}*/
+       /**
+        * @var string; timestamp of the current revision or empty string if not loaded
+        */
+       protected $mTimestamp = '';
+
+       /**
+        * @var string
+        */
+       protected $mTouched = '19700101000000';
+
+       /**
+        * @var int|null
+        */
+       protected $mCounter = null;
 
        /**
         * Constructor and clear the article
@@ -193,36 +205,39 @@ class WikiPage extends Page {
         * @return mixed false, Title object of local target, or string with URL
         */
        public function getRedirectURL( $rt ) {
-               if ( $rt ) {
-                       if ( $rt->getInterwiki() != '' ) {
-                               if ( $rt->isLocal() ) {
-                                       // Offsite wikis need an HTTP redirect.
-                                       //
-                                       // This can be hard to reverse and may produce loops,
-                                       // so they may be disabled in the site configuration.
-                                       $source = $this->mTitle->getFullURL( 'redirect=no' );
-                                       return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) );
-                               }
+               if ( !$rt ) {
+                       return false;
+               }
+
+               if ( $rt->isExternal() ) {
+                       if ( $rt->isLocal() ) {
+                               // Offsite wikis need an HTTP redirect.
+                               //
+                               // This can be hard to reverse and may produce loops,
+                               // so they may be disabled in the site configuration.
+                               $source = $this->mTitle->getFullURL( 'redirect=no' );
+                               return $rt->getFullURL( 'rdfrom=' . urlencode( $source ) );
                        } else {
-                               if ( $rt->isSpecialPage() ) {
-                                       // Gotta handle redirects to special pages differently:
-                                       // Fill the HTTP response "Location" header and ignore
-                                       // the rest of the page we're on.
-                                       //
-                                       // This can be hard to reverse, so they may be disabled.
-                                       if ( $rt->isSpecial( 'Userlogout' ) ) {
-                                               // rolleyes
-                                       } else {
-                                               return $rt->getFullURL();
-                                       }
-                               }
+                               // External pages pages without "local" bit set are not valid
+                               // redirect targets
+                               return false;
+                       }
+               }
 
-                               return $rt;
+               if ( $rt->isSpecialPage() ) {
+                       // Gotta handle redirects to special pages differently:
+                       // Fill the HTTP response "Location" header and ignore
+                       // the rest of the page we're on.
+                       //
+                       // Some pages are not valid targets
+                       if ( $rt->isValidRedirectTarget() ) {
+                               return $rt->getFullURL();
+                       } else {
+                               return false;
                        }
                }
 
-               // No or invalid redirect
-               return false;
+               return $rt;
        }
 
        /**
@@ -239,10 +254,11 @@ class WikiPage extends Page {
        public function clear() {
                $this->mDataLoaded = false;
 
+               $this->mCounter = null;
                $this->mRedirectTarget = null; # Title object if set
                $this->mLastRevision = null; # Latest revision
-               $this->mTimestamp = '';
                $this->mTouched = '19700101000000';
+               $this->mTimestamp = '';
                $this->mIsRedirect = false;
                $this->mLatest = false;
                $this->mPreparedEdit = false;
@@ -378,6 +394,7 @@ class WikiPage extends Page {
                        # Old-fashioned restrictions
                        $this->mTitle->loadRestrictions( $data->page_restrictions );
 
+                       $this->mCounter     = intval( $data->page_counter );
                        $this->mTouched     = wfTimestamp( TS_MW, $data->page_touched );
                        $this->mIsRedirect  = intval( $data->page_is_redirect );
                        $this->mLatest      = intval( $data->page_latest );
@@ -417,12 +434,14 @@ class WikiPage extends Page {
        }
 
        /**
-        * Get the number of views of this page
-        *
         * @return int The view count for the page
         */
        public function getCount() {
-               return $this->mTitle->getCount();
+               if ( !$this->mDataLoaded ) {
+                       $this->loadPageData();
+               }
+
+               return $this->mCounter;
        }
 
        /**
@@ -1021,7 +1040,7 @@ class WikiPage extends Page {
                // Delete if changing from redirect to non-redirect
                $isRedirect = !is_null( $redirectTitle );
 
-               if ( !$isRedirect && !is_null( $lastRevIsRedirect ) && $lastRevIsRedirect === $isRedirect ) {
+               if ( !$isRedirect && $lastRevIsRedirect === false ) {
                        return true;
                }
 
@@ -1098,6 +1117,7 @@ class WikiPage extends Page {
                                $oldtext = $this->getRawText();
                                if ( $oldtext === false ) {
                                        wfDebug( __METHOD__ . ": no page text\n" );
+                                       wfProfileOut( __METHOD__ );
                                        return null;
                                }
                        } else {
@@ -1255,6 +1275,15 @@ class WikiPage extends Page {
                        # Update article, but only if changed.
                        $status->value['new'] = false;
 
+                       if ( !$oldid ) {
+                               # Article gone missing
+                               wfDebug( __METHOD__ . ": EDIT_UPDATE specified but article doesn't exist\n" );
+                               $status->fatal( 'edit-gone-missing' );
+
+                               wfProfileOut( __METHOD__ );
+                               return $status;
+                       }
+
                        # Make sure the revision is either completely inserted or not inserted at all
                        if ( !$wgDBtransactions ) {
                                $userAbort = ignore_user_abort( true );
@@ -1274,15 +1303,6 @@ class WikiPage extends Page {
                        $changed = ( strcmp( $text, $oldtext ) != 0 );
 
                        if ( $changed ) {
-                               if ( !$this->mLatest ) {
-                                       # Article gone missing
-                                       wfDebug( __METHOD__ . ": EDIT_UPDATE specified but article doesn't exist\n" );
-                                       $status->fatal( 'edit-gone-missing' );
-
-                                       wfProfileOut( __METHOD__ );
-                                       return $status;
-                               }
-
                                $dbw->begin();
                                $revisionId = $revision->insertOn( $dbw );
 
@@ -1328,6 +1348,10 @@ class WikiPage extends Page {
                                        $user->incEditCount();
                                        $dbw->commit();
                                }
+                       } else {
+                               // Bug 32948: revision ID must be set to page {{REVISIONID}} and
+                               // related variables correctly
+                               $revision->setId( $this->getLatest() );
                        }
 
                        if ( !$wgDBtransactions ) {
@@ -1347,8 +1371,6 @@ class WikiPage extends Page {
                        if ( !$changed ) {
                                $status->warning( 'edit-no-change' );
                                $revision = null;
-                               // Keep the same revision ID, but do some updates on it
-                               $revisionId = $this->getLatest();
                                // Update page_touched, this is usually implicit in the page update
                                // Other cache updates are done in onArticleEdit()
                                $this->mTitle->invalidateCache();
@@ -1901,10 +1923,6 @@ class WikiPage extends Page {
                        return false;
                }
 
-               DeferredUpdates::addUpdate(
-                       new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 )
-               );
-
                // Bitfields to further suppress the content
                if ( $suppress ) {
                        $bitfield = 0;
@@ -1952,9 +1970,6 @@ class WikiPage extends Page {
                        ), __METHOD__
                );
 
-               # Delete restrictions for it
-               $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
-
                # Now that it's safely backed up, delete it
                $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__ );
                $ok = ( $dbw->affectedRows() > 0 ); // getArticleId() uses slave, could be laggy
@@ -1964,6 +1979,39 @@ class WikiPage extends Page {
                        return false;
                }
 
+               $this->doDeleteUpdates( $id );
+
+               # Log the deletion, if the page was suppressed, log it at Oversight instead
+               $logtype = $suppress ? 'suppress' : 'delete';
+
+               $logEntry = new ManualLogEntry( $logtype, 'delete' );
+               $logEntry->setPerformer( $user );
+               $logEntry->setTarget( $this->mTitle );
+               $logEntry->setComment( $reason );
+               $logid = $logEntry->insert();
+               $logEntry->publish( $logid );
+
+               if ( $commit ) {
+                       $dbw->commit();
+               }
+
+               wfRunHooks( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id ) );
+               return true;
+       }
+
+       /**
+        * Do some database updates after deletion
+        *
+        * @param $id Int: page_id value of the page being deleted
+        */
+       public function doDeleteUpdates( $id ) {
+               DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 1, - (int)$this->isCountable(), -1 ) );
+
+               $dbw = wfGetDB( DB_MASTER );
+
+               # Delete restrictions for it
+               $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
+
                # Fix category table counts
                $cats = array();
                $res = $dbw->select( 'categorylinks', 'cl_to', array( 'cl_from' => $id ), __METHOD__ );
@@ -2008,23 +2056,6 @@ class WikiPage extends Page {
 
                # Clear the cached article id so the interface doesn't act like we exist
                $this->mTitle->resetArticleID( 0 );
-
-               # Log the deletion, if the page was suppressed, log it at Oversight instead
-               $logtype = $suppress ? 'suppress' : 'delete';
-
-               $logEntry = new ManualLogEntry( $logtype, 'delete' );
-               $logEntry->setPerformer( $user );
-               $logEntry->setTarget( $this->mTitle );
-               $logEntry->setComment( $reason );
-               $logid = $logEntry->insert();
-               $logEntry->publish( $logid );
-
-               if ( $commit ) {
-                       $dbw->commit();
-               }
-
-               wfRunHooks( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id ) );
-               return true;
        }
 
        /**
@@ -2191,7 +2222,7 @@ class WikiPage extends Page {
                }
 
                # Actually store the edit
-               $status = $this->doEdit( $target->getText(), $summary, $flags, $target->getId() );
+               $status = $this->doEdit( $target->getText(), $summary, $flags, $target->getId(), $guser );
                if ( !empty( $status->value['revision'] ) ) {
                        $revId = $status->value['revision']->getId();
                } else {