Updates 'redirect' table on each save. WARNING: Breaking change. You must have the...
authorYuri Astrakhan <yurik@users.mediawiki.org>
Sun, 29 Oct 2006 21:25:40 +0000 (21:25 +0000)
committerYuri Astrakhan <yurik@users.mediawiki.org>
Sun, 29 Oct 2006 21:25:40 +0000 (21:25 +0000)
includes/Article.php

index 11eb966..c422cc1 100644 (file)
@@ -997,25 +997,31 @@ class Article {
         *                          when different from the currently set value.
         *                          Giving 0 indicates the new page flag should
         *                          be set on.
+        * @param bool $lastRevIsRedirect If given, will optimize adding and 
+        *                                                      removing rows in redirect table.
         * @return bool true on success, false on failure
         * @private
         */
-       function updateRevisionOn( &$dbw, $revision, $lastRevision = null ) {
+       function updateRevisionOn( &$dbw, $revision, $lastRevision = null, $lastRevIsRedirect = null ) {
                wfProfileIn( __METHOD__ );
 
+               $text = $revision->getText();
+               $rt = Title::newFromRedirect( $text );
+               
+               $this->updateRedirectOn( $dbw, $rt, $lastRevIsRedirect ); 
+
                $conditions = array( 'page_id' => $this->getId() );
                if( !is_null( $lastRevision ) ) {
                        # An extra check against threads stepping on each other
                        $conditions['page_latest'] = $lastRevision;
                }
 
-               $text = $revision->getText();
                $dbw->update( 'page',
                        array( /* SET */
                                'page_latest'      => $revision->getId(),
                                'page_touched'     => $dbw->timestamp(),
                                'page_is_new'      => ($lastRevision === 0) ? 1 : 0,
-                               'page_is_redirect' => Article::isRedirect( $text ) ? 1 : 0,
+                               'page_is_redirect' => $rt !== NULL ? 1 : 0,
                                'page_len'         => strlen( $text ),
                        ),
                        $conditions,
@@ -1025,6 +1031,56 @@ class Article {
                return ( $dbw->affectedRows() != 0 );
        }
 
+       /**
+        * Add row to the redirect table if this is a redirect, remove otherwise. 
+        *
+        * @param Database $dbw
+        * @param $redirectTitle a title object pointing to the redirect target,
+        *                                                      or NULL if this is not a redirect  
+        * @param bool $lastRevIsRedirect If given, will optimize adding and 
+        *                                                      removing rows in redirect table.
+        * @return bool true on success, false on failure
+        * @private
+        */
+       function updateRedirectOn( &$dbw, $redirectTitle, $lastRevIsRedirect = null ) {
+
+               // Always update redirects (target link might have changed)
+               // Update/Insert if we don't know if the last revision was a redirect or not
+               // Delete if changing from redirect to non-redirect
+               $isRedirect = !is_null($redirectTitle);
+               if ($isRedirect || is_null($lastRevIsRedirect) || $lastRevIsRedirect !== $isRedirect) {
+
+                       wfProfileIn( __METHOD__ );
+
+                       $where = array('rd_from' => $this->getId());
+
+                       if ($isRedirect) {
+
+                               // This title is a redirect, Add/Update row in the redirect table
+                               $set = array( /* SET */
+                                       'rd_namespace' => $redirectTitle->getNamespace(),
+                                       'rd_title'     => $redirectTitle->getDBkey()
+                               );
+
+                               $dbw->update( 'redirect', $set, $where, __METHOD__ );
+
+                               if ( $dbw->affectedRows() == 0 ) {
+                                       // Update failed, need to insert the row instead
+                                       $dbw->insert( 'redirect', array_merge($set, $where), __METHOD__ );
+                               }
+                       } else {
+
+                               // This is not a redirect, remove row from redirect table 
+                               $dbw->delete( 'redirect', $where, __METHOD__);
+                       }
+
+                       wfProfileOut( __METHOD__ );
+                       return ( $dbw->affectedRows() != 0 );
+               }
+               
+               return true;
+       }
+
        /**
         * If the given revision is newer than the currently set page_latest,
         * update the page record. Otherwise, do nothing.
@@ -1037,7 +1093,7 @@ class Article {
 
                $row = $dbw->selectRow(
                        array( 'revision', 'page' ),
-                       array( 'rev_id', 'rev_timestamp' ),
+                       array( 'rev_id', 'rev_timestamp', 'page_is_redirect' ),
                        array(
                                'page_id' => $this->getId(),
                                'page_latest=rev_id' ),
@@ -1048,12 +1104,14 @@ class Article {
                                return false;
                        }
                        $prev = $row->rev_id;
+                       $lastRevIsRedirect = $row->page_is_redirect === '1';
                } else {
                        # No or missing previous revision; mark the page as new
                        $prev = 0;
+                       $lastRevIsRedirect = null;
                }
 
-               $ret = $this->updateRevisionOn( $dbw, $revision, $prev );
+               $ret = $this->updateRevisionOn( $dbw, $revision, $prev, $lastRevIsRedirect );
                wfProfileOut( __METHOD__ );
                return $ret;
        }