Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 170
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiSiteMatrix
0.00% covered (danger)
0.00%
0 / 170
0.00% covered (danger)
0.00%
0 / 6
1406
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 107
0.00% covered (danger)
0.00%
0 / 1
1056
 setContinueEnumParameter
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHelpUrls
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\SiteMatrix;
4
5use ApiBase;
6use ApiMain;
7use ApiResult;
8use MediaWiki\Languages\LanguageFactory;
9use MediaWiki\Languages\LanguageNameUtils;
10use Wikimedia\ParamValidator\ParamValidator;
11use Wikimedia\ParamValidator\TypeDef\IntegerDef;
12
13/**
14 * Module to get site matrix
15 * @ingroup API
16 */
17class ApiSiteMatrix extends ApiBase {
18
19    /** @var LanguageNameUtils */
20    private $languageNameUtils;
21
22    /** @var LanguageFactory */
23    private $languageFactory;
24
25    /**
26     * @param ApiMain $main
27     * @param string $moduleName
28     * @param LanguageNameUtils $languageNameUtils
29     * @param LanguageFactory $languageFactory
30     */
31    public function __construct(
32        ApiMain $main,
33        $moduleName,
34        LanguageNameUtils $languageNameUtils,
35        LanguageFactory $languageFactory
36    ) {
37        parent::__construct( $main, $moduleName, 'sm' );
38        $this->languageNameUtils = $languageNameUtils;
39        $this->languageFactory = $languageFactory;
40    }
41
42    public function execute() {
43        $result = $this->getResult();
44        $matrix = new SiteMatrix();
45        $langNames = $this->languageNameUtils->getLanguageNames();
46
47        $matrix_out = [ 'count' => $matrix->getCount() ];
48
49        $localLanguageNames = $this->languageNameUtils->getLanguageNames( $this->getLanguage()->getCode() );
50
51        $params = $this->extractRequestParams();
52        $type = array_flip( $params['type'] );
53        $state = array_flip( $params['state'] );
54        $langProp = array_flip( $params['langprop'] );
55        $siteProp = array_flip( $params['siteprop'] );
56        $limit = $params['limit'];
57        $continue = isset( $params['continue'] )
58            ? explode( '|', $params['continue'] )
59            : [ 'language', '' ];
60        $this->dieContinueUsageIf( count( $continue ) != 2 );
61        '@phan-var array{string,string} $continue';
62
63        $all = isset( $state['all'] );
64        $closed = isset( $state['closed'] );
65        $private = isset( $state['private'] );
66        $fishbowl = isset( $state['fishbowl'] );
67        $nonglobal = isset( $state['nonglobal'] );
68
69        $count = 0;
70        if ( isset( $type['language'] ) && $continue[0] == 'language' ) {
71            foreach ( $matrix->getLangList() as $lang ) {
72                $langhost = str_replace( '_', '-', $lang );
73                if ( $langhost < $continue[1] ) {
74                    continue;
75                }
76                if ( $count >= $limit ) {
77                    $this->setContinueEnumParameter( 'continue', "language|$langhost" );
78                    break;
79                }
80                $language = [
81                    'code' => $langhost,
82                    'name' => $langNames[$lang] ?? null,
83                    'site' => [],
84                    'dir' => $this->languageFactory->getLanguage( $langhost )->getDir()
85                ];
86                if ( isset( $localLanguageNames[$lang] ) ) {
87                    $language['localname'] = $localLanguageNames[$lang];
88                }
89                $language = array_intersect_key( $language, $langProp );
90
91                if ( isset( $language['site'] ) ) {
92                    foreach ( $matrix->getSites() as $site ) {
93                        if ( $matrix->exist( $lang, $site ) ) {
94                            $skip = true;
95
96                            if ( $all ) {
97                                $skip = false;
98                            }
99
100                            $url = $matrix->getCanonicalUrl( $lang, $site );
101                            $site_out = [
102                                'url' => $url,
103                                'dbname' => $matrix->getDBName( $lang, $site ),
104                                'code' => $site,
105                                'lang' => $matrix->getLanguageCode( $lang, $site ),
106                                'sitename' => $matrix->getSitename( $lang, $site ),
107                            ];
108                            $site_out = array_intersect_key( $site_out, $siteProp );
109                            if ( $matrix->isClosed( $lang, $site ) ) {
110                                $site_out['closed'] = true;
111                                if ( $closed ) {
112                                    $skip = false;
113                                }
114                            }
115
116                            if ( $skip ) {
117                                continue;
118                            }
119                            $language['site'][] = $site_out;
120                        }
121                    }
122                    $result->setIndexedTagName( $language['site'], 'site' );
123                }
124
125                $count++;
126                $matrix_out[] = $language;
127            }
128        }
129
130        $result->setIndexedTagName( $matrix_out, 'language' );
131        $result->addValue( null, "sitematrix", $matrix_out );
132
133        if ( isset( $type['special'] ) && $count < $limit ) {
134            $specials = [];
135            foreach ( $matrix->getSpecials() as $special ) {
136                [ $lang, $site ] = $special;
137                $dbName = $matrix->getDBName( $lang, $site );
138                if ( $continue[0] == 'special' && $dbName < $continue[1] ) {
139                    continue;
140                }
141                if ( $count >= $limit ) {
142                    $this->setContinueEnumParameter( 'continue', "special|$dbName" );
143                    break;
144                }
145                $url = $matrix->getCanonicalUrl( $lang, $site );
146
147                $wiki = [];
148                $wiki['url'] = $url;
149                $wiki['dbname'] = $dbName;
150                $wiki['code'] = str_replace( '_', '-', $lang ) . ( $site != 'wiki' ? $site : '' );
151                $wiki['lang'] = $matrix->getLanguageCode( $lang, $site );
152                $wiki['sitename'] = $matrix->getSitename( $lang, $site );
153
154                $skip = true;
155
156                if ( $all ) {
157                    $skip = false;
158                }
159                if ( $matrix->isPrivate( $lang . $site ) ) {
160                    $wiki['private'] = true;
161
162                    if ( $private ) {
163                        $skip = false;
164                    }
165                }
166                if ( $matrix->isFishbowl( $lang . $site ) ) {
167                    $wiki['fishbowl'] = true;
168
169                    if ( $fishbowl ) {
170                        $skip = false;
171                    }
172                }
173                if ( $matrix->isNonGlobal( $lang . $site ) ) {
174                    $wiki['nonglobal'] = true;
175
176                    if ( $nonglobal ) {
177                        $skip = false;
178                    }
179                }
180                if ( $matrix->isClosed( $lang, $site ) ) {
181                    $wiki['closed'] = true;
182
183                    if ( $closed ) {
184                        $skip = false;
185                    }
186                }
187
188                if ( $skip ) {
189                    continue;
190                }
191
192                $specials[] = $wiki;
193            }
194
195            $result->setIndexedTagName( $specials, 'special' );
196            $result->addValue( "sitematrix", "specials", $specials );
197        }
198    }
199
200    /**
201     * @param string $paramName
202     * @param string $paramValue
203     */
204    protected function setContinueEnumParameter( $paramName, $paramValue ) {
205        $paramName = $this->encodeParamName( $paramName );
206        $msg = [ $paramName => $paramValue ];
207        $result = $this->getResult();
208        $result->addValue( 'query-continue', $this->getModuleName(), $msg, ApiResult::NO_SIZE_CHECK );
209    }
210
211    /** @inheritDoc */
212    public function getAllowedParams() {
213        return [
214            'type' => [
215                ParamValidator::PARAM_ISMULTI => true,
216                ParamValidator::PARAM_TYPE => [
217                    'special',
218                    'language'
219                ],
220                ParamValidator::PARAM_DEFAULT => 'special|language',
221                ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
222            ],
223            'state' => [
224                ParamValidator::PARAM_ISMULTI => true,
225                ParamValidator::PARAM_TYPE => [
226                    'all',
227                    'closed',
228                    'private',
229                    'fishbowl',
230                    'nonglobal',
231                ],
232                ParamValidator::PARAM_DEFAULT => 'all',
233            ],
234            'langprop' => [
235                ParamValidator::PARAM_ISMULTI => true,
236                ParamValidator::PARAM_TYPE => [
237                    'code',
238                    'name',
239                    'site',
240                    'dir',
241                    'localname',
242                ],
243                ParamValidator::PARAM_DEFAULT => 'code|name|site|dir|localname',
244            ],
245            'siteprop' => [
246                ParamValidator::PARAM_ISMULTI => true,
247                ParamValidator::PARAM_TYPE => [
248                    'url',
249                    'dbname',
250                    'code',
251                    'lang',
252                    'sitename',
253                ],
254                ParamValidator::PARAM_DEFAULT => 'url|dbname|code|sitename',
255            ],
256            'limit' => [
257                ParamValidator::PARAM_DEFAULT => 5000,
258                ParamValidator::PARAM_TYPE => 'limit',
259                IntegerDef::PARAM_MIN => 1,
260                IntegerDef::PARAM_MAX => 5000,
261                IntegerDef::PARAM_MAX2 => 5000,
262            ],
263            'continue' => [
264                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
265            ],
266        ];
267    }
268
269    /** @inheritDoc */
270    protected function getExamplesMessages() {
271        return [ 'action=sitematrix' => 'apihelp-sitematrix-example-1', ];
272    }
273
274    /** @inheritDoc */
275    public function getHelpUrls() {
276        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Sitematrix';
277    }
278}