2020-11-24 12:16:41 +00:00
|
|
|
<?php
|
|
|
|
|
2021-02-01 15:47:46 +00:00
|
|
|
namespace MediaWiki\Extension\AbuseFilter\EditBox;
|
2020-11-24 12:16:41 +00:00
|
|
|
|
2021-02-01 15:47:46 +00:00
|
|
|
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
|
|
|
|
use MediaWiki\Extension\AbuseFilter\KeywordsManager;
|
2020-11-24 12:16:41 +00:00
|
|
|
use MessageLocalizer;
|
2020-11-27 22:53:07 +00:00
|
|
|
use OOUI\ButtonWidget;
|
|
|
|
use OOUI\DropdownInputWidget;
|
|
|
|
use OOUI\FieldLayout;
|
|
|
|
use OOUI\FieldsetLayout;
|
|
|
|
use OOUI\Widget;
|
2020-11-24 12:16:41 +00:00
|
|
|
use OutputPage;
|
|
|
|
use User;
|
|
|
|
use Xml;
|
|
|
|
|
|
|
|
/**
|
2021-03-04 11:24:20 +00:00
|
|
|
* Base class for classes responsible for building filter edit boxes
|
2020-11-24 12:16:41 +00:00
|
|
|
*/
|
2021-03-04 11:24:20 +00:00
|
|
|
abstract class EditBoxBuilder {
|
2020-11-24 12:16:41 +00:00
|
|
|
/** @var AbuseFilterPermissionManager */
|
2021-03-04 11:24:20 +00:00
|
|
|
protected $afPermManager;
|
2020-11-24 12:16:41 +00:00
|
|
|
|
|
|
|
/** @var KeywordsManager */
|
2021-03-04 11:24:20 +00:00
|
|
|
protected $keywordsManager;
|
2020-11-24 12:16:41 +00:00
|
|
|
|
|
|
|
/** @var MessageLocalizer */
|
2021-03-04 11:24:20 +00:00
|
|
|
protected $localizer;
|
2020-11-24 12:16:41 +00:00
|
|
|
|
|
|
|
/** @var User */
|
2021-03-04 11:24:20 +00:00
|
|
|
protected $user;
|
2020-11-24 12:16:41 +00:00
|
|
|
|
|
|
|
/** @var OutputPage */
|
2021-03-04 11:24:20 +00:00
|
|
|
protected $output;
|
2020-11-24 12:16:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param AbuseFilterPermissionManager $afPermManager
|
|
|
|
* @param KeywordsManager $keywordsManager
|
|
|
|
* @param MessageLocalizer $messageLocalizer
|
|
|
|
* @param User $user
|
|
|
|
* @param OutputPage $output
|
|
|
|
*/
|
|
|
|
public function __construct(
|
|
|
|
AbuseFilterPermissionManager $afPermManager,
|
|
|
|
KeywordsManager $keywordsManager,
|
|
|
|
MessageLocalizer $messageLocalizer,
|
|
|
|
User $user,
|
|
|
|
OutputPage $output
|
|
|
|
) {
|
|
|
|
$this->afPermManager = $afPermManager;
|
|
|
|
$this->keywordsManager = $keywordsManager;
|
|
|
|
$this->localizer = $messageLocalizer;
|
|
|
|
$this->user = $user;
|
|
|
|
$this->output = $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $rules
|
|
|
|
* @param bool $addResultDiv
|
|
|
|
* @param bool $externalForm
|
|
|
|
* @param bool $needsModifyRights
|
|
|
|
* @param-taint $rules none
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function buildEditBox(
|
|
|
|
string $rules,
|
|
|
|
bool $addResultDiv = true,
|
|
|
|
bool $externalForm = false,
|
|
|
|
bool $needsModifyRights = true
|
2021-07-21 18:51:12 +00:00
|
|
|
): string {
|
2020-11-27 22:53:07 +00:00
|
|
|
$this->output->addModules( 'ext.abuseFilter.edit' );
|
2021-03-04 11:24:20 +00:00
|
|
|
$this->output->enableOOUI();
|
2020-11-24 12:16:41 +00:00
|
|
|
|
|
|
|
$isUserAllowed = $needsModifyRights ?
|
|
|
|
$this->afPermManager->canEdit( $this->user ) :
|
2021-02-19 17:50:38 +00:00
|
|
|
$this->afPermManager->canUseTestTools( $this->user );
|
2020-11-24 12:16:41 +00:00
|
|
|
if ( !$isUserAllowed ) {
|
|
|
|
$addResultDiv = false;
|
|
|
|
}
|
|
|
|
|
2021-03-04 11:24:20 +00:00
|
|
|
$output = $this->getEditBox( $rules, $isUserAllowed, $externalForm );
|
2020-11-24 12:16:41 +00:00
|
|
|
|
|
|
|
if ( $isUserAllowed ) {
|
2021-03-04 11:24:20 +00:00
|
|
|
$dropDown = $this->getSuggestionsDropdown();
|
2020-11-24 12:16:41 +00:00
|
|
|
|
2021-03-04 11:24:20 +00:00
|
|
|
$formElements = [
|
|
|
|
new FieldLayout( $dropDown ),
|
|
|
|
new FieldLayout( $this->getEditorControls() )
|
|
|
|
];
|
2020-11-24 12:16:41 +00:00
|
|
|
|
2020-11-27 22:53:07 +00:00
|
|
|
$fieldSet = new FieldsetLayout( [
|
2020-11-24 12:16:41 +00:00
|
|
|
'items' => $formElements,
|
|
|
|
'classes' => [ 'mw-abusefilter-edit-buttons', 'mw-abusefilter-javascript-tools' ]
|
|
|
|
] );
|
|
|
|
|
2021-03-04 11:24:20 +00:00
|
|
|
$output .= $fieldSet;
|
2020-11-24 12:16:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( $addResultDiv ) {
|
2021-03-04 11:24:20 +00:00
|
|
|
$output .= Xml::element(
|
2020-11-27 22:53:07 +00:00
|
|
|
'div',
|
2020-11-24 12:16:41 +00:00
|
|
|
[ 'id' => 'mw-abusefilter-syntaxresult', 'style' => 'display: none;' ],
|
2020-11-27 22:53:07 +00:00
|
|
|
' '
|
|
|
|
);
|
2020-11-24 12:16:41 +00:00
|
|
|
}
|
|
|
|
|
2021-03-04 11:24:20 +00:00
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return DropdownInputWidget
|
|
|
|
*/
|
2021-07-21 18:51:12 +00:00
|
|
|
private function getSuggestionsDropdown(): DropdownInputWidget {
|
2021-03-04 11:24:20 +00:00
|
|
|
$rawDropDown = $this->keywordsManager->getBuilderValues();
|
|
|
|
|
|
|
|
// The array needs to be rearranged to be understood by OOUI. It comes with the format
|
|
|
|
// [ group-msg-key => [ text-to-add => text-msg-key ] ] and we need it as
|
|
|
|
// [ group-msg => [ text-msg => text-to-add ] ]
|
|
|
|
// Also, the 'other' element must be the first one.
|
|
|
|
$dropDownOptions = [ $this->localizer->msg( 'abusefilter-edit-builder-select' )->text() => 'other' ];
|
|
|
|
foreach ( $rawDropDown as $group => $values ) {
|
|
|
|
// Give grep a chance to find the usages:
|
|
|
|
// abusefilter-edit-builder-group-op-arithmetic, abusefilter-edit-builder-group-op-comparison,
|
|
|
|
// abusefilter-edit-builder-group-op-bool, abusefilter-edit-builder-group-misc,
|
|
|
|
// abusefilter-edit-builder-group-funcs, abusefilter-edit-builder-group-vars
|
|
|
|
$localisedGroup = $this->localizer->msg( "abusefilter-edit-builder-group-$group" )->text();
|
|
|
|
$dropDownOptions[ $localisedGroup ] = array_flip( $values );
|
|
|
|
$newKeys = array_map(
|
|
|
|
function ( $key ) use ( $group ) {
|
|
|
|
return $this->localizer->msg( "abusefilter-edit-builder-$group-$key" )->text();
|
|
|
|
},
|
|
|
|
array_keys( $dropDownOptions[ $localisedGroup ] )
|
|
|
|
);
|
|
|
|
$dropDownOptions[ $localisedGroup ] = array_combine(
|
|
|
|
$newKeys,
|
|
|
|
$dropDownOptions[ $localisedGroup ]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$dropDownList = Xml::listDropDownOptionsOoui( $dropDownOptions );
|
|
|
|
return new DropdownInputWidget( [
|
|
|
|
'name' => 'wpFilterBuilder',
|
|
|
|
'inputId' => 'wpFilterBuilder',
|
|
|
|
'options' => $dropDownList
|
|
|
|
] );
|
2020-11-24 12:16:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-03-04 11:24:20 +00:00
|
|
|
* Get an additional widget that "controls" the editor, and is placed next to it
|
|
|
|
* Precondition: the user has full rights.
|
2020-11-24 12:16:41 +00:00
|
|
|
*
|
2021-03-04 11:24:20 +00:00
|
|
|
* @return Widget
|
2020-11-24 12:16:41 +00:00
|
|
|
*/
|
2021-07-21 18:51:12 +00:00
|
|
|
protected function getEditorControls(): Widget {
|
2021-03-04 11:24:20 +00:00
|
|
|
return new ButtonWidget(
|
|
|
|
[
|
|
|
|
'label' => $this->localizer->msg( 'abusefilter-edit-check' )->text(),
|
|
|
|
'id' => 'mw-abusefilter-syntaxcheck'
|
|
|
|
]
|
|
|
|
);
|
2020-11-24 12:16:41 +00:00
|
|
|
}
|
|
|
|
|
2021-03-04 11:24:20 +00:00
|
|
|
/**
|
|
|
|
* Generate the HTML for the actual edit box
|
|
|
|
*
|
|
|
|
* @param string $rules
|
|
|
|
* @param bool $isUserAllowed
|
|
|
|
* @param bool $externalForm
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-07-21 18:51:12 +00:00
|
|
|
abstract protected function getEditBox( string $rules, bool $isUserAllowed, bool $externalForm ): string;
|
2021-03-04 11:24:20 +00:00
|
|
|
|
2020-11-24 12:16:41 +00:00
|
|
|
}
|