1<?php 2 3namespace dokuwiki\Ui; 4 5use dokuwiki\ChangeLog\MediaChangeLog; 6use dokuwiki\Extension\Event; 7use dokuwiki\Form\Form; 8 9/** 10 * DokuWiki MediaDiff Interface 11 * 12 * @package dokuwiki\Ui 13 */ 14class MediaDiff extends Diff 15{ 16 /* @var string */ 17 protected $id; 18 19 /** 20 * MediaDiff Ui constructor 21 * 22 * @param string $id media id 23 */ 24 public function __construct($id) 25 { 26 $this->id = $id; 27 28 $this->preference['fromAjax'] = false; // see doluwiki\Ajax::callMediadiff() 29 $this->preference['showIntro'] = false; 30 $this->preference['difftype'] = null; // both, opacity or portions. see lib/scripts/media.js 31 } 32 33 /** 34 * Shows difference between two revisions of media 35 */ 36 public function show() 37 { 38 $ns = getNS($this->id); 39 $auth = auth_quickaclcheck("$ns:*"); 40 $this->media_diff($this->id, $ns, $auth, $this->preference['fromAjax']); 41 } 42 43 /** 44 * Shows difference between two revisions of file 45 * 46 * @author Kate Arzamastseva <pshns@ukr.net> 47 * 48 * @param string $image image id 49 * @param string $ns 50 * @param int $auth permission level 51 * @param bool $fromajax 52 * @return false|null|string 53 */ 54 protected function media_diff($image, $ns, $auth, $fromajax = false) 55 { 56 global $conf; 57 global $INPUT; 58 59 if ($auth < AUTH_READ || !$image || !$conf['mediarevisions']) return ''; 60 61 $rev1 = $INPUT->int('rev'); 62 63 $rev2 = $INPUT->ref('rev2'); 64 if (is_array($rev2)) { 65 $rev1 = (int) $rev2[0]; 66 $rev2 = (int) $rev2[1]; 67 68 if (!$rev1) { 69 $rev1 = $rev2; 70 unset($rev2); 71 } 72 } else { 73 $rev2 = $INPUT->int('rev2'); 74 } 75 76 if ($rev1 && !file_exists(mediaFN($image, $rev1))) $rev1 = false; 77 if ($rev2 && !file_exists(mediaFN($image, $rev2))) $rev2 = false; 78 79 if ($rev1 && $rev2) { // two specific revisions wanted 80 // make sure order is correct (older on the left) 81 if ($rev1 < $rev2) { 82 $l_rev = $rev1; 83 $r_rev = $rev2; 84 } else { 85 $l_rev = $rev2; 86 $r_rev = $rev1; 87 } 88 } elseif ($rev1) { // single revision given, compare to current 89 $r_rev = ''; 90 $l_rev = $rev1; 91 } else { // no revision was given, compare previous to current 92 $r_rev = ''; 93 $medialog = new MediaChangeLog($image); 94 $revs = $medialog->getRevisions(0, 1); 95 if (file_exists(mediaFN($image, $revs[0]))) { 96 $l_rev = $revs[0]; 97 } else { 98 $l_rev = ''; 99 } 100 } 101 102 // prepare event data 103 $data = array(); 104 $data[0] = $image; 105 $data[1] = $l_rev; 106 $data[2] = $r_rev; 107 $data[3] = $ns; 108 $data[4] = $auth; 109 $data[5] = $fromajax; 110 111 // trigger event 112 return Event::createAndTrigger('MEDIA_DIFF', $data, [$this,'_media_file_diff'], true); 113 } 114 115 /** 116 * Callback for media file diff 117 * 118 * @param array $data event data 119 * @return false|null 120 */ 121 public function _media_file_diff($data) 122 { 123 if (is_array($data) && count($data) === 6) { 124 $this->media_file_diff($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); 125 } else { 126 return false; 127 } 128 } 129 130 /** 131 * Shows difference between two revisions of image 132 * 133 * @author Kate Arzamastseva <pshns@ukr.net> 134 * 135 * @param string $image 136 * @param string|int $l_rev revision timestamp, or empty string 137 * @param string|int $r_rev revision timestamp, or empty string 138 * @param string $ns 139 * @param int $auth permission level 140 * @param bool $fromajax 141 */ 142 protected function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax) 143 { 144 global $lang; 145 global $INPUT; 146 147 $l_meta = new \JpegMeta(mediaFN($image, $l_rev)); 148 $r_meta = new \JpegMeta(mediaFN($image, $r_rev)); 149 150 $is_img = preg_match('/\.(jpe?g|gif|png)$/', $image); 151 if ($is_img) { 152 $l_size = media_image_preview_size($image, $l_rev, $l_meta); 153 $r_size = media_image_preview_size($image, $r_rev, $r_meta); 154 $is_img = ($l_size && $r_size && ($l_size[0] >= 30 || $r_size[0] >= 30)); 155 156 $difftype = $INPUT->str('difftype'); 157 158 if (!$fromajax) { 159 $form = new Form([ 160 'id' => 'mediamanager__form_diffview', 161 'action' => media_managerURL([], '&'), 162 'method' => 'get', 163 'class' => 'diffView', 164 ]); 165 $form->addTagOpen('div')->addClass('no'); 166 $form->setHiddenField('sectok', null); 167 $form->setHiddenField('mediado', 'diff'); 168 $form->setHiddenField('rev2[0]', $l_rev); 169 $form->setHiddenField('rev2[1]', $r_rev); 170 $form->addTagClose('div'); 171 echo $form->toHTML(); 172 173 echo NL.'<div id="mediamanager__diff" >'.NL; 174 } 175 176 if ($difftype == 'opacity' || $difftype == 'portions') { 177 $this->media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $difftype); 178 if (!$fromajax) echo '</div>'; 179 return; 180 } 181 } 182 183 $medialog = new MediaChangeLog($image); 184 185 list($l_head, $r_head) = $this->diffHead($medialog, $l_rev, $r_rev); 186 187 echo '<div class="table">'; 188 echo '<table>'; 189 echo '<tr>'; 190 echo '<th>'. $l_head .'</th>'; 191 echo '<th>'. $r_head .'</th>'; 192 echo '</tr>'.NL; 193 194 echo '<tr class="image">'; 195 echo '<td>'; 196 media_preview($image, $auth, $l_rev, $l_meta); 197 echo '</td>'; 198 199 echo '<td>'; 200 media_preview($image, $auth, $r_rev, $r_meta); 201 echo '</td>'; 202 echo '</tr>'.NL; 203 204 echo '<tr class="actions">'; 205 echo '<td>'; 206 media_preview_buttons($image, $auth, $l_rev); 207 echo '</td>'; 208 209 echo '<td>'; 210 media_preview_buttons($image, $auth, $r_rev); 211 echo '</td>'; 212 echo '</tr>'.NL; 213 214 $l_tags = media_file_tags($l_meta); 215 $r_tags = media_file_tags($r_meta); 216 // FIXME r_tags-only stuff 217 foreach ($l_tags as $key => $l_tag) { 218 if ($l_tag['value'] != $r_tags[$key]['value']) { 219 $r_tags[$key]['highlighted'] = true; 220 $l_tags[$key]['highlighted'] = true; 221 } elseif (!$l_tag['value'] || !$r_tags[$key]['value']) { 222 unset($r_tags[$key]); 223 unset($l_tags[$key]); 224 } 225 } 226 227 echo '<tr>'; 228 foreach (array($l_tags, $r_tags) as $tags) { 229 echo '<td>'.NL; 230 231 echo '<dl class="img_tags">'; 232 foreach ($tags as $tag) { 233 $value = cleanText($tag['value']); 234 if (!$value) $value = '-'; 235 echo '<dt>'.$lang[$tag['tag'][1]].'</dt>'; 236 echo '<dd>'; 237 if ($tag['highlighted']) echo '<strong>'; 238 if ($tag['tag'][2] == 'date') { 239 echo dformat($value); 240 } else { 241 echo hsc($value); 242 } 243 if ($tag['highlighted']) echo '</strong>'; 244 echo '</dd>'; 245 } 246 echo '</dl>'.NL; 247 248 echo '</td>'; 249 } 250 echo '</tr>'.NL; 251 252 echo '</table>'.NL; 253 echo '</div>'.NL; 254 255 if ($is_img && !$fromajax) echo '</div>'; 256 } 257 258 /** 259 * Prints two images side by side 260 * and slider 261 * 262 * @author Kate Arzamastseva <pshns@ukr.net> 263 * 264 * @param string $image image id 265 * @param int $l_rev revision timestamp, or empty string 266 * @param int $r_rev revision timestamp, or empty string 267 * @param array $l_size array with width and height 268 * @param array $r_size array with width and height 269 * @param string $type 270 */ 271 protected function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) 272 { 273 if ($l_size != $r_size) { 274 if ($r_size[0] > $l_size[0]) { 275 $l_size = $r_size; 276 } 277 } 278 279 $l_more = array('rev' => $l_rev, 'h' => $l_size[1], 'w' => $l_size[0]); 280 $r_more = array('rev' => $r_rev, 'h' => $l_size[1], 'w' => $l_size[0]); 281 282 $l_src = ml($image, $l_more); 283 $r_src = ml($image, $r_more); 284 285 // slider 286 echo '<div class="slider" style="max-width: '.($l_size[0]-20).'px;" ></div>'.NL; 287 288 // two images in divs 289 echo '<div class="imageDiff '.$type.'">'.NL; 290 echo '<div class="image1" style="max-width: '.$l_size[0].'px;">'; 291 echo '<img src="'.$l_src.'" alt="" />'; 292 echo '</div>'.NL; 293 echo '<div class="image2" style="max-width: '.$l_size[0].'px;">'; 294 echo '<img src="'.$r_src.'" alt="" />'; 295 echo '</div>'.NL; 296 echo '</div>'.NL; 297 } 298 299} 300