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