MediaWiki master
SpecialBlockList.php
Go to the documentation of this file.
1<?php
24namespace MediaWiki\Specials;
25
39use Wikimedia\IPUtils;
42
49 protected $target;
50
51 protected $options;
52
53 protected $blockType;
54
55 private LinkBatchFactory $linkBatchFactory;
56 private DatabaseBlockStore $blockStore;
57 private BlockRestrictionStore $blockRestrictionStore;
58 private IConnectionProvider $dbProvider;
59 private CommentStore $commentStore;
60 private BlockUtils $blockUtils;
61 private HideUserUtils $hideUserUtils;
62 private BlockActionInfo $blockActionInfo;
63 private RowCommentFormatter $rowCommentFormatter;
64
65 public function __construct(
66 LinkBatchFactory $linkBatchFactory,
67 DatabaseBlockStore $blockStore,
68 BlockRestrictionStore $blockRestrictionStore,
69 IConnectionProvider $dbProvider,
70 CommentStore $commentStore,
71 BlockUtils $blockUtils,
72 HideUserUtils $hideUserUtils,
73 BlockActionInfo $blockActionInfo,
74 RowCommentFormatter $rowCommentFormatter
75 ) {
76 parent::__construct( 'BlockList' );
77
78 $this->linkBatchFactory = $linkBatchFactory;
79 $this->blockStore = $blockStore;
80 $this->blockRestrictionStore = $blockRestrictionStore;
81 $this->dbProvider = $dbProvider;
82 $this->commentStore = $commentStore;
83 $this->blockUtils = $blockUtils;
84 $this->hideUserUtils = $hideUserUtils;
85 $this->blockActionInfo = $blockActionInfo;
86 $this->rowCommentFormatter = $rowCommentFormatter;
87 }
88
92 public function execute( $par ) {
93 $this->setHeaders();
94 $this->outputHeader();
95 $this->addHelpLink( 'Help:Blocking_users' );
96 $out = $this->getOutput();
97 $out->setPageTitleMsg( $this->msg( 'ipblocklist' ) );
98 $out->addModuleStyles( [ 'mediawiki.special' ] );
99
100 $request = $this->getRequest();
101 $par = $request->getVal( 'ip', $par ?? '' );
102 $this->target = trim( $request->getVal( 'wpTarget', $par ) );
103
104 $this->options = $request->getArray( 'wpOptions', [] );
105 $this->blockType = $request->getVal( 'blockType' );
106
107 $action = $request->getText( 'action' );
108
109 if ( $action == 'unblock' || ( $action == 'submit' && $request->wasPosted() ) ) {
110 // B/C @since 1.18: Unblock interface is now at Special:Unblock
111 $title = $this->getSpecialPageFactory()->getTitleForAlias( 'Unblock/' . $this->target );
112 $out->redirect( $title->getFullURL() );
113
114 return;
115 }
116
117 // Setup BlockListPager here to get the actual default Limit
118 $pager = $this->getBlockListPager();
119
120 // Just show the block list
121 $fields = [
122 'Target' => [
123 'type' => 'user',
124 'label-message' => 'ipaddressorusername',
125 'tabindex' => '1',
126 'size' => '45',
127 'default' => $this->target,
128 ],
129 'Options' => [
130 'type' => 'multiselect',
131 'options-messages' => [
132 'blocklist-tempblocks' => 'tempblocks',
133 'blocklist-indefblocks' => 'indefblocks',
134 'blocklist-autoblocks' => 'autoblocks',
135 'blocklist-userblocks' => 'userblocks',
136 'blocklist-addressblocks' => 'addressblocks',
137 'blocklist-rangeblocks' => 'rangeblocks',
138 ],
139 'flatlist' => true,
140 ],
141 ];
142
143 $fields['BlockType'] = [
144 'type' => 'select',
145 'label-message' => 'blocklist-type',
146 'options' => [
147 $this->msg( 'blocklist-type-opt-all' )->escaped() => '',
148 $this->msg( 'blocklist-type-opt-sitewide' )->escaped() => 'sitewide',
149 $this->msg( 'blocklist-type-opt-partial' )->escaped() => 'partial',
150 ],
151 'name' => 'blockType',
152 'cssclass' => 'mw-field-block-type',
153 ];
154
155 $fields['Limit'] = [
156 'type' => 'limitselect',
157 'label-message' => 'table_pager_limit_label',
158 'options' => $pager->getLimitSelectList(),
159 'name' => 'limit',
160 'default' => $pager->getLimit(),
161 'cssclass' => 'mw-field-limit mw-has-field-block-type',
162 ];
163
164 $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
165 $form
166 ->setMethod( 'get' )
167 ->setTitle( $this->getPageTitle() ) // Remove subpage
168 ->setFormIdentifier( 'blocklist' )
169 ->setWrapperLegendMsg( 'ipblocklist-legend' )
170 ->setSubmitTextMsg( 'ipblocklist-submit' )
171 ->prepareForm()
172 ->displayForm( false );
173
174 $this->showList( $pager );
175 }
176
181 protected function getBlockListPager() {
182 $conds = [];
183 $db = $this->getDB();
184
185 if ( $this->target !== '' ) {
186 [ $target, $type ] = $this->blockUtils->parseBlockTarget( $this->target );
187
188 switch ( $type ) {
189 case DatabaseBlock::TYPE_ID:
190 case DatabaseBlock::TYPE_AUTO:
191 $conds['bl_id'] = $target;
192 break;
193
194 case DatabaseBlock::TYPE_IP:
195 case DatabaseBlock::TYPE_RANGE:
196 [ $start, $end ] = IPUtils::parseRange( $target );
197 $conds[] = $this->blockStore->getRangeCond( $start, $end );
198 $conds['bt_auto'] = 0;
199 break;
200
201 case DatabaseBlock::TYPE_USER:
202 if ( $target->getId() ) {
203 $conds['bt_user'] = $target->getId();
204 $conds['bt_auto'] = 0;
205 } else {
206 // No such user
207 $conds[] = '1=0';
208 }
209 break;
210 }
211 }
212
213 // Apply filters
214 if ( in_array( 'userblocks', $this->options ) ) {
215 $conds['bt_user'] = null;
216 }
217 if ( in_array( 'autoblocks', $this->options ) ) {
218 $conds['bl_parent_block_id'] = null;
219 }
220 if ( in_array( 'addressblocks', $this->options )
221 && in_array( 'rangeblocks', $this->options )
222 ) {
223 // Simpler conditions for only user blocks (T360864)
224 $conds[] = "bt_user IS NOT NULL";
225 } elseif ( in_array( 'addressblocks', $this->options ) ) {
226 $conds[] = "bt_user IS NOT NULL OR bt_range_start IS NOT NULL";
227 } elseif ( in_array( 'rangeblocks', $this->options ) ) {
228 $conds['bt_range_start'] = null;
229 }
230
231 $hideTemp = in_array( 'tempblocks', $this->options );
232 $hideIndef = in_array( 'indefblocks', $this->options );
233 if ( $hideTemp && $hideIndef ) {
234 // If both types are hidden, ensure query doesn't produce any results
235 $conds[] = '1=0';
236 } elseif ( $hideTemp ) {
237 $conds['bl_expiry'] = $db->getInfinity();
238 } elseif ( $hideIndef ) {
239 $conds[] = $db->expr( 'bl_expiry', '!=', $db->getInfinity() );
240 }
241
242 if ( $this->blockType === 'sitewide' ) {
243 $conds['bl_sitewide'] = 1;
244 } elseif ( $this->blockType === 'partial' ) {
245 $conds['bl_sitewide'] = 0;
246 }
247
248 return new BlockListPager(
249 $this->getContext(),
250 $this->blockActionInfo,
251 $this->blockRestrictionStore,
252 $this->blockUtils,
253 $this->hideUserUtils,
254 $this->commentStore,
255 $this->linkBatchFactory,
256 $this->getLinkRenderer(),
257 $this->dbProvider,
258 $this->rowCommentFormatter,
259 $this->getSpecialPageFactory(),
260 $conds
261 );
262 }
263
268 protected function showList( BlockListPager $pager ) {
269 $out = $this->getOutput();
270
271 // Check for other blocks, i.e. global/tor blocks
272 $otherBlockLink = [];
273 $this->getHookRunner()->onOtherBlockLogLink( $otherBlockLink, $this->target );
274
275 // Show additional header for the local block only when other blocks exists.
276 // Not necessary in a standard installation without such extensions enabled
277 if ( count( $otherBlockLink ) ) {
278 $out->addHTML(
279 Html::element( 'h2', [], $this->msg( 'ipblocklist-localblock' )->text() ) . "\n"
280 );
281 }
282
283 if ( $pager->getNumRows() ) {
284 $out->addParserOutputContent( $pager->getFullOutput() );
285 } elseif ( $this->target ) {
286 $out->addWikiMsg( 'ipblocklist-no-results' );
287 } else {
288 $out->addWikiMsg( 'ipblocklist-empty' );
289 }
290
291 if ( count( $otherBlockLink ) ) {
292 $out->addHTML(
293 Html::rawElement(
294 'h2',
295 [],
296 $this->msg( 'ipblocklist-otherblocks', count( $otherBlockLink ) )->parse()
297 ) . "\n"
298 );
299 $list = '';
300 foreach ( $otherBlockLink as $link ) {
301 $list .= Html::rawElement( 'li', [], $link ) . "\n";
302 }
303 $out->addHTML( Html::rawElement(
304 'ul',
305 [ 'class' => 'mw-ipblocklist-otherblocks' ],
306 $list
307 ) . "\n" );
308 }
309 }
310
311 protected function getGroupName() {
312 return 'users';
313 }
314
320 protected function getDB() {
321 return $this->dbProvider->getReplicaDatabase();
322 }
323}
324
326class_alias( SpecialBlockList::class, 'SpecialBlockList' );
Defines the actions that can be blocked by a partial block.
Backend class for blocking utils.
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
Helpers for building queries that determine whether a user is hidden.
This is basically a CommentFormatter with a CommentStore dependency, allowing it to retrieve comment ...
Handle database storage of comments such as edit summaries and log reasons.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:206
This class is a collection of static functions that serve two purposes:
Definition Html.php:56
getNumRows()
Get the number of rows in the result set.
getFullOutput()
Get the formatted result list, with navigation bars.
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getPageTitle( $subpage=false)
Get a self-referential title object.
getContext()
Gets the context this SpecialPage is executed in.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages By default the message key is the canonical name of...
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
A special page that lists existing blocks.
showList(BlockListPager $pager)
Show the list of blocked accounts matching the actual filter.
__construct(LinkBatchFactory $linkBatchFactory, DatabaseBlockStore $blockStore, BlockRestrictionStore $blockRestrictionStore, IConnectionProvider $dbProvider, CommentStore $commentStore, BlockUtils $blockUtils, HideUserUtils $hideUserUtils, BlockActionInfo $blockActionInfo, RowCommentFormatter $rowCommentFormatter)
getDB()
Return a IDatabase object for reading.
getBlockListPager()
Setup a new BlockListPager instance.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Provide primary and replica IDatabase connections.
A database connection without write operations.
element(SerializerNode $parent, SerializerNode $node, $contents)
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...