1<?php 2 3namespace dokuwiki\Ui; 4 5/** 6 * DokuWiki Diff Interface 7 * parent class of PageDiff and MediaDiff 8 * 9 * @package dokuwiki\Ui 10 */ 11abstract class Diff extends Ui 12{ 13 /* @var string */ 14 protected $id; // page id or media id 15 protected $item; // page or media 16 17 /* @var int */ 18 protected $old_rev; // older revision, timestamp of left side 19 protected $new_rev; // newer revision, timestamp of right side 20 protected $last_rev; // current revision, or last revision when it had removed 21 22 /* @var array */ 23 protected $preference = []; 24 25 /* @var ChangeLog */ 26 protected $changelog; // PageChangeLog or MediaChangeLog object 27 28 /** 29 * Diff Ui constructor 30 * 31 * @param string $id page id or media id 32 */ 33 public function __construct($id) 34 { 35 $this->id = $id; 36 $this->setChangeLog(); 37 } 38 39 /** 40 * set class property changelog 41 */ 42 abstract protected function setChangeLog(); 43 44 /** 45 * Set a pair of revisions to be compared 46 * 47 * @param int $old_rev 48 * @param int $new_rev 49 * @return $this 50 */ 51 public function compare($old_rev, $new_rev) 52 { 53 $this->old_rev = $old_rev; 54 $this->new_rev = $new_rev; 55 return $this; 56 } 57 58 /** 59 * Gets or Sets preference of the Ui\Diff object 60 * 61 * @param string|array $prefs a key name or key-value pair(s) 62 * @param mixed $value value used when the first args is string 63 * @return array|$this 64 */ 65 public function preference($prefs = null, $value = null) 66 { 67 // set 68 if (is_string($prefs) && isset($value)) { 69 $this->preference[$prefs] = $value; 70 return $this; 71 } elseif (is_array($prefs)) { 72 foreach ($prefs as $name => $value) { 73 $this->preference[$name] = $value; 74 } 75 return $this; 76 } 77 // get 78 return $this->preference; 79 } 80 81 /** 82 * Retrieve requested revision(s) and difftype from Ui\Revisions 83 * 84 * @return void 85 */ 86 protected function preProcess() 87 { 88 global $INPUT; 89 90 // difflink icon click, eg. ?rev=123456789&do=diff 91 if ($INPUT->has('rev')) { 92 $this->old_rev = $INPUT->int('rev'); 93 $this->new_rev = ''; // current revision 94 } 95 96 // submit button with two checked boxes 97 $rev2 = $INPUT->arr('rev2', []); 98 if (count($rev2) > 1) { 99 if ($rev2[0] == 'current') { 100 [$this->old_rev, $this->new_rev] = [$rev2[1], '']; 101 } elseif ($rev2[1] == 'current') { 102 [$this->old_rev, $this->new_rev] = [$rev2[0], '']; 103 } elseif ($rev2[0] < $rev2[1]) { 104 [$this->old_rev, $this->new_rev] = [$rev2[0], $rev2[1]]; 105 } else { 106 [$this->old_rev, $this->new_rev] = [$rev2[1], $rev2[0]]; 107 } 108 } 109 110 // diff view type 111 if ($INPUT->has('difftype')) { 112 // retrieve requested $difftype 113 $this->preference['difftype'] = $INPUT->str('difftype'); 114 } else { 115 // read preference from DokuWiki cookie. PageDiff only 116 get_doku_pref('difftype', $mode); 117 if (isset($mode)) $this->preference['difftype'] = $mode; 118 } 119 } 120 121 /** 122 * get extended revision info 123 * 124 * @param int|string $rev revision identifier, '' means current one 125 * @return array revision info structure of a page or media file 126 */ 127 protected function getExtendedRevisionInfo($rev) 128 { 129 $changelog =& $this->changelog; 130 131 if ($rev) { 132 $info = $changelog->getRevisionInfo($rev); 133 } elseif (file_exists($filename = $this->itemFN($this->id))) { 134 $rev = filemtime(fullpath($filename)); 135 $info = $changelog->getRevisionInfo($rev) + array( 136 'current' => true, 137 ); 138 } else { // once exists, but now removed 139 $info = array( 140 'current' => true, 141 ); 142 } 143 return array('item' => $this->item) + $info; 144 } 145 146 147 148 /** 149 * Build header of diff HTML 150 * 151 * @param string $l_rev Left revisions 152 * @param string $r_rev Right revision 153 * @return string[] HTML snippets for diff header 154 * @deprecated 2020-12-31 155 */ 156 public function buildDiffHead($l_rev, $r_rev) 157 { 158 dbg_deprecated('not used see '. \dokuwiki\Ui\PageDiff::class .'::show()'); 159 } 160 161 /** 162 * item url generator 163 * 164 * @param string $id page id or media id 165 * @param string|array $urlParameters URL parameters, associative array recommended 166 * @return string 167 */ 168 protected function itemUrl($id, $urlParameters = '') 169 { 170 switch ($this->item) { 171 case 'page': return wl($id, $urlParameters, $absolute = false, '&'); 172 case 'media': return ml($id, $urlParameters, $direct = true, '&', $absolute = false); 173 } 174 } 175 176 /** 177 * item filename resolver 178 * 179 * @param string $id page id or media id 180 * @param string|int $rev empty string or revision timestamp 181 * @return string 182 */ 183 protected function itemFN($id, $rev = '') 184 { 185 switch ($this->item) { 186 case 'page': return wikiFN($id, $rev); 187 case 'media': return mediaFN($id, $rev); 188 } 189 } 190 191} 192