Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 91
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 * @license GPL-2.0-or-later
6 * @file
7 */
8
9namespace MediaWiki\Api;
10
11use MediaWiki\ChangeTags\ChangeTags;
12use MediaWiki\ChangeTags\ChangeTagsStore;
13use Wikimedia\ParamValidator\ParamValidator;
14use Wikimedia\ParamValidator\TypeDef\IntegerDef;
15
16/**
17 * Query module to enumerate change tags.
18 *
19 * @ingroup API
20 */
21class ApiQueryTags extends ApiQueryBase {
22
23    private ChangeTagsStore $changeTagsStore;
24
25    public function __construct( ApiQuery $query, string $moduleName, ChangeTagsStore $changeTagsStore ) {
26        parent::__construct( $query, $moduleName, 'tg' );
27        $this->changeTagsStore = $changeTagsStore;
28    }
29
30    public function execute() {
31        $params = $this->extractRequestParams();
32
33        $prop = array_fill_keys( $params['prop'], true );
34
35        $fld_displayname = isset( $prop['displayname'] );
36        $fld_description = isset( $prop['description'] );
37        $fld_hitcount = isset( $prop['hitcount'] );
38        $fld_defined = isset( $prop['defined'] );
39        $fld_source = isset( $prop['source'] );
40        $fld_active = isset( $prop['active'] );
41
42        $limit = $params['limit'];
43        $result = $this->getResult();
44
45        $softwareDefinedTags = array_fill_keys( $this->changeTagsStore->listSoftwareDefinedTags(), 0 );
46        $explicitlyDefinedTags = array_fill_keys( $this->changeTagsStore->listExplicitlyDefinedTags(), 0 );
47        $softwareActivatedTags = array_fill_keys( $this->changeTagsStore->listSoftwareActivatedTags(), 0 );
48
49        $tagHitcounts = array_merge(
50            $softwareDefinedTags,
51            $explicitlyDefinedTags,
52            $this->changeTagsStore->tagUsageStatistics()
53        );
54        $tags = array_keys( $tagHitcounts );
55
56        # Fetch defined tags that aren't past the continuation
57        if ( $params['continue'] !== null ) {
58            $cont = $params['continue'];
59            $tags = array_filter( $tags, static function ( $v ) use ( $cont ) {
60                return $v >= $cont;
61            } );
62        }
63
64        # Now make sure the array is sorted for proper continuation
65        sort( $tags );
66
67        $count = 0;
68        foreach ( $tags as $tagName ) {
69            if ( ++$count > $limit ) {
70                $this->setContinueEnumParameter( 'continue', $tagName );
71                break;
72            }
73
74            $tag = [];
75            $tag['name'] = $tagName;
76
77            if ( $fld_displayname ) {
78                $tag['displayname'] = ChangeTags::tagDescription( $tagName, $this );
79            }
80
81            if ( $fld_description ) {
82                $msg = $this->msg( "tag-$tagName-description" );
83                $tag['description'] = $msg->exists() ? $msg->text() : '';
84            }
85
86            if ( $fld_hitcount ) {
87                $tag['hitcount'] = (int)$tagHitcounts[$tagName];
88            }
89
90            $isSoftware = isset( $softwareDefinedTags[$tagName] );
91            $isExplicit = isset( $explicitlyDefinedTags[$tagName] );
92
93            if ( $fld_defined ) {
94                $tag['defined'] = $isSoftware || $isExplicit;
95            }
96
97            if ( $fld_source ) {
98                $tag['source'] = [];
99                if ( $isSoftware ) {
100                    $tag['source'][] = 'software';
101                    // @TODO: remove backwards compatibility entry (T247552)
102                    $tag['source'][] = 'extension';
103                }
104                if ( $isExplicit ) {
105                    $tag['source'][] = 'manual';
106                }
107            }
108
109            if ( $fld_active ) {
110                $tag['active'] = $isExplicit || isset( $softwareActivatedTags[$tagName] );
111            }
112
113            $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $tag );
114            if ( !$fit ) {
115                $this->setContinueEnumParameter( 'continue', $tagName );
116                break;
117            }
118        }
119
120        $result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'tag' );
121    }
122
123    /** @inheritDoc */
124    public function getCacheMode( $params ) {
125        return 'public';
126    }
127
128    /** @inheritDoc */
129    public function getAllowedParams() {
130        return [
131            'continue' => [
132                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
133            ],
134            'limit' => [
135                ParamValidator::PARAM_DEFAULT => 10,
136                ParamValidator::PARAM_TYPE => 'limit',
137                IntegerDef::PARAM_MIN => 1,
138                IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
139                IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
140            ],
141            'prop' => [
142                ParamValidator::PARAM_DEFAULT => '',
143                ParamValidator::PARAM_TYPE => [
144                    'displayname',
145                    'description',
146                    'hitcount',
147                    'defined',
148                    'source',
149                    'active',
150                ],
151                ParamValidator::PARAM_ISMULTI => true,
152                ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
153            ]
154        ];
155    }
156
157    /** @inheritDoc */
158    protected function getExamplesMessages() {
159        return [
160            'action=query&list=tags&tgprop=displayname|description|hitcount|defined'
161                => 'apihelp-query+tags-example-simple',
162        ];
163    }
164
165    /** @inheritDoc */
166    public function getHelpUrls() {
167        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Tags';
168    }
169}
170
171/** @deprecated class alias since 1.43 */
172class_alias( ApiQueryTags::class, 'ApiQueryTags' );