protected function getUndoContent($startContent, $stopContent, $currentContent)
 {
     if ($currentContent === $stopContent) {
         return $startContent;
     } else {
         // 3-way merge
         $ok = wfMerge($stopContent, $startContent, $currentContent, $result);
         if ($ok) {
             return $result;
         } else {
             return false;
         }
     }
 }
 /**
  * Attempts to merge differences between three versions. Returns a new
  * Content object for a clean merge and false for failure or a conflict.
  *
  * All three Content objects passed as parameters must have the same
  * content model.
  *
  * This text-based implementation uses wfMerge().
  *
  * @param Content $oldContent The page's previous content.
  * @param Content $myContent One of the page's conflicting contents.
  * @param Content $yourContent One of the page's conflicting contents.
  *
  * @return Content|bool
  */
 public function merge3(Content $oldContent, Content $myContent, Content $yourContent)
 {
     $this->checkModelID($oldContent->getModel());
     $this->checkModelID($myContent->getModel());
     $this->checkModelID($yourContent->getModel());
     $format = $this->getDefaultFormat();
     $old = $this->serializeContent($oldContent, $format);
     $mine = $this->serializeContent($myContent, $format);
     $yours = $this->serializeContent($yourContent, $format);
     $ok = wfMerge($old, $mine, $yours, $result);
     if (!$ok) {
         return false;
     }
     if (!$result) {
         return $this->makeEmptyContent();
     }
     $mergedContent = $this->unserializeContent($result, $format);
     return $mergedContent;
 }
示例#3
0
 /**
  * @access private
  * @todo document
  */
 function mergeChangesInto(&$editText)
 {
     $fname = 'EditPage::mergeChangesInto';
     wfProfileIn($fname);
     $db =& wfGetDB(DB_MASTER);
     // This is the revision the editor started from
     $baseRevision = Revision::loadFromTimestamp($db, $this->mArticle->mTitle, $this->edittime);
     if (is_null($baseRevision)) {
         wfProfileOut($fname);
         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)) {
         wfProfileOut($fname);
         return false;
     }
     $currentText = $currentRevision->getText();
     if (wfMerge($baseText, $editText, $currentText, $result)) {
         $editText = $result;
         wfProfileOut($fname);
         return true;
     } else {
         wfProfileOut($fname);
         return false;
     }
 }
示例#4
0
 /**
  * @param string $old Text as it was in the database
  * @param string $mine Text submitted while user was editing
  * @param string $yours Text submitted by the user
  * @param bool $expectedMergeResult Whether the merge should be a success
  * @param string $expectedText Text after merge has been completed
  *
  * @dataProvider provideMerge()
  * @group medium
  * @covers ::wfMerge
  */
 public function testMerge($old, $mine, $yours, $expectedMergeResult, $expectedText)
 {
     $this->checkHasDiff3();
     $mergedText = null;
     $isMerged = wfMerge($old, $mine, $yours, $mergedText);
     $msg = 'Merge should be a ';
     $msg .= $expectedMergeResult ? 'success' : 'failure';
     $this->assertEquals($expectedMergeResult, $isMerged, $msg);
     if ($isMerged) {
         // Verify the merged text
         $this->assertEquals($expectedText, $mergedText, 'is merged text as expected?');
     }
 }
示例#5
0
 /**
  * Get the text that needs to be saved in order to undo all revisions
  * between $undo and $undoafter. Revisions must belong to the same page,
  * must exist and must not be deleted
  * @param $undo Revision
  * @param $undoafter Revision Must be an earlier revision than $undo
  * @return mixed string on success, false on failure
  */
 public function getUndoText(Revision $undo, Revision $undoafter = null)
 {
     $currentRev = Revision::newFromTitle($this->mTitle);
     if (!$currentRev) {
         return false;
         // no page
     }
     $undo_text = $undo->getText();
     $undoafter_text = $undoafter->getText();
     $cur_text = $currentRev->getText();
     if ($cur_text == $undo_text) {
         # No use doing a merge if it's just a straight revert.
         return $undoafter_text;
     }
     $undone_text = '';
     if (!wfMerge($undo_text, $undoafter_text, $cur_text, $undone_text)) {
         return false;
     }
     return $undone_text;
 }
示例#6
0
 /**
  * @private
  * @todo document
  *
  * @parma $editText string
  *
  * @return bool
  */
 function mergeChangesInto(&$editText)
 {
     wfProfileIn(__METHOD__);
     $db = wfGetDB(DB_MASTER);
     // This is the revision the editor started from
     $baseRevision = $this->getBaseRevision();
     if (is_null($baseRevision)) {
         wfProfileOut(__METHOD__);
         return false;
     }
     $baseText = $baseRevision->getText();
     // The current state, we want to merge updates into it
     $currentRevision = Revision::loadFromTitle($db, $this->mTitle);
     if (is_null($currentRevision)) {
         wfProfileOut(__METHOD__);
         return false;
     }
     $currentText = $currentRevision->getText();
     $result = '';
     if (wfMerge($baseText, $editText, $currentText, $result)) {
         $editText = $result;
         wfProfileOut(__METHOD__);
         return true;
     } else {
         wfProfileOut(__METHOD__);
         return false;
     }
 }
示例#7
0
 /**
  * Get the text that needs to be saved in order to undo all revisions
  * between $undo and $undoafter. Revisions must belong to the same page,
  * must exist and must not be deleted
  * @param $undo Revision
  * @param $undoafter Revision Must be an earlier revision than $undo
  * @return mixed string on success, false on failure
  */
 public function getUndoText(Revision $undo, Revision $undoafter = null)
 {
     $cur_text = $this->getRawText();
     if ($cur_text === false) {
         return false;
         // no page
     }
     $undo_text = $undo->getText();
     $undoafter_text = $undoafter->getText();
     if ($cur_text == $undo_text) {
         # No use doing a merge if it's just a straight revert.
         return $undoafter_text;
     }
     $undone_text = '';
     if (!wfMerge($undo_text, $undoafter_text, $cur_text, $undone_text)) {
         return false;
     }
     return $undone_text;
 }
 /**
  * @desc Saving CSS content
  * If there is more recent edit it will try to merge text and save.
  * Returns false when conflict is found and cannot be resolved
  *
  * @param string $content
  * @param string $summary
  * @param bool $isMinor
  * @param int $editTime timestamp
  * @param User $user
  * @return Status|bool
  */
 public function saveCssFileContent($content, $summary, $isMinor, $editTime, $user)
 {
     $cssTitle = $this->getCssFileTitle();
     $flags = 0;
     if ($cssTitle instanceof Title) {
         $aid = $cssTitle->getArticleID(Title::GAID_FOR_UPDATE);
         $flags |= $aid == 0 ? EDIT_NEW : EDIT_UPDATE;
         if ($isMinor) {
             $flags |= EDIT_MINOR;
         }
         $db = wfGetDB(DB_MASTER);
         $currentRevision = Revision::loadFromTitle($db, $cssTitle);
         // we handle both - edit and creation conflicts below
         if (!empty($currentRevision) && $editTime != $currentRevision->getTimestamp()) {
             $result = '';
             $currentText = $currentRevision->getText();
             if (!$editTime) {
                 // the css did not exist when the editor was started, so the base revision for
                 // parallel edits is an empty file
                 $baseText = '';
             } else {
                 $baseText = Revision::loadFromTimestamp($db, $this->getCssFileTitle(), $editTime)->getText();
             }
             // remove windows endlines from input before merging texts
             $content = str_replace("\r", "", $content);
             if (wfMerge($baseText, $content, $currentText, $result)) {
                 // This conflict can be resolved
                 $content = $result;
             } else {
                 // We have real conflict here
                 return false;
             }
         }
         $page = new WikiPage($cssTitle);
         $status = $page->doEdit($content, $summary, $flags, false, $user);
         return $status;
     }
     return Status::newFatal('special-css-saving-internal-error');
 }