From: Brion Vibber Date: Tue, 28 Jun 2005 23:19:56 +0000 (+0000) Subject: * (bug 2572) Fix edit conflict handling X-Git-Tag: 1.5.0beta2~144 X-Git-Url: http://git.cyclocoop.org/%22.%24h.%22?a=commitdiff_plain;h=0226b12c83d80a6e042ab6515628f642abe0a16e;p=lhc%2Fweb%2Fwiklou.git * (bug 2572) Fix edit conflict handling --- diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 560980905f..0e07b1a310 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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 === diff --git a/includes/Article.php b/includes/Article.php index cd22c09cdb..fdefb53db4 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -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'; diff --git a/includes/EditPage.php b/includes/EditPage.php index 1291a4c59e..f1594707ad 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -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; diff --git a/includes/Revision.php b/includes/Revision.php index 7c74bd0cc1..1905a269f9 100644 --- a/includes/Revision.php +++ b/includes/Revision.php @@ -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,