getPage()->setFile( $file ); $this->displayImg = $file; $this->fileLoaded = true; } protected function loadFile() { if ( $this->fileLoaded ) { return; } $this->fileLoaded = true; $this->displayImg = $img = false; $this->getHookRunner()->onImagePageFindFile( $this, $img, $this->displayImg ); if ( !$img ) { // not set by hook? $services = MediaWikiServices::getInstance(); $img = $services->getRepoGroup()->findFile( $this->getTitle() ); if ( !$img ) { $img = $services->getRepoGroup()->getLocalRepo()->newFile( $this->getTitle() ); } } $this->getPage()->setFile( $img ); if ( !$this->displayImg ) { // not set by hook? $this->displayImg = $img; } $this->repo = $img->getRepo(); } public function view() { global $wgShowEXIF; // For action=render, include body text only; none of the image extras if ( $this->viewIsRenderAction ) { parent::view(); return; } $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->getFile()->getRedirected() ) { if ( $this->getTitle()->getDBkey() == $this->getFile()->getName() || $diff !== null ) { $request->setVal( 'diffonly', 'true' ); } parent::view(); return; } if ( $wgShowEXIF && $this->displayImg->exists() ) { // @todo FIXME: Bad interface, see note on MediaHandler::formatMetadata(). $formattedMetadata = $this->displayImg->formatMetadata( $this->getContext() ); } else { $formattedMetadata = false; } if ( !$diff && $this->displayImg->exists() ) { $out->addHTML( $this->showTOC( (bool)$formattedMetadata ) ); } if ( !$diff ) { $this->openShowImage(); } # No need to display noarticletext, we use our own message, output in openShowImage() if ( $this->getPage()->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', [ '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->getPage()->doViewUpdates( $this->getContext()->getUser(), $this->getOldID() ); } # Show shared description, if needed if ( $this->mExtraDescription ) { $fol = $this->getContext()->msg( 'shareddescriptionfollows' ); if ( !$fol->isDisabled() ) { $out->addWikiTextAsInterface( $fol->plain() ); } $out->addHTML( Html::rawElement( 'div', [ 'id' => 'shared-image-desc' ], $this->mExtraDescription ) . "\n" ); } $this->closeShowImage(); $this->imageHistory(); // TODO: Cleanup the following $out->addHTML( Xml::element( 'h2', [ 'id' => 'filelinks' ], $this->getContext()->msg( '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 = ''; $this->getHookRunner()->onImagePageAfterImageLinks( $this, $html ); if ( $html ) { $out->addHTML( $html ); } if ( $formattedMetadata ) { $out->addHTML( Xml::element( 'h2', [ 'id' => 'metadata' ], $this->getContext()->msg( 'metadata' )->text() ) . "\n" ); $out->wrapWikiTextAsInterface( 'mw-imagepage-section-metadata', $this->makeMetadataTable( $formattedMetadata ) ); $out->addModules( [ 'mediawiki.action.view.metadata' ] ); } // Add remote Filepage.css if ( !$this->repo->isLocal() ) { $css = $this->repo->getDescriptionStylesheetUrl(); if ( $css ) { $out->addStyle( $css ); } } $out->addModuleStyles( [ 'filepage', // always show the local local Filepage.css, T31277 'mediawiki.action.view.filepage', // Add MediaWiki styles for a file page ] ); } /** * @return File */ public function getDisplayedFile() { $this->loadFile(); return $this->displayImg; } /** * Create the TOC * * @param bool $metadata Whether or not to show the metadata link * @return string */ protected function showTOC( $metadata ) { $r = [ Html::rawElement( 'li', [], Html::rawElement( 'a', [ 'href' => '#file' ], $this->getContext()->msg( 'file-anchor-link' )->escaped() ) ), Html::rawElement( 'li', [], Html::rawElement( 'a', [ 'href' => '#filehistory' ], $this->getContext()->msg( 'filehist' )->escaped() ) ), Html::rawElement( 'li', [], Html::rawElement( 'a', [ 'href' => '#filelinks' ], $this->getContext()->msg( 'imagelinks' )->escaped() ) ), ]; $this->getHookRunner()->onImagePageShowTOC( $this, $r ); if ( $metadata ) { $r[] = Html::rawElement( 'li', [], Html::rawElement( 'a', [ 'href' => '#metadata' ], $this->getContext()->msg( 'metadata' )->escaped() ) ); } return Html::rawElement( 'ul', [ 'id' => 'filetoc' ], implode( "\n", $r ) ); } /** * 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 = $this->getContext()->msg( 'metadata-help' )->plain(); // Initial state is collapsed // see filepage.css and mediawiki.action.view.metadata module. $r .= "
| ' ); } if ( $thumbnail ) { $options = [ 'alt' => $this->displayImg->getTitle()->getPrefixedText(), 'file-link' => true, ]; $out->addHTML( Html::rawElement( 'div', [ 'class' => 'fullImageLink', 'id' => 'file' ], $thumbnail->toHtml( $options ) . $anchorclose ) . "\n" ); } if ( $isMulti ) { $count = $this->displayImg->pageCount(); $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); if ( $page > 1 ) { $label = $this->getContext()->msg( 'imgmultipageprev' )->text(); // on the client side, this link is generated in ajaxifyPageNavigation() // in the mediawiki.page.image.pagination module $link = $linkRenderer->makeKnownLink( $this->getTitle(), $label, [], [ 'page' => $page - 1 ] ); // @phan-suppress-next-line SecurityCheck-DoubleEscaped link getting a key, false positive $thumb1 = Linker::makeThumbLinkObj( $this->getTitle(), $this->displayImg, $link, $label, 'none', [ 'page' => $page - 1 ] ); } else { $thumb1 = ''; } if ( $page < $count ) { $label = $this->getContext()->msg( 'imgmultipagenext' )->text(); $link = $linkRenderer->makeKnownLink( $this->getTitle(), $label, [], [ 'page' => $page + 1 ] ); // @phan-suppress-next-line SecurityCheck-DoubleEscaped link getting a key, false positive $thumb2 = Linker::makeThumbLinkObj( $this->getTitle(), $this->displayImg, $link, $label, 'none', [ 'page' => $page + 1 ] ); } else { $thumb2 = ''; } global $wgScript; $formParams = [ 'name' => 'pageselector', 'action' => $wgScript, ]; $options = []; for ( $i = 1; $i <= $count; $i++ ) { $options[] = Xml::option( $lang->formatNum( $i ), $i, $i == $page ); } $select = Xml::tags( 'select', [ 'id' => 'pageselector', 'name' => 'page' ], implode( "\n", $options ) ); $out->addHTML( ' |