private static function findMovedNodes($aoDiffs, $aoRootDiffs = false) { //AnwDebug::logdetail(" ------ findMovedNodes ------ "); if (!$aoRootDiffs) { $aoRootDiffs = $aoDiffs; } //find moved nodes = deletion + addition with the same nodeName and nodeValue //2 passes are necessary, otherwise we could get sub-level movednodes included in main-level movednodes... //first pass $aoNewDiffs = array(); $nCountDiffs = count($aoDiffs); for ($i = 0; $i < $nCountDiffs; $i++) { $oDiff = $aoDiffs[$i]; //don't move blank lines... just delete it and add it again. avoids lots of problems. if ($oDiff->getDiffType() == AnwDiff::TYPE_ADDED && !AnwXml::xmlIsEmptyNode($oDiff->getNode())) { //AnwDebug::logdetail("findMovedNodesStep:".htmlentities(AnwUtils::xmlDumpNode($oDiff->getNode()))); //important : don't move nodes into untranslatable parent nodes ! (testApplyDiffsMoved20) if (AnwXml::xmlIsTranslatableParent($oDiff->getNode())) { $oDiffDeleted = self::findMovedNodes_findDeleted($aoRootDiffs, $oDiff); if ($oDiffDeleted) { //AnwDebug::logdetail(" * MOVED NODE FOUND : ".htmlentities(AnwUtils::xmlDumpNode($oDiff->getNode()))." <-- ".htmlentities(AnwUtils::xmlDumpNode($oDiffDeleted->getNode()))." ---parentDeleted---".htmlentities(AnwUtils::xmlDumpNode($oDiffDeleted->getNode()->parentNode))); // warning, here there is 2 possible cases: // 1. Nodes are 100% equals // 2. Values are not equals, but values are the same but have a different textLayout. // We do the test here, for better performances, so we don't test it more than 1 time even when applying diffs to several documents $oDiffMoved = new AnwDiffMoved(); // did the textlayout changed? $sNewNodeValue = $oDiff->getNode()->nodeValue; if ($oDiffDeleted->getNode()->nodeValue != $sNewNodeValue) { // mark the textlayout changed (ie: "\n" added/removed before/after text value), so that we will apply the new textlayout when applying the diffs later $oDiffMoved->setTextLayoutReferenceValue($sNewNodeValue); } else { // textlayout didn't change, the moved nodes are 100% the same } if ($oDiff->getDiffAddedParent()) { //$oDiff->getNode()->set = "***moved-node-from-added***"; //AnwDebug::logdetail("findMovedNodes : !special !!! moved node from SubAdded"); $oOldDiffSubAdded = $oDiff; $oDiffDeleted->setMovedDiff($oDiffMoved); $oOldDiffSubAdded->replaceBy($oDiffMoved); //notify ancestors from change } else { //replace AnwDiffAdded by AnwDiffMoved $oDiffDeleted->setMovedDiff($oDiffMoved); } $oDiff = $oDiffMoved; } /* else { //this DiffAdded has no move found. continue search into its subdiffsadded if ($oDiff->hasSubAddedDiffs()) { AnwDebug::log("findMovedNodes : subAddedDiffs --->"); $aoSubAddedDiffs = $oDiff->getSubAddedDiffs(); $aoSubAddedDiffs = self::findMovedNodes($aoSubAddedDiffs, $aoRootDiffs, true); AnwDebug::log("findMovedNodes : subAddedDiffs <---"); } }*/ } } /*else if ($oDiff->getDiffType() == AnwDiff::TYPE_DIFFS) { //continue into sub diffs AnwDebug::log("findMovedNodes : diffs --->"); $aoSubDiffs = self::findMovedNodes($oDiff->getAllDiffs(), $aoRootDiffs); AnwDebug::log("findMovedNodes : diffs <---"); $oDiff->setDiffs($aoSubDiffs); }*/ $aoNewDiffs[] = $oDiff; } //second pass $aoNewDiffs2 = array(); $nCountDiffs = count($aoNewDiffs); for ($i = 0; $i < $nCountDiffs; $i++) { $oDiff = $aoNewDiffs[$i]; if ($oDiff->getDiffType() == AnwDiff::TYPE_DIFFS) { //continue into sub diffs //AnwDebug::logdetail("findMovedNodes : diffs --->"); $aoSubDiffs = self::findMovedNodes($oDiff->getAllDiffs(), $aoRootDiffs); //AnwDebug::logdetail("findMovedNodes : diffs <---"); $oDiff->setDiffs($aoSubDiffs); } else { if ($oDiff->getDiffType() == AnwDiff::TYPE_ADDED) { if (AnwXml::xmlIsTranslatableParent($oDiff->getNode())) { //continue search into its subdiffsadded if ($oDiff->hasSubAddedDiffs()) { //AnwDebug::logdetail("findMovedNodes : subAddedDiffs --->"); $aoSubAddedDiffs = $oDiff->getSubAddedDiffs(); $aoSubAddedDiffs = self::findMovedNodes($aoSubAddedDiffs, $aoRootDiffs); //AnwDebug::logdetail("findMovedNodes : subAddedDiffs <---"); } } } } $aoNewDiffs2[] = $oDiff; } return $aoNewDiffs2; }
static function runCallbacksOnTranslatableValue($oInstance, $oRootNode, $sFieldInput, $fOnTextValue, $fBeforeChilds = null, $fAfterChilds = null, $fOnUntranslatableNode = null, $bFirstCall = true) { static $j = 0; if ($bFirstCall) { $j = 0; } //reset if (AnwXml::xmlIsTranslatableParent($oRootNode)) { if (AnwXml::xmlIsTextNode($oRootNode)) { if (!AnwXml::xmlIsEmptyNode($oRootNode)) { if ($fOnTextValue) { $oInstance->{$fOnTextValue}($oRootNode, $sFieldInput); } } } else { if (AnwXml::xmlIsCommentNode($oRootNode)) { } else { if (AnwXml::xmlIsPhpNode($oRootNode)) { //do nothing } else { if ($fBeforeChilds && !AnwXml::xmlIsRootNode($oRootNode)) { $oInstance->{$fBeforeChilds}($oRootNode); } $oChildNodes = $oRootNode->childNodes; if ($oChildNodes) { //WARNING - don't use foreach here ! bug on some servers, as childs are getting modified... for ($i = 0; $i < $oChildNodes->length; $i++) { $oChild = $oChildNodes->item($i); $sFieldInputNew = self::runCallbacks_getInputName($sFieldInput, $j, '-'); self::runCallbacksOnTranslatableValue($oInstance, $oChild, $sFieldInputNew, $fOnTextValue, $fBeforeChilds, $fAfterChilds, $fOnUntranslatableNode, false); //recursive $j++; } } if ($fAfterChilds && !AnwXml::xmlIsRootNode($oRootNode)) { $oInstance->{$fAfterChilds}($oRootNode); } } } } } else { if ($fOnUntranslatableNode) { $oInstance->{$fOnUntranslatableNode}($oRootNode); } } }