MediaWiki master
TraditionalImageGallery.php
Go to the documentation of this file.
1<?php
2
8namespace MediaWiki\Gallery;
9
22use Wikimedia\Assert\Assert;
23
39 public function toHTML() {
40 $resolveFilesViaParser = $this->mParser instanceof Parser;
41 if ( $resolveFilesViaParser ) {
42 $parserOutput = $this->mParser->getOutput();
43 $repoGroup = null;
44 $linkRenderer = $this->mParser->getLinkRenderer();
45 $badFileLookup = $this->mParser->getBadFileLookup();
46 } else {
47 $parserOutput = $this->getOutput();
49 $repoGroup = $services->getRepoGroup();
50 $linkRenderer = $services->getLinkRenderer();
51 $badFileLookup = $services->getBadFileLookup();
52 }
53
54 Html::addClass( $this->mAttribs['class'], 'gallery' );
55 Html::addClass( $this->mAttribs['class'], 'mw-gallery-' . $this->mMode );
56
57 if ( $this->mPerRow > 0 ) {
58 $maxwidth = $this->mPerRow * ( $this->mWidths + $this->getAllPadding() );
59 $oldStyle = $this->mAttribs['style'] ?? '';
60 $this->mAttribs['style'] = "max-width: {$maxwidth}px;" . $oldStyle;
61 }
62
63 $parserOutput->addModules( $this->getModules() );
64 $parserOutput->addModuleStyles( [ 'mediawiki.page.gallery.styles' ] );
65 $output = Html::openElement( 'ul', $this->mAttribs );
66 if ( $this->mCaption ) {
67 $output .= "\n\t" . Html::rawElement( 'li', [ 'class' => 'gallerycaption' ], $this->mCaption );
68 }
69
70 if ( $this->mShowFilename ) {
71 // Preload LinkCache info for when generating links
72 // of the filename below
73 $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
74 $lb = $linkBatchFactory->newLinkBatch()->setCaller( __METHOD__ );
75 foreach ( $this->mImages as [ $title, /* see below */ ] ) {
76 $lb->addObj( $title );
77 }
78 $lb->execute();
79 }
80
81 $lang = $this->getRenderLang();
82 $hookRunner = new HookRunner( MediaWikiServices::getInstance()->getHookContainer() );
83
84 # Output each image...
85 foreach ( $this->mImages as [ $nt, $text, $alt, $link, $handlerOpts, $loading, $imageOptions ] ) {
86 // "text" means "caption" here
89 $descQuery = false;
90 if ( $nt->inNamespace( NS_FILE ) && !$nt->isExternal() ) {
91 # Get the file...
92 if ( $resolveFilesViaParser ) {
93 # Give extensions a chance to select the file revision for us
94 $options = [];
95 $hookRunner->onBeforeParserFetchFileAndTitle(
96 // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args
97 $this->mParser, $nt, $options, $descQuery );
98 # Fetch and register the file (file title may be different via hooks)
99 [ $img, $nt ] = $this->mParser->fetchFileAndTitle( $nt, $options );
100 } else {
101 $img = $repoGroup->findFile( $nt );
102 }
103 } else {
104 $img = false;
105 }
106
107 $transformOptions = $this->getThumbParams( $img ) + $handlerOpts;
108 $transformOptions['requestProvenance'] = $resolveFilesViaParser ? 'parser' : 'gallery';
109 $thumb = $img ? $img->transform( $transformOptions ) : false;
110
111 $rdfaType = 'mw:File';
112
113 $isBadFile = $img && $thumb && $this->mHideBadImages &&
114 $badFileLookup->isBadFile( $nt->getDBkey(), $this->getContextTitle() );
115
116 if ( !$img || !$thumb || $thumb->isError() || $isBadFile ) {
117 $rdfaType = 'mw:Error ' . $rdfaType;
118
119 $currentExists = $img && $img->exists();
120 if ( $currentExists && !$thumb ) {
121 $label = wfMessage( 'thumbnail_error', '' )->text();
122 } elseif ( $thumb && $thumb->isError() ) {
123 Assert::invariant(
124 $thumb instanceof MediaTransformError,
125 'Unknown MediaTransformOutput: ' . get_class( $thumb )
126 );
127 $label = $thumb->toText();
128 } else {
129 $label = $alt ?? '';
130 }
131 $thumbhtml = Linker::makeBrokenImageLinkObj(
132 $nt, $label, '', '', '', false, $transformOptions, $currentExists
133 );
134 $thumbhtml = Html::rawElement( 'span', [ 'typeof' => $rdfaType ], $thumbhtml );
135
136 $thumbhtml = "\n\t\t\t" . Html::rawElement(
137 'div',
138 [
139 'class' => 'thumb',
140 'style' => 'height: ' . ( $this->getThumbPadding() + $this->mHeights ) . 'px;'
141 ],
142 $thumbhtml
143 );
144
145 if ( !$img && $resolveFilesViaParser ) {
146 $this->mParser->addTrackingCategory( 'broken-file-category' );
147 }
148 } else {
150 $vpad = $this->getVPad( $this->mHeights, $thumb->getHeight() );
151
152 // Backwards compat before the $imageOptions existed
153 if ( $imageOptions === null ) {
154 $imageParameters = [
155 'desc-link' => true,
156 'desc-query' => $descQuery,
157 'alt' => $alt ?? '',
158 'custom-url-link' => $link
159 ];
160 } else {
161 $params = [];
162 // An empty alt indicates an image is not a key part of the
163 // content and that non-visual browsers may omit it from
164 // rendering. Only set the parameter if it's explicitly
165 // requested.
166 if ( $alt !== null ) {
167 $params['alt'] = $alt;
168 }
169 $params['title'] = $imageOptions['title'];
170 $params['img-class'] = 'mw-file-element';
171 $imageParameters = Linker::getImageLinkMTOParams(
172 $imageOptions, $descQuery, $this->mParser
173 ) + $params;
174 }
175
176 if ( $loading === ImageGalleryBase::LOADING_LAZY ) {
177 $imageParameters['loading'] = 'lazy';
178 }
179
180 $this->adjustImageParameters( $thumb, $imageParameters );
181
182 Linker::processResponsiveImages( $img, $thumb, $transformOptions );
183
184 $thumbhtml = $thumb->toHtml( $imageParameters );
185 $thumbhtml = Html::rawElement(
186 'span', [ 'typeof' => $rdfaType ], $thumbhtml
187 );
188
189 # Set both fixed width and min-height.
190 $width = $this->getThumbDivWidth( $thumb->getWidth() );
191 $height = $this->getThumbPadding() + $this->mHeights;
192 $thumbhtml = "\n\t\t\t" . Html::rawElement( 'div', [
193 'class' => 'thumb',
194 'style' => "width: {$width}px;" .
195 ( $this->mMode === 'traditional' ? " height: {$height}px;" : '' ),
196 ], $thumbhtml );
197
198 // Call parser transform hook
199 if ( $resolveFilesViaParser ) {
201 $handler = $img->getHandler();
202 if ( $handler ) {
203 $handler->parserTransformHook( $this->mParser, $img );
204 }
205 $this->mParser->modifyImageHtml(
206 $img, [ 'handler' => $imageParameters ], $thumbhtml );
207 }
208 }
209
210 $meta = [];
211 if ( $img ) {
212 if ( $this->mShowDimensions ) {
213 $meta[] = htmlspecialchars( $img->getDimensionsString( $lang ) );
214 }
215 if ( $this->mShowBytes ) {
216 $meta[] = htmlspecialchars( $lang->formatSize( $img->getSize() ) );
217 }
218 } elseif ( $this->mShowDimensions || $this->mShowBytes ) {
219 $meta[] = $this->msg( 'filemissing' )->escaped();
220 }
221 $meta = $lang->semicolonList( $meta );
222 if ( $meta ) {
223 $meta .= Html::rawElement( 'br', [] ) . "\n";
224 }
225
226 $textlink = $this->mShowFilename ?
227 $this->getCaptionHtml( $nt, $lang, $linkRenderer ) :
228 '';
229
230 $galleryText = $this->wrapGalleryText( $textlink . $text . $meta, $thumb );
231
232 $gbWidth = $this->getGBWidthOverwrite( $thumb ) ?: $this->getGBWidth( $thumb ) . 'px';
233 # Weird double wrapping (the extra div inside the li) needed due to FF2 bug
234 # Can be safely removed if FF2 falls completely out of existence
235 $output .= "\n\t\t" .
236 Html::rawElement(
237 'li',
238 [ 'class' => 'gallerybox', 'style' => 'width: ' . $gbWidth ],
239 $thumbhtml
240 . $galleryText
241 . "\n\t\t"
242 );
243 }
244 $output .= "\n" . Html::closeElement( 'ul' );
245
246 return $output;
247 }
248
255 protected function getCaptionHtml( Title $nt, Language $lang, LinkRenderer $linkRenderer ) {
256 // Preloaded into LinkCache in toHTML
257 return $linkRenderer->makeKnownLink(
258 $nt,
259 is_int( $this->getCaptionLength() ) ?
260 $lang->truncateForVisual( $nt->getText(), $this->getCaptionLength() ) :
261 $nt->getText(),
262 [
263 'class' => 'galleryfilename' .
264 ( $this->getCaptionLength() === true ? ' galleryfilename-truncate' : '' )
265 ]
266 ) . "\n";
267 }
268
277 protected function wrapGalleryText( $galleryText, $thumb ) {
278 return "\n\t\t\t" . Html::rawElement( 'div', [ 'class' => "gallerytext" ], $galleryText );
279 }
280
287 protected function getThumbPadding() {
288 return 30;
289 }
290
296 protected function getGBPadding() {
297 return 5;
298 }
299
307 protected function getGBBorders() {
308 return 8;
309 }
310
318 protected function getCaptionLength() {
320 }
321
327 protected function getAllPadding() {
328 return $this->getThumbPadding() + $this->getGBPadding() + $this->getGBBorders();
329 }
330
340 protected function getVPad( $boxHeight, $thumbHeight ) {
341 return ( $this->getThumbPadding() + $boxHeight - $thumbHeight ) / 2;
342 }
343
350 protected function getThumbParams( $img ) {
351 return [
352 'width' => $this->mWidths,
353 'height' => $this->mHeights
354 ];
355 }
356
364 protected function getThumbDivWidth( $thumbWidth ) {
365 return $this->mWidths + $this->getThumbPadding();
366 }
367
378 protected function getGBWidth( $thumb ) {
379 return $this->mWidths + $this->getThumbPadding() + $this->getGBPadding();
380 }
381
393 protected function getGBWidthOverwrite( $thumb ) {
394 return false;
395 }
396
404 protected function getModules() {
405 return [];
406 }
407
415 protected function adjustImageParameters( $thumb, &$imageParameters ) {
416 }
417}
418
420class_alias( TraditionalImageGallery::class, 'TraditionalImageGallery' );
const NS_FILE
Definition Defines.php:57
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:80
bool int $mCaptionLength
Length to truncate filename to in caption when using "showfilename".
getRenderLang()
Determines the correct language to be used for this image gallery.
getThumbParams( $img)
Get the transform parameters for a thumbnail.
getThumbPadding()
How much padding the thumb has between the image and the inner div that contains the border.
getModules()
Get a list of modules to include in the page.
getGBBorders()
Get how much extra space the borders around the image takes up.
getThumbDivWidth( $thumbWidth)
Get the width of the inner div that contains the thumbnail in question.
getCaptionLength()
Length (in characters) to truncate filename to in caption when using "showfilename" (if int).
getGBWidth( $thumb)
Computed width of gallerybox .
getVPad( $boxHeight, $thumbHeight)
Get vertical padding for a thumbnail.
wrapGalleryText( $galleryText, $thumb)
Add the wrapper html around the thumb's caption.
getGBWidthOverwrite( $thumb)
Allows overwriting the computed width of the gallerybox with a string, like '100'.
toHTML()
Return a HTML representation of the image gallery.
adjustImageParameters( $thumb, &$imageParameters)
Adjust the image parameters for a thumbnail.
getCaptionHtml(Title $nt, Language $lang, LinkRenderer $linkRenderer)
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
This class is a collection of static functions that serve two purposes:
Definition Html.php:44
Base class for language-specific code.
Definition Language.php:65
truncateForVisual( $string, $length, $ellipsis='...', $adjustLength=true)
Truncate a string to a specified number of characters, appending an optional string (e....
Class that generates HTML for internal links.
makeKnownLink( $target, $text=null, array $extraAttribs=[], array $query=[])
Make a link that's styled as if the target page exists (usually a "blue link", although the styling m...
Some internal bits split of from Skin.php.
Definition Linker.php:47
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
Base media handler class.
Basic media transform error class.
Base class for the output of MediaHandler::doTransform() and File::transform().
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:136
Represents a title within MediaWiki.
Definition Title.php:69
exists( $flags=0)
Check if page exists.
Definition Title.php:3129
getText()
Get the text form (spaces not underscores) of the main part.
Definition Title.php:1010