/** * @since 1.1 * * @param EditPage $editpage * * @return true */ public function onAttemptSave(EditPage $editpage) { global $wgServerName, $wgScriptPath; $urlServer = 'http://' . $wgServerName . $wgScriptPath; $ns = $editpage->mTitle->getNamespace(); if ($ns == PATCH || $ns == PUSHFEED || $ns == PULLFEED || $ns == CHANGESET) { return true; } $actualtext = $editpage->textbox1; // V2 $dbr = wfGetDB(DB_SLAVE); $lastRevision = Revision::loadFromTitle($dbr, $editpage->mTitle); if (is_null($lastRevision)) { $conctext = ""; $rev_id = 0; } elseif (($ns == NS_FILE || $ns == NS_IMAGE || $ns == NS_MEDIA) && $lastRevision->getRawText() == "") { $rev_id = 0; $conctext = $lastRevision->getText(); } else { $conctext = $lastRevision->getText(); // V1 conc $rev_id = $lastRevision->getId(); } // if there is no modification on the text if ($actualtext == $conctext) { return true; } $model = DSMWRevisionManager::loadModel($rev_id); $logoot = new logootEngine($model); // get the revision with the edittime==>V0 $rev = Revision::loadFromTimestamp($dbr, $editpage->mTitle, $editpage->edittime); if (is_null($rev)) { $text = ""; $rev_id1 = 0; } else { $text = $rev->getText(); // VO $rev_id1 = $rev->getId(); } if ($conctext != $text) { // if last revision is not V0, there is editing conflict $model1 = DSMWRevisionManager::loadModel($rev_id1); $logoot1 = new logootEngine($model1); $listOp1 = $logoot1->generate($text, $actualtext); // creation Patch P2 $tmp = serialize($listOp1); $patch = new DSMWPatch(false, false, $listOp1, $urlServer, $rev_id1); if ($editpage->mTitle->getNamespace() == 0) { $title = $editpage->mTitle->getText(); } else { $title = $editpage->mTitle->getNsText() . ':' . $editpage->mTitle->getText(); } // integration: diffs between VO and V2 into V1 $modelAfterIntegrate = $logoot->integrate($listOp1); } else { // no edition conflict $listOp = $logoot->generate($conctext, $actualtext); $modelAfterIntegrate = $logoot->getModel(); $tmp = serialize($listOp); $patch = new DSMWPatch(false, false, $listOp, $urlServer, $rev_id1); if ($editpage->mTitle->getNamespace() == 0) { $title = $editpage->mTitle->getText(); } else { $title = $editpage->mTitle->getNsText() . ':' . $editpage->mTitle->getText(); } } $revId = utils::getNewArticleRevId(); wfDebugLog('p2p', ' -> store model rev : ' . $revId . ' session ' . session_id() . ' model ' . $modelAfterIntegrate->getText()); DSMWRevisionManager::storeModel($revId + 1, $sessionId = session_id(), $modelAfterIntegrate, $blobCB = 0); $patch->storePage($title, $revId + 1); // stores the patch in a wikipage $editpage->textbox1 = $modelAfterIntegrate->getText(); return true; }
function testConcDelOpIntegration() { $oldtext = ""; $conctext = "line1\nline2\nline3\nline4"; $model = manager::loadModel(0); $logoot = new logootEngine($model); $listOp = $logoot->generate($oldtext, $conctext); // $model has 4 lines created by 4 ins operations $tmpMod = $logoot->getModel(); $this->assertEquals(4, count($tmpMod->getPositionlist())); $this->assertEquals(4, count($tmpMod->getLinelist())); $oldtext = "line1\nline2\nline3\nline4"; $actualtext = "line1\nline2\nline4"; $listOp1 = $logoot->generate($oldtext, $actualtext); $tmpMod = $logoot->getModel(); $this->assertEquals(3, count($tmpMod->getPositionlist())); $this->assertEquals(3, count($tmpMod->getLinelist())); $modelAssert = $logoot->integrate($listOp1); $this->assertEquals(3, count($modelAssert->getPositionlist())); $this->assertEquals(3, count($modelAssert->getLinelist())); }
function testInsertDelete() { $model = manager::loadModel(0); $logoot = new logootEngine($model); // insert Y $oldContent = ""; $newContent = "Y"; $listOp1 = $logoot->generate($oldContent, $newContent); // insert X below Y $oldContent = "Y"; $newContent = "X\nY"; $listOp2 = $logoot->generate($oldContent, $newContent); // delete X $oldContent = "X\nY"; $newContent = "Y"; $listOp3 = $logoot->generate($oldContent, $newContent); $modelAssert = $logoot->getModel(); // model1 is another page model where we execute the 3 inserts in another order $model1 = manager::loadModel(0); $logoot1 = new logootEngine($model1); $logoot1->integrate($listOp1); $logoot1->integrate($listOp2); $modelAssert1 = $logoot1->integrate($listOp3); $this->assertEquals($modelAssert->getPositionlist(), $modelAssert1->getPositionlist()); $this->assertEquals($modelAssert->getLinelist(), $modelAssert1->getLinelist()); unset($logoot1); unset($model1); // model1 is another page model where we execute the 3 inserts in another order $model1 = manager::loadModel(0); $logoot1 = new logootEngine($model1); $modelAssert1 = $logoot1->integrate($listOp2); $modelAssert1 = $logoot1->integrate($listOp1); $modelAssert1 = $logoot1->integrate($listOp3); $this->assertEquals($modelAssert->getPositionlist(), $modelAssert1->getPositionlist()); $this->assertEquals($modelAssert->getLinelist(), $modelAssert1->getLinelist()); unset($logoot1); unset($model1); }
/** *Integrates the operation(LogootOp) into the article via the logoot algorithm * * @param <Object> $operation * @param <String or Object> $article */ function logootIntegrate($operations, $article) { global $wgCanonicalNamespaceNames; $indexNS = 0; wfDebugLog('p2p', ' - function logootIntegrate : ' . $article); $dbr = wfGetDB(DB_SLAVE); if (is_string($article)) { // if there is a space in the title, repalce by '_' $article = str_replace(" ", "_", $article); if (strpos($article, ":") === false) { $pageid = $dbr->selectField('page', 'page_id', array('page_title' => $article)); } else { // if there is a namespace preg_match("/^(.+?)_*:_*(.*)\$/S", $article, $tmp); $articleWithoutNS = $tmp[2]; $NS = $tmp[1]; if (in_array($NS, $wgCanonicalNamespaceNames)) { foreach ($wgCanonicalNamespaceNames as $key => $value) { if ($NS == $value) { $indexNS = $key; } } } $pageid = $dbr->selectField('page', 'page_id', array('page_title' => $articleWithoutNS, 'page_namespace' => $indexNS)); } // get the page namespace $pageNameSpace = $dbr->selectField('page', 'page_namespace', array('page_id' => $pageid)); /*the ns must not be a pullfeed, pushfeed, changeset or patch namespace. If the page name is the same in different ns we can get the wrong * page id */ if ($pageNameSpace == PULLFEED || $pageNameSpace == PUSHFEED || $pageNameSpace == PATCH || $pageNameSpace == CHANGESET) { $pageid = 0; } $lastRev = Revision::loadFromPageId($dbr, $pageid); if (is_null($lastRev)) { $rev_id = 0; } else { $rev_id = $lastRev->getId(); } wfDebugLog('p2p', ' -> pageId : ' . $pageid); wfDebugLog('p2p', ' -> rev_id : ' . $rev_id); $title = Title::newFromText($article); $article = new Article($title); } else { $rev_id = $article->getRevIdFetched(); } $listOp = array(); // $blobInfo = BlobInfo::loadBlobInfo($rev_id); $model = DSMWRevisionManager::loadModel($rev_id); if ($model instanceof boModel == false) { throw new MWException(__METHOD__ . ': model loading problem!'); } $logoot = new logootEngine($model); foreach ($operations as $operation) { wfDebugLog('p2p', ' - operation : ' . $operation); wfDebugLog('testlog', ' - operation : ' . $operation); $operation = operationToLogootOp($operation); if ($operation != false && is_object($operation)) { $listOp[] = $operation; wfDebugLog('testlog', ' -> Operation: ' . $operation->getLogootPosition()->toString()); // $blobInfo->integrateBlob($operation); } // end if // else { // throw new MWException( __METHOD__.': operation problem '.$operation ); // wfDebugLog('p2p',' - operation problem : '.$operation); // } } // end foreach operations $modelAfterIntegrate = $logoot->integrate($listOp); // $revId = utils::getNewArticleRevId(); $status = $article->doEdit($modelAfterIntegrate->getText(), $summary = ""); $revId = $status->value['revision']->getId(); DSMWRevisionManager::storeModel($revId, $sessionId = session_id(), $modelAfterIntegrate, $blobCB = 0); return $revId; // sleep(4); if (is_bool($status)) { return $status; } else { return $status->isGood(); } }