wiki.techinc.nl/includes/TrackingCategories.php

251 lines
7.7 KiB
PHP
Raw Normal View History

<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup Categories
*/
use MediaWiki\Config\ServiceOptions;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MainConfigNames;
use MediaWiki\Page\PageReference;
use Psr\Log\LoggerInterface;
/**
* This class performs some operations related to tracking categories, such as creating
* a list of all such categories.
* @since 1.29
*/
class TrackingCategories {
/**
* @internal For use by ServiceWiring
*/
public const CONSTRUCTOR_OPTIONS = [
MainConfigNames::TrackingCategories,
MainConfigNames::EnableMagicLinks,
];
/** @var ServiceOptions */
private $options;
/** @var NamespaceInfo */
private $namespaceInfo;
/** @var TitleParser */
private $titleParser;
/** @var ExtensionRegistry */
private $extensionRegistry;
/** @var LoggerInterface */
private $logger;
/**
* Tracking categories that exist in core
*
* @var array
*/
private const CORE_TRACKING_CATEGORIES = [
'broken-file-category',
'duplicate-args-category',
'expansion-depth-exceeded-category',
'expensive-parserfunction-category',
'hidden-category-category',
'index-category',
'node-count-exceeded-category',
'noindex-category',
'nonnumeric-formatnum',
'post-expand-template-argument-category',
'post-expand-template-inclusion-category',
'restricted-displaytitle-ignored',
# template-equals-category is unused in MW>=1.39, but the category
# can be left around for a major release or so for an easier
# transition for anyone who didn't do the cleanup. T91154
'template-equals-category',
'template-loop-category',
'unstrip-depth-category',
'unstrip-size-category',
];
/**
* @param ServiceOptions $options
* @param NamespaceInfo $namespaceInfo
* @param TitleParser $titleParser
* @param LoggerInterface $logger
*/
public function __construct(
ServiceOptions $options,
NamespaceInfo $namespaceInfo,
TitleParser $titleParser,
LoggerInterface $logger
) {
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
$this->options = $options;
$this->namespaceInfo = $namespaceInfo;
$this->titleParser = $titleParser;
$this->logger = $logger;
// TODO convert ExtensionRegistry to a service and inject it
$this->extensionRegistry = ExtensionRegistry::getInstance();
}
/**
* Read the global and extract title objects from the corresponding messages
*
* TODO consider renaming this method, since this class is retrieved from
* MediaWikiServices, resulting in calls like:
* MediaWikiServices::getInstance()->getTrackingCategories()->getTrackingCategories()
*
* @return array[] [ 'msg' => Title, 'cats' => Title[] ]
* @phan-return array<string,array{msg:Title,cats:Title[]}>
*/
public function getTrackingCategories() {
$categories = array_merge(
self::CORE_TRACKING_CATEGORIES,
$this->extensionRegistry->getAttribute( MainConfigNames::TrackingCategories ),
$this->options->get( MainConfigNames::TrackingCategories ) // deprecated
);
// Only show magic link tracking categories if they are enabled
$enableMagicLinks = $this->options->get( MainConfigNames::EnableMagicLinks );
if ( $enableMagicLinks['ISBN'] ) {
$categories[] = 'magiclink-tracking-isbn';
}
if ( $enableMagicLinks['RFC'] ) {
$categories[] = 'magiclink-tracking-rfc';
}
if ( $enableMagicLinks['PMID'] ) {
$categories[] = 'magiclink-tracking-pmid';
}
$trackingCategories = [];
foreach ( $categories as $catMsg ) {
/*
* Check if the tracking category varies by namespace
* Otherwise only pages in the current namespace will be displayed
* If it does vary, show pages considering all namespaces
*
* TODO replace uses of wfMessage with an injected service once that is available
*/
$msgObj = wfMessage( $catMsg )->inContentLanguage();
$allCats = [];
$catMsgTitle = $this->titleParser->makeTitleValueSafe( NS_MEDIAWIKI, $catMsg );
if ( !$catMsgTitle ) {
continue;
}
// Match things like {{NAMESPACE}} and {{NAMESPACENUMBER}}.
// False positives are ok, this is just an efficiency shortcut
if ( strpos( $msgObj->plain(), '{{' ) !== false ) {
$ns = $this->namespaceInfo->getValidNamespaces();
foreach ( $ns as $namesp ) {
$tempTitle = $this->titleParser->makeTitleValueSafe( $namesp, $catMsg );
if ( !$tempTitle ) {
continue;
}
// XXX: should be a better way to convert a TitleValue
// to a PageReference!
$tempTitle = Title::newFromLinkTarget( $tempTitle );
$catName = $msgObj->page( $tempTitle )->text();
# Allow tracking categories to be disabled by setting them to "-"
if ( $catName !== '-' ) {
$catTitle = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $catName );
if ( $catTitle ) {
$allCats[] = $catTitle;
}
}
}
} else {
$catName = $msgObj->text();
# Allow tracking categories to be disabled by setting them to "-"
if ( $catName !== '-' ) {
$catTitle = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $catName );
if ( $catTitle ) {
$allCats[] = $catTitle;
}
}
}
$trackingCategories[$catMsg] = [
'cats' => $allCats,
'msg' => $catMsgTitle,
];
}
return $trackingCategories;
}
/**
* Resolve a tracking category.
* @param string $msg Message key
* @param ?PageReference $contextPage Context page title
* @return ?LinkTarget the proper category page, or null if
* the tracking category is disabled or unsafe
* @since 1.38
*/
public function resolveTrackingCategory( string $msg, ?PageReference $contextPage ): ?LinkTarget {
if ( !$contextPage ) {
$this->logger->debug( "Not adding tracking category $msg to missing page!" );
return null;
}
if ( $contextPage->getNamespace() === NS_SPECIAL ) {
$this->logger->debug( "Not adding tracking category $msg to special page!" );
return null;
}
// Important to parse with correct title (T33469)
// TODO replace uses of wfMessage with an injected service once that is available
$cat = wfMessage( $msg )
->page( $contextPage )
->inContentLanguage()
->text();
# Allow tracking categories to be disabled by setting them to "-"
if ( $cat === '-' ) {
return null;
}
$containerCategory = $this->titleParser->makeTitleValueSafe( NS_CATEGORY, $cat );
if ( $containerCategory === null ) {
$this->logger->debug( "[[MediaWiki:$msg]] is not a valid title!" );
return null;
}
return $containerCategory;
}
/**
* Add a tracking category to a ParserOutput.
* @param ParserOutput $parserOutput
* @param string $msg Message key
* @param ?PageReference $contextPage Context page title
* @return bool Whether the addition was successful
* @since 1.38
*/
public function addTrackingCategory( ParserOutput $parserOutput, string $msg, ?PageReference $contextPage ): bool {
$categoryPage = $this->resolveTrackingCategory( $msg, $contextPage );
if ( $categoryPage === null ) {
return false;
}
$parserOutput->addCategory(
$categoryPage->getDBkey(),
Change return value of ParserOutput::getPageProperty() when property is missing The old ParserOutput::getProperty() method returned `false` when a property was missing. This requires callers to use the `?:` syntax to supply default values, which then causes any falsey value to be treated as missing. So, for example, setting the defaultsort to '0' will cause the default sort to be ignored. Modern php convention is to use `null` for missing values, and the `??` syntax is a better/more restrictive alternative to `?:`. We renamed `ParserOutput::getProperty()` to `::getPageProperty()` in 1.38 (Ie963eea5aa0f0e984ced7c4dfa0fd65d57313cfa/T287216) but kept the return value convention. Before this actually makes it into a 1.38 release, take the opportunity to fix the return value for the new `ParserOutput::getPageProperty()` method to return `null` when the property is missing. We need to do some temporary workarounds to the places we'd already swapped over to use the new `::getPageProperty()` method to allow them to handle either `false` or `null` as a return value; we'll clean that up once this is merged. Code search: https://codesearch.wmcloud.org/deployed/?q=-%3EgetPageProperty%5C%28|T301915&i=nope&files=&excludeFiles=&repos= Bug: T301915 Depends-On: I3f11ce604970e47b41fc1c123792df8c3045626f Depends-On: Ie7533f49fe4cad01ebfda29760d23c61e9867b10 Depends-On: Ic5c09f5caa4c897bc553c614fbae9cee159566a2 Depends-On: I0278b2eafd90e77e4fee41c45a1165fb79ddf47e Depends-On: I383abb6b7dc5e96c0061af13957609f6e31a1065 Depends-On: I79f9f4078e415284af29b15047bafd1c823d7f5b Depends-On: I02276c48c49f5d2d241a69eb0a6cdf439b572d8b Depends-On: I71628661b4539a4e35ae32846e719f92bcf782e0 Depends-On: I7e215cb43de0ce150a6bcc00f92481dcdcfed383 Change-Id: Iaa25c390118d2db2b6578cdd558f2defd5351d15
2022-02-16 22:03:26 +00:00
$parserOutput->getPageProperty( 'defaultsort' ) ?? ''
);
return true;
}
}