MediaWiki  master
TraditionalImageGallery.php
Go to the documentation of this file.
1 <?php
2 
6 
40  public function toHTML() {
41  $resolveFilesViaParser = $this->mParser instanceof Parser;
42  if ( $resolveFilesViaParser ) {
43  $parserOutput = $this->mParser->getOutput();
44  $repoGroup = null;
45  $linkRenderer = $this->mParser->getLinkRenderer();
46  $badFileLookup = $this->mParser->getBadFileLookup();
47  } else {
48  $parserOutput = $this->getOutput();
49  $services = MediaWikiServices::getInstance();
50  $repoGroup = $services->getRepoGroup();
51  $linkRenderer = $services->getLinkRenderer();
52  $badFileLookup = $services->getBadFileLookup();
53  }
54 
55  if ( $this->mPerRow > 0 ) {
56  $maxwidth = $this->mPerRow * ( $this->mWidths + $this->getAllPadding() );
57  $oldStyle = $this->mAttribs['style'] ?? '';
58  $this->mAttribs['style'] = "max-width: {$maxwidth}px;" . $oldStyle;
59  }
60 
61  $attribs = Sanitizer::mergeAttributes(
62  [ 'class' => 'gallery mw-gallery-' . $this->mMode ], $this->mAttribs );
63 
64  $parserOutput->addModules( $this->getModules() );
65  $parserOutput->addModuleStyles( [ 'mediawiki.page.gallery.styles' ] );
66  $output = Xml::openElement( 'ul', $attribs );
67  if ( $this->mCaption ) {
68  $output .= "\n\t<li class='gallerycaption'>{$this->mCaption}</li>";
69  }
70 
71  if ( $this->mShowFilename ) {
72  // Preload LinkCache info for when generating links
73  // of the filename below
74  $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
75  $lb = $linkBatchFactory->newLinkBatch();
76  foreach ( $this->mImages as [ $title, /* see below */ ] ) {
77  $lb->addObj( $title );
78  }
79  $lb->execute();
80  }
81 
82  $lang = $this->getRenderLang();
83  $enableLegacyMediaDOM =
84  $this->getConfig()->get( MainConfigNames::ParserEnableLegacyMediaDOM );
85 
86  # Output each image...
87  foreach ( $this->mImages as [ $nt, $text, $alt, $link, $handlerOpts, $loading, $imageOptions ] ) {
88  // "text" means "caption" here
91  $descQuery = false;
92  if ( $nt->inNamespace( NS_FILE ) && !$nt->isExternal() ) {
93  # Get the file...
94  if ( $resolveFilesViaParser ) {
95  # Give extensions a chance to select the file revision for us
96  $options = [];
97  Hooks::runner()->onBeforeParserFetchFileAndTitle(
98  // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args
99  $this->mParser, $nt, $options, $descQuery );
100  # Fetch and register the file (file title may be different via hooks)
101  list( $img, $nt ) = $this->mParser->fetchFileAndTitle( $nt, $options );
102  } else {
103  $img = $repoGroup->findFile( $nt );
104  }
105  } else {
106  $img = false;
107  }
108 
109  $transformOptions = $this->getThumbParams( $img ) + $handlerOpts;
110  $thumb = $img ? $img->transform( $transformOptions ) : false;
111 
112  $rdfaType = [
113  'AUDIO' => 'mw:Audio',
114  'VIDEO' => 'mw:Video',
115  ][ $img ? $img->getMediaType() : '' ] ?? 'mw:Image';
116 
117  $isBadFile = $img && $thumb && $this->mHideBadImages &&
118  $badFileLookup->isBadFile( $nt->getDBkey(), $this->getContextTitle() );
119 
120  if ( !$img || !$thumb || $isBadFile ) {
121  $rdfaType = 'mw:Error ' . $rdfaType;
122 
123  if ( $enableLegacyMediaDOM ) {
124  if ( $isBadFile ) {
125  $thumbhtml = $linkRenderer->makeKnownLink( $nt, $nt->getText() );
126  } else {
127  $thumbhtml = htmlspecialchars( $img ? $img->getLastError() : $nt->getText() );
128  }
129  } else {
130  // FIXME: BadFile is known
131  $thumbhtml = Linker::makeBrokenImageLinkObj(
132  $nt, '', '', '', '', false, $transformOptions
133  );
134  $thumbhtml = Html::rawElement( 'span', [ 'typeof' => $rdfaType ], $thumbhtml );
135  }
136 
137  $thumbhtml = "\n\t\t\t" . '<div class="thumb" style="height: '
138  . ( $this->getThumbPadding() + $this->mHeights ) . 'px;">'
139  . $thumbhtml . '</div>';
140 
141  if ( !$img && $resolveFilesViaParser ) {
142  $this->mParser->addTrackingCategory( 'broken-file-category' );
143  }
144  } else {
146  $vpad = $this->getVPad( $this->mHeights, $thumb->getHeight() );
147 
148  // Backwards compat before the $imageOptions existed
149  if ( $imageOptions === null ) {
150  $imageParameters = [
151  'desc-link' => true,
152  'desc-query' => $descQuery,
153  'alt' => $alt,
154  'custom-url-link' => $link
155  ];
156  } else {
157  $params = [
158  'alt' => $alt,
159  'title' => $imageOptions['title'],
160  ];
161  $imageParameters = Linker::getImageLinkMTOParams(
162  $imageOptions, $descQuery, $this->mParser
163  ) + $params;
164  }
165 
166  // In the absence of both alt text and caption, fall back on
167  // providing screen readers with the filename as alt text
168  if ( $alt == '' && $text == '' ) {
169  $imageParameters['alt'] = $nt->getText();
170  }
171 
172  if ( $loading === ImageGalleryBase::LOADING_LAZY ) {
173  $imageParameters['loading'] = 'lazy';
174  }
175 
176  $this->adjustImageParameters( $thumb, $imageParameters );
177 
178  Linker::processResponsiveImages( $img, $thumb, $transformOptions );
179 
180  $thumbhtml = $thumb->toHtml( $imageParameters );
181 
182  if ( !$enableLegacyMediaDOM ) {
183  $thumbhtml = Html::rawElement(
184  'span', [ 'typeof' => $rdfaType ], $thumbhtml
185  );
186  } else {
187  $thumbhtml = Html::rawElement( 'div', [
188  # Auto-margin centering for block-level elements. Needed
189  # now that we have video handlers since they may emit block-
190  # level elements as opposed to simple <img> tags. ref
191  # http://css-discuss.incutio.com/?page=CenteringBlockElement
192  'style' => "margin:{$vpad}px auto;",
193  ], $thumbhtml );
194  }
195 
196  # Set both fixed width and min-height.
197  $width = $this->getThumbDivWidth( $thumb->getWidth() );
198  $height = $this->getThumbPadding() + $this->mHeights;
199  $thumbhtml = "\n\t\t\t" . Html::rawElement( 'div', [
200  'class' => 'thumb',
201  'style' => "width: {$width}px;" .
202  ( !$enableLegacyMediaDOM && $this->mMode === 'traditional' ?
203  " height: {$height}px;" : '' ),
204  ], $thumbhtml );
205 
206  // Call parser transform hook
207  if ( $resolveFilesViaParser ) {
209  $handler = $img->getHandler();
210  if ( $handler ) {
211  $handler->parserTransformHook( $this->mParser, $img );
212  }
213  $this->mParser->modifyImageHtml(
214  $img, [ 'handler' => $imageParameters ], $thumbhtml );
215  }
216  }
217 
218  $meta = [];
219  if ( $img ) {
220  if ( $this->mShowDimensions ) {
221  $meta[] = htmlspecialchars( $img->getDimensionsString() );
222  }
223  if ( $this->mShowBytes ) {
224  $meta[] = htmlspecialchars( $lang->formatSize( $img->getSize() ) );
225  }
226  } elseif ( $this->mShowDimensions || $this->mShowBytes ) {
227  $meta[] = $this->msg( 'filemissing' )->escaped();
228  }
229  $meta = $lang->semicolonList( $meta );
230  if ( $meta ) {
231  $meta .= "<br />\n";
232  }
233 
234  $textlink = $this->mShowFilename ?
235  $this->getCaptionHtml( $nt, $lang, $linkRenderer ) :
236  '';
237 
238  $galleryText = $this->wrapGalleryText( $textlink . $text . $meta, $thumb );
239 
240  $gbWidth = $this->getGBWidthOverwrite( $thumb ) ?: $this->getGBWidth( $thumb ) . 'px';
241  # Weird double wrapping (the extra div inside the li) needed due to FF2 bug
242  # Can be safely removed if FF2 falls completely out of existence
243  $output .= "\n\t\t" . '<li class="gallerybox" style="width: '
244  . $gbWidth . '">'
245  . ( $enableLegacyMediaDOM ? '<div style="width: ' . $gbWidth . '">' : '' )
246  . $thumbhtml
247  . $galleryText
248  . "\n\t\t"
249  . ( $enableLegacyMediaDOM ? '</div>' : '' )
250  . "</li>";
251  }
252  $output .= "\n</ul>";
253 
254  return $output;
255  }
256 
263  protected function getCaptionHtml( Title $nt, Language $lang, LinkRenderer $linkRenderer ) {
264  // Preloaded into LinkCache in toHTML
265  return $linkRenderer->makeKnownLink(
266  $nt,
267  is_int( $this->getCaptionLength() ) ?
268  $lang->truncateForVisual( $nt->getText(), $this->getCaptionLength() ) :
269  $nt->getText(),
270  [
271  'class' => 'galleryfilename' .
272  ( $this->getCaptionLength() === true ? ' galleryfilename-truncate' : '' )
273  ]
274  ) . "\n";
275  }
276 
285  protected function wrapGalleryText( $galleryText, $thumb ) {
286  # ATTENTION: The newline after <div class="gallerytext"> is needed to
287  # accommodate htmltidy which in version 4.8.6 generated crackpot html in
288  # its absence, see: https://phabricator.wikimedia.org/T3765
289  # -Ævar
290 
291  return "\n\t\t\t" . '<div class="gallerytext">' . "\n"
292  . $galleryText
293  . "\n\t\t\t</div>";
294  }
295 
302  protected function getThumbPadding() {
303  return 30;
304  }
305 
311  protected function getGBPadding() {
312  return 5;
313  }
314 
322  protected function getGBBorders() {
323  return 8;
324  }
325 
333  protected function getCaptionLength() {
334  return $this->mCaptionLength;
335  }
336 
342  protected function getAllPadding() {
343  return $this->getThumbPadding() + $this->getGBPadding() + $this->getGBBorders();
344  }
345 
355  protected function getVPad( $boxHeight, $thumbHeight ) {
356  return ( $this->getThumbPadding() + $boxHeight - $thumbHeight ) / 2;
357  }
358 
365  protected function getThumbParams( $img ) {
366  return [
367  'width' => $this->mWidths,
368  'height' => $this->mHeights
369  ];
370  }
371 
379  protected function getThumbDivWidth( $thumbWidth ) {
380  return $this->mWidths + $this->getThumbPadding();
381  }
382 
393  protected function getGBWidth( $thumb ) {
394  return $this->mWidths + $this->getThumbPadding() + $this->getGBPadding();
395  }
396 
408  protected function getGBWidthOverwrite( $thumb ) {
409  return false;
410  }
411 
419  protected function getModules() {
420  return [];
421  }
422 
430  protected function adjustImageParameters( $thumb, &$imageParameters ) {
431  }
432 }
const NS_FILE
Definition: Defines.php:70
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:214
Image gallery.
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.
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:45
truncateForVisual( $string, $length, $ellipsis='...', $adjustLength=true)
Truncate a string to a specified number of characters, appending an optional string (e....
Definition: Language.php:3558
static processResponsiveImages( $file, $thumb, $hp)
Process responsive images: add 1.5x and 2x subimages to the thumbnail, where applicable.
Definition: Linker.php:811
static makeBrokenImageLinkObj( $title, $label='', $query='', $unused1='', $unused2='', $time=false, array $handlerParams=[])
Make a "broken" link to an image.
Definition: Linker.php:847
static getImageLinkMTOParams( $frameParams, $query='', $parser=null)
Get the link parameters for MediaTransformOutput::toHtml() from given frame parameters supplied by th...
Definition: Linker.php:541
Class that generates HTML anchor link elements for pages.
makeKnownLink( $target, $text=null, array $extraAttribs=[], array $query=[])
A class containing constants representing the names of configuration variables.
MediaWikiServices is the service locator for the application scope of MediaWiki.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition: Parser.php:95
getOutput()
Definition: Parser.php:1116
static mergeAttributes( $a, $b)
Merge two sets of HTML attributes.
Definition: Sanitizer.php:676
Represents a title within MediaWiki.
Definition: Title.php:48
getText()
Get the text form (spaces not underscores) of the main part.
Definition: Title.php:1038
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.
static openElement( $element, $attribs=null)
This opens an XML element.
Definition: Xml.php:112
if(!isset( $args[0])) $lang