Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 90
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiQueryTags
0.00% covered (danger)
0.00%
0 / 90
0.00% covered (danger)
0.00%
0 / 6
462
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 1
272
 getCacheMode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 4
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/**
3 * Copyright © 2009
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 */
22
23use MediaWiki\ChangeTags\ChangeTagsStore;
24use Wikimedia\ParamValidator\ParamValidator;
25use Wikimedia\ParamValidator\TypeDef\IntegerDef;
26
27/**
28 * Query module to enumerate change tags.
29 *
30 * @ingroup API
31 */
32class ApiQueryTags extends ApiQueryBase {
33
34    private ChangeTagsStore $changeTagsStore;
35
36    public function __construct( ApiQuery $query, $moduleName, ChangeTagsStore $changeTagsStore ) {
37        parent::__construct( $query, $moduleName, 'tg' );
38        $this->changeTagsStore = $changeTagsStore;
39    }
40
41    public function execute() {
42        $params = $this->extractRequestParams();
43
44        $prop = array_fill_keys( $params['prop'], true );
45
46        $fld_displayname = isset( $prop['displayname'] );
47        $fld_description = isset( $prop['description'] );
48        $fld_hitcount = isset( $prop['hitcount'] );
49        $fld_defined = isset( $prop['defined'] );
50        $fld_source = isset( $prop['source'] );
51        $fld_active = isset( $prop['active'] );
52
53        $limit = $params['limit'];
54        $result = $this->getResult();
55
56        $softwareDefinedTags = array_fill_keys( $this->changeTagsStore->listSoftwareDefinedTags(), 0 );
57        $explicitlyDefinedTags = array_fill_keys( $this->changeTagsStore->listExplicitlyDefinedTags(), 0 );
58        $softwareActivatedTags = array_fill_keys( $this->changeTagsStore->listSoftwareActivatedTags(), 0 );
59
60        $tagHitcounts = array_merge(
61            $softwareDefinedTags,
62            $explicitlyDefinedTags,
63            $this->changeTagsStore->tagUsageStatistics()
64        );
65        $tags = array_keys( $tagHitcounts );
66
67        # Fetch defined tags that aren't past the continuation
68        if ( $params['continue'] !== null ) {
69            $cont = $params['continue'];
70            $tags = array_filter( $tags, static function ( $v ) use ( $cont ) {
71                return $v >= $cont;
72            } );
73        }
74
75        # Now make sure the array is sorted for proper continuation
76        sort( $tags );
77
78        $count = 0;
79        foreach ( $tags as $tagName ) {
80            if ( ++$count > $limit ) {
81                $this->setContinueEnumParameter( 'continue', $tagName );
82                break;
83            }
84
85            $tag = [];
86            $tag['name'] = $tagName;
87
88            if ( $fld_displayname ) {
89                $tag['displayname'] = ChangeTags::tagDescription( $tagName, $this );
90            }
91
92            if ( $fld_description ) {
93                $msg = $this->msg( "tag-$tagName-description" );
94                $tag['description'] = $msg->exists() ? $msg->text() : '';
95            }
96
97            if ( $fld_hitcount ) {
98                $tag['hitcount'] = (int)$tagHitcounts[$tagName];
99            }
100
101            $isSoftware = isset( $softwareDefinedTags[$tagName] );
102            $isExplicit = isset( $explicitlyDefinedTags[$tagName] );
103
104            if ( $fld_defined ) {
105                $tag['defined'] = $isSoftware || $isExplicit;
106            }
107
108            if ( $fld_source ) {
109                $tag['source'] = [];
110                if ( $isSoftware ) {
111                    $tag['source'][] = 'software';
112                    // @TODO: remove backwards compatibility entry (T247552)
113                    $tag['source'][] = 'extension';
114                }
115                if ( $isExplicit ) {
116                    $tag['source'][] = 'manual';
117                }
118            }
119
120            if ( $fld_active ) {
121                $tag['active'] = $isExplicit || isset( $softwareActivatedTags[$tagName] );
122            }
123
124            $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $tag );
125            if ( !$fit ) {
126                $this->setContinueEnumParameter( 'continue', $tagName );
127                break;
128            }
129        }
130
131        $result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'tag' );
132    }
133
134    public function getCacheMode( $params ) {
135        return 'public';
136    }
137
138    public function getAllowedParams() {
139        return [
140            'continue' => [
141                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
142            ],
143            'limit' => [
144                ParamValidator::PARAM_DEFAULT => 10,
145                ParamValidator::PARAM_TYPE => 'limit',
146                IntegerDef::PARAM_MIN => 1,
147                IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
148                IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
149            ],
150            'prop' => [
151                ParamValidator::PARAM_DEFAULT => '',
152                ParamValidator::PARAM_TYPE => [
153                    'displayname',
154                    'description',
155                    'hitcount',
156                    'defined',
157                    'source',
158                    'active',
159                ],
160                ParamValidator::PARAM_ISMULTI => true,
161                ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
162            ]
163        ];
164    }
165
166    protected function getExamplesMessages() {
167        return [
168            'action=query&list=tags&tgprop=displayname|description|hitcount|defined'
169                => 'apihelp-query+tags-example-simple',
170        ];
171    }
172
173    public function getHelpUrls() {
174        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Tags';
175    }
176}