Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AceEditBoxBuilder
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
20
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEditBox
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 getEditorControls
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 getAceConfig
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter\EditBox;
4
5use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
6use MediaWiki\Extension\AbuseFilter\KeywordsManager;
7use MediaWiki\Extension\AbuseFilter\Parser\AbuseFilterTokenizer;
8use MediaWiki\Extension\AbuseFilter\Parser\FilterEvaluator;
9use MediaWiki\Html\Html;
10use MediaWiki\Language\MessageLocalizer;
11use MediaWiki\Output\OutputPage;
12use MediaWiki\Permissions\Authority;
13use OOUI\ButtonWidget;
14use OOUI\HorizontalLayout;
15use OOUI\Widget;
16
17/**
18 * Class responsible for building filter edit boxes with both the Ace and the plain version
19 */
20class AceEditBoxBuilder extends EditBoxBuilder {
21
22    /**
23     * @inheritDoc
24     * @param PlainEditBoxBuilder $plainBuilder
25     */
26    public function __construct(
27        AbuseFilterPermissionManager $afPermManager,
28        KeywordsManager $keywordsManager,
29        MessageLocalizer $messageLocalizer,
30        Authority $authority,
31        OutputPage $output,
32        private readonly PlainEditBoxBuilder $plainBuilder
33    ) {
34        parent::__construct( $afPermManager, $keywordsManager, $messageLocalizer, $authority, $output );
35    }
36
37    /**
38     * @inheritDoc
39     */
40    protected function getEditBox( string $rules, bool $isUserAllowed, bool $externalForm ): string {
41        $rules = rtrim( $rules ) . "\n";
42
43        $attribs = [
44            // Rules are in English
45            'dir' => 'ltr',
46            'name' => 'wpAceFilterEditor',
47            'id' => 'wpAceFilterEditor',
48            'class' => 'mw-abusefilter-editor'
49        ];
50        $rulesContainer = Html::element( 'div', $attribs, $rules );
51        $editorConfig = $this->getAceConfig( $isUserAllowed );
52        $this->output->addJsConfigVars( 'aceConfig', $editorConfig );
53        return $rulesContainer . $this->plainBuilder->getEditBox( $rules, $isUserAllowed, $externalForm );
54    }
55
56    /**
57     * @inheritDoc
58     */
59    protected function getEditorControls(): Widget {
60        $base = parent::getEditorControls();
61        $switchEditor = new ButtonWidget(
62            [
63                'label' => $this->localizer->msg( 'abusefilter-edit-switch-editor' )->text(),
64                'id' => 'mw-abusefilter-switcheditor'
65            ]
66        );
67        return new Widget( [
68            'content' => new HorizontalLayout( [
69                'items' => [ $switchEditor, $base ]
70            ] )
71        ] );
72    }
73
74    /**
75     * Extract values for syntax highlight
76     *
77     * @param bool $canEdit
78     * @return array
79     */
80    private function getAceConfig( bool $canEdit ): array {
81        $values = $this->keywordsManager->getBuilderValues();
82        $deprecatedVars = $this->keywordsManager->getDeprecatedVariables();
83
84        $builderVariables = implode( '|', array_keys( $values['vars'] ) );
85        $builderFunctions = implode( '|', array_keys( FilterEvaluator::FUNCTIONS ) );
86        // AbuseFilterTokenizer::KEYWORDS also includes constants (true, false and null),
87        // but Ace redefines these constants afterwards so this will not be an issue
88        $builderKeywords = implode( '|', AbuseFilterTokenizer::KEYWORDS );
89        // Extract operators from tokenizer like we do in AbuseFilterParserTest
90        $operators = implode( '|', array_map( static function ( $op ) {
91            return preg_quote( $op, '/' );
92        }, AbuseFilterTokenizer::OPERATORS ) );
93        $deprecatedVariables = implode( '|', array_keys( $deprecatedVars ) );
94        $disabledVariables = implode( '|', array_keys( $this->keywordsManager->getDisabledVariables() ) );
95
96        return [
97            'variables' => $builderVariables,
98            'functions' => $builderFunctions,
99            'keywords' => $builderKeywords,
100            'operators' => $operators,
101            'deprecated' => $deprecatedVariables,
102            'disabled' => $disabledVariables,
103            'aceReadOnly' => !$canEdit
104        ];
105    }
106}