From c1f9b1f7b1b77776192048005dcc66dcf3df2bfb Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sat, 27 Dec 2014 15:41:37 +0100 Subject: Update to MediaWiki 1.24.1 --- includes/ImagePage.php | 1402 ------------------------------------------------ 1 file changed, 1402 deletions(-) delete mode 100644 includes/ImagePage.php (limited to 'includes/ImagePage.php') diff --git a/includes/ImagePage.php b/includes/ImagePage.php deleted file mode 100644 index d696a17c..00000000 --- a/includes/ImagePage.php +++ /dev/null @@ -1,1402 +0,0 @@ -mPage->setFile( $file ); - $this->displayImg = $file; - $this->fileLoaded = true; - } - - protected function loadFile() { - if ( $this->fileLoaded ) { - return; - } - $this->fileLoaded = true; - - $this->displayImg = $img = false; - wfRunHooks( 'ImagePageFindFile', array( $this, &$img, &$this->displayImg ) ); - if ( !$img ) { // not set by hook? - $img = wfFindFile( $this->getTitle() ); - if ( !$img ) { - $img = wfLocalFile( $this->getTitle() ); - } - } - $this->mPage->setFile( $img ); - if ( !$this->displayImg ) { // not set by hook? - $this->displayImg = $img; - } - $this->repo = $img->getRepo(); - } - - /** - * Handler for action=render - * Include body text only; none of the image extras - */ - public function render() { - $this->getContext()->getOutput()->setArticleBodyOnly( true ); - parent::view(); - } - - public function view() { - global $wgShowEXIF; - - $out = $this->getContext()->getOutput(); - $request = $this->getContext()->getRequest(); - $diff = $request->getVal( 'diff' ); - $diffOnly = $request->getBool( 'diffonly', $this->getContext()->getUser()->getOption( 'diffonly' ) ); - - if ( $this->getTitle()->getNamespace() != NS_FILE || ( $diff !== null && $diffOnly ) ) { - parent::view(); - return; - } - - $this->loadFile(); - - if ( $this->getTitle()->getNamespace() == NS_FILE && $this->mPage->getFile()->getRedirected() ) { - if ( $this->getTitle()->getDBkey() == $this->mPage->getFile()->getName() || $diff !== null ) { - // mTitle is the same as the redirect target so ask Article - // to perform the redirect for us. - $request->setVal( 'diffonly', 'true' ); - parent::view(); - return; - } else { - // mTitle is not the same as the redirect target so it is - // probably the redirect page itself. Fake the redirect symbol - $out->setPageTitle( $this->getTitle()->getPrefixedText() ); - $out->addHTML( $this->viewRedirect( Title::makeTitle( NS_FILE, $this->mPage->getFile()->getName() ), - /* $appendSubtitle */ true, /* $forceKnown */ true ) ); - $this->mPage->doViewUpdates( $this->getContext()->getUser() ); - return; - } - } - - if ( $wgShowEXIF && $this->displayImg->exists() ) { - // @todo FIXME: Bad interface, see note on MediaHandler::formatMetadata(). - $formattedMetadata = $this->displayImg->formatMetadata(); - $showmeta = $formattedMetadata !== false; - } else { - $showmeta = false; - } - - if ( !$diff && $this->displayImg->exists() ) { - $out->addHTML( $this->showTOC( $showmeta ) ); - } - - if ( !$diff ) { - $this->openShowImage(); - } - - # No need to display noarticletext, we use our own message, output in openShowImage() - if ( $this->mPage->getID() ) { - # NS_FILE is in the user language, but this section (the actual wikitext) - # should be in page content language - $pageLang = $this->getTitle()->getPageViewLanguage(); - $out->addHTML( Xml::openElement( 'div', array( 'id' => 'mw-imagepage-content', - 'lang' => $pageLang->getHtmlCode(), 'dir' => $pageLang->getDir(), - 'class' => 'mw-content-' . $pageLang->getDir() ) ) ); - - parent::view(); - - $out->addHTML( Xml::closeElement( 'div' ) ); - } else { - # Just need to set the right headers - $out->setArticleFlag( true ); - $out->setPageTitle( $this->getTitle()->getPrefixedText() ); - $this->mPage->doViewUpdates( $this->getContext()->getUser() ); - } - - # Show shared description, if needed - if ( $this->mExtraDescription ) { - $fol = wfMessage( 'shareddescriptionfollows' ); - if ( !$fol->isDisabled() ) { - $out->addWikiText( $fol->plain() ); - } - $out->addHTML( '
' . $this->mExtraDescription . "
\n" ); - } - - $this->closeShowImage(); - $this->imageHistory(); - // TODO: Cleanup the following - - $out->addHTML( Xml::element( 'h2', - array( 'id' => 'filelinks' ), - wfMessage( 'imagelinks' )->text() ) . "\n" ); - $this->imageDupes(); - # @todo FIXME: For some freaky reason, we can't redirect to foreign images. - # Yet we return metadata about the target. Definitely an issue in the FileRepo - $this->imageLinks(); - - # Allow extensions to add something after the image links - $html = ''; - wfRunHooks( 'ImagePageAfterImageLinks', array( $this, &$html ) ); - if ( $html ) { - $out->addHTML( $html ); - } - - if ( $showmeta ) { - $out->addHTML( Xml::element( - 'h2', - array( 'id' => 'metadata' ), - wfMessage( 'metadata' )->text() ) . "\n" ); - $out->addWikiText( $this->makeMetadataTable( $formattedMetadata ) ); - $out->addModules( array( 'mediawiki.action.view.metadata' ) ); - } - - // Add remote Filepage.css - if ( !$this->repo->isLocal() ) { - $css = $this->repo->getDescriptionStylesheetUrl(); - if ( $css ) { - $out->addStyle( $css ); - } - } - // always show the local local Filepage.css, bug 29277 - $out->addModuleStyles( 'filepage' ); - } - - /** - * @return File - */ - public function getDisplayedFile() { - $this->loadFile(); - return $this->displayImg; - } - - /** - * Create the TOC - * - * @param $metadata Boolean: whether or not to show the metadata link - * @return String - */ - protected function showTOC( $metadata ) { - $r = array( - '
  • ' . wfMessage( 'file-anchor-link' )->escaped() . '
  • ', - '
  • ' . wfMessage( 'filehist' )->escaped() . '
  • ', - '
  • ' . wfMessage( 'imagelinks' )->escaped() . '
  • ', - ); - if ( $metadata ) { - $r[] = '
  • ' . wfMessage( 'metadata' )->escaped() . '
  • '; - } - - wfRunHooks( 'ImagePageShowTOC', array( $this, &$r ) ); - - return ''; - } - - /** - * Make a table with metadata to be shown in the output page. - * - * @todo FIXME: Bad interface, see note on MediaHandler::formatMetadata(). - * - * @param array $metadata the array containing the Exif data - * @return String The metadata table. This is treated as Wikitext (!) - */ - protected function makeMetadataTable( $metadata ) { - $r = "
    "; - $r .= wfMessage( 'metadata-help' )->plain(); - $r .= "\n"; - foreach ( $metadata as $type => $stuff ) { - foreach ( $stuff as $v ) { - # @todo FIXME: Why is this using escapeId for a class?! - $class = Sanitizer::escapeId( $v['id'] ); - if ( $type == 'collapsed' ) { - $class .= ' collapsable'; // sic - } - $r .= "\n"; - $r .= "\n"; - $r .= "\n"; - } - } - $r .= "
    {$v['name']}{$v['value']}
    \n
    \n"; - return $r; - } - - /** - * Overloading Article's getContentObject method. - * - * Omit noarticletext if sharedupload; text will be fetched from the - * shared upload server if possible. - * @return string - */ - public function getContentObject() { - $this->loadFile(); - if ( $this->mPage->getFile() && !$this->mPage->getFile()->isLocal() && 0 == $this->getID() ) { - return null; - } - return parent::getContentObject(); - } - - protected function openShowImage() { - global $wgImageLimits, $wgEnableUploads, $wgSend404Code; - - $this->loadFile(); - $out = $this->getContext()->getOutput(); - $user = $this->getContext()->getUser(); - $lang = $this->getContext()->getLanguage(); - $dirmark = $lang->getDirMarkEntity(); - $request = $this->getContext()->getRequest(); - - $max = $this->getImageLimitsFromOption( $user, 'imagesize' ); - $maxWidth = $max[0]; - $maxHeight = $max[1]; - - if ( $this->displayImg->exists() ) { - # image - $page = $request->getIntOrNull( 'page' ); - if ( is_null( $page ) ) { - $params = array(); - $page = 1; - } else { - $params = array( 'page' => $page ); - } - - $renderLang = $request->getVal( 'lang' ); - if ( !is_null( $renderLang ) ) { - $params['lang'] = $renderLang; - } - - $width_orig = $this->displayImg->getWidth( $page ); - $width = $width_orig; - $height_orig = $this->displayImg->getHeight( $page ); - $height = $height_orig; - - $filename = wfEscapeWikiText( $this->displayImg->getName() ); - $linktext = $filename; - - wfRunHooks( 'ImageOpenShowImageInlineBefore', array( &$this, &$out ) ); - - if ( $this->displayImg->allowInlineDisplay() ) { - # image - - # "Download high res version" link below the image - # $msgsize = wfMessage( 'file-info-size', $width_orig, $height_orig, Linker::formatSize( $this->displayImg->getSize() ), $mime )->escaped(); - # We'll show a thumbnail of this image - if ( $width > $maxWidth || $height > $maxHeight ) { - # Calculate the thumbnail size. - # First case, the limiting factor is the width, not the height. - if ( $width / $height >= $maxWidth / $maxHeight ) { // FIXME: Possible division by 0. bug 36911 - $height = round( $height * $maxWidth / $width ); // FIXME: Possible division by 0. bug 36911 - $width = $maxWidth; - # Note that $height <= $maxHeight now. - } else { - $newwidth = floor( $width * $maxHeight / $height ); // FIXME: Possible division by 0. bug 36911 - $height = round( $height * $newwidth / $width ); // FIXME: Possible division by 0. bug 36911 - $width = $newwidth; - # Note that $height <= $maxHeight now, but might not be identical - # because of rounding. - } - $linktext = wfMessage( 'show-big-image' )->escaped(); - if ( $this->displayImg->getRepo()->canTransformVia404() ) { - $thumbSizes = $wgImageLimits; - } else { - # Creating thumb links triggers thumbnail generation. - # Just generate the thumb for the current users prefs. - $thumbSizes = array( $this->getImageLimitsFromOption( $user, 'thumbsize' ) ); - } - # Generate thumbnails or thumbnail links as needed... - $otherSizes = array(); - foreach ( $thumbSizes as $size ) { - if ( $size[0] < $width_orig && $size[1] < $height_orig - && $size[0] != $width && $size[1] != $height ) - { - $sizeLink = $this->makeSizeLink( $params, $size[0], $size[1] ); - if ( $sizeLink ) { - $otherSizes[] = $sizeLink; - } - } - } - $msgsmall = ''; - $sizeLinkBigImagePreview = $this->makeSizeLink( $params, $width, $height ); - if ( $sizeLinkBigImagePreview ) { - $msgsmall .= wfMessage( 'show-big-image-preview' )-> - rawParams( $sizeLinkBigImagePreview )-> - parse(); - } - if ( count( $otherSizes ) ) { - $msgsmall .= ' ' . - Html::rawElement( 'span', array( 'class' => 'mw-filepage-other-resolutions' ), - wfMessage( 'show-big-image-other' )->rawParams( $lang->pipeList( $otherSizes ) )-> - params( count( $otherSizes ) )->parse() - ); - } - } elseif ( $width == 0 && $height == 0 ) { - # Some sort of audio file that doesn't have dimensions - # Don't output a no hi res message for such a file - $msgsmall = ''; - } elseif ( $this->displayImg->isVectorized() ) { - # For vectorized images, full size is just the frame size - $msgsmall = ''; - } else { - # Image is small enough to show full size on image page - $msgsmall = wfMessage( 'file-nohires' )->parse(); - } - - $params['width'] = $width; - $params['height'] = $height; - $thumbnail = $this->displayImg->transform( $params ); - - $anchorclose = Html::rawElement( 'div', array( 'class' => 'mw-filepage-resolutioninfo' ), $msgsmall ); - - $isMulti = $this->displayImg->isMultipage() && $this->displayImg->pageCount() > 1; - if ( $isMulti ) { - $out->addModules( 'mediawiki.page.image.pagination' ); - $out->addHTML( '
    ' ); - } - - if ( $thumbnail ) { - $options = array( - 'alt' => $this->displayImg->getTitle()->getPrefixedText(), - 'file-link' => true, - ); - $out->addHTML( '\n" ); - } - - if ( $isMulti ) { - $count = $this->displayImg->pageCount(); - - if ( $page > 1 ) { - $label = $out->parse( wfMessage( 'imgmultipageprev' )->text(), false ); - // on the client side, this link is generated in ajaxifyPageNavigation() - // in the mediawiki.page.image.pagination module - $link = Linker::linkKnown( - $this->getTitle(), - $label, - array(), - array( 'page' => $page - 1 ) - ); - $thumb1 = Linker::makeThumbLinkObj( $this->getTitle(), $this->displayImg, $link, $label, 'none', - array( 'page' => $page - 1 ) ); - } else { - $thumb1 = ''; - } - - if ( $page < $count ) { - $label = wfMessage( 'imgmultipagenext' )->text(); - $link = Linker::linkKnown( - $this->getTitle(), - $label, - array(), - array( 'page' => $page + 1 ) - ); - $thumb2 = Linker::makeThumbLinkObj( $this->getTitle(), $this->displayImg, $link, $label, 'none', - array( 'page' => $page + 1 ) ); - } else { - $thumb2 = ''; - } - - global $wgScript; - - $formParams = array( - 'name' => 'pageselector', - 'action' => $wgScript, - ); - $options = array(); - for ( $i = 1; $i <= $count; $i++ ) { - $options[] = Xml::option( $lang->formatNum( $i ), $i, $i == $page ); - } - $select = Xml::tags( 'select', - array( 'id' => 'pageselector', 'name' => 'page' ), - implode( "\n", $options ) ); - - $out->addHTML( - '
    ' . - Xml::openElement( 'form', $formParams ) . - Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . - wfMessage( 'imgmultigoto' )->rawParams( $select )->parse() . - Xml::submitButton( wfMessage( 'imgmultigo' )->text() ) . - Xml::closeElement( 'form' ) . - "
    $thumb1\n$thumb2
    " - ); - } - } elseif ( $this->displayImg->isSafeFile() ) { - # if direct link is allowed but it's not a renderable image, show an icon. - $icon = $this->displayImg->iconThumb(); - - $out->addHTML( '\n" ); - } - - $longDesc = wfMessage( 'parentheses', $this->displayImg->getLongDesc() )->text(); - - $medialink = "[[Media:$filename|$linktext]]"; - - if ( !$this->displayImg->isSafeFile() ) { - $warning = wfMessage( 'mediawarning' )->plain(); - // dirmark is needed here to separate the file name, which - // most likely ends in Latin characters, from the description, - // which may begin with the file type. In RTL environment - // this will get messy. - // The dirmark, however, must not be immediately adjacent - // to the filename, because it can get copied with it. - // See bug 25277. - $out->addWikiText( <<{$medialink} $dirmark$longDesc -
    $warning
    -EOT - ); - } else { - $out->addWikiText( <<{$medialink} {$dirmark}$longDesc - -EOT - ); - } - - // Add cannot animate thumbnail warning - if ( !$this->displayImg->canAnimateThumbIfAppropriate() ) { - // Include the extension so wiki admins can - // customize it on a per file-type basis - // (aka say things like use format X instead). - // additionally have a specific message for - // file-no-thumb-animation-gif - $ext = $this->displayImg->getExtension(); - $noAnimMesg = wfMessageFallback( - 'file-no-thumb-animation-' . $ext, - 'file-no-thumb-animation' - )->plain(); - - $out->addWikiText( <<{$noAnimMesg} -EOT - ); - } - - if ( !$this->displayImg->isLocal() ) { - $this->printSharedImageText(); - } - } else { - # Image does not exist - if ( !$this->getID() ) { - # No article exists either - # Show deletion log to be consistent with normal articles - LogEventsList::showLogExtract( - $out, - array( 'delete', 'move' ), - $this->getTitle()->getPrefixedText(), - '', - array( 'lim' => 10, - 'conds' => array( "log_action != 'revision'" ), - 'showIfEmpty' => false, - 'msgKey' => array( 'moveddeleted-notice' ) - ) - ); - } - - if ( $wgEnableUploads && $user->isAllowed( 'upload' ) ) { - // Only show an upload link if the user can upload - $uploadTitle = SpecialPage::getTitleFor( 'Upload' ); - $nofile = array( - 'filepage-nofile-link', - $uploadTitle->getFullURL( array( 'wpDestFile' => $this->mPage->getFile()->getName() ) ) - ); - } else { - $nofile = 'filepage-nofile'; - } - // Note, if there is an image description page, but - // no image, then this setRobotPolicy is overridden - // by Article::View(). - $out->setRobotPolicy( 'noindex,nofollow' ); - $out->wrapWikiMsg( "", $nofile ); - if ( !$this->getID() && $wgSend404Code ) { - // If there is no image, no shared image, and no description page, - // output a 404, to be consistent with articles. - $request->response()->header( 'HTTP/1.1 404 Not Found' ); - } - } - $out->setFileVersion( $this->displayImg ); - } - - /** - * Creates an thumbnail of specified size and returns an HTML link to it - * @param array $params Scaler parameters - * @param $width int - * @param $height int - * @return string - */ - private function makeSizeLink( $params, $width, $height ) { - $params['width'] = $width; - $params['height'] = $height; - $thumbnail = $this->displayImg->transform( $params ); - if ( $thumbnail && !$thumbnail->isError() ) { - return Html::rawElement( 'a', array( - 'href' => $thumbnail->getUrl(), - 'class' => 'mw-thumbnail-link' - ), wfMessage( 'show-big-image-size' )->numParams( - $thumbnail->getWidth(), $thumbnail->getHeight() - )->parse() ); - } else { - return ''; - } - } - - /** - * Show a notice that the file is from a shared repository - */ - protected function printSharedImageText() { - $out = $this->getContext()->getOutput(); - $this->loadFile(); - - $descUrl = $this->mPage->getFile()->getDescriptionUrl(); - $descText = $this->mPage->getFile()->getDescriptionText(); - - /* Add canonical to head if there is no local page for this shared file */ - if ( $descUrl && $this->mPage->getID() == 0 ) { - $out->setCanonicalUrl( $descUrl ); - } - - $wrap = "
    \n$1\n
    \n"; - $repo = $this->mPage->getFile()->getRepo()->getDisplayName(); - - if ( $descUrl && $descText && wfMessage( 'sharedupload-desc-here' )->plain() !== '-' ) { - $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-here', $repo, $descUrl ) ); - } elseif ( $descUrl && wfMessage( 'sharedupload-desc-there' )->plain() !== '-' ) { - $out->wrapWikiMsg( $wrap, array( 'sharedupload-desc-there', $repo, $descUrl ) ); - } else { - $out->wrapWikiMsg( $wrap, array( 'sharedupload', $repo ), ''/*BACKCOMPAT*/ ); - } - - if ( $descText ) { - $this->mExtraDescription = $descText; - } - } - - public function getUploadUrl() { - $this->loadFile(); - $uploadTitle = SpecialPage::getTitleFor( 'Upload' ); - return $uploadTitle->getFullURL( array( - 'wpDestFile' => $this->mPage->getFile()->getName(), - 'wpForReUpload' => 1 - ) ); - } - - /** - * Print out the various links at the bottom of the image page, e.g. reupload, - * external editing (and instructions link) etc. - */ - protected function uploadLinksBox() { - global $wgEnableUploads; - - if ( !$wgEnableUploads ) { - return; - } - - $this->loadFile(); - if ( !$this->mPage->getFile()->isLocal() ) { - return; - } - - $out = $this->getContext()->getOutput(); - $out->addHTML( "
      \n" ); - - # "Upload a new version of this file" link - $canUpload = $this->getTitle()->userCan( 'upload', $this->getContext()->getUser() ); - if ( $canUpload && UploadBase::userCanReUpload( $this->getContext()->getUser(), $this->mPage->getFile()->name ) ) { - $ulink = Linker::makeExternalLink( $this->getUploadUrl(), wfMessage( 'uploadnewversion-linktext' )->text() ); - $out->addHTML( "
    • {$ulink}
    • \n" ); - } else { - $out->addHTML( "
    • " . $this->getContext()->msg( 'upload-disallowed-here' )->escaped() . "
    • \n" ); - } - - $out->addHTML( "
    \n" ); - } - - protected function closeShowImage() { } # For overloading - - /** - * If the page we've just displayed is in the "Image" namespace, - * we follow it with an upload history of the image and its usage. - */ - protected function imageHistory() { - $this->loadFile(); - $out = $this->getContext()->getOutput(); - $pager = new ImageHistoryPseudoPager( $this ); - $out->addHTML( $pager->getBody() ); - $out->preventClickjacking( $pager->getPreventClickjacking() ); - - $this->mPage->getFile()->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 ( $this->mPage->getFile()->exists() ) { - $this->uploadLinksBox(); - } - } - - /** - * @param $target - * @param $limit - * @return ResultWrapper - */ - protected function queryImageLinks( $target, $limit ) { - $dbr = wfGetDB( DB_SLAVE ); - - return $dbr->select( - array( 'imagelinks', 'page' ), - array( 'page_namespace', 'page_title', 'page_is_redirect', 'il_to' ), - array( 'il_to' => $target, 'il_from = page_id' ), - __METHOD__, - array( 'LIMIT' => $limit + 1, 'ORDER BY' => 'il_from', ) - ); - } - - protected function imageLinks() { - $limit = 100; - - $out = $this->getContext()->getOutput(); - $res = $this->queryImageLinks( $this->getTitle()->getDBkey(), $limit + 1 ); - $rows = array(); - $redirects = array(); - foreach ( $res as $row ) { - if ( $row->page_is_redirect ) { - $redirects[$row->page_title] = array(); - } - $rows[] = $row; - } - $count = count( $rows ); - - $hasMore = $count > $limit; - if ( !$hasMore && count( $redirects ) ) { - $res = $this->queryImageLinks( array_keys( $redirects ), - $limit - count( $rows ) + 1 ); - foreach ( $res as $row ) { - $redirects[$row->il_to][] = $row; - $count++; - } - $hasMore = ( $res->numRows() + count( $rows ) ) > $limit; - } - - if ( $count == 0 ) { - $out->wrapWikiMsg( - Html::rawElement( 'div', - array( 'id' => 'mw-imagepage-nolinkstoimage' ), "\n$1\n" ), - 'nolinkstoimage' - ); - return; - } - - $out->addHTML( "
    \n" ); - if ( !$hasMore ) { - $out->addWikiMsg( 'linkstoimage', $count ); - } else { - // More links than the limit. Add a link to [[Special:Whatlinkshere]] - $out->addWikiMsg( 'linkstoimage-more', - $this->getContext()->getLanguage()->formatNum( $limit ), - $this->getTitle()->getPrefixedDBkey() - ); - } - - $out->addHTML( - Html::openElement( 'ul', - array( 'class' => 'mw-imagepage-linkstoimage' ) ) . "\n" - ); - $count = 0; - - // Sort the list by namespace:title - usort( $rows, array( $this, 'compare' ) ); - - // Create links for every element - $currentCount = 0; - foreach ( $rows as $element ) { - $currentCount++; - if ( $currentCount > $limit ) { - break; - } - - $query = array(); - # Add a redirect=no to make redirect pages reachable - if ( isset( $redirects[$element->page_title] ) ) { - $query['redirect'] = 'no'; - } - $link = Linker::linkKnown( - Title::makeTitle( $element->page_namespace, $element->page_title ), - null, array(), $query - ); - if ( !isset( $redirects[$element->page_title] ) ) { - # No redirects - $liContents = $link; - } elseif ( count( $redirects[$element->page_title] ) === 0 ) { - # Redirect without usages - $liContents = wfMessage( 'linkstoimage-redirect' )->rawParams( $link, '' )->parse(); - } else { - # Redirect with usages - $li = ''; - foreach ( $redirects[$element->page_title] as $row ) { - $currentCount++; - if ( $currentCount > $limit ) { - break; - } - - $link2 = Linker::linkKnown( Title::makeTitle( $row->page_namespace, $row->page_title ) ); - $li .= Html::rawElement( - 'li', - array( 'class' => 'mw-imagepage-linkstoimage-ns' . $element->page_namespace ), - $link2 - ) . "\n"; - } - - $ul = Html::rawElement( - 'ul', - array( 'class' => 'mw-imagepage-redirectstofile' ), - $li - ) . "\n"; - $liContents = wfMessage( 'linkstoimage-redirect' )->rawParams( - $link, $ul )->parse(); - } - $out->addHTML( Html::rawElement( - 'li', - array( 'class' => 'mw-imagepage-linkstoimage-ns' . $element->page_namespace ), - $liContents - ) . "\n" - ); - - }; - $out->addHTML( Html::closeElement( 'ul' ) . "\n" ); - $res->free(); - - // Add a links to [[Special:Whatlinkshere]] - if ( $count > $limit ) { - $out->addWikiMsg( 'morelinkstoimage', $this->getTitle()->getPrefixedDBkey() ); - } - $out->addHTML( Html::closeElement( 'div' ) . "\n" ); - } - - protected function imageDupes() { - $this->loadFile(); - $out = $this->getContext()->getOutput(); - - $dupes = $this->mPage->getDuplicates(); - if ( count( $dupes ) == 0 ) { - return; - } - - $out->addHTML( "
    \n" ); - $out->addWikiMsg( 'duplicatesoffile', - $this->getContext()->getLanguage()->formatNum( count( $dupes ) ), $this->getTitle()->getDBkey() - ); - $out->addHTML( "
      \n" ); - - /** - * @var $file File - */ - foreach ( $dupes as $file ) { - $fromSrc = ''; - if ( $file->isLocal() ) { - $link = Linker::linkKnown( $file->getTitle() ); - } else { - $link = Linker::makeExternalLink( $file->getDescriptionUrl(), - $file->getTitle()->getPrefixedText() ); - $fromSrc = wfMessage( 'shared-repo-from', $file->getRepo()->getDisplayName() )->text(); - } - $out->addHTML( "
    • {$link} {$fromSrc}
    • \n" ); - } - $out->addHTML( "
    \n" ); - } - - /** - * Delete the file, or an earlier version of it - */ - public function delete() { - $file = $this->mPage->getFile(); - if ( !$file->exists() || !$file->isLocal() || $file->getRedirected() ) { - // Standard article deletion - parent::delete(); - return; - } - - $deleter = new FileDeleteForm( $file ); - $deleter->execute(); - } - - /** - * Display an error with a wikitext description - * - * @param $description String - */ - function showError( $description ) { - $out = $this->getContext()->getOutput(); - $out->setPageTitle( wfMessage( 'internalerror' ) ); - $out->setRobotPolicy( 'noindex,nofollow' ); - $out->setArticleRelated( false ); - $out->enableClientCache( false ); - $out->addWikiText( $description ); - } - - /** - * Callback for usort() to do link sorts by (namespace, title) - * Function copied from Title::compare() - * - * @param $a object page to compare with - * @param $b object page to compare with - * @return Integer: result of string comparison, or namespace comparison - */ - protected function compare( $a, $b ) { - if ( $a->page_namespace == $b->page_namespace ) { - return strcmp( $a->page_title, $b->page_title ); - } else { - return $a->page_namespace - $b->page_namespace; - } - } - - /** - * Returns the corresponding $wgImageLimits entry for the selected user option - * - * @param $user User - * @param string $optionName Name of a option to check, typically imagesize or thumbsize - * @return array - * @since 1.21 - */ - public function getImageLimitsFromOption( $user, $optionName ) { - global $wgImageLimits; - - $option = $user->getIntOption( $optionName ); - if ( !isset( $wgImageLimits[$option] ) ) { - $option = User::getDefaultOption( $optionName ); - } - - // The user offset might still be incorrect, specially if - // $wgImageLimits got changed (see bug #8858). - if ( !isset( $wgImageLimits[$option] ) ) { - // Default to the first offset in $wgImageLimits - $option = 0; - } - - return isset( $wgImageLimits[$option] ) - ? $wgImageLimits[$option] - : array( 800, 600 ); // if nothing is set, fallback to a hardcoded default - } -} - -/** - * Builds the image revision log shown on image pages - * - * @ingroup Media - */ -class ImageHistoryList extends ContextSource { - - /** - * @var Title - */ - protected $title; - - /** - * @var File - */ - protected $img; - - /** - * @var ImagePage - */ - protected $imagePage; - - /** - * @var File - */ - protected $current; - - protected $repo, $showThumb; - protected $preventClickjacking = false; - - /** - * @param ImagePage $imagePage - */ - public function __construct( $imagePage ) { - global $wgShowArchiveThumbnails; - $this->current = $imagePage->getFile(); - $this->img = $imagePage->getDisplayedFile(); - $this->title = $imagePage->getTitle(); - $this->imagePage = $imagePage; - $this->showThumb = $wgShowArchiveThumbnails && $this->img->canRender(); - $this->setContext( $imagePage->getContext() ); - } - - /** - * @return ImagePage - */ - public function getImagePage() { - return $this->imagePage; - } - - /** - * @return File - */ - public function getFile() { - return $this->img; - } - - /** - * @param $navLinks string - * @return string - */ - public function beginImageHistoryList( $navLinks = '' ) { - return Xml::element( 'h2', array( 'id' => 'filehistory' ), $this->msg( 'filehist' )->text() ) . "\n" - . "
    \n" - . $this->msg( 'filehist-help' )->parseAsBlock() - . $navLinks . "\n" - . Xml::openElement( 'table', array( 'class' => 'wikitable filehistory' ) ) . "\n" - . '' - . ( $this->current->isLocal() && ( $this->getUser()->isAllowedAny( 'delete', 'deletedhistory' ) ) ? '' : '' ) - . '' . $this->msg( 'filehist-datetime' )->escaped() . '' - . ( $this->showThumb ? '' . $this->msg( 'filehist-thumb' )->escaped() . '' : '' ) - . '' . $this->msg( 'filehist-dimensions' )->escaped() . '' - . '' . $this->msg( 'filehist-user' )->escaped() . '' - . '' . $this->msg( 'filehist-comment' )->escaped() . '' - . "\n"; - } - - /** - * @param $navLinks string - * @return string - */ - public function endImageHistoryList( $navLinks = '' ) { - return "\n$navLinks\n
    \n"; - } - - /** - * @param $iscur - * @param $file File - * @return string - */ - public function imageHistoryLine( $iscur, $file ) { - global $wgContLang; - - $user = $this->getUser(); - $lang = $this->getLanguage(); - $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() ); - $img = $iscur ? $file->getName() : $file->getArchiveName(); - $userId = $file->getUser( 'id' ); - $userText = $file->getUser( 'text' ); - $description = $file->getDescription( File::FOR_THIS_USER, $user ); - - $local = $this->current->isLocal(); - $row = $selected = ''; - - // Deletion link - if ( $local && ( $user->isAllowedAny( 'delete', 'deletedhistory' ) ) ) { - $row .= ''; - # Link to remove from history - if ( $user->isAllowed( 'delete' ) ) { - $q = array( 'action' => 'delete' ); - if ( !$iscur ) { - $q['oldimage'] = $img; - } - $row .= Linker::linkKnown( - $this->title, - $this->msg( $iscur ? 'filehist-deleteall' : 'filehist-deleteone' )->escaped(), - array(), $q - ); - } - # Link to hide content. Don't show useless link to people who cannot hide revisions. - $canHide = $user->isAllowed( 'deleterevision' ); - if ( $canHide || ( $user->isAllowed( 'deletedhistory' ) && $file->getVisibility() ) ) { - if ( $user->isAllowed( 'delete' ) ) { - $row .= '
    '; - } - // If file is top revision or locked from this user, don't link - if ( $iscur || !$file->userCan( File::DELETED_RESTRICTED, $user ) ) { - $del = Linker::revDeleteLinkDisabled( $canHide ); - } else { - list( $ts, ) = explode( '!', $img, 2 ); - $query = array( - 'type' => 'oldimage', - 'target' => $this->title->getPrefixedText(), - 'ids' => $ts, - ); - $del = Linker::revDeleteLink( $query, - $file->isDeleted( File::DELETED_RESTRICTED ), $canHide ); - } - $row .= $del; - } - $row .= ''; - } - - // Reversion link/current indicator - $row .= ''; - if ( $iscur ) { - $row .= $this->msg( 'filehist-current' )->escaped(); - } elseif ( $local && $this->title->quickUserCan( 'edit', $user ) - && $this->title->quickUserCan( 'upload', $user ) - ) { - if ( $file->isDeleted( File::DELETED_FILE ) ) { - $row .= $this->msg( 'filehist-revert' )->escaped(); - } else { - $row .= Linker::linkKnown( - $this->title, - $this->msg( 'filehist-revert' )->escaped(), - array(), - array( - 'action' => 'revert', - 'oldimage' => $img, - 'wpEditToken' => $user->getEditToken( $img ) - ) - ); - } - } - $row .= ''; - - // Date/time and image link - if ( $file->getTimestamp() === $this->img->getTimestamp() ) { - $selected = "class='filehistory-selected'"; - } - $row .= ""; - if ( !$file->userCan( File::DELETED_FILE, $user ) ) { - # Don't link to unviewable files - $row .= '' . $lang->userTimeAndDate( $timestamp, $user ) . ''; - } elseif ( $file->isDeleted( File::DELETED_FILE ) ) { - if ( $local ) { - $this->preventClickjacking(); - $revdel = SpecialPage::getTitleFor( 'Revisiondelete' ); - # Make a link to review the image - $url = Linker::linkKnown( - $revdel, - $lang->userTimeAndDate( $timestamp, $user ), - array(), - array( - 'target' => $this->title->getPrefixedText(), - 'file' => $img, - 'token' => $user->getEditToken( $img ) - ) - ); - } else { - $url = $lang->userTimeAndDate( $timestamp, $user ); - } - $row .= '' . $url . ''; - } else { - $url = $iscur ? $this->current->getUrl() : $this->current->getArchiveUrl( $img ); - $row .= Xml::element( 'a', array( 'href' => $url ), $lang->userTimeAndDate( $timestamp, $user ) ); - } - $row .= ""; - - // Thumbnail - if ( $this->showThumb ) { - $row .= '' . $this->getThumbForLine( $file ) . ''; - } - - // Image dimensions + size - $row .= ''; - $row .= htmlspecialchars( $file->getDimensionsString() ); - $row .= $this->msg( 'word-separator' )->plain(); - $row .= ''; - $row .= $this->msg( 'parentheses' )->rawParams( Linker::formatSize( $file->getSize() ) )->plain(); - $row .= ''; - $row .= ''; - - // Uploading user - $row .= ''; - // Hide deleted usernames - if ( $file->isDeleted( File::DELETED_USER ) ) { - $row .= '' . $this->msg( 'rev-deleted-user' )->escaped() . ''; - } else { - if ( $local ) { - $row .= Linker::userLink( $userId, $userText ); - $row .= $this->msg( 'word-separator' )->plain(); - $row .= ''; - $row .= Linker::userToolLinks( $userId, $userText ); - $row .= ''; - } else { - $row .= htmlspecialchars( $userText ); - } - } - $row .= ''; - - // Don't show deleted descriptions - if ( $file->isDeleted( File::DELETED_COMMENT ) ) { - $row .= '' . $this->msg( 'rev-deleted-comment' )->escaped() . ''; - } else { - $row .= '' . Linker::formatComment( $description, $this->title ) . ''; - } - - $rowClass = null; - wfRunHooks( 'ImagePageFileHistoryLine', array( $this, $file, &$row, &$rowClass ) ); - $classAttr = $rowClass ? " class='$rowClass'" : ''; - - return "{$row}\n"; - } - - /** - * @param $file File - * @return string - */ - protected function getThumbForLine( $file ) { - $lang = $this->getLanguage(); - $user = $this->getUser(); - if ( $file->allowInlineDisplay() && $file->userCan( File::DELETED_FILE, $user ) - && !$file->isDeleted( File::DELETED_FILE ) ) - { - $params = array( - 'width' => '120', - 'height' => '120', - ); - $timestamp = wfTimestamp( TS_MW, $file->getTimestamp() ); - - $thumbnail = $file->transform( $params ); - $options = array( - 'alt' => $this->msg( 'filehist-thumbtext', - $lang->userTimeAndDate( $timestamp, $user ), - $lang->userDate( $timestamp, $user ), - $lang->userTime( $timestamp, $user ) )->text(), - 'file-link' => true, - ); - - if ( !$thumbnail ) { - return $this->msg( 'filehist-nothumb' )->escaped(); - } - - return $thumbnail->toHtml( $options ); - } else { - return $this->msg( 'filehist-nothumb' )->escaped(); - } - } - - /** - * @param $enable bool - */ - protected function preventClickjacking( $enable = true ) { - $this->preventClickjacking = $enable; - } - - /** - * @return bool - */ - public function getPreventClickjacking() { - return $this->preventClickjacking; - } -} - -class ImageHistoryPseudoPager extends ReverseChronologicalPager { - protected $preventClickjacking = false; - - /** - * @var File - */ - protected $mImg; - - /** - * @var Title - */ - protected $mTitle; - - /** - * @param ImagePage $imagePage - */ - function __construct( $imagePage ) { - parent::__construct( $imagePage->getContext() ); - $this->mImagePage = $imagePage; - $this->mTitle = clone ( $imagePage->getTitle() ); - $this->mTitle->setFragment( '#filehistory' ); - $this->mImg = null; - $this->mHist = array(); - $this->mRange = array( 0, 0 ); // display range - } - - /** - * @return Title - */ - function getTitle() { - return $this->mTitle; - } - - function getQueryInfo() { - return false; - } - - /** - * @return string - */ - function getIndexField() { - return ''; - } - - /** - * @param $row object - * @return string - */ - function formatRow( $row ) { - return ''; - } - - /** - * @return string - */ - function getBody() { - $s = ''; - $this->doQuery(); - if ( count( $this->mHist ) ) { - $list = new ImageHistoryList( $this->mImagePage ); - # Generate prev/next links - $navLink = $this->getNavigationBar(); - $s = $list->beginImageHistoryList( $navLink ); - // Skip rows there just for paging links - for ( $i = $this->mRange[0]; $i <= $this->mRange[1]; $i++ ) { - $file = $this->mHist[$i]; - $s .= $list->imageHistoryLine( !$file->isOld(), $file ); - } - $s .= $list->endImageHistoryList( $navLink ); - - if ( $list->getPreventClickjacking() ) { - $this->preventClickjacking(); - } - } - return $s; - } - - function doQuery() { - if ( $this->mQueryDone ) { - return; - } - $this->mImg = $this->mImagePage->getFile(); // ensure loading - if ( !$this->mImg->exists() ) { - return; - } - $queryLimit = $this->mLimit + 1; // limit plus extra row - if ( $this->mIsBackwards ) { - // Fetch the file history - $this->mHist = $this->mImg->getHistory( $queryLimit, null, $this->mOffset, false ); - // The current rev may not meet the offset/limit - $numRows = count( $this->mHist ); - if ( $numRows <= $this->mLimit && $this->mImg->getTimestamp() > $this->mOffset ) { - $this->mHist = array_merge( array( $this->mImg ), $this->mHist ); - } - } else { - // The current rev may not meet the offset - if ( !$this->mOffset || $this->mImg->getTimestamp() < $this->mOffset ) { - $this->mHist[] = $this->mImg; - } - // Old image versions (fetch extra row for nav links) - $oiLimit = count( $this->mHist ) ? $this->mLimit : $this->mLimit + 1; - // Fetch the file history - $this->mHist = array_merge( $this->mHist, - $this->mImg->getHistory( $oiLimit, $this->mOffset, null, false ) ); - } - $numRows = count( $this->mHist ); // Total number of query results - if ( $numRows ) { - # Index value of top item in the list - $firstIndex = $this->mIsBackwards ? - $this->mHist[$numRows - 1]->getTimestamp() : $this->mHist[0]->getTimestamp(); - # Discard the extra result row if there is one - if ( $numRows > $this->mLimit && $numRows > 1 ) { - if ( $this->mIsBackwards ) { - # Index value of item past the index - $this->mPastTheEndIndex = $this->mHist[0]->getTimestamp(); - # Index value of bottom item in the list - $lastIndex = $this->mHist[1]->getTimestamp(); - # Display range - $this->mRange = array( 1, $numRows - 1 ); - } else { - # Index value of item past the index - $this->mPastTheEndIndex = $this->mHist[$numRows - 1]->getTimestamp(); - # Index value of bottom item in the list - $lastIndex = $this->mHist[$numRows - 2]->getTimestamp(); - # Display range - $this->mRange = array( 0, $numRows - 2 ); - } - } else { - # Setting indexes to an empty string means that they will be - # omitted if they would otherwise appear in URLs. It just so - # happens that this is the right thing to do in the standard - # UI, in all the relevant cases. - $this->mPastTheEndIndex = ''; - # Index value of bottom item in the list - $lastIndex = $this->mIsBackwards ? - $this->mHist[0]->getTimestamp() : $this->mHist[$numRows - 1]->getTimestamp(); - # Display range - $this->mRange = array( 0, $numRows - 1 ); - } - } else { - $firstIndex = ''; - $lastIndex = ''; - $this->mPastTheEndIndex = ''; - } - if ( $this->mIsBackwards ) { - $this->mIsFirst = ( $numRows < $queryLimit ); - $this->mIsLast = ( $this->mOffset == '' ); - $this->mLastShown = $firstIndex; - $this->mFirstShown = $lastIndex; - } else { - $this->mIsFirst = ( $this->mOffset == '' ); - $this->mIsLast = ( $numRows < $queryLimit ); - $this->mLastShown = $lastIndex; - $this->mFirstShown = $firstIndex; - } - $this->mQueryDone = true; - } - - /** - * @param $enable bool - */ - protected function preventClickjacking( $enable = true ) { - $this->preventClickjacking = $enable; - } - - /** - * @return bool - */ - public function getPreventClickjacking() { - return $this->preventClickjacking; - } - -} -- cgit v1.2.2