MediaWiki  master
ThumbnailImage.php
Go to the documentation of this file.
1 <?php
30  private static $firstNonIconImageRendered = false;
31 
44  function __construct( $file, $url, $path = false, $parameters = [] ) {
45  # Previous parameters:
46  # $file, $url, $width, $height, $path = false, $page = false
47 
48  $defaults = [
49  'page' => false,
50  'lang' => false
51  ];
52 
53  if ( is_array( $parameters ) ) {
54  $actualParams = $parameters + $defaults;
55  } else {
56  # Using old format, should convert. Later a warning could be added here.
57  $numArgs = func_num_args();
58  $actualParams = [
59  'width' => $path,
60  'height' => $parameters,
61  'page' => ( $numArgs > 5 ) ? func_get_arg( 5 ) : false
62  ] + $defaults;
63  $path = ( $numArgs > 4 ) ? func_get_arg( 4 ) : false;
64  }
65 
66  $this->file = $file;
67  $this->url = $url;
68  $this->path = $path;
69 
70  # These should be integers when they get here.
71  # If not, there's a bug somewhere. But let's at
72  # least produce valid HTML code regardless.
73  $this->width = round( $actualParams['width'] );
74  $this->height = round( $actualParams['height'] );
75 
76  $this->page = $actualParams['page'];
77  $this->lang = $actualParams['lang'];
78  }
79 
112  function toHtml( $options = [] ) {
114 
115  if ( func_num_args() == 2 ) {
116  throw new MWException( __METHOD__ . ' called in the old style' );
117  }
118 
119  $alt = $options['alt'] ?? '';
120 
121  $query = $options['desc-query'] ?? '';
122 
123  $attribs = [
124  'alt' => $alt,
125  'src' => $this->url,
126  'decoding' => 'async',
127  ];
128 
129  if ( $wgNativeImageLazyLoading ) {
130  $attribs['loading'] = 'lazy';
131  }
132 
133  $elementTimingName = 'thumbnail';
134 
135  if ( $wgPriorityHints
136  && !self::$firstNonIconImageRendered
137  && $this->width * $this->height > 100 * 100 ) {
138  self::$firstNonIconImageRendered = true;
139 
140  // Generate a random number between 0.01 and 1.0, included
141  $random = rand( 1, 100 ) / 100.0;
142 
143  if ( $random <= $wgPriorityHintsRatio ) {
144  $attribs['importance'] = 'high';
145  $elementTimingName = 'thumbnail-high';
146  } else {
147  // This lets us track that the thumbnail *would* have gotten high priority but didn't.
148  $elementTimingName = 'thumbnail-top';
149  }
150  }
151 
152  if ( $wgElementTiming ) {
153  $attribs['elementtiming'] = $elementTimingName;
154  }
155 
156  if ( !empty( $options['custom-url-link'] ) ) {
157  $linkAttribs = [ 'href' => $options['custom-url-link'] ];
158  if ( !empty( $options['title'] ) ) {
159  $linkAttribs['title'] = $options['title'];
160  }
161  if ( !empty( $options['custom-target-link'] ) ) {
162  $linkAttribs['target'] = $options['custom-target-link'];
163  } elseif ( !empty( $options['parser-extlink-target'] ) ) {
164  $linkAttribs['target'] = $options['parser-extlink-target'];
165  }
166  if ( !empty( $options['parser-extlink-rel'] ) ) {
167  $linkAttribs['rel'] = $options['parser-extlink-rel'];
168  }
169  } elseif ( !empty( $options['custom-title-link'] ) ) {
171  $title = $options['custom-title-link'];
172  $linkAttribs = [
173  'href' => $title->getLinkURL(),
174  'title' => empty( $options['title'] ) ? $title->getFullText() : $options['title']
175  ];
176  } elseif ( !empty( $options['desc-link'] ) ) {
177  $linkAttribs = $this->getDescLinkAttribs(
178  empty( $options['title'] ) ? null : $options['title'],
179  $query
180  );
181  } elseif ( !empty( $options['file-link'] ) ) {
182  $linkAttribs = [ 'href' => $this->file->getUrl() ];
183  } else {
184  $linkAttribs = false;
185  if ( !empty( $options['title'] ) ) {
186  $attribs['title'] = $options['title'];
187  }
188  }
189 
190  if ( empty( $options['no-dimensions'] ) ) {
191  $attribs['width'] = $this->width;
192  $attribs['height'] = $this->height;
193  }
194  if ( !empty( $options['valign'] ) ) {
195  $attribs['style'] = "vertical-align: {$options['valign']}";
196  }
197  if ( !empty( $options['img-class'] ) ) {
198  $attribs['class'] = $options['img-class'];
199  }
200  if ( isset( $options['override-height'] ) ) {
201  $attribs['height'] = $options['override-height'];
202  }
203  if ( isset( $options['override-width'] ) ) {
204  $attribs['width'] = $options['override-width'];
205  }
206 
207  // Additional densities for responsive images, if specified.
208  // If any of these urls is the same as src url, it'll be excluded.
209  $responsiveUrls = array_diff( $this->responsiveUrls, [ $this->url ] );
210  if ( !empty( $responsiveUrls ) ) {
211  $attribs['srcset'] = Html::srcSet( $responsiveUrls );
212  }
213 
214  Hooks::run( 'ThumbnailBeforeProduceHTML', [ $this, &$attribs, &$linkAttribs ] );
215 
216  return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
217  }
218 }
toHtml( $options=[])
Return HTML.
static $firstNonIconImageRendered
bool string $path
Filesystem path to the thumb.
string $url
URL path to the thumb.
array $responsiveUrls
Associative array mapping optional supplementary image files from pixel density (eg 1...
Base class for the output of MediaHandler::doTransform() and File::transform().
bool $wgPriorityHints
Enable client-side Priority Hints.
__construct( $file, $url, $path=false, $parameters=[])
Get a thumbnail object from a file and parameters.
Media transform output for images.
getDescLinkAttribs( $title=null, $params=[])
linkWrap( $linkAttribs, $contents)
Wrap some XHTML text in an anchor tag with the given attributes.
bool $wgElementTiming
Enable Element Timing.
float $wgPriorityHintsRatio
Ratio of requests that should get Priority Hints when the feature is enabled.
static srcSet(array $urls)
Generate a srcset attribute value.
Definition: Html.php:1068
array $wgNativeImageLazyLoading
Toggles native image lazy loading, via the "loading" attribute.
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
int $height
Image height.
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200