diff --git a/hooks.txt b/hooks.txt index 6380fded9..6802e01a8 100644 --- a/hooks.txt +++ b/hooks.txt @@ -61,3 +61,10 @@ $method: Method to generate the variable $vars: AbuseFilterVariableHolder $parameters: Parameters with data to compute the value &$result: Result of the computation + +'AbuseFilterShouldFilterAction': Called before filtering an action. If the current action should not be filtered, +return false and add a useful reason to $skipReasons. +$vars: AbuseFilterVariableHolder +$title: Title object target of the action +$user: User object performer of the action +&$skipReasons: Array of reasons why the action should be skipped diff --git a/includes/AbuseFilterRunner.php b/includes/AbuseFilterRunner.php index 441e36ca9..0b24f874f 100644 --- a/includes/AbuseFilterRunner.php +++ b/includes/AbuseFilterRunner.php @@ -107,7 +107,20 @@ class AbuseFilterRunner { $this->executeMode = true; $this->init(); - $useStash = $allowStash && $this->vars->getVar( 'action' )->toString() === 'edit'; + $action = $this->vars->getVar( 'action' )->toString(); + + $skipReasons = []; + $shouldFilter = Hooks::run( + 'AbuseFilterShouldFilterAction', + [ $this->vars, $this->title, $this->user, &$skipReasons ] + ); + if ( !$shouldFilter ) { + $logger = LoggerFactory::getInstance( 'AbuseFilter' ); + $logger->info( "Skipping action $action. Reasons provided: " . implode( ', ', $skipReasons ) ); + return Status::newGood(); + } + + $useStash = $allowStash && $action === 'edit'; $startTime = microtime( true ); @@ -195,6 +208,16 @@ class AbuseFilterRunner { $this->executeMode = false; $this->init(); + $skipReasons = []; + $shouldFilter = Hooks::run( + 'AbuseFilterShouldFilterAction', + [ $this->vars, $this->title, $this->user, &$skipReasons ] + ); + if ( !$shouldFilter ) { + // Don't log it yet + return Status::newGood(); + } + $cache = ObjectCache::getLocalClusterInstance(); $stashKey = $this->getStashKey( $cache );