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);
}
}
}