id = $id; $this->setChangeLog(); } /** * set class property changelog */ abstract protected function setChangeLog(); /** * Set a pair of revisions to be compared * * @param int $old_rev * @param int $new_rev * @return $this */ public function compare($old_rev, $new_rev) { $this->old_rev = $old_rev; $this->new_rev = $new_rev; return $this; } /** * Gets or Sets preference of the Ui\Diff object * * @param string|array $prefs a key name or key-value pair(s) * @param mixed $value value used when the first args is string * @return array|$this */ public function preference($prefs = null, $value = null) { // set if (is_string($prefs) && isset($value)) { $this->preference[$prefs] = $value; return $this; } elseif (is_array($prefs)) { foreach ($prefs as $name => $value) { $this->preference[$name] = $value; } return $this; } // get return $this->preference; } /** * Retrieve requested revision(s) and difftype from Ui\Revisions * * @return void */ protected function preProcess() { global $INPUT; // difflink icon click, eg. ?rev=123456789&do=diff if ($INPUT->has('rev')) { $this->old_rev = $INPUT->int('rev'); $this->new_rev = ''; // current revision } // submit button with two checked boxes $rev2 = $INPUT->arr('rev2', []); if (count($rev2) > 1) { if ($rev2[0] == 'current') { [$this->old_rev, $this->new_rev] = [$rev2[1], '']; } elseif ($rev2[1] == 'current') { [$this->old_rev, $this->new_rev] = [$rev2[0], '']; } elseif ($rev2[0] < $rev2[1]) { [$this->old_rev, $this->new_rev] = [$rev2[0], $rev2[1]]; } else { [$this->old_rev, $this->new_rev] = [$rev2[1], $rev2[0]]; } } // diff view type if ($INPUT->has('difftype')) { // retrieve requested $difftype $this->preference['difftype'] = $INPUT->str('difftype'); } else { // read preference from DokuWiki cookie. PageDiff only get_doku_pref('difftype', $mode); if (isset($mode)) $this->preference['difftype'] = $mode; } } /** * get extended revision info * * @param int|string $rev revision identifier, '' means current one * @return array revision info structure of a page or media file */ protected function getExtendedRevisionInfo($rev) { $changelog =& $this->changelog; if ($rev) { $info = $changelog->getRevisionInfo($rev); } elseif (file_exists($filename = $this->itemFN($this->id))) { $rev = filemtime(fullpath($filename)); $info = $changelog->getRevisionInfo($rev) + array( 'current' => true, ); } else { // once exists, but now removed $info = array( 'current' => true, ); } return array('item' => $this->item) + $info; } /** * Build header of diff HTML * * @param string $l_rev Left revisions * @param string $r_rev Right revision * @return string[] HTML snippets for diff header */ public function buildDiffHead($l_rev, $r_rev) { global $lang; $changelog =& $this->changelog; switch ($this->item) { case 'page': $isMedia = false; $ui = new PageRevisions($this->id); break; case 'media': $isMedia = true; $ui = new MediaRevisions($this->id); break; } $head_separator = ($this->preference['difftype'] === 'inline') ? ' ' : '
'; // assign minor edit checker to the variable $isMinorEdit = function ($info) { return ($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT); }; // assign title builder to the variable $itemTitle = function ($id, $rev = '') use ($isMedia) { return ($isMedia) ? dformat($rev) : $id.' ['.dformat($rev).']'; }; // left side if (!$l_rev) { $l_minor = ''; $l_head = '—'; } else { $info = $changelog->getRevisionInfo($l_rev); $objRevInfo = $ui->getObjRevInfo($info); $l_minor = $isMinorEdit($info) ? ' class="minor"' : ''; $l_head = '' .'' .$itemTitle($this->id, $l_rev).''.$head_separator .$objRevInfo->editor().' '.$objRevInfo->editSummary(); } // right side if ($r_rev) { $info = $changelog->getRevisionInfo($r_rev); $objRevInfo = $ui->getObjRevInfo($info); $r_minor = $isMinorEdit($info) ? ' class="minor"' : ''; $r_head = '' .'' .$itemTitle($this->id, $r_rev).''.$head_separator .$objRevInfo->editor().' '.$objRevInfo->editSummary(); } elseif ($this->last_rev) { $_rev = $this->last_rev; $info = $changelog->getRevisionInfo($_rev); $objRevInfo = $ui->getObjRevInfo($info); $r_minor = $isMinorEdit($info) ? ' class="minor"' : ''; $r_head = '' .'' .$itemTitle($this->id, $_rev).' '.'('.$lang['current'].')'.$head_separator .$objRevInfo->editor().' '.$objRevInfo->editSummary(); } else { $r_minor = ''; $r_head = '— ('.$lang['current'].')'; } return array($l_head, $r_head, $l_minor, $r_minor); } /** * item url generator * * @param string $id page id or media id * @param string|array $urlParameters URL parameters, associative array recommended * @return string */ protected function itemUrl($id, $urlParameters = '') { switch ($this->item) { case 'page': return wl($id, $urlParameters, $absolute = false, '&'); case 'media': return ml($id, $urlParameters, $direct = true, '&', $absolute = false); } } /** * item filename resolver * * @param string $id page id or media id * @param string|int $rev empty string or revision timestamp * @return string */ protected function itemFN($id, $rev = '') { switch ($this->item) { case 'page': return wikiFN($id, $rev); case 'media': return mediaFN($id, $rev); } } }