163ab9afeSSatoshi Sahara<?php 263ab9afeSSatoshi Sahara 363ab9afeSSatoshi Saharanamespace dokuwiki\Ui; 463ab9afeSSatoshi Sahara 563ab9afeSSatoshi Saharause dokuwiki\ChangeLog\MediaChangeLog; 6bf3fa5e9SSatoshi Saharause dokuwiki\ChangeLog\RevisionInfo; 763ab9afeSSatoshi Saharause dokuwiki\Form\Form; 879a2d784SGerrit Uitslaguse InvalidArgumentException; 930a159abSSatoshi Saharause JpegMeta; 1063ab9afeSSatoshi Sahara 1163ab9afeSSatoshi Sahara/** 1263ab9afeSSatoshi Sahara * DokuWiki MediaDiff Interface 1363ab9afeSSatoshi Sahara * 1463ab9afeSSatoshi Sahara * @package dokuwiki\Ui 1563ab9afeSSatoshi Sahara */ 1663ab9afeSSatoshi Saharaclass MediaDiff extends Diff 1763ab9afeSSatoshi Sahara{ 18d9c75b22SSatoshi Sahara /* @var MediaChangeLog */ 19d9c75b22SSatoshi Sahara protected $changelog; 20d9c75b22SSatoshi Sahara 216714d8ceSSatoshi Sahara /* @var RevisionInfo older revision */ 22*c02dcaa0SSatoshi Sahara protected $RevInfo1; 236714d8ceSSatoshi Sahara /* @var RevisionInfo newer revision */ 24*c02dcaa0SSatoshi Sahara protected $RevInfo2; 250ea1f71bSSatoshi Sahara 260ea1f71bSSatoshi Sahara /* @var bool */ 270ea1f71bSSatoshi Sahara protected $is_img; 280ea1f71bSSatoshi Sahara 2963ab9afeSSatoshi Sahara /** 3063ab9afeSSatoshi Sahara * MediaDiff Ui constructor 3163ab9afeSSatoshi Sahara * 32edb50e6aSSatoshi Sahara * @param string $id media id 3363ab9afeSSatoshi Sahara */ 34edb50e6aSSatoshi Sahara public function __construct($id) 3563ab9afeSSatoshi Sahara { 364557f463SSatoshi Sahara if (!isset($id)) { 3779a2d784SGerrit Uitslag throw new InvalidArgumentException('media id should not be empty!'); 3830a159abSSatoshi Sahara } 39edb50e6aSSatoshi Sahara 40295564cdSSatoshi Sahara // init preference 416527839fSSatoshi Sahara $this->preference['fromAjax'] = false; // see dokuwiki\Ajax::callMediadiff() 42edb50e6aSSatoshi Sahara $this->preference['showIntro'] = false; 430ea1f71bSSatoshi Sahara $this->preference['difftype'] = 'both'; // diff view type: both, opacity or portions 448068440fSSatoshi Sahara 4530a159abSSatoshi Sahara parent::__construct($id); 468068440fSSatoshi Sahara } 478068440fSSatoshi Sahara 488068440fSSatoshi Sahara /** @inheritdoc */ 498068440fSSatoshi Sahara protected function setChangeLog() 508068440fSSatoshi Sahara { 518068440fSSatoshi Sahara $this->changelog = new MediaChangeLog($this->id); 5263ab9afeSSatoshi Sahara } 5363ab9afeSSatoshi Sahara 540ea1f71bSSatoshi Sahara /** 550ea1f71bSSatoshi Sahara * Handle requested revision(s) and diff view preferences 560ea1f71bSSatoshi Sahara * 570ea1f71bSSatoshi Sahara * @return void 580ea1f71bSSatoshi Sahara */ 590ea1f71bSSatoshi Sahara protected function handle() 60b4b4c5c6SSatoshi Sahara { 610ea1f71bSSatoshi Sahara global $INPUT; 620ea1f71bSSatoshi Sahara 636714d8ceSSatoshi Sahara // retrieve requested rev or rev2 640ea1f71bSSatoshi Sahara parent::handle(); 650ea1f71bSSatoshi Sahara 660ea1f71bSSatoshi Sahara // requested diff view type 670ea1f71bSSatoshi Sahara if ($INPUT->has('difftype')) { 680ea1f71bSSatoshi Sahara $this->preference['difftype'] = $INPUT->str('difftype'); 690ea1f71bSSatoshi Sahara } 70b4b4c5c6SSatoshi Sahara } 71b4b4c5c6SSatoshi Sahara 7263ab9afeSSatoshi Sahara /** 730ea1f71bSSatoshi Sahara * Prepare revision info of comparison pair 740ea1f71bSSatoshi Sahara */ 750ea1f71bSSatoshi Sahara protected function preProcess() 760ea1f71bSSatoshi Sahara { 770ea1f71bSSatoshi Sahara $changelog =& $this->changelog; 780ea1f71bSSatoshi Sahara 796714d8ceSSatoshi Sahara // create revision info object for older and newer sides 80*c02dcaa0SSatoshi Sahara // RevInfo1 : older, left side 81*c02dcaa0SSatoshi Sahara // RevInfo2 : newer, right side 82*c02dcaa0SSatoshi Sahara $this->RevInfo1 = new RevisionInfo($changelog->getRevisionInfo($this->rev1)); 83*c02dcaa0SSatoshi Sahara $this->RevInfo2 = new RevisionInfo($changelog->getRevisionInfo($this->rev2)); 840ea1f71bSSatoshi Sahara 850ea1f71bSSatoshi Sahara $this->is_img = preg_match('/\.(jpe?g|gif|png)$/', $this->id); 860ea1f71bSSatoshi Sahara 87*c02dcaa0SSatoshi Sahara foreach ([$this->RevInfo1, $this->RevInfo2] as $RevInfo) { 88*c02dcaa0SSatoshi Sahara $isCurrent = $changelog->isCurrentRevision($RevInfo->val('date')); 89*c02dcaa0SSatoshi Sahara $RevInfo->isCurrent($isCurrent); 900ea1f71bSSatoshi Sahara 910ea1f71bSSatoshi Sahara if ($this->is_img) { 92*c02dcaa0SSatoshi Sahara $rev = $isCurrent ? '' : $RevInfo->val('date'); 930ea1f71bSSatoshi Sahara $meta = new JpegMeta(mediaFN($this->id, $rev)); 940ea1f71bSSatoshi Sahara // get image width and height for the media manager preview panel 95*c02dcaa0SSatoshi Sahara $RevInfo->append([ 966714d8ceSSatoshi Sahara 'previewSize' => media_image_preview_size($this->id, $rev, $meta) 976714d8ceSSatoshi Sahara ]); 980ea1f71bSSatoshi Sahara } 990ea1f71bSSatoshi Sahara } 1000ea1f71bSSatoshi Sahara 1010ea1f71bSSatoshi Sahara // re-check image, ensure minimum image width for showImageDiff() 1020ea1f71bSSatoshi Sahara $this->is_img = ($this->is_img 103*c02dcaa0SSatoshi Sahara && ($this->RevInfo1->val('previewSize')[0] ?? 0) >= 30 104*c02dcaa0SSatoshi Sahara && ($this->RevInfo2->val('previewSize')[0] ?? 0) >= 30 1050ea1f71bSSatoshi Sahara ); 1060ea1f71bSSatoshi Sahara // adjust requested diff view type 1070ea1f71bSSatoshi Sahara if (!$this->is_img) { 1080ea1f71bSSatoshi Sahara $this->preference['difftype'] = 'both'; 1090ea1f71bSSatoshi Sahara } 1100ea1f71bSSatoshi Sahara } 1110ea1f71bSSatoshi Sahara 1120ea1f71bSSatoshi Sahara 1130ea1f71bSSatoshi Sahara /** 11463ab9afeSSatoshi Sahara * Shows difference between two revisions of media 115675f74fbSSatoshi Sahara * 116675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 11763ab9afeSSatoshi Sahara */ 118309aaee5SSatoshi Sahara public function show() 11963ab9afeSSatoshi Sahara { 120675f74fbSSatoshi Sahara global $conf; 121675f74fbSSatoshi Sahara 12263ab9afeSSatoshi Sahara $ns = getNS($this->id); 12363ab9afeSSatoshi Sahara $auth = auth_quickaclcheck("$ns:*"); 124675f74fbSSatoshi Sahara 12579a2d784SGerrit Uitslag if ($auth < AUTH_READ || !$this->id || !$conf['mediarevisions']) return; 126675f74fbSSatoshi Sahara 1270ea1f71bSSatoshi Sahara // retrieve form parameters: rev, rev2, difftype 1280ea1f71bSSatoshi Sahara $this->handle(); 1290ea1f71bSSatoshi Sahara // prepare revision info of comparison pair 1300ea1f71bSSatoshi Sahara $this->preProcess(); 131675f74fbSSatoshi Sahara 132675f74fbSSatoshi Sahara // display intro 133675f74fbSSatoshi Sahara if ($this->preference['showIntro']) echo p_locale_xhtml('diff'); 134675f74fbSSatoshi Sahara 135675f74fbSSatoshi Sahara // print form to choose diff view type 1360ea1f71bSSatoshi Sahara if ($this->is_img && !$this->preference['fromAjax']) { 13791e70b5fSSatoshi Sahara $this->showDiffViewSelector(); 138675f74fbSSatoshi Sahara echo '<div id="mediamanager__diff" >'; 139675f74fbSSatoshi Sahara } 140675f74fbSSatoshi Sahara 141309aaee5SSatoshi Sahara switch ($this->preference['difftype']) { 142675f74fbSSatoshi Sahara case 'opacity': 143675f74fbSSatoshi Sahara case 'portions': 1440ea1f71bSSatoshi Sahara $this->showImageDiff(); 145675f74fbSSatoshi Sahara break; 146675f74fbSSatoshi Sahara case 'both': 147675f74fbSSatoshi Sahara default: 1480ea1f71bSSatoshi Sahara $this->showFileDiff(); 149675f74fbSSatoshi Sahara break; 150675f74fbSSatoshi Sahara } 151675f74fbSSatoshi Sahara 1520ea1f71bSSatoshi Sahara if ($this->is_img && !$this->preference['fromAjax']) { 153675f74fbSSatoshi Sahara echo '</div>'; 154675f74fbSSatoshi Sahara } 1552db397b2SSatoshi Sahara } 1562db397b2SSatoshi Sahara 1572db397b2SSatoshi Sahara /** 158675f74fbSSatoshi Sahara * Print form to choose diff view type 159675f74fbSSatoshi Sahara * the dropdown is to be added through JavaScript, see lib/scripts/media.js 1602db397b2SSatoshi Sahara */ 16191e70b5fSSatoshi Sahara protected function showDiffViewSelector() 1622db397b2SSatoshi Sahara { 163*c02dcaa0SSatoshi Sahara // use timestamp for current revision, date may be false when revisions < 2 164*c02dcaa0SSatoshi Sahara [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')]; 1650ea1f71bSSatoshi Sahara 16691e70b5fSSatoshi Sahara echo '<div class="diffoptions group">'; 16791e70b5fSSatoshi Sahara 1682db397b2SSatoshi Sahara $form = new Form([ 1692db397b2SSatoshi Sahara 'id' => 'mediamanager__form_diffview', 1702db397b2SSatoshi Sahara 'action' => media_managerURL([], '&'), 1712db397b2SSatoshi Sahara 'method' => 'get', 1722db397b2SSatoshi Sahara 'class' => 'diffView', 1732db397b2SSatoshi Sahara ]); 1742db397b2SSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1752db397b2SSatoshi Sahara $form->setHiddenField('sectok', null); 1762db397b2SSatoshi Sahara $form->setHiddenField('mediado', 'diff'); 177*c02dcaa0SSatoshi Sahara $form->setHiddenField('rev2[0]', $rev1); 178*c02dcaa0SSatoshi Sahara $form->setHiddenField('rev2[1]', $rev2); 1792db397b2SSatoshi Sahara $form->addTagClose('div'); 1802db397b2SSatoshi Sahara echo $form->toHTML(); 18191e70b5fSSatoshi Sahara 18291e70b5fSSatoshi Sahara echo '</div>'; // .diffoptions 1832db397b2SSatoshi Sahara } 1842db397b2SSatoshi Sahara 185675f74fbSSatoshi Sahara /** 186675f74fbSSatoshi Sahara * Prints two images side by side 187675f74fbSSatoshi Sahara * and slider 188675f74fbSSatoshi Sahara * 189675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 190675f74fbSSatoshi Sahara */ 1910ea1f71bSSatoshi Sahara protected function showImageDiff() 192675f74fbSSatoshi Sahara { 193*c02dcaa0SSatoshi Sahara $rev1 = $this->RevInfo1->isCurrent() ? '' : $this->RevInfo1->val('date'); 194*c02dcaa0SSatoshi Sahara $rev2 = $this->RevInfo2->isCurrent() ? '' : $this->RevInfo2->val('date'); 1956714d8ceSSatoshi Sahara 1960ea1f71bSSatoshi Sahara // diff view type: opacity or portions 197675f74fbSSatoshi Sahara $type = $this->preference['difftype']; 1980ea1f71bSSatoshi Sahara 199675f74fbSSatoshi Sahara // adjust image width, right side (newer) has priority 200*c02dcaa0SSatoshi Sahara $rev1Size = $this->RevInfo1->val('previewSize'); 201*c02dcaa0SSatoshi Sahara $rev2Size = $this->RevInfo2->val('previewSize'); 2026714d8ceSSatoshi Sahara if ($rev1Size != $rev2Size) { 2036714d8ceSSatoshi Sahara if ($rev2Size[0] > $rev1Size[0]) { 2046714d8ceSSatoshi Sahara $rev1Size = $rev2Size; 2052db397b2SSatoshi Sahara } 2062db397b2SSatoshi Sahara } 2072db397b2SSatoshi Sahara 2086714d8ceSSatoshi Sahara $rev1Src = ml($this->id, ['rev' => $rev1, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); 2096714d8ceSSatoshi Sahara $rev2Src = ml($this->id, ['rev' => $rev2, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); 210675f74fbSSatoshi Sahara 211675f74fbSSatoshi Sahara // slider 2126714d8ceSSatoshi Sahara echo '<div class="slider" style="max-width: '.($rev1Size[0]-20).'px;" ></div>'; 213675f74fbSSatoshi Sahara 214675f74fbSSatoshi Sahara // two images in divs 215675f74fbSSatoshi Sahara echo '<div class="imageDiff '.$type.'">'; 2166714d8ceSSatoshi Sahara echo '<div class="image1" style="max-width: '.$rev1Size[0].'px;">'; 2176714d8ceSSatoshi Sahara echo '<img src="'.$rev1Src.'" alt="" />'; 218675f74fbSSatoshi Sahara echo '</div>'; 2196714d8ceSSatoshi Sahara echo '<div class="image2" style="max-width: '.$rev1Size[0].'px;">'; 2206714d8ceSSatoshi Sahara echo '<img src="'.$rev2Src.'" alt="" />'; 221675f74fbSSatoshi Sahara echo '</div>'; 222675f74fbSSatoshi Sahara echo '</div>'; 223675f74fbSSatoshi Sahara } 224675f74fbSSatoshi Sahara 225675f74fbSSatoshi Sahara /** 226675f74fbSSatoshi Sahara * Shows difference between two revisions of media file 227675f74fbSSatoshi Sahara * 228675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 229675f74fbSSatoshi Sahara */ 2300ea1f71bSSatoshi Sahara protected function showFileDiff() 231675f74fbSSatoshi Sahara { 232a6dd7f90SSatoshi Sahara global $lang; 233a6dd7f90SSatoshi Sahara 2340ea1f71bSSatoshi Sahara $ns = getNS($this->id); 2350ea1f71bSSatoshi Sahara $auth = auth_quickaclcheck("$ns:*"); 2360ea1f71bSSatoshi Sahara 237*c02dcaa0SSatoshi Sahara $rev1 = $this->RevInfo1->isCurrent() ? '' : (int)$this->RevInfo1->val('date'); 238*c02dcaa0SSatoshi Sahara $rev2 = $this->RevInfo2->isCurrent() ? '' : (int)$this->RevInfo2->val('date'); 2396714d8ceSSatoshi Sahara 2406714d8ceSSatoshi Sahara // revision title 241*c02dcaa0SSatoshi Sahara $rev1Title = trim($this->RevInfo1->showRevisionTitle() .' '. $this->RevInfo1->showCurrentIndicator()); 242*c02dcaa0SSatoshi Sahara $rev1Summary = ($this->RevInfo1->val('date')) 243*c02dcaa0SSatoshi Sahara ? $this->RevInfo1->showEditSummary() .' '. $this->RevInfo1->showEditor() 2446714d8ceSSatoshi Sahara : ''; 245*c02dcaa0SSatoshi Sahara $rev2Title = trim($this->RevInfo2->showRevisionTitle() .' '. $this->RevInfo2->showCurrentIndicator()); 246*c02dcaa0SSatoshi Sahara $rev2Summary = ($this->RevInfo2->val('date')) 247*c02dcaa0SSatoshi Sahara ? $this->RevInfo2->showEditSummary() .' '. $this->RevInfo2->showEditor() 2486714d8ceSSatoshi Sahara : ''; 2496714d8ceSSatoshi Sahara 2506714d8ceSSatoshi Sahara $rev1Meta = new JpegMeta(mediaFN($this->id, $rev1)); 2516714d8ceSSatoshi Sahara $rev2Meta = new JpegMeta(mediaFN($this->id, $rev2)); 2522db397b2SSatoshi Sahara 253179b4660SSatoshi Sahara // display diff view table 2542db397b2SSatoshi Sahara echo '<div class="table">'; 2552db397b2SSatoshi Sahara echo '<table>'; 2562db397b2SSatoshi Sahara echo '<tr>'; 2573712ae9eSSatoshi Sahara echo '<th>'. $rev1Title .' '. $rev1Summary .'</th>'; 2583712ae9eSSatoshi Sahara echo '<th>'. $rev2Title .' '. $rev2Summary .'</th>'; 259675f74fbSSatoshi Sahara echo '</tr>'; 2602db397b2SSatoshi Sahara 2612db397b2SSatoshi Sahara echo '<tr class="image">'; 2622db397b2SSatoshi Sahara echo '<td>'; 2636714d8ceSSatoshi Sahara media_preview($this->id, $auth, $rev1, $rev1Meta); // $auth not used in media_preview()? 2642db397b2SSatoshi Sahara echo '</td>'; 2652db397b2SSatoshi Sahara 2662db397b2SSatoshi Sahara echo '<td>'; 2676714d8ceSSatoshi Sahara media_preview($this->id, $auth, $rev2, $rev2Meta); 2682db397b2SSatoshi Sahara echo '</td>'; 269675f74fbSSatoshi Sahara echo '</tr>'; 2702db397b2SSatoshi Sahara 2712db397b2SSatoshi Sahara echo '<tr class="actions">'; 2722db397b2SSatoshi Sahara echo '<td>'; 2736714d8ceSSatoshi Sahara media_preview_buttons($this->id, $auth, $rev1); // $auth used in media_preview_buttons() 2742db397b2SSatoshi Sahara echo '</td>'; 2752db397b2SSatoshi Sahara 2762db397b2SSatoshi Sahara echo '<td>'; 2776714d8ceSSatoshi Sahara media_preview_buttons($this->id, $auth, $rev2); 2782db397b2SSatoshi Sahara echo '</td>'; 279675f74fbSSatoshi Sahara echo '</tr>'; 2802db397b2SSatoshi Sahara 2816714d8ceSSatoshi Sahara $rev1Tags = media_file_tags($rev1Meta); 2826714d8ceSSatoshi Sahara $rev2Tags = media_file_tags($rev2Meta); 2836714d8ceSSatoshi Sahara // FIXME rev2Tags-only stuff ignored 2846714d8ceSSatoshi Sahara foreach ($rev1Tags as $key => $tag) { 2856714d8ceSSatoshi Sahara if ($tag['value'] != $rev2Tags[$key]['value']) { 2866714d8ceSSatoshi Sahara $rev2Tags[$key]['highlighted'] = true; 2876714d8ceSSatoshi Sahara $rev1Tags[$key]['highlighted'] = true; 2886714d8ceSSatoshi Sahara } elseif (!$tag['value'] || !$rev2Tags[$key]['value']) { 2896714d8ceSSatoshi Sahara unset($rev2Tags[$key]); 2906714d8ceSSatoshi Sahara unset($rev1Tags[$key]); 2912db397b2SSatoshi Sahara } 2922db397b2SSatoshi Sahara } 2932db397b2SSatoshi Sahara 2942db397b2SSatoshi Sahara echo '<tr>'; 2956714d8ceSSatoshi Sahara foreach ([$rev1Tags, $rev2Tags] as $tags) { 296675f74fbSSatoshi Sahara echo '<td>'; 2972db397b2SSatoshi Sahara 2982db397b2SSatoshi Sahara echo '<dl class="img_tags">'; 2992db397b2SSatoshi Sahara foreach ($tags as $tag) { 3002db397b2SSatoshi Sahara $value = cleanText($tag['value']); 3012db397b2SSatoshi Sahara if (!$value) $value = '-'; 3022db397b2SSatoshi Sahara echo '<dt>'.$lang[$tag['tag'][1]].'</dt>'; 3032db397b2SSatoshi Sahara echo '<dd>'; 304f2749649SSatoshi Sahara if (!empty($tag['highlighted'])) echo '<strong>'; 3052db397b2SSatoshi Sahara if ($tag['tag'][2] == 'date') { 3062db397b2SSatoshi Sahara echo dformat($value); 3072db397b2SSatoshi Sahara } else { 3082db397b2SSatoshi Sahara echo hsc($value); 3092db397b2SSatoshi Sahara } 310f2749649SSatoshi Sahara if (!empty($tag['highlighted'])) echo '</strong>'; 3112db397b2SSatoshi Sahara echo '</dd>'; 3122db397b2SSatoshi Sahara } 313675f74fbSSatoshi Sahara echo '</dl>'; 3142db397b2SSatoshi Sahara 3152db397b2SSatoshi Sahara echo '</td>'; 3162db397b2SSatoshi Sahara } 317675f74fbSSatoshi Sahara echo '</tr>'; 3182db397b2SSatoshi Sahara 319675f74fbSSatoshi Sahara echo '</table>'; 320675f74fbSSatoshi Sahara echo '</div>'; 32163ab9afeSSatoshi Sahara } 32263ab9afeSSatoshi Sahara 32363ab9afeSSatoshi Sahara} 324