MediaWiki  master
TraditionalImageGallery.php
Go to the documentation of this file.
1 <?php
2 
9 
43  public function toHTML() {
44  $resolveFilesViaParser = $this->mParser instanceof Parser;
45  if ( $resolveFilesViaParser ) {
46  $parserOutput = $this->mParser->getOutput();
47  $repoGroup = null;
48  $linkRenderer = $this->mParser->getLinkRenderer();
49  $badFileLookup = $this->mParser->getBadFileLookup();
50  } else {
51  $parserOutput = $this->getOutput();
52  $services = MediaWikiServices::getInstance();
53  $repoGroup = $services->getRepoGroup();
54  $linkRenderer = $services->getLinkRenderer();
55  $badFileLookup = $services->getBadFileLookup();
56  }
57 
58  if ( $this->mPerRow > 0 ) {
59  $maxwidth = $this->mPerRow * ( $this->mWidths + $this->getAllPadding() );
60  $oldStyle = $this->mAttribs['style'] ?? '';
61  $this->mAttribs['style'] = "max-width: {$maxwidth}px;" . $oldStyle;
62  }
63 
64  $attribs = Sanitizer::mergeAttributes(
65  [ 'class' => 'gallery mw-gallery-' . $this->mMode ], $this->mAttribs );
66 
67  $parserOutput->addModules( $this->getModules() );
68  $parserOutput->addModuleStyles( [ 'mediawiki.page.gallery.styles' ] );
69  $output = Xml::openElement( 'ul', $attribs );
70  if ( $this->mCaption ) {
71  $output .= "\n\t<li class='gallerycaption'>{$this->mCaption}</li>";
72  }
73 
74  if ( $this->mShowFilename ) {
75  // Preload LinkCache info for when generating links
76  // of the filename below
77  $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
78  $lb = $linkBatchFactory->newLinkBatch();
79  foreach ( $this->mImages as [ $title, /* see below */ ] ) {
80  $lb->addObj( $title );
81  }
82  $lb->execute();
83  }
84 
85  $lang = $this->getRenderLang();
86  $enableLegacyMediaDOM =
87  $this->getConfig()->get( MainConfigNames::ParserEnableLegacyMediaDOM );
88 
89  # Output each image...
90  foreach ( $this->mImages as [ $nt, $text, $alt, $link, $handlerOpts, $loading, $imageOptions ] ) {
91  // "text" means "caption" here
94  $descQuery = false;
95  if ( $nt->inNamespace( NS_FILE ) && !$nt->isExternal() ) {
96  # Get the file...
97  if ( $resolveFilesViaParser ) {
98  # Give extensions a chance to select the file revision for us
99  $options = [];
100  Hooks::runner()->onBeforeParserFetchFileAndTitle(
101  // @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args
102  $this->mParser, $nt, $options, $descQuery );
103  # Fetch and register the file (file title may be different via hooks)
104  [ $img, $nt ] = $this->mParser->fetchFileAndTitle( $nt, $options );
105  } else {
106  $img = $repoGroup->findFile( $nt );
107  }
108  } else {
109  $img = false;
110  }
111 
112  $transformOptions = $this->getThumbParams( $img ) + $handlerOpts;
113  $thumb = $img ? $img->transform( $transformOptions ) : false;
114 
115  $rdfaType = 'mw:File';
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  $label = $alt ?? '';
132  $thumbhtml = Linker::makeBrokenImageLinkObj(
133  $nt, $label, '', '', '', false, $transformOptions
134  );
135  $thumbhtml = Html::rawElement( 'span', [ 'typeof' => $rdfaType ], $thumbhtml );
136  }
137 
138  $thumbhtml = "\n\t\t\t" . '<div class="thumb" style="height: '
139  . ( $this->getThumbPadding() + $this->mHeights ) . 'px;">'
140  . $thumbhtml . '</div>';
141 
142  if ( !$img && $resolveFilesViaParser ) {
143  $this->mParser->addTrackingCategory( 'broken-file-category' );
144  }
145  } else {
147  $vpad = $this->getVPad( $this->mHeights, $thumb->getHeight() );
148 
149  // Backwards compat before the $imageOptions existed
150  if ( $imageOptions === null ) {
151  $imageParameters = [
152  'desc-link' => true,
153  'desc-query' => $descQuery,
154  'alt' => $alt ?? '',
155  'custom-url-link' => $link
156  ];
157  } else {
158  $params = [];
159  // An empty alt indicates an image is not a key part of the
160  // content and that non-visual browsers may omit it from
161  // rendering. Only set the parameter if it's explicitly
162  // requested.
163  if ( $alt !== null ) {
164  $params['alt'] = $alt;
165  }
166  $params['title'] = $imageOptions['title'];
167  $imageParameters = Linker::getImageLinkMTOParams(
168  $imageOptions, $descQuery, $this->mParser
169  ) + $params;
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:172
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.
Base class for language-specific code.
Definition: Language.php:56
truncateForVisual( $string, $length, $ellipsis='...', $adjustLength=true)
Truncate a string to a specified number of characters, appending an optional string (e....
Definition: Language.php:3513
This class is a collection of static functions that serve two purposes:
Definition: Html.php:55
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.
Represents a title within MediaWiki.
Definition: Title.php:82
getText()
Get the text form (spaces not underscores) of the main part.
Definition: Title.php:1078
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition: Parser.php:107
getOutput()
Definition: Parser.php:1095
static mergeAttributes( $a, $b)
Merge two sets of HTML attributes.
Definition: Sanitizer.php:675
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:113
if(!isset( $args[0])) $lang