* (bug 2572) Fix edit conflict handling
authorBrion Vibber <brion@users.mediawiki.org>
Tue, 28 Jun 2005 23:19:56 +0000 (23:19 +0000)
committerBrion Vibber <brion@users.mediawiki.org>
Tue, 28 Jun 2005 23:19:56 +0000 (23:19 +0000)
RELEASE-NOTES
includes/Article.php
includes/EditPage.php
includes/Revision.php

index 5609809..0e07b1a 100644 (file)
@@ -410,6 +410,7 @@ Various bugfixes, small features, and a few experimental things:
 * (bug 2562) Show rollback link for current revisions on diff pages
 * (bug 2583) Add --missinig option on rebuildImages.php to add db entries
   for uploaded files that don't have them
+* (bug 2572) Fix edit conflict handling
 
 
 === Caveats ===
index cd22c09..fdefb53 100644 (file)
@@ -524,7 +524,7 @@ class Article {
        function isRedirect( $text = false ) {
                if ( $text === false ) {
                        $this->loadContent();
-                       $titleObj = Title::newFromRedirect( $this->fetchRevisionText() );
+                       $titleObj = Title::newFromRedirect( $this->fetchContent( false, true ) );
                } else {
                        $titleObj = Title::newFromRedirect( $text );
                }
@@ -961,38 +961,6 @@ class Article {
                $oldid = 0; # new article
                $this->showArticle( $text, wfMsg( 'newarticle' ), false, $isminor, $now, $summary, $oldid );
        }
-
-       /**
-        * Fetch and uncompress the text for a given revision.
-        * Can ask by rev_id number or timestamp (set $field)
-        * FIXME: This function is broken. Eliminate all uses and remove.
-        * Use Revision class in place.
-        */
-       function fetchRevisionText( $revId = null, $field = 'rev_id' ) {
-               $fname = 'Article::fetchRevisionText';
-               $dbw =& wfGetDB( DB_MASTER );
-               if( $revId ) {
-                       $rev = $dbw->addQuotes( $revId );
-               } else {
-                       $rev = 'page_latest';
-               }
-               $result = $dbw->query(
-                       sprintf( "SELECT old_text, old_flags
-                               FROM %s,%s,%s
-                               WHERE old_id=rev_id AND rev_page=page_id AND page_id=%d
-                               AND %s=%s",
-                               $dbw->tableName( 'page' ),
-                               $dbw->tableName( 'revision' ),
-                               $dbw->tableName( 'text' ),
-                               IntVal( $this->mTitle->getArticleId() ),
-                               $field,
-                               $rev ),
-                       $fname );
-               $obj = $dbw->fetchObject( $result );
-               $dbw->freeResult( $result );
-               $oldtext = Revision::getRevisionText( $obj );
-               return $oldtext;
-       }
        
        function getTextOfLastEditWithSectionReplacedOrAdded($section, $text, $summary = '', $edittime = NULL) {
                $fname = 'Article::getTextOfLastEditWithSectionReplacedOrAdded';
index 1291a4c..f159470 100644 (file)
@@ -381,7 +381,8 @@ class EditPage {
                        $userid = $wgUser->getID();
 
                        if ( $isConflict) {
-                               wfDebug( "EditPage::editForm conflict! getting section '$this->section' for time '$this->edittime'\n" );
+                               wfDebug( "EditPage::editForm conflict! getting section '$this->section' for time '$this->edittime' (article time '" .
+                                       $this->mArticle->getTimestamp() . "'\n" );
                                $text = $this->mArticle->getTextOfLastEditWithSectionReplacedOrAdded(
                                        $this->section, $this->textbox1, $this->summary, $this->edittime);
                        }
@@ -393,6 +394,7 @@ class EditPage {
                        # Suppress edit conflict with self
 
                        if ( ( 0 != $userid ) && ( $this->mArticle->getUser() == $userid ) ) {
+                               wfDebug( "Suppressing edit conflict, same user.\n" );
                                $isConflict = false;
                        } else {
                                # switch from section editing to normal editing in edit conflict
@@ -401,9 +403,11 @@ class EditPage {
                                        if( $this->mergeChangesInto( $text ) ){
                                                // Successful merge! Maybe we should tell the user the good news?
                                                $isConflict = false;
+                                               wfDebug( "Suppressing edit conflict, successful merge.\n" );
                                        } else {
                                                $this->section = '';
                                                $this->textbox1 = $text;
+                                               wfDebug( "Keeping edit conflict, failed merge.\n" );
                                        }
                                }
                        }
@@ -875,16 +879,27 @@ END
         * @access private
         * @todo document
         */
-       function mergeChangesInto( &$text ){
-               $yourtext = $this->mArticle->fetchRevisionText();
-               
+       function mergeChangesInto( &$editText ){
                $db =& wfGetDB( DB_MASTER );
-               $oldText = $this->mArticle->fetchRevisionText(
-                       $db->timestamp( $this->edittime ),
-                       'rev_timestamp' );
                
-               if(wfMerge($oldText, $text, $yourtext, $result)){
-                       $text = $result;
+               // This is the revision the editor started from
+               $baseRevision = Revision::loadFromTimestamp(
+                       $db, $this->mArticle->mTitle, $this->edittime );
+               if( is_null( $baseRevision ) ) {
+                       return false;
+               }
+               $baseText = $baseRevision->getText();
+
+               // The current state, we want to merge updates into it
+               $currentRevision =  Revision::loadFromTitle(
+                       $db, $this->mArticle->mTitle );
+               if( is_null( $currentRevision ) ) {
+                       return false;
+               }
+               $currentText = $currentRevision->getText();
+               
+               if( wfMerge( $baseText, $editText, $currentText, $result ) ){
+                       $editText = $result;
                        return true;
                } else {
                        return false;
index 7c74bd0..1905a26 100644 (file)
@@ -75,6 +75,31 @@ class Revision {
                               'page_id=rev_page' ) );
        }
        
+       /**
+        * Load either the current, or a specified, revision
+        * that's attached to a given page. If not attached
+        * to that page, will return null.
+        *
+        * @param Database $db
+        * @param Title $title
+        * @param int $id
+        * @return Revision
+        * @access public
+        */
+       function &loadFromTitle( &$db, $title, $id = 0 ) {
+               if( $id ) {
+                       $matchId = IntVal( $id );
+               } else {
+                       $matchId = 'page_latest';
+               }
+               return Revision::loadFromConds(
+                       $db,
+                       array( "rev_id=$matchId",
+                              'page_id=rev_page',
+                              'page_namespace' => $title->getNamespace(),
+                              'page_title'     => $title->getDbkey() ) );
+       }
+       
        /**
         * Load the revision for the given title with the given timestamp.
         * WARNING: Timestamps may in some circumstances not be unique,