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