Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
EchoNotifier
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
5 / 5
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTitleForFilter
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFilterObject
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDataForEvent
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 notifyForFilter
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter;
4
5use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesRegistry;
6use MediaWiki\Extension\AbuseFilter\Filter\ExistingFilter;
7use MediaWiki\Extension\AbuseFilter\Special\SpecialAbuseFilter;
8use MediaWiki\Extension\Notifications\Model\Event;
9use MediaWiki\Notification\RecipientSet;
10use MediaWiki\Title\Title;
11
12/**
13 * Helper service for EmergencyWatcher to notify filter maintainers of throttled filters
14 * @todo DI not possible due to Echo
15 */
16class EchoNotifier {
17    public const SERVICE_NAME = 'AbuseFilterEchoNotifier';
18    public const EVENT_TYPE = 'throttled-filter';
19
20    public function __construct(
21        private readonly FilterLookup $filterLookup,
22        private readonly ConsequencesRegistry $consequencesRegistry,
23        private readonly bool $isEchoLoaded
24    ) {
25    }
26
27    private function getTitleForFilter( int $filter ): Title {
28        return SpecialAbuseFilter::getTitleForSubpage( (string)$filter );
29    }
30
31    private function getFilterObject( int $filter ): ExistingFilter {
32        return $this->filterLookup->getFilter( $filter, false );
33    }
34
35    /**
36     * @param ExistingFilter $filterObj
37     * @return array
38     */
39    private function getDataForEvent( ExistingFilter $filterObj ): array {
40        $throttledActionNames = array_intersect(
41            $filterObj->getActionsNames(),
42            $this->consequencesRegistry->getDangerousActionNames()
43        );
44        return [
45            'type' => self::EVENT_TYPE,
46            'title' => $this->getTitleForFilter( $filterObj->getID() ),
47            'extra' => [
48                'throttled-actions' => $throttledActionNames,
49            ],
50        ];
51    }
52
53    /**
54     * Send notification about a filter being throttled
55     *
56     * @param int $filter
57     * @return Event|false
58     */
59    public function notifyForFilter( int $filter ) {
60        if ( $this->isEchoLoaded ) {
61            $filterObj = $this->getFilterObject( $filter );
62            return Event::create(
63                $this->getDataForEvent( $filterObj ),
64                new RecipientSet( $filterObj->getUserIdentity() )
65            );
66        }
67        return false;
68    }
69
70}