Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.72% |
59 / 61 |
|
87.50% |
7 / 8 |
CRAP | |
0.00% |
0 / 1 |
SpecsFormatter | |
96.72% |
59 / 61 |
|
87.50% |
7 / 8 |
24 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setMessageLocalizer | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getActionDisplay | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
getActionMessage | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
formatAction | |
100.00% |
37 / 37 |
|
100.00% |
1 / 1 |
12 | |||
formatFlags | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
formatFilterFlags | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
2 | |||
nameGroup | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\AbuseFilter; |
4 | |
5 | use MediaWiki\Extension\AbuseFilter\Filter\AbstractFilter; |
6 | use MediaWiki\Language\Language; |
7 | use MediaWiki\Language\RawMessage; |
8 | use MediaWiki\Message\Message; |
9 | use MessageLocalizer; |
10 | |
11 | /** |
12 | * @todo Improve this once DI around Message objects is improved in MW core. |
13 | */ |
14 | class SpecsFormatter { |
15 | public const SERVICE_NAME = 'AbuseFilterSpecsFormatter'; |
16 | |
17 | /** @var MessageLocalizer */ |
18 | private $messageLocalizer; |
19 | |
20 | /** |
21 | * @param MessageLocalizer $messageLocalizer |
22 | */ |
23 | public function __construct( MessageLocalizer $messageLocalizer ) { |
24 | $this->messageLocalizer = $messageLocalizer; |
25 | } |
26 | |
27 | /** |
28 | * @param MessageLocalizer $messageLocalizer |
29 | */ |
30 | public function setMessageLocalizer( MessageLocalizer $messageLocalizer ): void { |
31 | $this->messageLocalizer = $messageLocalizer; |
32 | } |
33 | |
34 | /** |
35 | * @param string $action |
36 | * @return string HTML |
37 | * @todo Replace usage with getActionMessage |
38 | */ |
39 | public function getActionDisplay( string $action ): string { |
40 | // Give grep a chance to find the usages: |
41 | // abusefilter-action-tag, abusefilter-action-throttle, abusefilter-action-warn, |
42 | // abusefilter-action-blockautopromote, abusefilter-action-block, abusefilter-action-degroup, |
43 | // abusefilter-action-rangeblock, abusefilter-action-disallow |
44 | $msg = $this->messageLocalizer->msg( "abusefilter-action-$action" ); |
45 | return $msg->isDisabled() ? htmlspecialchars( $action ) : $msg->escaped(); |
46 | } |
47 | |
48 | /** |
49 | * @param string $action |
50 | * @return Message |
51 | */ |
52 | public function getActionMessage( string $action ): Message { |
53 | // Give grep a chance to find the usages: |
54 | // abusefilter-action-tag, abusefilter-action-throttle, abusefilter-action-warn, |
55 | // abusefilter-action-blockautopromote, abusefilter-action-block, abusefilter-action-degroup, |
56 | // abusefilter-action-rangeblock, abusefilter-action-disallow |
57 | $msg = $this->messageLocalizer->msg( "abusefilter-action-$action" ); |
58 | // XXX Why do we expect the message to be disabled? |
59 | return $msg->isDisabled() ? new RawMessage( $action ) : $msg; |
60 | } |
61 | |
62 | /** |
63 | * @param string $action |
64 | * @param string[] $parameters |
65 | * @param Language $lang |
66 | * @return string |
67 | */ |
68 | public function formatAction( string $action, array $parameters, Language $lang ): string { |
69 | if ( count( $parameters ) === 0 || ( $action === 'block' && count( $parameters ) !== 3 ) ) { |
70 | $displayAction = $this->getActionDisplay( $action ); |
71 | } elseif ( $action === 'block' ) { |
72 | // Needs to be treated separately since the message is more complex |
73 | $messages = [ |
74 | $this->messageLocalizer->msg( 'abusefilter-block-anon' )->escaped() . |
75 | $this->messageLocalizer->msg( 'colon-separator' )->escaped() . |
76 | $lang->translateBlockExpiry( $parameters[1] ), |
77 | $this->messageLocalizer->msg( 'abusefilter-block-user' )->escaped() . |
78 | $this->messageLocalizer->msg( 'colon-separator' )->escaped() . |
79 | $lang->translateBlockExpiry( $parameters[2] ) |
80 | ]; |
81 | if ( $parameters[0] === 'blocktalk' ) { |
82 | $messages[] = $this->messageLocalizer->msg( 'abusefilter-block-talk' )->escaped(); |
83 | } |
84 | $displayAction = $lang->commaList( $messages ); |
85 | } elseif ( $action === 'throttle' ) { |
86 | array_shift( $parameters ); |
87 | [ $actions, $time ] = explode( ',', array_shift( $parameters ) ); |
88 | |
89 | // Join comma-separated groups in a commaList with a final "and", and convert to messages. |
90 | // Messages used here: abusefilter-throttle-ip, abusefilter-throttle-user, |
91 | // abusefilter-throttle-site, abusefilter-throttle-creationdate, abusefilter-throttle-editcount |
92 | // abusefilter-throttle-range, abusefilter-throttle-page, abusefilter-throttle-none |
93 | foreach ( $parameters as &$val ) { |
94 | if ( strpos( $val, ',' ) !== false ) { |
95 | $subGroups = explode( ',', $val ); |
96 | foreach ( $subGroups as &$group ) { |
97 | $msg = $this->messageLocalizer->msg( "abusefilter-throttle-$group" ); |
98 | // We previously accepted literally everything in this field, so old entries |
99 | // may have weird stuff. |
100 | $group = $msg->exists() ? $msg->text() : $group; |
101 | } |
102 | unset( $group ); |
103 | $val = $lang->listToText( $subGroups ); |
104 | } else { |
105 | $msg = $this->messageLocalizer->msg( "abusefilter-throttle-$val" ); |
106 | $val = $msg->exists() ? $msg->text() : $val; |
107 | } |
108 | } |
109 | unset( $val ); |
110 | $groups = $lang->semicolonList( $parameters ); |
111 | |
112 | $displayAction = $this->getActionDisplay( $action ) . |
113 | $this->messageLocalizer->msg( 'colon-separator' )->escaped() . |
114 | $this->messageLocalizer->msg( 'abusefilter-throttle-details' ) |
115 | ->params( $actions, $time, $groups )->escaped(); |
116 | } else { |
117 | $displayAction = $this->getActionDisplay( $action ) . |
118 | $this->messageLocalizer->msg( 'colon-separator' )->escaped() . |
119 | $lang->semicolonList( array_map( 'htmlspecialchars', $parameters ) ); |
120 | } |
121 | |
122 | return $displayAction; |
123 | } |
124 | |
125 | /** |
126 | * @param string $value |
127 | * @param Language $lang |
128 | * @return string |
129 | */ |
130 | public function formatFlags( string $value, Language $lang ): string { |
131 | $flags = array_filter( explode( ',', $value ) ); |
132 | $flagsDisplay = []; |
133 | foreach ( $flags as $flag ) { |
134 | $flagsDisplay[] = $this->messageLocalizer->msg( "abusefilter-history-$flag" )->escaped(); |
135 | } |
136 | |
137 | return $lang->commaList( $flagsDisplay ); |
138 | } |
139 | |
140 | /** |
141 | * @param AbstractFilter $filter |
142 | * @param Language $lang |
143 | * @return string |
144 | */ |
145 | public function formatFilterFlags( AbstractFilter $filter, Language $lang ): string { |
146 | $flags = array_filter( [ |
147 | 'enabled' => $filter->isEnabled(), |
148 | 'deleted' => $filter->isDeleted(), |
149 | 'hidden' => $filter->isHidden(), |
150 | 'protected' => $filter->isProtected(), |
151 | 'global' => $filter->isGlobal() |
152 | ] ); |
153 | $flagsDisplay = []; |
154 | foreach ( $flags as $flag => $_ ) { |
155 | // The following messages are generated here: |
156 | // * abusefilter-history-enabled |
157 | // * abusefilter-history-deleted |
158 | // * abusefilter-history-hidden |
159 | // * abusefilter-history-protected |
160 | // * abusefilter-history-global |
161 | $flagsDisplay[] = $this->messageLocalizer->msg( "abusefilter-history-$flag" )->escaped(); |
162 | } |
163 | |
164 | return $lang->commaList( $flagsDisplay ); |
165 | } |
166 | |
167 | /** |
168 | * Gives either the user-specified name for a group, |
169 | * or spits the input back out when the message for the group is disabled |
170 | * @param string $group The filter's group (as defined in $wgAbuseFilterValidGroups) |
171 | * @return string A name for that filter group, or the input. |
172 | */ |
173 | public function nameGroup( string $group ): string { |
174 | // Give grep a chance to find the usages: abusefilter-group-default |
175 | $msg = $this->messageLocalizer->msg( "abusefilter-group-$group" ); |
176 | return $msg->isDisabled() ? $group : $msg->escaped(); |
177 | } |
178 | } |