MediaWiki master
TrackingCategories.php
Go to the documentation of this file.
1<?php
22namespace MediaWiki\Category;
23
33use Psr\Log\LoggerInterface;
34use Wikimedia\Parsoid\Core\ContentMetadataCollector;
35
43
47 public const CONSTRUCTOR_OPTIONS = [
50 ];
51
53 private $options;
54
56 private $namespaceInfo;
57
59 private $titleParser;
60
62 private $extensionRegistry;
63
65 private $logger;
66
72 private const CORE_TRACKING_CATEGORIES = [
73 'broken-file-category',
74 'duplicate-args-category',
75 'expansion-depth-exceeded-category',
76 'expensive-parserfunction-category',
77 'hidden-category-category',
78 'index-category',
79 'node-count-exceeded-category',
80 'noindex-category',
81 'nonnumeric-formatnum',
82 'post-expand-template-argument-category',
83 'post-expand-template-inclusion-category',
84 'restricted-displaytitle-ignored',
85 # template-equals-category is unused in MW>=1.39, but the category
86 # can be left around for a major release or so for an easier
87 # transition for anyone who didn't do the cleanup. T91154
88 'template-equals-category',
89 'template-loop-category',
90 'unstrip-depth-category',
91 'unstrip-size-category',
92 'bad-language-code-category',
93 'double-px-category',
94 ];
95
102 public function __construct(
103 ServiceOptions $options,
104 NamespaceInfo $namespaceInfo,
105 TitleParser $titleParser,
106 LoggerInterface $logger
107 ) {
108 $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
109 $this->options = $options;
110 $this->namespaceInfo = $namespaceInfo;
111 $this->titleParser = $titleParser;
112 $this->logger = $logger;
113
114 // TODO convert ExtensionRegistry to a service and inject it
115 $this->extensionRegistry = ExtensionRegistry::getInstance();
116 }
117
128 public function getTrackingCategories() {
129 $categories = array_merge(
130 self::CORE_TRACKING_CATEGORIES,
131 $this->extensionRegistry->getAttribute( MainConfigNames::TrackingCategories ),
132 $this->options->get( MainConfigNames::TrackingCategories ) // deprecated
133 );
134
135 // Only show magic link tracking categories if they are enabled
136 $enableMagicLinks = $this->options->get( MainConfigNames::EnableMagicLinks );
137 if ( $enableMagicLinks['ISBN'] ) {
138 $categories[] = 'magiclink-tracking-isbn';
139 }
140 if ( $enableMagicLinks['RFC'] ) {
141 $categories[] = 'magiclink-tracking-rfc';
142 }
143 if ( $enableMagicLinks['PMID'] ) {
144 $categories[] = 'magiclink-tracking-pmid';
145 }
146
147 $trackingCategories = [];
148 foreach ( $categories as $catMsg ) {
149 /*
150 * Check if the tracking category varies by namespace
151 * Otherwise only pages in the current namespace will be displayed
152 * If it does vary, show pages considering all namespaces
153 *
154 * TODO replace uses of wfMessage with an injected service once that is available
155 */
156 $msgObj = wfMessage( $catMsg )->inContentLanguage();
157 $allCats = [];
158 $catMsgTitle = $this->titleParser->makeTitleValueSafe( NS_MEDIAWIKI, $catMsg );
159 if ( !$catMsgTitle ) {
160 continue;
161 }
162
163 // Match things like {{NAMESPACE}} and {{NAMESPACENUMBER}}.
164 // False positives are ok, this is just an efficiency shortcut
165 if ( strpos( $msgObj->plain(), '{{' ) !== false ) {
166 $ns = $this->namespaceInfo->getValidNamespaces();
167 foreach ( $ns as $namesp ) {
168 $tempTitle = $this->titleParser->makeTitleValueSafe( $namesp, $catMsg );
169 if ( !$tempTitle ) {
170 continue;
171 }
172 // XXX: should be a better way to convert a TitleValue
173 // to a PageReference!
174 $tempTitle = Title::newFromLinkTarget( $tempTitle );
175 $catName = $msgObj->page( $tempTitle )->text();
176 # Allow tracking categories to be disabled by setting them to "-"
177 if ( $catName !== '-' ) {
178 $catTitle = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $catName );
179 if ( $catTitle ) {
180 $allCats[] = $catTitle;
181 }
182 }
183 }
184 } else {
185 $catName = $msgObj->text();
186 # Allow tracking categories to be disabled by setting them to "-"
187 if ( $catName !== '-' ) {
188 $catTitle = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $catName );
189 if ( $catTitle ) {
190 $allCats[] = $catTitle;
191 }
192 }
193 }
194 $trackingCategories[$catMsg] = [
195 'cats' => $allCats,
196 'msg' => $catMsgTitle,
197 ];
198 }
199
200 return $trackingCategories;
201 }
202
211 public function resolveTrackingCategory( string $msg, ?PageReference $contextPage ): ?LinkTarget {
212 if ( !$contextPage ) {
213 $this->logger->debug( "Not adding tracking category $msg to missing page!" );
214 return null;
215 }
216
217 if ( $contextPage->getNamespace() === NS_SPECIAL ) {
218 $this->logger->debug( "Not adding tracking category $msg to special page!" );
219 return null;
220 }
221
222 // Important to parse with correct title (T33469)
223 // TODO replace uses of wfMessage with an injected service once that is available
224 $cat = wfMessage( $msg )
225 ->page( $contextPage )
226 ->inContentLanguage()
227 ->text();
228
229 # Allow tracking categories to be disabled by setting them to "-"
230 if ( $cat === '-' ) {
231 return null;
232 }
233
234 $containerCategory = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $cat );
235 if ( $containerCategory === null ) {
236 $this->logger->debug( "[[MediaWiki:$msg]] is not a valid title!" );
237 return null;
238 }
239 return $containerCategory;
240 }
241
259 public function addTrackingCategory(
260 ContentMetadataCollector $parserOutput,
261 string $msg,
262 ?PageReference $contextPage
263 ): bool {
264 $categoryPage = $this->resolveTrackingCategory( $msg, $contextPage );
265 if ( $categoryPage === null ) {
266 return false;
267 }
268 $parserOutput->addCategory( $categoryPage );
269 return true;
270 }
271}
272
274class_alias( TrackingCategories::class, 'TrackingCategories' );
const NS_MEDIAWIKI
Definition Defines.php:73
const NS_SPECIAL
Definition Defines.php:54
const NS_CATEGORY
Definition Defines.php:79
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
This class performs some operations related to tracking categories, such as adding a tracking categor...
resolveTrackingCategory(string $msg, ?PageReference $contextPage)
Resolve a tracking category.
__construct(ServiceOptions $options, NamespaceInfo $namespaceInfo, TitleParser $titleParser, LoggerInterface $logger)
getTrackingCategories()
Read the global and extract title objects from the corresponding messages.
addTrackingCategory(ContentMetadataCollector $parserOutput, string $msg, ?PageReference $contextPage)
Add a tracking category to a ParserOutput, getting the title from a system message.
A class for passing options to services.
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
A class containing constants representing the names of configuration variables.
const EnableMagicLinks
Name constant for the EnableMagicLinks setting, for use with Config::get()
const TrackingCategories
Name constant for the TrackingCategories setting, for use with Config::get()
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:155
Load JSON files, and uses a Processor to extract information.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Represents a title within MediaWiki.
Definition Title.php:78
Represents the target of a wiki link.
Interface for objects (potentially) representing a page that can be viewable and linked to on a wiki.
getNamespace()
Returns the page's namespace number.
A title parser service for MediaWiki.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...