163ab9afeSSatoshi Sahara<?php 263ab9afeSSatoshi Sahara 363ab9afeSSatoshi Saharanamespace dokuwiki\Ui; 463ab9afeSSatoshi Sahara 563ab9afeSSatoshi Saharause dokuwiki\ChangeLog\MediaChangeLog; 663ab9afeSSatoshi Saharause dokuwiki\Extension\Event; 763ab9afeSSatoshi Saharause dokuwiki\Form\Form; 863ab9afeSSatoshi Sahara 963ab9afeSSatoshi Sahara/** 1063ab9afeSSatoshi Sahara * DokuWiki MediaDiff Interface 1163ab9afeSSatoshi Sahara * 1263ab9afeSSatoshi Sahara * @package dokuwiki\Ui 1363ab9afeSSatoshi Sahara */ 1463ab9afeSSatoshi Saharaclass MediaDiff extends Diff 1563ab9afeSSatoshi Sahara{ 1663ab9afeSSatoshi Sahara /* @var string */ 1763ab9afeSSatoshi Sahara protected $id; 1863ab9afeSSatoshi Sahara 1963ab9afeSSatoshi Sahara /** 2063ab9afeSSatoshi Sahara * MediaDiff Ui constructor 2163ab9afeSSatoshi Sahara * 22edb50e6aSSatoshi Sahara * @param string $id media id 2363ab9afeSSatoshi Sahara */ 24edb50e6aSSatoshi Sahara public function __construct($id) 2563ab9afeSSatoshi Sahara { 2663ab9afeSSatoshi Sahara $this->id = $id; 27edb50e6aSSatoshi Sahara 28edb50e6aSSatoshi Sahara $this->preference['fromAjax'] = false; // see doluwiki\Ajax::callMediadiff() 29edb50e6aSSatoshi Sahara $this->preference['showIntro'] = false; 30*675f74fbSSatoshi Sahara $this->preference['difftype'] = null; // both, opacity or portions. 3163ab9afeSSatoshi Sahara } 3263ab9afeSSatoshi Sahara 3363ab9afeSSatoshi Sahara /** 3463ab9afeSSatoshi Sahara * Shows difference between two revisions of media 35*675f74fbSSatoshi Sahara * 36*675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 37*675f74fbSSatoshi Sahara * @param string $difftype diff view type for media (both, opacity or portions) 3863ab9afeSSatoshi Sahara */ 39*675f74fbSSatoshi Sahara public function show($difftype = null) 4063ab9afeSSatoshi Sahara { 41*675f74fbSSatoshi Sahara global $conf; 42*675f74fbSSatoshi Sahara 4363ab9afeSSatoshi Sahara $ns = getNS($this->id); 4463ab9afeSSatoshi Sahara $auth = auth_quickaclcheck("$ns:*"); 45*675f74fbSSatoshi Sahara 46*675f74fbSSatoshi Sahara if ($auth < AUTH_READ || !$this->id || !$conf['mediarevisions']) return ''; 47*675f74fbSSatoshi Sahara 48*675f74fbSSatoshi Sahara // determine left and right revision 49*675f74fbSSatoshi Sahara list($l_rev, $r_rev) = $this->getRevisionPair(); 50*675f74fbSSatoshi Sahara 51*675f74fbSSatoshi Sahara // prepare event data 52*675f74fbSSatoshi Sahara // NOTE: MEDIA_DIFF event does not found in DokuWiki Event List? 53*675f74fbSSatoshi Sahara $data = array(); 54*675f74fbSSatoshi Sahara $data[0] = $this->id; 55*675f74fbSSatoshi Sahara $data[1] = $l_rev; 56*675f74fbSSatoshi Sahara $data[2] = $r_rev; 57*675f74fbSSatoshi Sahara $data[3] = $ns; 58*675f74fbSSatoshi Sahara $data[4] = $auth; // permission level 59*675f74fbSSatoshi Sahara $data[5] = $this->preference['fromAjax']; 60*675f74fbSSatoshi Sahara 61*675f74fbSSatoshi Sahara // trigger event 62*675f74fbSSatoshi Sahara Event::createAndTrigger('MEDIA_DIFF', $data, null, false); 63*675f74fbSSatoshi Sahara 64*675f74fbSSatoshi Sahara if (is_array($data) && count($data) === 6) { 65*675f74fbSSatoshi Sahara $this->id = $data[0]; 66*675f74fbSSatoshi Sahara $l_rev = $data[1]; 67*675f74fbSSatoshi Sahara $r_rev = $data[2]; 68*675f74fbSSatoshi Sahara $ns = $data[3]; 69*675f74fbSSatoshi Sahara $auth = $data[4]; 70*675f74fbSSatoshi Sahara $this->preference['fromAjax'] = $data[5]; 71*675f74fbSSatoshi Sahara } else { 72*675f74fbSSatoshi Sahara return ''; 73*675f74fbSSatoshi Sahara } 74*675f74fbSSatoshi Sahara 75*675f74fbSSatoshi Sahara $l_meta = new \JpegMeta(mediaFN($this->id, $l_rev)); 76*675f74fbSSatoshi Sahara $r_meta = new \JpegMeta(mediaFN($this->id, $r_rev)); 77*675f74fbSSatoshi Sahara 78*675f74fbSSatoshi Sahara $is_img = preg_match('/\.(jpe?g|gif|png)$/', $this->id); 79*675f74fbSSatoshi Sahara if ($is_img) { 80*675f74fbSSatoshi Sahara // get image width and height for the mediamanager preview panel 81*675f74fbSSatoshi Sahara $l_size = media_image_preview_size($this->id, $l_rev, $l_meta); 82*675f74fbSSatoshi Sahara $r_size = media_image_preview_size($this->id, $r_rev, $r_meta); 83*675f74fbSSatoshi Sahara // re-check image, ensure minimum image width for showImageDiff() 84*675f74fbSSatoshi Sahara $is_img = ($l_size && $r_size && ($l_size[0] >= 30 || $r_size[0] >= 30)); 85*675f74fbSSatoshi Sahara } 86*675f74fbSSatoshi Sahara 87*675f74fbSSatoshi Sahara // determine requested diff view type 88*675f74fbSSatoshi Sahara $difftype = $this->getDiffType($difftype); 89*675f74fbSSatoshi Sahara 90*675f74fbSSatoshi Sahara // display intro 91*675f74fbSSatoshi Sahara if ($this->preference['showIntro']) echo p_locale_xhtml('diff'); 92*675f74fbSSatoshi Sahara 93*675f74fbSSatoshi Sahara // print form to choose diff view type 94*675f74fbSSatoshi Sahara if ($is_img && !$this->preference['fromAjax']) { 95*675f74fbSSatoshi Sahara $this->showDiffViewSelector($l_rev, $r_rev); 96*675f74fbSSatoshi Sahara echo '<div id="mediamanager__diff" >'; 97*675f74fbSSatoshi Sahara } 98*675f74fbSSatoshi Sahara 99*675f74fbSSatoshi Sahara if ($is_img) { 100*675f74fbSSatoshi Sahara switch ($difftype) { 101*675f74fbSSatoshi Sahara case 'opacity': 102*675f74fbSSatoshi Sahara case 'portions': 103*675f74fbSSatoshi Sahara $this->showImageDiff($l_rev, $r_rev, $l_size, $r_size, $difftype); 104*675f74fbSSatoshi Sahara break; 105*675f74fbSSatoshi Sahara case 'both': 106*675f74fbSSatoshi Sahara default: 107*675f74fbSSatoshi Sahara $this->showFileDiff($l_rev, $r_rev, $l_meta, $r_meta, $auth); 108*675f74fbSSatoshi Sahara break; 109*675f74fbSSatoshi Sahara } 110*675f74fbSSatoshi Sahara } else { 111*675f74fbSSatoshi Sahara $this->showFileDiff($l_rev, $r_rev, $l_meta, $r_meta, $auth); 112*675f74fbSSatoshi Sahara } 113*675f74fbSSatoshi Sahara 114*675f74fbSSatoshi Sahara if ($is_img && !$this->preference['fromAjax']) { 115*675f74fbSSatoshi Sahara echo '</div>'; 116*675f74fbSSatoshi Sahara } 1172db397b2SSatoshi Sahara } 1182db397b2SSatoshi Sahara 1192db397b2SSatoshi Sahara /** 120*675f74fbSSatoshi Sahara * Determine requested diff view type for media 1212db397b2SSatoshi Sahara * 122*675f74fbSSatoshi Sahara * @param string $mode diff view type (both, opacity or portions) 123*675f74fbSSatoshi Sahara * @return string 1242db397b2SSatoshi Sahara */ 125*675f74fbSSatoshi Sahara protected function getDiffType($mode = null) 1262db397b2SSatoshi Sahara { 1272db397b2SSatoshi Sahara global $INPUT; 128*675f74fbSSatoshi Sahara $difftype =& $this->preference['difftype']; 1292db397b2SSatoshi Sahara 130*675f74fbSSatoshi Sahara if (!isset($mode)) { 131*675f74fbSSatoshi Sahara $difftype = $INPUT->str('difftype'); 132*675f74fbSSatoshi Sahara } elseif (in_array($mode, ['both', 'opacity', 'portions'])) { 133*675f74fbSSatoshi Sahara $difftype = $mode; 134*675f74fbSSatoshi Sahara } 135*675f74fbSSatoshi Sahara return $this->preference['difftype']; 136*675f74fbSSatoshi Sahara } 137*675f74fbSSatoshi Sahara 138*675f74fbSSatoshi Sahara /** 139*675f74fbSSatoshi Sahara * Determine requested revision(s) 140*675f74fbSSatoshi Sahara * 141*675f74fbSSatoshi Sahara * @return array 142*675f74fbSSatoshi Sahara */ 143*675f74fbSSatoshi Sahara protected function getRevisions() 144*675f74fbSSatoshi Sahara { 145*675f74fbSSatoshi Sahara global $INPUT; 1462db397b2SSatoshi Sahara 1472db397b2SSatoshi Sahara $rev1 = $INPUT->int('rev'); 1482db397b2SSatoshi Sahara 1492db397b2SSatoshi Sahara $rev2 = $INPUT->ref('rev2'); 1502db397b2SSatoshi Sahara if (is_array($rev2)) { 1512db397b2SSatoshi Sahara $rev1 = (int) $rev2[0]; 1522db397b2SSatoshi Sahara $rev2 = (int) $rev2[1]; 1532db397b2SSatoshi Sahara 1542db397b2SSatoshi Sahara if (!$rev1) { 1552db397b2SSatoshi Sahara $rev1 = $rev2; 156*675f74fbSSatoshi Sahara $rev2 = null; 1572db397b2SSatoshi Sahara } 1582db397b2SSatoshi Sahara } else { 1592db397b2SSatoshi Sahara $rev2 = $INPUT->int('rev2'); 1602db397b2SSatoshi Sahara } 161*675f74fbSSatoshi Sahara return array($rev1, $rev2); 162*675f74fbSSatoshi Sahara } 1632db397b2SSatoshi Sahara 164*675f74fbSSatoshi Sahara /** 165*675f74fbSSatoshi Sahara * Determine left and right revision 166*675f74fbSSatoshi Sahara * 167*675f74fbSSatoshi Sahara * @return array 168*675f74fbSSatoshi Sahara */ 169*675f74fbSSatoshi Sahara protected function getRevisionPair() 170*675f74fbSSatoshi Sahara { 171*675f74fbSSatoshi Sahara // determine requested revision(s) 172*675f74fbSSatoshi Sahara list($rev1, $rev2) = $this->getRevisions(); 173*675f74fbSSatoshi Sahara 174*675f74fbSSatoshi Sahara if ($rev1 && !file_exists(mediaFN($this->id, $rev1))) $rev1 = false; 175*675f74fbSSatoshi Sahara if ($rev2 && !file_exists(mediaFN($this->id, $rev2))) $rev2 = false; 1762db397b2SSatoshi Sahara 1772db397b2SSatoshi Sahara if ($rev1 && $rev2) { // two specific revisions wanted 1782db397b2SSatoshi Sahara // make sure order is correct (older on the left) 1792db397b2SSatoshi Sahara if ($rev1 < $rev2) { 1802db397b2SSatoshi Sahara $l_rev = $rev1; 1812db397b2SSatoshi Sahara $r_rev = $rev2; 1822db397b2SSatoshi Sahara } else { 1832db397b2SSatoshi Sahara $l_rev = $rev2; 1842db397b2SSatoshi Sahara $r_rev = $rev1; 1852db397b2SSatoshi Sahara } 1862db397b2SSatoshi Sahara } elseif ($rev1) { // single revision given, compare to current 1872db397b2SSatoshi Sahara $r_rev = ''; 1882db397b2SSatoshi Sahara $l_rev = $rev1; 1892db397b2SSatoshi Sahara } else { // no revision was given, compare previous to current 1902db397b2SSatoshi Sahara $r_rev = ''; 191*675f74fbSSatoshi Sahara $medialog = new MediaChangeLog($this->id); 1922db397b2SSatoshi Sahara $revs = $medialog->getRevisions(0, 1); 193*675f74fbSSatoshi Sahara if (file_exists(mediaFN($this->id, $revs[0]))) { 1942db397b2SSatoshi Sahara $l_rev = $revs[0]; 1952db397b2SSatoshi Sahara } else { 1962db397b2SSatoshi Sahara $l_rev = ''; 1972db397b2SSatoshi Sahara } 1982db397b2SSatoshi Sahara } 199*675f74fbSSatoshi Sahara return array($l_rev, $r_rev); 2002db397b2SSatoshi Sahara } 2012db397b2SSatoshi Sahara 2022db397b2SSatoshi Sahara /** 203*675f74fbSSatoshi Sahara * Print form to choose diff view type 204*675f74fbSSatoshi Sahara * the dropdown is to be added through JavaScript, see lib/scripts/media.js 2052db397b2SSatoshi Sahara * 206*675f74fbSSatoshi Sahara * @param int $l_rev revision timestamp of left side 207*675f74fbSSatoshi Sahara * @param int $r_rev revision timestamp of right side 2082db397b2SSatoshi Sahara */ 209*675f74fbSSatoshi Sahara protected function showDiffViewSelector($l_rev, $r_rev) 2102db397b2SSatoshi Sahara { 2112db397b2SSatoshi Sahara $form = new Form([ 2122db397b2SSatoshi Sahara 'id' => 'mediamanager__form_diffview', 2132db397b2SSatoshi Sahara 'action' => media_managerURL([], '&'), 2142db397b2SSatoshi Sahara 'method' => 'get', 2152db397b2SSatoshi Sahara 'class' => 'diffView', 2162db397b2SSatoshi Sahara ]); 2172db397b2SSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 2182db397b2SSatoshi Sahara $form->setHiddenField('sectok', null); 2192db397b2SSatoshi Sahara $form->setHiddenField('mediado', 'diff'); 2202db397b2SSatoshi Sahara $form->setHiddenField('rev2[0]', $l_rev); 2212db397b2SSatoshi Sahara $form->setHiddenField('rev2[1]', $r_rev); 2222db397b2SSatoshi Sahara $form->addTagClose('div'); 2232db397b2SSatoshi Sahara echo $form->toHTML(); 2242db397b2SSatoshi Sahara } 2252db397b2SSatoshi Sahara 226*675f74fbSSatoshi Sahara /** 227*675f74fbSSatoshi Sahara * Prints two images side by side 228*675f74fbSSatoshi Sahara * and slider 229*675f74fbSSatoshi Sahara * 230*675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 231*675f74fbSSatoshi Sahara * 232*675f74fbSSatoshi Sahara * @param int $l_rev revision timestamp, or empty string 233*675f74fbSSatoshi Sahara * @param int $r_rev revision timestamp, or empty string 234*675f74fbSSatoshi Sahara * @param array $l_size array with width and height 235*675f74fbSSatoshi Sahara * @param array $r_size array with width and height 236*675f74fbSSatoshi Sahara * @param string $type diff type: opacity or portions 237*675f74fbSSatoshi Sahara */ 238*675f74fbSSatoshi Sahara protected function showImageDiff($l_rev, $r_rev, $l_size, $r_size, $type = null) 239*675f74fbSSatoshi Sahara { 240*675f74fbSSatoshi Sahara if (!isset($type)) { 241*675f74fbSSatoshi Sahara $type = $this->preference['difftype']; 242*675f74fbSSatoshi Sahara } 243*675f74fbSSatoshi Sahara 244*675f74fbSSatoshi Sahara // adjust image width, right side (newer) has priority 245*675f74fbSSatoshi Sahara if ($l_size != $r_size) { 246*675f74fbSSatoshi Sahara if ($r_size[0] > $l_size[0]) { 247*675f74fbSSatoshi Sahara $l_size = $r_size; 2482db397b2SSatoshi Sahara } 2492db397b2SSatoshi Sahara } 2502db397b2SSatoshi Sahara 251*675f74fbSSatoshi Sahara $l_src = ml($this->id, ['rev' => $l_rev, 'h' => $l_size[1], 'w' => $l_size[0]]); 252*675f74fbSSatoshi Sahara $r_src = ml($this->id, ['rev' => $r_rev, 'h' => $l_size[1], 'w' => $l_size[0]]); 253*675f74fbSSatoshi Sahara 254*675f74fbSSatoshi Sahara // slider 255*675f74fbSSatoshi Sahara echo '<div class="slider" style="max-width: '.($l_size[0]-20).'px;" ></div>'; 256*675f74fbSSatoshi Sahara 257*675f74fbSSatoshi Sahara // two images in divs 258*675f74fbSSatoshi Sahara echo '<div class="imageDiff '.$type.'">'; 259*675f74fbSSatoshi Sahara echo '<div class="image1" style="max-width: '.$l_size[0].'px;">'; 260*675f74fbSSatoshi Sahara echo '<img src="'.$l_src.'" alt="" />'; 261*675f74fbSSatoshi Sahara echo '</div>'; 262*675f74fbSSatoshi Sahara echo '<div class="image2" style="max-width: '.$l_size[0].'px;">'; 263*675f74fbSSatoshi Sahara echo '<img src="'.$r_src.'" alt="" />'; 264*675f74fbSSatoshi Sahara echo '</div>'; 265*675f74fbSSatoshi Sahara echo '</div>'; 266*675f74fbSSatoshi Sahara } 267*675f74fbSSatoshi Sahara 268*675f74fbSSatoshi Sahara /** 269*675f74fbSSatoshi Sahara * Shows difference between two revisions of media file 270*675f74fbSSatoshi Sahara * 271*675f74fbSSatoshi Sahara * @author Kate Arzamastseva <pshns@ukr.net> 272*675f74fbSSatoshi Sahara * 273*675f74fbSSatoshi Sahara * @param string|int $l_rev revision timestamp, or empty string 274*675f74fbSSatoshi Sahara * @param string|int $r_rev revision timestamp, or empty string 275*675f74fbSSatoshi Sahara * @param JpegMeta $l_meta 276*675f74fbSSatoshi Sahara * @param JpegMeta $r_meta 277*675f74fbSSatoshi Sahara * @param int $auth permission level 278*675f74fbSSatoshi Sahara */ 279*675f74fbSSatoshi Sahara protected function showFileDiff($l_rev, $r_rev, $l_meta, $r_meta, $auth) 280*675f74fbSSatoshi Sahara { 281*675f74fbSSatoshi Sahara $medialog = new MediaChangeLog($this->id); 2822db397b2SSatoshi Sahara 2832db397b2SSatoshi Sahara list($l_head, $r_head) = $this->diffHead($medialog, $l_rev, $r_rev); 2842db397b2SSatoshi Sahara 2852db397b2SSatoshi Sahara echo '<div class="table">'; 2862db397b2SSatoshi Sahara echo '<table>'; 2872db397b2SSatoshi Sahara echo '<tr>'; 2882db397b2SSatoshi Sahara echo '<th>'. $l_head .'</th>'; 2892db397b2SSatoshi Sahara echo '<th>'. $r_head .'</th>'; 290*675f74fbSSatoshi Sahara echo '</tr>'; 2912db397b2SSatoshi Sahara 2922db397b2SSatoshi Sahara echo '<tr class="image">'; 2932db397b2SSatoshi Sahara echo '<td>'; 294*675f74fbSSatoshi Sahara media_preview($this->id, $auth, $l_rev, $l_meta); // $auth not used in media_preview()? 2952db397b2SSatoshi Sahara echo '</td>'; 2962db397b2SSatoshi Sahara 2972db397b2SSatoshi Sahara echo '<td>'; 298*675f74fbSSatoshi Sahara media_preview($this->id, $auth, $r_rev, $r_meta); 2992db397b2SSatoshi Sahara echo '</td>'; 300*675f74fbSSatoshi Sahara echo '</tr>'; 3012db397b2SSatoshi Sahara 3022db397b2SSatoshi Sahara echo '<tr class="actions">'; 3032db397b2SSatoshi Sahara echo '<td>'; 304*675f74fbSSatoshi Sahara media_preview_buttons($this->id, $auth, $l_rev); // $auth used in media_preview_buttons() 3052db397b2SSatoshi Sahara echo '</td>'; 3062db397b2SSatoshi Sahara 3072db397b2SSatoshi Sahara echo '<td>'; 308*675f74fbSSatoshi Sahara media_preview_buttons($this->id, $auth, $r_rev); 3092db397b2SSatoshi Sahara echo '</td>'; 310*675f74fbSSatoshi Sahara echo '</tr>'; 3112db397b2SSatoshi Sahara 3122db397b2SSatoshi Sahara $l_tags = media_file_tags($l_meta); 3132db397b2SSatoshi Sahara $r_tags = media_file_tags($r_meta); 3142db397b2SSatoshi Sahara // FIXME r_tags-only stuff 3152db397b2SSatoshi Sahara foreach ($l_tags as $key => $l_tag) { 3162db397b2SSatoshi Sahara if ($l_tag['value'] != $r_tags[$key]['value']) { 3172db397b2SSatoshi Sahara $r_tags[$key]['highlighted'] = true; 3182db397b2SSatoshi Sahara $l_tags[$key]['highlighted'] = true; 3192db397b2SSatoshi Sahara } elseif (!$l_tag['value'] || !$r_tags[$key]['value']) { 3202db397b2SSatoshi Sahara unset($r_tags[$key]); 3212db397b2SSatoshi Sahara unset($l_tags[$key]); 3222db397b2SSatoshi Sahara } 3232db397b2SSatoshi Sahara } 3242db397b2SSatoshi Sahara 3252db397b2SSatoshi Sahara echo '<tr>'; 3262db397b2SSatoshi Sahara foreach (array($l_tags, $r_tags) as $tags) { 327*675f74fbSSatoshi Sahara echo '<td>'; 3282db397b2SSatoshi Sahara 3292db397b2SSatoshi Sahara echo '<dl class="img_tags">'; 3302db397b2SSatoshi Sahara foreach ($tags as $tag) { 3312db397b2SSatoshi Sahara $value = cleanText($tag['value']); 3322db397b2SSatoshi Sahara if (!$value) $value = '-'; 3332db397b2SSatoshi Sahara echo '<dt>'.$lang[$tag['tag'][1]].'</dt>'; 3342db397b2SSatoshi Sahara echo '<dd>'; 3352db397b2SSatoshi Sahara if ($tag['highlighted']) echo '<strong>'; 3362db397b2SSatoshi Sahara if ($tag['tag'][2] == 'date') { 3372db397b2SSatoshi Sahara echo dformat($value); 3382db397b2SSatoshi Sahara } else { 3392db397b2SSatoshi Sahara echo hsc($value); 3402db397b2SSatoshi Sahara } 3412db397b2SSatoshi Sahara if ($tag['highlighted']) echo '</strong>'; 3422db397b2SSatoshi Sahara echo '</dd>'; 3432db397b2SSatoshi Sahara } 344*675f74fbSSatoshi Sahara echo '</dl>'; 3452db397b2SSatoshi Sahara 3462db397b2SSatoshi Sahara echo '</td>'; 3472db397b2SSatoshi Sahara } 348*675f74fbSSatoshi Sahara echo '</tr>'; 3492db397b2SSatoshi Sahara 350*675f74fbSSatoshi Sahara echo '</table>'; 351*675f74fbSSatoshi Sahara echo '</div>'; 35263ab9afeSSatoshi Sahara } 35363ab9afeSSatoshi Sahara 35463ab9afeSSatoshi Sahara} 355