mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/CategoryTree
synced 2024-11-30 19:16:15 +00:00
Convert to new hook system (Workshop)
This converts the CategtoryTree extension to the new (MW1.35) hook system. The patch was written live during a hackathon workshop. A recording of the workshop is available at <https://www.youtube.com/watch?v=ZOj44Rbh0tM&t>. Bug: T282110 Bug: T271011 Change-Id: Ie52c393af378a980a2dac4ae7076fd6c016a8e0e
This commit is contained in:
parent
31314b9332
commit
2ee5743cfa
|
@ -11,9 +11,6 @@
|
|||
"ConfigRegistry": {
|
||||
"categorytree": "GlobalVarConfig::newInstance"
|
||||
},
|
||||
"ExtensionFunctions": [
|
||||
"MediaWiki\\Extension\\CategoryTree\\Hooks::initialize"
|
||||
],
|
||||
"SpecialPages": {
|
||||
"CategoryTree": {
|
||||
"class": "MediaWiki\\Extension\\CategoryTree\\CategoryTreePage",
|
||||
|
@ -84,16 +81,23 @@
|
|||
"localBasePath": "modules",
|
||||
"remoteExtPath": "CategoryTree/modules"
|
||||
},
|
||||
"HookHandlers": {
|
||||
"default": {
|
||||
"class": "MediaWiki\\Extension\\CategoryTree\\Hooks",
|
||||
"services": [ "DBLoadBalancer", "MainConfig" ]
|
||||
}
|
||||
},
|
||||
"Hooks": {
|
||||
"ArticleFromTitle": "MediaWiki\\Extension\\CategoryTree\\Hooks::articleFromTitle",
|
||||
"SpecialTrackingCategories::preprocess": "MediaWiki\\Extension\\CategoryTree\\Hooks::onSpecialTrackingCategoriesPreprocess",
|
||||
"SpecialTrackingCategories::generateCatLink": "MediaWiki\\Extension\\CategoryTree\\Hooks::onSpecialTrackingCategoriesGenerateCatLink",
|
||||
"SkinBuildSidebar": "MediaWiki\\Extension\\CategoryTree\\Hooks::onSkinBuildSidebar",
|
||||
"ParserFirstCallInit": "MediaWiki\\Extension\\CategoryTree\\Hooks::setHooks",
|
||||
"OutputPageMakeCategoryLinks": "MediaWiki\\Extension\\CategoryTree\\Hooks::outputPageMakeCategoryLinks",
|
||||
"BeforePageDisplay": "MediaWiki\\Extension\\CategoryTree\\Hooks::addHeaders",
|
||||
"BeforePageDisplayMobile": "MediaWiki\\Extension\\CategoryTree\\Hooks::addHeaders",
|
||||
"OutputPageParserOutput": "MediaWiki\\Extension\\CategoryTree\\Hooks::parserOutput"
|
||||
"MediaWikiServices": "default",
|
||||
"ArticleFromTitle": "default",
|
||||
"SpecialTrackingCategories::preprocess": "default",
|
||||
"SpecialTrackingCategories::generateCatLink": "default",
|
||||
"SkinBuildSidebar": "default",
|
||||
"ParserFirstCallInit": "default",
|
||||
"OutputPageMakeCategoryLinks": "default",
|
||||
"BeforePageDisplay": "default",
|
||||
"OutputPageParserOutput": "default",
|
||||
"BeforePageDisplayMobile": "MediaWiki\\Extension\\CategoryTree\\Hooks::addHeaders"
|
||||
},
|
||||
"config": {
|
||||
"CategoryTreeMaxChildren": {
|
||||
|
|
|
@ -26,7 +26,19 @@ namespace MediaWiki\Extension\CategoryTree;
|
|||
|
||||
use Article;
|
||||
use Category;
|
||||
use Config;
|
||||
use Html;
|
||||
use IContextSource;
|
||||
use MediaWiki\Hook\BeforePageDisplayHook;
|
||||
use MediaWiki\Hook\MediaWikiServicesHook;
|
||||
use MediaWiki\Hook\OutputPageMakeCategoryLinksHook;
|
||||
use MediaWiki\Hook\OutputPageParserOutputHook;
|
||||
use MediaWiki\Hook\ParserFirstCallInitHook;
|
||||
use MediaWiki\Hook\SkinBuildSidebarHook;
|
||||
use MediaWiki\Hook\SpecialTrackingCategories__generateCatLinkHook;
|
||||
use MediaWiki\Hook\SpecialTrackingCategories__preprocessHook;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Page\Hook\ArticleFromTitleHook;
|
||||
use OutputPage;
|
||||
use Parser;
|
||||
use ParserOutput;
|
||||
|
@ -35,15 +47,45 @@ use Sanitizer;
|
|||
use Skin;
|
||||
use SpecialPage;
|
||||
use Title;
|
||||
use Wikimedia\Rdbms\ILoadBalancer;
|
||||
|
||||
/**
|
||||
* Hooks for the CategoryTree extension, an AJAX based gadget
|
||||
* to display the category structure of a wiki
|
||||
*
|
||||
* @phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
|
||||
*/
|
||||
class Hooks {
|
||||
class Hooks implements
|
||||
ArticleFromTitleHook,
|
||||
SpecialTrackingCategories__preprocessHook,
|
||||
SpecialTrackingCategories__generateCatLinkHook,
|
||||
BeforePageDisplayHook,
|
||||
OutputPageParserOutputHook,
|
||||
MediaWikiServicesHook,
|
||||
SkinBuildSidebarHook,
|
||||
ParserFirstCallInitHook,
|
||||
OutputPageMakeCategoryLinksHook
|
||||
{
|
||||
|
||||
private const EXTENSION_DATA_FLAG = 'CategoryTree';
|
||||
|
||||
/** @var ILoadBalancer */
|
||||
private $loadBalancer;
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* @param ILoadBalancer $loadBalancer
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct( ILoadBalancer $loadBalancer, Config $config ) {
|
||||
$this->loadBalancer = $loadBalancer;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal For use by CategoryTreeCategoryViewer and CategoryTreePage only!
|
||||
* @return bool
|
||||
|
@ -56,8 +98,9 @@ class Hooks {
|
|||
/**
|
||||
* Adjusts config once MediaWiki is fully initialised
|
||||
* TODO: Don't do this, lazy initialize the config
|
||||
* @param MediaWikiServices $services
|
||||
*/
|
||||
public static function initialize() {
|
||||
public function onMediaWikiServices( $services ) {
|
||||
global $wgRequest;
|
||||
global $wgCategoryTreeDefaultOptions, $wgCategoryTreeDefaultMode;
|
||||
global $wgCategoryTreeCategoryPageOptions, $wgCategoryTreeCategoryPageMode;
|
||||
|
@ -87,13 +130,12 @@ class Hooks {
|
|||
/**
|
||||
* @param Parser $parser
|
||||
*/
|
||||
public static function setHooks( Parser $parser ) {
|
||||
global $wgCategoryTreeAllowTag;
|
||||
if ( !$wgCategoryTreeAllowTag ) {
|
||||
public function onParserFirstCallInit( $parser ) {
|
||||
if ( !$this->config->get( 'CategoryTreeAllowTag' ) ) {
|
||||
return;
|
||||
}
|
||||
$parser->setHook( 'categorytree', [ self::class, 'parserHook' ] );
|
||||
$parser->setFunctionHook( 'categorytree', [ self::class, 'parserFunction' ] );
|
||||
$parser->setHook( 'categorytree', [ $this, 'parserHook' ] );
|
||||
$parser->setFunctionHook( 'categorytree', [ $this, 'parserFunction' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +145,7 @@ class Hooks {
|
|||
* @param string ...$params
|
||||
* @return array|string
|
||||
*/
|
||||
public static function parserFunction( Parser $parser, ...$params ) {
|
||||
public function parserFunction( Parser $parser, ...$params ) {
|
||||
// first user-supplied parameter must be category name
|
||||
if ( !$params ) {
|
||||
// no category specified, return nothing
|
||||
|
@ -131,7 +173,7 @@ class Hooks {
|
|||
$cat . Html::closeElement( 'categorytree' );
|
||||
} else {
|
||||
// now handle just like a <categorytree> tag
|
||||
$html = self::parserHook( $cat, $argv, $parser );
|
||||
$html = $this->parserHook( $cat, $argv, $parser );
|
||||
return [ $html, 'noparse' => true, 'isHTML' => true ];
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +184,7 @@ class Hooks {
|
|||
* @param Skin $skin
|
||||
* @param array &$sidebar
|
||||
*/
|
||||
public static function onSkinBuildSidebar( Skin $skin, array &$sidebar ) {
|
||||
public function onSkinBuildSidebar( $skin, &$sidebar ) {
|
||||
global $wgCategoryTreeSidebarRoot, $wgCategoryTreeSidebarOptions;
|
||||
|
||||
if ( !$wgCategoryTreeSidebarRoot ) {
|
||||
|
@ -166,7 +208,7 @@ class Hooks {
|
|||
* @param bool $allowMissing
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function parserHook(
|
||||
public function parserHook(
|
||||
$cat,
|
||||
array $argv,
|
||||
Parser $parser = null,
|
||||
|
@ -203,7 +245,7 @@ class Hooks {
|
|||
* @param OutputPage $outputPage
|
||||
* @param ParserOutput $parserOutput
|
||||
*/
|
||||
public static function parserOutput( OutputPage $outputPage, ParserOutput $parserOutput ) {
|
||||
public function onOutputPageParserOutput( $outputPage, $parserOutput ) : void {
|
||||
if ( self::shouldForceHeaders() ) {
|
||||
// Skip, we've already set the headers unconditionally
|
||||
return;
|
||||
|
@ -213,6 +255,17 @@ class Hooks {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This hook is called prior to outputting a page.
|
||||
*
|
||||
* @param OutputPage $out
|
||||
* @param Skin $skin
|
||||
* @return void This hook must not abort, it must return no value
|
||||
*/
|
||||
public function onBeforePageDisplay( $out, $skin ) : void {
|
||||
self::addHeaders( $out );
|
||||
}
|
||||
|
||||
/**
|
||||
* BeforePageDisplay and BeforePageDisplayMobile hooks.
|
||||
* These hooks are used when $wgCategoryTreeForceHeaders is set.
|
||||
|
@ -231,8 +284,10 @@ class Hooks {
|
|||
*
|
||||
* @param Title $title
|
||||
* @param Article|null &$article Article (object) that will be returned
|
||||
* @param IContextSource $context
|
||||
* @return bool|void True or no return value to continue or false to abort
|
||||
*/
|
||||
public static function articleFromTitle( Title $title, Article &$article = null ) {
|
||||
public function onArticleFromTitle( $title, &$article, $context ) {
|
||||
if ( $title->getNamespace() == NS_CATEGORY ) {
|
||||
$article = new CategoryTreeCategoryPage( $title );
|
||||
}
|
||||
|
@ -245,11 +300,7 @@ class Hooks {
|
|||
* @param array &$links
|
||||
* @return bool
|
||||
*/
|
||||
public static function outputPageMakeCategoryLinks(
|
||||
OutputPage $out,
|
||||
array $categories,
|
||||
array &$links
|
||||
) {
|
||||
public function onOutputPageMakeCategoryLinks( $out, $categories, &$links ) {
|
||||
global $wgCategoryTreePageCategoryOptions, $wgCategoryTreeHijackPageCategories;
|
||||
|
||||
if ( !$wgCategoryTreeHijackPageCategories ) {
|
||||
|
@ -258,7 +309,7 @@ class Hooks {
|
|||
}
|
||||
|
||||
foreach ( $categories as $category => $type ) {
|
||||
$links[$type][] = self::parserHook( $category, $wgCategoryTreePageCategoryOptions, null, null, true );
|
||||
$links[$type][] = $this->parserHook( $category, $wgCategoryTreePageCategoryOptions, null, null, true );
|
||||
}
|
||||
CategoryTree::setHeaders( $out );
|
||||
|
||||
|
@ -289,8 +340,9 @@ class Hooks {
|
|||
* @param array $trackingCategories [ 'msg' => Title, 'cats' => Title[] ]
|
||||
* @phan-param array<string,array{msg:Title,cats:Title[]}> $trackingCategories
|
||||
*/
|
||||
public static function onSpecialTrackingCategoriesPreprocess(
|
||||
SpecialPage $specialPage, array $trackingCategories
|
||||
public function onSpecialTrackingCategories__preprocess(
|
||||
$specialPage,
|
||||
$trackingCategories
|
||||
) {
|
||||
$categoryDbKeys = [];
|
||||
foreach ( $trackingCategories as $catMsg => $data ) {
|
||||
|
@ -300,7 +352,7 @@ class Hooks {
|
|||
}
|
||||
$categories = [];
|
||||
if ( $categoryDbKeys ) {
|
||||
$dbr = wfGetDB( DB_REPLICA );
|
||||
$dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
|
||||
$res = $dbr->select(
|
||||
'category',
|
||||
[ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
|
||||
|
@ -321,16 +373,16 @@ class Hooks {
|
|||
* @param Title $catTitle Title object of the linked category
|
||||
* @param string &$html Result html
|
||||
*/
|
||||
public static function onSpecialTrackingCategoriesGenerateCatLink(
|
||||
SpecialPage $specialPage, Title $catTitle, &$html
|
||||
public function onSpecialTrackingCategories__generateCatLink( $specialPage,
|
||||
$catTitle, &$html
|
||||
) {
|
||||
if ( !isset( $specialPage->categoryTreeCategories ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cat = null;
|
||||
if ( isset( $specialPage->categoryTreeCategories[$catTitle->getDbKey()] ) ) {
|
||||
$cat = $specialPage->categoryTreeCategories[$catTitle->getDbKey()];
|
||||
if ( isset( $specialPage->categoryTreeCategories[$catTitle->getDBkey()] ) ) {
|
||||
$cat = $specialPage->categoryTreeCategories[$catTitle->getDBkey()];
|
||||
}
|
||||
|
||||
$html .= CategoryTree::createCountString( $specialPage->getContext(), $cat, 0 );
|
||||
|
|
Loading…
Reference in a new issue