MediaWiki master
TraditionalImageGallery.php
Go to the documentation of this file.
1<?php
2
12use Wikimedia\Assert\Assert;
13
47 public function toHTML() {
48 $resolveFilesViaParser = $this->mParser instanceof Parser;
49 if ( $resolveFilesViaParser ) {
50 $parserOutput = $this->mParser->getOutput();
51 $repoGroup = null;
52 $linkRenderer = $this->mParser->getLinkRenderer();
53 $badFileLookup = $this->mParser->getBadFileLookup();
54 } else {
55 $parserOutput = $this->getOutput();
56 $services = MediaWikiServices::getInstance();
57 $repoGroup = $services->getRepoGroup();
58 $linkRenderer = $services->getLinkRenderer();
59 $badFileLookup = $services->getBadFileLookup();
60 }
61
62 if ( $this->mPerRow > 0 ) {
63 $maxwidth = $this->mPerRow * ( $this->mWidths + $this->getAllPadding() );
64 $oldStyle = $this->mAttribs['style'] ?? '';
65 $this->mAttribs['style'] = "max-width: {$maxwidth}px;" . $oldStyle;
66 }
67
68 $attribs = Sanitizer::mergeAttributes(
69 [ 'class' => 'gallery mw-gallery-' . $this->mMode ], $this->mAttribs );
70
71 $parserOutput->addModules( $this->getModules() );
72 $parserOutput->addModuleStyles( [ 'mediawiki.page.gallery.styles' ] );
73 $output = Html::openElement( 'ul', $attribs );
74 if ( $this->mCaption ) {
75 $output .= "\n\t" . Html::rawElement( 'li', [ 'class' => 'gallerycaption' ], $this->mCaption );
76 }
77
78 if ( $this->mShowFilename ) {
79 // Preload LinkCache info for when generating links
80 // of the filename below
81 $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
82 $lb = $linkBatchFactory->newLinkBatch();
83 foreach ( $this->mImages as [ $title, /* see below */ ] ) {
84 $lb->addObj( $title );
85 }
86 $lb->execute();
87 }
88
89 $lang = $this->getRenderLang();
90 $enableLegacyMediaDOM =
91 $this->getConfig()->get( MainConfigNames::ParserEnableLegacyMediaDOM );
92 $hookRunner = new HookRunner( MediaWikiServices::getInstance()->getHookContainer() );
93
94 # Output each image...
95 foreach ( $this->mImages as [ $nt, $text, $alt, $link, $handlerOpts, $loading, $imageOptions ] ) {
96 // "text" means "caption" here
99 $descQuery = false;
100 if ( $nt->inNamespace( NS_FILE ) && !$nt->isExternal() ) {
101 # Get the file...
102 if ( $resolveFilesViaParser ) {
103 # Give extensions a chance to select the file revision for us
104 $options = [];
105 $hookRunner->onBeforeParserFetchFileAndTitle(
106 // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args
107 $this->mParser, $nt, $options, $descQuery );
108 # Fetch and register the file (file title may be different via hooks)
109 [ $img, $nt ] = $this->mParser->fetchFileAndTitle( $nt, $options );
110 } else {
111 $img = $repoGroup->findFile( $nt );
112 }
113 } else {
114 $img = false;
115 }
116
117 $transformOptions = $this->getThumbParams( $img ) + $handlerOpts;
118 $thumb = $img ? $img->transform( $transformOptions ) : false;
119
120 $rdfaType = 'mw:File';
121
122 $isBadFile = $img && $thumb && $this->mHideBadImages &&
123 $badFileLookup->isBadFile( $nt->getDBkey(), $this->getContextTitle() );
124
125 if ( !$img || !$thumb || ( !$enableLegacyMediaDOM && $thumb->isError() ) || $isBadFile ) {
126 $rdfaType = 'mw:Error ' . $rdfaType;
127
128 if ( $enableLegacyMediaDOM ) {
129 if ( $isBadFile ) {
130 $thumbhtml = $linkRenderer->makeKnownLink( $nt, $nt->getText() );
131 } else {
132 $thumbhtml = htmlspecialchars( $img ? $img->getLastError() : $nt->getText() );
133 }
134 } else {
135 $currentExists = $img && $img->exists();
136 if ( $currentExists && !$thumb ) {
137 $label = wfMessage( 'thumbnail_error', '' )->text();
138 } elseif ( $thumb && $thumb->isError() ) {
139 Assert::invariant(
140 $thumb instanceof MediaTransformError,
141 'Unknown MediaTransformOutput: ' . get_class( $thumb )
142 );
143 $label = $thumb->toText();
144 } else {
145 $label = $alt ?? '';
146 }
147 $thumbhtml = Linker::makeBrokenImageLinkObj(
148 $nt, $label, '', '', '', false, $transformOptions, $currentExists
149 );
150 $thumbhtml = Html::rawElement( 'span', [ 'typeof' => $rdfaType ], $thumbhtml );
151 }
152
153 $thumbhtml = "\n\t\t\t" . Html::rawElement(
154 'div',
155 [
156 'class' => 'thumb',
157 'style' => 'height: ' . ( $this->getThumbPadding() + $this->mHeights ) . 'px;'
158 ],
159 $thumbhtml
160 );
161
162 if ( !$img && $resolveFilesViaParser ) {
163 $this->mParser->addTrackingCategory( 'broken-file-category' );
164 }
165 } else {
167 $vpad = $this->getVPad( $this->mHeights, $thumb->getHeight() );
168
169 // Backwards compat before the $imageOptions existed
170 if ( $imageOptions === null ) {
171 $imageParameters = [
172 'desc-link' => true,
173 'desc-query' => $descQuery,
174 'alt' => $alt ?? '',
175 'custom-url-link' => $link
176 ];
177 } else {
178 $params = [];
179 // An empty alt indicates an image is not a key part of the
180 // content and that non-visual browsers may omit it from
181 // rendering. Only set the parameter if it's explicitly
182 // requested.
183 if ( $alt !== null ) {
184 $params['alt'] = $alt;
185 }
186 $params['title'] = $imageOptions['title'];
187 if ( !$enableLegacyMediaDOM ) {
188 $params['img-class'] = 'mw-file-element';
189 }
190 $imageParameters = Linker::getImageLinkMTOParams(
191 $imageOptions, $descQuery, $this->mParser
192 ) + $params;
193 }
194
195 if ( $loading === ImageGalleryBase::LOADING_LAZY ) {
196 $imageParameters['loading'] = 'lazy';
197 }
198
199 $this->adjustImageParameters( $thumb, $imageParameters );
200
201 Linker::processResponsiveImages( $img, $thumb, $transformOptions );
202
203 $thumbhtml = $thumb->toHtml( $imageParameters );
204
205 if ( !$enableLegacyMediaDOM ) {
206 $thumbhtml = Html::rawElement(
207 'span', [ 'typeof' => $rdfaType ], $thumbhtml
208 );
209 } else {
210 $thumbhtml = Html::rawElement( 'div', [
211 # Auto-margin centering for block-level elements. Needed
212 # now that we have video handlers since they may emit block-
213 # level elements as opposed to simple <img> tags. ref
214 # http://css-discuss.incutio.com/?page=CenteringBlockElement
215 'style' => "margin:{$vpad}px auto;",
216 ], $thumbhtml );
217 }
218
219 # Set both fixed width and min-height.
220 $width = $this->getThumbDivWidth( $thumb->getWidth() );
221 $height = $this->getThumbPadding() + $this->mHeights;
222 $thumbhtml = "\n\t\t\t" . Html::rawElement( 'div', [
223 'class' => 'thumb',
224 'style' => "width: {$width}px;" .
225 ( !$enableLegacyMediaDOM && $this->mMode === 'traditional' ?
226 " height: {$height}px;" : '' ),
227 ], $thumbhtml );
228
229 // Call parser transform hook
230 if ( $resolveFilesViaParser ) {
232 $handler = $img->getHandler();
233 if ( $handler ) {
234 $handler->parserTransformHook( $this->mParser, $img );
235 }
236 $this->mParser->modifyImageHtml(
237 $img, [ 'handler' => $imageParameters ], $thumbhtml );
238 }
239 }
240
241 $meta = [];
242 if ( $img ) {
243 if ( $this->mShowDimensions ) {
244 $meta[] = htmlspecialchars( $img->getDimensionsString() );
245 }
246 if ( $this->mShowBytes ) {
247 $meta[] = htmlspecialchars( $lang->formatSize( $img->getSize() ) );
248 }
249 } elseif ( $this->mShowDimensions || $this->mShowBytes ) {
250 $meta[] = $this->msg( 'filemissing' )->escaped();
251 }
252 $meta = $lang->semicolonList( $meta );
253 if ( $meta ) {
254 $meta .= Html::rawElement( 'br', [] ) . "\n";
255 }
256
257 $textlink = $this->mShowFilename ?
258 $this->getCaptionHtml( $nt, $lang, $linkRenderer ) :
259 '';
260
261 $galleryText = $this->wrapGalleryText( $textlink . $text . $meta, $thumb );
262
263 $gbWidth = $this->getGBWidthOverwrite( $thumb ) ?: $this->getGBWidth( $thumb ) . 'px';
264 # Weird double wrapping (the extra div inside the li) needed due to FF2 bug
265 # Can be safely removed if FF2 falls completely out of existence
266 $output .= "\n\t\t" .
267 Html::rawElement(
268 'li',
269 [ 'class' => 'gallerybox', 'style' => 'width: ' . $gbWidth ],
270 ( $enableLegacyMediaDOM ? Html::openElement( 'div', [ 'style' => 'width: ' . $gbWidth ] ) : '' )
271 . $thumbhtml
272 . $galleryText
273 . "\n\t\t"
274 . ( $enableLegacyMediaDOM ? Html::closeElement( 'div' ) : '' )
275 );
276 }
277 $output .= "\n" . Html::closeElement( 'ul' );
278
279 return $output;
280 }
281
288 protected function getCaptionHtml( Title $nt, Language $lang, LinkRenderer $linkRenderer ) {
289 // Preloaded into LinkCache in toHTML
290 return $linkRenderer->makeKnownLink(
291 $nt,
292 is_int( $this->getCaptionLength() ) ?
293 $lang->truncateForVisual( $nt->getText(), $this->getCaptionLength() ) :
294 $nt->getText(),
295 [
296 'class' => 'galleryfilename' .
297 ( $this->getCaptionLength() === true ? ' galleryfilename-truncate' : '' )
298 ]
299 ) . "\n";
300 }
301
310 protected function wrapGalleryText( $galleryText, $thumb ) {
311 return "\n\t\t\t" . Html::rawElement( 'div', [ 'class' => "gallerytext" ], $galleryText );
312 }
313
320 protected function getThumbPadding() {
321 return 30;
322 }
323
329 protected function getGBPadding() {
330 return 5;
331 }
332
340 protected function getGBBorders() {
341 return 8;
342 }
343
351 protected function getCaptionLength() {
353 }
354
360 protected function getAllPadding() {
361 return $this->getThumbPadding() + $this->getGBPadding() + $this->getGBBorders();
362 }
363
373 protected function getVPad( $boxHeight, $thumbHeight ) {
374 return ( $this->getThumbPadding() + $boxHeight - $thumbHeight ) / 2;
375 }
376
383 protected function getThumbParams( $img ) {
384 return [
385 'width' => $this->mWidths,
386 'height' => $this->mHeights
387 ];
388 }
389
397 protected function getThumbDivWidth( $thumbWidth ) {
398 return $this->mWidths + $this->getThumbPadding();
399 }
400
411 protected function getGBWidth( $thumb ) {
412 return $this->mWidths + $this->getThumbPadding() + $this->getGBPadding();
413 }
414
426 protected function getGBWidthOverwrite( $thumb ) {
427 return false;
428 }
429
437 protected function getModules() {
438 return [];
439 }
440
448 protected function adjustImageParameters( $thumb, &$imageParameters ) {
449 }
450}
const NS_FILE
Definition Defines.php:70
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
array $params
The job parameters.
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.
Base class for language-specific code.
Definition Language.php:63
truncateForVisual( $string, $length, $ellipsis='...', $adjustLength=true)
Truncate a string to a specified number of characters, appending an optional string (e....
Basic media transform error class.
Base class for the output of MediaHandler::doTransform() and File::transform().
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
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:56
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:65
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:156
HTML sanitizer for MediaWiki.
Definition Sanitizer.php:46
Represents a title within MediaWiki.
Definition Title.php:78
exists( $flags=0)
Check if page exists.
Definition Title.php:3201
getText()
Get the text form (spaces not underscores) of the main part.
Definition Title.php:1017
getThumbPadding()
How much padding the thumb has between the image and the inner div that contains the border.
getCaptionLength()
Length (in characters) to truncate filename to in caption when using "showfilename" (if int).
getVPad( $boxHeight, $thumbHeight)
Get vertical padding for a thumbnail.
getCaptionHtml(Title $nt, Language $lang, LinkRenderer $linkRenderer)
getThumbParams( $img)
Get the transform parameters for a thumbnail.
toHTML()
Return a HTML representation of the image gallery.
getGBWidth( $thumb)
Computed width of gallerybox .
getModules()
Get a list of modules to include in the page.
getGBBorders()
Get how much extra space the borders around the image takes up.
wrapGalleryText( $galleryText, $thumb)
Add the wrapper html around the thumb's caption.
adjustImageParameters( $thumb, &$imageParameters)
Adjust the image parameters for a thumbnail.
getGBWidthOverwrite( $thumb)
Allows overwriting the computed width of the gallerybox with a string, like '100'.
getThumbDivWidth( $thumbWidth)
Get the width of the inner div that contains the thumbnail in question.