X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FImagePage.php;h=002fc250c3365319c89e026e7313dba52465f8ef;hb=82a0d6c1c03a4f618cd86aee2eb5d8d65ccb2a28;hp=226bf26a2b96be01c7a16373fead6388ddbb09f0;hpb=81befad1cf8c4e396cd574373af89a96e804254f;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ImagePage.php b/includes/ImagePage.php index 226bf26a2b..002fc250c3 100644 --- a/includes/ImagePage.php +++ b/includes/ImagePage.php @@ -1,6 +1,5 @@ img = wfFindFile( $this->mTitle, $time ); + if ( !$this->img ) { + $this->img = wfLocalFile( $this->mTitle ); + $this->current = $this->img; + } else { + $this->current = $time ? wfLocalFile( $this->mTitle ) : $this->img; + } + $this->repo = $this->img->repo; + } + /** * Handler for action=render * Include body text only; none of the image extras @@ -25,14 +38,12 @@ class ImagePage extends Article { function render() { global $wgOut; $wgOut->setArticleBodyOnly( true ); - $wgOut->addSecondaryWikitext( $this->getContent() ); + $wgOut->addWikiTextTitleTidy( $this->getContent(), $this->mTitle ); } function view() { global $wgOut, $wgShowEXIF, $wgRequest, $wgUser; - $this->img = new Image( $this->mTitle ); - $diff = $wgRequest->getVal( 'diff' ); $diffOnly = $wgRequest->getBool( 'diffonly', $wgUser->getOption( 'diffonly' ) ); @@ -40,10 +51,10 @@ class ImagePage extends Article { return Article::view(); if ($wgShowEXIF && $this->img->exists()) { - $exif = $this->img->getExifData(); - $showmeta = count($exif) ? true : false; + // FIXME: bad interface, see note on MediaHandler::formatMetadata(). + $formattedMetadata = $this->img->formatMetadata(); + $showmeta = $formattedMetadata !== false; } else { - $exif = false; $showmeta = false; } @@ -58,15 +69,15 @@ class ImagePage extends Article { } else { # Just need to set the right headers $wgOut->setArticleFlag( true ); - $wgOut->setRobotpolicy( 'index,follow' ); + $wgOut->setRobotpolicy( 'noindex,nofollow' ); $wgOut->setPageTitle( $this->mTitle->getPrefixedText() ); $this->viewUpdates(); } # Show shared description, if needed if ( $this->mExtraDescription ) { - $fol = wfMsg( 'shareddescriptionfollows' ); - if( $fol != '-' ) { + $fol = wfMsgNoTrans( 'shareddescriptionfollows' ); + if( $fol != '-' && !wfEmptyMsg( 'shareddescriptionfollows', $fol ) ) { $wgOut->addWikiText( $fol ); } $wgOut->addHTML( '
' . $this->mExtraDescription . '
' ); @@ -76,12 +87,12 @@ class ImagePage extends Article { $this->imageHistory(); $this->imageLinks(); - if ( $exif ) { + if ( $showmeta ) { global $wgStylePath, $wgStyleVersion; $expand = htmlspecialchars( wfEscapeJsString( wfMsg( 'metadata-expand' ) ) ); $collapse = htmlspecialchars( wfEscapeJsString( wfMsg( 'metadata-collapse' ) ) ); - $wgOut->addHTML( "

" . wfMsgHtml( 'metadata' ) . "

\n" ); - $wgOut->addWikiText( $this->makeMetadataTable( $exif ) ); + $wgOut->addHTML( Xml::element( 'h2', array( 'id' => 'metadata' ), wfMsg( 'metadata' ) ). "\n" ); + $wgOut->addWikiText( $this->makeMetadataTable( $formattedMetadata ) ); $wgOut->addHTML( "\n" . "\n" ); @@ -100,9 +111,9 @@ class ImagePage extends Article { global $wgLang; $r = ''; return $r; } @@ -110,49 +121,31 @@ class ImagePage extends Article { /** * Make a table with metadata to be shown in the output page. * + * FIXME: bad interface, see note on MediaHandler::formatMetadata(). + * * @access private * * @param array $exif The array containing the EXIF data * @return string */ - function makeMetadataTable( $exif ) { + function makeMetadataTable( $metadata ) { $r = wfMsg( 'metadata-help' ) . "\n\n"; $r .= "{| id=mw_metadata class=mw_metadata\n"; - $visibleFields = $this->visibleMetadataFields(); - foreach( $exif as $k => $v ) { - $tag = strtolower( $k ); - $msg = wfMsg( "exif-$tag" ); - $class = "exif-$tag"; - if( !in_array( $tag, $visibleFields ) ) { - $class .= ' collapsable'; + foreach ( $metadata as $type => $stuff ) { + foreach ( $stuff as $v ) { + $class = Sanitizer::escapeId( $v['id'] ); + if( $type == 'collapsed' ) { + $class .= ' collapsable'; + } + $r .= "|- class=\"$class\"\n"; + $r .= "!| {$v['name']}\n"; + $r .= "|| {$v['value']}\n"; } - $r .= "|- class=\"$class\"\n"; - $r .= "!| $msg\n"; - $r .= "|| $v\n"; } $r .= '|}'; return $r; } - /** - * Get a list of EXIF metadata items which should be displayed when - * the metadata table is collapsed. - * - * @return array of strings - * @access private - */ - function visibleMetadataFields() { - $fields = array(); - $lines = explode( "\n", wfMsgForContent( 'metadata-fields' ) ); - foreach( $lines as $line ) { - $matches = array(); - if( preg_match( '/^\\*\s*(.*?)\s*$/', $line, $matches ) ) { - $fields[] = $matches[1]; - } - } - return $fields; - } - /** * Overloading Article's getContent method. * @@ -160,47 +153,59 @@ class ImagePage extends Article { * shared upload server if possible. */ function getContent() { - if( $this->img && $this->img->fromSharedDirectory && 0 == $this->getID() ) { + if( $this->img && !$this->img->isLocal() && 0 == $this->getID() ) { return ''; } return Article::getContent(); } function openShowImage() { - global $wgOut, $wgUser, $wgImageLimits, $wgRequest, $wgLang; - global $wgUseImageResize, $wgGenerateThumbnailOnParse; + global $wgOut, $wgUser, $wgImageLimits, $wgRequest, $wgLang, $wgContLang; $full_url = $this->img->getURL(); - $anchoropen = ''; - $anchorclose = ''; + $linkAttribs = false; $sizeSel = intval( $wgUser->getOption( 'imagesize') ); - if( !isset( $wgImageLimits[$sizeSel] ) ) { $sizeSel = User::getDefaultOption( 'imagesize' ); + + // The user offset might still be incorrect, specially if + // $wgImageLimits got changed (see bug #8858). + if( !isset( $wgImageLimits[$sizeSel] ) ) { + // Default to the first offset in $wgImageLimits + $sizeSel = 0; + } } $max = $wgImageLimits[$sizeSel]; $maxWidth = $max[0]; $maxHeight = $max[1]; $sk = $wgUser->getSkin(); + $dirmark = $wgContLang->getDirMark(); if ( $this->img->exists() ) { # image $page = $wgRequest->getIntOrNull( 'page' ); - if ( ! is_null( $page ) ) { - $this->img->selectPage( $page ); - } else { + if ( is_null( $page ) ) { + $params = array(); $page = 1; + } else { + $params = array( 'page' => $page ); } - $width = $this->img->getWidth(); - $height = $this->img->getHeight(); + $width_orig = $this->img->getWidth(); + $width = $width_orig; + $height_orig = $this->img->getHeight(); + $height = $height_orig; + $mime = $this->img->getMimeType(); $showLink = false; + $linkAttribs = array( 'href' => $full_url ); + $longDesc = $this->img->getLongDesc(); + + wfRunHooks( 'ImageOpenShowImageInlineBefore', array( &$this , &$wgOut ) ) ; - if ( $this->img->allowInlineDisplay() and $width and $height) { + if ( $this->img->allowInlineDisplay() ) { # image # "Download high res version" link below the image - $msg = wfMsgHtml('showbigimage', $width, $height, intval( $this->img->getSize()/1024 ) ); - + #$msgsize = wfMsgHtml('file-info-size', $width_orig, $height_orig, $sk->formatSize( $this->img->getSize() ), $mime ); # We'll show a thumbnail of this image if ( $width > $maxWidth || $height > $maxHeight ) { # Calculate the thumbnail size. @@ -216,61 +221,67 @@ class ImagePage extends Article { # Note that $height <= $maxHeight now, but might not be identical # because of rounding. } - - if( $wgUseImageResize ) { - $thumbnail = $this->img->getThumbnail( $width, -1, $wgGenerateThumbnailOnParse ); - if ( $thumbnail == null ) { - $url = $this->img->getViewURL(); - } else { - $url = $thumbnail->getURL(); - } - } else { - # No resize ability? Show the full image, but scale - # it down in the browser so it fits on the page. - $url = $this->img->getViewURL(); - } - $anchoropen = ""; - $anchorclose = "
"; - if( $this->img->mustRender() ) { - $showLink = true; - } else { - $anchorclose .= "\n$anchoropen{$msg}"; - } + $msgbig = wfMsgHtml( 'show-big-image' ); + $msgsmall = wfMsgExt( 'show-big-image-thumb', + array( 'parseinline' ), $wgLang->formatNum( $width ), $wgLang->formatNum( $height ) ); } else { - $url = $this->img->getViewURL(); + # Image is small enough to show full size on image page + $msgbig = htmlspecialchars( $this->img->getName() ); + $msgsmall = wfMsgExt( 'file-nohires', array( 'parseinline' ) ); + } + + $params['width'] = $width; + $thumbnail = $this->img->transform( $params ); + + $anchorclose = "
"; + if( $this->img->mustRender() ) { $showLink = true; + } else { + $anchorclose .= + $msgsmall . + '
' . Xml::tags( 'a', $linkAttribs, $msgbig ) . "$dirmark " . $longDesc; } if ( $this->img->isMultipage() ) { $wgOut->addHTML( '
' ); } - $wgOut->addHTML( '' ); + if ( $thumbnail ) { + $options = array( + 'alt' => $this->img->getTitle()->getPrefixedText(), + 'file-link' => true, + ); + $wgOut->addHTML( '' ); + } if ( $this->img->isMultipage() ) { $count = $this->img->pageCount(); if ( $page > 1 ) { $label = $wgOut->parse( wfMsg( 'imgmultipageprev' ), false ); - $link = $sk->makeLinkObj( $this->mTitle, $label, 'page='. ($page-1) ); - $this->img->selectPage( $page - 1 ); - $thumb1 = $sk->makeThumbLinkObj( $this->img, $link, $label, 'none' ); + $link = $sk->makeKnownLinkObj( $this->mTitle, $label, 'page='. ($page-1) ); + $thumb1 = $sk->makeThumbLinkObj( $this->mTitle, $this->img, $link, $label, 'none', + array( 'page' => $page - 1 ) ); } else { $thumb1 = ''; } if ( $page < $count ) { $label = wfMsg( 'imgmultipagenext' ); - $this->img->selectPage( $page + 1 ); - $link = $sk->makeLinkObj( $this->mTitle, $label, 'page='. ($page+1) ); - $thumb2 = $sk->makeThumbLinkObj( $this->img, $link, $label, 'none' ); + $link = $sk->makeKnownLinkObj( $this->mTitle, $label, 'page='. ($page+1) ); + $thumb2 = $sk->makeThumbLinkObj( $this->mTitle, $this->img, $link, $label, 'none', + array( 'page' => $page + 1 ) ); } else { $thumb2 = ''; } - $select = '
' ; + global $wgScript; + $select = '' . + Xml::hidden( 'title', $this->getTitle()->getPrefixedDbKey() ); $select .= $wgOut->parse( wfMsg( 'imgmultigotopre' ), false ) . '
' . - "$select
$thumb1\n$thumb2
" ); + "$select
$thumb1\n$thumb2
" ); } } else { #if direct link is allowed but it's not a renderable image, show an icon. if ($this->img->isSafeFile()) { $icon= $this->img->iconThumb(); - $wgOut->addHTML( '' ); + $wgOut->addHTML( '' ); } $showLink = true; @@ -300,40 +311,29 @@ class ImagePage extends Article { if ($showLink) { $filename = wfEscapeWikiText( $this->img->getName() ); - // Hacky workaround: for some reason we use the incorrect MIME type - // image/svg for SVG. This should be fixed internally, but at least - // make the displayed type right. - $mime = $this->img->getMimeType(); - if ($mime == 'image/svg') $mime = 'image/svg+xml'; - - $info = wfMsg( 'fileinfo', - ceil($this->img->getSize()/1024.0), - $mime ); - - global $wgContLang; - $dirmark = $wgContLang->getDirMark(); + if (!$this->img->isSafeFile()) { - $warning = wfMsg( 'mediawarning' ); - $wgOut->addWikiText( <<addWikiText( << [[Media:$filename|$filename]]$dirmark - ($info) + $longDesc
$warning
-END +EOT ); } else { - $wgOut->addWikiText( <<addWikiText( << -[[Media:$filename|$filename]]$dirmark ($info) +[[Media:$filename|$filename]]$dirmark $longDesc -END +EOT ); } } - if($this->img->fromSharedDirectory) { + if(!$this->img->isLocal()) { $this->printSharedImageText(); } } else { @@ -346,33 +346,36 @@ END } } + /** + * Show a notice that the file is from a shared repository + */ function printSharedImageText() { - global $wgRepositoryBaseUrl, $wgFetchCommonsDescriptions, $wgOut, $wgUser; - - $url = $wgRepositoryBaseUrl . urlencode($this->mTitle->getDBkey()); - $sharedtext = "
" . wfMsgWikiHtml("sharedupload"); - if ($wgRepositoryBaseUrl && !$wgFetchCommonsDescriptions) { + global $wgOut, $wgUser; + $descUrl = $this->img->getDescriptionUrl(); + $descText = $this->img->getDescriptionText(); + $s = "
" . wfMsgWikiHtml( 'sharedupload' ); + if ( $descUrl ) { $sk = $wgUser->getSkin(); - $title = SpecialPage::getTitleFor( 'Upload' ); - $link = $sk->makeKnownLinkObj($title, wfMsgHtml('shareduploadwiki-linktext'), - array( 'wpDestFile' => urlencode( $this->img->getName() ))); - $sharedtext .= " " . wfMsgWikiHtml('shareduploadwiki', $link); + $link = $sk->makeExternalLink( $descUrl, wfMsg( 'shareduploadwiki-linktext' ) ); + $msg = ( $descText ) ? 'shareduploadwiki-desc' : 'shareduploadwiki'; + $msg = wfMsgExt( $msg, array( 'parseinline', 'replaceafter' ), $link ); + if ( $msg != '-' ) { + # Show message only if not voided by local sysops + $s .= $msg; + } } - $sharedtext .= "
"; - $wgOut->addHTML($sharedtext); + $s .= "
"; + $wgOut->addHTML( $s ); - if ($wgRepositoryBaseUrl && $wgFetchCommonsDescriptions) { - $text = Http::get($url . '?action=render'); - if ($text) - $this->mExtraDescription = $text; + if ( $descText ) { + $this->mExtraDescription = $descText; } } function getUploadUrl() { - global $wgServer; $uploadTitle = SpecialPage::getTitleFor( 'Upload' ); - return $wgServer . $uploadTitle->getLocalUrl( 'wpDestFile=' . urlencode( $this->img->getName() ) ); + return $uploadTitle->getFullUrl( 'wpDestFile=' . urlencode( $this->img->getName() ) ); } /** @@ -382,7 +385,7 @@ END function uploadLinksBox() { global $wgUser, $wgOut; - if( $this->img->fromSharedDirectory ) + if( !$this->img->isLocal() ) return; $sk = $wgUser->getSkin(); @@ -390,13 +393,17 @@ END $wgOut->addHtml( '
    ' ); # "Upload a new version of this file" link - if( $wgUser->isAllowed( 'reupload' ) ) { + if( UploadForm::userCanReUpload($wgUser,$this->img->name) ) { $ulink = $sk->makeExternalLink( $this->getUploadUrl(), wfMsg( 'uploadnewversion-linktext' ) ); - $wgOut->addHtml( "
  • {$ulink}
  • " ); + $wgOut->addHtml( "
  • " ); } - + + # Link to Special:FileDuplicateSearch + $dupeLink = $sk->makeKnownLinkObj( SpecialPage::getTitleFor( 'FileDuplicateSearch', $this->mTitle->getDBkey() ), wfMsgHtml( 'imagepage-searchdupe' ) ); + $wgOut->addHtml( "
  • {$dupeLink}
  • " ); + # External editing link - $elink = $sk->makeKnownLinkObj( $this->mTitle, wfMsg( 'edit-externally' ), 'action=edit&externaledit=true&mode=file' ); + $elink = $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'edit-externally' ), 'action=edit&externaledit=true&mode=file' ); $wgOut->addHtml( '
  • ' . $elink . '
    ' . wfMsgWikiHtml( 'edit-externally-help' ) . '
  • ' ); $wgOut->addHtml( '
' ); @@ -418,28 +425,24 @@ END $sk = $wgUser->getSkin(); - $line = $this->img->nextHistoryLine(); - - if ( $line ) { - $list = new ImageHistoryList( $sk ); + if ( $this->img->exists() ) { + $list = new ImageHistoryList( $sk, $this->current ); + $file = $this->current; + $dims = $file->getDimensionsString(); $s = $list->beginImageHistoryList() . - $list->imageHistoryLine( true, wfTimestamp(TS_MW, $line->img_timestamp), - $this->mTitle->getDBkey(), $line->img_user, - $line->img_user_text, $line->img_size, $line->img_description, - $line->img_width, $line->img_height - ); - - while ( $line = $this->img->nextHistoryLine() ) { - $s .= $list->imageHistoryLine( false, $line->img_timestamp, - $line->oi_archive_name, $line->img_user, - $line->img_user_text, $line->img_size, $line->img_description, - $line->img_width, $line->img_height - ); + $list->imageHistoryLine( true, $file ); + // old image versions + $hist = $this->img->getHistory(); + foreach( $hist as $file ) { + $dims = $file->getDimensionsString(); + $s .= $list->imageHistoryLine( false, $file ); } $s .= $list->endImageHistoryList(); } else { $s=''; } $wgOut->addHTML( $s ); + $this->img->resetHistory(); // free db resources + # Exist check because we don't want to show this on pages where an image # doesn't exist along with the noimage message, that would suck. -ævar if( $wgUseExternalEditor && $this->img->exists() ) { @@ -452,9 +455,9 @@ END { global $wgUser, $wgOut; - $wgOut->addHTML( '\n" ); + $wgOut->addHTML( Xml::element( 'h2', array( 'id' => 'filelinks' ), wfMsg( 'imagelinks' ) ) . "\n" ); - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $page = $dbr->tableName( 'page' ); $imagelinks = $dbr->tableName( 'imagelinks' ); @@ -478,211 +481,36 @@ END $wgOut->addHTML( "\n" ); } - function delete() - { - global $wgUser, $wgOut, $wgRequest; - - $confirm = $wgRequest->wasPosted(); - $reason = $wgRequest->getVal( 'wpReason' ); - $image = $wgRequest->getVal( 'image' ); - $oldimage = $wgRequest->getVal( 'oldimage' ); - - # Only sysops can delete images. Previously ordinary users could delete - # old revisions, but this is no longer the case. - if ( !$wgUser->isAllowed('delete') ) { - $wgOut->permissionRequired( 'delete' ); - return; - } - if ( $wgUser->isBlocked() ) { - return $this->blockedIPpage(); - } - if ( wfReadOnly() ) { - $wgOut->readOnlyPage(); - return; - } - - # Better double-check that it hasn't been deleted yet! - $wgOut->setPagetitle( wfMsg( 'confirmdelete' ) ); - if ( ( !is_null( $image ) ) - && ( '' == trim( $image ) ) ) { - $wgOut->showFatalError( wfMsg( 'cannotdelete' ) ); - return; - } - - $this->img = new Image( $this->mTitle ); - - # Deleting old images doesn't require confirmation - if ( !is_null( $oldimage ) || $confirm ) { - if( $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) { - $this->doDelete( $reason ); - } else { - $wgOut->showFatalError( wfMsg( 'sessionfailure' ) ); - } - return; - } - - if ( !is_null( $image ) ) { - $q = '&image=' . urlencode( $image ); - } else if ( !is_null( $oldimage ) ) { - $q = '&oldimage=' . urlencode( $oldimage ); - } else { - $q = ''; - } - return $this->confirmDelete( $q, $wgRequest->getText( 'wpReason' ) ); - } - - /* - * Delete an image. - * @param $reason User provided reason for deletion. - */ - function doDelete( $reason ) { - global $wgOut, $wgRequest; - - $oldimage = $wgRequest->getVal( 'oldimage' ); - - if ( !is_null( $oldimage ) ) { - if ( strlen( $oldimage ) < 16 ) { - $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) ); - return; - } - if ( strstr( $oldimage, "/" ) || strstr( $oldimage, "\\" ) ) { - $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) ); - return; - } - if ( !$this->doDeleteOldImage( $oldimage ) ) { - return; - } - $deleted = $oldimage; - } else { - $ok = $this->img->delete( $reason ); - if( !$ok ) { - # If the deletion operation actually failed, bug out: - $wgOut->showFileDeleteError( $this->img->getName() ); - return; - } - - # Image itself is now gone, and database is cleaned. - # Now we remove the image description page. - - $article = new Article( $this->mTitle ); - $article->doDeleteArticle( $reason ); # ignore errors - - $deleted = $this->img->getName(); - } - - $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); - $wgOut->setRobotpolicy( 'noindex,nofollow' ); - - $loglink = '[[Special:Log/delete|' . wfMsg( 'deletionlog' ) . ']]'; - $text = wfMsg( 'deletedtext', $deleted, $loglink ); - - $wgOut->addWikiText( $text ); - - $wgOut->returnToMain( false, $this->mTitle->getPrefixedText() ); - } - /** - * @return success + * Delete the file, or an earlier version of it */ - function doDeleteOldImage( $oldimage ) - { - global $wgOut; - - $ok = $this->img->deleteOld( $oldimage, '' ); - if( !$ok ) { - # If we actually have a file and can't delete it, throw an error. - # Something went awry... - $wgOut->showFileDeleteError( "$oldimage" ); - } else { - # Log the deletion - $log = new LogPage( 'delete' ); - $log->addEntry( 'delete', $this->mTitle, wfMsg('deletedrevision',$oldimage) ); - } - return $ok; - } - - function revert() { - global $wgOut, $wgRequest, $wgUser; - - $oldimage = $wgRequest->getText( 'oldimage' ); - if ( strlen( $oldimage ) < 16 ) { - $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) ); - return; - } - if ( strstr( $oldimage, "/" ) || strstr( $oldimage, "\\" ) ) { - $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) ); - return; - } - - if ( wfReadOnly() ) { - $wgOut->readOnlyPage(); - return; - } - if( $wgUser->isAnon() ) { - $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' ); - return; - } - if ( ! $this->mTitle->userCanEdit() ) { - $wgOut->readOnlyPage( $this->getContent(), true ); + public function delete() { + if( !$this->img->exists() || !$this->img->isLocal() ) { + // Standard article deletion + Article::delete(); return; } - if ( $wgUser->isBlocked() ) { - return $this->blockedIPpage(); - } - if( !$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) { - $wgOut->showErrorPage( 'internalerror', 'sessionfailure' ); - return; - } - $name = substr( $oldimage, 15 ); - - $dest = wfImageDir( $name ); - $archive = wfImageArchiveDir( $name ); - $curfile = "{$dest}/{$name}"; - - if ( !is_dir( $dest ) ) wfMkdirParents( $dest ); - if ( !is_dir( $archive ) ) wfMkdirParents( $archive ); - - if ( ! is_file( $curfile ) ) { - $wgOut->showFileNotFoundError( htmlspecialchars( $curfile ) ); - return; - } - $oldver = wfTimestampNow() . "!{$name}"; - - if ( ! rename( $curfile, "${archive}/{$oldver}" ) ) { - $wgOut->showFileRenameError( $curfile, "${archive}/{$oldver}" ); - return; - } - if ( ! copy( "{$archive}/{$oldimage}", $curfile ) ) { - $wgOut->showFileCopyError( "${archive}/{$oldimage}", $curfile ); - return; - } - - # Record upload and update metadata cache - $img = Image::newFromName( $name ); - $img->recordUpload( $oldver, wfMsg( "reverted" ) ); - - $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) ); - $wgOut->setRobotpolicy( 'noindex,nofollow' ); - $wgOut->addHTML( wfMsg( 'imagereverted' ) ); - - $descTitle = $img->getTitle(); - $wgOut->returnToMain( false, $descTitle->getPrefixedText() ); + $deleter = new FileDeleteForm( $this->img ); + $deleter->execute(); } - function blockedIPpage() { - $edit = new EditPage( $this ); - return $edit->blockedIPpage(); + /** + * Revert the file to an earlier version + */ + public function revert() { + $reverter = new FileRevertForm( $this->img ); + $reverter->execute(); } /** * Override handling of action=purge */ function doPurge() { - $this->img = new Image( $this->mTitle ); if( $this->img->exists() ) { wfDebug( "ImagePage::doPurge purging " . $this->img->getName() . "\n" ); $update = new HTMLCacheUpdate( $this->mTitle, 'imagelinks' ); $update->doUpdate(); + $this->img->upgradeRow(); $this->img->purgeCache(); } else { wfDebug( "ImagePage::doPurge no image\n" ); @@ -690,81 +518,172 @@ END parent::doPurge(); } + /** + * Display an error with a wikitext description + */ + function showError( $description ) { + global $wgOut; + $wgOut->setPageTitle( wfMsg( "internalerror" ) ); + $wgOut->setRobotpolicy( "noindex,nofollow" ); + $wgOut->setArticleRelated( false ); + $wgOut->enableClientCache( false ); + $wgOut->addWikiText( $description ); + } + } /** - * @todo document - * @package MediaWiki + * Builds the image revision log shown on image pages + * + * @addtogroup Media */ class ImageHistoryList { - function ImageHistoryList( &$skin ) { - $this->skin =& $skin; - } - function beginImageHistoryList() { - $s = "\n

" . wfMsg( 'imghistory' ) . "

\n" . - "

" . wfMsg( 'imghistlegend' ) . "

\n".'
    '; - return $s; - } + protected $img, $skin, $title, $repo; - function endImageHistoryList() { - $s = "
\n"; - return $s; + public function __construct( $skin, $img ) { + $this->skin = $skin; + $this->img = $img; + $this->title = $img->getTitle(); } - function imageHistoryLine( $iscur, $timestamp, $img, $user, $usertext, $size, $description, $width, $height ) { - global $wgUser, $wgLang, $wgTitle, $wgContLang; + public function beginImageHistoryList() { + global $wgOut, $wgUser; + $deleteColumn = $wgUser->isAllowed( 'delete' ) || $wgUser->isAllowed( 'deleterevision' ); + return Xml::element( 'h2', array( 'id' => 'filehistory' ), wfMsg( 'filehist' ) ) + . $wgOut->parse( wfMsgNoTrans( 'filehist-help' ) ) + . Xml::openElement( 'table', array( 'class' => 'filehistory' ) ) . "\n" + . '' + . ( $this->img->isLocal() && $deleteColumn ? '' : '' ) + . '' . wfMsgHtml( 'filehist-datetime' ) . '' + . '' . wfMsgHtml( 'filehist-user' ) . '' + . '' . wfMsgHtml( 'filehist-dimensions' ) . '' + . '' . wfMsgHtml( 'filehist-filesize' ) . '' + . '' . wfMsgHtml( 'filehist-comment' ) . '' + . "\n"; + } - $datetime = $wgLang->timeanddate( $timestamp, true ); - $del = wfMsg( 'deleteimg' ); - $delall = wfMsg( 'deleteimgcompletely' ); - $cur = wfMsg( 'cur' ); + public function endImageHistoryList() { + return "\n"; + } - if ( $iscur ) { - $url = Image::imageUrl( $img ); - $rlink = $cur; - if ( $wgUser->isAllowed('delete') ) { - $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() . - '&action=delete' ); - $style = $this->skin->getInternalLinkAttributes( $link, $delall ); + public function imageHistoryLine( $iscur, $file ) { + global $wgUser, $wgLang, $wgContLang, $wgTitle; + + $timestamp = wfTimestamp(TS_MW, $file->getTimestamp()); + $img = $iscur ? $file->getName() : $file->getArchiveName(); + $user = $file->getUser('id'); + $usertext = $file->getUser('text'); + $size = $file->getSize(); + $description = $file->getDescription(); + $dims = $file->getDimensionsString(); + $sha1 = $file->getSha1(); + + $local = $this->img->isLocal(); + $row = ''; + + // Deletion link + if( $local && ($wgUser->isAllowed('delete') || $wgUser->isAllowed('deleterevision') ) ) { + $row .= ''; + # Link to remove from history + if( $wgUser->isAllowed( 'delete' ) ) { + $q = array(); + $q[] = 'action=delete'; + if( !$iscur ) + $q[] = 'oldimage=' . urlencode( $img ); + $row .= $this->skin->makeKnownLinkObj( + $this->title, + wfMsgHtml( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' ), + implode( '&', $q ) + ); + $row .= '
'; + } + # Link to hide content + if( $wgUser->isAllowed( 'deleterevision' ) ) { + $revdel = SpecialPage::getTitleFor( 'Revisiondelete' ); + // If file is top revision or locked from this user, don't link + if( $iscur || !$file->userCan(File::DELETED_RESTRICTED) ) { + $del = wfMsgHtml( 'rev-delundel' ); + } else { + // If the file was hidden, link to sha-1 + list($ts,$name) = explode('!',$img,2); + $del = $this->skin->makeKnownLinkObj( $revdel, wfMsg( 'rev-delundel' ), + 'target=' . urlencode( $wgTitle->getPrefixedText() ) . + '&oldimage=' . urlencode( $ts ) ); + // Bolden oversighted content + if( $file->isDeleted(File::DELETED_RESTRICTED) ) + $del = "$del"; + } + $row .= "$del"; + } + $row .= ''; + } - $dlink = ''.$delall.''; + // Reversion link/current indicator + $row .= ''; + if( $iscur ) { + $row .= wfMsgHtml( 'filehist-current' ); + } elseif( $local && $wgUser->isLoggedIn() && $this->title->userCan( 'edit' ) ) { + if( $file->isDeleted(File::DELETED_FILE) ) { + $row .= wfMsgHtml('filehist-revert'); } else { - $dlink = $del; + $q = array(); + $q[] = 'action=revert'; + $q[] = 'oldimage=' . urlencode( $img ); + $q[] = 'wpEditToken=' . urlencode( $wgUser->editToken( $img ) ); + $row .= $this->skin->makeKnownLinkObj( $this->title, + wfMsgHtml( 'filehist-revert' ), + implode( '&', $q ) ); } + } + $row .= ''; + + // Date/time and image link + $row .= ''; + if( !$file->userCan(File::DELETED_FILE) ) { + # Don't link to unviewable files + $row .= '' . $wgLang->timeAndDate( $timestamp, true ) . ''; + } else if( $file->isDeleted(File::DELETED_FILE) ) { + $revdel = SpecialPage::getTitleFor( 'Revisiondelete' ); + # Make a link to review the image + $url = $this->skin->makeKnownLinkObj( $revdel, $wgLang->timeAndDate( $timestamp, true ), + "target=".$wgTitle->getPrefixedText()."&file=$sha1.".$this->img->getExtension() ); + $row .= ''.$url.''; } else { - $url = htmlspecialchars( wfImageArchiveUrl( $img ) ); - if( $wgUser->getID() != 0 && $wgTitle->userCanEdit() ) { - $token = urlencode( $wgUser->editToken( $img ) ); - $rlink = $this->skin->makeKnownLinkObj( $wgTitle, - wfMsg( 'revertimg' ), 'action=revert&oldimage=' . - urlencode( $img ) . "&wpEditToken=$token" ); - $dlink = $this->skin->makeKnownLinkObj( $wgTitle, - $del, 'action=delete&oldimage=' . urlencode( $img ) . - "&wpEditToken=$token" ); - } else { - # Having live active links for non-logged in users - # means that bots and spiders crawling our site can - # inadvertently change content. Baaaad idea. - $rlink = wfMsg( 'revertimg' ); - $dlink = $del; - } + $url = $iscur ? $this->img->getUrl() : $this->img->getArchiveUrl( $img ); + $row .= Xml::element( 'a', + array( 'href' => $url ), + $wgLang->timeAndDate( $timestamp, true ) ); + } + + $row .= ''; + + // Uploading user + $row .= ''; + if( $local ) { + // Hide deleted usernames + if( $file->isDeleted(File::DELETED_USER) ) + $row .= '' . wfMsgHtml( 'rev-deleted-user' ) . ''; + else + $row .= $this->skin->userLink( $user, $usertext ) . + $this->skin->userToolLinks( $user, $usertext ); + } else { + $row .= htmlspecialchars( $usertext ); } - - $userlink = $this->skin->userLink( $user, $usertext ) . $this->skin->userToolLinks( $user, $usertext ); - $nbytes = wfMsgExt( 'nbytes', array( 'parsemag', 'escape' ), - $wgLang->formatNum( $size ) ); - $widthheight = wfMsg( 'widthheight', $width, $height ); - $style = $this->skin->getInternalLinkAttributes( $url, $datetime ); + $row .= ''; - $s = "
  • ({$dlink}) ({$rlink}) {$datetime} . . {$userlink} . . {$widthheight} ({$nbytes})"; + // Image dimensions + $row .= '' . htmlspecialchars( $dims ) . ''; - $s .= $this->skin->commentBlock( $description, $wgTitle ); - $s .= "
  • \n"; - return $s; - } - -} + // File size + $row .= '' . $this->skin->formatSize( $size ) . ''; + // Don't show deleted descriptions + if ( $file->isDeleted(File::DELETED_COMMENT) ) + $row .= '' . wfMsgHtml('rev-deleted-comment') . ''; + else + $row .= '' . $this->skin->commentBlock( $description, $this->title ) . ''; -?> + return "{$row}\n"; + } +}