163ab9afeSSatoshi Sahara<?php 263ab9afeSSatoshi Sahara 363ab9afeSSatoshi Saharanamespace dokuwiki\Ui; 463ab9afeSSatoshi Sahara 563ab9afeSSatoshi Sahara/** 663ab9afeSSatoshi Sahara * DokuWiki Diff Interface 763ab9afeSSatoshi Sahara * parent class of PageDiff and MediaDiff 863ab9afeSSatoshi Sahara * 963ab9afeSSatoshi Sahara * @package dokuwiki\Ui 1063ab9afeSSatoshi Sahara */ 1163ab9afeSSatoshi Saharaabstract class Diff extends Ui 1263ab9afeSSatoshi Sahara{ 13edb50e6aSSatoshi Sahara /* @var string */ 14edb50e6aSSatoshi Sahara protected $id; // page id or media id 15e71e09a6SSatoshi Sahara protected $item; // page or media 16edb50e6aSSatoshi Sahara 17b4b4c5c6SSatoshi Sahara /* @var int */ 18b4b4c5c6SSatoshi Sahara protected $old_rev; // older revision, timestamp of left side 19b4b4c5c6SSatoshi Sahara protected $new_rev; // newer revision, timestamp of right side 200bb448f0SSatoshi Sahara protected $last_rev; // current revision, or last revision when it had removed 21b4b4c5c6SSatoshi Sahara 22edb50e6aSSatoshi Sahara /* @var array */ 23edb50e6aSSatoshi Sahara protected $preference = []; 24edb50e6aSSatoshi Sahara 258068440fSSatoshi Sahara /* @var ChangeLog */ 268068440fSSatoshi Sahara protected $changelog; // PageChangeLog or MediaChangeLog object 278068440fSSatoshi Sahara 28edb50e6aSSatoshi Sahara /** 29edb50e6aSSatoshi Sahara * Diff Ui constructor 30edb50e6aSSatoshi Sahara * 31edb50e6aSSatoshi Sahara * @param string $id page id or media id 32edb50e6aSSatoshi Sahara */ 33edb50e6aSSatoshi Sahara public function __construct($id) 34edb50e6aSSatoshi Sahara { 35edb50e6aSSatoshi Sahara $this->id = $id; 368068440fSSatoshi Sahara $this->setChangeLog(); 37edb50e6aSSatoshi Sahara } 38edb50e6aSSatoshi Sahara 39edb50e6aSSatoshi Sahara /** 408068440fSSatoshi Sahara * set class property changelog 418068440fSSatoshi Sahara */ 428068440fSSatoshi Sahara abstract protected function setChangeLog(); 438068440fSSatoshi Sahara 448068440fSSatoshi Sahara /** 45b4b4c5c6SSatoshi Sahara * Set a pair of revisions to be compared 46b4b4c5c6SSatoshi Sahara * 47b4b4c5c6SSatoshi Sahara * @param int $old_rev 48b4b4c5c6SSatoshi Sahara * @param int $new_rev 49b4b4c5c6SSatoshi Sahara * @return $this 50b4b4c5c6SSatoshi Sahara */ 51b4b4c5c6SSatoshi Sahara public function compare($old_rev, $new_rev) 52b4b4c5c6SSatoshi Sahara { 53b4b4c5c6SSatoshi Sahara $this->old_rev = $old_rev; 54b4b4c5c6SSatoshi Sahara $this->new_rev = $new_rev; 55b4b4c5c6SSatoshi Sahara return $this; 56b4b4c5c6SSatoshi Sahara } 57b4b4c5c6SSatoshi Sahara 58b4b4c5c6SSatoshi Sahara /** 59edb50e6aSSatoshi Sahara * Gets or Sets preference of the Ui\Diff object 60edb50e6aSSatoshi Sahara * 61edb50e6aSSatoshi Sahara * @param string|array $prefs a key name or key-value pair(s) 62edb50e6aSSatoshi Sahara * @param mixed $value value used when the first args is string 63edb50e6aSSatoshi Sahara * @return array|$this 64edb50e6aSSatoshi Sahara */ 65edb50e6aSSatoshi Sahara public function preference($prefs = null, $value = null) 66edb50e6aSSatoshi Sahara { 67edb50e6aSSatoshi Sahara // set 68295564cdSSatoshi Sahara if (is_string($prefs) && isset($value)) { 69295564cdSSatoshi Sahara $this->preference[$prefs] = $value; 70295564cdSSatoshi Sahara return $this; 71295564cdSSatoshi Sahara } elseif (is_array($prefs)) { 72edb50e6aSSatoshi Sahara foreach ($prefs as $name => $value) { 73edb50e6aSSatoshi Sahara $this->preference[$name] = $value; 74edb50e6aSSatoshi Sahara } 75edb50e6aSSatoshi Sahara return $this; 76edb50e6aSSatoshi Sahara } 77edb50e6aSSatoshi Sahara // get 78edb50e6aSSatoshi Sahara return $this->preference; 79edb50e6aSSatoshi Sahara } 80edb50e6aSSatoshi Sahara 81b4b4c5c6SSatoshi Sahara /** 82b4b4c5c6SSatoshi Sahara * Retrieve requested revision(s) and difftype from Ui\Revisions 83b4b4c5c6SSatoshi Sahara * 84b4b4c5c6SSatoshi Sahara * @return void 85b4b4c5c6SSatoshi Sahara */ 86b4b4c5c6SSatoshi Sahara protected function preProcess() 87b4b4c5c6SSatoshi Sahara { 88b4b4c5c6SSatoshi Sahara global $INPUT; 89b4b4c5c6SSatoshi Sahara 90b4b4c5c6SSatoshi Sahara // difflink icon click, eg. ?rev=123456789&do=diff 91b4b4c5c6SSatoshi Sahara if ($INPUT->has('rev')) { 92b4b4c5c6SSatoshi Sahara $this->old_rev = $INPUT->int('rev'); 93b4b4c5c6SSatoshi Sahara $this->new_rev = ''; // current revision 94b4b4c5c6SSatoshi Sahara } 95b4b4c5c6SSatoshi Sahara 96b4b4c5c6SSatoshi Sahara // submit button with two checked boxes 97b4b4c5c6SSatoshi Sahara $rev2 = $INPUT->arr('rev2', []); 98b4b4c5c6SSatoshi Sahara if (count($rev2) > 1) { 99b4b4c5c6SSatoshi Sahara if ($rev2[0] == 'current') { 100b4b4c5c6SSatoshi Sahara [$this->old_rev, $this->new_rev] = [$rev2[1], '']; 101b4b4c5c6SSatoshi Sahara } elseif ($rev2[1] == 'current') { 102b4b4c5c6SSatoshi Sahara [$this->old_rev, $this->new_rev] = [$rev2[0], '']; 103b4b4c5c6SSatoshi Sahara } elseif ($rev2[0] < $rev2[1]) { 104b4b4c5c6SSatoshi Sahara [$this->old_rev, $this->new_rev] = [$rev2[0], $rev2[1]]; 105b4b4c5c6SSatoshi Sahara } else { 106b4b4c5c6SSatoshi Sahara [$this->old_rev, $this->new_rev] = [$rev2[1], $rev2[0]]; 107b4b4c5c6SSatoshi Sahara } 108b4b4c5c6SSatoshi Sahara } 109b4b4c5c6SSatoshi Sahara 110b4b4c5c6SSatoshi Sahara // diff view type 111b4b4c5c6SSatoshi Sahara if ($INPUT->has('difftype')) { 112b4b4c5c6SSatoshi Sahara // retrieve requested $difftype 113b4b4c5c6SSatoshi Sahara $this->preference['difftype'] = $INPUT->str('difftype'); 114b4b4c5c6SSatoshi Sahara } else { 115b4b4c5c6SSatoshi Sahara // read preference from DokuWiki cookie. PageDiff only 11691e70b5fSSatoshi Sahara get_doku_pref('difftype', $mode); 11791e70b5fSSatoshi Sahara if (isset($mode)) $this->preference['difftype'] = $mode; 118b4b4c5c6SSatoshi Sahara } 119b4b4c5c6SSatoshi Sahara } 120b4b4c5c6SSatoshi Sahara 121*179b4660SSatoshi Sahara /** 122*179b4660SSatoshi Sahara * get extended revision info 123*179b4660SSatoshi Sahara * 124*179b4660SSatoshi Sahara * @param int|string $rev revision identifier, '' means current one 125*179b4660SSatoshi Sahara * @return array revision info structure of a page or media file 126*179b4660SSatoshi Sahara */ 127*179b4660SSatoshi Sahara protected function getExtendedRevisionInfo($rev) 128*179b4660SSatoshi Sahara { 129*179b4660SSatoshi Sahara $changelog =& $this->changelog; 130*179b4660SSatoshi Sahara 131*179b4660SSatoshi Sahara if ($rev) { 132*179b4660SSatoshi Sahara $info = $changelog->getRevisionInfo($rev); 133*179b4660SSatoshi Sahara } elseif (file_exists($filename = $this->itemFN($this->id))) { 134*179b4660SSatoshi Sahara $rev = filemtime(fullpath($filename)); 135*179b4660SSatoshi Sahara $info = $changelog->getRevisionInfo($rev) + array( 136*179b4660SSatoshi Sahara 'current' => true, 137*179b4660SSatoshi Sahara ); 138*179b4660SSatoshi Sahara } else { // once exists, but now removed 139*179b4660SSatoshi Sahara $info = array( 140*179b4660SSatoshi Sahara 'current' => true, 141*179b4660SSatoshi Sahara ); 142*179b4660SSatoshi Sahara } 143*179b4660SSatoshi Sahara return array('item' => $this->item) + $info; 144*179b4660SSatoshi Sahara } 145*179b4660SSatoshi Sahara 146b4b4c5c6SSatoshi Sahara 147edb50e6aSSatoshi Sahara 14863ab9afeSSatoshi Sahara /** 149ec019cbfSSatoshi Sahara * Build header of diff HTML 15063ab9afeSSatoshi Sahara * 15163ab9afeSSatoshi Sahara * @param string $l_rev Left revisions 15263ab9afeSSatoshi Sahara * @param string $r_rev Right revision 15363ab9afeSSatoshi Sahara * @return string[] HTML snippets for diff header 15463ab9afeSSatoshi Sahara */ 1558068440fSSatoshi Sahara public function buildDiffHead($l_rev, $r_rev) 15663ab9afeSSatoshi Sahara { 15763ab9afeSSatoshi Sahara global $lang; 158edb50e6aSSatoshi Sahara 159e71e09a6SSatoshi Sahara $changelog =& $this->changelog; 160e71e09a6SSatoshi Sahara 161e71e09a6SSatoshi Sahara switch ($this->item) { 162e71e09a6SSatoshi Sahara case 'page': 1630bb448f0SSatoshi Sahara $isMedia = false; 1640bb448f0SSatoshi Sahara $ui = new PageRevisions($this->id); 165edb50e6aSSatoshi Sahara break; 166e71e09a6SSatoshi Sahara case 'media': 1670bb448f0SSatoshi Sahara $isMedia = true; 1680bb448f0SSatoshi Sahara $ui = new MediaRevisions($this->id); 169edb50e6aSSatoshi Sahara break; 17063ab9afeSSatoshi Sahara } 171edb50e6aSSatoshi Sahara 172edb50e6aSSatoshi Sahara $head_separator = ($this->preference['difftype'] === 'inline') ? ' ' : '<br />'; 1730bb448f0SSatoshi Sahara 1740bb448f0SSatoshi Sahara // assign minor edit checker to the variable 175e71e09a6SSatoshi Sahara $isMinorEdit = function ($info) { 176e71e09a6SSatoshi Sahara return ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT); 1770bb448f0SSatoshi Sahara }; 1780bb448f0SSatoshi Sahara 1790bb448f0SSatoshi Sahara // assign title builder to the variable 180e71e09a6SSatoshi Sahara $itemTitle = function ($id, $rev = '') use ($isMedia) { 1810bb448f0SSatoshi Sahara return ($isMedia) ? dformat($rev) : $id.' ['.dformat($rev).']'; 1820bb448f0SSatoshi Sahara }; 18363ab9afeSSatoshi Sahara 184edb50e6aSSatoshi Sahara // left side 18563ab9afeSSatoshi Sahara if (!$l_rev) { 1860bb448f0SSatoshi Sahara $l_minor = ''; 18763ab9afeSSatoshi Sahara $l_head = '—'; 18863ab9afeSSatoshi Sahara } else { 189e71e09a6SSatoshi Sahara $info = $changelog->getRevisionInfo($l_rev); 1900bb448f0SSatoshi Sahara $objRevInfo = $ui->getObjRevInfo($info); 191e71e09a6SSatoshi Sahara $l_minor = $isMinorEdit($info) ? ' class="minor"' : ''; 192e71e09a6SSatoshi Sahara $l_head = '<bdi>' 193e71e09a6SSatoshi Sahara .'<a class="wikilink1" href="'.$this->itemUrl($this->id, "rev=$l_rev").'">' 194e71e09a6SSatoshi Sahara .$itemTitle($this->id, $l_rev).'</a></bdi>'.$head_separator 1950bb448f0SSatoshi Sahara .$objRevInfo->editor().' '.$objRevInfo->editSummary(); 19663ab9afeSSatoshi Sahara } 19763ab9afeSSatoshi Sahara 198edb50e6aSSatoshi Sahara // right side 19963ab9afeSSatoshi Sahara if ($r_rev) { 200e71e09a6SSatoshi Sahara $info = $changelog->getRevisionInfo($r_rev); 2010bb448f0SSatoshi Sahara $objRevInfo = $ui->getObjRevInfo($info); 202e71e09a6SSatoshi Sahara $r_minor = $isMinorEdit($info) ? ' class="minor"' : ''; 203e71e09a6SSatoshi Sahara $r_head = '<bdi>' 204e71e09a6SSatoshi Sahara .'<a class="wikilink1" href="'.$this->itemUrl($this->id, "rev=$r_rev").'">' 205e71e09a6SSatoshi Sahara .$itemTitle($this->id, $r_rev).'</a></bdi>'.$head_separator 2060bb448f0SSatoshi Sahara .$objRevInfo->editor().' '.$objRevInfo->editSummary(); 2070bb448f0SSatoshi Sahara } elseif ($this->last_rev) { 2080bb448f0SSatoshi Sahara $_rev = $this->last_rev; 209e71e09a6SSatoshi Sahara $info = $changelog->getRevisionInfo($_rev); 2100bb448f0SSatoshi Sahara $objRevInfo = $ui->getObjRevInfo($info); 211e71e09a6SSatoshi Sahara $r_minor = $isMinorEdit($info) ? ' class="minor"' : ''; 212e71e09a6SSatoshi Sahara $r_head = '<bdi>' 213e71e09a6SSatoshi Sahara .'<a class="wikilink1" href="'.$this->itemUrl($this->id).'">' 214e71e09a6SSatoshi Sahara .$itemTitle($this->id, $_rev).'</a></bdi> '.'('.$lang['current'].')'.$head_separator 2150bb448f0SSatoshi Sahara .$objRevInfo->editor().' '.$objRevInfo->editSummary(); 21663ab9afeSSatoshi Sahara } else { 2170bb448f0SSatoshi Sahara $r_minor = ''; 21863ab9afeSSatoshi Sahara $r_head = '— ('.$lang['current'].')'; 21963ab9afeSSatoshi Sahara } 22063ab9afeSSatoshi Sahara 22163ab9afeSSatoshi Sahara return array($l_head, $r_head, $l_minor, $r_minor); 22263ab9afeSSatoshi Sahara } 22363ab9afeSSatoshi Sahara 224e71e09a6SSatoshi Sahara /** 225e71e09a6SSatoshi Sahara * item url generator 226e71e09a6SSatoshi Sahara * 227e71e09a6SSatoshi Sahara * @param string $id page id or media id 228e71e09a6SSatoshi Sahara * @param string|array $urlParameters URL parameters, associative array recommended 229e71e09a6SSatoshi Sahara * @return string 230e71e09a6SSatoshi Sahara */ 231e71e09a6SSatoshi Sahara protected function itemUrl($id, $urlParameters = '') 232e71e09a6SSatoshi Sahara { 233e71e09a6SSatoshi Sahara switch ($this->item) { 234e71e09a6SSatoshi Sahara case 'page': return wl($id, $urlParameters, $absolute = false, '&'); 235e71e09a6SSatoshi Sahara case 'media': return ml($id, $urlParameters, $direct = true, '&', $absolute = false); 236e71e09a6SSatoshi Sahara } 237e71e09a6SSatoshi Sahara } 238e71e09a6SSatoshi Sahara 239*179b4660SSatoshi Sahara /** 240*179b4660SSatoshi Sahara * item filename resolver 241*179b4660SSatoshi Sahara * 242*179b4660SSatoshi Sahara * @param string $id page id or media id 243*179b4660SSatoshi Sahara * @param string|int $rev empty string or revision timestamp 244*179b4660SSatoshi Sahara * @return string 245*179b4660SSatoshi Sahara */ 246*179b4660SSatoshi Sahara protected function itemFN($id, $rev = '') 247*179b4660SSatoshi Sahara { 248*179b4660SSatoshi Sahara switch ($this->item) { 249*179b4660SSatoshi Sahara case 'page': return wikiFN($id, $rev); 250*179b4660SSatoshi Sahara case 'media': return mediaFN($id, $rev); 251*179b4660SSatoshi Sahara } 252*179b4660SSatoshi Sahara } 253*179b4660SSatoshi Sahara 25463ab9afeSSatoshi Sahara} 255