Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
82.35% |
56 / 68 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
SpecialAbuseFilter | |
82.35% |
56 / 68 |
|
80.00% |
4 / 5 |
32.31 | |
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 | |
47.83% |
11 / 23 |
|
0.00% |
0 / 1 |
2.57 | |||
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 | 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 | AbuseLoggerFactory::SERVICE_NAME |
71 | ], |
72 | AbuseFilterViewHistory::class => [ |
73 | 'UserNameUtils', |
74 | 'LinkBatchFactory', |
75 | AbuseFilterPermissionManager::SERVICE_NAME, |
76 | FilterLookup::SERVICE_NAME, |
77 | SpecsFormatter::SERVICE_NAME, |
78 | ], |
79 | AbuseFilterViewImport::class => [ |
80 | AbuseFilterPermissionManager::SERVICE_NAME, |
81 | ], |
82 | AbuseFilterViewList::class => [ |
83 | 'LinkBatchFactory', |
84 | 'ConnectionProvider', |
85 | AbuseFilterPermissionManager::SERVICE_NAME, |
86 | FilterProfiler::SERVICE_NAME, |
87 | SpecsFormatter::SERVICE_NAME, |
88 | CentralDBManager::SERVICE_NAME, |
89 | FilterLookup::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->addModuleStyles( 'mediawiki.codex.messagebox.styles' ); |
160 | $out->addHTML( Html::successBox( |
161 | $this->msg( |
162 | 'abusefilter-edit-done', |
163 | $changedFilter, |
164 | $changeId, |
165 | $this->getLanguage()->formatNum( $changedFilter ) |
166 | )->parse() |
167 | ) ); |
168 | } |
169 | |
170 | [ $view, $pageType, $params ] = $this->getViewClassAndPageType( $subpage ); |
171 | |
172 | // Links at the top |
173 | $this->addNavigationLinks( $pageType ); |
174 | |
175 | $view = $this->instantiateView( $view, $params ); |
176 | $view->show(); |
177 | } |
178 | |
179 | /** |
180 | * Instantiate the view class |
181 | * |
182 | * @suppress PhanTypeInvalidCallableArraySize |
183 | * |
184 | * @param class-string<AbuseFilterView> $viewClass |
185 | * @param array $params |
186 | * @return AbuseFilterView |
187 | */ |
188 | public function instantiateView( string $viewClass, array $params ): AbuseFilterView { |
189 | return $this->objectFactory->createObject( [ |
190 | 'class' => $viewClass, |
191 | 'services' => self::SERVICES_PER_VIEW[$viewClass], |
192 | 'args' => [ $this->getContext(), $this->getLinkRenderer(), self::PAGE_NAME, $params ] |
193 | ] ); |
194 | } |
195 | |
196 | /** |
197 | * Determine the view class to instantiate |
198 | * |
199 | * @param string|null $subpage |
200 | * @return array A tuple of three elements: |
201 | * - a subclass of AbuseFilterView |
202 | * - type of page for addNavigationLinks |
203 | * - array of parameters for the class |
204 | * @phan-return array{0:class-string,1:string,2:array} |
205 | */ |
206 | public function getViewClassAndPageType( $subpage ): array { |
207 | // Filter by removing blanks. |
208 | $params = array_values( array_filter( |
209 | explode( '/', $subpage ?: '' ), |
210 | static function ( $value ) { |
211 | return $value !== ''; |
212 | } |
213 | ) ); |
214 | |
215 | if ( $subpage === 'tools' ) { |
216 | return [ AbuseFilterViewTools::class, 'tools', [] ]; |
217 | } |
218 | |
219 | if ( $subpage === 'import' ) { |
220 | return [ AbuseFilterViewImport::class, 'import', [] ]; |
221 | } |
222 | |
223 | if ( is_numeric( $subpage ) || $subpage === 'new' ) { |
224 | return [ |
225 | AbuseFilterViewEdit::class, |
226 | 'edit', |
227 | [ 'filter' => is_numeric( $subpage ) ? (int)$subpage : null ] |
228 | ]; |
229 | } |
230 | |
231 | if ( $params ) { |
232 | if ( count( $params ) === 2 && $params[0] === 'revert' && is_numeric( $params[1] ) ) { |
233 | $params[1] = (int)$params[1]; |
234 | return [ AbuseFilterViewRevert::class, 'revert', $params ]; |
235 | } |
236 | |
237 | if ( $params[0] === 'test' ) { |
238 | return [ AbuseFilterViewTestBatch::class, 'test', $params ]; |
239 | } |
240 | |
241 | if ( $params[0] === 'examine' ) { |
242 | return [ AbuseFilterViewExamine::class, 'examine', $params ]; |
243 | } |
244 | |
245 | if ( $params[0] === 'history' || $params[0] === 'log' ) { |
246 | if ( count( $params ) <= 2 ) { |
247 | $params = isset( $params[1] ) ? [ 'filter' => (int)$params[1] ] : []; |
248 | return [ AbuseFilterViewHistory::class, 'recentchanges', $params ]; |
249 | } |
250 | if ( count( $params ) === 4 && $params[2] === 'item' ) { |
251 | return [ |
252 | AbuseFilterViewEdit::class, |
253 | '', |
254 | [ 'filter' => (int)$params[1], 'history' => (int)$params[3] ] |
255 | ]; |
256 | } |
257 | if ( count( $params ) === 5 && $params[2] === 'diff' ) { |
258 | // Special:AbuseFilter/history/<filter>/diff/<oldid>/<newid> |
259 | return [ AbuseFilterViewDiff::class, '', $params ]; |
260 | } |
261 | } |
262 | } |
263 | |
264 | return [ AbuseFilterViewList::class, 'home', [] ]; |
265 | } |
266 | |
267 | /** |
268 | * Static variant to get the associated Title. |
269 | * |
270 | * @param string|int $subpage |
271 | * @return Title |
272 | */ |
273 | public static function getTitleForSubpage( $subpage ): Title { |
274 | return self::getTitleFor( self::PAGE_NAME, $subpage ); |
275 | } |
276 | } |