123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <?php
- namespace dokuwiki\Ui;
- use dokuwiki\ChangeLog\MediaChangeLog;
- use dokuwiki\ChangeLog\RevisionInfo;
- use dokuwiki\Form\Form;
- use InvalidArgumentException;
- use JpegMeta;
- /**
- * DokuWiki MediaDiff Interface
- *
- * @package dokuwiki\Ui
- */
- class MediaDiff extends Diff
- {
- /* @var MediaChangeLog */
- protected $changelog;
- /* @var RevisionInfo older revision */
- protected $RevInfo1;
- /* @var RevisionInfo newer revision */
- protected $RevInfo2;
- /* @var bool */
- protected $is_img;
- /**
- * MediaDiff Ui constructor
- *
- * @param string $id media id
- */
- public function __construct($id)
- {
- if (!isset($id)) {
- throw new InvalidArgumentException('media id should not be empty!');
- }
- // init preference
- $this->preference['fromAjax'] = false; // see dokuwiki\Ajax::callMediadiff()
- $this->preference['showIntro'] = false;
- $this->preference['difftype'] = 'both'; // diff view type: both, opacity or portions
- parent::__construct($id);
- }
- /** @inheritdoc */
- protected function setChangeLog()
- {
- $this->changelog = new MediaChangeLog($this->id);
- }
- /**
- * Handle requested revision(s) and diff view preferences
- *
- * @return void
- */
- protected function handle()
- {
- global $INPUT;
- // retrieve requested rev or rev2
- parent::handle();
- // requested diff view type
- if ($INPUT->has('difftype')) {
- $this->preference['difftype'] = $INPUT->str('difftype');
- }
- }
- /**
- * Prepare revision info of comparison pair
- */
- protected function preProcess()
- {
- $changelog =& $this->changelog;
- // create revision info object for older and newer sides
- // RevInfo1 : older, left side
- // RevInfo2 : newer, right side
-
- $changelogRev1 = $changelog->getRevisionInfo($this->rev1);
- $changelogRev2 = $changelog->getRevisionInfo($this->rev2);
- $changelogRev1['media'] = $changelogRev2['media'] = true;
- $this->RevInfo1 = new RevisionInfo($changelogRev1);
- $this->RevInfo2 = new RevisionInfo($changelogRev2);
- $this->is_img = preg_match('/\.(jpe?g|gif|png)$/', $this->id);
- foreach ([$this->RevInfo1, $this->RevInfo2] as $RevInfo) {
- $isCurrent = $changelog->isCurrentRevision($RevInfo->val('date'));
- $RevInfo->isCurrent($isCurrent);
- if ($this->is_img) {
- $rev = $isCurrent ? '' : $RevInfo->val('date');
- $meta = new JpegMeta(mediaFN($this->id, $rev));
- // get image width and height for the media manager preview panel
- $RevInfo->append([
- 'previewSize' => media_image_preview_size($this->id, $rev, $meta)
- ]);
- }
- }
- // re-check image, ensure minimum image width for showImageDiff()
- $this->is_img = ($this->is_img
- && ($this->RevInfo1->val('previewSize')[0] ?? 0) >= 30
- && ($this->RevInfo2->val('previewSize')[0] ?? 0) >= 30
- );
- // adjust requested diff view type
- if (!$this->is_img) {
- $this->preference['difftype'] = 'both';
- }
- }
- /**
- * Shows difference between two revisions of media
- *
- * @author Kate Arzamastseva <pshns@ukr.net>
- */
- public function show()
- {
- global $conf;
- $ns = getNS($this->id);
- $auth = auth_quickaclcheck("$ns:*");
- if ($auth < AUTH_READ || !$this->id || !$conf['mediarevisions']) return;
- // retrieve form parameters: rev, rev2, difftype
- $this->handle();
- // prepare revision info of comparison pair
- $this->preProcess();
- // display intro
- if ($this->preference['showIntro']) echo p_locale_xhtml('diff');
- // print form to choose diff view type
- if ($this->is_img && !$this->preference['fromAjax']) {
- $this->showDiffViewSelector();
- echo '<div id="mediamanager__diff" >';
- }
- switch ($this->preference['difftype']) {
- case 'opacity':
- case 'portions':
- $this->showImageDiff();
- break;
- case 'both':
- default:
- $this->showFileDiff();
- break;
- }
- if ($this->is_img && !$this->preference['fromAjax']) {
- echo '</div>';
- }
- }
- /**
- * Print form to choose diff view type
- * the dropdown is to be added through JavaScript, see lib/scripts/media.js
- */
- protected function showDiffViewSelector()
- {
- // use timestamp for current revision, date may be false when revisions < 2
- [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')];
- echo '<div class="diffoptions group">';
- $form = new Form([
- 'id' => 'mediamanager__form_diffview',
- 'action' => media_managerURL([], '&'),
- 'method' => 'get',
- 'class' => 'diffView',
- ]);
- $form->addTagOpen('div')->addClass('no');
- $form->setHiddenField('sectok', null);
- $form->setHiddenField('mediado', 'diff');
- $form->setHiddenField('rev2[0]', $rev1);
- $form->setHiddenField('rev2[1]', $rev2);
- $form->addTagClose('div');
- echo $form->toHTML();
- echo '</div>'; // .diffoptions
- }
- /**
- * Prints two images side by side
- * and slider
- *
- * @author Kate Arzamastseva <pshns@ukr.net>
- */
- protected function showImageDiff()
- {
- $rev1 = $this->RevInfo1->isCurrent() ? '' : $this->RevInfo1->val('date');
- $rev2 = $this->RevInfo2->isCurrent() ? '' : $this->RevInfo2->val('date');
- // diff view type: opacity or portions
- $type = $this->preference['difftype'];
- // adjust image width, right side (newer) has priority
- $rev1Size = $this->RevInfo1->val('previewSize');
- $rev2Size = $this->RevInfo2->val('previewSize');
- if ($rev1Size != $rev2Size) {
- if ($rev2Size[0] > $rev1Size[0]) {
- $rev1Size = $rev2Size;
- }
- }
- $rev1Src = ml($this->id, ['rev' => $rev1, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]);
- $rev2Src = ml($this->id, ['rev' => $rev2, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]);
- // slider
- echo '<div class="slider" style="max-width: '.($rev1Size[0]-20).'px;" ></div>';
- // two images in divs
- echo '<div class="imageDiff '.$type.'">';
- echo '<div class="image1" style="max-width: '.$rev1Size[0].'px;">';
- echo '<img src="'.$rev1Src.'" alt="" />';
- echo '</div>';
- echo '<div class="image2" style="max-width: '.$rev1Size[0].'px;">';
- echo '<img src="'.$rev2Src.'" alt="" />';
- echo '</div>';
- echo '</div>';
- }
- /**
- * Shows difference between two revisions of media file
- *
- * @author Kate Arzamastseva <pshns@ukr.net>
- */
- protected function showFileDiff()
- {
- global $lang;
- $ns = getNS($this->id);
- $auth = auth_quickaclcheck("$ns:*");
- $rev1 = $this->RevInfo1->isCurrent() ? '' : (int)$this->RevInfo1->val('date');
- $rev2 = $this->RevInfo2->isCurrent() ? '' : (int)$this->RevInfo2->val('date');
- // revision title
- $rev1Title = trim($this->RevInfo1->showRevisionTitle() .' '. $this->RevInfo1->showCurrentIndicator());
- $rev1Summary = ($this->RevInfo1->val('date'))
- ? $this->RevInfo1->showEditSummary() .' '. $this->RevInfo1->showEditor()
- : '';
- $rev2Title = trim($this->RevInfo2->showRevisionTitle() .' '. $this->RevInfo2->showCurrentIndicator());
- $rev2Summary = ($this->RevInfo2->val('date'))
- ? $this->RevInfo2->showEditSummary() .' '. $this->RevInfo2->showEditor()
- : '';
- $rev1Meta = new JpegMeta(mediaFN($this->id, $rev1));
- $rev2Meta = new JpegMeta(mediaFN($this->id, $rev2));
- // display diff view table
- echo '<div class="table">';
- echo '<table>';
- echo '<tr>';
- echo '<th>'. $rev1Title .' '. $rev1Summary .'</th>';
- echo '<th>'. $rev2Title .' '. $rev2Summary .'</th>';
- echo '</tr>';
- echo '<tr class="image">';
- echo '<td>';
- media_preview($this->id, $auth, $rev1, $rev1Meta); // $auth not used in media_preview()?
- echo '</td>';
- echo '<td>';
- media_preview($this->id, $auth, $rev2, $rev2Meta);
- echo '</td>';
- echo '</tr>';
- echo '<tr class="actions">';
- echo '<td>';
- media_preview_buttons($this->id, $auth, $rev1); // $auth used in media_preview_buttons()
- echo '</td>';
- echo '<td>';
- media_preview_buttons($this->id, $auth, $rev2);
- echo '</td>';
- echo '</tr>';
- $rev1Tags = media_file_tags($rev1Meta);
- $rev2Tags = media_file_tags($rev2Meta);
- // FIXME rev2Tags-only stuff ignored
- foreach ($rev1Tags as $key => $tag) {
- if ($tag['value'] != $rev2Tags[$key]['value']) {
- $rev2Tags[$key]['highlighted'] = true;
- $rev1Tags[$key]['highlighted'] = true;
- } elseif (!$tag['value'] || !$rev2Tags[$key]['value']) {
- unset($rev2Tags[$key]);
- unset($rev1Tags[$key]);
- }
- }
- echo '<tr>';
- foreach ([$rev1Tags, $rev2Tags] as $tags) {
- echo '<td>';
- echo '<dl class="img_tags">';
- foreach ($tags as $tag) {
- $value = cleanText($tag['value']);
- if (!$value) $value = '-';
- echo '<dt>'.$lang[$tag['tag'][1]].'</dt>';
- echo '<dd>';
- if (!empty($tag['highlighted'])) echo '<strong>';
- if ($tag['tag'][2] == 'date') {
- echo dformat($value);
- } else {
- echo hsc($value);
- }
- if (!empty($tag['highlighted'])) echo '</strong>';
- echo '</dd>';
- }
- echo '</dl>';
- echo '</td>';
- }
- echo '</tr>';
- echo '</table>';
- echo '</div>';
- }
- }
|