summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'AbuseFilter/includes/Views/AbuseFilterViewList.php')
-rw-r--r--AbuseFilter/includes/Views/AbuseFilterViewList.php199
1 files changed, 96 insertions, 103 deletions
diff --git a/AbuseFilter/includes/Views/AbuseFilterViewList.php b/AbuseFilter/includes/Views/AbuseFilterViewList.php
index ad92ad6c..efbf6217 100644
--- a/AbuseFilter/includes/Views/AbuseFilterViewList.php
+++ b/AbuseFilter/includes/Views/AbuseFilterViewList.php
@@ -1,5 +1,7 @@
<?php
+use MediaWiki\MediaWikiServices;
+
/**
* The default view used in Special:AbuseFilter
*/
@@ -11,6 +13,7 @@ class AbuseFilterViewList extends AbuseFilterView {
$out = $this->getOutput();
$request = $this->getRequest();
$config = $this->getConfig();
+ $user = $this->getUser();
// Show filter performance statistics
$this->showStatus();
@@ -18,18 +21,27 @@ class AbuseFilterViewList extends AbuseFilterView {
$out->addWikiMsg( 'abusefilter-intro' );
// New filter button
- if ( $this->canEdit() ) {
+ if ( AbuseFilter::canEdit( $user ) ) {
$out->enableOOUI();
- $link = new OOUI\ButtonWidget( [
- 'label' => $this->msg( 'abusefilter-new' )->text(),
- 'href' => $this->getTitle( 'new' )->getFullURL(),
+ $buttons = new OOUI\HorizontalLayout( [
+ 'items' => [
+ new OOUI\ButtonWidget( [
+ 'label' => $this->msg( 'abusefilter-new' )->text(),
+ 'href' => $this->getTitle( 'new' )->getFullURL(),
+ ] ),
+ new OOUI\ButtonWidget( [
+ 'label' => $this->msg( 'abusefilter-import-button' )->text(),
+ 'href' => $this->getTitle( 'import' )->getFullURL(),
+ ] )
+ ]
] );
- $out->addHTML( $link );
+ $out->addHTML( $buttons );
}
$conds = [];
$deleted = $request->getVal( 'deletedfilters' );
$furtherOptions = $request->getArray( 'furtheroptions', [] );
+ '@phan-var array $furtherOptions';
// Backward compatibility with old links
if ( $request->getBool( 'hidedisabled' ) ) {
$furtherOptions[] = 'hidedisabled';
@@ -45,22 +57,22 @@ class AbuseFilterViewList extends AbuseFilterView {
}
$scope = $request->getVal( 'rulescope', $defaultscope );
- $searchEnabled = $this->canViewPrivate() && !(
+ $searchEnabled = AbuseFilter::canViewPrivate( $user ) && !(
$config->get( 'AbuseFilterCentralDB' ) !== null &&
!$config->get( 'AbuseFilterIsCentral' ) &&
- $scope == 'global' );
+ $scope === 'global' );
if ( $searchEnabled ) {
- $querypattern = $request->getVal( 'querypattern' );
+ $querypattern = $request->getVal( 'querypattern', '' );
$searchmode = $request->getVal( 'searchoption', 'LIKE' );
} else {
$querypattern = '';
$searchmode = '';
}
- if ( $deleted == 'show' ) {
+ if ( $deleted === 'show' ) {
// Nothing
- } elseif ( $deleted == 'only' ) {
+ } elseif ( $deleted === 'only' ) {
$conds['af_deleted'] = 1;
} else {
// hide, or anything else.
@@ -75,79 +87,57 @@ class AbuseFilterViewList extends AbuseFilterView {
$conds['af_hidden'] = 0;
}
- if ( $scope == 'local' ) {
+ if ( $scope === 'local' ) {
$conds['af_global'] = 0;
- } elseif ( $scope == 'global' ) {
+ } elseif ( $scope === 'global' ) {
$conds['af_global'] = 1;
}
- $dbr = wfGetDB( DB_REPLICA );
-
if ( $querypattern !== '' ) {
- if ( $searchmode !== 'LIKE' ) {
- // Check regex pattern validity
- Wikimedia\suppressWarnings();
- $validreg = preg_match( '/' . $querypattern . '/', null );
- Wikimedia\restoreWarnings();
+ // Check the search pattern. Filtering the results is done in AbuseFilterPager
+ $error = null;
+ if ( !in_array( $searchmode, [ 'LIKE', 'RLIKE', 'IRLIKE' ] ) ) {
+ $error = 'abusefilter-list-invalid-searchmode';
+ } elseif ( $searchmode !== 'LIKE' && !StringUtils::isValidPCRERegex( "/$querypattern/" ) ) {
+ $error = 'abusefilter-list-regexerror';
+ }
- if ( $validreg === false ) {
- $out->addHTML(
- Xml::tags(
- 'p',
- null,
- Html::errorBox( $this->msg( 'abusefilter-list-regexerror' )->parse() )
- )
- );
- $this->showList(
- [ 'af_deleted' => 0 ],
- compact(
- 'deleted',
- 'furtherOptions',
- 'querypattern',
- 'searchmode',
- 'scope',
- 'searchEnabled'
- )
- );
- return;
- }
- if ( $searchmode === 'RLIKE' ) {
- $conds[] = 'af_pattern RLIKE ' .
- $dbr->addQuotes( $querypattern );
- } else {
- $conds[] = 'LOWER( CAST( af_pattern AS char ) ) RLIKE ' .
- strtolower( $dbr->addQuotes( $querypattern ) );
- }
- } else {
- // Build like query escaping tokens and encapsulating in % to search everywhere
- $conds[] = 'LOWER( CAST( af_pattern AS char ) ) ' .
- $dbr->buildLike(
- $dbr->anyString(),
- strtolower( $querypattern ),
- $dbr->anyString()
- );
+ if ( $error !== null ) {
+ $out->addHTML(
+ Xml::tags(
+ 'p',
+ null,
+ Html::errorBox( $this->msg( $error )->escaped() )
+ )
+ );
+
+ // Reset the conditions in case of error
+ $conds = [ 'af_deleted' => 0 ];
+ $querypattern = '';
}
}
$this->showList(
- $conds,
compact(
'deleted',
'furtherOptions',
'querypattern',
'searchmode',
- 'scope',
- 'searchEnabled'
- )
+ 'scope'
+ ),
+ $conds
);
}
/**
- * @param array $conds
* @param array $optarray
+ * @param array $conds
*/
- public function showList( $conds = [ 'af_deleted' => 0 ], $optarray = [] ) {
+ private function showList( array $optarray, array $conds = [ 'af_deleted' => 0 ] ) {
+ $user = $this->getUser();
$config = $this->getConfig();
+ $centralDB = $config->get( 'AbuseFilterCentralDB' );
+ $dbIsCentral = $config->get( 'AbuseFilterIsCentral' );
$this->getOutput()->addHTML(
Xml::tags( 'h2', null, $this->msg( 'abusefilter-list' )->parse() )
);
@@ -155,15 +145,10 @@ class AbuseFilterViewList extends AbuseFilterView {
$deleted = $optarray['deleted'];
$furtherOptions = $optarray['furtherOptions'];
$scope = $optarray['scope'];
- $searchEnabled = $optarray['searchEnabled'];
$querypattern = $optarray['querypattern'];
$searchmode = $optarray['searchmode'];
- if (
- $config->get( 'AbuseFilterCentralDB' ) !== null
- && !$config->get( 'AbuseFilterIsCentral' )
- && $scope == 'global'
- ) {
+ if ( $centralDB !== null && !$dbIsCentral && $scope === 'global' ) {
$pager = new GlobalAbuseFilterPager(
$this,
$conds,
@@ -174,31 +159,20 @@ class AbuseFilterViewList extends AbuseFilterView {
$this,
$conds,
$this->linkRenderer,
- [ $querypattern, $searchmode ]
+ $querypattern,
+ $searchmode
);
}
// Options form
$formDescriptor = [];
- $formDescriptor['deletedfilters'] = [
- 'name' => 'deletedfilters',
- 'type' => 'radio',
- 'flatlist' => true,
- 'label-message' => 'abusefilter-list-options-deleted',
- 'options-messages' => [
- 'abusefilter-list-options-deleted-show' => 'show',
- 'abusefilter-list-options-deleted-hide' => 'hide',
- 'abusefilter-list-options-deleted-only' => 'only',
- ],
- 'default' => $deleted,
- ];
- if ( $config->get( 'AbuseFilterCentralDB' ) !== null ) {
+ if ( $centralDB !== null ) {
$optionsMsg = [
'abusefilter-list-options-scope-local' => 'local',
'abusefilter-list-options-scope-global' => 'global',
];
- if ( $config->get( 'AbuseFilterIsCentral' ) ) {
+ if ( $dbIsCentral ) {
// For central wiki: add third scope option
$optionsMsg['abusefilter-list-options-scope-all'] = 'all';
}
@@ -212,6 +186,19 @@ class AbuseFilterViewList extends AbuseFilterView {
];
}
+ $formDescriptor['deletedfilters'] = [
+ 'name' => 'deletedfilters',
+ 'type' => 'radio',
+ 'flatlist' => true,
+ 'label-message' => 'abusefilter-list-options-deleted',
+ 'options-messages' => [
+ 'abusefilter-list-options-deleted-show' => 'show',
+ 'abusefilter-list-options-deleted-hide' => 'hide',
+ 'abusefilter-list-options-deleted-only' => 'only',
+ ],
+ 'default' => $deleted,
+ ];
+
$formDescriptor['furtheroptions'] = [
'name' => 'furtheroptions',
'type' => 'multiselect',
@@ -224,11 +211,12 @@ class AbuseFilterViewList extends AbuseFilterView {
'default' => $furtherOptions
];
- // ToDo: Since this is only for saving space, we should convert it to use a 'hide-if'
- if ( $searchEnabled ) {
+ if ( AbuseFilter::canViewPrivate( $user ) ) {
+ $globalEnabled = $centralDB !== null && !$dbIsCentral;
$formDescriptor['querypattern'] = [
'name' => 'querypattern',
'type' => 'text',
+ 'hide-if' => $globalEnabled ? [ '===', 'rulescope', 'global' ] : [],
'label-message' => 'abusefilter-list-options-searchfield',
'placeholder' => $this->msg( 'abusefilter-list-options-searchpattern' )->text(),
'default' => $querypattern
@@ -239,6 +227,9 @@ class AbuseFilterViewList extends AbuseFilterView {
'type' => 'radio',
'flatlist' => true,
'label-message' => 'abusefilter-list-options-searchoptions',
+ 'hide-if' => $globalEnabled ?
+ [ 'OR', [ '===', 'querypattern', '' ], $formDescriptor['querypattern']['hide-if'] ] :
+ [ '===', 'querypattern', '' ],
'options-messages' => [
'abusefilter-list-options-search-like' => 'LIKE',
'abusefilter-list-options-search-rlike' => 'RLIKE',
@@ -265,37 +256,39 @@ class AbuseFilterViewList extends AbuseFilterView {
->prepareForm()
->displayForm( false );
- $this->getOutput()->addHTML(
- $pager->getNavigationBar() .
- $pager->getBody() .
- $pager->getNavigationBar()
- );
+ $this->getOutput()->addParserOutputContent( $pager->getFullOutput() );
}
/**
- * Show stats
+ * Generates a summary of filter activity using the internal statistics.
*/
public function showStatus() {
- $stash = ObjectCache::getMainStashInstance();
- $overflow_count = (int)$stash->get( AbuseFilter::filterLimitReachedKey() );
- $match_count = (int)$stash->get( AbuseFilter::filterMatchesKey() );
- $total_count = 0;
+ $stash = MediaWikiServices::getInstance()->getMainObjectStash();
+
+ $totalCount = 0;
+ $matchCount = 0;
+ $overflowCount = 0;
foreach ( $this->getConfig()->get( 'AbuseFilterValidGroups' ) as $group ) {
- $total_count += (int)$stash->get( AbuseFilter::filterUsedKey( $group ) );
+ $profile = $stash->get( AbuseFilter::filterProfileGroupKey( $group ) );
+ if ( $profile !== false ) {
+ $totalCount += $profile[ 'total' ];
+ $overflowCount += $profile[ 'overflow' ];
+ $matchCount += $profile[ 'matches' ];
+ }
}
- if ( $total_count > 0 ) {
- $overflow_percent = sprintf( "%.2f", 100 * $overflow_count / $total_count );
- $match_percent = sprintf( "%.2f", 100 * $match_count / $total_count );
+ if ( $totalCount > 0 ) {
+ $overflowPercent = round( 100 * $overflowCount / $totalCount, 2 );
+ $matchPercent = round( 100 * $matchCount / $totalCount, 2 );
$status = $this->msg( 'abusefilter-status' )
->numParams(
- $total_count,
- $overflow_count,
- $overflow_percent,
+ $totalCount,
+ $overflowCount,
+ $overflowPercent,
$this->getConfig()->get( 'AbuseFilterConditionLimit' ),
- $match_count,
- $match_percent
+ $matchCount,
+ $matchPercent
)->parse();
$status = Xml::tags( 'div', [ 'class' => 'mw-abusefilter-status' ], $status );