diff --git a/.phan/config.php b/.phan/config.php
index 0d43c78..e4bd302 100644
--- a/.phan/config.php
+++ b/.phan/config.php
@@ -17,7 +17,6 @@
$cfg['suppress_issue_types'] = [
'PhanAccessMethodInternal',
'SecurityCheck-LikelyFalsePositive',
- 'UnusedPluginSuppression'
];
return $cfg;
diff --git a/.phpcs.xml b/.phpcs.xml
index 304518b..ae2956a 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -2,7 +2,24 @@
.
-
-
-
+
+ 5
+
+
+ 5
+
+
+ 5
+
+
+ 5
+
+
+
+
+
+
+
+
+
diff --git a/extension.json b/extension.json
index b226dc0..ccc1a38 100644
--- a/extension.json
+++ b/extension.json
@@ -30,14 +30,13 @@
"Miraheze\\RottenLinks\\": "includes/"
},
"JobClasses": {
- "RottenLinksJob": "Miraheze\\RottenLinks\\RottenLinksJob"
+ "RottenLinksJob": "Miraheze\\RottenLinks\\Jobs\\RottenLinksJob"
},
"SpecialPages": {
"RottenLinks": {
- "class": "Miraheze\\RottenLinks\\SpecialRottenLinks",
+ "class": "Miraheze\\RottenLinks\\Specials\\SpecialRottenLinks",
"services": [
- "ConfigFactory",
- "DBLoadBalancer"
+ "ConnectionProvider"
]
}
},
@@ -62,8 +61,8 @@
"Main": {
"class": "Miraheze\\RottenLinks\\HookHandlers\\Main",
"services": [
- "JobQueueGroup",
- "ConnectionProvider"
+ "ConnectionProvider",
+ "JobQueueGroupFactory"
]
},
"Scribunto": {
@@ -72,36 +71,36 @@
},
"config": {
"RottenLinksBadCodes": {
- "value": [ "0", "400", "401", "403", "404", "405", "410", "502", "503", "504" ],
- "description": "Holds a list of HTTP codes that are considered bad. (array)"
+ "description": "Array. Holds a list of HTTP codes that are considered bad.",
+ "value": [ "0", "400", "401", "403", "404", "405", "410", "502", "503", "504" ]
},
"RottenLinksCurlTimeout": {
- "value": 30,
- "description": "Sets the timeout for cURL in seconds. (integer)"
- },
- "RottenLinksHTTPProxy": {
- "value": "",
- "description": "Sets a proxy to use for requests. (string)"
+ "description": "Integer. Sets the timeout for cURL in seconds.",
+ "value": 30
},
"RottenLinksExcludeProtocols": {
- "value": [ "tel", "mailto" ],
- "description": "Holds a list of protocols that should not be checked for validity. (array)"
+ "description": "Array. Holds a list of protocols that should not be checked for validity.",
+ "value": [ "tel", "mailto" ]
},
"RottenLinksExcludeWebsites": {
- "value": false,
- "description": "List of websites to exclude checking of response codes for. (array)"
+ "description": "Array. List of websites to exclude checking of response codes for.",
+ "value": []
},
"RottenLinksExternalLinkTarget": {
- "value": "_self",
- "description": "Sets the external link target (_self for the current tab or _blank for a new tab). (string)"
+ "description": "String. Sets the external link target (_self for the current tab or _blank for a new tab).",
+ "value": "_self"
+ },
+ "RottenLinksHTTPProxy": {
+ "description": "String. Sets a proxy to use for requests.",
+ "value": ""
},
"RottenLinksUserAgent": {
- "value": "",
- "description": "Overrides the user-agent to use for requests. Defaults to 'RottenLinks, MediaWiki extension (https://github.com/miraheze/RottenLinks), running on '. (string)"
+ "description": "String. Overrides the user-agent to use for requests. Defaults to 'RottenLinks, MediaWiki extension (https://github.com/miraheze/RottenLinks), running on '.",
+ "value": ""
}
},
"ConfigRegistry": {
- "RottenLinks": "GlobalVarConfig::newInstance"
+ "RottenLinks": "MediaWiki\\Config\\GlobalVarConfig::newInstance"
},
"manifest_version": 2
}
diff --git a/includes/HookHandlers/Installer.php b/includes/HookHandlers/Installer.php
index f2733fc..1d2bd4f 100644
--- a/includes/HookHandlers/Installer.php
+++ b/includes/HookHandlers/Installer.php
@@ -2,14 +2,11 @@
namespace Miraheze\RottenLinks\HookHandlers;
-use DatabaseUpdater;
use MediaWiki\Installer\Hook\LoadExtensionSchemaUpdatesHook;
class Installer implements LoadExtensionSchemaUpdatesHook {
- /**
- * @param DatabaseUpdater $updater
- */
+ /** @inheritDoc */
public function onLoadExtensionSchemaUpdates( $updater ) {
$dir = __DIR__ . '/../../sql';
diff --git a/includes/HookHandlers/Main.php b/includes/HookHandlers/Main.php
index 8baa93a..af1fe61 100644
--- a/includes/HookHandlers/Main.php
+++ b/includes/HookHandlers/Main.php
@@ -2,26 +2,25 @@
namespace Miraheze\RottenLinks\HookHandlers;
-use JobQueueGroup;
use MediaWiki\Deferred\LinksUpdate\LinksUpdate;
use MediaWiki\Hook\LinksUpdateCompleteHook;
use MediaWiki\Hook\ParserFirstCallInitHook;
+use MediaWiki\JobQueue\JobQueueGroupFactory;
use MediaWiki\Parser\Parser;
-use Miraheze\RottenLinks\RottenLinksJob;
+use Miraheze\RottenLinks\Jobs\RottenLinksJob;
use Miraheze\RottenLinks\RottenLinksParserFunctions;
use Wikimedia\Rdbms\IConnectionProvider;
class Main implements LinksUpdateCompleteHook, ParserFirstCallInitHook {
- private JobQueueGroup $jobQueueGroup;
+ private JobQueueGroupFactory $jobQueueGroupFactory;
private RottenLinksParserFunctions $parserFunctions;
- /**
- * @param JobQueueGroup $jobQueueGroup
- * @param IConnectionProvider $connectionProvider
- */
- public function __construct( JobQueueGroup $jobQueueGroup, IConnectionProvider $connectionProvider ) {
- $this->jobQueueGroup = $jobQueueGroup;
+ public function __construct(
+ IConnectionProvider $connectionProvider,
+ JobQueueGroupFactory $jobQueueGroupFactory
+ ) {
+ $this->jobQueueGroupFactory = $jobQueueGroupFactory;
$this->parserFunctions = new RottenLinksParserFunctions( $connectionProvider );
}
@@ -37,11 +36,12 @@ public function onLinksUpdateComplete( $linksUpdate, $ticket ) {
if ( $addedExternalLinks || $removedExternalLinks ) {
$params = [
- 'addedExternalLinks' => $addedExternalLinks,
- 'removedExternalLinks' => $removedExternalLinks
+ 'addedExternalLinks' => $addedExternalLinks ?? [],
+ 'removedExternalLinks' => $removedExternalLinks ?? [],
];
- $this->jobQueueGroup->push( new RottenLinksJob( $params ) );
+ $jobQueueGroup = $this->jobQueueGroupFactory->makeJobQueueGroup();
+ $jobQueueGroup->push( new RottenLinksJob( $params ) );
}
}
diff --git a/includes/RottenLinksJob.php b/includes/Jobs/RottenLinksJob.php
similarity index 81%
rename from includes/RottenLinksJob.php
rename to includes/Jobs/RottenLinksJob.php
index 5d76584..865ca8d 100644
--- a/includes/RottenLinksJob.php
+++ b/includes/Jobs/RottenLinksJob.php
@@ -1,43 +1,30 @@
addedExternalLinks = $params['addedExternalLinks'] ?? [];
- $this->removedExternalLinks = $params['removedExternalLinks'] ?? [];
+ $this->addedExternalLinks = $params['addedExternalLinks'];
+ $this->removedExternalLinks = $params['removedExternalLinks'];
}
- /**
- * Execute the job, updating the 'rottenlinks' table based on added and removed external links.
- *
- * @return bool True on success.
- */
- public function run() {
+ public function run(): bool {
$config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'RottenLinks' );
+ $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase();
if ( $this->addedExternalLinks ) {
- $dbw = MediaWikiServices::getInstance()
- ->getDBLoadBalancer()
- ->getMaintenanceConnectionRef( DB_PRIMARY );
-
$excludeProtocols = (array)$config->get( 'RottenLinksExcludeProtocols' );
$excludeWebsites = (array)$config->get( 'RottenLinksExcludeWebsites' );
@@ -86,10 +73,6 @@ public function run() {
}
if ( $this->removedExternalLinks ) {
- $dbw = MediaWikiServices::getInstance()
- ->getDBLoadBalancer()
- ->getMaintenanceConnectionRef( DB_PRIMARY );
-
foreach ( $this->removedExternalLinks as $url ) {
$url = $this->decodeDomainName( $url );
@@ -130,7 +113,6 @@ public function run() {
* URL-decoding the domain part turns these URLs back into valid syntax.
*
* @param string $url The URL to decode.
- *
* @return string The URL with the decoded domain name.
*/
private function decodeDomainName( string $url ): string {
diff --git a/includes/RottenLinks.php b/includes/RottenLinks.php
index 9b3cccd..9496d8e 100644
--- a/includes/RottenLinks.php
+++ b/includes/RottenLinks.php
@@ -2,19 +2,19 @@
namespace Miraheze\RottenLinks;
-use Config;
+use MediaWiki\Config\Config;
use MediaWiki\MediaWikiServices;
use WikiMedia\Rdbms\IReadableDatabase;
class RottenLinks {
+
/**
* Get the HTTP response status code for a given URL.
*
* @param string $url The URL to check.
- *
* @return int The HTTP status code.
*/
- public static function getResponse( string $url ) {
+ public static function getResponse( string $url ): int {
$services = MediaWikiServices::getInstance();
$config = $services->getConfigFactory()->makeConfig( 'RottenLinks' );
@@ -41,7 +41,6 @@ public static function getResponse( string $url ) {
* @param string $method The HTTP method to use ('HEAD' or 'GET').
* @param MediaWikiServices $services MediaWiki service instance.
* @param Config $config Configuration instance.
- *
* @return int The HTTP status code.
*/
private static function getHttpStatus(
@@ -49,7 +48,7 @@ private static function getHttpStatus(
string $method,
MediaWikiServices $services,
Config $config
- ) {
+ ): int {
$httpProxy = $config->get( 'RottenLinksHTTPProxy' );
$userAgent = $config->get( 'RottenLinksUserAgent' ) ?:
@@ -76,7 +75,6 @@ private static function getHttpStatus(
*
* @param IReadableDatabase $dbr
* @param string $url
- *
* @return ?int null if the URL is not in the database, 0 if there was no response, or the response code
*/
public static function getResponseFromDatabase( IReadableDatabase $dbr, string $url ): ?int {
diff --git a/includes/RottenLinksLuaLibrary.php b/includes/RottenLinksLuaLibrary.php
index b1d03bb..420d437 100644
--- a/includes/RottenLinksLuaLibrary.php
+++ b/includes/RottenLinksLuaLibrary.php
@@ -1,4 +1,5 @@
showBad = $showBad;
$this->config = $config;
+ $this->showBad = $showBad;
}
/**
diff --git a/includes/RottenLinksParserFunctions.php b/includes/RottenLinksParserFunctions.php
index 6b44361..652ba16 100644
--- a/includes/RottenLinksParserFunctions.php
+++ b/includes/RottenLinksParserFunctions.php
@@ -12,9 +12,6 @@ class RottenLinksParserFunctions {
private IConnectionProvider $connectionProvider;
- /**
- * @param IConnectionProvider $connectionProvider
- */
public function __construct( IConnectionProvider $connectionProvider ) {
$this->connectionProvider = $connectionProvider;
}
diff --git a/includes/SpecialRottenLinks.php b/includes/Specials/SpecialRottenLinks.php
similarity index 65%
rename from includes/SpecialRottenLinks.php
rename to includes/Specials/SpecialRottenLinks.php
index bdbb1d4..b0ffbed 100644
--- a/includes/SpecialRottenLinks.php
+++ b/includes/Specials/SpecialRottenLinks.php
@@ -1,40 +1,26 @@
config = $configFactory->makeConfig( 'RottenLinks' );
- $this->dbLoadBalancer = $dbLoadBalancer;
+ $this->connectionProvider = $connectionProvider;
}
/**
- * @param string $par
+ * @param ?string $par
*/
- public function execute( $par ) {
+ public function execute( $par ): void {
$this->setHeaders();
$this->outputHeader();
$this->addHelpLink( 'Extension:RottenLinks' );
@@ -42,7 +28,12 @@ public function execute( $par ) {
$showBad = $this->getRequest()->getBool( 'showBad' );
$stats = $this->getRequest()->getBool( 'stats' );
- $pager = new RottenLinksPager( $this->getContext(), $this->config, $showBad );
+ $pager = new RottenLinksPager(
+ $this->getConfig(),
+ $this->getContext(),
+ $this->getLinkRenderer(),
+ $showBad
+ );
$formDescriptor = [
'info' => [
@@ -53,21 +44,21 @@ public function execute( $par ) {
'type' => 'check',
'name' => 'showBad',
'label-message' => 'rottenlinks-showbad',
- 'default' => $showBad
+ 'default' => $showBad,
],
'statistics' => [
'type' => 'check',
'name' => 'stats',
'label-message' => 'rottenlinks-stats',
- 'default' => $stats
+ 'default' => $stats,
],
'limit' => [
'type' => 'limitselect',
'name' => 'limit',
'label-message' => 'table_pager_limit_label',
'default' => $pager->getLimit(),
- 'options' => $pager->getLimitSelectList()
- ]
+ 'options' => $pager->getLimitSelectList(),
+ ],
];
$htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() );
@@ -91,13 +82,8 @@ public function execute( $par ) {
$this->getOutput()->addParserOutputContent( $pager->getFullOutput() );
}
- /**
- * Display statistics related to RottenLinks.
- *
- * @return array Array with statistics information.
- */
- private function showStatistics() {
- $dbr = $this->dbLoadBalancer->getMaintenanceConnectionRef( DB_REPLICA );
+ private function showStatistics(): array {
+ $dbr = $this->connectionProvider->getReplicaDatabase();
$statusNumbers = $dbr->newSelectQueryBuilder()
->select( 'rl_respcode' )
@@ -122,19 +108,15 @@ private function showStatistics() {
'label' => "HTTP: {$respCode} " .
( $respCode != 0 ? HttpStatus::getMessage( $respCode ) : 'No Response' ),
'default' => $count,
- 'section' => 'statistics'
+ 'section' => 'statistics',
];
}
return $statDescriptor;
}
- /**
- * Get the group name for the special page.
- *
- * @return string Group name.
- */
- protected function getGroupName() {
+ /** @inheritDoc */
+ protected function getGroupName(): string {
return 'maintenance';
}
}
diff --git a/maintenance/updateExternalLinks.php b/maintenance/updateExternalLinks.php
index b5c64c4..8c19a3c 100644
--- a/maintenance/updateExternalLinks.php
+++ b/maintenance/updateExternalLinks.php
@@ -2,75 +2,53 @@
namespace Miraheze\RottenLinks\Maintenance;
+$IP ??= getenv( 'MW_INSTALL_PATH' ) ?: dirname( __DIR__, 3 );
+require_once "$IP/maintenance/Maintenance.php";
+
use Maintenance;
use MediaWiki\ExternalLinks\LinkFilter;
-use MediaWiki\MediaWikiServices;
use Miraheze\RottenLinks\RottenLinks;
-$IP = getenv( 'MW_INSTALL_PATH' );
-if ( $IP === false ) {
- $IP = __DIR__ . '/../../..';
-}
-
-require_once "$IP/maintenance/Maintenance.php";
-
class UpdateExternalLinks extends Maintenance {
+
public function __construct() {
parent::__construct();
$this->addDescription( 'Updates rottenlinks database table based on externallinks table.' );
-
$this->requireExtension( 'RottenLinks' );
}
- public function execute() {
+ public function execute(): void {
$time = time();
- $config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'RottenLinks' );
$dbw = $this->getDB( DB_PRIMARY );
$this->output( "Dropping all existing recorded entries\n" );
- $dbw->delete( 'rottenlinks',
- '*',
- __METHOD__
- );
+ $dbw->newDeleteQueryBuilder()
+ ->deleteFrom( 'rottenlinks' )
+ ->where( '*' )
+ ->caller( __METHOD__ )
+ ->execute();
+
+ $res = $dbw->newSelectQueryBuilder()
+ ->select( [
+ 'el_from',
+ 'el_to_domain_index',
+ 'el_to_path',
+ ] )
+ ->from( 'externallinks' )
+ ->caller( __METHOD__ )
+ ->fetchResultSet();
$rottenlinksarray = [];
-
- if ( version_compare( MW_VERSION, '1.41', '>=' ) ) {
- $res = $dbw->newSelectQueryBuilder()
- ->select( [
- 'el_from',
- 'el_to_domain_index',
- 'el_to_path',
- ] )
- ->from( 'externallinks' )
- ->caller( __METHOD__ )
- ->fetchResultSet();
-
- foreach ( $res as $row ) {
- // @phan-suppress-next-line PhanUndeclaredStaticMethod
- $elUrl = LinkFilter::reverseIndexes( $row->el_to_domain_index ) . $row->el_to_path;
- $rottenlinksarray[$elUrl][] = (int)$row->el_from;
- }
- } else {
- $res = $dbw->newSelectQueryBuilder()
- ->select( [
- 'el_from',
- 'el_to',
- ] )
- ->from( 'externallinks' )
- ->caller( __METHOD__ )
- ->fetchResultSet();
-
- foreach ( $res as $row ) {
- $rottenlinksarray[$row->el_to][] = (int)$row->el_from;
- }
+ foreach ( $res as $row ) {
+ $elUrl = LinkFilter::reverseIndexes( $row->el_to_domain_index ) . $row->el_to_path;
+ $rottenlinksarray[$elUrl][] = (int)$row->el_from;
}
- $excludeProtocols = (array)$config->get( 'RottenLinksExcludeProtocols' );
- $excludeWebsites = (array)$config->get( 'RottenLinksExcludeWebsites' );
+ $excludeProtocols = (array)$this->getConfig()->get( 'RottenLinksExcludeProtocols' );
+ $excludeWebsites = (array)$this->getConfig()->get( 'RottenLinksExcludeWebsites' );
foreach ( $rottenlinksarray as $url => $pages ) {
$url = $this->decodeDomainName( $url );
@@ -108,13 +86,14 @@ public function execute() {
$resp = RottenLinks::getResponse( $url );
$pagecount = count( $pages );
- $dbw->insert( 'rottenlinks',
- [
+ $dbw->newInsertQueryBuilder()
+ ->insertInto( 'rottenlinks' )
+ ->row( [
'rl_externallink' => $url,
- 'rl_respcode' => $resp
- ],
- __METHOD__
- );
+ 'rl_respcode' => $resp,
+ ] )
+ ->caller( __METHOD__ )
+ ->execute();
$this->output( "Added externallink ($url) used on $pagecount with code $resp\n" );
}
@@ -130,7 +109,6 @@ public function execute() {
* URL-decoding the domain part turns these URLs back into valid syntax.
*
* @param string $url The URL to decode.
- *
* @return string The URL with the decoded domain name.
*/
private function decodeDomainName( string $url ): string {