Make use of the APIEditBeforeSave hook for nicer errors

Bug: 32216
Change-Id: I654eb21faffa1371f637d98d0fcd38c005048507
This commit is contained in:
Marius Hoch 2013-07-04 02:25:25 +02:00
parent 321b567c1a
commit 83357aafd0
2 changed files with 63 additions and 3 deletions

View file

@ -7,6 +7,57 @@ class AbuseFilterHooks {
// So far, all of the error message out-params for these hooks accept HTML.
// Hooray!
/**
* Entry point for the APIEditBeforeSave hook.
* This is needed to give a useful error for API edits (Bug 32216)
*
* @see https://www.mediawiki.org/wiki/Manual:Hooks/APIEditBeforeSave
*
* @param EditPage $editPage
* @param string $text New text of the article (has yet to be saved)
* @param array &$resultArr Data in this array will be added to the API result
*
* @return bool
*/
public static function onAPIEditBeforeSave( $editPage, $text, &$result ) {
global $wgUser;
$context = $editPage->mArticle->getContext();
$status = Status::newGood();
$minoredit = $editPage->minoredit;
$summary = $editPage->summary;
// poor man's PST, see bug 20310
$text = str_replace( "\r\n", "\n", $text );
$continue = self::filterEdit( $context, null, $text, $status, $summary, $wgUser, $minoredit );
if ( !$status->isOK() ) {
$msg = $status->getErrorsArray();
// Use the error message key name as error code, the first parameter is the filter description.
if ( $msg[0] instanceof Message ) {
// For forward compatibility: In case we switch over towards using Message objects someday.
// (see the todo for AbuseFilter::buildStatus)
$code = $msg[0]->getKey();
$filterDescription = $msg[0]->getParams();
$filterDescription = $filterDescription[0];
} else {
$code = $msg[0][0];
$filterDescription = $msg[0][1];
}
$result = array(
'code' => $code,
'info' => 'Hit AbuseFilter: ' . $filterDescription,
'warning' => $status->getHTML()
);
}
return $status->isOK();
}
/**
* Entry points for MediaWiki hook 'EditFilterMerged' (MW 1.20 and earlier)
*
@ -58,7 +109,8 @@ class AbuseFilterHooks {
}
/**
* Common implementation for EditFilterMerged and EditFilterMergedContent hooks.
* Common implementation for the APIEditBeforeSave, EditFilterMerged
* and EditFilterMergedContent hooks.
*
* @param IContextSource $context the context of the edit
* @param Content|null $content the new Content generated by the edit
@ -73,7 +125,15 @@ class AbuseFilterHooks {
public static function filterEdit( IContextSource $context, $content, $text,
Status $status, $summary, User $user, $minoredit ) {
// Load vars
$vars = new AbuseFilterVariableHolder;
$vars = new AbuseFilterVariableHolder();
$title = $context->getTitle();
// Some edits are running through multiple hooks, but we only want to filter them once
if ( isset( $title->editAlreadyFiltered ) ) {
return true;
}
$title->editAlreadyFiltered = true;
self::$successful_action_vars = false;
self::$last_edit_page = false;
@ -82,7 +142,6 @@ class AbuseFilterHooks {
$oldtext = '';
$oldcontent = null;
$title = $context->getTitle();
if ( ( $title instanceof Title ) && $title->canExist() && $title->exists() ) {
// Make sure we load the latest text saved in database (bug 31656)
$page = $context->getWikiPage();

View file

@ -87,6 +87,7 @@ $wgHooks['ContributionsToolLinks'][] = 'AbuseFilterHooks::onContributionsToolLin
$wgHooks['UploadVerifyFile'][] = 'AbuseFilterHooks::onUploadVerifyFile';
$wgHooks['MakeGlobalVariablesScript'][] = 'AbuseFilterHooks::onMakeGlobalVariablesScript';
$wgHooks['ArticleSaveComplete'][] = 'AbuseFilterHooks::onArticleSaveComplete';
$wgHooks['APIEditBeforeSave'][] = 'AbuseFilterHooks::onAPIEditBeforeSave';
$wgAvailableRights[] = 'abusefilter-modify';
$wgAvailableRights[] = 'abusefilter-log-detail';