public function generate($oldText, $newText) { $patch = parent::generate($oldText, $newText); $opList = array(); foreach ($patch as $op) { if ($op instanceof LogootIns) { $opList[] = LogootPlusIns::plus($op); } elseif ($op instanceof LogootDel) { $opList[] = LogootPlusDel::plus($op); } } $p = new LogootPatch($patch->getId(), $opList); $p->applied(); return $p; }
/** * @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; }
public function run() { global $wgServerName, $wgScriptPath, $wgServer, $wgScriptExtension; wfProfileIn('DSMWUpdateJob::run()'); $urlServer = 'http://' . $wgServerName; $revids = array(); $revids1 = array(); $page_ids = array(); // Getting all the revision ids of pages having been logootized $db = wfGetDB(DB_SLAVE); $model_table = $db->tableName('model'); $sql = "SELECT `rev_id` FROM {$model_table}"; $res = $db->query($sql); while ($row = $db->fetchObject($res)) { $revids[] = $row->rev_id; } $db->freeResult($res); // if (count($revids)==0) $revids=array(); // Getting all the revision ids without the pages in the DSMW namespaces and // Administration_pull_site_addition and Administration_pull_site_addition pages $rev_table = $db->tableName('revision'); $page_table = $db->tableName('page'); $sql = "SELECT {$rev_table}.`rev_id` FROM {$rev_table}, {$page_table} WHERE\n `rev_page`=`page_id` and `page_namespace`!= 110 and `page_namespace`!= 200\n and `page_namespace`!= 210 and `page_namespace`!= 220\nand `page_title`!= \"Administration_pull_site_addition\"\nand `page_title` != \"Administration_push_site_addition\""; $res1 = $db->query($sql); while ($row = $db->fetchObject($res1)) { $revids1[] = $row->rev_id; } $db->freeResult($res1); // if (count($revids1)==0) $revids1=array(); // Array_diff returns an array containing all the entries from $revids1 that are // not present in $revids. $diff = array_diff($revids1, $revids); // get page ids of these revisions (each id must be unique in the array) foreach ($diff as $id) { $page_id = $db->selectField('revision', 'rev_page', array('rev_id' => $id)); $page_ids[] = $page_id; } $page_ids = array_unique($page_ids); sort($page_ids); // Now we can logootize: if (count($page_ids) != 0) { foreach ($page_ids as $pageid) { $title = Title::newFromID($pageid); $ns = $title->getNamespace(); $lastRev = Revision::loadFromPageId($db, $pageid); $pageText = $lastRev->getText(); // load an empty model $model = DSMWRevisionManager::loadModel(0); $logoot = new logootEngine($model); $listOp = $logoot->generate("", $pageText); $modelAfterIntegrate = $logoot->getModel(); $tmp = serialize($listOp); $patchid = sha1($tmp); if ($ns == NS_FILE || $ns == NS_IMAGE || $ns == NS_MEDIA) { $apiUrl = $wgServer . $wgScriptPath . "/api" . $wgScriptExtension; $onPage = str_replace(array(' '), array('%20'), $lastRev->getTitle()->getText()); $download = $apiUrl . "?action=query&titles=File:" . $onPage . "&prop=imageinfo&format=php&iiprop=mime|url|size"; $resp = Http::get($download); $resp = unserialize($resp); $a = $resp['query']['pages']; $a = current($a); $a = $a['imageinfo']; $a = current($a); $mime = $a['mime']; $size = $a['size']; $url = $a['url']; $patch = new DSMWPatch(false, true, null, $urlServer . $wgScriptPath, 0, null, null, null, $mime, $size, $url, null); $patch->storePage('File:' . $lastRev->getTitle()->getText(), $lastRev->getId()); } else { $patch = new DSMWPatch(false, false, $listOp, $urlServer, 0); $patch->storePage($lastRev->getTitle()->getText(), $lastRev->getId()); } DSMWRevisionManager::storeModel($lastRev->getId(), $sessionId = session_id(), $modelAfterIntegrate, $blobCB = 0); } } wfProfileOut('DSMWUpdateJob::run()'); return true; }
function testManyInsDel() { $model = manager::loadModel(0); $logoot = new logootEngine($model); $oldContent = ""; for ($i = 0; $i < 500; $i++) { // 500 inserts / 499 deletion // insert X $newContent = $i; $listOp1 = $logoot->generate($oldContent, $newContent); if ($i == 0) { $this->assertEquals(1, count($listOp1)); } else { $this->assertEquals(2, count($listOp1)); } $oldContent = $newContent; } $modelAssert = $logoot->getModel(); $this->assertEquals(1, count($modelAssert->getPositionlist())); }
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())); }
/** *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(); } }