1<?php 2 3namespace dokuwiki\plugin\farmsync\meta; 4 5 6class PageUpdates extends EntityUpdates { 7 8 public function updateEntity($page, $source, $target) { 9 $result = new UpdateResults($page, $target); 10 $sourceModTime = $this->farm_util->getRemoteFilemtime($source, $page); 11 $sourceText = $this->farm_util->readRemotePage($source, $page); 12 13 if (!$this->farm_util->remotePageExists($target, $page)) { 14 $this->farm_util->saveRemotePage($target, $page, $sourceText, $sourceModTime); 15 $result->setMergeResult('new file'); 16 $this->results[$target]['passed'][] = $result; 17 return; 18 } 19 $targetModTime = $this->farm_util->getRemoteFilemtime($target, $page); 20 $targetText = $this->farm_util->readRemotePage($target, $page); 21 if ($targetModTime == $sourceModTime && $targetText == $sourceText) { 22 $result->setMergeResult('unchanged'); 23 $this->results[$target]['passed'][] = $result; 24 return; 25 } 26 27 $sourceArchiveText = $this->farm_util->readRemotePage($source, $page, null, $targetModTime); 28 if ($targetModTime < $sourceModTime && $sourceArchiveText == $targetText) { 29 $this->farm_util->saveRemotePage($target, $page, $sourceText, $sourceModTime); 30 $result->setMergeResult('file overwritten'); 31 $this->results[$target]['passed'][] = $result; 32 return; 33 } 34 35 // We have to merge 36 $commonroot = $this->farm_util->findCommonAncestor($page, $source, $target); 37 $diff3 = new \Diff3(explode("\n", $commonroot), explode("\n", $targetText), explode("\n", $sourceText)); 38 39 // prepare labels 40 $label1 = '✎————————————————— ' . $this->getLang('merge_animal') . ' ————'; 41 $label3 = '✏————————————————— ' . $this->getLang('merge_source') . ' ————'; 42 $label2 = '✐————————————————————————————————————'; 43 $final = join("\n", $diff3->mergedOutput($label1, $label2, $label3)); 44 if ($final == $targetText) { 45 $result->setMergeResult('unchanged'); 46 $this->results[$target]['passed'][] = $result; 47 return; 48 } 49 if (!$diff3->_conflictingBlocks) { 50 $this->farm_util->saveRemotePage($target, $page, $final); 51 $result->setFinalText($final); 52 $result->setMergeResult('merged without conflicts'); 53 $this->results[$target]['passed'][] = $result; 54 return; 55 } 56 $result = new PageConflict($page, $target); 57 $result->setMergeResult('merged with conflicts'); 58 $result->setConflictingBlocks($diff3->_conflictingBlocks); 59 $result->setFinalText($final); 60 $this->results[$target]['failed'][] = $result; 61 return; 62 } 63 64 protected function preProcessEntities($pagelines) { 65 $pages = array(); 66 foreach ($pagelines as $line) { 67 $pages = array_merge($pages, $this->getDocumentsFromLine($this->source, $line)); 68 } 69 array_unique($pages); 70 return $pages; 71 } 72 73 74 function printProgressLine($target, $i, $total) { 75 echo sprintf($this->getLang('progress:pages'), $target, $i, $total) . "</br>"; 76 } 77 78 protected function printResultHeading() { 79 echo "<h3>".$this->getLang('heading:pages')."</h3>"; 80 } 81 82 /** 83 * @param string $source 84 * @param string $line 85 * 86 * @return \string[] 87 * 88 */ 89 public function getDocumentsFromLine($source, $line) { 90 if (trim($line) == '') return array(); 91 $cleanline = str_replace('/', ':', $line); 92 $namespace = join(':', explode(':', $cleanline, -1)); 93 $documentdir = dirname($this->farm_util->getRemoteFilename($source, $cleanline, null, false)); 94 $search_algo = 'search_allpages'; 95 $documents = array(); 96 97 if (substr($cleanline, -3) == ':**') { 98 $nsfiles = array(); 99 search($nsfiles, $documentdir, $search_algo, array()); 100 $documents = array_map(function ($elem) use ($namespace) { 101 return $namespace . ':' . $elem['id']; 102 }, $nsfiles); 103 } elseif (substr($cleanline, -2) == ':*') { 104 $nsfiles = array(); 105 search($nsfiles, $documentdir, $search_algo, array('depth' => 1)); 106 $documents = array_map(function ($elem) use ($namespace) { 107 return $namespace . ':' . $elem['id']; 108 }, $nsfiles); 109 } else { 110 $document = $cleanline; 111 if (substr(noNS($document), 0, 1) == '_') return array(); 112 if (in_array(substr($document, -1), array(':', ';'))) { 113 $document = $this->handleStartpage($source, $document); 114 } 115 if (!$this->farm_util->remotePageExists($source, $document)) { 116 msg("Page $document does not exist in source wiki!", -1); 117 return array(); 118 } 119 $documents[] = cleanID($document); 120 } 121 122 return $documents; 123 } 124} 125