Completed
Push — master ( 9b2ed5...981814 )
by Jeroen De
76:07
created

formats/gallery/Gallery.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SRF;
4
5
use Html;
6
use SMW\ResultPrinter;
7
use SMWDataItem;
8
use SMWOutputs;
9
use SMWPrintRequest;
10
use SMWQueryResult;
11
use SRFUtils;
12
use Title;
13
14
/**
15
 * Result printer that outputs query results as a image gallery.
16
 *
17
 * @author Jeroen De Dauw < [email protected] >
18
 * @author mwjames
19
 * @author Rowan Rodrik van der Molen
20
 */
21
class Gallery extends ResultPrinter {
22
23
	/**
24
	 * @see SMWResultPrinter::getName
25
	 *
26
	 * @return string
27
	 */
28
	public function getName() {
29
		return $this->msg( 'srf_printername_gallery' )->text();
30
	}
31
32
	/**
33
	 * @see SMWResultPrinter::buildResult
34
	 *
35
	 * @since 1.8
36
	 *
37
	 * @param SMWQueryResult $results
38
	 *
39
	 * @return string
40
	 */
41 1
	protected function buildResult( SMWQueryResult $results ) {
42
43
		// Intro/outro are not planned to work with the widget option
44 1
		if ( ( $this->params['intro'] !== '' || $this->params['outro'] !== '' ) && $this->params['widget'] !== '' ) {
45
			return $results->addErrors(
46
				[
47
					$this->msg( 'srf-error-option-mix', 'widget' )->inContentLanguage()->text()
48
				]
49
			);
50
		};
51
52 1
		return $this->getResultText( $results, $this->outputMode );
53
	}
54
55
	/**
56
	 * @see SMWResultPrinter::getResultText
57
	 *
58
	 * @param $results SMWQueryResult
59
	 * @param $outputmode integer
60
	 *
61
	 * @return string
62
	 */
63 1
	public function getResultText( SMWQueryResult $results, $outputmode ) {
64
65
		// #224
66 1
		$ig = class_exists( '\TraditionalImageGallery' ) ? new \TraditionalImageGallery() : new \ImageGallery();
67
68 1
		$ig->setShowBytes( false );
69 1
		$ig->setShowFilename( false );
70
		
71 1
		if ( method_exists( $ig, 'setShowDimensions' ) ) {
72
			$ig->setShowDimensions( false );
73
		}
74
		
75 1
		$ig->setCaption( $this->mIntro ); // set caption to IQ header
76
77
		// No need for a special page to use the parser but for the "normal" page
78
		// view we have to ensure caption text is parsed correctly through the parser
79 1
		if ( !$this->isSpecialPage() ) {
80 1
			$ig->setParser( $GLOBALS['wgParser'] );
81
		}
82
83 1
		$html = '';
84 1
		$processing = '';
85
86 1
		if ( $this->params['widget'] == 'carousel' ) {
87
			// Carousel widget
88
			$ig->setAttributes( $this->getCarouselWidget() );
89 1
		} elseif ( $this->params['widget'] == 'slideshow' ) {
90
			// Slideshow widget
91
			$ig->setAttributes( $this->getSlideshowWidget() );
92
		} else {
93
94
			// Standard gallery attributes
95
			$attribs = [
96 1
				'id' => uniqid(),
97 1
				'class' => $this->getImageOverlay(),
98
			];
99
100 1
			$ig->setAttributes( $attribs );
101
		}
102
103
		// Only use redirects where the overlay option is not used and redirect
104
		// thumb images towards a different target
105 1
		if ( $this->params['redirects'] !== '' && !$this->params['overlay'] ) {
106
			SMWOutputs::requireResource( 'ext.srf.gallery.redirect' );
107
		}
108
109
		// For the carousel widget, the perrow option should not be set
110 1
		if ( $this->params['perrow'] !== '' && $this->params['widget'] !== 'carousel' ) {
111
			$ig->setPerRow( $this->params['perrow'] );
112
		}
113
114 1
		if ( $this->params['widths'] !== '' ) {
115
			$ig->setWidths( $this->params['widths'] );
116
		}
117
118 1
		if ( $this->params['heights'] !== '' ) {
119
			$ig->setHeights( $this->params['heights'] );
120
		}
121
122 1
		$printReqLabels = [];
123 1
		$redirectType = '';
124
125
		/**
126
		 * @var SMWPrintRequest $printReq
127
		 */
128 1
		foreach ( $results->getPrintRequests() as $printReq ) {
129 1
			$printReqLabels[] = $printReq->getLabel();
130
131
			// Get redirect type
132 1
			if ( $this->params['redirects'] === $printReq->getLabel() ) {
133 1
				$redirectType = $printReq->getTypeID();
134
			}
135
		}
136
137 1
		if ( $this->params['imageproperty'] !== '' && in_array( $this->params['imageproperty'], $printReqLabels ) ||
138 1
			$this->params['redirects'] !== '' && in_array( $this->params['redirects'], $printReqLabels ) ) {
139
140
			$this->addImageProperties(
141
				$results,
142
				$ig,
143
				$this->params['imageproperty'],
144
				$this->params['captionproperty'],
145
				$this->params['redirects'],
146
				$outputmode
147
			);
148
		} else {
149 1
			$this->addImagePages( $results, $ig );
150
		}
151
152
		// SRF Global settings
153 1
		SRFUtils::addGlobalJSVariables();
154
155
		// Display a processing image as long as the DOM is no ready
156 1
		if ( $this->params['widget'] !== '' ) {
157
			$processing = SRFUtils::htmlProcessingElement();
158
		}
159
160
		// Beautify the class selector
161 1
		$class = $this->params['widget'] ? '-' . $this->params['widget'] . ' ' : '';
162 1
		$class = $this->params['redirects'] !== '' && $this->params['overlay'] === false ? $class . ' srf-redirect' . ' ' : $class;
163 1
		$class = $this->params['class'] ? $class . ' ' . $this->params['class'] : $class;
164
165
		// Separate content from result output
166 1
		if ( !$ig->isEmpty() ) {
167
			$attribs = [
168 1
				'class' => 'srf-gallery' . $class,
169 1
				'data-redirect-type' => $redirectType,
170 1
				'data-ns-text' => $this->getFileNsTextForPageLanguage()
171
			];
172
173 1
			$html = Html::rawElement( 'div', $attribs, $processing . $ig->toHTML() );
174
		}
175
176
		// If available, create a link that points to further results
177 1
		if ( $this->linkFurtherResults( $results ) ) {
178
			$html .= $this->getLink( $results, SMW_OUTPUT_HTML )->getText( SMW_OUTPUT_HTML, $this->mLinker );
179
		}
180
181 1
		return [ $html, 'nowiki' => true, 'isHTML' => true ];
182
	}
183
184
	/**
185
	 * Handles queries where the images (and optionally their captions) are specified as properties.
186
	 *
187
	 * @since 1.5.3
188
	 *
189
	 * @param SMWQueryResult $results
190
	 * @param ImageGallery $ig
191
	 * @param string $imageProperty
192
	 * @param string $captionProperty
193
	 * @param string $redirectProperty
194
	 * @param $outputMode
195
	 */
196
	protected function addImageProperties( SMWQueryResult $results, &$ig, $imageProperty, $captionProperty, $redirectProperty, $outputMode ) {
197
		while ( /* array of SMWResultArray */
198
		$rows = $results->getNext() ) { // Objects (pages)
199
			$images = [];
200
			$captions = [];
201
			$redirects = [];
202
203
			for ( $i = 0, $n = count( $rows ); $i < $n; $i++ ) { // Properties
204
				/**
205
				 * @var SMWResultArray $resultArray
206
				 * @var SMWDataValue $dataValue
207
				 */
208
				$resultArray = $rows[$i];
209
210
				$label = $resultArray->getPrintRequest()->getMode() == SMWPrintRequest::PRINT_THIS
211
					? '-' : $resultArray->getPrintRequest()->getLabel();
212
213
				// Make sure always use real label here otherwise it results in an empty array
214
				if ( $resultArray->getPrintRequest()->getLabel() == $imageProperty ) {
215
					while ( ( $dataValue = $resultArray->getNextDataValue() ) !== false ) { // Property values
216
						if ( $dataValue->getTypeID() == '_wpg' ) {
217
							$images[] = $dataValue->getTitle();
218
						}
219
					}
220
				} elseif ( $label == $captionProperty ) {
221
					while ( ( $dataValue = $resultArray->getNextDataValue() ) !== false ) { // Property values
222
						$captions[] = $dataValue->getShortText( $outputMode, $this->getLinker( true ) );
223
					}
224
				} elseif ( $label == $redirectProperty ) {
225
					while ( ( $dataValue = $resultArray->getNextDataValue() ) !== false ) { // Property values
226
						if ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_WIKIPAGE ) {
227
							$redirects[] = $dataValue->getTitle();
228
						} elseif ( $dataValue->getDataItem()->getDIType() == SMWDataItem::TYPE_URI ) {
229
							$redirects[] = $dataValue->getURL();
230
						}
231
					}
232
				}
233
			}
234
235
			// Check available matches against captions
236
			$amountMatches = count( $captions ) == count( $images );
237
			$hasCaption = $amountMatches || count( $captions ) > 0;
238
239
			// Check available matches against redirects
240
			$amountRedirects = count( $redirects ) == count( $images );
241
			$hasRedirect = $amountRedirects || count( $redirects ) > 0;
242
243
			/**
244
			 * @var Title $imgTitle
245
			 */
246
			foreach ( $images as $imgTitle ) {
247
				if ( $imgTitle->exists() ) {
248
					$imgCaption = $hasCaption ? ( $amountMatches ? array_shift( $captions ) : $captions[0] ) : '';
249
					$imgRedirect = $hasRedirect ? ( $amountRedirects ? array_shift( $redirects ) : $redirects[0] ) : '';
250
					$this->addImageToGallery( $ig, $imgTitle, $imgCaption, $imgRedirect );
251
				}
252
			}
253
		}
254
	}
255
256
	/**
257
	 * Handles queries where the result objects are image pages.
258
	 *
259
	 * @since 1.5.3
260
	 *
261
	 * @param SMWQueryResult $results
262
	 * @param ImageGallery $ig
263
	 */
264 1
	protected function addImagePages( SMWQueryResult $results, &$ig ) {
265 1
		while ( $row = $results->getNext() ) {
266
			/**
267
			 * @var SMWResultArray $firstField
268
			 */
269 1
			$firstField = $row[0];
270 1
			$nextObject = $firstField->getNextDataValue();
271
272 1
			if ( $nextObject !== false ) {
273 1
				$imgTitle = $nextObject->getTitle();
274
275
				// Ensure the title belongs to the image namespace
276 1
				if ( $imgTitle instanceof Title && $imgTitle->getNamespace() === NS_FILE ) {
277 1
					$imgCaption = '';
278
279
					// Is there a property queried for display with ?property
280 1
					if ( isset( $row[1] ) ) {
281 1
						$imgCaption = $row[1]->getNextDataValue();
282 1
						if ( is_object( $imgCaption ) ) {
283 1
							$imgCaption = $imgCaption->getShortText( $this->outputMode, $this->getLinker( true ) );
284
						}
285
					}
286
287 1
					$this->addImageToGallery( $ig, $imgTitle, $imgCaption );
288
				}
289
			}
290
		}
291 1
	}
292
293
	/**
294
	 * Adds a single image to the gallery.
295
	 * Takes care of automatically adding a caption when none is provided and parsing it's wikitext.
296
	 *
297
	 * @since 1.5.3
298
	 *
299
	 * @param ImageGallery $ig The gallery to add the image to
300
	 * @param Title $imgTitle The title object of the page of the image
301
	 * @param string $imgCaption An optional caption for the image
302
	 * @param string $imgRedirect
303
	 */
304 1
	protected function addImageToGallery( &$ig, Title $imgTitle, $imgCaption, $imgRedirect = '' ) {
305
306 1
		if ( empty( $imgCaption ) ) {
307
			if ( $this->params['autocaptions'] ) {
308
				$imgCaption = $imgTitle->getBaseText();
309
310
				if ( !$this->params['fileextensions'] ) {
311
					$imgCaption = preg_replace( '#\.[^.]+$#', '', $imgCaption );
312
				}
313
			} else {
314
				$imgCaption = '';
315
			}
316
		} else {
317 1
			if ( $imgTitle instanceof Title && $imgTitle->getNamespace() == NS_FILE && !$this->isSpecialPage() ) {
318 1
				$imgCaption = $ig->mParser->recursiveTagParse( $imgCaption );
319
			}
320
		}
321
		// Use image alt as helper for either text
322 1
		$imgAlt = $this->params['redirects'] === '' ? $imgCaption : $imgRedirect !== '' ? $imgRedirect : '';
323 1
		$ig->add( $imgTitle, $imgCaption, $imgAlt );
324 1
	}
325
326
	/**
327
	 * Returns the overlay setting
328
	 *
329
	 * @since 1.8
330
	 *
331
	 * @return string
332
	 */
333 1
	private function getImageOverlay() {
334 1
		if ( array_key_exists( 'overlay', $this->params ) && $this->params['overlay'] == true ) {
335
			SMWOutputs::requireResource( 'ext.srf.gallery.overlay' );
336
			return ' srf-overlay';
337
		} else {
338 1
			return '';
339
		}
340
	}
341
342
	/**
343
	 * Init carousel widget
344
	 *
345
	 * @since 1.8
346
	 *
347
	 * @return string
348
	 */
349
	private function getCarouselWidget() {
350
351
		// Set attributes for jcarousel
352
		$dataAttribs = [
353
			'wrap' => 'both', // Whether to wrap at the first/last item (or both) and jump back to the start/end.
354
			'vertical' => 'false', // Orientation: vertical = false means horizontal
355
			'rtl' => 'false', // Directionality: rtl = false means ltr
356
		];
357
358
		// Use the perrow parameter to determine the scroll sequence.
359
		if ( empty( $this->params['perrow'] ) ) {
360
			$dataAttribs['scroll'] = 1;  // default 1
361
		} else {
362
			$dataAttribs['scroll'] = $this->params['perrow'];
363
			$dataAttribs['visible'] = $this->params['perrow'];
364
		}
365
366
		$attribs = [
367
			'id' => uniqid(),
368
			'class' => 'jcarousel jcarousel-skin-smw' . $this->getImageOverlay(),
369
			'style' => 'display:none;',
370
		];
371
372
		foreach ( $dataAttribs as $name => $value ) {
373
			$attribs['data-' . $name] = $value;
374
		}
375
376
		SMWOutputs::requireResource( 'ext.srf.gallery.carousel' );
377
378
		return $attribs;
379
	}
380
381
	/**
382
	 * Init slideshow widget
383
	 *
384
	 * @since 1.8
385
	 *
386
	 * @return string
387
	 */
388
	private function getSlideshowWidget() {
389
390
		$attribs = [
391
			'id' => uniqid(),
392
			'class' => $this->getImageOverlay(),
393
			'style' => 'display:none;',
394
			'data-nav-control' => $this->params['navigation']
395
		];
396
397
		SMWOutputs::requireResource( 'ext.srf.gallery.slideshow' );
398
399
		return $attribs;
400
	}
401
402
	/**
403
	 * @see SMWResultPrinter::getParamDefinitions
404
	 *
405
	 * @since 1.8
406
	 *
407
	 * @param $definitions array of IParamDefinition
408
	 *
409
	 * @return array of IParamDefinition|array
410
	 */
411 1
	public function getParamDefinitions( array $definitions ) {
412 1
		$params = parent::getParamDefinitions( $definitions );
413
414 1
		$params['class'] = [
415
			'type' => 'string',
416
			'message' => 'srf-paramdesc-class',
417
			'default' => ''
418
		];
419
420 1
		$params['widget'] = [
421
			'type' => 'string',
422
			'default' => '',
423
			'message' => 'srf-paramdesc-widget',
424
			'values' => [ 'carousel', 'slideshow', '' ]
425
		];
426
427 1
		$params['navigation'] = [
428
			'type' => 'string',
429
			'default' => 'nav',
430
			'message' => 'srf-paramdesc-navigation',
431
			'values' => [ 'nav', 'pager', 'auto' ]
432
		];
433
434 1
		$params['overlay'] = [
435
			'type' => 'boolean',
436
			'default' => false,
437
			'message' => 'srf-paramdesc-overlay'
438
		];
439
440 1
		$params['perrow'] = [
441
			'type' => 'integer',
442
			'default' => '',
443
			'message' => 'srf_paramdesc_perrow'
444
		];
445
446 1
		$params['widths'] = [
447
			'type' => 'integer',
448
			'default' => '',
449
			'message' => 'srf_paramdesc_widths'
450
		];
451
452 1
		$params['heights'] = [
453
			'type' => 'integer',
454
			'default' => '',
455
			'message' => 'srf_paramdesc_heights'
456
		];
457
458 1
		$params['autocaptions'] = [
459
			'type' => 'boolean',
460
			'default' => true,
461
			'message' => 'srf_paramdesc_autocaptions'
462
		];
463
464 1
		$params['fileextensions'] = [
465
			'type' => 'boolean',
466
			'default' => false,
467
			'message' => 'srf_paramdesc_fileextensions'
468
		];
469
470 1
		$params['captionproperty'] = [
471
			'type' => 'string',
472
			'default' => '',
473
			'message' => 'srf_paramdesc_captionproperty'
474
		];
475
476 1
		$params['imageproperty'] = [
477
			'type' => 'string',
478
			'default' => '',
479
			'message' => 'srf_paramdesc_imageproperty'
480
		];
481
482 1
		$params['redirects'] = [
483
			'type' => 'string',
484
			'default' => '',
485
			'message' => 'srf-paramdesc-redirects'
486
		];
487
488 1
		return $params;
489
	}
490
491 1
	private function isSpecialPage() {
0 ignored issues
show
isSpecialPage uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
492 1
		$title = $GLOBALS['wgTitle'];
493 1
		return $title instanceof Title && $title->isSpecialPage();
494
	}
495
496 1
	private function getFileNsTextForPageLanguage() {
497 1
		$title = $GLOBALS['wgTitle'];
498 1
		return $title instanceof Title ? $title->getPageLanguage()->getNsText( NS_FILE ) : null;
499
	}
500
501
}
502