Use PHP types

* Add PHP type hints where possible.
* Remove @var, @param and @return if redundant to type declaration
* Remove redundant type conversions which are now enforced by type
  hints.
* Enforce that decodeBoolean returns only a bool.

Change-Id: I8da84ed4dc778dd9d84f8d9eec0a399f5ed26405
This commit is contained in:
Fomafix 2024-08-17 21:49:42 +00:00
parent cc2b1f21e2
commit 8fe224cd60
6 changed files with 50 additions and 155 deletions

View file

@ -32,33 +32,15 @@ use Wikimedia\Rdbms\IConnectionProvider;
*/ */
class ApiCategoryTree extends ApiBase { class ApiCategoryTree extends ApiBase {
/** @var ConfigFactory */ private ConfigFactory $configFactory;
private $configFactory; private LanguageConverterFactory $languageConverterFactory;
private LinkRenderer $linkRenderer;
private IConnectionProvider $dbProvider;
private WANObjectCache $wanCache;
/** @var LanguageConverterFactory */
private $languageConverterFactory;
/** @var LinkRenderer */
private $linkRenderer;
/** @var IConnectionProvider */
private $dbProvider;
/** @var WANObjectCache */
private $wanCache;
/**
* @param ApiMain $main
* @param string $action
* @param ConfigFactory $configFactory
* @param IConnectionProvider $dbProvider
* @param LanguageConverterFactory $languageConverterFactory
* @param LinkRenderer $linkRenderer
* @param WANObjectCache $wanCache
*/
public function __construct( public function __construct(
ApiMain $main, ApiMain $main,
$action, string $action,
ConfigFactory $configFactory, ConfigFactory $configFactory,
IConnectionProvider $dbProvider, IConnectionProvider $dbProvider,
LanguageConverterFactory $languageConverterFactory, LanguageConverterFactory $languageConverterFactory,
@ -102,7 +84,7 @@ class ApiCategoryTree extends ApiBase {
* @param array $params * @param array $params
* @return string[] * @return string[]
*/ */
private function extractOptions( $params ): array { private function extractOptions( array $params ): array {
if ( !isset( $params['options'] ) ) { if ( !isset( $params['options'] ) ) {
return []; return [];
} }
@ -157,7 +139,7 @@ class ApiCategoryTree extends ApiBase {
* @param Config $ctConfig Config for CategoryTree * @param Config $ctConfig Config for CategoryTree
* @return string HTML * @return string HTML
*/ */
private function getHTML( CategoryTree $ct, Title $title, $depth, Config $ctConfig ) { private function getHTML( CategoryTree $ct, Title $title, int $depth, Config $ctConfig ): string {
$langConv = $this->languageConverterFactory->getLanguageConverter(); $langConv = $this->languageConverterFactory->getLanguageConverter();
return $this->wanCache->getWithSetCallback( return $this->wanCache->getWithSetCallback(

View file

@ -30,14 +30,10 @@ use Wikimedia\Rdbms\IResultWrapper;
*/ */
class CategoryCache { class CategoryCache {
/** @var (?Category)[] Keys are category database names, values are either a Category object or null */ /** @var (?Category)[] Keys are category database names, values are either a Category object or null */
private $cache = []; private array $cache = [];
/** @var ILoadBalancer */ private ILoadBalancer $loadBalancer;
private $loadBalancer;
/**
* @param ILoadBalancer $loadBalancer
*/
public function __construct( public function __construct(
ILoadBalancer $loadBalancer ILoadBalancer $loadBalancer
) { ) {
@ -47,8 +43,6 @@ class CategoryCache {
/** /**
* Get a preloaded Category object or null when the Category does not exists. Loaded the Category on demand, * Get a preloaded Category object or null when the Category does not exists. Loaded the Category on demand,
* if not in cache, use self::doQuery when requesting a high number of category * if not in cache, use self::doQuery when requesting a high number of category
* @param LinkTarget $categoryTarget
* @return ?Category
*/ */
public function getCategory( LinkTarget $categoryTarget ): ?Category { public function getCategory( LinkTarget $categoryTarget ): ?Category {
if ( $categoryTarget->getNamespace() !== NS_CATEGORY ) { if ( $categoryTarget->getNamespace() !== NS_CATEGORY ) {
@ -95,10 +89,7 @@ class CategoryCache {
$this->fillFromQuery( $rows ); $this->fillFromQuery( $rows );
} }
/** public function fillFromQuery( IResultWrapper $rows ): void {
* @param IResultWrapper $rows
*/
public function fillFromQuery( IResultWrapper $rows ) {
foreach ( $rows as $row ) { foreach ( $rows as $row ) {
$this->cache[$row->cat_title] = Category::newFromRow( $row ); $this->cache[$row->cat_title] = Category::newFromRow( $row );
} }

View file

@ -44,24 +44,11 @@ use Wikimedia\Rdbms\IConnectionProvider;
* to display the category structure of a wiki * to display the category structure of a wiki
*/ */
class CategoryTree { class CategoryTree {
/** @var OptionManager */ public OptionManager $optionManager;
public $optionManager; private Config $config;
private IConnectionProvider $dbProvider;
private LinkRenderer $linkRenderer;
/** @var Config */
private $config;
/** @var IConnectionProvider */
private $dbProvider;
/** @var LinkRenderer */
private $linkRenderer;
/**
* @param array $options
* @param Config $config
* @param IConnectionProvider $dbProvider
* @param LinkRenderer $linkRenderer
*/
public function __construct( public function __construct(
array $options, array $options,
Config $config, Config $config,
@ -76,9 +63,8 @@ class CategoryTree {
/** /**
* Add ResourceLoader modules to the OutputPage object * Add ResourceLoader modules to the OutputPage object
* @param OutputPage $outputPage
*/ */
public static function setHeaders( OutputPage $outputPage ) { public static function setHeaders( OutputPage $outputPage ): void {
# Add the modules # Add the modules
$outputPage->addModuleStyles( 'ext.categoryTree.styles' ); $outputPage->addModuleStyles( 'ext.categoryTree.styles' );
$outputPage->addModules( 'ext.categoryTree' ); $outputPage->addModules( 'ext.categoryTree' );
@ -95,8 +81,8 @@ class CategoryTree {
* @param bool $allowMissing * @param bool $allowMissing
* @return bool|string * @return bool|string
*/ */
public function getTag( ?Parser $parser, $category, $hideroot = false, array $attr = [], public function getTag( ?Parser $parser, string $category, bool $hideroot = false, array $attr = [],
$depth = 1, $allowMissing = false int $depth = 1, bool $allowMissing = false
) { ) {
$disableCache = $this->config->get( 'CategoryTreeDisableCache' ); $disableCache = $this->config->get( 'CategoryTreeDisableCache' );
@ -147,12 +133,9 @@ class CategoryTree {
/** /**
* Returns a string with an HTML representation of the children of the given category. * Returns a string with an HTML representation of the children of the given category.
* @param Title $title
* @param int $depth
* @suppress PhanUndeclaredClassMethod,PhanUndeclaredClassInstanceof * @suppress PhanUndeclaredClassMethod,PhanUndeclaredClassInstanceof
* @return string
*/ */
public function renderChildren( Title $title, $depth = 1 ) { public function renderChildren( Title $title, int $depth = 1 ): string {
if ( !$title->inNamespace( NS_CATEGORY ) ) { if ( !$title->inNamespace( NS_CATEGORY ) ) {
// Non-categories can't have children. :) // Non-categories can't have children. :)
return ''; return '';
@ -274,10 +257,8 @@ class CategoryTree {
/** /**
* Returns a string with an HTML representation of the parents of the given category. * Returns a string with an HTML representation of the parents of the given category.
* @param Title $title
* @return string
*/ */
public function renderParents( Title $title ) { public function renderParents( Title $title ): string {
$dbr = $this->dbProvider->getReplicaDatabase(); $dbr = $this->dbProvider->getReplicaDatabase();
$res = $dbr->newSelectQueryBuilder() $res = $dbr->newSelectQueryBuilder()
@ -315,7 +296,7 @@ class CategoryTree {
* @param int $children * @param int $children
* @return string * @return string
*/ */
public function renderNode( Title $title, $children = 0 ) { public function renderNode( Title $title, int $children = 0 ): string {
if ( $this->config->get( 'CategoryTreeUseCategoryTable' ) if ( $this->config->get( 'CategoryTreeUseCategoryTable' )
&& $title->inNamespace( NS_CATEGORY ) && $title->inNamespace( NS_CATEGORY )
&& !$this->optionManager->isInverse() && !$this->optionManager->isInverse()
@ -331,12 +312,8 @@ class CategoryTree {
/** /**
* Returns a string with a HTML represenation of the given page. * Returns a string with a HTML represenation of the given page.
* $info must be an associative array, containing at least a Title object under the 'title' key. * $info must be an associative array, containing at least a Title object under the 'title' key.
* @param Title $title
* @param Category|null $cat
* @param int $children
* @return string
*/ */
public function renderNodeInfo( Title $title, Category $cat = null, $children = 0 ) { public function renderNodeInfo( Title $title, Category $cat = null, int $children = 0 ): string {
$mode = $this->optionManager->getOption( 'mode' ); $mode = $this->optionManager->getOption( 'mode' );
$isInCatNS = $title->inNamespace( NS_CATEGORY ); $isInCatNS = $title->inNamespace( NS_CATEGORY );
@ -458,14 +435,10 @@ class CategoryTree {
/** /**
* Create a string which format the page, subcat and file counts of a category * Create a string which format the page, subcat and file counts of a category
* @param IContextSource $context
* @param ?Category $cat
* @param int $countMode
* @return string
*/ */
public static function createCountString( IContextSource $context, ?Category $cat, public static function createCountString( IContextSource $context, ?Category $cat,
$countMode int $countMode
) { ): string {
$allCount = $cat ? $cat->getMemberCount() : 0; $allCount = $cat ? $cat->getMemberCount() : 0;
$subcatCount = $cat ? $cat->getSubcatCount() : 0; $subcatCount = $cat ? $cat->getSubcatCount() : 0;
$fileCount = $cat ? $cat->getFileCount() : 0; $fileCount = $cat ? $cat->getFileCount() : 0;
@ -513,11 +486,9 @@ class CategoryTree {
/** /**
* Creates a Title object from a user provided (and thus unsafe) string * Creates a Title object from a user provided (and thus unsafe) string
* @param string $title
* @return null|Title
*/ */
public static function makeTitle( $title ) { public static function makeTitle( string $title ): ?Title {
$title = trim( strval( $title ) ); $title = trim( $title );
if ( $title === '' ) { if ( $title === '' ) {
return null; return null;

View file

@ -36,22 +36,11 @@ use Wikimedia\Rdbms\IConnectionProvider;
* to display the category structure of a wiki * to display the category structure of a wiki
*/ */
class CategoryTreePage extends SpecialPage { class CategoryTreePage extends SpecialPage {
/** @var string */ public string $target = '';
public $target = ''; private IConnectionProvider $dbProvider;
private SearchEngineFactory $searchEngineFactory;
public ?CategoryTree $tree = null;
/** @var IConnectionProvider */
private $dbProvider;
/** @var SearchEngineFactory */
private $searchEngineFactory;
/** @var CategoryTree */
public $tree = null;
/**
* @param IConnectionProvider $dbProvider
* @param SearchEngineFactory $searchEngineFactory
*/
public function __construct( public function __construct(
IConnectionProvider $dbProvider, IConnectionProvider $dbProvider,
SearchEngineFactory $searchEngineFactory SearchEngineFactory $searchEngineFactory
@ -65,7 +54,7 @@ class CategoryTreePage extends SpecialPage {
* @param string $name * @param string $name
* @return mixed * @return mixed
*/ */
private function getOption( $name ) { private function getOption( string $name ) {
if ( $this->tree ) { if ( $this->tree ) {
return $this->tree->optionManager->getOption( $name ); return $this->tree->optionManager->getOption( $name );
} else { } else {

View file

@ -62,25 +62,11 @@ class Hooks implements
CategoryViewer__doCategoryQueryHook, CategoryViewer__doCategoryQueryHook,
CategoryViewer__generateLinkHook CategoryViewer__generateLinkHook
{ {
private CategoryCache $categoryCache;
/** @var CategoryCache */ private Config $config;
private $categoryCache;
/** @var Config */
private $config;
/** @var IConnectionProvider */
private IConnectionProvider $dbProvider; private IConnectionProvider $dbProvider;
private LinkRenderer $linkRenderer;
/** @var LinkRenderer */
private $linkRenderer;
/**
* @param CategoryCache $categoryCache
* @param Config $config
* @param IConnectionProvider $dbProvider
* @param LinkRenderer $linkRenderer
*/
public function __construct( public function __construct(
CategoryCache $categoryCache, CategoryCache $categoryCache,
Config $config, Config $config,
@ -215,10 +201,10 @@ class Hooks implements
$attr = Sanitizer::validateTagAttributes( $argv, 'div' ); $attr = Sanitizer::validateTagAttributes( $argv, 'div' );
$hideroot = isset( $argv['hideroot'] ) $hideroot = isset( $argv['hideroot'] )
? OptionManager::decodeBoolean( $argv['hideroot'] ) : null; ? OptionManager::decodeBoolean( $argv['hideroot'] ) : false;
$onlyroot = isset( $argv['onlyroot'] ) $onlyroot = isset( $argv['onlyroot'] )
? OptionManager::decodeBoolean( $argv['onlyroot'] ) : null; ? OptionManager::decodeBoolean( $argv['onlyroot'] ) : false;
$depthArg = isset( $argv['depth'] ) ? (int)$argv['depth'] : null; $depthArg = isset( $argv['depth'] ) ? (int)$argv['depth'] : 1;
$depth = $ct->optionManager->capDepth( $depthArg ); $depth = $ct->optionManager->capDepth( $depthArg );
if ( $onlyroot ) { if ( $onlyroot ) {

View file

@ -33,16 +33,9 @@ use MediaWiki\MediaWikiServices;
* Core functions to handle the options * Core functions to handle the options
*/ */
class OptionManager { class OptionManager {
/** @var array */ private array $mOptions = [];
private $mOptions = []; private Config $config;
/** @var Config */
private $config;
/**
* @param array $options
* @param Config $config
*/
public function __construct( array $options, Config $config ) { public function __construct( array $options, Config $config ) {
$this->config = $config; $this->config = $config;
@ -76,10 +69,7 @@ class OptionManager {
} }
} }
/** public function getOptions(): array {
* @return array
*/
public function getOptions() {
return $this->mOptions; return $this->mOptions;
} }
@ -87,14 +77,11 @@ class OptionManager {
* @param string $name * @param string $name
* @return mixed * @return mixed
*/ */
public function getOption( $name ) { public function getOption( string $name ) {
return $this->mOptions[$name]; return $this->mOptions[$name];
} }
/** public function isInverse(): bool {
* @return bool
*/
public function isInverse() {
return $this->getOption( 'mode' ) === CategoryTreeMode::PARENTS; return $this->getOption( 'mode' ) === CategoryTreeMode::PARENTS;
} }
@ -182,11 +169,11 @@ class OptionManager {
* Helper function to convert a string to a boolean value. * Helper function to convert a string to a boolean value.
* Perhaps make this a global function in MediaWiki proper * Perhaps make this a global function in MediaWiki proper
* @param mixed $value * @param mixed $value
* @return bool|null|string * @return bool
*/ */
public static function decodeBoolean( $value ) { public static function decodeBoolean( $value ): bool {
if ( $value === null ) { if ( $value === null ) {
return null; return false;
} }
if ( is_bool( $value ) ) { if ( is_bool( $value ) ) {
return $value; return $value;
@ -204,12 +191,6 @@ class OptionManager {
|| $value === 'true' || $value === 't' || $value === 'on' || $value === 'true' || $value === 't' || $value === 'on'
) { ) {
return true; return true;
} elseif ( $value === 'no' || $value === 'n'
|| $value === 'false' || $value === 'f' || $value === 'off'
) {
return false;
} elseif ( $value === 'null' || $value === 'default' || $value === 'none' || $value === 'x' ) {
return null;
} else { } else {
return false; return false;
} }
@ -263,7 +244,7 @@ class OptionManager {
* @param string $enc * @param string $enc
* @return mixed * @return mixed
*/ */
private static function encodeOptions( array $options, $enc ) { private static function encodeOptions( array $options, string $enc ) {
if ( $enc === 'mode' || $enc === '' ) { if ( $enc === 'mode' || $enc === '' ) {
$opt = $options['mode']; $opt = $options['mode'];
} elseif ( $enc === 'json' ) { } elseif ( $enc === 'json' ) {
@ -279,7 +260,7 @@ class OptionManager {
* @param int|null $depth * @param int|null $depth
* @return string * @return string
*/ */
public function getOptionsAsCacheKey( $depth = null ) { public function getOptionsAsCacheKey( int $depth = null ): string {
$key = ''; $key = '';
foreach ( $this->mOptions as $k => $v ) { foreach ( $this->mOptions as $k => $v ) {
@ -299,7 +280,7 @@ class OptionManager {
* @param int|null $depth * @param int|null $depth
* @return mixed * @return mixed
*/ */
public function getOptionsAsJsStructure( $depth = null ) { public function getOptionsAsJsStructure( int $depth = null ) {
$opt = $this->mOptions; $opt = $this->mOptions;
if ( $depth !== null ) { if ( $depth !== null ) {
$opt['depth'] = $depth; $opt['depth'] = $depth;
@ -311,15 +292,10 @@ class OptionManager {
/** /**
* Internal function to cap depth * Internal function to cap depth
* @param int $depth * @param int $depth
* @return int|mixed * @return int
*/ */
public function capDepth( $depth ) { public function capDepth( int $depth ): int {
if ( !is_numeric( $depth ) ) {
return 1;
}
$mode = $this->getOption( 'mode' ); $mode = $this->getOption( 'mode' );
$depth = intval( $depth );
$maxDepth = $this->config->get( 'CategoryTreeMaxDepth' ); $maxDepth = $this->config->get( 'CategoryTreeMaxDepth' );
if ( is_array( $maxDepth ) ) { if ( is_array( $maxDepth ) ) {