[ Index ] |
PHP Cross Reference of DokuWiki |
[Summary view] [Print] [Text view]
1 <?php 2 3 namespace dokuwiki\Ui; 4 5 use dokuwiki\ChangeLog\MediaChangeLog; 6 use dokuwiki\ChangeLog\RevisionInfo; 7 use dokuwiki\Form\Form; 8 use InvalidArgumentException; 9 use JpegMeta; 10 11 /** 12 * DokuWiki MediaDiff Interface 13 * 14 * @package dokuwiki\Ui 15 */ 16 class MediaDiff extends Diff 17 { 18 /* @var MediaChangeLog */ 19 protected $changelog; 20 21 /* @var RevisionInfo older revision */ 22 protected $RevInfo1; 23 /* @var RevisionInfo newer revision */ 24 protected $RevInfo2; 25 26 /* @var bool */ 27 protected $is_img; 28 29 /** 30 * MediaDiff Ui constructor 31 * 32 * @param string $id media id 33 */ 34 public function __construct($id) 35 { 36 if (!isset($id)) { 37 throw new InvalidArgumentException('media id should not be empty!'); 38 } 39 40 // init preference 41 $this->preference['fromAjax'] = false; // see dokuwiki\Ajax::callMediadiff() 42 $this->preference['showIntro'] = false; 43 $this->preference['difftype'] = 'both'; // diff view type: both, opacity or portions 44 45 parent::__construct($id); 46 } 47 48 /** @inheritdoc */ 49 protected function setChangeLog() 50 { 51 $this->changelog = new MediaChangeLog($this->id); 52 } 53 54 /** 55 * Handle requested revision(s) and diff view preferences 56 * 57 * @return void 58 */ 59 protected function handle() 60 { 61 global $INPUT; 62 63 // retrieve requested rev or rev2 64 parent::handle(); 65 66 // requested diff view type 67 if ($INPUT->has('difftype')) { 68 $this->preference['difftype'] = $INPUT->str('difftype'); 69 } 70 } 71 72 /** 73 * Prepare revision info of comparison pair 74 */ 75 protected function preProcess() 76 { 77 $changelog =& $this->changelog; 78 79 // create revision info object for older and newer sides 80 // RevInfo1 : older, left side 81 // RevInfo2 : newer, right side 82 83 $changelogRev1 = $changelog->getRevisionInfo($this->rev1); 84 $changelogRev2 = $changelog->getRevisionInfo($this->rev2); 85 $changelogRev1['media'] = $changelogRev2['media'] = true; 86 87 $this->RevInfo1 = new RevisionInfo($changelogRev1); 88 $this->RevInfo2 = new RevisionInfo($changelogRev2); 89 90 $this->is_img = preg_match('/\.(jpe?g|gif|png)$/', $this->id); 91 92 foreach ([$this->RevInfo1, $this->RevInfo2] as $RevInfo) { 93 $isCurrent = $changelog->isCurrentRevision($RevInfo->val('date')); 94 $RevInfo->isCurrent($isCurrent); 95 96 if ($this->is_img) { 97 $rev = $isCurrent ? '' : $RevInfo->val('date'); 98 $meta = new JpegMeta(mediaFN($this->id, $rev)); 99 // get image width and height for the media manager preview panel 100 $RevInfo->append([ 101 'previewSize' => media_image_preview_size($this->id, $rev, $meta) 102 ]); 103 } 104 } 105 106 // re-check image, ensure minimum image width for showImageDiff() 107 $this->is_img = ($this->is_img 108 && ($this->RevInfo1->val('previewSize')[0] ?? 0) >= 30 109 && ($this->RevInfo2->val('previewSize')[0] ?? 0) >= 30 110 ); 111 // adjust requested diff view type 112 if (!$this->is_img) { 113 $this->preference['difftype'] = 'both'; 114 } 115 } 116 117 118 /** 119 * Shows difference between two revisions of media 120 * 121 * @author Kate Arzamastseva <pshns@ukr.net> 122 */ 123 public function show() 124 { 125 global $conf; 126 127 $ns = getNS($this->id); 128 $auth = auth_quickaclcheck("$ns:*"); 129 130 if ($auth < AUTH_READ || !$this->id || !$conf['mediarevisions']) return; 131 132 // retrieve form parameters: rev, rev2, difftype 133 $this->handle(); 134 // prepare revision info of comparison pair 135 $this->preProcess(); 136 137 // display intro 138 if ($this->preference['showIntro']) echo p_locale_xhtml('diff'); 139 140 // print form to choose diff view type 141 if ($this->is_img && !$this->preference['fromAjax']) { 142 $this->showDiffViewSelector(); 143 echo '<div id="mediamanager__diff" >'; 144 } 145 146 switch ($this->preference['difftype']) { 147 case 'opacity': 148 case 'portions': 149 $this->showImageDiff(); 150 break; 151 case 'both': 152 default: 153 $this->showFileDiff(); 154 break; 155 } 156 157 if ($this->is_img && !$this->preference['fromAjax']) { 158 echo '</div>'; 159 } 160 } 161 162 /** 163 * Print form to choose diff view type 164 * the dropdown is to be added through JavaScript, see lib/scripts/media.js 165 */ 166 protected function showDiffViewSelector() 167 { 168 // use timestamp for current revision, date may be false when revisions < 2 169 [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')]; 170 171 echo '<div class="diffoptions group">'; 172 173 $form = new Form([ 174 'id' => 'mediamanager__form_diffview', 175 'action' => media_managerURL([], '&'), 176 'method' => 'get', 177 'class' => 'diffView', 178 ]); 179 $form->addTagOpen('div')->addClass('no'); 180 $form->setHiddenField('sectok', null); 181 $form->setHiddenField('mediado', 'diff'); 182 $form->setHiddenField('rev2[0]', $rev1); 183 $form->setHiddenField('rev2[1]', $rev2); 184 $form->addTagClose('div'); 185 echo $form->toHTML(); 186 187 echo '</div>'; // .diffoptions 188 } 189 190 /** 191 * Prints two images side by side 192 * and slider 193 * 194 * @author Kate Arzamastseva <pshns@ukr.net> 195 */ 196 protected function showImageDiff() 197 { 198 $rev1 = $this->RevInfo1->isCurrent() ? '' : $this->RevInfo1->val('date'); 199 $rev2 = $this->RevInfo2->isCurrent() ? '' : $this->RevInfo2->val('date'); 200 201 // diff view type: opacity or portions 202 $type = $this->preference['difftype']; 203 204 // adjust image width, right side (newer) has priority 205 $rev1Size = $this->RevInfo1->val('previewSize'); 206 $rev2Size = $this->RevInfo2->val('previewSize'); 207 if ($rev1Size != $rev2Size) { 208 if ($rev2Size[0] > $rev1Size[0]) { 209 $rev1Size = $rev2Size; 210 } 211 } 212 213 $rev1Src = ml($this->id, ['rev' => $rev1, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); 214 $rev2Src = ml($this->id, ['rev' => $rev2, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); 215 216 // slider 217 echo '<div class="slider" style="max-width: ' . ($rev1Size[0] - 20) . 'px;" ></div>'; 218 219 // two images in divs 220 echo '<div class="imageDiff ' . $type . '">'; 221 echo '<div class="image1" style="max-width: ' . $rev1Size[0] . 'px;">'; 222 echo '<img src="' . $rev1Src . '" alt="" />'; 223 echo '</div>'; 224 echo '<div class="image2" style="max-width: ' . $rev1Size[0] . 'px;">'; 225 echo '<img src="' . $rev2Src . '" alt="" />'; 226 echo '</div>'; 227 echo '</div>'; 228 } 229 230 /** 231 * Shows difference between two revisions of media file 232 * 233 * @author Kate Arzamastseva <pshns@ukr.net> 234 */ 235 protected function showFileDiff() 236 { 237 global $lang; 238 239 $ns = getNS($this->id); 240 $auth = auth_quickaclcheck("$ns:*"); 241 242 $rev1 = $this->RevInfo1->isCurrent() ? '' : (int)$this->RevInfo1->val('date'); 243 $rev2 = $this->RevInfo2->isCurrent() ? '' : (int)$this->RevInfo2->val('date'); 244 245 // revision title 246 $rev1Title = trim($this->RevInfo1->showRevisionTitle() . ' ' . $this->RevInfo1->showCurrentIndicator()); 247 $rev1Summary = ($this->RevInfo1->val('date')) 248 ? $this->RevInfo1->showEditSummary() . ' ' . $this->RevInfo1->showEditor() 249 : ''; 250 $rev2Title = trim($this->RevInfo2->showRevisionTitle() . ' ' . $this->RevInfo2->showCurrentIndicator()); 251 $rev2Summary = ($this->RevInfo2->val('date')) 252 ? $this->RevInfo2->showEditSummary() . ' ' . $this->RevInfo2->showEditor() 253 : ''; 254 255 $rev1Meta = new JpegMeta(mediaFN($this->id, $rev1)); 256 $rev2Meta = new JpegMeta(mediaFN($this->id, $rev2)); 257 258 // display diff view table 259 echo '<div class="table">'; 260 echo '<table>'; 261 echo '<tr>'; 262 echo '<th>' . $rev1Title . ' ' . $rev1Summary . '</th>'; 263 echo '<th>' . $rev2Title . ' ' . $rev2Summary . '</th>'; 264 echo '</tr>'; 265 266 echo '<tr class="image">'; 267 echo '<td>'; 268 media_preview($this->id, $auth, $rev1, $rev1Meta); // $auth not used in media_preview()? 269 echo '</td>'; 270 271 echo '<td>'; 272 media_preview($this->id, $auth, $rev2, $rev2Meta); 273 echo '</td>'; 274 echo '</tr>'; 275 276 echo '<tr class="actions">'; 277 echo '<td>'; 278 media_preview_buttons($this->id, $auth, $rev1); // $auth used in media_preview_buttons() 279 echo '</td>'; 280 281 echo '<td>'; 282 media_preview_buttons($this->id, $auth, $rev2); 283 echo '</td>'; 284 echo '</tr>'; 285 286 $rev1Tags = media_file_tags($rev1Meta); 287 $rev2Tags = media_file_tags($rev2Meta); 288 // FIXME rev2Tags-only stuff ignored 289 foreach ($rev1Tags as $key => $tag) { 290 if ($tag['value'] != $rev2Tags[$key]['value']) { 291 $rev2Tags[$key]['highlighted'] = true; 292 $rev1Tags[$key]['highlighted'] = true; 293 } elseif (!$tag['value'] || !$rev2Tags[$key]['value']) { 294 unset($rev2Tags[$key]); 295 unset($rev1Tags[$key]); 296 } 297 } 298 299 echo '<tr>'; 300 foreach ([$rev1Tags, $rev2Tags] as $tags) { 301 echo '<td>'; 302 303 echo '<dl class="img_tags">'; 304 foreach ($tags as $tag) { 305 $value = cleanText($tag['value']); 306 if (!$value) $value = '-'; 307 echo '<dt>' . $lang[$tag['tag'][1]] . '</dt>'; 308 echo '<dd>'; 309 if (!empty($tag['highlighted'])) echo '<strong>'; 310 if ($tag['tag'][2] == 'date') { 311 echo dformat($value); 312 } else { 313 echo hsc($value); 314 } 315 if (!empty($tag['highlighted'])) echo '</strong>'; 316 echo '</dd>'; 317 } 318 echo '</dl>'; 319 320 echo '</td>'; 321 } 322 echo '</tr>'; 323 324 echo '</table>'; 325 echo '</div>'; 326 } 327 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body