* Added templatelinks table. The table currently represents a literal list of templat...
[lhc/web/wiklou.git] / includes / ImagePage.php
1 <?php
2 /**
3 * @package MediaWiki
4 */
5
6 /**
7 *
8 */
9 if( !defined( 'MEDIAWIKI' ) )
10 die();
11
12 require_once( 'Image.php' );
13
14 /**
15 * Special handling for image description pages
16 * @package MediaWiki
17 */
18 class ImagePage extends Article {
19
20 /* private */ var $img; // Image object this page is shown for
21 var $mExtraDescription = false;
22
23 function render() {
24 global $wgOut;
25 $wgOut->setArticleBodyOnly(true);
26 $wgOut->addWikitext($this->getContent(true));
27 }
28
29 function view() {
30 global $wgOut, $wgShowEXIF;
31
32 $this->img = new Image( $this->mTitle );
33
34 if( $this->mTitle->getNamespace() == NS_IMAGE ) {
35 if ($wgShowEXIF && $this->img->exists()) {
36 $exif = $this->img->getExifData();
37 $showmeta = count($exif) ? true : false;
38 } else {
39 $exif = false;
40 $showmeta = false;
41 }
42
43 if ($this->img->exists())
44 $wgOut->addHTML($this->showTOC($showmeta));
45
46 $this->openShowImage();
47
48 # No need to display noarticletext, we use our own message, output in openShowImage()
49 if( $this->getID() ) {
50 Article::view();
51 } else {
52 # Just need to set the right headers
53 $wgOut->setArticleFlag( true );
54 $wgOut->setRobotpolicy( 'index,follow' );
55 $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
56 $this->viewUpdates();
57 }
58
59 if ($this->mExtraDescription) {
60 $fol = wfMsg('shareddescriptionfollows');
61 if ($fol != '-')
62 $wgOut->addWikiText(wfMsg('shareddescriptionfollows'));
63 $wgOut->addHTML($this->mExtraDescription);
64 }
65
66 $this->closeShowImage();
67 $this->imageHistory();
68 $this->imageLinks();
69 if( $exif ) {
70 global $wgStylePath;
71 $expand = htmlspecialchars( wfEscapeJsString( wfMsg( 'metadata-expand' ) ) );
72 $collapse = htmlspecialchars( wfEscapeJsString( wfMsg( 'metadata-collapse' ) ) );
73 $wgOut->addHTML( "<h2 id=\"metadata\">" . wfMsgHtml( 'metadata' ) . "</h2>\n" );
74 $wgOut->addWikiText( $this->makeMetadataTable( $exif ) );
75 $wgOut->addHTML(
76 "<script type=\"text/javascript\" src=\"$wgStylePath/common/metadata.js\"></script>\n" .
77 "<script type=\"text/javascript\">attachMetadataToggle('mw_metadata', '$expand', '$collapse');</script>\n" );
78 }
79 } else {
80 Article::view();
81 }
82 }
83
84 /**
85 * Create the TOC
86 *
87 * @access private
88 *
89 * @param bool $metadata Whether or not to show the metadata link
90 * @return string
91 */
92 function showTOC( $metadata ) {
93 global $wgLang;
94 $r = '<ul id="filetoc">
95 <li><a href="#file">' . $wgLang->getNsText( NS_IMAGE ) . '</a></li>
96 <li><a href="#filehistory">' . wfMsgHtml( 'imghistory' ) . '</a></li>
97 <li><a href="#filelinks">' . wfMsgHtml( 'imagelinks' ) . '</a></li>' .
98 ($metadata ? '<li><a href="#metadata">' . wfMsgHtml( 'metadata' ) . '</a></li>' : '') . '
99 </ul>';
100 return $r;
101 }
102
103 /**
104 * Make a table with metadata to be shown in the output page.
105 *
106 * @access private
107 *
108 * @param array $exif The array containing the EXIF data
109 * @return string
110 */
111 function makeMetadataTable( $exif ) {
112 $r = wfMsg( 'metadata-help' ) . "\n\n";
113 $r .= "{| id=mw_metadata class=mw_metadata\n";
114 $visibleFields = $this->visibleMetadataFields();
115 foreach( $exif as $k => $v ) {
116 $tag = strtolower( $k );
117 $msg = wfMsg( "exif-$tag" );
118 $class = "exif-$tag";
119 if( !in_array( $tag, $visibleFields ) ) {
120 $class .= ' collapsable';
121 }
122 $r .= "|- class=\"$class\"\n";
123 $r .= "!| $msg\n";
124 $r .= "|| $v\n";
125 }
126 $r .= '|}';
127 return $r;
128 }
129
130 /**
131 * Get a list of EXIF metadata items which should be displayed when
132 * the metadata table is collapsed.
133 *
134 * @return array of strings
135 * @access private
136 */
137 function visibleMetadataFields() {
138 $fields = array();
139 $lines = explode( "\n", wfMsgForContent( 'metadata-fields' ) );
140 foreach( $lines as $line ) {
141 if( preg_match( '/^\\*\s*(.*?)\s*$/', $line, $matches ) ) {
142 $fields[] = $matches[1];
143 }
144 }
145 return $fields;
146 }
147
148 /**
149 * Overloading Article's getContent method.
150 * Omit noarticletext if sharedupload
151 *
152 * @param $noredir If true, do not follow redirects
153 */
154 function getContent( $noredir )
155 {
156 if ( $this->img && $this->img->fromSharedDirectory && 0 == $this->getID() ) {
157 return '';
158 }
159 return Article::getContent( $noredir );
160 }
161
162 function openShowImage() {
163 global $wgOut, $wgUser, $wgImageLimits, $wgRequest, $wgUseImageResize;
164
165 $full_url = $this->img->getURL();
166 $anchoropen = '';
167 $anchorclose = '';
168
169 if( $wgUser->getOption( 'imagesize' ) == '' ) {
170 $sizeSel = User::getDefaultOption( 'imagesize' );
171 } else {
172 $sizeSel = intval( $wgUser->getOption( 'imagesize' ) );
173 }
174 if( !isset( $wgImageLimits[$sizeSel] ) ) {
175 $sizeSel = User::getDefaultOption( 'imagesize' );
176 }
177 $max = $wgImageLimits[$sizeSel];
178 $maxWidth = $max[0];
179 $maxHeight = $max[1];
180 $sk = $wgUser->getSkin();
181
182 if ( $this->img->exists() ) {
183 # image
184 $width = $this->img->getWidth();
185 $height = $this->img->getHeight();
186 $showLink = false;
187
188 if ( $this->img->allowInlineDisplay() and $width and $height) {
189 # image
190
191 # "Download high res version" link below the image
192 $msg = wfMsgHtml('showbigimage', $width, $height, intval( $this->img->getSize()/1024 ) );
193
194 # We'll show a thumbnail of this image
195 if ( $width > $maxWidth || $height > $maxHeight ) {
196 # Calculate the thumbnail size.
197 # First case, the limiting factor is the width, not the height.
198 if ( $width / $height >= $maxWidth / $maxHeight ) {
199 $height = round( $height * $maxWidth / $width);
200 $width = $maxWidth;
201 # Note that $height <= $maxHeight now.
202 } else {
203 $newwidth = floor( $width * $maxHeight / $height);
204 $height = round( $height * $newwidth / $width );
205 $width = $newwidth;
206 # Note that $height <= $maxHeight now, but might not be identical
207 # because of rounding.
208 }
209
210 if( $wgUseImageResize ) {
211 $thumbnail = $this->img->getThumbnail( $width );
212 if ( $thumbnail == null ) {
213 $url = $this->img->getViewURL();
214 } else {
215 $url = $thumbnail->getURL();
216 }
217 } else {
218 # No resize ability? Show the full image, but scale
219 # it down in the browser so it fits on the page.
220 $url = $this->img->getViewURL();
221 }
222 $anchoropen = "<a href=\"{$full_url}\">";
223 $anchorclose = "</a><br />";
224 if( $this->img->mustRender() ) {
225 $showLink = true;
226 } else {
227 $anchorclose .= "\n$anchoropen{$msg}</a>";
228 }
229 } else {
230 $url = $this->img->getViewURL();
231 $showLink = true;
232 }
233 $wgOut->addHTML( '<div class="fullImageLink" id="file">' . $anchoropen .
234 "<img border=\"0\" src=\"{$url}\" width=\"{$width}\" height=\"{$height}\" alt=\"" .
235 htmlspecialchars( $wgRequest->getVal( 'image' ) ).'" />' . $anchorclose . '</div>' );
236 } else {
237 #if direct link is allowed but it's not a renderable image, show an icon.
238 if ($this->img->isSafeFile()) {
239 $icon= $this->img->iconThumb();
240
241 $wgOut->addHTML( '<div class="fullImageLink" id="file"><a href="' . $full_url . '">' .
242 $icon->toHtml() .
243 '</a></div>' );
244 }
245
246 $showLink = true;
247 }
248
249
250 if ($showLink) {
251 $filename = wfEscapeWikiText( $this->img->getName() );
252 $info = wfMsg( 'fileinfo',
253 ceil($this->img->getSize()/1024.0),
254 $this->img->getMimeType() );
255
256 if (!$this->img->isSafeFile()) {
257 $warning = wfMsg( 'mediawarning' );
258 $wgOut->addWikiText( <<<END
259 <div class="fullMedia">
260 <span class="dangerousLink">[[Media:$filename|$filename]]</span>
261 <span class="fileInfo"> ($info)</span>
262 </div>
263
264 <div class="mediaWarning">$warning</div>
265 END
266 );
267 } else {
268 $wgOut->addWikiText( <<<END
269 <div class="fullMedia">
270 [[Media:$filename|$filename]] <span class="fileInfo"> ($info)</span>
271 </div>
272 END
273 );
274 }
275 }
276
277 if($this->img->fromSharedDirectory) {
278 $this->printSharedImageText();
279 }
280 } else {
281 # Image does not exist
282
283 $title = Title::makeTitle( NS_SPECIAL, 'Upload' );
284 $link = $sk->makeKnownLinkObj($title, wfMsgHtml('noimage-linktext'),
285 'wpDestFile=' . urlencode( $this->img->getName() ) );
286 $wgOut->addHTML( wfMsgWikiHtml( 'noimage', $link ) );
287 }
288 }
289
290 function printSharedImageText() {
291 global $wgRepositoryBaseUrl, $wgFetchCommonsDescriptions, $wgOut, $wgUser;
292
293 $url = $wgRepositoryBaseUrl . urlencode($this->mTitle->getDBkey());
294 $sharedtext = "<div class='sharedUploadNotice'>" . wfMsgWikiHtml("sharedupload");
295 if ($wgRepositoryBaseUrl && !$wgFetchCommonsDescriptions) {
296
297 $sk = $wgUser->getSkin();
298 $title = Title::makeTitle( NS_SPECIAL, 'Upload' );
299 $link = $sk->makeKnownLinkObj($title, wfMsgHtml('shareduploadwiki-linktext'),
300 array( 'wpDestFile' => urlencode( $this->img->getName() )));
301 $sharedtext .= " " . wfMsgWikiHtml('shareduploadwiki', $link);
302 }
303 $sharedtext .= "</div>";
304 $wgOut->addHTML($sharedtext);
305
306 if ($wgRepositoryBaseUrl && $wgFetchCommonsDescriptions) {
307 require_once("HttpFunctions.php");
308 $ur = ini_set('allow_url_fopen', true);
309 $text = wfGetHTTP($url . '?action=render');
310 ini_set('allow_url_fopen', $ur);
311 if ($text)
312 $this->mExtraDescription = $text;
313 }
314 }
315
316 function getUploadUrl() {
317 global $wgServer;
318 $uploadTitle = Title::makeTitle( NS_SPECIAL, 'Upload' );
319 return $wgServer . $uploadTitle->getLocalUrl( 'wpDestFile=' . urlencode( $this->img->getName() ) );
320 }
321
322
323 function uploadLinksBox()
324 {
325 global $wgUser, $wgOut;
326
327 if ($this->img->fromSharedDirectory)
328 return;
329
330 $sk = $wgUser->getSkin();
331 $wgOut->addHTML( '<br /><ul>' );
332 if( $wgUser->isAllowed( 'reupload' ) ) {
333 $wgOut->addWikiText( "<li>\n<div>". wfMsg( 'uploadnewversion', $this->getUploadUrl() ) ."</div>\n</li>\n" );
334 }
335 $wgOut->addHTML( '<li>' );
336 $wgOut->addHTML( $sk->makeKnownLinkObj( $this->mTitle,
337 wfMsg( 'edit-externally' ), "action=edit&externaledit=true&mode=file" ) );
338 $wgOut->addWikiText( '<div>' . wfMsg('edit-externally-help') . '</div>' );
339 $wgOut->addHTML( '</li></ul>' );
340 }
341
342 function closeShowImage()
343 {
344 # For overloading
345
346 }
347
348 /**
349 * If the page we've just displayed is in the "Image" namespace,
350 * we follow it with an upload history of the image and its usage.
351 */
352 function imageHistory()
353 {
354 global $wgUser, $wgOut, $wgUseExternalEditor;
355
356 $sk = $wgUser->getSkin();
357
358 $line = $this->img->nextHistoryLine();
359
360 if ( $line ) {
361 $list =& new ImageHistoryList( $sk );
362 $s = $list->beginImageHistoryList() .
363 $list->imageHistoryLine( true, wfTimestamp(TS_MW, $line->img_timestamp),
364 $this->mTitle->getDBkey(), $line->img_user,
365 $line->img_user_text, $line->img_size, $line->img_description,
366 $line->img_width, $line->img_height
367 );
368
369 while ( $line = $this->img->nextHistoryLine() ) {
370 $s .= $list->imageHistoryLine( false, $line->img_timestamp,
371 $line->oi_archive_name, $line->img_user,
372 $line->img_user_text, $line->img_size, $line->img_description,
373 $line->img_width, $line->img_height
374 );
375 }
376 $s .= $list->endImageHistoryList();
377 } else { $s=''; }
378 $wgOut->addHTML( $s );
379
380 # Exist check because we don't want to show this on pages where an image
381 # doesn't exist along with the noimage message, that would suck. -ævar
382 if( $wgUseExternalEditor && $this->img->exists() ) {
383 $this->uploadLinksBox();
384 }
385
386 }
387
388 function imageLinks()
389 {
390 global $wgUser, $wgOut;
391
392 $wgOut->addHTML( '<h2 id="filelinks">' . wfMsg( 'imagelinks' ) . "</h2>\n" );
393
394 $dbr =& wfGetDB( DB_SLAVE );
395 $page = $dbr->tableName( 'page' );
396 $imagelinks = $dbr->tableName( 'imagelinks' );
397
398 $sql = "SELECT page_namespace,page_title FROM $imagelinks,$page WHERE il_to=" .
399 $dbr->addQuotes( $this->mTitle->getDBkey() ) . " AND il_from=page_id";
400 $sql = $dbr->limitResult($sql, 500, 0);
401 $res = $dbr->query( $sql, "ImagePage::imageLinks" );
402
403 if ( 0 == $dbr->numRows( $res ) ) {
404 $wgOut->addHtml( '<p>' . wfMsg( "nolinkstoimage" ) . "</p>\n" );
405 return;
406 }
407 $wgOut->addHTML( '<p>' . wfMsg( 'linkstoimage' ) . "</p>\n<ul>" );
408
409 $sk = $wgUser->getSkin();
410 while ( $s = $dbr->fetchObject( $res ) ) {
411 $name = Title::MakeTitle( $s->page_namespace, $s->page_title );
412 $link = $sk->makeKnownLinkObj( $name, "" );
413 $wgOut->addHTML( "<li>{$link}</li>\n" );
414 }
415 $wgOut->addHTML( "</ul>\n" );
416 }
417
418 function delete()
419 {
420 global $wgUser, $wgOut, $wgRequest;
421
422 $confirm = $wgRequest->wasPosted();
423 $image = $wgRequest->getVal( 'image' );
424 $oldimage = $wgRequest->getVal( 'oldimage' );
425
426 # Only sysops can delete images. Previously ordinary users could delete
427 # old revisions, but this is no longer the case.
428 if ( !$wgUser->isAllowed('delete') ) {
429 $wgOut->sysopRequired();
430 return;
431 }
432 if ( $wgUser->isBlocked() ) {
433 return $this->blockedIPpage();
434 }
435 if ( wfReadOnly() ) {
436 $wgOut->readOnlyPage();
437 return;
438 }
439
440 # Better double-check that it hasn't been deleted yet!
441 $wgOut->setPagetitle( wfMsg( 'confirmdelete' ) );
442 if ( ( !is_null( $image ) )
443 && ( '' == trim( $image ) ) ) {
444 $wgOut->fatalError( wfMsg( 'cannotdelete' ) );
445 return;
446 }
447
448 $this->img = new Image( $this->mTitle );
449
450 # Deleting old images doesn't require confirmation
451 if ( !is_null( $oldimage ) || $confirm ) {
452 if( $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) {
453 $this->doDelete();
454 } else {
455 $wgOut->fatalError( wfMsg( 'sessionfailure' ) );
456 }
457 return;
458 }
459
460 if ( !is_null( $image ) ) {
461 $q = '&image=' . urlencode( $image );
462 } else if ( !is_null( $oldimage ) ) {
463 $q = '&oldimage=' . urlencode( $oldimage );
464 } else {
465 $q = '';
466 }
467 return $this->confirmDelete( $q, $wgRequest->getText( 'wpReason' ) );
468 }
469
470 function doDelete() {
471 global $wgOut, $wgUser, $wgRequest, $wgUseSquid, $wgInternalServer;
472 global $wgPostCommitUpdateList;
473
474 $fname = 'ImagePage::doDelete';
475
476 $reason = $wgRequest->getVal( 'wpReason' );
477 $oldimage = $wgRequest->getVal( 'oldimage' );
478
479 $dbw =& wfGetDB( DB_MASTER );
480
481 if ( !is_null( $oldimage ) ) {
482 if ( strlen( $oldimage ) < 16 ) {
483 $wgOut->unexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
484 return;
485 }
486 if ( strstr( $oldimage, "/" ) || strstr( $oldimage, "\\" ) ) {
487 $wgOut->unexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
488 return;
489 }
490
491 # Invalidate description page cache
492 $this->mTitle->invalidateCache();
493
494 # Squid purging
495 if ( $wgUseSquid ) {
496 $urlArr = array(
497 $wgInternalServer.wfImageArchiveUrl( $oldimage ),
498 $this->mTitle->getInternalURL()
499 );
500 wfPurgeSquidServers($urlArr);
501 }
502 $this->doDeleteOldImage( $oldimage );
503 $dbw->delete( 'oldimage', array( 'oi_archive_name' => $oldimage ) );
504 $deleted = $oldimage;
505 } else {
506 $image = $this->mTitle->getDBkey();
507 $dest = wfImageDir( $image );
508 $archive = wfImageDir( $image );
509
510 # Delete the image file if it exists; due to sync problems
511 # or manual trimming sometimes the file will be missing.
512 $targetFile = "{$dest}/{$image}";
513 if( file_exists( $targetFile ) && ! @unlink( $targetFile ) ) {
514 # If the deletion operation actually failed, bug out:
515 $wgOut->fileDeleteError( $targetFile );
516 return;
517 }
518 $dbw->delete( 'image', array( 'img_name' => $image ) );
519 $res = $dbw->select( 'oldimage', array( 'oi_archive_name' ), array( 'oi_name' => $image ) );
520
521 # Purge archive URLs from the squid
522 $urlArr = Array();
523 while ( $s = $dbw->fetchObject( $res ) ) {
524 $this->doDeleteOldImage( $s->oi_archive_name );
525 $urlArr[] = $wgInternalServer.wfImageArchiveUrl( $s->oi_archive_name );
526 }
527
528 # And also the HTML of all pages using this image
529 $linksTo = $this->img->getLinksTo();
530 if ( $wgUseSquid ) {
531 $u = SquidUpdate::newFromTitles( $linksTo, $urlArr );
532 array_push( $wgPostCommitUpdateList, $u );
533 }
534
535 $dbw->delete( 'oldimage', array( 'oi_name' => $image ) );
536
537 # Image itself is now gone, and database is cleaned.
538 # Now we remove the image description page.
539
540 $article = new Article( $this->mTitle );
541 $article->doDeleteArticle( $reason ); # ignore errors
542
543 # Invalidate parser cache and client cache for pages using this image
544 # This is left until relatively late to reduce lock time
545 Title::touchArray( $linksTo );
546
547 /* Delete thumbnails and refresh image metadata cache */
548 $this->img->purgeCache();
549
550
551 $deleted = $image;
552 }
553
554 $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
555 $wgOut->setRobotpolicy( 'noindex,nofollow' );
556
557 $loglink = '[[Special:Log/delete|' . wfMsg( 'deletionlog' ) . ']]';
558 $text = wfMsg( 'deletedtext', $deleted, $loglink );
559
560 $wgOut->addWikiText( $text );
561
562 $wgOut->returnToMain( false, $this->mTitle->getPrefixedText() );
563 }
564
565 function doDeleteOldImage( $oldimage )
566 {
567 global $wgOut;
568
569 $name = substr( $oldimage, 15 );
570 $archive = wfImageArchiveDir( $name );
571
572 # Delete the image if it exists. Sometimes the file will be missing
573 # due to manual intervention or weird sync problems; treat that
574 # condition gracefully and continue to delete the database entry.
575 # Also some records may end up with an empty oi_archive_name field
576 # if the original file was missing when a new upload was made;
577 # don't try to delete the directory then!
578 #
579 $targetFile = "{$archive}/{$oldimage}";
580 if( $oldimage != '' && file_exists( $targetFile ) && !@unlink( $targetFile ) ) {
581 # If we actually have a file and can't delete it, throw an error.
582 $wgOut->fileDeleteError( "{$archive}/{$oldimage}" );
583 } else {
584 # Log the deletion
585 $log = new LogPage( 'delete' );
586 $log->addEntry( 'delete', $this->mTitle, wfMsg('deletedrevision',$oldimage) );
587 }
588 }
589
590 function revert() {
591 global $wgOut, $wgRequest, $wgUser;
592
593 $oldimage = $wgRequest->getText( 'oldimage' );
594 if ( strlen( $oldimage ) < 16 ) {
595 $wgOut->unexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
596 return;
597 }
598 if ( strstr( $oldimage, "/" ) || strstr( $oldimage, "\\" ) ) {
599 $wgOut->unexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
600 return;
601 }
602
603 if ( wfReadOnly() ) {
604 $wgOut->readOnlyPage();
605 return;
606 }
607 if( $wgUser->isAnon() ) {
608 $wgOut->errorpage( 'uploadnologin', 'uploadnologintext' );
609 return;
610 }
611 if ( ! $this->mTitle->userCanEdit() ) {
612 $wgOut->sysopRequired();
613 return;
614 }
615 if ( $wgUser->isBlocked() ) {
616 return $this->blockedIPpage();
617 }
618 if( !$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) {
619 $wgOut->errorpage( 'internalerror', 'sessionfailure' );
620 return;
621 }
622 $name = substr( $oldimage, 15 );
623
624 $dest = wfImageDir( $name );
625 $archive = wfImageArchiveDir( $name );
626 $curfile = "{$dest}/{$name}";
627
628 if ( ! is_file( $curfile ) ) {
629 $wgOut->fileNotFoundError( htmlspecialchars( $curfile ) );
630 return;
631 }
632 $oldver = wfTimestampNow() . "!{$name}";
633
634 $dbr =& wfGetDB( DB_SLAVE );
635 $size = $dbr->selectField( 'oldimage', 'oi_size', array( 'oi_archive_name' => $oldimage ) );
636
637 if ( ! rename( $curfile, "${archive}/{$oldver}" ) ) {
638 $wgOut->fileRenameError( $curfile, "${archive}/{$oldver}" );
639 return;
640 }
641 if ( ! copy( "{$archive}/{$oldimage}", $curfile ) ) {
642 $wgOut->fileCopyError( "${archive}/{$oldimage}", $curfile );
643 }
644
645 # Record upload and update metadata cache
646 $img = Image::newFromName( $name );
647 $img->recordUpload( $oldver, wfMsg( "reverted" ) );
648
649 $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
650 $wgOut->setRobotpolicy( 'noindex,nofollow' );
651 $wgOut->addHTML( wfMsg( 'imagereverted' ) );
652
653 $descTitle = $img->getTitle();
654 $wgOut->returnToMain( false, $descTitle->getPrefixedText() );
655 }
656
657 function blockedIPpage() {
658 require_once( 'EditPage.php' );
659 $edit = new EditPage( $this );
660 return $edit->blockedIPpage();
661 }
662
663 }
664
665 /**
666 * @todo document
667 * @package MediaWiki
668 */
669 class ImageHistoryList {
670 function ImageHistoryList( &$skin ) {
671 $this->skin =& $skin;
672 }
673
674 function beginImageHistoryList() {
675 $s = "\n<h2 id=\"filehistory\">" . wfMsg( 'imghistory' ) . "</h2>\n" .
676 "<p>" . wfMsg( 'imghistlegend' ) . "</p>\n".'<ul class="special">';
677 return $s;
678 }
679
680 function endImageHistoryList() {
681 $s = "</ul>\n";
682 return $s;
683 }
684
685 function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description, $width, $height ) {
686 global $wgUser, $wgLang, $wgTitle, $wgContLang;
687
688 $datetime = $wgLang->timeanddate( $timestamp, true );
689 $del = wfMsg( 'deleteimg' );
690 $delall = wfMsg( 'deleteimgcompletely' );
691 $cur = wfMsg( 'cur' );
692
693 if ( $iscur ) {
694 $url = Image::imageUrl( $img );
695 $rlink = $cur;
696 if ( $wgUser->isAllowed('delete') ) {
697 $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
698 '&action=delete' );
699 $style = $this->skin->getInternalLinkAttributes( $link, $delall );
700
701 $dlink = '<a href="'.$link.'"'.$style.'>'.$delall.'</a>';
702 } else {
703 $dlink = $del;
704 }
705 } else {
706 $url = htmlspecialchars( wfImageArchiveUrl( $img ) );
707 if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) {
708 $token = urlencode( $wgUser->editToken( $img ) );
709 $rlink = $this->skin->makeKnownLinkObj( $wgTitle,
710 wfMsg( 'revertimg' ), 'action=revert&oldimage=' .
711 urlencode( $img ) . "&wpEditToken=$token" );
712 $dlink = $this->skin->makeKnownLinkObj( $wgTitle,
713 $del, 'action=delete&oldimage=' . urlencode( $img ) .
714 "&wpEditToken=$token" );
715 } else {
716 # Having live active links for non-logged in users
717 # means that bots and spiders crawling our site can
718 # inadvertently change content. Baaaad idea.
719 $rlink = wfMsg( 'revertimg' );
720 $dlink = $del;
721 }
722 }
723 if ( 0 == $user ) {
724 $userlink = $usertext;
725 } else {
726 $userlink = $this->skin->makeLinkObj( Title::makeTitle( NS_USER, $usertext ), $usertext );
727 $usertalk = $this->skin->makeLinkObj( Title::makeTitle( NS_USER_TALK, $usertext), $wgContLang->getNsText( NS_TALK ) );
728 $userdata = $userlink . ' (' . $usertalk . ')';
729 }
730 $nbytes = wfMsg( 'nbytes', $size );
731 $widthheight = wfMsg( 'widthheight', $width, $height );
732 $style = $this->skin->getInternalLinkAttributes( $url, $datetime );
733
734 $s = "<li> ({$dlink}) ({$rlink}) <a href=\"{$url}\"{$style}>{$datetime}</a> . . {$userdata} . . {$widthheight} ({$nbytes})";
735
736 $s .= $this->skin->commentBlock( $description, $wgTitle );
737 $s .= "</li>\n";
738 return $s;
739 }
740
741 }
742
743
744 ?>