mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/AbuseFilter.git
synced 2024-09-23 10:18:22 +00:00
Add a service to format filter specs
This requires a MessageLocalizer, which currently means providing the main RequestContext. This is the only alternative right now, until core provides a proper MessageLocalizer service (see T247127). Change-Id: I8c93e2ae7e7bd4fc561c5e8490ed2feb1ef0edc2
This commit is contained in:
parent
dc7509811a
commit
7bcb5ec2d5
|
@ -70,7 +70,8 @@
|
|||
"PermissionManager",
|
||||
"AbuseFilterPermissionManager",
|
||||
"AbuseFilterConsequencesRegistry",
|
||||
"AbuseFilterVariablesBlobStore"
|
||||
"AbuseFilterVariablesBlobStore",
|
||||
"AbuseFilterSpecsFormatter"
|
||||
]
|
||||
},
|
||||
"AbuseFilter": {
|
||||
|
@ -164,6 +165,7 @@
|
|||
"MediaWiki\\Extension\\AbuseFilter\\AbuseFilterPermissionManager": "includes/AbuseFilterPermissionManager.php",
|
||||
"MediaWiki\\Extension\\AbuseFilter\\EchoNotifier": "includes/EchoNotifier.php",
|
||||
"MediaWiki\\Extension\\AbuseFilter\\ThrottleFilterPresentationModel": "includes/ThrottleFilterPresentationModel.php",
|
||||
"MediaWiki\\Extension\\AbuseFilter\\SpecsFormatter": "includes/SpecsFormatter.php",
|
||||
"MediaWiki\\Extension\\AbuseFilter\\AbuseFilterServices": "includes/AbuseFilterServices.php",
|
||||
"MediaWiki\\Extension\\AbuseFilter\\FilterProfiler": "includes/FilterProfiler.php",
|
||||
"MediaWiki\\Extension\\AbuseFilter\\BlockAutopromoteStore": "includes/BlockAutopromoteStore.php",
|
||||
|
|
|
@ -68,21 +68,6 @@ class AbuseFilter {
|
|||
return $runner->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @param MessageLocalizer|null $localizer
|
||||
* @return string HTML
|
||||
*/
|
||||
public static function getActionDisplay( $action, MessageLocalizer $localizer = null ) {
|
||||
$msgCallback = $localizer != null ? [ $localizer, 'msg' ] : 'wfMessage';
|
||||
// Give grep a chance to find the usages:
|
||||
// abusefilter-action-tag, abusefilter-action-throttle, abusefilter-action-warn,
|
||||
// abusefilter-action-blockautopromote, abusefilter-action-block, abusefilter-action-degroup,
|
||||
// abusefilter-action-rangeblock, abusefilter-action-disallow
|
||||
$msg = $msgCallback( "abusefilter-action-$action" );
|
||||
return $msg->isDisabled() ? htmlspecialchars( $action ) : $msg->escaped();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $var
|
||||
* @param string $indent
|
||||
|
@ -177,99 +162,6 @@ class AbuseFilter {
|
|||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @param string[] $parameters
|
||||
* @param Language $lang
|
||||
* @return string
|
||||
*/
|
||||
public static function formatAction( $action, $parameters, $lang ) {
|
||||
if ( count( $parameters ) === 0 ||
|
||||
( $action === 'block' && count( $parameters ) !== 3 ) ) {
|
||||
$displayAction = self::getActionDisplay( $action );
|
||||
} else {
|
||||
if ( $action === 'block' ) {
|
||||
// Needs to be treated separately since the message is more complex
|
||||
$messages = [
|
||||
wfMessage( 'abusefilter-block-anon' )->escaped() .
|
||||
wfMessage( 'colon-separator' )->escaped() .
|
||||
$lang->translateBlockExpiry( $parameters[1] ),
|
||||
wfMessage( 'abusefilter-block-user' )->escaped() .
|
||||
wfMessage( 'colon-separator' )->escaped() .
|
||||
$lang->translateBlockExpiry( $parameters[2] )
|
||||
];
|
||||
if ( $parameters[0] === 'blocktalk' ) {
|
||||
$messages[] = wfMessage( 'abusefilter-block-talk' )->escaped();
|
||||
}
|
||||
$displayAction = $lang->commaList( $messages );
|
||||
} elseif ( $action === 'throttle' ) {
|
||||
array_shift( $parameters );
|
||||
list( $actions, $time ) = explode( ',', array_shift( $parameters ) );
|
||||
|
||||
// Join comma-separated groups in a commaList with a final "and", and convert to messages.
|
||||
// Messages used here: abusefilter-throttle-ip, abusefilter-throttle-user,
|
||||
// abusefilter-throttle-site, abusefilter-throttle-creationdate, abusefilter-throttle-editcount
|
||||
// abusefilter-throttle-range, abusefilter-throttle-page, abusefilter-throttle-none
|
||||
foreach ( $parameters as &$val ) {
|
||||
if ( strpos( $val, ',' ) !== false ) {
|
||||
$subGroups = explode( ',', $val );
|
||||
foreach ( $subGroups as &$group ) {
|
||||
$msg = wfMessage( "abusefilter-throttle-$group" );
|
||||
// We previously accepted literally everything in this field, so old entries
|
||||
// may have weird stuff.
|
||||
$group = $msg->exists() ? $msg->text() : $group;
|
||||
}
|
||||
unset( $group );
|
||||
$val = $lang->listToText( $subGroups );
|
||||
} else {
|
||||
$msg = wfMessage( "abusefilter-throttle-$val" );
|
||||
$val = $msg->exists() ? $msg->text() : $val;
|
||||
}
|
||||
}
|
||||
unset( $val );
|
||||
$groups = $lang->semicolonList( $parameters );
|
||||
|
||||
$displayAction = self::getActionDisplay( $action ) .
|
||||
wfMessage( 'colon-separator' )->escaped() .
|
||||
wfMessage( 'abusefilter-throttle-details' )->params( $actions, $time, $groups )->escaped();
|
||||
} else {
|
||||
$displayAction = self::getActionDisplay( $action ) .
|
||||
wfMessage( 'colon-separator' )->escaped() .
|
||||
$lang->semicolonList( array_map( 'htmlspecialchars', $parameters ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $displayAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Language $lang
|
||||
* @return string
|
||||
*/
|
||||
public static function formatFlags( $value, $lang ) {
|
||||
$flags = array_filter( explode( ',', $value ) );
|
||||
$flags_display = [];
|
||||
foreach ( $flags as $flag ) {
|
||||
$flags_display[] = wfMessage( "abusefilter-history-$flag" )->escaped();
|
||||
}
|
||||
|
||||
return $lang->commaList( $flags_display );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives either the user-specified name for a group,
|
||||
* or spits the input back out
|
||||
* @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups)
|
||||
* @return string A name for that filter group, or the input.
|
||||
*/
|
||||
public static function nameGroup( $group ) {
|
||||
// Give grep a chance to find the usages: abusefilter-group-default
|
||||
$msg = "abusefilter-group-$group";
|
||||
|
||||
return wfMessage( $msg )->exists() ? wfMessage( $msg )->escaped() : $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up some text of a revision from its revision id
|
||||
*
|
||||
|
|
|
@ -197,4 +197,11 @@ class AbuseFilterServices {
|
|||
public static function getFilterRunnerFactory() : FilterRunnerFactory {
|
||||
return MediaWikiServices::getInstance()->getService( FilterRunnerFactory::SERVICE_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SpecsFormatter
|
||||
*/
|
||||
public static function getSpecsFormatter() : SpecsFormatter {
|
||||
return MediaWikiServices::getInstance()->getService( SpecsFormatter::SERVICE_NAME );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace MediaWiki\Extension\AbuseFilter\LogFormatter;
|
||||
|
||||
use AbuseFilter;
|
||||
use LogFormatter;
|
||||
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
|
||||
use Message;
|
||||
use SpecialPage;
|
||||
|
||||
|
@ -52,8 +52,10 @@ class AbuseLogHitFormatter extends LogFormatter {
|
|||
$actions = explode( ',', $actions_takenRaw );
|
||||
$displayActions = [];
|
||||
|
||||
$specsFormatter = AbuseFilterServices::getSpecsFormatter();
|
||||
$specsFormatter->setMessageLocalizer( $this->context );
|
||||
foreach ( $actions as $action ) {
|
||||
$displayActions[] = AbuseFilter::getActionDisplay( $action, $this->context );
|
||||
$displayActions[] = $specsFormatter->getActionDisplay( $action );
|
||||
}
|
||||
$actions_taken = $this->context->getLanguage()->commaList( $displayActions );
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace MediaWiki\Extension\AbuseFilter\Pager;
|
|||
use AbuseFilter;
|
||||
use HtmlArmor;
|
||||
use Linker;
|
||||
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
|
||||
use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewHistory;
|
||||
use MediaWiki\Linker\LinkRenderer;
|
||||
use SpecialPage;
|
||||
|
@ -92,6 +93,8 @@ class AbuseFilterHistoryPager extends TablePager {
|
|||
public function formatValue( $name, $value ) {
|
||||
$lang = $this->getLanguage();
|
||||
$linkRenderer = $this->getLinkRenderer();
|
||||
$specsFormatter = AbuseFilterServices::getSpecsFormatter();
|
||||
$specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
|
||||
$row = $this->mCurrentRow;
|
||||
|
||||
|
@ -119,7 +122,7 @@ class AbuseFilterHistoryPager extends TablePager {
|
|||
$formatted = htmlspecialchars( $value, ENT_QUOTES, 'UTF-8', false );
|
||||
break;
|
||||
case 'afh_flags':
|
||||
$formatted = AbuseFilter::formatFlags( $value, $lang );
|
||||
$formatted = $specsFormatter->formatFlags( $value, $lang );
|
||||
break;
|
||||
case 'afh_actions':
|
||||
$actions = unserialize( $value );
|
||||
|
@ -127,7 +130,7 @@ class AbuseFilterHistoryPager extends TablePager {
|
|||
$display_actions = '';
|
||||
|
||||
foreach ( $actions as $action => $parameters ) {
|
||||
$displayAction = AbuseFilter::formatAction( $action, $parameters, $lang );
|
||||
$displayAction = $specsFormatter->formatAction( $action, $parameters, $lang );
|
||||
$display_actions .= Xml::tags( 'li', null, $displayAction );
|
||||
}
|
||||
$display_actions = Xml::tags( 'ul', null, $display_actions );
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace MediaWiki\Extension\AbuseFilter\Pager;
|
||||
|
||||
use AbuseFilter;
|
||||
use FakeResultWrapper;
|
||||
use Linker;
|
||||
use LogicException;
|
||||
|
@ -187,6 +186,8 @@ class AbuseFilterPager extends TablePager {
|
|||
$lang = $this->getLanguage();
|
||||
$user = $this->getUser();
|
||||
$linkRenderer = $this->getLinkRenderer();
|
||||
$specsFormatter = AbuseFilterServices::getSpecsFormatter();
|
||||
$specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
$row = $this->mCurrentRow;
|
||||
|
||||
switch ( $name ) {
|
||||
|
@ -205,9 +206,8 @@ class AbuseFilterPager extends TablePager {
|
|||
case 'af_actions':
|
||||
$actions = explode( ',', $value );
|
||||
$displayActions = [];
|
||||
$context = $this->getContext();
|
||||
foreach ( $actions as $action ) {
|
||||
$displayActions[] = AbuseFilter::getActionDisplay( $action, $context );
|
||||
$displayActions[] = $specsFormatter->getActionDisplay( $action );
|
||||
}
|
||||
return $lang->commaList( $displayActions );
|
||||
case 'af_enabled':
|
||||
|
@ -276,7 +276,7 @@ class AbuseFilterPager extends TablePager {
|
|||
wfEscapeWikiText( $row->af_user_text )
|
||||
)->parse();
|
||||
case 'af_group':
|
||||
return AbuseFilter::nameGroup( $value );
|
||||
return $specsFormatter->nameGroup( $value );
|
||||
default:
|
||||
throw new MWException( "Unknown row type $name!" );
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace MediaWiki\Extension\AbuseFilter\Pager;
|
||||
|
||||
use AbuseFilter;
|
||||
use HtmlArmor;
|
||||
use IContextSource;
|
||||
use Linker;
|
||||
|
@ -166,9 +165,10 @@ class AbuseLogPager extends ReverseChronologicalPager {
|
|||
$actions = explode( ',', $actions_takenRaw );
|
||||
$displayActions = [];
|
||||
|
||||
$context = $this->getContext();
|
||||
$specsFormatter = AbuseFilterServices::getSpecsFormatter();
|
||||
$specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
foreach ( $actions as $action ) {
|
||||
$displayActions[] = AbuseFilter::getActionDisplay( $action, $context );
|
||||
$displayActions[] = $specsFormatter->getActionDisplay( $action );
|
||||
}
|
||||
$actions_taken = $lang->commaList( $displayActions );
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace MediaWiki\Extension\AbuseFilter\Pager;
|
||||
|
||||
use AbuseFilter;
|
||||
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
|
||||
use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewList;
|
||||
use MediaWiki\Linker\LinkRenderer;
|
||||
|
||||
|
@ -28,6 +28,8 @@ class GlobalAbuseFilterPager extends AbuseFilterPager {
|
|||
*/
|
||||
public function formatValue( $name, $value ) {
|
||||
$lang = $this->getLanguage();
|
||||
$specsFormatter = AbuseFilterServices::getSpecsFormatter();
|
||||
$specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
$row = $this->mCurrentRow;
|
||||
|
||||
switch ( $name ) {
|
||||
|
@ -67,7 +69,7 @@ class GlobalAbuseFilterPager extends AbuseFilterPager {
|
|||
)->parse();
|
||||
case 'af_group':
|
||||
// If this is global, local name probably doesn't exist, but try
|
||||
return AbuseFilter::nameGroup( $value );
|
||||
return $specsFormatter->nameGroup( $value );
|
||||
default:
|
||||
return parent::formatValue( $name, $value );
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ use MediaWiki\Extension\AbuseFilter\FilterValidator;
|
|||
use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner;
|
||||
use MediaWiki\Extension\AbuseFilter\KeywordsManager;
|
||||
use MediaWiki\Extension\AbuseFilter\Parser\ParserFactory;
|
||||
use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
|
||||
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
|
||||
use MediaWiki\Extension\AbuseFilter\Watcher\EmergencyWatcher;
|
||||
use MediaWiki\Extension\AbuseFilter\Watcher\UpdateHitCountWatcher;
|
||||
|
@ -263,6 +264,12 @@ return [
|
|||
$services->getMainConfig()->get( 'AbuseFilterValidGroups' )
|
||||
);
|
||||
},
|
||||
SpecsFormatter::SERVICE_NAME => function ( MediaWikiServices $services ): SpecsFormatter {
|
||||
return new SpecsFormatter(
|
||||
// TODO: Use a proper MessageLocalizer once available (T247127)
|
||||
RequestContext::getMain()
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
|
133
includes/SpecsFormatter.php
Normal file
133
includes/SpecsFormatter.php
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
namespace MediaWiki\Extension\AbuseFilter;
|
||||
|
||||
use Language;
|
||||
use MessageLocalizer;
|
||||
|
||||
/**
|
||||
* @todo Improve this once DI around Message objects is improved in MW core.
|
||||
*/
|
||||
class SpecsFormatter {
|
||||
public const SERVICE_NAME = 'AbuseFilterSpecsFormatter';
|
||||
|
||||
/** @var MessageLocalizer */
|
||||
private $messageLocalizer;
|
||||
|
||||
/**
|
||||
* @param MessageLocalizer $messageLocalizer
|
||||
*/
|
||||
public function __construct( MessageLocalizer $messageLocalizer ) {
|
||||
$this->messageLocalizer = $messageLocalizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MessageLocalizer $messageLocalizer
|
||||
*/
|
||||
public function setMessageLocalizer( MessageLocalizer $messageLocalizer ) : void {
|
||||
$this->messageLocalizer = $messageLocalizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @return string HTML
|
||||
*/
|
||||
public function getActionDisplay( string $action ) : string {
|
||||
// Give grep a chance to find the usages:
|
||||
// abusefilter-action-tag, abusefilter-action-throttle, abusefilter-action-warn,
|
||||
// abusefilter-action-blockautopromote, abusefilter-action-block, abusefilter-action-degroup,
|
||||
// abusefilter-action-rangeblock, abusefilter-action-disallow
|
||||
$msg = $this->messageLocalizer->msg( "abusefilter-action-$action" );
|
||||
return $msg->isDisabled() ? htmlspecialchars( $action ) : $msg->escaped();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @param string[] $parameters
|
||||
* @param Language $lang
|
||||
* @return string
|
||||
*/
|
||||
public function formatAction( string $action, array $parameters, Language $lang ) : string {
|
||||
if ( count( $parameters ) === 0 || ( $action === 'block' && count( $parameters ) !== 3 ) ) {
|
||||
$displayAction = $this->getActionDisplay( $action );
|
||||
} elseif ( $action === 'block' ) {
|
||||
// Needs to be treated separately since the message is more complex
|
||||
$messages = [
|
||||
$this->messageLocalizer->msg( 'abusefilter-block-anon' )->escaped() .
|
||||
$this->messageLocalizer->msg( 'colon-separator' )->escaped() .
|
||||
$lang->translateBlockExpiry( $parameters[1] ),
|
||||
$this->messageLocalizer->msg( 'abusefilter-block-user' )->escaped() .
|
||||
$this->messageLocalizer->msg( 'colon-separator' )->escaped() .
|
||||
$lang->translateBlockExpiry( $parameters[2] )
|
||||
];
|
||||
if ( $parameters[0] === 'blocktalk' ) {
|
||||
$messages[] = $this->messageLocalizer->msg( 'abusefilter-block-talk' )->escaped();
|
||||
}
|
||||
$displayAction = $lang->commaList( $messages );
|
||||
} elseif ( $action === 'throttle' ) {
|
||||
array_shift( $parameters );
|
||||
list( $actions, $time ) = explode( ',', array_shift( $parameters ) );
|
||||
|
||||
// Join comma-separated groups in a commaList with a final "and", and convert to messages.
|
||||
// Messages used here: abusefilter-throttle-ip, abusefilter-throttle-user,
|
||||
// abusefilter-throttle-site, abusefilter-throttle-creationdate, abusefilter-throttle-editcount
|
||||
// abusefilter-throttle-range, abusefilter-throttle-page, abusefilter-throttle-none
|
||||
foreach ( $parameters as &$val ) {
|
||||
if ( strpos( $val, ',' ) !== false ) {
|
||||
$subGroups = explode( ',', $val );
|
||||
foreach ( $subGroups as &$group ) {
|
||||
$msg = $this->messageLocalizer->msg( "abusefilter-throttle-$group" );
|
||||
// We previously accepted literally everything in this field, so old entries
|
||||
// may have weird stuff.
|
||||
$group = $msg->exists() ? $msg->text() : $group;
|
||||
}
|
||||
unset( $group );
|
||||
$val = $lang->listToText( $subGroups );
|
||||
} else {
|
||||
$msg = $this->messageLocalizer->msg( "abusefilter-throttle-$val" );
|
||||
$val = $msg->exists() ? $msg->text() : $val;
|
||||
}
|
||||
}
|
||||
unset( $val );
|
||||
$groups = $lang->semicolonList( $parameters );
|
||||
|
||||
$displayAction = $this->getActionDisplay( $action ) .
|
||||
$this->messageLocalizer->msg( 'colon-separator' )->escaped() .
|
||||
$this->messageLocalizer->msg( 'abusefilter-throttle-details' )
|
||||
->params( $actions, $time, $groups )->escaped();
|
||||
} else {
|
||||
$displayAction = $this->getActionDisplay( $action ) .
|
||||
$this->messageLocalizer->msg( 'colon-separator' )->escaped() .
|
||||
$lang->semicolonList( array_map( 'htmlspecialchars', $parameters ) );
|
||||
}
|
||||
|
||||
return $displayAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param Language $lang
|
||||
* @return string
|
||||
*/
|
||||
public function formatFlags( string $value, Language $lang ) : string {
|
||||
$flags = array_filter( explode( ',', $value ) );
|
||||
$flagsDisplay = [];
|
||||
foreach ( $flags as $flag ) {
|
||||
$flagsDisplay[] = $this->messageLocalizer->msg( "abusefilter-history-$flag" )->escaped();
|
||||
}
|
||||
|
||||
return $lang->commaList( $flagsDisplay );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives either the user-specified name for a group,
|
||||
* or spits the input back out when the message for the group is disabled
|
||||
* @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups)
|
||||
* @return string A name for that filter group, or the input.
|
||||
*/
|
||||
public function nameGroup( string $group ) : string {
|
||||
// Give grep a chance to find the usages: abusefilter-group-default
|
||||
$msg = $this->messageLocalizer->msg( "abusefilter-group-$group" );
|
||||
return $msg->isDisabled() ? $group : $msg->escaped();
|
||||
}
|
||||
}
|
|
@ -5,7 +5,11 @@ namespace MediaWiki\Extension\AbuseFilter\View;
|
|||
use AbuseFilter;
|
||||
use Diff;
|
||||
use DifferenceEngine;
|
||||
use IContextSource;
|
||||
use Linker;
|
||||
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
|
||||
use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
|
||||
use MediaWiki\Linker\LinkRenderer;
|
||||
use OOUI;
|
||||
use stdClass;
|
||||
use TableDiffFormatterFullContext;
|
||||
|
@ -31,6 +35,31 @@ class AbuseFilterViewDiff extends AbuseFilterView {
|
|||
* @var int|null The ID of the filter
|
||||
*/
|
||||
private $filter;
|
||||
/**
|
||||
* @var SpecsFormatter
|
||||
*/
|
||||
private $specsFormatter;
|
||||
|
||||
/**
|
||||
* @param AbuseFilterPermissionManager $afPermManager
|
||||
* @param SpecsFormatter $specsFormatter
|
||||
* @param IContextSource $context
|
||||
* @param LinkRenderer $linkRenderer
|
||||
* @param string $basePageName
|
||||
* @param array $params
|
||||
*/
|
||||
public function __construct(
|
||||
AbuseFilterPermissionManager $afPermManager,
|
||||
SpecsFormatter $specsFormatter,
|
||||
IContextSource $context,
|
||||
LinkRenderer $linkRenderer,
|
||||
string $basePageName,
|
||||
array $params
|
||||
) {
|
||||
parent::__construct( $afPermManager, $context, $linkRenderer, $basePageName, $params );
|
||||
$this->specsFormatter = $specsFormatter;
|
||||
$this->specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the page
|
||||
|
@ -338,14 +367,14 @@ class AbuseFilterViewDiff extends AbuseFilterView {
|
|||
) {
|
||||
$info .= $this->getDiffRow(
|
||||
'abusefilter-edit-group',
|
||||
AbuseFilter::nameGroup( $oldVersion['info']['group'] ),
|
||||
AbuseFilter::nameGroup( $newVersion['info']['group'] )
|
||||
$this->specsFormatter->nameGroup( $oldVersion['info']['group'] ),
|
||||
$this->specsFormatter->nameGroup( $newVersion['info']['group'] )
|
||||
);
|
||||
}
|
||||
$info .= $this->getDiffRow(
|
||||
'abusefilter-edit-flags',
|
||||
AbuseFilter::formatFlags( $oldVersion['info']['flags'], $this->getLanguage() ),
|
||||
AbuseFilter::formatFlags( $newVersion['info']['flags'], $this->getLanguage() )
|
||||
$this->specsFormatter->formatFlags( $oldVersion['info']['flags'], $this->getLanguage() ),
|
||||
$this->specsFormatter->formatFlags( $newVersion['info']['flags'], $this->getLanguage() )
|
||||
);
|
||||
|
||||
$info .= $this->getDiffRow(
|
||||
|
@ -397,7 +426,7 @@ class AbuseFilterViewDiff extends AbuseFilterView {
|
|||
|
||||
ksort( $actions );
|
||||
foreach ( $actions as $action => $parameters ) {
|
||||
$lines[] = AbuseFilter::formatAction( $action, $parameters, $this->getLanguage() );
|
||||
$lines[] = $this->specsFormatter->formatAction( $action, $parameters, $this->getLanguage() );
|
||||
}
|
||||
|
||||
return $lines;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace MediaWiki\Extension\AbuseFilter\View;
|
||||
|
||||
use AbuseFilter;
|
||||
use BadMethodCallException;
|
||||
use Html;
|
||||
use HtmlArmor;
|
||||
|
@ -20,6 +19,7 @@ use MediaWiki\Extension\AbuseFilter\FilterLookup;
|
|||
use MediaWiki\Extension\AbuseFilter\FilterProfiler;
|
||||
use MediaWiki\Extension\AbuseFilter\FilterStore;
|
||||
use MediaWiki\Extension\AbuseFilter\InvalidImportDataException;
|
||||
use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
|
||||
use MediaWiki\Linker\LinkRenderer;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use MWException;
|
||||
|
@ -57,6 +57,9 @@ class AbuseFilterViewEdit extends AbuseFilterView {
|
|||
/** @var ConsequencesRegistry */
|
||||
private $consequencesRegistry;
|
||||
|
||||
/** @var SpecsFormatter */
|
||||
private $specsFormatter;
|
||||
|
||||
/**
|
||||
* @param PermissionManager $permissionManager
|
||||
* @param AbuseFilterPermissionManager $afPermManager
|
||||
|
@ -66,6 +69,7 @@ class AbuseFilterViewEdit extends AbuseFilterView {
|
|||
* @param FilterStore $filterStore
|
||||
* @param EditBoxBuilderFactory $boxBuilderFactory
|
||||
* @param ConsequencesRegistry $consequencesRegistry
|
||||
* @param SpecsFormatter $specsFormatter
|
||||
* @param IContextSource $context
|
||||
* @param LinkRenderer $linkRenderer
|
||||
* @param string $basePageName
|
||||
|
@ -80,6 +84,7 @@ class AbuseFilterViewEdit extends AbuseFilterView {
|
|||
FilterStore $filterStore,
|
||||
EditBoxBuilderFactory $boxBuilderFactory,
|
||||
ConsequencesRegistry $consequencesRegistry,
|
||||
SpecsFormatter $specsFormatter,
|
||||
IContextSource $context,
|
||||
LinkRenderer $linkRenderer,
|
||||
string $basePageName,
|
||||
|
@ -93,6 +98,8 @@ class AbuseFilterViewEdit extends AbuseFilterView {
|
|||
$this->filterStore = $filterStore;
|
||||
$this->boxBuilderFactory = $boxBuilderFactory;
|
||||
$this->consequencesRegistry = $consequencesRegistry;
|
||||
$this->specsFormatter = $specsFormatter;
|
||||
$this->specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
$this->filter = $this->mParams['filter'];
|
||||
$this->historyID = $this->mParams['history'] ?? null;
|
||||
}
|
||||
|
@ -321,7 +328,7 @@ class AbuseFilterViewEdit extends AbuseFilterView {
|
|||
|
||||
$options = [];
|
||||
foreach ( $validGroups as $group ) {
|
||||
$options += [ AbuseFilter::nameGroup( $group ) => $group ];
|
||||
$options += [ $this->specsFormatter->nameGroup( $group ) => $group ];
|
||||
}
|
||||
|
||||
$options = Xml::listDropDownOptionsOoui( $options );
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace MediaWiki\Extension\AbuseFilter\View;
|
||||
|
||||
use AbuseFilter;
|
||||
use HTMLForm;
|
||||
use IContextSource;
|
||||
use Linker;
|
||||
|
@ -11,6 +10,7 @@ use MediaWiki\Block\DatabaseBlock;
|
|||
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
|
||||
use MediaWiki\Extension\AbuseFilter\BlockAutopromoteStore;
|
||||
use MediaWiki\Extension\AbuseFilter\FilterUser;
|
||||
use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
|
||||
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
|
||||
use MediaWiki\Linker\LinkRenderer;
|
||||
use MediaWiki\User\UserGroupManager;
|
||||
|
@ -63,12 +63,18 @@ class AbuseFilterViewRevert extends AbuseFilterView {
|
|||
*/
|
||||
private $varBlobStore;
|
||||
|
||||
/**
|
||||
* @var SpecsFormatter
|
||||
*/
|
||||
private $specsFormatter;
|
||||
|
||||
/**
|
||||
* @param UserGroupManager $userGroupManager
|
||||
* @param AbuseFilterPermissionManager $afPermManager
|
||||
* @param BlockAutopromoteStore $blockAutopromoteStore
|
||||
* @param FilterUser $filterUser
|
||||
* @param VariablesBlobStore $varBlobStore
|
||||
* @param SpecsFormatter $specsFormatter
|
||||
* @param IContextSource $context
|
||||
* @param LinkRenderer $linkRenderer
|
||||
* @param string $basePageName
|
||||
|
@ -80,6 +86,7 @@ class AbuseFilterViewRevert extends AbuseFilterView {
|
|||
BlockAutopromoteStore $blockAutopromoteStore,
|
||||
FilterUser $filterUser,
|
||||
VariablesBlobStore $varBlobStore,
|
||||
SpecsFormatter $specsFormatter,
|
||||
IContextSource $context,
|
||||
LinkRenderer $linkRenderer,
|
||||
string $basePageName,
|
||||
|
@ -90,6 +97,8 @@ class AbuseFilterViewRevert extends AbuseFilterView {
|
|||
$this->blockAutopromoteStore = $blockAutopromoteStore;
|
||||
$this->filterUser = $filterUser;
|
||||
$this->varBlobStore = $varBlobStore;
|
||||
$this->specsFormatter = $specsFormatter;
|
||||
$this->specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,11 +195,10 @@ class AbuseFilterViewRevert extends AbuseFilterView {
|
|||
$dateForm->addPostText( $this->msg( 'abusefilter-revert-preview-intro' )->parseAsBlock() );
|
||||
$list = [];
|
||||
|
||||
$context = $this->getContext();
|
||||
foreach ( $results as $result ) {
|
||||
$displayActions = [];
|
||||
foreach ( $result['actions'] as $action ) {
|
||||
$displayActions[] = AbuseFilter::getActionDisplay( $action, $context );
|
||||
$displayActions[] = $this->specsFormatter->getActionDisplay( $action );
|
||||
}
|
||||
|
||||
$msg = $this->msg( 'abusefilter-revert-preview-item' )
|
||||
|
|
|
@ -10,6 +10,7 @@ use MediaWiki\Extension\AbuseFilter\FilterProfiler;
|
|||
use MediaWiki\Extension\AbuseFilter\FilterStore;
|
||||
use MediaWiki\Extension\AbuseFilter\FilterUser;
|
||||
use MediaWiki\Extension\AbuseFilter\Parser\ParserFactory as AfParserFactory;
|
||||
use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
|
||||
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
|
||||
use MediaWiki\Extension\AbuseFilter\View\AbuseFilterView;
|
||||
use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewDiff;
|
||||
|
@ -35,6 +36,7 @@ class SpecialAbuseFilter extends AbuseFilterSpecialPage {
|
|||
private const SERVICES_PER_VIEW = [
|
||||
AbuseFilterViewDiff::class => [
|
||||
AbuseFilterPermissionManager::SERVICE_NAME,
|
||||
SpecsFormatter::SERVICE_NAME,
|
||||
],
|
||||
AbuseFilterViewEdit::class => [
|
||||
'PermissionManager',
|
||||
|
@ -45,6 +47,7 @@ class SpecialAbuseFilter extends AbuseFilterSpecialPage {
|
|||
FilterStore::SERVICE_NAME,
|
||||
EditBoxBuilderFactory::SERVICE_NAME,
|
||||
ConsequencesRegistry::SERVICE_NAME,
|
||||
SpecsFormatter::SERVICE_NAME,
|
||||
],
|
||||
AbuseFilterViewExamine::class => [
|
||||
'RevisionLookup',
|
||||
|
@ -70,6 +73,7 @@ class SpecialAbuseFilter extends AbuseFilterSpecialPage {
|
|||
BlockAutopromoteStore::SERVICE_NAME,
|
||||
FilterUser::SERVICE_NAME,
|
||||
VariablesBlobStore::SERVICE_NAME,
|
||||
SpecsFormatter::SERVICE_NAME,
|
||||
],
|
||||
AbuseFilterViewTestBatch::class => [
|
||||
AbuseFilterPermissionManager::SERVICE_NAME,
|
||||
|
|
|
@ -6,6 +6,7 @@ use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
|
|||
use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesRegistry;
|
||||
use MediaWiki\Extension\AbuseFilter\GlobalNameUtils;
|
||||
use MediaWiki\Extension\AbuseFilter\Pager\AbuseLogPager;
|
||||
use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
|
||||
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
|
||||
use MediaWiki\Extension\AbuseFilter\View\HideAbuseLog;
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
|
@ -82,19 +83,24 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage {
|
|||
/** @var VariablesBlobStore */
|
||||
private $varBlobStore;
|
||||
|
||||
/** @var SpecsFormatter */
|
||||
private $specsFormatter;
|
||||
|
||||
/**
|
||||
* @param LinkBatchFactory $linkBatchFactory
|
||||
* @param PermissionManager $permissionManager
|
||||
* @param AbuseFilterPermissionManager $afPermissionManager
|
||||
* @param ConsequencesRegistry $consequencesRegistry
|
||||
* @param VariablesBlobStore $varBlobStore
|
||||
* @param SpecsFormatter $specsFormatter
|
||||
*/
|
||||
public function __construct(
|
||||
LinkBatchFactory $linkBatchFactory,
|
||||
PermissionManager $permissionManager,
|
||||
AbuseFilterPermissionManager $afPermissionManager,
|
||||
ConsequencesRegistry $consequencesRegistry,
|
||||
VariablesBlobStore $varBlobStore
|
||||
VariablesBlobStore $varBlobStore,
|
||||
SpecsFormatter $specsFormatter
|
||||
) {
|
||||
parent::__construct( 'AbuseLog', 'abusefilter-log' );
|
||||
$this->linkBatchFactory = $linkBatchFactory;
|
||||
|
@ -102,6 +108,8 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage {
|
|||
$this->afPermissionManager = $afPermissionManager;
|
||||
$this->consequencesRegistry = $consequencesRegistry;
|
||||
$this->varBlobStore = $varBlobStore;
|
||||
$this->specsFormatter = $specsFormatter;
|
||||
$this->specsFormatter->setMessageLocalizer( $this->getContext() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -274,9 +282,8 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage {
|
|||
'default' => 'any',
|
||||
];
|
||||
$options = [];
|
||||
$context = $this->getContext();
|
||||
foreach ( $this->consequencesRegistry->getAllActionNames() as $action ) {
|
||||
$key = AbuseFilter::getActionDisplay( $action, $context );
|
||||
$key = $this->specsFormatter->getActionDisplay( $action );
|
||||
$options[$key] = $action;
|
||||
}
|
||||
ksort( $options );
|
||||
|
|
176
tests/phpunit/unit/AbuseFilterSpecsFormatterTest.php
Normal file
176
tests/phpunit/unit/AbuseFilterSpecsFormatterTest.php
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\Extension\AbuseFilter\SpecsFormatter;
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \MediaWiki\Extension\AbuseFilter\SpecsFormatter
|
||||
*/
|
||||
class AbuseFilterSpecsFormatterTest extends MediaWikiUnitTestCase {
|
||||
/**
|
||||
* @param bool $msgDisabled Should the message be disabled?
|
||||
* @return SpecsFormatter
|
||||
*/
|
||||
private function getFormatter( bool $msgDisabled = false ) : SpecsFormatter {
|
||||
$localizer = $this->createMock( MessageLocalizer::class );
|
||||
$localizer->method( 'msg' )->willReturnCallback( function ( $k, $p = [] ) use ( $msgDisabled ) {
|
||||
if ( $k === 'abusefilter-throttle-details' ) {
|
||||
// Special case
|
||||
$msg = $this->createMock( Message::class );
|
||||
$msg->method( 'params' )->willReturnCallback( function ( ...$p ) use ( $k ) {
|
||||
$text = implode( '|', array_merge( [ $k ], $p ) );
|
||||
return $this->getMockMessage( $text, [] );
|
||||
} );
|
||||
return $msg;
|
||||
}
|
||||
$msg = $this->getMockMessage( $k, $p );
|
||||
$msg->method( 'isDisabled' )->willReturn( $msgDisabled );
|
||||
return $msg;
|
||||
} );
|
||||
return new SpecsFormatter( $localizer );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::__construct
|
||||
*/
|
||||
public function testConstruct() {
|
||||
$this->assertInstanceOf(
|
||||
SpecsFormatter::class,
|
||||
new SpecsFormatter( $this->createMock( MessageLocalizer::class ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::setMessageLocalizer
|
||||
*/
|
||||
public function testSetMessageLocalizer() {
|
||||
$formatter = $this->getFormatter();
|
||||
$ml = $this->createMock( MessageLocalizer::class );
|
||||
$formatter->setMessageLocalizer( $ml );
|
||||
$this->assertSame( $ml, TestingAccessWrapper::newFromObject( $formatter )->messageLocalizer );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @param bool $msgDisabled
|
||||
* @param string $expected
|
||||
* @dataProvider provideActionDisplay
|
||||
* @covers ::getActionDisplay
|
||||
*/
|
||||
public function testGetActionDisplay( string $action, bool $msgDisabled, string $expected ) {
|
||||
$formatter = $this->getFormatter( $msgDisabled );
|
||||
$this->assertSame( $expected, $formatter->getActionDisplay( $action ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function provideActionDisplay() : array {
|
||||
return [
|
||||
'exists' => [ 'foobar', false, 'abusefilter-action-foobar' ],
|
||||
'does not exist' => [ 'foobar', true, 'foobar' ],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Language
|
||||
*/
|
||||
private function getMockLanguage() : Language {
|
||||
$lang = $this->createMock( Language::class );
|
||||
$lang->method( 'translateBlockExpiry' )->willReturnCallback( function ( $x ) {
|
||||
return "expiry-$x";
|
||||
} );
|
||||
$lang->method( 'commaList' )->willReturnCallback( function ( $x ) {
|
||||
return implode( ',', $x );
|
||||
} );
|
||||
$lang->method( 'listToText' )->willReturnCallback( function ( $x ) {
|
||||
return implode( ',', $x );
|
||||
} );
|
||||
$lang->method( 'semicolonList' )->willReturnCallback( function ( $x ) {
|
||||
return implode( ';', $x );
|
||||
} );
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @param array $params
|
||||
* @param string $expected
|
||||
* @dataProvider provideFormatAction
|
||||
* @covers ::formatAction
|
||||
*/
|
||||
public function testFormatAction( string $action, array $params, string $expected ) {
|
||||
$formatter = $this->getFormatter();
|
||||
$lang = $this->getMockLanguage();
|
||||
$this->assertSame( $expected, $formatter->formatAction( $action, $params, $lang ) );
|
||||
}
|
||||
|
||||
public function provideFormatAction() {
|
||||
yield 'no params' => [ 'foobar', [], 'abusefilter-action-foobar' ];
|
||||
yield 'legacy block' => [ 'block', [], 'abusefilter-action-block' ];
|
||||
|
||||
$colon = 'colon-separator';
|
||||
$baseBlock = "abusefilter-block-anon{$colon}expiry-1 day,abusefilter-block-user{$colon}expiry-1 week";
|
||||
yield 'new block, no talk' => [ 'block', [ 'noTalkBlockSet', '1 day', '1 week' ], $baseBlock ];
|
||||
yield 'new block, with talk' => [
|
||||
'block',
|
||||
[ 'blocktalk', '1 day', '1 week' ],
|
||||
"$baseBlock,abusefilter-block-talk"
|
||||
];
|
||||
yield 'throttle' => [
|
||||
'throttle',
|
||||
[ 'ignored', '42,163', 'ip,user', 'site' ],
|
||||
"abusefilter-action-throttle{$colon}abusefilter-throttle-details|42|163|" .
|
||||
'abusefilter-throttle-ip,abusefilter-throttle-user;abusefilter-throttle-site'
|
||||
];
|
||||
yield 'generic parametrized' => [ 'myaction', [ 'foo', 'bar' ], "abusefilter-action-myaction{$colon}foo;bar" ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $flags
|
||||
* @param string $expected
|
||||
* @dataProvider provideFlags
|
||||
* @covers ::formatFlags
|
||||
*/
|
||||
public function testFormatFlags( string $flags, string $expected ) {
|
||||
$formatter = $this->getFormatter();
|
||||
$lang = $this->createMock( Language::class );
|
||||
$lang->method( 'commaList' )->willReturnCallback( function ( $x ) {
|
||||
return implode( ',', $x );
|
||||
} );
|
||||
$this->assertSame( $expected, $formatter->formatFlags( $flags, $lang ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function provideFlags() : array {
|
||||
return [
|
||||
'empty' => [ '', '' ],
|
||||
'single' => [ 'foo', 'abusefilter-history-foo' ],
|
||||
'multiple' => [ 'foo,bar,baz', 'abusefilter-history-foo,abusefilter-history-bar,abusefilter-history-baz' ]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
* @param bool $msgDisabled
|
||||
* @param string $expected
|
||||
* @dataProvider provideGroup
|
||||
* @covers ::nameGroup
|
||||
*/
|
||||
public function testNameGroup( string $group, bool $msgDisabled, string $expected ) {
|
||||
$formatter = $this->getFormatter( $msgDisabled );
|
||||
$this->assertSame( $expected, $formatter->nameGroup( $group ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function provideGroup() : array {
|
||||
return [
|
||||
'exists' => [ 'foobar', false, 'abusefilter-group-foobar' ],
|
||||
'does not exist' => [ 'foobar', true, 'foobar' ],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue