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( 'span',
186 [
187 'class' => $imageOptions['class'] ?? null,
188 'typeof' => $rdfaType,
189 ],
190 $thumbhtml
191 );
192
193 # Set both fixed width and min-height.
194 $width = $this->getThumbDivWidth( $thumb->getWidth() );
195 $height = $this->getThumbPadding() + $this->mHeights;
196 $thumbhtml = "\n\t\t\t" . Html::rawElement( 'div', [
197 'class' => 'thumb',
198 'style' => "width: {$width}px;" .
199 ( $this->mMode === 'traditional' ? " height: {$height}px;" : '' ),
200 ], $thumbhtml );
201
202 // Call parser transform hook
203 if ( $resolveFilesViaParser ) {
205 $handler = $img->getHandler();
206 if ( $handler ) {
207 $handler->parserTransformHook( $this->mParser, $img );
208 }
209 $this->mParser->modifyImageHtml(
210 $img, [ 'handler' => $imageParameters ], $thumbhtml );
211 }
212 }
213
214 $meta = [];
215 if ( $img ) {
216 if ( $this->mShowDimensions ) {
217 $meta[] = htmlspecialchars( $img->getDimensionsString( $lang ) );
218 }
219 if ( $this->mShowBytes ) {
220 $meta[] = htmlspecialchars( $lang->formatSize( $img->getSize() ) );
221 }
222 } elseif ( $this->mShowDimensions || $this->mShowBytes ) {
223 $meta[] = $this->msg( 'filemissing' )->escaped();
224 }
225 $meta = $lang->semicolonList( $meta );
226 if ( $meta ) {
227 $meta .= Html::rawElement( 'br', [] ) . "\n";
228 }
229
230 $textlink = $this->mShowFilename ?
231 $this->getCaptionHtml( $nt, $lang, $linkRenderer ) :
232 '';
233
234 $galleryText = $this->wrapGalleryText( $textlink . $text . $meta, $thumb );
235
236 $gbWidth = $this->getGBWidthOverwrite( $thumb ) ?: $this->getGBWidth( $thumb ) . 'px';
237 # Weird double wrapping (the extra div inside the li) needed due to FF2 bug
238 # Can be safely removed if FF2 falls completely out of existence
239 $output .= "\n\t\t" .
240 Html::rawElement(
241 'li',
242 [ 'class' => 'gallerybox', 'style' => 'width: ' . $gbWidth ],
243 $thumbhtml
244 . $galleryText
245 . "\n\t\t"
246 );
247 }
248 $output .= "\n" . Html::closeElement( 'ul' );
249
250 return $output;
251 }
252
259 protected function getCaptionHtml( Title $nt, Language $lang, LinkRenderer $linkRenderer ) {
260 // Preloaded into LinkCache in toHTML
261 return $linkRenderer->makeKnownLink(
262 $nt,
263 is_int( $this->getCaptionLength() ) ?
264 $lang->truncateForVisual( $nt->getText(), $this->getCaptionLength() ) :
265 $nt->getText(),
266 [
267 'class' => 'galleryfilename' .
268 ( $this->getCaptionLength() === true ? ' galleryfilename-truncate' : '' )
269 ]
270 ) . "\n";
271 }
272
281 protected function wrapGalleryText( $galleryText, $thumb ) {
282 return "\n\t\t\t" . Html::rawElement( 'div', [ 'class' => "gallerytext" ], $galleryText );
283 }
284
291 protected function getThumbPadding() {
292 return 30;
293 }
294
300 protected function getGBPadding() {
301 return 5;
302 }
303
311 protected function getGBBorders() {
312 return 8;
313 }
314
322 protected function getCaptionLength() {
324 }
325
331 protected function getAllPadding() {
332 return $this->getThumbPadding() + $this->getGBPadding() + $this->getGBBorders();
333 }
334
344 protected function getVPad( $boxHeight, $thumbHeight ) {
345 return ( $this->getThumbPadding() + $boxHeight - $thumbHeight ) / 2;
346 }
347
354 protected function getThumbParams( $img ) {
355 return [
356 'width' => $this->mWidths,
357 'height' => $this->mHeights
358 ];
359 }
360
368 protected function getThumbDivWidth( $thumbWidth ) {
369 return $this->mWidths + $this->getThumbPadding();
370 }
371
382 protected function getGBWidth( $thumb ) {
383 return $this->mWidths + $this->getThumbPadding() + $this->getGBPadding();
384 }
385
397 protected function getGBWidthOverwrite( $thumb ) {
398 return false;
399 }
400
408 protected function getModules() {
409 return [];
410 }
411
419 protected function adjustImageParameters( $thumb, &$imageParameters ) {
420 }
421}
422
424class_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:48
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:138
Represents a title within MediaWiki.
Definition Title.php:69
exists( $flags=0)
Check if page exists.
Definition Title.php:3132
getText()
Get the text form (spaces not underscores) of the main part.
Definition Title.php:1007