Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.12% covered (success)
94.12%
16 / 17
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ArticleTopicFiltersRegistry
94.12% covered (success)
94.12%
16 / 17
66.67% covered (warning)
66.67%
2 / 3
8.01
0.00% covered (danger)
0.00%
0 / 1
 getTopicList
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getGroupedTopics
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTopicMessages
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3declare( strict_types = 1 );
4
5namespace MediaWiki\Extension\WikimediaMessages;
6
7use InvalidArgumentException;
8
9/**
10 * This class provides a list of topic filters for articles that can be presented directly to users. Each filter defined
11 * here is mapped to one or more topics in the Articletopic taxonomy (https://www.mediawiki.org/wiki/ORES/Articletopic)
12 * used by the Lift Wing API (https://wikitech.wikimedia.org/wiki/Machine_Learning/LiftWing/API)
13 * via the predict-topics endpoint (https://www.mediawiki.org/w/index.php?api=lift-wing&title=Special%3ARestSandbox#/Topics%20and%20descriptions/outlinkTopicModelPredict).
14 * Topic filters are grouped by category, and both the topics and the categories are localisable.
15 * Originally written for the ContentTranslation extension in includes/ArticleTopicsDefinition.php.
16 */
17class ArticleTopicFiltersRegistry {
18    private const FILTERS = [
19        [
20            'groupId' => 'geography',
21            'msgKey' => 'wikimedia-articletopics-group-geography',
22            'topics' => [
23                [
24                    'topicId' => 'africa',
25                    'msgKey' => 'wikimedia-articletopics-topic-africa',
26                    'articleTopics' => [
27                        'africa',
28                        'central-africa',
29                        'eastern-africa',
30                        'northern-africa',
31                        'southern-africa',
32                        'western-africa',
33                    ],
34                ],
35                [
36                    'topicId' => 'asia',
37                    'msgKey' => 'wikimedia-articletopics-topic-asia',
38                    'articleTopics' => [
39                        'asia',
40                        'central-asia',
41                        'east-asia',
42                        'north-asia',
43                        'south-asia',
44                        'southeast-asia',
45                        'west-asia',
46                    ],
47                ],
48                [
49                    'topicId' => 'central-america',
50                    'msgKey' => 'wikimedia-articletopics-topic-central-america',
51                    'articleTopics' => [ 'central-america' ],
52                ],
53                [
54                    'topicId' => 'north-america',
55                    'msgKey' => 'wikimedia-articletopics-topic-north-america',
56                    'articleTopics' => [ 'north-america' ],
57                ],
58                [
59                    'topicId' => 'south-america',
60                    'msgKey' => 'wikimedia-articletopics-topic-south-america',
61                    'articleTopics' => [ 'south-america' ],
62                ],
63                [
64                    'topicId' => 'europe',
65                    'msgKey' => 'wikimedia-articletopics-topic-europe',
66                    'articleTopics' => [
67                        'europe',
68                        'eastern-europe',
69                        'northern-europe',
70                        'southern-europe',
71                        'western-europe',
72                    ],
73                ],
74                [
75                    'topicId' => 'oceania',
76                    'msgKey' => 'wikimedia-articletopics-topic-oceania',
77                    'articleTopics' => [ 'oceania' ],
78                ],
79            ],
80        ],
81        [
82            'groupId' => 'culture',
83            'msgKey' => 'wikimedia-articletopics-group-culture',
84            'topics' => [
85                [
86                    'topicId' => 'architecture',
87                    'msgKey' => 'wikimedia-articletopics-topic-architecture',
88                    'articleTopics' => [ 'architecture' ],
89                ],
90                [
91                    'topicId' => 'art',
92                    'msgKey' => 'wikimedia-articletopics-topic-art',
93                    'articleTopics' => [ 'visual-arts' ],
94                ],
95                [
96                    'topicId' => 'comics-and-anime',
97                    'msgKey' => 'wikimedia-articletopics-topic-comics-and-anime',
98                    'articleTopics' => [ 'comics-and-anime' ],
99                ],
100                [
101                    'topicId' => 'entertainment',
102                    'msgKey' => 'wikimedia-articletopics-topic-entertainment',
103                    'articleTopics' => [
104                        'entertainment',
105                        'radio',
106                    ],
107                ],
108                [
109                    'topicId' => 'fashion',
110                    'msgKey' => 'wikimedia-articletopics-topic-fashion',
111                    'articleTopics' => [ 'fashion' ],
112                ],
113                [
114                    'topicId' => 'literature',
115                    'msgKey' => 'wikimedia-articletopics-topic-literature',
116                    'articleTopics' => [ 'books' ],
117                ],
118                [
119                    'topicId' => 'music',
120                    'msgKey' => 'wikimedia-articletopics-topic-music',
121                    'articleTopics' => [ 'music' ],
122                ],
123                [
124                    'topicId' => 'performing-arts',
125                    'msgKey' => 'wikimedia-articletopics-topic-performing-arts',
126                    'articleTopics' => [ 'performing-arts' ],
127                ],
128                [
129                    'topicId' => 'sports',
130                    'msgKey' => 'wikimedia-articletopics-topic-sports',
131                    'articleTopics' => [ 'sports' ],
132                ],
133                [
134                    'topicId' => 'tv-and-film',
135                    'msgKey' => 'wikimedia-articletopics-topic-tv-and-film',
136                    'articleTopics' => [ 'films', 'television' ],
137                ],
138                [
139                    'topicId' => 'video-games',
140                    'msgKey' => 'wikimedia-articletopics-topic-video-games',
141                    'articleTopics' => [ 'video-games' ],
142                ],
143            ],
144        ],
145        [
146            'groupId' => 'history-and-society',
147            'msgKey' => 'wikimedia-articletopics-group-history-and-society',
148            'topics' => [
149                [
150                    'topicId' => 'biography',
151                    'msgKey' => 'wikimedia-articletopics-topic-biography',
152                    'articleTopics' => [ 'biography' ],
153                ],
154                [
155                    'topicId' => 'business-and-economics',
156                    'msgKey' => 'wikimedia-articletopics-topic-business-and-economics',
157                    'articleTopics' => [ 'business-and-economics' ],
158                ],
159                [
160                    'topicId' => 'education',
161                    'msgKey' => 'wikimedia-articletopics-topic-education',
162                    'articleTopics' => [ 'education' ],
163                ],
164                [
165                    'topicId' => 'food-and-drink',
166                    'msgKey' => 'wikimedia-articletopics-topic-food-and-drink',
167                    'articleTopics' => [ 'food-and-drink' ],
168                ],
169                [
170                    'topicId' => 'history',
171                    'msgKey' => 'wikimedia-articletopics-topic-history',
172                    'articleTopics' => [ 'history' ],
173                ],
174                [
175                    'topicId' => 'military-and-warfare',
176                    'msgKey' => 'wikimedia-articletopics-topic-military-and-warfare',
177                    'articleTopics' => [ 'military-and-warfare' ],
178                ],
179                [
180                    'topicId' => 'philosophy-and-religion',
181                    'msgKey' => 'wikimedia-articletopics-topic-philosophy-and-religion',
182                    'articleTopics' => [ 'philosophy-and-religion' ],
183                ],
184                [
185                    'topicId' => 'politics-and-government',
186                    'msgKey' => 'wikimedia-articletopics-topic-politics-and-government',
187                    'articleTopics' => [ 'politics-and-government' ],
188                ],
189                [
190                    'topicId' => 'society',
191                    'msgKey' => 'wikimedia-articletopics-topic-society',
192                    'articleTopics' => [ 'society' ],
193                ],
194                [
195                    'topicId' => 'transportation',
196                    'msgKey' => 'wikimedia-articletopics-topic-transportation',
197                    'articleTopics' => [ 'transportation' ],
198                ],
199                [
200                    'topicId' => 'women',
201                    'msgKey' => 'wikimedia-articletopics-topic-women',
202                    'articleTopics' => [ 'women' ],
203                ],
204            ],
205        ],
206        [
207            'groupId' => 'science-technology-and-math',
208            'msgKey' => 'wikimedia-articletopics-group-science-technology-and-math',
209            'topics' => [
210                [
211                    'topicId' => 'biology',
212                    'msgKey' => 'wikimedia-articletopics-topic-biology',
213                    'articleTopics' => [ 'biology' ],
214                ],
215                [
216                    'topicId' => 'chemistry',
217                    'msgKey' => 'wikimedia-articletopics-topic-chemistry',
218                    'articleTopics' => [ 'chemistry' ],
219                ],
220                [
221                    'topicId' => 'computers-and-internet',
222                    'msgKey' => 'wikimedia-articletopics-topic-computers-and-internet',
223                    'articleTopics' => [
224                        'internet-culture',
225                        'computing',
226                        'software',
227                    ],
228                ],
229                [
230                    'topicId' => 'earth-and-environment',
231                    'msgKey' => 'wikimedia-articletopics-topic-earth-and-environment',
232                    'articleTopics' => [
233                        'geographical',
234                        'earth-and-environment',
235                    ],
236                ],
237                [
238                    'topicId' => 'engineering',
239                    'msgKey' => 'wikimedia-articletopics-topic-engineering',
240                    'articleTopics' => [ 'engineering' ],
241                ],
242                [
243                    'topicId' => 'general-science',
244                    'msgKey' => 'wikimedia-articletopics-topic-general-science',
245                    'articleTopics' => [ 'stem' ],
246                ],
247                [
248                    'topicId' => 'mathematics',
249                    'msgKey' => 'wikimedia-articletopics-topic-mathematics',
250                    'articleTopics' => [ 'mathematics' ],
251                ],
252                [
253                    'topicId' => 'medicine-and-health',
254                    'msgKey' => 'wikimedia-articletopics-topic-medicine-and-health',
255                    'articleTopics' => [ 'medicine-and-health' ],
256                ],
257                [
258                    'topicId' => 'physics',
259                    'msgKey' => 'wikimedia-articletopics-topic-physics',
260                    'articleTopics' => [
261                        'physics',
262                        'space',
263                    ],
264                ],
265                [
266                    'topicId' => 'technology',
267                    'msgKey' => 'wikimedia-articletopics-topic-technology',
268                    'articleTopics' => [ 'technology' ],
269                ],
270            ],
271        ],
272    ];
273
274    /**
275     * Returns a plain list of topic IDs, for validation and the like.
276     * @return list<string>
277     */
278    public static function getTopicList(): array {
279        $topics = [];
280        foreach ( self::FILTERS as $group ) {
281            $topics = array_merge( $topics, array_column( $group['topics'], 'topicId' ) );
282        }
283        return $topics;
284    }
285
286    /**
287     * Get the article topics definition, organized into groups with their associated articletopics and label messages.
288     *
289     * @return array[]
290     * @phan-return list<array{groupId:string,msgKey:string,topics:list<array{topicId:string,msgKey:string,articleTopics:list<string>}>}>
291     */
292    public static function getGroupedTopics(): array {
293        // @phan-suppress-next-line PhanTypeMismatchReturn phan-return list vs. array mismatch
294        return self::FILTERS;
295    }
296
297    /**
298     * Returns message keys for the given topic IDs. The caller is responsible for validating that all the given
299     * topics exist.
300     *
301     * @param string[] $topicIDs
302     * @return array<string,string>
303     */
304    public static function getTopicMessages( array $topicIDs ): array {
305        $flatTopics = array_merge( ...array_column( self::FILTERS, 'topics' ) );
306        $topicCount = count( $flatTopics );
307        $ret = [];
308        $toFind = array_fill_keys( $topicIDs, true );
309        for ( $i = 0; $i < $topicCount && $toFind !== []; $i++ ) {
310            $curTopic = $flatTopics[$i]['topicId'];
311            if ( isset( $toFind[$curTopic] ) ) {
312                $ret[$curTopic] = $flatTopics[$i]['msgKey'];
313                unset( $toFind[$curTopic] );
314            }
315        }
316        if ( $toFind ) {
317            throw new InvalidArgumentException( "Unrecognized topics: " . implode( ', ', array_keys( $toFind ) ) );
318        }
319        return $ret;
320    }
321}