Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
82.09% |
55 / 67 |
|
60.00% |
3 / 5 |
CRAP | |
0.00% |
0 / 1 |
SpecialAbuseFilter | |
82.09% |
55 / 67 |
|
60.00% |
3 / 5 |
32.50 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
doesWrites | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
getGroupName | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
execute | |
50.00% |
11 / 22 |
|
0.00% |
0 / 1 |
2.50 | |||
instantiateView | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
getViewClassAndPageType | |
100.00% |
37 / 37 |
|
100.00% |
1 / 1 |
21 | |||
getTitleForSubpage | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\AbuseFilter\Special; |
4 | |
5 | use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager; |
6 | use MediaWiki\Extension\AbuseFilter\CentralDBManager; |
7 | use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesFactory; |
8 | use MediaWiki\Extension\AbuseFilter\Consequences\ConsequencesRegistry; |
9 | use MediaWiki\Extension\AbuseFilter\EditBox\EditBoxBuilderFactory; |
10 | use MediaWiki\Extension\AbuseFilter\FilterImporter; |
11 | use MediaWiki\Extension\AbuseFilter\FilterLookup; |
12 | use MediaWiki\Extension\AbuseFilter\FilterProfiler; |
13 | use MediaWiki\Extension\AbuseFilter\FilterStore; |
14 | use MediaWiki\Extension\AbuseFilter\Parser\RuleCheckerFactory; |
15 | use MediaWiki\Extension\AbuseFilter\SpecsFormatter; |
16 | use MediaWiki\Extension\AbuseFilter\VariableGenerator\VariableGeneratorFactory; |
17 | use MediaWiki\Extension\AbuseFilter\Variables\VariablesBlobStore; |
18 | use MediaWiki\Extension\AbuseFilter\Variables\VariablesFormatter; |
19 | use MediaWiki\Extension\AbuseFilter\Variables\VariablesManager; |
20 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterView; |
21 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewDiff; |
22 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewEdit; |
23 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewExamine; |
24 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewHistory; |
25 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewImport; |
26 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewList; |
27 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewRevert; |
28 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewTestBatch; |
29 | use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewTools; |
30 | use MediaWiki\Html\Html; |
31 | use MediaWiki\Title\Title; |
32 | use Wikimedia\ObjectFactory\ObjectFactory; |
33 | |
34 | class SpecialAbuseFilter extends AbuseFilterSpecialPage { |
35 | |
36 | private const PAGE_NAME = 'AbuseFilter'; |
37 | |
38 | /** |
39 | * @var ObjectFactory |
40 | */ |
41 | private $objectFactory; |
42 | |
43 | private const SERVICES_PER_VIEW = [ |
44 | AbuseFilterViewDiff::class => [ |
45 | AbuseFilterPermissionManager::SERVICE_NAME, |
46 | SpecsFormatter::SERVICE_NAME, |
47 | FilterLookup::SERVICE_NAME, |
48 | ], |
49 | AbuseFilterViewEdit::class => [ |
50 | 'DBLoadBalancerFactory', |
51 | 'PermissionManager', |
52 | AbuseFilterPermissionManager::SERVICE_NAME, |
53 | FilterProfiler::SERVICE_NAME, |
54 | FilterLookup::SERVICE_NAME, |
55 | FilterImporter::SERVICE_NAME, |
56 | FilterStore::SERVICE_NAME, |
57 | EditBoxBuilderFactory::SERVICE_NAME, |
58 | ConsequencesRegistry::SERVICE_NAME, |
59 | SpecsFormatter::SERVICE_NAME, |
60 | ], |
61 | AbuseFilterViewExamine::class => [ |
62 | 'DBLoadBalancerFactory', |
63 | AbuseFilterPermissionManager::SERVICE_NAME, |
64 | FilterLookup::SERVICE_NAME, |
65 | EditBoxBuilderFactory::SERVICE_NAME, |
66 | VariablesBlobStore::SERVICE_NAME, |
67 | VariablesFormatter::SERVICE_NAME, |
68 | VariablesManager::SERVICE_NAME, |
69 | VariableGeneratorFactory::SERVICE_NAME, |
70 | ], |
71 | AbuseFilterViewHistory::class => [ |
72 | 'UserNameUtils', |
73 | 'LinkBatchFactory', |
74 | AbuseFilterPermissionManager::SERVICE_NAME, |
75 | FilterLookup::SERVICE_NAME, |
76 | SpecsFormatter::SERVICE_NAME, |
77 | ], |
78 | AbuseFilterViewImport::class => [ |
79 | AbuseFilterPermissionManager::SERVICE_NAME, |
80 | ], |
81 | AbuseFilterViewList::class => [ |
82 | 'LinkBatchFactory', |
83 | 'ConnectionProvider', |
84 | AbuseFilterPermissionManager::SERVICE_NAME, |
85 | FilterProfiler::SERVICE_NAME, |
86 | SpecsFormatter::SERVICE_NAME, |
87 | CentralDBManager::SERVICE_NAME, |
88 | ], |
89 | AbuseFilterViewRevert::class => [ |
90 | 'DBLoadBalancerFactory', |
91 | 'UserFactory', |
92 | AbuseFilterPermissionManager::SERVICE_NAME, |
93 | FilterLookup::SERVICE_NAME, |
94 | ConsequencesFactory::SERVICE_NAME, |
95 | VariablesBlobStore::SERVICE_NAME, |
96 | SpecsFormatter::SERVICE_NAME, |
97 | ], |
98 | AbuseFilterViewTestBatch::class => [ |
99 | 'DBLoadBalancerFactory', |
100 | AbuseFilterPermissionManager::SERVICE_NAME, |
101 | EditBoxBuilderFactory::SERVICE_NAME, |
102 | RuleCheckerFactory::SERVICE_NAME, |
103 | VariableGeneratorFactory::SERVICE_NAME, |
104 | ], |
105 | AbuseFilterViewTools::class => [ |
106 | AbuseFilterPermissionManager::SERVICE_NAME, |
107 | EditBoxBuilderFactory::SERVICE_NAME, |
108 | ], |
109 | ]; |
110 | |
111 | /** |
112 | * @param AbuseFilterPermissionManager $afPermissionManager |
113 | * @param ObjectFactory $objectFactory |
114 | */ |
115 | public function __construct( |
116 | AbuseFilterPermissionManager $afPermissionManager, |
117 | ObjectFactory $objectFactory |
118 | ) { |
119 | parent::__construct( self::PAGE_NAME, 'abusefilter-view', $afPermissionManager ); |
120 | $this->objectFactory = $objectFactory; |
121 | } |
122 | |
123 | /** |
124 | * @codeCoverageIgnore Merely declarative |
125 | * @inheritDoc |
126 | */ |
127 | public function doesWrites() { |
128 | return true; |
129 | } |
130 | |
131 | /** |
132 | * @codeCoverageIgnore Merely declarative |
133 | * @inheritDoc |
134 | */ |
135 | protected function getGroupName() { |
136 | return 'wiki'; |
137 | } |
138 | |
139 | /** |
140 | * @param string|null $subpage |
141 | */ |
142 | public function execute( $subpage ) { |
143 | $out = $this->getOutput(); |
144 | $request = $this->getRequest(); |
145 | |
146 | $out->addModuleStyles( 'ext.abuseFilter' ); |
147 | |
148 | $this->setHeaders(); |
149 | $this->addHelpLink( 'Extension:AbuseFilter' ); |
150 | |
151 | $this->checkPermissions(); |
152 | |
153 | if ( $request->getVal( 'result' ) === 'success' ) { |
154 | $out->setSubtitle( $this->msg( 'abusefilter-edit-done-subtitle' ) ); |
155 | $changedFilter = intval( $request->getVal( 'changedfilter' ) ); |
156 | $changeId = intval( $request->getVal( 'changeid' ) ); |
157 | $out->addHTML( Html::successBox( |
158 | $this->msg( |
159 | 'abusefilter-edit-done', |
160 | $changedFilter, |
161 | $changeId, |
162 | $this->getLanguage()->formatNum( $changedFilter ) |
163 | )->parse() |
164 | ) ); |
165 | } |
166 | |
167 | [ $view, $pageType, $params ] = $this->getViewClassAndPageType( $subpage ); |
168 | |
169 | // Links at the top |
170 | $this->addNavigationLinks( $pageType ); |
171 | |
172 | $view = $this->instantiateView( $view, $params ); |
173 | $view->show(); |
174 | } |
175 | |
176 | /** |
177 | * Instantiate the view class |
178 | * |
179 | * @suppress PhanTypeInvalidCallableArraySize |
180 | * |
181 | * @param class-string<AbuseFilterView> $viewClass |
182 | * @param array $params |
183 | * @return AbuseFilterView |
184 | */ |
185 | public function instantiateView( string $viewClass, array $params ): AbuseFilterView { |
186 | return $this->objectFactory->createObject( [ |
187 | 'class' => $viewClass, |
188 | 'services' => self::SERVICES_PER_VIEW[$viewClass], |
189 | 'args' => [ $this->getContext(), $this->getLinkRenderer(), self::PAGE_NAME, $params ] |
190 | ] ); |
191 | } |
192 | |
193 | /** |
194 | * Determine the view class to instantiate |
195 | * |
196 | * @param string|null $subpage |
197 | * @return array A tuple of three elements: |
198 | * - a subclass of AbuseFilterView |
199 | * - type of page for addNavigationLinks |
200 | * - array of parameters for the class |
201 | * @phan-return array{0:class-string,1:string,2:array} |
202 | */ |
203 | public function getViewClassAndPageType( $subpage ): array { |
204 | // Filter by removing blanks. |
205 | $params = array_values( array_filter( |
206 | explode( '/', $subpage ?: '' ), |
207 | static function ( $value ) { |
208 | return $value !== ''; |
209 | } |
210 | ) ); |
211 | |
212 | if ( $subpage === 'tools' ) { |
213 | return [ AbuseFilterViewTools::class, 'tools', [] ]; |
214 | } |
215 | |
216 | if ( $subpage === 'import' ) { |
217 | return [ AbuseFilterViewImport::class, 'import', [] ]; |
218 | } |
219 | |
220 | if ( is_numeric( $subpage ) || $subpage === 'new' ) { |
221 | return [ |
222 | AbuseFilterViewEdit::class, |
223 | 'edit', |
224 | [ 'filter' => is_numeric( $subpage ) ? (int)$subpage : null ] |
225 | ]; |
226 | } |
227 | |
228 | if ( $params ) { |
229 | if ( count( $params ) === 2 && $params[0] === 'revert' && is_numeric( $params[1] ) ) { |
230 | $params[1] = (int)$params[1]; |
231 | return [ AbuseFilterViewRevert::class, 'revert', $params ]; |
232 | } |
233 | |
234 | if ( $params[0] === 'test' ) { |
235 | return [ AbuseFilterViewTestBatch::class, 'test', $params ]; |
236 | } |
237 | |
238 | if ( $params[0] === 'examine' ) { |
239 | return [ AbuseFilterViewExamine::class, 'examine', $params ]; |
240 | } |
241 | |
242 | if ( $params[0] === 'history' || $params[0] === 'log' ) { |
243 | if ( count( $params ) <= 2 ) { |
244 | $params = isset( $params[1] ) ? [ 'filter' => (int)$params[1] ] : []; |
245 | return [ AbuseFilterViewHistory::class, 'recentchanges', $params ]; |
246 | } |
247 | if ( count( $params ) === 4 && $params[2] === 'item' ) { |
248 | return [ |
249 | AbuseFilterViewEdit::class, |
250 | '', |
251 | [ 'filter' => (int)$params[1], 'history' => (int)$params[3] ] |
252 | ]; |
253 | } |
254 | if ( count( $params ) === 5 && $params[2] === 'diff' ) { |
255 | // Special:AbuseFilter/history/<filter>/diff/<oldid>/<newid> |
256 | return [ AbuseFilterViewDiff::class, '', $params ]; |
257 | } |
258 | } |
259 | } |
260 | |
261 | return [ AbuseFilterViewList::class, 'home', [] ]; |
262 | } |
263 | |
264 | /** |
265 | * Static variant to get the associated Title. |
266 | * |
267 | * @param string|int $subpage |
268 | * @return Title |
269 | */ |
270 | public static function getTitleForSubpage( $subpage ): Title { |
271 | return self::getTitleFor( self::PAGE_NAME, $subpage ); |
272 | } |
273 | } |