/**
  * @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();
    }
}