MediaWiki master
SpecialBlockList.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\Specials;
22
36use Wikimedia\IPUtils;
39
49 protected $target;
50
52 protected $options;
53
55 protected $blockType;
56
57 private LinkBatchFactory $linkBatchFactory;
58 private DatabaseBlockStore $blockStore;
59 private BlockRestrictionStore $blockRestrictionStore;
60 private IConnectionProvider $dbProvider;
61 private CommentStore $commentStore;
62 private BlockUtils $blockUtils;
63 private HideUserUtils $hideUserUtils;
64 private BlockActionInfo $blockActionInfo;
65 private RowCommentFormatter $rowCommentFormatter;
66
67 public function __construct(
68 LinkBatchFactory $linkBatchFactory,
69 DatabaseBlockStore $blockStore,
70 BlockRestrictionStore $blockRestrictionStore,
71 IConnectionProvider $dbProvider,
72 CommentStore $commentStore,
73 BlockUtils $blockUtils,
74 HideUserUtils $hideUserUtils,
75 BlockActionInfo $blockActionInfo,
76 RowCommentFormatter $rowCommentFormatter
77 ) {
78 parent::__construct( 'BlockList' );
79
80 $this->linkBatchFactory = $linkBatchFactory;
81 $this->blockStore = $blockStore;
82 $this->blockRestrictionStore = $blockRestrictionStore;
83 $this->dbProvider = $dbProvider;
84 $this->commentStore = $commentStore;
85 $this->blockUtils = $blockUtils;
86 $this->hideUserUtils = $hideUserUtils;
87 $this->blockActionInfo = $blockActionInfo;
88 $this->rowCommentFormatter = $rowCommentFormatter;
89 }
90
94 public function execute( $par ) {
95 $this->setHeaders();
96 $this->outputHeader();
97 $this->addHelpLink( 'Help:Blocking_users' );
98 $out = $this->getOutput();
99 $out->setPageTitleMsg( $this->msg( 'ipblocklist' ) );
100 $out->addModuleStyles( [ 'mediawiki.special' ] );
101
102 $request = $this->getRequest();
103 $par = $request->getVal( 'ip', $par ?? '' );
104 $this->target = trim( $request->getVal( 'wpTarget', $par ) );
105
106 $this->options = $request->getArray( 'wpOptions', [] );
107 $this->blockType = $request->getVal( 'blockType' );
108
109 $action = $request->getText( 'action' );
110
111 if ( $action == 'unblock' || ( $action == 'submit' && $request->wasPosted() ) ) {
112 // B/C @since 1.18: Unblock interface is now at Special:Unblock
113 $title = $this->getSpecialPageFactory()->getTitleForAlias( 'Unblock/' . $this->target );
114 $out->redirect( $title->getFullURL() );
115
116 return;
117 }
118
119 // Setup BlockListPager here to get the actual default Limit
120 $pager = $this->getBlockListPager();
121
122 // Just show the block list
123 $fields = [
124 'Target' => [
125 'type' => 'user',
126 'label-message' => 'ipaddressorusername',
127 'tabindex' => '1',
128 'size' => '45',
129 'default' => $this->target,
130 ],
131 'Options' => [
132 'type' => 'multiselect',
133 'options-messages' => [
134 'blocklist-tempblocks' => 'tempblocks',
135 'blocklist-indefblocks' => 'indefblocks',
136 'blocklist-autoblocks' => 'autoblocks',
137 'blocklist-userblocks' => 'userblocks',
138 'blocklist-addressblocks' => 'addressblocks',
139 'blocklist-rangeblocks' => 'rangeblocks',
140 ],
141 'flatlist' => true,
142 ],
143 ];
144
145 $fields['BlockType'] = [
146 'type' => 'select',
147 'label-message' => 'blocklist-type',
148 'options' => [
149 $this->msg( 'blocklist-type-opt-all' )->escaped() => '',
150 $this->msg( 'blocklist-type-opt-sitewide' )->escaped() => 'sitewide',
151 $this->msg( 'blocklist-type-opt-partial' )->escaped() => 'partial',
152 ],
153 'name' => 'blockType',
154 'cssclass' => 'mw-field-block-type',
155 ];
156
157 $fields['Limit'] = [
158 'type' => 'limitselect',
159 'label-message' => 'table_pager_limit_label',
160 'options' => $pager->getLimitSelectList(),
161 'name' => 'limit',
162 'default' => $pager->getLimit(),
163 'cssclass' => 'mw-field-limit mw-has-field-block-type',
164 ];
165
166 $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
167 $form
168 ->setMethod( 'get' )
169 ->setTitle( $this->getPageTitle() ) // Remove subpage
170 ->setFormIdentifier( 'blocklist' )
171 ->setWrapperLegendMsg( 'ipblocklist-legend' )
172 ->setSubmitTextMsg( 'ipblocklist-submit' )
173 ->prepareForm()
174 ->displayForm( false );
175
176 $this->showList( $pager );
177 }
178
183 protected function getBlockListPager() {
184 $conds = [];
185 $db = $this->getDB();
186
187 if ( $this->target !== '' ) {
188 [ $target, $type ] = $this->blockUtils->parseBlockTarget( $this->target );
189
190 switch ( $type ) {
191 case DatabaseBlock::TYPE_ID:
192 case DatabaseBlock::TYPE_AUTO:
193 $conds['bl_id'] = $target;
194 break;
195
196 case DatabaseBlock::TYPE_IP:
197 case DatabaseBlock::TYPE_RANGE:
198 [ $start, $end ] = IPUtils::parseRange( $target );
199 $conds[] = $this->blockStore->getRangeCond( $start, $end );
200 $conds['bt_auto'] = 0;
201 break;
202
203 case DatabaseBlock::TYPE_USER:
204 if ( $target->getId() ) {
205 $conds['bt_user'] = $target->getId();
206 $conds['bt_auto'] = 0;
207 } else {
208 // No such user
209 $conds[] = '1=0';
210 }
211 break;
212 }
213 }
214
215 // Apply filters
216 if ( in_array( 'userblocks', $this->options ) ) {
217 $conds['bt_user'] = null;
218 }
219 if ( in_array( 'autoblocks', $this->options ) ) {
220 $conds['bl_parent_block_id'] = null;
221 }
222 if ( in_array( 'addressblocks', $this->options )
223 && in_array( 'rangeblocks', $this->options )
224 ) {
225 // Simpler conditions for only user blocks (T360864)
226 $conds[] = $db->expr( 'bt_user', '!=', null );
227 } elseif ( in_array( 'addressblocks', $this->options ) ) {
228 $conds[] = $db->expr( 'bt_user', '!=', null )->or( 'bt_range_start', '!=', null );
229 } elseif ( in_array( 'rangeblocks', $this->options ) ) {
230 $conds['bt_range_start'] = null;
231 }
232
233 $hideTemp = in_array( 'tempblocks', $this->options );
234 $hideIndef = in_array( 'indefblocks', $this->options );
235 if ( $hideTemp && $hideIndef ) {
236 // If both types are hidden, ensure query doesn't produce any results
237 $conds[] = '1=0';
238 } elseif ( $hideTemp ) {
239 $conds['bl_expiry'] = $db->getInfinity();
240 } elseif ( $hideIndef ) {
241 $conds[] = $db->expr( 'bl_expiry', '!=', $db->getInfinity() );
242 }
243
244 if ( $this->blockType === 'sitewide' ) {
245 $conds['bl_sitewide'] = 1;
246 } elseif ( $this->blockType === 'partial' ) {
247 $conds['bl_sitewide'] = 0;
248 }
249
250 return new BlockListPager(
251 $this->getContext(),
252 $this->blockActionInfo,
253 $this->blockRestrictionStore,
254 $this->blockUtils,
255 $this->hideUserUtils,
256 $this->commentStore,
257 $this->linkBatchFactory,
258 $this->getLinkRenderer(),
259 $this->dbProvider,
260 $this->rowCommentFormatter,
261 $this->getSpecialPageFactory(),
262 $conds
263 );
264 }
265
270 protected function showList( BlockListPager $pager ) {
271 $out = $this->getOutput();
272
273 // Check for other blocks, i.e. global/tor blocks
274 $otherBlockLink = [];
275 $this->getHookRunner()->onOtherBlockLogLink( $otherBlockLink, $this->target );
276
277 // Show additional header for the local block only when other blocks exists.
278 // Not necessary in a standard installation without such extensions enabled
279 if ( count( $otherBlockLink ) ) {
280 $out->addHTML(
281 Html::element( 'h2', [], $this->msg( 'ipblocklist-localblock' )->text() ) . "\n"
282 );
283 }
284
285 if ( $pager->getNumRows() ) {
286 $out->addParserOutputContent( $pager->getFullOutput() );
287 } elseif ( $this->target ) {
288 $out->addWikiMsg( 'ipblocklist-no-results' );
289 } else {
290 $out->addWikiMsg( 'ipblocklist-empty' );
291 }
292
293 if ( count( $otherBlockLink ) ) {
294 $out->addHTML(
295 Html::rawElement(
296 'h2',
297 [],
298 $this->msg( 'ipblocklist-otherblocks', count( $otherBlockLink ) )->parse()
299 ) . "\n"
300 );
301 $list = '';
302 foreach ( $otherBlockLink as $link ) {
303 $list .= Html::rawElement( 'li', [], $link ) . "\n";
304 }
305 $out->addHTML( Html::rawElement(
306 'ul',
307 [ 'class' => 'mw-ipblocklist-otherblocks' ],
308 $list
309 ) . "\n" );
310 }
311 }
312
313 protected function getGroupName() {
314 return 'users';
315 }
316
322 protected function getDB() {
323 return $this->dbProvider->getReplicaDatabase();
324 }
325}
326
328class_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:209
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.
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)