Page MenuHomeWickedGov Phorge

PerformRetroactiveAutoblockHandler.php
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

PerformRetroactiveAutoblockHandler.php

<?php
namespace MediaWiki\CheckUser\HookHandler;
use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Block\DatabaseBlockStoreFactory;
use MediaWiki\Block\Hook\PerformRetroactiveAutoblockHook;
use MediaWiki\CheckUser\CheckUserQueryInterface;
use MediaWiki\Config\Config;
use Wikimedia\Rdbms\IConnectionProvider;
use Wikimedia\Rdbms\SelectQueryBuilder;
use Wikimedia\Timestamp\ConvertibleTimestamp;
class PerformRetroactiveAutoblockHandler implements PerformRetroactiveAutoblockHook, CheckUserQueryInterface {
private IConnectionProvider $dbProvider;
private DatabaseBlockStoreFactory $databaseBlockStoreFactory;
private Config $config;
/**
* @param IConnectionProvider $dbProvider
* @param DatabaseBlockStoreFactory $databaseBlockStoreFactory
* @param Config $config
*/
public function __construct(
IConnectionProvider $dbProvider,
DatabaseBlockStoreFactory $databaseBlockStoreFactory,
Config $config
) {
$this->dbProvider = $dbProvider;
$this->databaseBlockStoreFactory = $databaseBlockStoreFactory;
$this->config = $config;
}
/**
* Retroactively autoblocks the last IP used by the user (if it is a user)
* blocked by this block.
*
* @param DatabaseBlock $block
* @param int[] &$blockIds
* @return bool
*/
public function onPerformRetroactiveAutoblock( $block, &$blockIds ) {
// If the maximum number of IPs to autoblock is 0, then defer to core or another extension to perform the
// autoblocks.
$maximumIPsToAutoblock = $this->config->get( 'CheckUserMaximumIPsToAutoblock' );
if ( !$maximumIPsToAutoblock ) {
return true;
}
// Check that the user is registered. If the user is not registered, then an autoblock does not make sense
// (because it would have the same target as the existing $block). In this case return true in case that core
// or another extension can handle this situation.
$user = $block->getTargetUserIdentity();
if ( !$user->isRegistered() ) {
return true;
}
// Get the last used IPs for the user that is the target of this block. These IPs will come from all three
// result tables if event table migration is set to read new.
$dbr = $this->dbProvider->getReplicaDatabase( $block->getWikiId() );
$lastUsedIPs = [];
foreach ( self::RESULT_TABLES as $table ) {
$tablePrefix = self::RESULT_TABLE_TO_PREFIX[$table];
$res = $dbr->newSelectQueryBuilder()
->select( [ 'ip' => $tablePrefix . 'ip', 'timestamp' => 'MAX(' . $tablePrefix . 'timestamp)' ] )
->from( $table )
->useIndex( $tablePrefix . 'actor_ip_time' )
->join( 'actor', null, 'actor_id=' . $tablePrefix . 'actor' )
->where( [ 'actor_user' => $user->getId( $block->getWikiId() ) ] )
->limit( $maximumIPsToAutoblock )
->groupBy( 'ip' )
->orderBy( 'timestamp', SelectQueryBuilder::SORT_DESC )
->caller( __METHOD__ )
->fetchResultSet();
// Use the results of the query to fill an array of IPs and their last usage timestamp.
// This will be truncated later to meet the specified limit.
foreach ( $res as $row ) {
$timestamp = ConvertibleTimestamp::convert( TS_MW, $row->timestamp );
// @phan-suppress-next-line PhanPossiblyUndeclaredVariable
if ( !array_key_exists( $row->ip, $lastUsedIPs ) ) {
$lastUsedIPs[$row->ip] = $timestamp;
} else {
$lastUsedIPs[$row->ip] = max( $lastUsedIPs[$row->ip], $timestamp );
}
}
}
// Sort the IPs by their last usage timestamp, and then truncate the list to a length of $maximumIPsToAutoblock.
arsort( $lastUsedIPs );
$lastUsedIPs = array_slice( array_flip( $lastUsedIPs ), 0, $maximumIPsToAutoblock );
// Iterate through the list of IPs to autoblock and actually perform the autoblocks.
$databaseBlockStore = $this->databaseBlockStoreFactory->getDatabaseBlockStore( $block->getWikiId() );
foreach ( $lastUsedIPs as $ip ) {
$id = $databaseBlockStore->doAutoblock( $block, $ip );
if ( $id ) {
$blockIds[] = $id;
}
}
// The autoblocking of the most recently used IP(s) has been handled by CheckUser, so return false.
return false;
}
}

File Metadata

Mime Type
text/x-php
Expires
Aug 16 2026, 11:26 (12 w, 7 h ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
35/34/12e500eae13d091aa636855cca68
Default Alt Text
PerformRetroactiveAutoblockHandler.php (3 KB)

Event Timeline