Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
Tutorial
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 3
306
0.00% covered (danger)
0.00%
0 / 1
 getHtml
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
72
 getFile
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getImageHtml
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3namespace MediaWiki\Extension\UploadWizard;
4
5use File;
6use MediaTransformOutput;
7use MediaWiki\Html\Html;
8use MediaWiki\MediaWikiServices;
9use MediaWiki\Title\Title;
10
11/**
12 * Class to encapsulate all the html generation associated with the UploadWizard tutorial.
13 * Might be a start for a subclass of UploadWizard, if we ever free it of its WMF-oriented features
14 * So that non-WMF'ers can use it
15 */
16class Tutorial {
17
18    // Id of imagemap used in tutorial.
19    private const IMAGEMAP_ID = 'tutorialMap';
20
21    /**
22     * Fetches appropriate HTML for the tutorial portion of the wizard.
23     * Looks up an image on the current wiki. This will work as is on Commons, and will also work
24     * on test wikis that enable instantCommons.
25     * @param string|null $campaign Upload Wizard campaign for which the tutorial should be displayed.
26     * @return string html that will display the tutorial.
27     */
28    public static function getHtml( $campaign = null ) {
29        global $wgLang;
30
31        $error = null;
32        $errorHtml = '';
33        $tutorialHtml = '';
34
35        $langCode = $wgLang->getCode();
36
37        $tutorial = Config::getSetting( 'tutorial', $campaign );
38        // getFile returns false if it can't find the right file
39        $tutorialFile = self::getFile( $langCode, $tutorial );
40        if ( $tutorialFile === false ) {
41            $error = 'localized-file-missing';
42            foreach ( $wgLang->getFallbackLanguages() as $langCode ) {
43                $tutorialFile = self::getFile( $langCode, $tutorial );
44                if ( $tutorialFile !== false ) {
45                    // $langCode remains as the code where a file is found.
46                    break;
47                }
48            }
49        }
50
51        // at this point, we have one of the following situations:
52        // $error is null, and tutorialFile is the right one for this language
53        // $error notes we couldn't find the tutorialFile for your language,
54        // and $tutorialFile is the english one
55        // $error notes we couldn't find the tutorialFile for your language,
56        // and $tutorialFile is still false (major file failure)
57
58        if ( $tutorialFile ) {
59            // XXX TODO if the client can handle SVG, we could also just send it the unscaled thumb,
60            // client-scaled into a DIV or something.
61            // if ( client can handle SVG ) {
62            // $tutorialThumbnailImage->getUnscaledThumb();
63            // }
64            // put it into a div of appropriate dimensions.
65
66            // n.b. File::transform() returns false if failed, MediaTransformOutput otherwise
67            $thumbnailImage = $tutorialFile->transform( [ 'width' => $tutorial['width'] ] );
68
69            if ( $thumbnailImage ) {
70                $tutorialHtml = self::getImageHtml( $thumbnailImage, $tutorial );
71            } else {
72                $error = 'cannot-transform';
73            }
74        } else {
75            $error = 'file-missing';
76        }
77
78        if ( $error !== null ) {
79            // Messages:
80            // mwe-upwiz-tutorial-error-localized-file-missing, mwe-upwiz-tutorial-error-file-missing,
81            // mwe-upwiz-tutorial-error-cannot-transform
82            $errorMsg = wfMessage( 'mwe-upwiz-tutorial-error-' . $error );
83            if ( $error === 'localized-file-missing' ) {
84                $errorMsg->params( MediaWikiServices::getInstance()->getLanguageNameUtils()
85                    ->getLanguageName( $langCode, $wgLang->getCode() ) );
86            }
87            $errorHtml = Html::errorBox(
88                $errorMsg->text()
89            );
90        }
91
92        return $errorHtml . $tutorialHtml;
93    }
94
95    /**
96     * Get tutorial file for a particular language, or false if not available.
97     *
98     * @param string $langCode language Code
99     * @param string[] $tutorial Upload Wizard campaign for which the tutorial should be displayed.
100     *
101     * @return File|false
102     */
103    public static function getFile( $langCode, $tutorial ) {
104        $tutorialName = str_replace( '$1', $langCode, $tutorial['template'] );
105        return MediaWikiServices::getInstance()->getRepoGroup()
106            ->findFile( Title::newFromText( $tutorialName, NS_FILE ) );
107    }
108
109    /**
110     * Constructs HTML for the tutorial (laboriously),
111     * including an imagemap for the clickable "Help desk" button.
112     *
113     * @param MediaTransformOutput $thumb
114     * @param string[] $tutorial Upload Wizard campaign for which the tutorial should be displayed.
115     *
116     * @return string HTML representing the image, with clickable helpdesk button
117     */
118    public static function getImageHtml( MediaTransformOutput $thumb, $tutorial ) {
119        $helpDeskUrl = wfMessage( 'mwe-upwiz-help-desk-url' )->text();
120
121        // Per convention, we may be either using an absolute URL or a wiki page title in this UI message
122        if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $helpDeskUrl ) ) {
123            $helpDeskHref = $helpDeskUrl;
124        } else {
125            $helpDeskTitle = Title::newFromText( $helpDeskUrl );
126            if ( !$helpDeskTitle || !$helpDeskTitle->exists() ) {
127                // Fall back to the wiki's content language...if that page
128                // doesn't exist, we can't help.
129                $helpDeskUrl = wfMessage( 'mwe-upwiz-help-desk-url' )->inContentLanguage()->text();
130                $helpDeskTitle = Title::newFromText( $helpDeskUrl );
131            }
132
133            $helpDeskHref = $helpDeskTitle ? $helpDeskTitle->getLocalURL() : '#';
134        }
135
136        $buttonCoords = $tutorial['helpdeskCoords'];
137        $useMap = $buttonCoords !== false && trim( $buttonCoords ) != '';
138
139        $imgAttributes = [
140            'src' => $thumb->getUrl(),
141            'width' => $thumb->getWidth(),
142            'height' => $thumb->getHeight(),
143        ];
144
145        if ( $useMap ) {
146            $imgAttributes['usemap'] = '#' . self::IMAGEMAP_ID;
147        }
148
149        // here we use the not-yet-forgotten HTML imagemap to add a clickable area to the tutorial image.
150        // we could do more special effects with hovers and images and such, not to mention SVG scripting,
151        // but we aren't sure what we want yet...
152        $imgHtml = Html::element( 'img', $imgAttributes );
153
154        if ( $useMap ) {
155            $areaAltText = wfMessage( 'mwe-upwiz-help-desk' )->text();
156
157            $area = Html::element( 'area', [
158                'shape' => 'rect',
159                'coords' => $buttonCoords,
160                'href' => $helpDeskHref,
161                'alt' => $areaAltText,
162                'title' => $areaAltText,
163                'id' => 'mwe-upwiz-tutorial-helpdesk',
164            ] );
165
166            $imgHtml = Html::rawElement(
167                'map',
168                [ 'id' => self::IMAGEMAP_ID, 'name' => self::IMAGEMAP_ID ],
169                $area
170            ) . $imgHtml;
171        }
172
173        return $imgHtml;
174    }
175
176}