Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 182
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
InfoPage
0.00% covered (danger)
0.00%
0 / 182
0.00% covered (danger)
0.00%
0 / 9
992
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
20
 makeLogo
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
42
 listOtherProjects
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
6
 listMultilingualProjects
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 showWelcome
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 StandardInfoPage
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 showMissingWiki
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
6
 showIncubatingWiki
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
72
 showExistingWiki
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace MediaWiki\Extension\WikimediaIncubator;
4
5use Language;
6use MediaWiki\Html\Html;
7use MediaWiki\Languages\LanguageNameUtils;
8use MediaWiki\Linker\Linker;
9use MediaWiki\MediaWikiServices;
10use MediaWiki\SpecialPage\SpecialPage;
11use MediaWiki\Title\Title;
12use MediaWiki\User\UserIdentity;
13use RequestContext;
14
15/**
16 * Implements the "info page" (Wx/xx pages)
17 *
18 * 'missing' showMissingWiki()
19 *   A [Project] in this language does not yet exist.
20 * 'incubator' showIncubatingWiki()
21 *    'open': This is a new Incubator wiki that is not yet verified by the language committee.
22 *    'eligible': This Incubator wiki has been marked as eligible by the language committee.
23 *    'imported': This Incubator wiki has been imported from xyz.wikiproject.org after that wiki
24 *       was closed.
25 *    'approved': This Incubator wiki has been approved by the language committee and will soon
26 *       be created.
27 * 'existing' showExistingWiki()
28 *    'created': This project has been approved by the language committee and is now available at
29 *       xyz.wikiproject.org.
30 *    'beforeincubator': This project was created before Wikimedia Incubator started and is
31 *       available at xyz.wikiproject.org.
32 *
33 * @file
34 * @ingroup Extensions
35 * @author Robin Pepermans (SPQRobin)
36 */
37
38class InfoPage {
39
40    /** @var Title */
41    private $mTitle;
42
43    /** @var string */
44    private $mPrefix;
45
46    /** @var string */
47    private $mLangCode;
48
49    /** @var string */
50    private $mProjectCode;
51
52    /** @var string */
53    private $mProjectName;
54
55    /** @var string */
56    private $mPortal;
57
58    /** @var bool */
59    private $mIsSister;
60
61    /** @var string */
62    public $mSubStatus;
63
64    /** @var string[] */
65    private $mThisLangData;
66
67    /** @var string */
68    private $mLangName;
69
70    /** @var string */
71    public $mFormatTitle;
72
73    /** @var string[] */
74    public $mOptions = [];
75
76    /** @var UserIdentity */
77    private $user;
78
79    /** @var Language */
80    private $userLang;
81
82    /**
83     * @param Title $title
84     * @param array $prefixdata
85     * @param UserIdentity $user
86     */
87    public function __construct( $title, $prefixdata, UserIdentity $user ) {
88        global $wmincProjects;
89        $this->mTitle = $title;
90        $this->mPrefix = $prefixdata['prefix'];
91        $this->mLangCode = $prefixdata['lang'];
92        $this->mProjectCode = $prefixdata['project'];
93        $this->mProjectName = $wmincProjects[$this->mProjectCode]['name'] ?? '';
94        $this->mPortal = WikimediaIncubator::getSubdomain( $user, 'www', $this->mProjectCode );
95        $this->mIsSister = $wmincProjects[$this->mProjectCode]['sister'];
96        $this->mSubStatus = '';
97        $this->mThisLangData = [ 'type' => 'valid' ]; # For later code check feature
98        $this->userLang = RequestContext::getMain()->getLanguage();
99        $languageNameUtils = MediaWikiServices::getInstance()->getLanguageNameUtils();
100        $name = $languageNameUtils->getLanguageName(
101            $this->mLangCode,
102            $this->userLang->getCode(),
103            LanguageNameUtils::ALL
104        );
105        $this->mLangName = $name ?:
106            $languageNameUtils->getLanguageName( $this->mLangCode, 'en', LanguageNameUtils::ALL );
107        $titleParam = $this->mLangName ?:
108            wfMessage( 'quotation-marks', $this->mLangCode )->text(); # Name, else code
109        # Give grep a chance to find the usages:
110        # wminc-infopage-title-p, wminc-infopage-title-b, wminc-infopage-title-t,
111        # wminc-infopage-title-q, wminc-infopage-title-n, wminc-infopage-title-s,
112        # wminc-infopage-title-v, wminc-infopage-title-y
113        $this->mFormatTitle = wfMessage( 'wminc-infopage-title-' . $this->mProjectCode,
114            $titleParam )->text();
115        if ( !$this->mLangName ) {
116            # Unknown language, add short note to title
117            $this->mFormatTitle .= ' ' . wfMessage( 'wminc-unknownlang', $this->mLangCode )->text();
118        }
119        $this->user = $user;
120    }
121
122    /**
123     * Small convenience function to display a (clickable) logo
124     * @param string $project Project code
125     * @param bool $clickable
126     * @param array $params
127     * @param string|null $url
128     * @param string|null $lang
129     * @param bool $mul
130     * @return string
131     */
132    public function makeLogo( $project, $clickable = true, $params = [],
133        $url = null, $lang = null, $mul = false
134    ) {
135        $lang = $lang ?: $this->mLangCode;
136        if ( !$mul ) { // for non-multilingual wikis
137            $getDbStatus = WikimediaIncubator::getDBState(
138                [ 'error' => null, 'lang' => $lang, 'project' => $project ]
139            );
140            $lang = $getDbStatus == 'missing' ? 'en' : $lang;
141            $params['title'] = WikimediaIncubator::getProject(
142                $this->user,
143                $project,
144                true,
145                true
146            );
147        }
148
149        $params['src'] = WikimediaIncubator::getConf(
150            $this->user,
151            'wmgSiteLogoIcon',
152            $lang,
153            $project
154        );
155        $params['alt'] = "$project ($lang)";
156        $img = Html::element( 'img', $params );
157        if ( $clickable ) {
158            if ( $url === null ) {
159                $url = WikimediaIncubator::getSubdomain( $this->user, 'www', $project );
160            }
161            return Html::rawElement( 'a', [ 'href' => $url ], $img );
162        }
163        return $img;
164    }
165
166    /**
167     * @return string list of clickable logos of other projects
168     *                     (Wikipedia, Wiktionary, ...)
169     */
170    public function listOtherProjects() {
171        global $wmincProjects;
172        $otherProjects = $wmincProjects;
173        '@phan-var array $otherProjects';
174        unset( $otherProjects[$this->mProjectCode] );
175        $listOtherProjects = [];
176        foreach ( $otherProjects as $code => $metadata ) {
177            $listOtherProjects[$code] = '<li>' . $this->makeLogo(
178                $code,
179                true,
180                [ 'width' => 75 ],
181                WikimediaIncubator::getSubdomain( $this->user, $this->mLangCode, $code )
182            ) . '</li>';
183        }
184        return '<ul class="wminc-infopage-otherprojects">' .
185            implode( '', $listOtherProjects ) . '</ul>';
186    }
187
188    /**
189     * @return string list of clickable logos of multilingual projects
190     *                     (Meta, Commons, ...)
191     */
192    public function listMultilingualProjects() {
193        global $wmincMultilingualProjects, $wmincProjects;
194        if ( !is_array( $wmincMultilingualProjects ) ) {
195            return '';
196        }
197        $list = [];
198        foreach ( $wmincMultilingualProjects as $key => $name ) {
199            # multilingual projects are listed under wikipedia
200            $fakeProject = key( $wmincProjects );
201            $url = WikimediaIncubator::getSubdomain( $this->user, $key, $fakeProject );
202            $list[$url] = '<li>' . $this->makeLogo( $fakeProject, true,
203                [ 'width' => 75 ], $url, $key, true ) . '</li>';
204        }
205        return '<ul class="wminc-infopage-multilingualprojects">' .
206            implode( '', $list ) . '</ul>';
207    }
208
209    /**
210     * @return string "Welcome to Incubator" message
211     */
212    public function showWelcome() {
213        return Html::rawElement( 'div', [ 'class' => 'wminc-infopage-welcome' ],
214            wfMessage( 'wminc-infopage-welcome' )->parseAsBlock() );
215    }
216
217    /**
218     * @param string $beforetitle
219     * @param string $aftertitle
220     * @param string $content
221     * @return string the core HTML for the info page
222     */
223    public function StandardInfoPage( $beforetitle, $aftertitle, $content ) {
224        return Html::rawElement( 'div', [ 'class' => 'wminc-infopage plainlinks',
225            'lang' => $this->userLang->getCode(), 'dir' => $this->userLang->getDir() ],
226            $beforetitle .
227            Html::rawElement( 'div', [ 'class' => 'wminc-infopage-logo' ],
228                $this->makeLogo( $this->mProjectCode )
229            ) .
230            Html::rawElement( 'div', [ 'class' => 'wminc-infopage-title' ],
231                htmlspecialchars( $this->mFormatTitle ) . $aftertitle ) .
232            $content );
233    }
234
235    /**
236     * @return string
237     */
238    public function showMissingWiki() {
239        global $wgRequest;
240        $link = SpecialPage::getTitleFor( 'IncubatorFirstSteps' );
241        $query = [ 'testwiki' => $this->mPrefix,
242            'uselang' => $wgRequest->getVal( 'uselang' ) ];
243        $steps = $link->getFullUrl( $query );
244
245        $content = Html::rawElement( 'div',
246            [ 'class' => 'wminc-infopage-status' ],
247            wfMessage( 'wminc-infopage-missingwiki-text',
248            $this->mProjectName, $this->mLangName )->parseAsBlock()
249        ) .
250        Html::rawElement( 'ul', [ 'class' => 'wminc-infopage-options' ],
251            Html::rawElement( 'li', [],
252                wfMessage( $this->mIsSister
253                    ? 'wminc-infopage-option-startsister' : 'wminc-infopage-option-startwiki',
254                    $this->mProjectName, $this->mPortal, $steps )->parse() ) .
255            Html::rawElement( 'li', [],
256                wfMessage( 'wminc-infopage-option-languages-existing',
257                    $this->mProjectName )->parse() ) .
258            Html::rawElement( 'li', [],
259                wfMessage( 'wminc-infopage-option-sisterprojects-existing' )->parse() .
260                $this->listOtherProjects() ) .
261            Html::rawElement( 'li', [],
262                wfMessage( 'wminc-infopage-option-multilingual' )->parse() .
263                $this->listMultilingualProjects() )
264        );
265        return $this->StandardInfoPage( $this->showWelcome(), '', $content );
266    }
267
268    /**
269     * @return string
270     */
271    public function showIncubatingWiki() {
272        $substatus = $this->mSubStatus;
273        if ( $substatus == 'imported' && $this->mIsSister ) {
274            $substatus = 'closedsister';
275        }
276        $portalLink = Linker::makeExternalLink( $this->mPortal, $this->mProjectName );
277        $mainpage = isset( $this->mOptions['mainpage'] ) ?
278            Title::newFromText( $this->mPrefix . '/' . $this->mOptions['mainpage'] ) :
279            WikimediaIncubator::getMainPage( $this->mLangCode, $this->mPrefix );
280        if ( $this->mThisLangData['type'] != 'invalid' ) {
281            $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
282            $gotoLink = $linkRenderer->makeLink(
283                $mainpage,
284                wfMessage( 'wminc-infopage-enter' )->text() );
285            $gotoMainPage = Html::rawElement( 'span',
286                [ 'class' => 'wminc-infopage-entertest' ],
287                $this->userLang->getArrow() . ' ' . ( $this->mIsSister ? $portalLink : $gotoLink ) );
288        } else {
289            $gotoMainPage = '';
290        }
291        $subdomain = WikimediaIncubator::getSubdomain(
292            $this->user,
293            $this->mLangCode,
294            $this->mProjectCode
295        );
296        $subdomainLink = WikimediaIncubator::makeExternalLinkText( $subdomain, true );
297        # Give grep a chance to find the usages:
298        # wminc-infopage-status-open, wminc-infopage-status-imported,
299        # wminc-infopage-status-closedsister, wminc-infopage-status-approved,
300        # wminc-infopage-status-created, wminc-infopage-status-beforeincubator
301        $content = Html::rawElement( 'div', [ 'class' => 'wminc-infopage-status' ],
302            wfMessage( 'wminc-infopage-status-' . $substatus )
303                ->rawParams( $subdomainLink, $portalLink )->parseAsBlock()
304        );
305        if ( $this->mSubStatus != 'approved' && $this->mThisLangData['type'] != 'invalid' ) {
306            $content .= Html::element( 'div',
307                [ 'class' => 'wminc-infopage-contribute' ],
308                wfMessage( 'wminc-infopage-contribute' )->plain() );
309        }
310        $content .= Html::rawElement( 'div', [ 'class' => 'wminc-infopage-links' ],
311            # custom links and other stuff
312            wfMessage( 'wminc-infopage-links',
313                $this->mSubStatus, $this->mPrefix,
314                $this->mProjectCode, $this->mProjectName,
315                $this->mLangCode, $this->mLangName
316            )->inContentLanguage()->parse()
317        );
318        $content .= Html::rawElement( 'ul', [ 'class' => 'wminc-infopage-options' ],
319            Html::rawElement( 'li', [], wfMessage( 'wminc-infopage-option-sisterprojects-other' )
320                ->parseAsBlock() . $this->listOtherProjects() ) );
321        return $this->StandardInfoPage( '', $gotoMainPage, $content );
322    }
323
324    /**
325     * @return string
326     */
327    public function showExistingWiki() {
328        $subdomain = WikimediaIncubator::getSubdomain(
329            $this->user,
330            $this->mLangCode,
331            $this->mProjectCode
332        );
333        $subdomainLink = WikimediaIncubator::makeExternalLinkText( $subdomain, true );
334        if ( $this->mThisLangData['type'] != 'invalid' ) {
335            $gotoSubdomain = Html::rawElement( 'span',
336                [ 'class' => 'wminc-infopage-entertest' ],
337                $this->userLang->getArrow() . ' ' . $subdomainLink );
338        } else {
339            $gotoSubdomain = '';
340        }
341        # Give grep a chance to find the usages:
342        # wminc-infopage-status-open, wminc-infopage-status-imported,
343        # wminc-infopage-status-closedsister, wminc-infopage-status-approved,
344        # wminc-infopage-status-created, wminc-infopage-status-beforeincubator
345        $msgname = 'wminc-infopage-status-' . $this->mSubStatus;
346        if ( $this->mSubStatus === 'beforeincubator'
347            && $this->mIsSister
348        ) {
349            $msgname = 'wminc-infopage-status-beforeincubator-sister';
350        }
351        $content = Html::rawElement( 'div',
352            [ 'class' => 'wminc-infopage-status' ],
353            wfMessage( $msgname )->rawParams( $subdomainLink )->parseAsBlock()
354        ) . Html::rawElement( 'ul', [ 'class' => 'wminc-infopage-options' ],
355            Html::rawElement( 'li', [],
356                wfMessage( 'wminc-infopage-option-sisterprojects-other' )->parseAsBlock() .
357                $this->listOtherProjects() ) .
358            Html::rawElement( 'li', [],
359                wfMessage( 'wminc-infopage-option-multilingual' )->parseAsBlock() .
360                $this->listMultilingualProjects() )
361        );
362        return $this->StandardInfoPage( $this->showWelcome(), $gotoSubdomain, $content );
363    }
364}