Revised design of Special:Userlogin
[lhc/web/wiklou.git] / includes / Title.php
index e81023a..aa8fb93 100644 (file)
@@ -575,10 +575,12 @@ class Title {
         */
        public function isLocal() {
                if ( $this->mInterwiki != '' ) {
-                       return Interwiki::fetch( $this->mInterwiki )->isLocal();
-               } else {
-                       return true;
+                       $iw = Interwiki::fetch( $this->mInterwiki );
+                       if ( $iw ) {
+                               return $iw->isLocal();
+                       }
                }
+               return true;
        }
 
        /**
@@ -680,7 +682,6 @@ class Title {
        public function getContentModel() {
                if ( !$this->mContentModel ) {
                        $linkCache = LinkCache::singleton();
-                       $linkCache->addLinkObj( $this );
                        $this->mContentModel = $linkCache->getGoodLinkFieldObj( $this, 'model' );
                }
 
@@ -994,7 +995,7 @@ class Title {
         */
        public function getSkinFromCssJsSubpage() {
                $subpage = explode( '/', $this->mTextform );
-               $subpage = $subpage[ count( $subpage ) - 1 ];
+               $subpage = $subpage[count( $subpage ) - 1];
                $lastdot = strrpos( $subpage, '.' );
                if ( $lastdot === false )
                        return $subpage; # Never happens: only called for names ending in '.css' or '.js'
@@ -1326,8 +1327,8 @@ class Title {
        }
 
        /**
-        * Helper to fix up the get{Local,Full,Link,Canonical}URL args
-        * get{Canonical,Full,Link,Local}URL methods accepted an optional
+        * Helper to fix up the get{Canonical,Full,Link,Local,Internal}URL args
+        * get{Canonical,Full,Link,Local,Internal}URL methods accepted an optional
         * second argument named variant. This was deprecated in favor
         * of passing an array of option with a "variant" key
         * Once $query2 is removed for good, this helper can be dropped
@@ -1340,7 +1341,9 @@ class Title {
         */
        private static function fixUrlQueryArgs( $query, $query2 = false ) {
                if( $query2 !== false ) {
-                       wfDeprecated( "Title::get{Canonical,Full,Link,Local} method called with a second parameter is deprecated. Add your parameter to an array passed as the first parameter.", "1.19" );
+                       wfDeprecated( "Title::get{Canonical,Full,Link,Local,Internal}URL " .
+                               "method called with a second parameter is deprecated. Add your " .
+                               "parameter to an array passed as the first parameter.", "1.19" );
                }
                if ( is_array( $query ) ) {
                        $query = wfArrayToCgi( $query );
@@ -1398,7 +1401,6 @@ class Title {
         * Get a URL with no fragment or server name.  If this page is generated
         * with action=render, $wgServer is prepended.
         *
-
         * @param string|array $query an optional query string,
         *   not used for interwiki links. Can be specified as an associative array as well,
         *   e.g., array( 'action' => 'edit' ) (keys and values will be URL-escaped).
@@ -2948,21 +2950,22 @@ class Title {
         * @return Bool
         */
        public function isRedirect( $flags = 0 ) {
-               if ( !( $flags & Title::GAID_FOR_UPDATE ) && !is_null( $this->mRedirect ) ) {
+               if ( !is_null( $this->mRedirect ) ) {
                        return $this->mRedirect;
                }
-
+               # Calling getArticleID() loads the field from cache as needed
                if ( !$this->getArticleID( $flags ) ) {
                        return $this->mRedirect = false;
                }
 
                $linkCache = LinkCache::singleton();
-               $linkCache->addLinkObj( $this );
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'redirect' );
-
                if ( $cached === null ) {
-                       // Should not happen
-                       throw new MWException( "LinkCache doesn't know redirect status of this title: " . $this->getPrefixedDBkey() );
+                       // TODO: check the assumption that the cache actually knows about this title
+                       // and handle this, such as get the title from the database.
+                       // See https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
+                       wfDebug( "LinkCache doesn't currently know about this title: " . $this->getPrefixedDBkey() );
+                       wfDebug( wfBacktrace() );
                }
 
                $this->mRedirect = (bool)$cached;
@@ -2978,21 +2981,20 @@ class Title {
         * @return Int
         */
        public function getLength( $flags = 0 ) {
-               if ( !( $flags & Title::GAID_FOR_UPDATE ) && $this->mLength != -1 ) {
+               if ( $this->mLength != -1 ) {
                        return $this->mLength;
                }
-
+               # Calling getArticleID() loads the field from cache as needed
                if ( !$this->getArticleID( $flags ) ) {
                        return $this->mLength = 0;
                }
-
                $linkCache = LinkCache::singleton();
-               $linkCache->addLinkObj( $this );
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'length' );
-
-               if ( $cached === null ) {
-                       // Should not happen
-                       throw new MWException( "LinkCache doesn't know redirect status of this title: " . $this->getPrefixedDBkey() );
+               if ( $cached === null ) { # check the assumption that the cache actually knows about this title
+                       # XXX: this does apparently happen, see https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
+                       #      as a stop gap, perhaps log this, but don't throw an exception?
+                       wfDebug( "LinkCache doesn't currently know about this title: " . $this->getPrefixedDBkey() );
+                       wfDebug( wfBacktrace() );
                }
 
                $this->mLength = intval( $cached );
@@ -3011,18 +3013,17 @@ class Title {
                if ( !( $flags & Title::GAID_FOR_UPDATE ) && $this->mLatestID !== false ) {
                        return intval( $this->mLatestID );
                }
-
+               # Calling getArticleID() loads the field from cache as needed
                if ( !$this->getArticleID( $flags ) ) {
                        return $this->mLatestID = 0;
                }
-
                $linkCache = LinkCache::singleton();
                $linkCache->addLinkObj( $this );
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'revision' );
-
-               if ( $cached === null ) {
-                       // Should not happen
-                       throw new MWException( "LinkCache doesn't know latest revision ID of this title: " . $this->getPrefixedDBkey() );
+               if ( $cached === null ) { # check the assumption that the cache actually knows about this title
+                       # XXX: this does apparently happen, see https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
+                       #      as a stop gap, perhaps log this, but don't throw an exception?
+                       throw new MWException( "LinkCache doesn't currently know about this title: " . $this->getPrefixedDBkey() );
                }
 
                $this->mLatestID = intval( $cached );
@@ -3838,6 +3839,7 @@ class Title {
 
                $this->resetArticleID( 0 );
                $nt->resetArticleID( $oldid );
+               $newpage->loadPageData( WikiPage::READ_LOCKING ); // bug 46397
 
                $newpage->updateRevisionOn( $dbw, $nullRevision );
 
@@ -3855,6 +3857,7 @@ class Title {
                        WikiPage::onArticleDelete( $this );
                } else {
                        $redirectArticle = WikiPage::factory( $this );
+                       $redirectArticle->loadFromRow( false, WikiPage::READ_LOCKING ); // bug 46397
                        $newid = $redirectArticle->insertOn( $dbw );
                        if ( $newid ) { // sanity
                                $redirectRevision = new Revision( array(
@@ -4070,8 +4073,8 @@ class Title {
 
                if ( $res->numRows() > 0 ) {
                        foreach ( $res as $row ) {
-                               // $data[] = Title::newFromText($wgContLang->getNSText ( NS_CATEGORY ).':'.$row->cl_to);
-                               $data[$wgContLang->getNSText( NS_CATEGORY ) . ':' . $row->cl_to] = $this->getFullText();
+                               // $data[] = Title::newFromText($wgContLang->getNsText ( NS_CATEGORY ).':'.$row->cl_to);
+                               $data[$wgContLang->getNsText( NS_CATEGORY ) . ':' . $row->cl_to] = $this->getFullText();
                        }
                }
                return $data;
@@ -4501,23 +4504,30 @@ class Title {
         */
        public function invalidateCache() {
                global $wgMemc;
+
                if ( wfReadOnly() ) {
                        return false;
                }
+
                $dbw = wfGetDB( DB_MASTER );
-               $success = $dbw->update(
-                       'page',
-                       array( 'page_touched' => $dbw->timestamp() ),
-                       $this->pageCond(),
-                       __METHOD__
-               );
+               $conds = $this->pageCond();
+               $dbw->onTransactionIdle( function() use ( $dbw, $conds ) {
+                       $dbw->update(
+                               'page',
+                               array( 'page_touched' => $dbw->timestamp() ),
+                               $conds,
+                               __METHOD__
+                       );
+               } );
                HTMLFileCache::clearFileCache( $this );
 
                // Clear page info.
                $revision = WikiPage::factory( $this )->getRevision();
-               if( $revision !== null ) {
+               if ( $revision !== null ) {
                        $memcKey = wfMemcKey( 'infoaction', $this->getPrefixedText(), $revision->getId() );
-                       $success = $success && $wgMemc->delete( $memcKey );
+                       $success = $wgMemc->delete( $memcKey );
+               } else {
+                       $success = true;
                }
 
                return $success;