getOutput();
$request = $this->getRequest();
// Status info...
$this->showStatus();
$out->addWikiMsg( 'abusefilter-intro' );
// New filter button
if ( $this->canEdit() ) {
$out->enableOOUI();
$link = new OOUI\ButtonWidget( [
'label' => $this->msg( 'abusefilter-new' )->text(),
'href' => $this->getTitle( 'new' )->getFullURL(),
] );
$out->addHTML( $link );
}
// Options.
$conds = [];
$deleted = $request->getVal( 'deletedfilters' );
$hidedisabled = $request->getBool( 'hidedisabled' );
$defaultscope = 'all';
if ( isset( $wgAbuseFilterCentralDB ) && !$wgAbuseFilterIsCentral ) {
// Show on remote wikis as default only local filters
$defaultscope = 'local';
}
$scope = $request->getVal( 'rulescope', $defaultscope );
$searchEnabled = $this->canViewPrivate() && !( isset( $wgAbuseFilterCentralDB ) &&
!$wgAbuseFilterIsCentral && $scope == 'global' );
if ( $searchEnabled ) {
$querypattern = $request->getVal( 'querypattern' );
$searchmode = $request->getVal( 'searchoption', 'LIKE' );
} else {
$querypattern = '';
$searchmode = '';
}
if ( $deleted == 'show' ) {
# Nothing
} elseif ( $deleted == 'only' ) {
$conds['af_deleted'] = 1;
} else { # hide, or anything else.
$conds['af_deleted'] = 0;
$deleted = 'hide';
}
if ( $hidedisabled ) {
$conds['af_deleted'] = 0;
$conds['af_enabled'] = 1;
}
if ( $scope == 'local' ) {
$conds['af_global'] = 0;
} 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();
if ( $validreg === false ) {
$out->wrapWikiMsg(
'
$1
',
'abusefilter-list-regexerror'
);
$this->showList(
[ 'af_deleted' => 0 ],
compact( 'deleted', 'hidedisabled', '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()
);
}
}
$this->showList(
$conds,
compact( 'deleted', 'hidedisabled', 'querypattern', 'searchmode', 'scope', 'searchEnabled' )
);
}
function showList( $conds = [ 'af_deleted' => 0 ], $optarray = [] ) {
global $wgAbuseFilterCentralDB, $wgAbuseFilterIsCentral;
$this->getOutput()->addHTML(
Xml::element( 'h2', null, $this->msg( 'abusefilter-list' )->parse() )
);
$deleted = $optarray['deleted'];
$hidedisabled = $optarray['hidedisabled'];
$scope = $optarray['scope'];
$searchEnabled = $optarray['searchEnabled'];
$querypattern = $optarray['querypattern'];
$searchmode = $optarray['searchmode'];
if ( isset( $wgAbuseFilterCentralDB ) && !$wgAbuseFilterIsCentral && $scope == 'global' ) {
$pager = new GlobalAbuseFilterPager(
$this,
$conds,
$this->linkRenderer
);
} else {
$pager = new AbuseFilterPager(
$this,
$conds,
$this->linkRenderer,
[ $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 ( isset( $wgAbuseFilterCentralDB ) ) {
$optionsMsg = [
'abusefilter-list-options-scope-local' => 'local',
'abusefilter-list-options-scope-global' => 'global',
];
if ( $wgAbuseFilterIsCentral ) {
// For central wiki: add third scope option
$optionsMsg['abusefilter-list-options-scope-all'] = 'all';
}
$formDescriptor['rulescope'] = [
'name' => 'rulescope',
'type' => 'radio',
'flatlist' => true,
'label-message' => 'abusefilter-list-options-scope',
'options-messages' => $optionsMsg,
'default' => $scope,
];
}
$formDescriptor['info'] = [
'type' => 'info',
'default' => $this->msg( 'abusefilter-list-options-disabled' )->parse(),
];
$formDescriptor['hidedisabled'] = [
'name' => 'hidedisabled',
'type' => 'check',
'label-message' => 'abusefilter-list-options-hidedisabled',
'selected' => $hidedisabled,
];
// ToDo: Since this is only for saving space, we should convert it
// to use a 'hide-if'
if ( $searchEnabled ) {
$formDescriptor['querypattern'] = [
'name' => 'querypattern',
'type' => 'text',
'label-message' => 'abusefilter-list-options-searchfield',
'placeholder' => $this->msg( 'abusefilter-list-options-searchpattern' )->text(),
'default' => $querypattern
];
$formDescriptor['searchoption'] = [
'name' => 'searchoption',
'type' => 'radio',
'flatlist' => true,
'label-message' => 'abusefilter-list-options-searchoptions',
'options-messages' => [
'abusefilter-list-options-search-like' => 'LIKE',
'abusefilter-list-options-search-rlike' => 'RLIKE',
'abusefilter-list-options-search-irlike' => 'IRLIKE',
],
'default' => $searchmode
];
}
$formDescriptor['limit'] = [
'name' => 'limit',
'type' => 'select',
'label-message' => 'abusefilter-list-limit',
'options' => $pager->getLimitSelectList(),
'default' => $pager->getLimit(),
];
HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
->addHiddenField( 'title', $this->getTitle()->getPrefixedDBkey() )
->setAction( $this->getTitle()->getFullURL() )
->setWrapperLegendMsg( 'abusefilter-list-options' )
->setSubmitTextMsg( 'abusefilter-list-options-submit' )
->setMethod( 'get' )
->prepareForm()
->displayForm( false );
$output =
$pager->getNavigationBar() .
$pager->getBody() .
$pager->getNavigationBar();
$this->getOutput()->addHTML( $output );
}
function showStatus() {
global $wgAbuseFilterConditionLimit, $wgAbuseFilterValidGroups;
$stash = ObjectCache::getMainStashInstance();
$overflow_count = (int)$stash->get( AbuseFilter::filterLimitReachedKey() );
$match_count = (int)$stash->get( AbuseFilter::filterMatchesKey() );
$total_count = 0;
foreach ( $wgAbuseFilterValidGroups as $group ) {
$total_count += (int)$stash->get( AbuseFilter::filterUsedKey( $group ) );
}
if ( $total_count > 0 ) {
$overflow_percent = sprintf( "%.2f", 100 * $overflow_count / $total_count );
$match_percent = sprintf( "%.2f", 100 * $match_count / $total_count );
$status = $this->msg( 'abusefilter-status' )
->numParams(
$total_count,
$overflow_count,
$overflow_percent,
$wgAbuseFilterConditionLimit,
$match_count,
$match_percent
)->parse();
$status = Xml::tags( 'div', [ 'class' => 'mw-abusefilter-status' ], $status );
$this->getOutput()->addHTML( $status );
}
}
}