Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 87
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
CargoSlideshowFormat
0.00% covered (danger)
0.00%
0 / 87
0.00% covered (danger)
0.00%
0 / 3
1122
0.00% covered (danger)
0.00%
0 / 1
 allowedParameters
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getFileTitles
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
210
 display
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 1
342
1<?php
2
3use MediaWiki\Html\Html;
4use MediaWiki\MediaWikiServices;
5use MediaWiki\Title\Title;
6
7/**
8 * @author Yaron Koren
9 * @ingroup Cargo
10 *
11 * Defines the 'slideshow' format, which displays a slideshow of images,
12 * using the Slick JS library.
13 */
14
15class CargoSlideshowFormat extends CargoDisplayFormat {
16
17    public static function allowedParameters() {
18        return [
19            'caption field' => [ 'type' => 'string' ],
20            'link field' => [ 'type' => 'string' ],
21            'slides per screen' => [ 'type' => 'int' ]
22        ];
23    }
24
25    protected function getFileTitles( $valuesTable, $fieldDescriptions, $captionField, $linkField ) {
26        $fileField = null;
27        foreach ( $fieldDescriptions as $field => $fieldDesc ) {
28            if ( $fieldDesc->mType == 'File' ) {
29                $fileField = $field;
30                break;
31            }
32        }
33
34        // If there's no 'File' field in the schema, just use the
35        // page name.
36        if ( $fileField == null ) {
37            $usingPageName = true;
38            $fileField = '_pageName';
39        } else {
40            $usingPageName = false;
41        }
42
43        $fileNames = [];
44        foreach ( $valuesTable as $row ) {
45            if ( array_key_exists( $fileField, $row ) ) {
46                $caption = ( $captionField == null ) ? null : $row[$captionField];
47                $link = ( $linkField == null ) ? null : Title::newFromText( $row[$linkField] );
48                $fileNames[] = [
49                    'title' => $row[$fileField],
50                    'caption' => $caption,
51                    'link' => $link
52                ];
53            }
54        }
55
56        $files = [];
57        foreach ( $fileNames as $f ) {
58            if ( $usingPageName ) {
59                $title = Title::newFromText( $f['title'] );
60                if ( $title == null || $title->getNamespace() != NS_FILE ) {
61                    continue;
62                }
63            } else {
64                $title = Title::makeTitleSafe( NS_FILE, $f['title'] );
65                if ( $title == null ) {
66                    continue;
67                }
68            }
69
70            $files[] = [
71                'title' => $title,
72                'caption' => CargoUtils::smartParse( $f['caption'], null ),
73                'link' => ( $f['link'] !== null ) ? $f['link']->getLinkURL() : null
74            ];
75
76        }
77
78        return $files;
79    }
80
81    /**
82     * @param array $valuesTable Unused
83     * @param array $formattedValuesTable
84     * @param array $fieldDescriptions
85     * @param array $displayParams Unused
86     * @return string HTML
87     */
88    public function display( $valuesTable, $formattedValuesTable, $fieldDescriptions, $displayParams ) {
89        $this->mOutput->addModules( [ 'ext.cargo.slick' ] );
90
91        if ( array_key_exists( 'caption field', $displayParams ) ) {
92            $captionField = str_replace( '_', ' ', $displayParams['caption field'] );
93            if ( $captionField[0] == ' ' ) {
94                $captionField[0] = '_';
95            }
96            if ( count( $valuesTable ) > 0 && !array_key_exists( $captionField, $valuesTable[0] ) ) {
97                throw new MWException( wfMessage( "cargo-query-specifiedfieldmissing", $captionField, "caption field" )->parse() );
98            }
99        } else {
100            $captionField = null;
101        }
102        if ( array_key_exists( 'link field', $displayParams ) ) {
103            $linkField = str_replace( '_', ' ', $displayParams['link field'] );
104            if ( $linkField[0] == ' ' ) {
105                $linkField[0] = '_';
106            }
107            if ( count( $valuesTable ) > 0 && !array_key_exists( $linkField, $valuesTable[0] ) ) {
108                throw new MWException( wfMessage( "cargo-query-specifiedfieldmissing", $linkField, "link field" )->parse() );
109            }
110        } else {
111            $linkField = null;
112        }
113
114        $localRepo = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo();
115        $bodyText = '';
116        $files = self::getFileTitles( $valuesTable, $fieldDescriptions, $captionField, $linkField );
117        foreach ( $files as $file ) {
118            $fileTitle = $file['title'];
119            $actualFile = $localRepo->newFile( $fileTitle->getText() );
120            $imageHTML = '<img src="' . $actualFile->getURL() . '" />';
121            if ( $file['link'] != '' ) {
122                $imageHTML = Html::rawElement( 'a', [ 'href' => $file['link'] ], $imageHTML );
123            }
124            $slideText = '<div class="image">' . $imageHTML .
125                "</div>\n";
126            if ( $file['caption'] != '' ) {
127                $slideText .= '<span class="cargoSliderCaption">' . $file['caption'] . '</span>';
128            }
129            $bodyText .= "<div>$slideText</div>\n";
130        }
131
132        $slickData = [];
133        if ( array_key_exists( 'slides per screen', $displayParams ) ) {
134            $slickData['slidesToShow'] = $displayParams['slides per screen'];
135            // @TODO - add this? Add a separate param for it?
136            // $slickData['slidesToScroll'] = $displayParams['slides per screen'];
137        }
138        if ( array_key_exists( 'autoplay speed', $displayParams ) && $displayParams['autoplay speed'] != '' ) {
139            $slickData['autoplay'] = 'true';
140            // Cargo's value is in seconds, not milliseconds.
141            $slickData['autoplaySpeed'] = 1000 * $displayParams['autoplay speed'];
142        }
143
144        $text = '<div class="cargoSlider"';
145        if ( count( $slickData ) > 0 ) {
146            // Slick requires the inline data to be encoded in a
147            // JSON-like way, but it's not quite JSON, and it has
148            // to be done in the exact right format, so we just
149            // create it manually.
150            $slickDataStr = '{';
151            $firstVal = true;
152            foreach ( $slickData as $key => $val ) {
153                if ( !$firstVal ) {
154                    $slickDataStr .= ', ';
155                } else {
156                    $firstVal = false;
157                }
158                $slickDataStr .= "\"$key\": $val";
159            }
160            $slickDataStr .= '}';
161            $text .= " data-slick='$slickDataStr'";
162        }
163        $text .= ">$bodyText</div>";
164
165        return $text;
166    }
167
168}