Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 76 |
|
0.00% |
0 / 23 |
CRAP | |
0.00% |
0 / 1 |
ImageGalleryBase | |
0.00% |
0 / 76 |
|
0.00% |
0 / 23 |
1482 | |
0.00% |
0 / 1 |
factory | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
loadModes | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
6 | |||
__construct | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
6 | |||
setParser | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setHideBadImages | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setCaption | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setCaptionHtml | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setPerRow | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
setWidths | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
setHeights | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
setAdditionalOptions | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
add | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
insert | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getImages | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isEmpty | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setShowDimensions | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setShowBytes | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setShowFilename | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setAttributes | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
toHTML | n/a |
0 / 0 |
n/a |
0 / 0 |
0 | |||||
count | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setContextTitle | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getContextTitle | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRenderLang | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * Image gallery. |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
18 | * http://www.gnu.org/copyleft/gpl.html |
19 | * |
20 | * @file |
21 | */ |
22 | |
23 | use MediaWiki\Context\ContextSource; |
24 | use MediaWiki\Context\IContextSource; |
25 | use MediaWiki\Context\RequestContext; |
26 | use MediaWiki\HookContainer\HookRunner; |
27 | use MediaWiki\Language\Language; |
28 | use MediaWiki\MainConfigNames; |
29 | use MediaWiki\MediaWikiServices; |
30 | use MediaWiki\Parser\Parser; |
31 | use MediaWiki\Title\Title; |
32 | |
33 | /** |
34 | * Image gallery |
35 | * |
36 | * Add images to the gallery using add(), then render that list to HTML using toHTML(). |
37 | * @stable to extend |
38 | * @ingroup Media |
39 | */ |
40 | abstract class ImageGalleryBase extends ContextSource { |
41 | public const LOADING_DEFAULT = 1; |
42 | public const LOADING_LAZY = 2; |
43 | |
44 | /** |
45 | * @var array[] Gallery images |
46 | * @phan-var array<int,array{0:Title,1:string,2:string,3:string,4:array,5:int}> |
47 | */ |
48 | protected $mImages; |
49 | |
50 | /** |
51 | * @var bool Whether to show the filesize in bytes in categories |
52 | */ |
53 | protected $mShowBytes; |
54 | |
55 | /** |
56 | * @var bool Whether to show the dimensions in categories |
57 | */ |
58 | protected $mShowDimensions; |
59 | |
60 | /** |
61 | * @var bool Whether to show the filename. Default: true |
62 | */ |
63 | protected $mShowFilename; |
64 | |
65 | /** |
66 | * @var string Gallery mode. Default: traditional |
67 | */ |
68 | protected $mMode; |
69 | |
70 | /** |
71 | * @var string|false Gallery caption. Default: false |
72 | */ |
73 | protected $mCaption = false; |
74 | |
75 | /** |
76 | * Length to truncate filename to in caption when using "showfilename". |
77 | * A value of 'true' will truncate the filename to one line using CSS |
78 | * and will be the behaviour after deprecation. |
79 | * |
80 | * @var bool|int |
81 | */ |
82 | protected $mCaptionLength = true; |
83 | |
84 | /** |
85 | * @var bool Hide bad images? |
86 | */ |
87 | protected $mHideBadImages; |
88 | |
89 | /** |
90 | * @var Parser|false Registered parser object for output callbacks |
91 | */ |
92 | public $mParser; |
93 | |
94 | /** |
95 | * @var Title|null Contextual title, used when images are being screened against |
96 | * the bad image list |
97 | */ |
98 | protected $contextTitle = null; |
99 | |
100 | /** @var array */ |
101 | protected $mAttribs = []; |
102 | |
103 | /** @var int */ |
104 | protected $mPerRow; |
105 | |
106 | /** @var int */ |
107 | protected $mWidths; |
108 | |
109 | /** @var int */ |
110 | protected $mHeights; |
111 | |
112 | /** @var array */ |
113 | private static $modeMapping; |
114 | |
115 | /** |
116 | * Get a new image gallery. This is the method other callers |
117 | * should use to get a gallery. |
118 | * |
119 | * @param string|false $mode Mode to use. False to use the default |
120 | * @param IContextSource|null $context |
121 | * @return ImageGalleryBase |
122 | * @throws ImageGalleryClassNotFoundException |
123 | */ |
124 | public static function factory( $mode = false, ?IContextSource $context = null ) { |
125 | self::loadModes(); |
126 | if ( !$context ) { |
127 | $context = RequestContext::getMainAndWarn( __METHOD__ ); |
128 | } |
129 | if ( !$mode ) { |
130 | $galleryOptions = $context->getConfig()->get( MainConfigNames::GalleryOptions ); |
131 | $mode = $galleryOptions['mode']; |
132 | } |
133 | |
134 | $mode = MediaWikiServices::getInstance()->getContentLanguage()->lc( $mode ); |
135 | |
136 | if ( isset( self::$modeMapping[$mode] ) ) { |
137 | $class = self::$modeMapping[$mode]; |
138 | return new $class( $mode, $context ); |
139 | } else { |
140 | throw new ImageGalleryClassNotFoundException( "No gallery class registered for mode $mode" ); |
141 | } |
142 | } |
143 | |
144 | private static function loadModes() { |
145 | if ( self::$modeMapping === null ) { |
146 | self::$modeMapping = [ |
147 | 'traditional' => TraditionalImageGallery::class, |
148 | 'nolines' => NolinesImageGallery::class, |
149 | 'packed' => PackedImageGallery::class, |
150 | 'packed-hover' => PackedHoverImageGallery::class, |
151 | 'packed-overlay' => PackedOverlayImageGallery::class, |
152 | 'slideshow' => SlideshowImageGallery::class, |
153 | ]; |
154 | // Allow extensions to make a new gallery format. |
155 | ( new HookRunner( MediaWikiServices::getInstance()->getHookContainer() ) ) |
156 | ->onGalleryGetModes( self::$modeMapping ); |
157 | } |
158 | } |
159 | |
160 | /** |
161 | * Create a new image gallery object. |
162 | * |
163 | * You should not call this directly, but instead use |
164 | * ImageGalleryBase::factory(). |
165 | * |
166 | * @stable to call |
167 | * @note constructors of subclasses must have a compatible signature |
168 | * for use by the factory() method. |
169 | * |
170 | * @param string $mode |
171 | * @param IContextSource|null $context |
172 | */ |
173 | public function __construct( $mode = 'traditional', ?IContextSource $context = null ) { |
174 | if ( $context ) { |
175 | $this->setContext( $context ); |
176 | } |
177 | |
178 | $galleryOptions = $this->getConfig()->get( MainConfigNames::GalleryOptions ); |
179 | $this->mImages = []; |
180 | $this->mShowBytes = $galleryOptions['showBytes']; |
181 | $this->mShowDimensions = $galleryOptions['showDimensions']; |
182 | $this->mShowFilename = true; |
183 | $this->mParser = false; |
184 | $this->mHideBadImages = false; |
185 | $this->mPerRow = $galleryOptions['imagesPerRow']; |
186 | $this->mWidths = $galleryOptions['imageWidth']; |
187 | $this->mHeights = $galleryOptions['imageHeight']; |
188 | $this->mCaptionLength = $galleryOptions['captionLength']; |
189 | $this->mMode = $mode; |
190 | } |
191 | |
192 | /** |
193 | * Register a parser object. If you do not set this |
194 | * and the output of this gallery ends up in parser |
195 | * cache, the javascript will break! |
196 | * |
197 | * @note This also triggers using the page's target |
198 | * language instead of the user language. |
199 | * |
200 | * @param Parser $parser |
201 | */ |
202 | public function setParser( $parser ) { |
203 | $this->mParser = $parser; |
204 | } |
205 | |
206 | /** |
207 | * @param bool $flag |
208 | */ |
209 | public function setHideBadImages( $flag = true ) { |
210 | $this->mHideBadImages = $flag; |
211 | } |
212 | |
213 | /** |
214 | * Set the caption (as plain text) |
215 | * |
216 | * @param string $caption |
217 | */ |
218 | public function setCaption( $caption ) { |
219 | $this->mCaption = htmlspecialchars( $caption ); |
220 | } |
221 | |
222 | /** |
223 | * Set the caption (as HTML) |
224 | * |
225 | * @param string $caption |
226 | */ |
227 | public function setCaptionHtml( $caption ) { |
228 | $this->mCaption = $caption; |
229 | } |
230 | |
231 | /** |
232 | * Set how many images will be displayed per row. |
233 | * |
234 | * @param int $num Integer >= 0; If perrow=0 the gallery layout will adapt |
235 | * to screensize invalid numbers will be rejected |
236 | */ |
237 | public function setPerRow( $num ) { |
238 | if ( $num >= 0 ) { |
239 | $this->mPerRow = (int)$num; |
240 | } |
241 | } |
242 | |
243 | /** |
244 | * Set how wide each image will be, in pixels. |
245 | * |
246 | * @param string $num Number. Unit other than 'px is invalid. Invalid numbers |
247 | * and those below 0 are ignored. |
248 | */ |
249 | public function setWidths( $num ) { |
250 | $parser = $this->mParser; |
251 | if ( !$parser ) { |
252 | wfDeprecated( __METHOD__ . ' without parser', '1.43' ); |
253 | $parser = MediaWikiServices::getInstance()->getParser(); |
254 | } |
255 | $parsed = $parser->parseWidthParam( $num, false ); |
256 | if ( isset( $parsed['width'] ) && $parsed['width'] > 0 ) { |
257 | $this->mWidths = $parsed['width']; |
258 | } |
259 | } |
260 | |
261 | /** |
262 | * Set how high each image will be, in pixels. |
263 | * |
264 | * @param string $num Number. Unit other than 'px is invalid. Invalid numbers |
265 | * and those below 0 are ignored. |
266 | */ |
267 | public function setHeights( $num ) { |
268 | $parser = $this->mParser; |
269 | if ( !$parser ) { |
270 | wfDeprecated( __METHOD__ . ' without parser', '1.43' ); |
271 | $parser = MediaWikiServices::getInstance()->getParser(); |
272 | } |
273 | $parsed = $parser->parseWidthParam( $num, false ); |
274 | if ( isset( $parsed['width'] ) && $parsed['width'] > 0 ) { |
275 | $this->mHeights = $parsed['width']; |
276 | } |
277 | } |
278 | |
279 | /** |
280 | * Allow setting additional options. This is meant |
281 | * to allow extensions to add additional parameters to |
282 | * <gallery> parser tag. |
283 | * |
284 | * @stable to override |
285 | * |
286 | * @param array $options Attributes of gallery tag |
287 | */ |
288 | public function setAdditionalOptions( $options ) { |
289 | } |
290 | |
291 | /** |
292 | * Add an image to the gallery. |
293 | * |
294 | * @param Title $title Title object of the image that is added to the gallery |
295 | * @param string $html Additional HTML text to be shown. The name and size |
296 | * of the image are always shown. |
297 | * @param string|null $alt Alt text for the image, or null to omit |
298 | * @param string $link Override image link (optional) |
299 | * @param array $handlerOpts Array of options for image handler (aka page number) |
300 | * @param int $loading Sets loading attribute of the underlying <img> (optional) |
301 | * @param ?array $imageOptions To supercede the $link param |
302 | */ |
303 | public function add( |
304 | $title, |
305 | $html = '', |
306 | $alt = '', |
307 | $link = '', |
308 | $handlerOpts = [], |
309 | $loading = self::LOADING_DEFAULT, |
310 | ?array $imageOptions = null |
311 | ) { |
312 | if ( $title instanceof File ) { |
313 | // Old calling convention |
314 | $title = $title->getTitle(); |
315 | } |
316 | $this->mImages[] = [ $title, $html, $alt, $link, $handlerOpts, $loading, $imageOptions ]; |
317 | wfDebug( 'ImageGallery::add ' . $title->getText() ); |
318 | } |
319 | |
320 | /** |
321 | * Add an image at the beginning of the gallery. |
322 | * |
323 | * @param Title $title Title object of the image that is added to the gallery |
324 | * @param string $html Additional HTML text to be shown. The name and size |
325 | * of the image are always shown. |
326 | * @param string $alt Alt text for the image |
327 | * @param string $link Override image link (optional) |
328 | * @param array $handlerOpts Array of options for image handler (aka page number) |
329 | * @param int $loading Sets loading attribute of the underlying <img> (optional) |
330 | * @param ?array $imageOptions To supercede the $link param |
331 | */ |
332 | public function insert( |
333 | $title, |
334 | $html = '', |
335 | $alt = '', |
336 | $link = '', |
337 | $handlerOpts = [], |
338 | $loading = self::LOADING_DEFAULT, |
339 | ?array $imageOptions = null |
340 | ) { |
341 | if ( $title instanceof File ) { |
342 | // Old calling convention |
343 | $title = $title->getTitle(); |
344 | } |
345 | array_unshift( $this->mImages, [ &$title, $html, $alt, $link, $handlerOpts, $loading, $imageOptions ] ); |
346 | } |
347 | |
348 | /** |
349 | * Returns the list of images this gallery contains |
350 | * @return array[] |
351 | * @phan-return array<int,array{0:Title,1:string,2:string,3:string,4:array}> |
352 | */ |
353 | public function getImages() { |
354 | return $this->mImages; |
355 | } |
356 | |
357 | /** |
358 | * isEmpty() returns true if the gallery contains no images |
359 | * @return bool |
360 | */ |
361 | public function isEmpty() { |
362 | return $this->mImages === []; |
363 | } |
364 | |
365 | /** |
366 | * Enable/Disable showing of the dimensions of an image in the gallery. |
367 | * Enabled by default. |
368 | * |
369 | * @param bool $f Set to false to disable |
370 | */ |
371 | public function setShowDimensions( $f ) { |
372 | $this->mShowDimensions = (bool)$f; |
373 | } |
374 | |
375 | /** |
376 | * Enable/Disable showing of the file size of an image in the gallery. |
377 | * Enabled by default. |
378 | * |
379 | * @param bool $f Set to false to disable |
380 | */ |
381 | public function setShowBytes( $f ) { |
382 | $this->mShowBytes = (bool)$f; |
383 | } |
384 | |
385 | /** |
386 | * Enable/Disable showing of the filename of an image in the gallery. |
387 | * Enabled by default. |
388 | * |
389 | * @param bool $f Set to false to disable |
390 | */ |
391 | public function setShowFilename( $f ) { |
392 | $this->mShowFilename = (bool)$f; |
393 | } |
394 | |
395 | /** |
396 | * Set arbitrary attributes to go on the HTML gallery output element. |
397 | * Should be suitable for a <ul> element. |
398 | * |
399 | * Note -- if taking from user input, you should probably run through |
400 | * Sanitizer::validateAttributes() first. |
401 | * |
402 | * @param array $attribs Array of HTML attribute pairs |
403 | */ |
404 | public function setAttributes( $attribs ) { |
405 | $this->mAttribs = $attribs; |
406 | } |
407 | |
408 | /** |
409 | * Display an html representation of the gallery |
410 | * |
411 | * @return string The html |
412 | */ |
413 | abstract public function toHTML(); |
414 | |
415 | /** |
416 | * @return int Number of images in the gallery |
417 | */ |
418 | public function count() { |
419 | return count( $this->mImages ); |
420 | } |
421 | |
422 | /** |
423 | * Set the contextual title |
424 | * |
425 | * @param Title|null $title Contextual title |
426 | */ |
427 | public function setContextTitle( $title ) { |
428 | $this->contextTitle = $title; |
429 | } |
430 | |
431 | /** |
432 | * Get the contextual title, if applicable |
433 | * |
434 | * @return Title|null |
435 | */ |
436 | public function getContextTitle() { |
437 | return $this->contextTitle; |
438 | } |
439 | |
440 | /** |
441 | * Determines the correct language to be used for this image gallery |
442 | * @return Language |
443 | */ |
444 | protected function getRenderLang() { |
445 | return $this->mParser |
446 | ? $this->mParser->getTargetLanguage() |
447 | : $this->getLanguage(); |
448 | } |
449 | } |