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 */ 226714d8ceSSatoshi Sahara protected $Rev1; 236714d8ceSSatoshi Sahara /* @var RevisionInfo newer revision */ 246714d8ceSSatoshi Sahara protected $Rev2; 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 806714d8ceSSatoshi Sahara // Rev1 : older, left side 816714d8ceSSatoshi Sahara // Rev2 : newer, right side 826714d8ceSSatoshi Sahara $this->Rev1 = new RevisionInfo($changelog->getRevisionInfo($this->rev1)); 836714d8ceSSatoshi Sahara $this->Rev2 = new RevisionInfo($changelog->getRevisionInfo($this->rev2)); 846714d8ceSSatoshi Sahara [$Rev1, $Rev2] = [$this->Rev1, $this->Rev2]; 850ea1f71bSSatoshi Sahara 860ea1f71bSSatoshi Sahara $this->is_img = preg_match('/\.(jpe?g|gif|png)$/', $this->id); 870ea1f71bSSatoshi Sahara 886714d8ceSSatoshi Sahara foreach ([$Rev1, $Rev2] as $Revision) { 896714d8ceSSatoshi Sahara $isCurrent = $changelog->isCurrentRevision($Revision->val('date')); 906714d8ceSSatoshi Sahara $Revision->isCurrent($isCurrent); 910ea1f71bSSatoshi Sahara 920ea1f71bSSatoshi Sahara if ($this->is_img) { 936714d8ceSSatoshi Sahara $rev = $isCurrent ? '' : $Revision->val('date'); 940ea1f71bSSatoshi Sahara $meta = new JpegMeta(mediaFN($this->id, $rev)); 950ea1f71bSSatoshi Sahara // get image width and height for the media manager preview panel 966714d8ceSSatoshi Sahara $Revision->append([ 976714d8ceSSatoshi Sahara 'previewSize' => media_image_preview_size($this->id, $rev, $meta) 986714d8ceSSatoshi Sahara ]); 990ea1f71bSSatoshi Sahara } 1000ea1f71bSSatoshi Sahara } 1010ea1f71bSSatoshi Sahara 1020ea1f71bSSatoshi Sahara // re-check image, ensure minimum image width for showImageDiff() 1030ea1f71bSSatoshi Sahara $this->is_img = ($this->is_img 1046714d8ceSSatoshi Sahara && ($Rev1->val('previewSize')[0] ?? 0) >= 30 1056714d8ceSSatoshi Sahara && ($Rev2->val('previewSize')[0] ?? 0) >= 30 1060ea1f71bSSatoshi Sahara ); 1070ea1f71bSSatoshi Sahara // adjust requested diff view type 1080ea1f71bSSatoshi Sahara if (!$this->is_img) { 1090ea1f71bSSatoshi Sahara $this->preference['difftype'] = 'both'; 1100ea1f71bSSatoshi Sahara } 1110ea1f71bSSatoshi Sahara } 1120ea1f71bSSatoshi Sahara 1130ea1f71bSSatoshi Sahara 1140ea1f71bSSatoshi Sahara /** 11563ab9afeSSatoshi Sahara * Shows difference between two revisions of media 116675f74fbSSatoshi Sahara * 117675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 11863ab9afeSSatoshi Sahara */ 119309aaee5SSatoshi Sahara public function show() 12063ab9afeSSatoshi Sahara { 121675f74fbSSatoshi Sahara global $conf; 122675f74fbSSatoshi Sahara 12363ab9afeSSatoshi Sahara $ns = getNS($this->id); 12463ab9afeSSatoshi Sahara $auth = auth_quickaclcheck("$ns:*"); 125675f74fbSSatoshi Sahara 12679a2d784SGerrit Uitslag if ($auth < AUTH_READ || !$this->id || !$conf['mediarevisions']) return; 127675f74fbSSatoshi Sahara 1280ea1f71bSSatoshi Sahara // retrieve form parameters: rev, rev2, difftype 1290ea1f71bSSatoshi Sahara $this->handle(); 1300ea1f71bSSatoshi Sahara // prepare revision info of comparison pair 1310ea1f71bSSatoshi Sahara $this->preProcess(); 132675f74fbSSatoshi Sahara 133675f74fbSSatoshi Sahara // display intro 134675f74fbSSatoshi Sahara if ($this->preference['showIntro']) echo p_locale_xhtml('diff'); 135675f74fbSSatoshi Sahara 136675f74fbSSatoshi Sahara // print form to choose diff view type 1370ea1f71bSSatoshi Sahara if ($this->is_img && !$this->preference['fromAjax']) { 13891e70b5fSSatoshi Sahara $this->showDiffViewSelector(); 139675f74fbSSatoshi Sahara echo '<div id="mediamanager__diff" >'; 140675f74fbSSatoshi Sahara } 141675f74fbSSatoshi Sahara 142309aaee5SSatoshi Sahara switch ($this->preference['difftype']) { 143675f74fbSSatoshi Sahara case 'opacity': 144675f74fbSSatoshi Sahara case 'portions': 1450ea1f71bSSatoshi Sahara $this->showImageDiff(); 146675f74fbSSatoshi Sahara break; 147675f74fbSSatoshi Sahara case 'both': 148675f74fbSSatoshi Sahara default: 1490ea1f71bSSatoshi Sahara $this->showFileDiff(); 150675f74fbSSatoshi Sahara break; 151675f74fbSSatoshi Sahara } 152675f74fbSSatoshi Sahara 1530ea1f71bSSatoshi Sahara if ($this->is_img && !$this->preference['fromAjax']) { 154675f74fbSSatoshi Sahara echo '</div>'; 155675f74fbSSatoshi Sahara } 1562db397b2SSatoshi Sahara } 1572db397b2SSatoshi Sahara 1582db397b2SSatoshi Sahara /** 159675f74fbSSatoshi Sahara * Print form to choose diff view type 160675f74fbSSatoshi Sahara * the dropdown is to be added through JavaScript, see lib/scripts/media.js 1612db397b2SSatoshi Sahara */ 16291e70b5fSSatoshi Sahara protected function showDiffViewSelector() 1632db397b2SSatoshi Sahara { 1646714d8ceSSatoshi Sahara // revision information object 1656714d8ceSSatoshi Sahara [$Rev1, $Rev2] = [$this->Rev1, $this->Rev2]; 1660ea1f71bSSatoshi Sahara 16791e70b5fSSatoshi Sahara echo '<div class="diffoptions group">'; 16891e70b5fSSatoshi Sahara 1692db397b2SSatoshi Sahara $form = new Form([ 1702db397b2SSatoshi Sahara 'id' => 'mediamanager__form_diffview', 1712db397b2SSatoshi Sahara 'action' => media_managerURL([], '&'), 1722db397b2SSatoshi Sahara 'method' => 'get', 1732db397b2SSatoshi Sahara 'class' => 'diffView', 1742db397b2SSatoshi Sahara ]); 1752db397b2SSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1762db397b2SSatoshi Sahara $form->setHiddenField('sectok', null); 1772db397b2SSatoshi Sahara $form->setHiddenField('mediado', 'diff'); 1786714d8ceSSatoshi Sahara $form->setHiddenField('rev2[0]', (int)$Rev1->val('date')); 1796714d8ceSSatoshi Sahara $form->setHiddenField('rev2[1]', (int)$Rev2->val('date')); 1802db397b2SSatoshi Sahara $form->addTagClose('div'); 1812db397b2SSatoshi Sahara echo $form->toHTML(); 18291e70b5fSSatoshi Sahara 18391e70b5fSSatoshi Sahara echo '</div>'; // .diffoptions 1842db397b2SSatoshi Sahara } 1852db397b2SSatoshi Sahara 186675f74fbSSatoshi Sahara /** 187675f74fbSSatoshi Sahara * Prints two images side by side 188675f74fbSSatoshi Sahara * and slider 189675f74fbSSatoshi Sahara * 190675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 191675f74fbSSatoshi Sahara */ 1920ea1f71bSSatoshi Sahara protected function showImageDiff() 193675f74fbSSatoshi Sahara { 1946714d8ceSSatoshi Sahara // revision information object 1956714d8ceSSatoshi Sahara [$Rev1, $Rev2] = [$this->Rev1, $this->Rev2]; 1966714d8ceSSatoshi Sahara 1976714d8ceSSatoshi Sahara $rev1 = $Rev1->isCurrent() ? '' : $Rev1->val('date'); 1986714d8ceSSatoshi Sahara $rev2 = $Rev2->isCurrent() ? '' : $Rev2->val('date'); 1996714d8ceSSatoshi Sahara 2000ea1f71bSSatoshi Sahara // diff view type: opacity or portions 201675f74fbSSatoshi Sahara $type = $this->preference['difftype']; 2020ea1f71bSSatoshi Sahara 203675f74fbSSatoshi Sahara // adjust image width, right side (newer) has priority 2046714d8ceSSatoshi Sahara $rev1Size = $Rev1->val('previewSize'); 2056714d8ceSSatoshi Sahara $rev2Size = $Rev2->val('previewSize'); 2066714d8ceSSatoshi Sahara if ($rev1Size != $rev2Size) { 2076714d8ceSSatoshi Sahara if ($rev2Size[0] > $rev1Size[0]) { 2086714d8ceSSatoshi Sahara $rev1Size = $rev2Size; 2092db397b2SSatoshi Sahara } 2102db397b2SSatoshi Sahara } 2112db397b2SSatoshi Sahara 2126714d8ceSSatoshi Sahara $rev1Src = ml($this->id, ['rev' => $rev1, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); 2136714d8ceSSatoshi Sahara $rev2Src = ml($this->id, ['rev' => $rev2, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); 214675f74fbSSatoshi Sahara 215675f74fbSSatoshi Sahara // slider 2166714d8ceSSatoshi Sahara echo '<div class="slider" style="max-width: '.($rev1Size[0]-20).'px;" ></div>'; 217675f74fbSSatoshi Sahara 218675f74fbSSatoshi Sahara // two images in divs 219675f74fbSSatoshi Sahara echo '<div class="imageDiff '.$type.'">'; 2206714d8ceSSatoshi Sahara echo '<div class="image1" style="max-width: '.$rev1Size[0].'px;">'; 2216714d8ceSSatoshi Sahara echo '<img src="'.$rev1Src.'" alt="" />'; 222675f74fbSSatoshi Sahara echo '</div>'; 2236714d8ceSSatoshi Sahara echo '<div class="image2" style="max-width: '.$rev1Size[0].'px;">'; 2246714d8ceSSatoshi Sahara echo '<img src="'.$rev2Src.'" alt="" />'; 225675f74fbSSatoshi Sahara echo '</div>'; 226675f74fbSSatoshi Sahara echo '</div>'; 227675f74fbSSatoshi Sahara } 228675f74fbSSatoshi Sahara 229675f74fbSSatoshi Sahara /** 230675f74fbSSatoshi Sahara * Shows difference between two revisions of media file 231675f74fbSSatoshi Sahara * 232675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 233675f74fbSSatoshi Sahara */ 2340ea1f71bSSatoshi Sahara protected function showFileDiff() 235675f74fbSSatoshi Sahara { 236a6dd7f90SSatoshi Sahara global $lang; 237a6dd7f90SSatoshi Sahara 2380ea1f71bSSatoshi Sahara $ns = getNS($this->id); 2390ea1f71bSSatoshi Sahara $auth = auth_quickaclcheck("$ns:*"); 2400ea1f71bSSatoshi Sahara 2416714d8ceSSatoshi Sahara // revision information object 2426714d8ceSSatoshi Sahara [$Rev1, $Rev2] = [$this->Rev1, $this->Rev2]; 2430ea1f71bSSatoshi Sahara 2446714d8ceSSatoshi Sahara $rev1 = $Rev1->isCurrent() ? '' : (int)$Rev1->val('date'); 2456714d8ceSSatoshi Sahara $rev2 = $Rev2->isCurrent() ? '' : (int)$Rev2->val('date'); 2466714d8ceSSatoshi Sahara 2476714d8ceSSatoshi Sahara // revision title 2486714d8ceSSatoshi Sahara $rev1Title = trim($Rev1->showRevisionTitle() .' '. $Rev1->showCurrentIndicator()); 249*3712ae9eSSatoshi Sahara $rev1Summary = ($Rev1->val('date')) 2506714d8ceSSatoshi Sahara ? $Rev1->showEditSummary() .' '. $Rev1->showEditor() 2516714d8ceSSatoshi Sahara : ''; 2526714d8ceSSatoshi Sahara $rev2Title = trim($Rev2->showRevisionTitle() .' '. $Rev2->showCurrentIndicator()); 253*3712ae9eSSatoshi Sahara $rev2Summary = ($Rev2->val('date')) 2546714d8ceSSatoshi Sahara ? $Rev2->showEditSummary() .' '. $Rev2->showEditor() 2556714d8ceSSatoshi Sahara : ''; 2566714d8ceSSatoshi Sahara 2576714d8ceSSatoshi Sahara $rev1Meta = new JpegMeta(mediaFN($this->id, $rev1)); 2586714d8ceSSatoshi Sahara $rev2Meta = new JpegMeta(mediaFN($this->id, $rev2)); 2592db397b2SSatoshi Sahara 260179b4660SSatoshi Sahara // display diff view table 2612db397b2SSatoshi Sahara echo '<div class="table">'; 2622db397b2SSatoshi Sahara echo '<table>'; 2632db397b2SSatoshi Sahara echo '<tr>'; 264*3712ae9eSSatoshi Sahara echo '<th>'. $rev1Title .' '. $rev1Summary .'</th>'; 265*3712ae9eSSatoshi Sahara echo '<th>'. $rev2Title .' '. $rev2Summary .'</th>'; 266675f74fbSSatoshi Sahara echo '</tr>'; 2672db397b2SSatoshi Sahara 2682db397b2SSatoshi Sahara echo '<tr class="image">'; 2692db397b2SSatoshi Sahara echo '<td>'; 2706714d8ceSSatoshi Sahara media_preview($this->id, $auth, $rev1, $rev1Meta); // $auth not used in media_preview()? 2712db397b2SSatoshi Sahara echo '</td>'; 2722db397b2SSatoshi Sahara 2732db397b2SSatoshi Sahara echo '<td>'; 2746714d8ceSSatoshi Sahara media_preview($this->id, $auth, $rev2, $rev2Meta); 2752db397b2SSatoshi Sahara echo '</td>'; 276675f74fbSSatoshi Sahara echo '</tr>'; 2772db397b2SSatoshi Sahara 2782db397b2SSatoshi Sahara echo '<tr class="actions">'; 2792db397b2SSatoshi Sahara echo '<td>'; 2806714d8ceSSatoshi Sahara media_preview_buttons($this->id, $auth, $rev1); // $auth used in media_preview_buttons() 2812db397b2SSatoshi Sahara echo '</td>'; 2822db397b2SSatoshi Sahara 2832db397b2SSatoshi Sahara echo '<td>'; 2846714d8ceSSatoshi Sahara media_preview_buttons($this->id, $auth, $rev2); 2852db397b2SSatoshi Sahara echo '</td>'; 286675f74fbSSatoshi Sahara echo '</tr>'; 2872db397b2SSatoshi Sahara 2886714d8ceSSatoshi Sahara $rev1Tags = media_file_tags($rev1Meta); 2896714d8ceSSatoshi Sahara $rev2Tags = media_file_tags($rev2Meta); 2906714d8ceSSatoshi Sahara // FIXME rev2Tags-only stuff ignored 2916714d8ceSSatoshi Sahara foreach ($rev1Tags as $key => $tag) { 2926714d8ceSSatoshi Sahara if ($tag['value'] != $rev2Tags[$key]['value']) { 2936714d8ceSSatoshi Sahara $rev2Tags[$key]['highlighted'] = true; 2946714d8ceSSatoshi Sahara $rev1Tags[$key]['highlighted'] = true; 2956714d8ceSSatoshi Sahara } elseif (!$tag['value'] || !$rev2Tags[$key]['value']) { 2966714d8ceSSatoshi Sahara unset($rev2Tags[$key]); 2976714d8ceSSatoshi Sahara unset($rev1Tags[$key]); 2982db397b2SSatoshi Sahara } 2992db397b2SSatoshi Sahara } 3002db397b2SSatoshi Sahara 3012db397b2SSatoshi Sahara echo '<tr>'; 3026714d8ceSSatoshi Sahara foreach ([$rev1Tags, $rev2Tags] as $tags) { 303675f74fbSSatoshi Sahara echo '<td>'; 3042db397b2SSatoshi Sahara 3052db397b2SSatoshi Sahara echo '<dl class="img_tags">'; 3062db397b2SSatoshi Sahara foreach ($tags as $tag) { 3072db397b2SSatoshi Sahara $value = cleanText($tag['value']); 3082db397b2SSatoshi Sahara if (!$value) $value = '-'; 3092db397b2SSatoshi Sahara echo '<dt>'.$lang[$tag['tag'][1]].'</dt>'; 3102db397b2SSatoshi Sahara echo '<dd>'; 311f2749649SSatoshi Sahara if (!empty($tag['highlighted'])) echo '<strong>'; 3122db397b2SSatoshi Sahara if ($tag['tag'][2] == 'date') { 3132db397b2SSatoshi Sahara echo dformat($value); 3142db397b2SSatoshi Sahara } else { 3152db397b2SSatoshi Sahara echo hsc($value); 3162db397b2SSatoshi Sahara } 317f2749649SSatoshi Sahara if (!empty($tag['highlighted'])) echo '</strong>'; 3182db397b2SSatoshi Sahara echo '</dd>'; 3192db397b2SSatoshi Sahara } 320675f74fbSSatoshi Sahara echo '</dl>'; 3212db397b2SSatoshi Sahara 3222db397b2SSatoshi Sahara echo '</td>'; 3232db397b2SSatoshi Sahara } 324675f74fbSSatoshi Sahara echo '</tr>'; 3252db397b2SSatoshi Sahara 326675f74fbSSatoshi Sahara echo '</table>'; 327675f74fbSSatoshi Sahara echo '</div>'; 32863ab9afeSSatoshi Sahara } 32963ab9afeSSatoshi Sahara 33063ab9afeSSatoshi Sahara} 331