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