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 $thumb = $img ? $img->transform( $transformOptions ) : false;
109
110 $rdfaType = 'mw:File';
111
112 $isBadFile = $img && $thumb && $this->mHideBadImages &&
113 $badFileLookup->isBadFile( $nt->getDBkey(), $this->getContextTitle() );
114
115 if ( !$img || !$thumb || $thumb->isError() || $isBadFile ) {
116 $rdfaType = 'mw:Error ' . $rdfaType;
117
118 $currentExists = $img && $img->exists();
119 if ( $currentExists && !$thumb ) {
120 $label = wfMessage( 'thumbnail_error', '' )->text();
121 } elseif ( $thumb && $thumb->isError() ) {
122 Assert::invariant(
123 $thumb instanceof MediaTransformError,
124 'Unknown MediaTransformOutput: ' . get_class( $thumb )
125 );
126 $label = $thumb->toText();
127 } else {
128 $label = $alt ?? '';
129 }
130 $thumbhtml = Linker::makeBrokenImageLinkObj(
131 $nt, $label, '', '', '', false, $transformOptions, $currentExists
132 );
133 $thumbhtml = Html::rawElement( 'span', [ 'typeof' => $rdfaType ], $thumbhtml );
134
135 $thumbhtml = "\n\t\t\t" . Html::rawElement(
136 'div',
137 [
138 'class' => 'thumb',
139 'style' => 'height: ' . ( $this->getThumbPadding() + $this->mHeights ) . 'px;'
140 ],
141 $thumbhtml
142 );
143
144 if ( !$img && $resolveFilesViaParser ) {
145 $this->mParser->addTrackingCategory( 'broken-file-category' );
146 }
147 } else {
149 $vpad = $this->getVPad( $this->mHeights, $thumb->getHeight() );
150
151 // Backwards compat before the $imageOptions existed
152 if ( $imageOptions === null ) {
153 $imageParameters = [
154 'desc-link' => true,
155 'desc-query' => $descQuery,
156 'alt' => $alt ?? '',
157 'custom-url-link' => $link
158 ];
159 } else {
160 $params = [];
161 // An empty alt indicates an image is not a key part of the
162 // content and that non-visual browsers may omit it from
163 // rendering. Only set the parameter if it's explicitly
164 // requested.
165 if ( $alt !== null ) {
166 $params['alt'] = $alt;
167 }
168 $params['title'] = $imageOptions['title'];
169 $params['img-class'] = 'mw-file-element';
170 $imageParameters = Linker::getImageLinkMTOParams(
171 $imageOptions, $descQuery, $this->mParser
172 ) + $params;
173 }
174
175 if ( $loading === ImageGalleryBase::LOADING_LAZY ) {
176 $imageParameters['loading'] = 'lazy';
177 }
178
179 $this->adjustImageParameters( $thumb, $imageParameters );
180
181 Linker::processResponsiveImages( $img, $thumb, $transformOptions );
182
183 $thumbhtml = $thumb->toHtml( $imageParameters );
184 $thumbhtml = Html::rawElement(
185 'span', [ 'typeof' => $rdfaType ], $thumbhtml
186 );
187
188 # Set both fixed width and min-height.
189 $width = $this->getThumbDivWidth( $thumb->getWidth() );
190 $height = $this->getThumbPadding() + $this->mHeights;
191 $thumbhtml = "\n\t\t\t" . Html::rawElement( 'div', [
192 'class' => 'thumb',
193 'style' => "width: {$width}px;" .
194 ( $this->mMode === 'traditional' ? " height: {$height}px;" : '' ),
195 ], $thumbhtml );
196
197 // Call parser transform hook
198 if ( $resolveFilesViaParser ) {
200 $handler = $img->getHandler();
201 if ( $handler ) {
202 $handler->parserTransformHook( $this->mParser, $img );
203 }
204 $this->mParser->modifyImageHtml(
205 $img, [ 'handler' => $imageParameters ], $thumbhtml );
206 }
207 }
208
209 $meta = [];
210 if ( $img ) {
211 if ( $this->mShowDimensions ) {
212 $meta[] = htmlspecialchars( $img->getDimensionsString() );
213 }
214 if ( $this->mShowBytes ) {
215 $meta[] = htmlspecialchars( $lang->formatSize( $img->getSize() ) );
216 }
217 } elseif ( $this->mShowDimensions || $this->mShowBytes ) {
218 $meta[] = $this->msg( 'filemissing' )->escaped();
219 }
220 $meta = $lang->semicolonList( $meta );
221 if ( $meta ) {
222 $meta .= Html::rawElement( 'br', [] ) . "\n";
223 }
224
225 $textlink = $this->mShowFilename ?
226 $this->getCaptionHtml( $nt, $lang, $linkRenderer ) :
227 '';
228
229 $galleryText = $this->wrapGalleryText( $textlink . $text . $meta, $thumb );
230
231 $gbWidth = $this->getGBWidthOverwrite( $thumb ) ?: $this->getGBWidth( $thumb ) . 'px';
232 # Weird double wrapping (the extra div inside the li) needed due to FF2 bug
233 # Can be safely removed if FF2 falls completely out of existence
234 $output .= "\n\t\t" .
235 Html::rawElement(
236 'li',
237 [ 'class' => 'gallerybox', 'style' => 'width: ' . $gbWidth ],
238 $thumbhtml
239 . $galleryText
240 . "\n\t\t"
241 );
242 }
243 $output .= "\n" . Html::closeElement( 'ul' );
244
245 return $output;
246 }
247
254 protected function getCaptionHtml( Title $nt, Language $lang, LinkRenderer $linkRenderer ) {
255 // Preloaded into LinkCache in toHTML
256 return $linkRenderer->makeKnownLink(
257 $nt,
258 is_int( $this->getCaptionLength() ) ?
259 $lang->truncateForVisual( $nt->getText(), $this->getCaptionLength() ) :
260 $nt->getText(),
261 [
262 'class' => 'galleryfilename' .
263 ( $this->getCaptionLength() === true ? ' galleryfilename-truncate' : '' )
264 ]
265 ) . "\n";
266 }
267
276 protected function wrapGalleryText( $galleryText, $thumb ) {
277 return "\n\t\t\t" . Html::rawElement( 'div', [ 'class' => "gallerytext" ], $galleryText );
278 }
279
286 protected function getThumbPadding() {
287 return 30;
288 }
289
295 protected function getGBPadding() {
296 return 5;
297 }
298
306 protected function getGBBorders() {
307 return 8;
308 }
309
317 protected function getCaptionLength() {
319 }
320
326 protected function getAllPadding() {
327 return $this->getThumbPadding() + $this->getGBPadding() + $this->getGBBorders();
328 }
329
339 protected function getVPad( $boxHeight, $thumbHeight ) {
340 return ( $this->getThumbPadding() + $boxHeight - $thumbHeight ) / 2;
341 }
342
349 protected function getThumbParams( $img ) {
350 return [
351 'width' => $this->mWidths,
352 'height' => $this->mHeights
353 ];
354 }
355
363 protected function getThumbDivWidth( $thumbWidth ) {
364 return $this->mWidths + $this->getThumbPadding();
365 }
366
377 protected function getGBWidth( $thumb ) {
378 return $this->mWidths + $this->getThumbPadding() + $this->getGBPadding();
379 }
380
392 protected function getGBWidthOverwrite( $thumb ) {
393 return false;
394 }
395
403 protected function getModules() {
404 return [];
405 }
406
414 protected function adjustImageParameters( $thumb, &$imageParameters ) {
415 }
416}
417
419class_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:79
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:43
Base class for language-specific code.
Definition Language.php:68
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:135
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