2008-06-27 06:18:51 +00:00
|
|
|
<?php
|
|
|
|
if ( ! defined( 'MEDIAWIKI' ) )
|
|
|
|
die();
|
|
|
|
|
|
|
|
class SpecialAbuseLog extends SpecialPage {
|
|
|
|
|
|
|
|
function __construct() {
|
|
|
|
wfLoadExtensionMessages('AbuseFilter');
|
|
|
|
parent::__construct( 'AbuseLog', 'abusefilter-log' );
|
|
|
|
}
|
|
|
|
|
|
|
|
function execute( $parameter ) {
|
2009-01-27 17:32:30 +00:00
|
|
|
global $wgUser,$wgOut,$wgRequest, $wgAbuseFilterStyleVersion;
|
2009-03-11 05:55:06 +00:00
|
|
|
|
|
|
|
AbuseFilter::addNavigationLinks( $wgOut, $wgUser->getSkin(), 'log' );
|
2008-06-27 06:18:51 +00:00
|
|
|
|
|
|
|
$this->setHeaders();
|
2009-02-27 09:12:25 +00:00
|
|
|
$this->outputHeader( 'abusefilter-log-summary' );
|
2008-06-27 06:18:51 +00:00
|
|
|
$this->loadParameters();
|
|
|
|
|
|
|
|
$wgOut->setPageTitle( wfMsg( 'abusefilter-log' ) );
|
2008-07-23 19:33:28 +00:00
|
|
|
$wgOut->setRobotPolicy( "noindex,nofollow" );
|
2008-06-27 06:18:51 +00:00
|
|
|
$wgOut->setArticleRelated( false );
|
|
|
|
$wgOut->enableClientCache( false );
|
2009-01-26 19:23:27 +00:00
|
|
|
|
|
|
|
global $wgScriptPath;
|
2009-02-07 09:34:11 +00:00
|
|
|
$wgOut->addExtensionStyle( $wgScriptPath .
|
|
|
|
"/extensions/AbuseFilter/abusefilter.css?$wgAbuseFilterStyleVersion" );
|
2009-01-27 17:32:30 +00:00
|
|
|
|
2008-06-27 06:18:51 +00:00
|
|
|
// Are we allowed?
|
2009-02-07 09:34:11 +00:00
|
|
|
$errors = $this->getTitle()->getUserPermissionsErrors(
|
|
|
|
'abusefilter-log', $wgUser, true, array( 'ns-specialprotected' ) );
|
|
|
|
if ( count( $errors ) ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
// Go away.
|
|
|
|
$wgOut->showPermissionsErrorPage( $errors, 'abusefilter-log' );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-03-22 23:33:27 +00:00
|
|
|
$detailsid = $wgRequest->getIntOrNull( 'details' );
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $detailsid ) {
|
2009-03-22 23:33:27 +00:00
|
|
|
$this->showDetails( $detailsid );
|
|
|
|
} else {
|
|
|
|
// Show the search form.
|
|
|
|
$this->searchForm();
|
|
|
|
|
|
|
|
// Show the log itself.
|
|
|
|
$this->showList();
|
|
|
|
}
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function loadParameters() {
|
|
|
|
global $wgRequest;
|
|
|
|
|
|
|
|
$this->mSearchUser = $wgRequest->getText( 'wpSearchUser' );
|
2009-04-01 03:38:57 +00:00
|
|
|
|
|
|
|
$t = Title::newFromText( trim($this->mSearchUser) );
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $t ) {
|
2009-04-01 03:38:57 +00:00
|
|
|
$this->mSearchUser = $t->getText(); // Username normalisation
|
2009-05-22 06:42:10 +00:00
|
|
|
} else {
|
|
|
|
$this->mSearchUser = null;
|
|
|
|
}
|
2009-04-01 03:38:57 +00:00
|
|
|
|
2008-06-27 06:18:51 +00:00
|
|
|
$this->mSearchTitle = $wgRequest->getText( 'wpSearchTitle' );
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $this->canSeeDetails() ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
$this->mSearchFilter = $wgRequest->getIntOrNull( 'wpSearchFilter' );
|
2009-05-22 06:42:10 +00:00
|
|
|
}
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function searchForm() {
|
|
|
|
global $wgOut, $wgUser;
|
|
|
|
|
|
|
|
$output = Xml::element( 'legend', null, wfMsg( 'abusefilter-log-search' ) );
|
|
|
|
$fields = array();
|
|
|
|
|
|
|
|
// Search conditions
|
2009-02-07 09:34:11 +00:00
|
|
|
$fields['abusefilter-log-search-user'] =
|
|
|
|
Xml::input( 'wpSearchUser', 45, $this->mSearchUser );
|
|
|
|
if ($this->canSeeDetails()) {
|
|
|
|
$fields['abusefilter-log-search-filter'] =
|
|
|
|
Xml::input( 'wpSearchFilter', 45, $this->mSearchFilter );
|
|
|
|
}
|
|
|
|
$fields['abusefilter-log-search-title'] =
|
|
|
|
Xml::input( 'wpSearchTitle', 45, $this->mSearchTitle );
|
2008-06-27 06:18:51 +00:00
|
|
|
|
|
|
|
$form = Xml::hidden( 'title', $this->getTitle()->getPrefixedText() );
|
|
|
|
|
|
|
|
$form .= Xml::buildForm( $fields, 'abusefilter-log-search-submit' );
|
2009-02-07 09:34:11 +00:00
|
|
|
$output .= Xml::tags( 'form',
|
|
|
|
array( 'method' => 'GET', 'action' => $this->getTitle()->getLocalURL() ),
|
|
|
|
$form );
|
2008-06-27 06:18:51 +00:00
|
|
|
$output = Xml::tags( 'fieldset', null, $output );
|
|
|
|
|
2008-11-06 22:20:29 +00:00
|
|
|
$wgOut->addHTML( $output );
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function showList() {
|
|
|
|
global $wgOut;
|
|
|
|
|
|
|
|
// Generate conditions list.
|
|
|
|
$conds = array();
|
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( !empty( $this->mSearchUser ) ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
$conds['afl_user_text'] = $this->mSearchUser;
|
2009-05-22 06:42:10 +00:00
|
|
|
}
|
|
|
|
if ( !empty( $this->mSearchFilter ) ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
$conds['afl_filter'] = $this->mSearchFilter;
|
2009-05-22 06:42:10 +00:00
|
|
|
}
|
2008-06-27 06:18:51 +00:00
|
|
|
|
|
|
|
$searchTitle = Title::newFromText( $this->mSearchTitle );
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $this->mSearchTitle && $searchTitle ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
$conds['afl_namespace'] = $searchTitle->getNamespace();
|
2009-05-24 08:33:57 +00:00
|
|
|
$conds['afl_title'] = $searchTitle->getDBkey();
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$pager = new AbuseLogPager( $this, $conds );
|
|
|
|
|
2009-04-28 19:30:50 +00:00
|
|
|
$body = Xml::tags( 'ul', null, $pager->getBody() );
|
2008-11-06 22:20:29 +00:00
|
|
|
$wgOut->addHTML( $pager->getNavigationBar() .
|
2009-04-28 19:30:50 +00:00
|
|
|
$body .
|
2008-06-27 06:18:51 +00:00
|
|
|
$pager->getNavigationBar() );
|
|
|
|
}
|
|
|
|
|
|
|
|
function showDetails( $id ) {
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( !$this->canSeeDetails() ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
2009-02-07 09:34:11 +00:00
|
|
|
$row = $dbr->selectRow( array('abuse_filter_log','abuse_filter'), '*',
|
2009-03-31 04:00:30 +00:00
|
|
|
array( 'afl_id' => $id ), __METHOD__,
|
|
|
|
array( 'abuse_filter' => array( 'left join', 'af_id=afl_filter') ) );
|
2008-06-27 06:18:51 +00:00
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( !$row ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
return;
|
2009-05-22 06:42:10 +00:00
|
|
|
}
|
2008-06-27 06:18:51 +00:00
|
|
|
|
|
|
|
$output = '';
|
|
|
|
|
|
|
|
$output .= Xml::element( 'legend', null, wfMsg( 'abusefilter-log-details-legend', $id ) );
|
2008-10-21 15:14:30 +00:00
|
|
|
$output .= Xml::tags( 'p', null, $this->formatRow( $row, false ) );
|
2009-03-22 23:33:27 +00:00
|
|
|
|
|
|
|
// Load data
|
2009-02-27 03:06:19 +00:00
|
|
|
$vars = AbuseFilter::loadVarDump( $row->afl_var_dump );
|
2008-06-27 06:18:51 +00:00
|
|
|
|
2009-03-18 05:45:36 +00:00
|
|
|
// Diff, if available
|
|
|
|
if ( $vars->getVar( 'action' )->toString() == 'edit' ) {
|
|
|
|
## Stolen from DifferenceEngine.php
|
|
|
|
global $wgStylePath, $wgStyleVersion, $wgOut;
|
|
|
|
$wgOut->addStyle( 'common/diff.css' );
|
|
|
|
|
|
|
|
// JS is needed to detect old versions of Mozilla to work around an annoyance bug.
|
|
|
|
$wgOut->addScript( "<script type=\"text/javascript\" src=\"$wgStylePath/common/diff.js?$wgStyleVersion\"></script>" );
|
|
|
|
|
|
|
|
$old_wikitext = $vars->getVar('old_wikitext')->toString();
|
|
|
|
$new_wikitext = $vars->getVar('new_wikitext')->toString();
|
|
|
|
|
|
|
|
$old_lines = explode( "\n", $old_wikitext );
|
|
|
|
$new_lines = explode( "\n", $new_wikitext );
|
|
|
|
|
|
|
|
$diff = new Diff( $old_lines, $new_lines );
|
|
|
|
$formatter = new TableDiffFormatter;
|
|
|
|
|
|
|
|
static $colDescriptions = "<col class='diff-marker' />
|
|
|
|
<col class='diff-content' />
|
|
|
|
<col class='diff-marker' />
|
|
|
|
<col class='diff-content' />";
|
|
|
|
|
|
|
|
$formattedDiff = $formatter->format( $diff );
|
|
|
|
$formattedDiff =
|
|
|
|
"<table class='diff'>$colDescriptions<tbody>$formattedDiff</tbody></table>";
|
|
|
|
|
|
|
|
$output .=
|
|
|
|
Xml::tags( 'h3',
|
|
|
|
null,
|
|
|
|
wfMsgExt( 'abusefilter-log-details-diff', 'parseinline' )
|
|
|
|
);
|
|
|
|
$output .= $formattedDiff;
|
|
|
|
}
|
|
|
|
|
2009-03-22 23:33:27 +00:00
|
|
|
$output .= Xml::element( 'h3', null, wfMsg( 'abusefilter-log-details-vars' ) );
|
|
|
|
|
|
|
|
// Build a table.
|
|
|
|
$output .= AbuseFilter::buildVarDumpTable( $vars );
|
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $this->canSeePrivate() ) {
|
2008-06-27 08:11:09 +00:00
|
|
|
// Private stuff, like IPs.
|
2009-02-07 09:34:11 +00:00
|
|
|
$header =
|
|
|
|
Xml::element( 'th', null, wfMsg( 'abusefilter-log-details-var' ) ) .
|
|
|
|
Xml::element( 'th', null, wfMsg( 'abusefilter-log-details-val' ) );
|
2008-06-27 08:11:09 +00:00
|
|
|
$output .= Xml::element( 'h3', null, wfMsg( 'abusefilter-log-details-private' ) );
|
2009-02-07 09:34:11 +00:00
|
|
|
$output .=
|
|
|
|
Xml::openElement( 'table',
|
|
|
|
array(
|
|
|
|
'class' => 'wikitable mw-abuselog-private',
|
|
|
|
'style' => "width: 80%;"
|
|
|
|
)
|
|
|
|
) .
|
|
|
|
Xml::openElement( 'tbody' );
|
2008-06-27 08:11:09 +00:00
|
|
|
$output .= $header;
|
|
|
|
|
|
|
|
// IP address
|
2009-02-07 09:34:11 +00:00
|
|
|
$output .=
|
|
|
|
Xml::tags( 'tr', null,
|
|
|
|
Xml::element( 'td',
|
|
|
|
array( 'style' => 'width: 30%;' ),
|
|
|
|
wfMsg('abusefilter-log-details-ip' )
|
|
|
|
) .
|
|
|
|
Xml::element( 'td', null, $row->afl_ip )
|
|
|
|
);
|
2008-06-27 08:11:09 +00:00
|
|
|
|
|
|
|
$output .= Xml::closeElement( 'tbody' ) . Xml::closeElement( 'table' );
|
|
|
|
}
|
2008-06-27 06:18:51 +00:00
|
|
|
|
|
|
|
$output = Xml::tags( 'fieldset', null, $output );
|
|
|
|
|
|
|
|
global $wgOut;
|
|
|
|
$wgOut->addHTML( $output );
|
|
|
|
}
|
|
|
|
|
|
|
|
function canSeeDetails() {
|
|
|
|
global $wgUser;
|
2009-05-22 06:42:10 +00:00
|
|
|
return !count( $this->getTitle()->getUserPermissionsErrors(
|
|
|
|
'abusefilter-log-detail', $wgUser, true, array( 'ns-specialprotected' ) ) );
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
2008-06-27 08:11:09 +00:00
|
|
|
function canSeePrivate() {
|
|
|
|
global $wgUser;
|
2009-02-07 09:34:11 +00:00
|
|
|
return !count(
|
|
|
|
$this->getTitle()->getUserPermissionsErrors(
|
|
|
|
'abusefilter-private', $wgUser, true, array( 'ns-specialprotected' ) ));
|
2008-06-27 08:11:09 +00:00
|
|
|
}
|
|
|
|
|
2008-10-21 15:14:30 +00:00
|
|
|
function formatRow( $row, $li = true ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
global $wgLang,$wgUser;
|
|
|
|
|
|
|
|
## One-time setup
|
|
|
|
static $sk=null;
|
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( is_null( $sk ) ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
$sk = $wgUser->getSkin();
|
|
|
|
}
|
|
|
|
|
|
|
|
$title = Title::makeTitle( $row->afl_namespace, $row->afl_title );
|
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( !$row->afl_wiki ) {
|
2009-03-30 06:12:12 +00:00
|
|
|
$pageLink = $sk->link( $title );
|
|
|
|
} else {
|
|
|
|
$pageLink = WikiMap::makeForeignLink( $row->afl_wiki, $row->afl_title );
|
|
|
|
}
|
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( !$row->afl_wiki ) {
|
2009-03-30 06:12:12 +00:00
|
|
|
// Local user
|
|
|
|
$user = $sk->userLink( $row->afl_user, $row->afl_user_text ) .
|
|
|
|
$sk->userToolLinks( $row->afl_user, $row->afl_user_text );
|
|
|
|
} else {
|
|
|
|
$user = WikiMap::foreignUserLink( $row->afl_wiki, $row->afl_user_text );
|
|
|
|
$user .= " (".WikiMap::getWikiName( $row->afl_wiki ) . ")";
|
|
|
|
}
|
2008-06-27 06:18:51 +00:00
|
|
|
|
|
|
|
$description = '';
|
|
|
|
|
2009-02-26 21:45:07 +00:00
|
|
|
$timestamp = $wgLang->timeanddate( $row->afl_timestamp, true );
|
|
|
|
|
2008-06-27 06:18:51 +00:00
|
|
|
$actions_taken = $row->afl_actions;
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( !strlen( trim( $actions_taken ) ) ) {
|
2008-06-27 06:18:51 +00:00
|
|
|
$actions_taken = wfMsg( 'abusefilter-log-noactions' );
|
2009-01-28 01:26:38 +00:00
|
|
|
} else {
|
2009-05-22 06:42:10 +00:00
|
|
|
$actions = explode( ',', $actions_taken );
|
2009-01-28 01:26:38 +00:00
|
|
|
$displayActions = array();
|
|
|
|
|
|
|
|
foreach( $actions as $action ) {
|
2009-03-30 06:12:12 +00:00
|
|
|
$displayActions[] = AbuseFilter::getActionDisplay( $action );
|
2009-01-28 01:26:38 +00:00
|
|
|
}
|
|
|
|
$actions_taken = implode( ', ', $displayActions );
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
2009-03-30 06:12:12 +00:00
|
|
|
|
|
|
|
$globalIndex = AbuseFilter::decodeGlobalName( $row->afl_filter );
|
|
|
|
|
2009-01-31 01:59:13 +00:00
|
|
|
global $wgOut;
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $globalIndex ) {
|
2009-03-30 06:12:12 +00:00
|
|
|
// Pull global filter description
|
|
|
|
$parsed_comments =
|
|
|
|
$wgOut->parseInline( AbuseFilter::getGlobalFilterDescription( $globalIndex ) );
|
|
|
|
} else {
|
|
|
|
$parsed_comments = $wgOut->parseInline( $row->af_public_comments );
|
|
|
|
}
|
2008-06-27 06:18:51 +00:00
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $this->canSeeDetails() ) {
|
2009-02-04 21:22:41 +00:00
|
|
|
$examineTitle = SpecialPage::getTitleFor( 'AbuseFilter', "examine/log/".$row->afl_id );
|
2009-02-07 09:34:11 +00:00
|
|
|
$detailsLink = $sk->makeKnownLinkObj(
|
|
|
|
$this->getTitle(),
|
|
|
|
wfMsg( 'abusefilter-log-detailslink' ),
|
|
|
|
'details='.$row->afl_id );
|
|
|
|
$examineLink = $sk->link(
|
|
|
|
$examineTitle,
|
|
|
|
wfMsgExt( 'abusefilter-changeslist-examine', 'parseinline' ),
|
|
|
|
array() );
|
2009-03-30 06:12:12 +00:00
|
|
|
|
2009-05-22 06:42:10 +00:00
|
|
|
if ( $globalIndex ) {
|
2009-03-30 06:12:12 +00:00
|
|
|
global $wgAbuseFilterCentralDB;
|
|
|
|
$globalURL =
|
|
|
|
WikiMap::getForeignURL( $wgAbuseFilterCentralDB,
|
|
|
|
'Special:AbuseFilter/'.$globalIndex );
|
|
|
|
|
|
|
|
$linkText = wfMsgExt( 'abusefilter-log-detailedentry-global',
|
|
|
|
'parseinline', array($globalIndex) );
|
|
|
|
|
|
|
|
$filterLink = $sk->makeExternalLink( $globalURL, $linkText );
|
|
|
|
} else {
|
|
|
|
$title = SpecialPage::getTitleFor( 'AbuseFilter', $row->afl_filter );
|
|
|
|
$linkText = wfMsgExt( 'abusefilter-log-detailedentry-local',
|
|
|
|
'parseinline', array($row->afl_filter) );
|
|
|
|
$filterLink = $sk->link( $title, $linkText );
|
|
|
|
}
|
|
|
|
$description = wfMsgExt( 'abusefilter-log-detailedentry-meta',
|
2009-02-07 09:34:11 +00:00
|
|
|
array( 'parseinline', 'replaceafter' ),
|
|
|
|
array(
|
2009-02-26 21:48:49 +00:00
|
|
|
$timestamp,
|
2009-02-07 09:34:11 +00:00
|
|
|
$user,
|
2009-03-30 06:12:12 +00:00
|
|
|
$filterLink,
|
2009-02-07 09:34:11 +00:00
|
|
|
$row->afl_action,
|
2009-03-30 06:12:12 +00:00
|
|
|
$pageLink,
|
2009-02-07 09:34:11 +00:00
|
|
|
$actions_taken,
|
|
|
|
$parsed_comments,
|
|
|
|
$detailsLink,
|
|
|
|
$examineLink
|
|
|
|
)
|
|
|
|
);
|
2008-06-27 06:18:51 +00:00
|
|
|
} else {
|
2009-02-07 09:34:11 +00:00
|
|
|
$description = wfMsgExt(
|
|
|
|
'abusefilter-log-entry',
|
|
|
|
array( 'parseinline', 'replaceafter' ),
|
|
|
|
array(
|
|
|
|
$timestamp,
|
|
|
|
$user,
|
|
|
|
$row->afl_action,
|
2009-03-01 12:56:11 +00:00
|
|
|
$sk->link( $title ),
|
2009-02-07 09:34:11 +00:00
|
|
|
$actions_taken,
|
|
|
|
$parsed_comments
|
|
|
|
)
|
|
|
|
);
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
2008-10-21 15:14:30 +00:00
|
|
|
return $li ? Xml::tags( 'li', null, $description ) : $description;
|
2008-06-27 06:18:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class AbuseLogPager extends ReverseChronologicalPager {
|
|
|
|
public $mForm, $mConds;
|
|
|
|
|
|
|
|
function __construct( $form, $conds = array(), $details = false ) {
|
|
|
|
$this->mForm = $form;
|
|
|
|
$this->mConds = $conds;
|
|
|
|
parent::__construct();
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatRow( $row ) {
|
|
|
|
return $this->mForm->formatRow( $row );
|
|
|
|
}
|
|
|
|
|
|
|
|
function getQueryInfo() {
|
|
|
|
$conds = $this->mConds;
|
|
|
|
|
|
|
|
return array(
|
|
|
|
'tables' => array('abuse_filter_log','abuse_filter'),
|
|
|
|
'fields' => '*',
|
|
|
|
'conds' => $conds,
|
2009-03-30 06:12:12 +00:00
|
|
|
'join_conds' =>
|
|
|
|
array( 'abuse_filter' =>
|
|
|
|
array(
|
|
|
|
'LEFT JOIN',
|
|
|
|
'af_id=afl_filter',
|
|
|
|
),
|
|
|
|
),
|
2008-06-27 06:18:51 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getIndexField() {
|
|
|
|
return 'afl_timestamp';
|
|
|
|
}
|
2008-12-20 09:32:47 +00:00
|
|
|
}
|