MediaWiki  master
TrackingCategories.php
Go to the documentation of this file.
1 <?php
25 use Psr\Log\LoggerInterface;
26 
33 
37  public const CONSTRUCTOR_OPTIONS = [
38  'TrackingCategories',
39  'EnableMagicLinks',
40  ];
41 
43  private $options;
44 
46  private $namespaceInfo;
47 
49  private $titleParser;
50 
53 
55  private $logger;
56 
62  private const CORE_TRACKING_CATEGORIES = [
63  'broken-file-category',
64  'duplicate-args-category',
65  'expansion-depth-exceeded-category',
66  'expensive-parserfunction-category',
67  'hidden-category-category',
68  'index-category',
69  'node-count-exceeded-category',
70  'noindex-category',
71  'nonnumeric-formatnum',
72  'post-expand-template-argument-category',
73  'post-expand-template-inclusion-category',
74  'restricted-displaytitle-ignored',
75  'template-equals-category',
76  'template-loop-category',
77  'unstrip-depth-category',
78  'unstrip-size-category',
79  ];
80 
87  public function __construct(
91  LoggerInterface $logger
92  ) {
93  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
94  $this->options = $options;
95  $this->namespaceInfo = $namespaceInfo;
96  $this->titleParser = $titleParser;
97  $this->logger = $logger;
98 
99  // TODO convert ExtensionRegistry to a service and inject it
100  $this->extensionRegistry = ExtensionRegistry::getInstance();
101  }
102 
113  public function getTrackingCategories() {
114  $categories = array_merge(
115  self::CORE_TRACKING_CATEGORIES,
116  $this->extensionRegistry->getAttribute( 'TrackingCategories' ),
117  $this->options->get( 'TrackingCategories' ) // deprecated
118  );
119 
120  // Only show magic link tracking categories if they are enabled
121  $enableMagicLinks = $this->options->get( 'EnableMagicLinks' );
122  if ( $enableMagicLinks['ISBN'] ) {
123  $categories[] = 'magiclink-tracking-isbn';
124  }
125  if ( $enableMagicLinks['RFC'] ) {
126  $categories[] = 'magiclink-tracking-rfc';
127  }
128  if ( $enableMagicLinks['PMID'] ) {
129  $categories[] = 'magiclink-tracking-pmid';
130  }
131 
132  $trackingCategories = [];
133  foreach ( $categories as $catMsg ) {
134  /*
135  * Check if the tracking category varies by namespace
136  * Otherwise only pages in the current namespace will be displayed
137  * If it does vary, show pages considering all namespaces
138  *
139  * TODO replace uses of wfMessage with an injected service once that is available
140  */
141  $msgObj = wfMessage( $catMsg )->inContentLanguage();
142  $allCats = [];
143  $catMsgTitle = $this->titleParser->makeTitleValueSafe( NS_MEDIAWIKI, $catMsg );
144  if ( !$catMsgTitle ) {
145  continue;
146  }
147 
148  // Match things like {{NAMESPACE}} and {{NAMESPACENUMBER}}.
149  // False positives are ok, this is just an efficiency shortcut
150  if ( strpos( $msgObj->plain(), '{{' ) !== false ) {
151  $ns = $this->namespaceInfo->getValidNamespaces();
152  foreach ( $ns as $namesp ) {
153  $tempTitle = $this->titleParser->makeTitleValueSafe( $namesp, $catMsg );
154  if ( !$tempTitle ) {
155  continue;
156  }
157  // XXX: should be a better way to convert a TitleValue
158  // to a PageReference!
159  $tempTitle = Title::newFromTitleValue( $tempTitle );
160  $catName = $msgObj->page( $tempTitle )->text();
161  # Allow tracking categories to be disabled by setting them to "-"
162  if ( $catName !== '-' ) {
163  $catTitle = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $catName );
164  if ( $catTitle ) {
165  $allCats[] = $catTitle;
166  }
167  }
168  }
169  } else {
170  $catName = $msgObj->text();
171  # Allow tracking categories to be disabled by setting them to "-"
172  if ( $catName !== '-' ) {
173  $catTitle = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $catName );
174  if ( $catTitle ) {
175  $allCats[] = $catTitle;
176  }
177  }
178  }
179  $trackingCategories[$catMsg] = [
180  'cats' => $allCats,
181  'msg' => $catMsgTitle,
182  ];
183  }
184 
185  return $trackingCategories;
186  }
187 
196  public function resolveTrackingCategory( string $msg, ?PageReference $contextPage ): ?LinkTarget {
197  if ( !$contextPage ) {
198  $this->logger->debug( "Not adding tracking category $msg to missing page!" );
199  return null;
200  }
201 
202  if ( $contextPage->getNamespace() === NS_SPECIAL ) {
203  $this->logger->debug( "Not adding tracking category $msg to special page!" );
204  return null;
205  }
206 
207  // Important to parse with correct title (T33469)
208  // TODO replace uses of wfMessage with an injected service once that is available
209  $cat = wfMessage( $msg )
210  ->page( $contextPage )
211  ->inContentLanguage()
212  ->text();
213 
214  # Allow tracking categories to be disabled by setting them to "-"
215  if ( $cat === '-' ) {
216  return null;
217  }
218 
219  $containerCategory = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $cat );
220  if ( $containerCategory === null ) {
221  $this->logger->debug( "[[MediaWiki:$msg]] is not a valid title!" );
222  return null;
223  }
224  return $containerCategory;
225  }
226 
235  public function addTrackingCategory( ParserOutput $parserOutput, string $msg, ?PageReference $contextPage ): bool {
236  $categoryPage = $this->resolveTrackingCategory( $msg, $contextPage );
237  if ( $categoryPage === null ) {
238  return false;
239  }
240  $parserOutput->addCategory(
241  $categoryPage->getDBkey(),
242  $parserOutput->getPageProperty( 'defaultsort' ) ?: ''
243  );
244  return true;
245  }
246 }
TrackingCategories\addTrackingCategory
addTrackingCategory(ParserOutput $parserOutput, string $msg, ?PageReference $contextPage)
Add a tracking category to a ParserOutput.
Definition: TrackingCategories.php:235
ParserOutput
Definition: ParserOutput.php:35
NS_MEDIAWIKI
const NS_MEDIAWIKI
Definition: Defines.php:72
TrackingCategories\getTrackingCategories
getTrackingCategories()
Read the global and extract title objects from the corresponding messages.
Definition: TrackingCategories.php:113
ExtensionRegistry
The Registry loads JSON files, and uses a Processor to extract information from them.
Definition: ExtensionRegistry.php:15
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1167
TrackingCategories\CONSTRUCTOR_OPTIONS
const CONSTRUCTOR_OPTIONS
Definition: TrackingCategories.php:37
Page\PageReference
Interface for objects (potentially) representing a page that can be viewable and linked to on a wiki.
Definition: PageReference.php:49
TrackingCategories\$namespaceInfo
NamespaceInfo $namespaceInfo
Definition: TrackingCategories.php:46
NS_SPECIAL
const NS_SPECIAL
Definition: Defines.php:53
ExtensionRegistry\getInstance
static getInstance()
Definition: ExtensionRegistry.php:134
TrackingCategories\$options
ServiceOptions $options
Definition: TrackingCategories.php:43
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:27
Page\PageReference\getNamespace
getNamespace()
Returns the page's namespace number.
ParserOutput\addCategory
addCategory( $c, $sort)
Add a category.
Definition: ParserOutput.php:851
TitleParser
A title parser service for MediaWiki.
Definition: TitleParser.php:33
ParserOutput\getPageProperty
getPageProperty(string $name)
Look up a page property.
Definition: ParserOutput.php:1334
TrackingCategories\__construct
__construct(ServiceOptions $options, NamespaceInfo $namespaceInfo, TitleParser $titleParser, LoggerInterface $logger)
Definition: TrackingCategories.php:87
TrackingCategories\resolveTrackingCategory
resolveTrackingCategory(string $msg, ?PageReference $contextPage)
Resolve a tracking category.
Definition: TrackingCategories.php:196
TrackingCategories\$logger
LoggerInterface $logger
Definition: TrackingCategories.php:55
TrackingCategories
This class performs some operations related to tracking categories, such as creating a list of all su...
Definition: TrackingCategories.php:32
TrackingCategories\$titleParser
TitleParser $titleParser
Definition: TrackingCategories.php:49
TrackingCategories\$extensionRegistry
ExtensionRegistry $extensionRegistry
Definition: TrackingCategories.php:52
NS_CATEGORY
const NS_CATEGORY
Definition: Defines.php:78
NamespaceInfo
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Definition: NamespaceInfo.php:35
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:71
Title\newFromTitleValue
static newFromTitleValue(TitleValue $titleValue, $forceClone='')
Returns a Title given a TitleValue.
Definition: Title.php:274