mediawiki-extensions-AbuseF.../includes/Views/AbuseFilterViewTestBatch.php
Matěj Suchánek efaae31263 Improve queries for testing on recent changes
- Use rc_source with values that we know we support. In
  particular, this drops categorization changes.
- Filter on rc_log_type and rc_log_action (which itself
  may be shared across types).
- Use the same query on both Special:AbuseFilter/test
  and Special:AbuseFilter/examine.

Bug: T170574
Change-Id: I79b903b4424d3c15095a1e0491d35f6e005db0b8
2017-08-20 14:00:39 +02:00

191 lines
5.2 KiB
PHP

<?php
class AbuseFilterViewTestBatch extends AbuseFilterView {
// Hard-coded for now.
protected static $mChangeLimit = 100;
public $mShowNegative, $mTestPeriodStart, $mTestPeriodEnd, $mTestPage,
$mTestUser;
function show() {
$out = $this->getOutput();
AbuseFilter::disableConditionLimit();
if ( !$this->getUser()->isAllowed( 'abusefilter-modify' ) ) {
$out->addWikiMsg( 'abusefilter-mustbeeditor' );
return;
}
$this->loadParameters();
$out->setPageTitle( $this->msg( 'abusefilter-test' ) );
$out->addWikiMsg( 'abusefilter-test-intro', self::$mChangeLimit );
$output = '';
$output .= AbuseFilter::buildEditBox( $this->mFilter, 'wpTestFilter' ) . "\n";
$output .=
Xml::inputLabel(
$this->msg( 'abusefilter-test-load-filter' )->text(),
'wpInsertFilter',
'mw-abusefilter-load-filter',
10,
''
) .
'&#160;' .
Xml::element(
'input',
[
'type' => 'button',
'value' => $this->msg( 'abusefilter-test-load' )->text(),
'id' => 'mw-abusefilter-load'
]
);
$output = Xml::tags( 'div', [ 'id' => 'mw-abusefilter-test-editor' ], $output );
$output .= Xml::tags( 'p', null, Xml::checkLabel(
$this->msg( 'abusefilter-test-shownegative' )->text(),
'wpShowNegative', 'wpShowNegative', $this->mShowNegative )
);
// Selectory stuff
$selectFields = [];
$selectFields['abusefilter-test-user'] = Xml::input( 'wpTestUser', 45, $this->mTestUser );
$selectFields['abusefilter-test-period-start'] =
Xml::input( 'wpTestPeriodStart', 45, $this->mTestPeriodStart );
$selectFields['abusefilter-test-period-end'] =
Xml::input( 'wpTestPeriodEnd', 45, $this->mTestPeriodEnd );
$selectFields['abusefilter-test-page'] =
Xml::input( 'wpTestPage', 45, $this->mTestPage );
$output .= Xml::buildForm( $selectFields, 'abusefilter-test-submit' );
$output .= Html::hidden( 'title', $this->getTitle( 'test' )->getPrefixedDBkey() );
$output = Xml::tags( 'form',
[
'action' => $this->getTitle( 'test' )->getLocalURL(),
'method' => 'post'
],
$output
);
$output = Xml::fieldset( $this->msg( 'abusefilter-test-legend' )->text(), $output );
$out->addHTML( $output );
if ( $this->getRequest()->wasPosted() ) {
$this->doTest();
}
}
/**
* @fixme this is similar to AbuseFilterExaminePager::getQueryInfo
*/
function doTest() {
// Quick syntax check.
$out = $this->getOutput();
$result = AbuseFilter::checkSyntax( $this->mFilter );
if ( $result !== true ) {
$out->addWikiMsg( 'abusefilter-test-syntaxerr' );
return;
}
$dbr = wfGetDB( DB_SLAVE );
$conds = [];
$conds['rc_user_text'] = $this->mTestUser;
if ( $this->mTestPeriodStart ) {
$conds[] = 'rc_timestamp >= ' .
$dbr->addQuotes( $dbr->timestamp( strtotime( $this->mTestPeriodStart ) ) );
}
if ( $this->mTestPeriodEnd ) {
$conds[] = 'rc_timestamp <= ' .
$dbr->addQuotes( $dbr->timestamp( strtotime( $this->mTestPeriodEnd ) ) );
}
if ( $this->mTestPage ) {
$title = Title::newFromText( $this->mTestPage );
if ( $title instanceof Title ) {
$conds['rc_namespace'] = $title->getNamespace();
$conds['rc_title'] = $title->getDBkey();
} else {
$out->addWikiMsg( 'abusefilter-test-badtitle' );
return;
}
}
$conds[] = $this->buildTestConditions( $dbr );
// Get our ChangesList
$changesList = new AbuseFilterChangesList( $this->getSkin() );
$output = $changesList->beginRecentChangesList();
$res = $dbr->select(
'recentchanges',
'*',
array_filter( $conds ),
__METHOD__,
[ 'LIMIT' => self::$mChangeLimit, 'ORDER BY' => 'rc_timestamp desc' ]
);
$counter = 1;
foreach ( $res as $row ) {
$vars = AbuseFilter::getVarsFromRCRow( $row );
if ( !$vars ) {
continue;
}
$result = AbuseFilter::checkConditions( $this->mFilter, $vars );
if ( $result || $this->mShowNegative ) {
// Stash result in RC item
$rc = RecentChange::newFromRow( $row );
$rc->examineParams['testfilter'] = $this->mFilter;
$rc->filterResult = $result;
$rc->counter = $counter++;
$output .= $changesList->recentChangesLine( $rc, false );
}
}
$output .= $changesList->endRecentChangesList();
$out->addHTML( $output );
}
function loadParameters() {
$request = $this->getRequest();
$this->mFilter = $request->getText( 'wpTestFilter' );
$this->mShowNegative = $request->getBool( 'wpShowNegative' );
$testUsername = $request->getText( 'wpTestUser' );
$this->mTestPeriodEnd = $request->getText( 'wpTestPeriodEnd' );
$this->mTestPeriodStart = $request->getText( 'wpTestPeriodStart' );
$this->mTestPage = $request->getText( 'wpTestPage' );
if ( !$this->mFilter
&& count( $this->mParams ) > 1
&& is_numeric( $this->mParams[1] )
) {
$dbr = wfGetDB( DB_SLAVE );
$this->mFilter = $dbr->selectField( 'abuse_filter',
'af_pattern',
[ 'af_id' => $this->mParams[1] ],
__METHOD__
);
}
// Normalise username
$userTitle = Title::newFromText( $testUsername );
if ( $userTitle && $userTitle->getNamespace() == NS_USER ) {
$this->mTestUser = $userTitle->getText(); // Allow User:Blah syntax.
} elseif ( $userTitle ) {
// Not sure of the value of prefixedText over text, but no need to munge unnecessarily.
$this->mTestUser = $userTitle->getPrefixedText();
} else {
$this->mTestUser = null; // No user specified.
}
}
}