MediaWiki  master
SpecialBlockList.php
Go to the documentation of this file.
1 <?php
24 namespace MediaWiki\Specials;
25 
26 use HTMLForm;
37 use Wikimedia\IPUtils;
40 
47  protected $target;
48 
49  protected $options;
50 
51  protected $blockType;
52 
53  private LinkBatchFactory $linkBatchFactory;
54  private BlockRestrictionStore $blockRestrictionStore;
55  private IConnectionProvider $dbProvider;
56  private CommentStore $commentStore;
57  private BlockUtils $blockUtils;
58  private BlockActionInfo $blockActionInfo;
59  private RowCommentFormatter $rowCommentFormatter;
60 
61  public function __construct(
62  LinkBatchFactory $linkBatchFactory,
63  BlockRestrictionStore $blockRestrictionStore,
64  IConnectionProvider $dbProvider,
65  CommentStore $commentStore,
66  BlockUtils $blockUtils,
67  BlockActionInfo $blockActionInfo,
68  RowCommentFormatter $rowCommentFormatter
69  ) {
70  parent::__construct( 'BlockList' );
71 
72  $this->linkBatchFactory = $linkBatchFactory;
73  $this->blockRestrictionStore = $blockRestrictionStore;
74  $this->dbProvider = $dbProvider;
75  $this->commentStore = $commentStore;
76  $this->blockUtils = $blockUtils;
77  $this->blockActionInfo = $blockActionInfo;
78  $this->rowCommentFormatter = $rowCommentFormatter;
79  }
80 
84  public function execute( $par ) {
85  $this->setHeaders();
86  $this->outputHeader();
87  $this->addHelpLink( 'Help:Blocking_users' );
88  $out = $this->getOutput();
89  $out->setPageTitleMsg( $this->msg( 'ipblocklist' ) );
90  $out->addModuleStyles( [ 'mediawiki.special' ] );
91 
92  $request = $this->getRequest();
93  $par = $request->getVal( 'ip', $par ?? '' );
94  $this->target = trim( $request->getVal( 'wpTarget', $par ) );
95 
96  $this->options = $request->getArray( 'wpOptions', [] );
97  $this->blockType = $request->getVal( 'blockType' );
98 
99  $action = $request->getText( 'action' );
100 
101  if ( $action == 'unblock' || $action == 'submit' && $request->wasPosted() ) {
102  // B/C @since 1.18: Unblock interface is now at Special:Unblock
103  $title = $this->getSpecialPageFactory()->getTitleForAlias( 'Unblock/' . $this->target );
104  $out->redirect( $title->getFullURL() );
105 
106  return;
107  }
108 
109  // Setup BlockListPager here to get the actual default Limit
110  $pager = $this->getBlockListPager();
111 
112  // Just show the block list
113  $fields = [
114  'Target' => [
115  'type' => 'user',
116  'label-message' => 'ipaddressorusername',
117  'tabindex' => '1',
118  'size' => '45',
119  'default' => $this->target,
120  ],
121  'Options' => [
122  'type' => 'multiselect',
123  'options-messages' => [
124  'blocklist-tempblocks' => 'tempblocks',
125  'blocklist-indefblocks' => 'indefblocks',
126  'blocklist-autoblocks' => 'autoblocks',
127  'blocklist-userblocks' => 'userblocks',
128  'blocklist-addressblocks' => 'addressblocks',
129  'blocklist-rangeblocks' => 'rangeblocks',
130  ],
131  'flatlist' => true,
132  ],
133  ];
134 
135  $fields['BlockType'] = [
136  'type' => 'select',
137  'label-message' => 'blocklist-type',
138  'options' => [
139  $this->msg( 'blocklist-type-opt-all' )->escaped() => '',
140  $this->msg( 'blocklist-type-opt-sitewide' )->escaped() => 'sitewide',
141  $this->msg( 'blocklist-type-opt-partial' )->escaped() => 'partial',
142  ],
143  'name' => 'blockType',
144  'cssclass' => 'mw-field-block-type',
145  ];
146 
147  $fields['Limit'] = [
148  'type' => 'limitselect',
149  'label-message' => 'table_pager_limit_label',
150  'options' => $pager->getLimitSelectList(),
151  'name' => 'limit',
152  'default' => $pager->getLimit(),
153  'cssclass' => 'mw-field-limit mw-has-field-block-type',
154  ];
155 
156  $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
157  $form
158  ->setMethod( 'get' )
159  ->setTitle( $this->getPageTitle() ) // Remove subpage
160  ->setFormIdentifier( 'blocklist' )
161  ->setWrapperLegendMsg( 'ipblocklist-legend' )
162  ->setSubmitTextMsg( 'ipblocklist-submit' )
163  ->prepareForm()
164  ->displayForm( false );
165 
166  $this->showList( $pager );
167  }
168 
173  protected function getBlockListPager() {
174  $conds = [];
175  $db = $this->getDB();
176  // Is the user allowed to see hidden blocks?
177  if ( !$this->getAuthority()->isAllowed( 'hideuser' ) ) {
178  $conds['ipb_deleted'] = 0;
179  }
180 
181  if ( $this->target !== '' ) {
182  [ $target, $type ] = $this->blockUtils->parseBlockTarget( $this->target );
183 
184  switch ( $type ) {
187  $conds['ipb_id'] = $target;
188  break;
189 
192  [ $start, $end ] = IPUtils::parseRange( $target );
193  $conds[] = $db->makeList(
194  [
195  'ipb_address' => $target,
196  DatabaseBlock::getRangeCond( $start, $end )
197  ],
198  LIST_OR
199  );
200  $conds['ipb_auto'] = 0;
201  break;
202 
204  $conds['ipb_address'] = $target->getName();
205  $conds['ipb_auto'] = 0;
206  break;
207  }
208  }
209 
210  // Apply filters
211  if ( in_array( 'userblocks', $this->options ) ) {
212  $conds['ipb_user'] = 0;
213  }
214  if ( in_array( 'autoblocks', $this->options ) ) {
215  // ipb_parent_block_id = 0 because of T282890
216  $conds['ipb_parent_block_id'] = [ null, 0 ];
217  }
218  if ( in_array( 'addressblocks', $this->options ) ) {
219  $conds[] = "ipb_user != 0 OR ipb_range_end > ipb_range_start";
220  }
221  if ( in_array( 'rangeblocks', $this->options ) ) {
222  $conds[] = "ipb_range_end = ipb_range_start";
223  }
224 
225  $hideTemp = in_array( 'tempblocks', $this->options );
226  $hideIndef = in_array( 'indefblocks', $this->options );
227  if ( $hideTemp && $hideIndef ) {
228  // If both types are hidden, ensure query doesn't produce any results
229  $conds[] = '1=0';
230  } elseif ( $hideTemp ) {
231  $conds['ipb_expiry'] = $db->getInfinity();
232  } elseif ( $hideIndef ) {
233  $conds[] = "ipb_expiry != " . $db->addQuotes( $db->getInfinity() );
234  }
235 
236  if ( $this->blockType === 'sitewide' ) {
237  $conds['ipb_sitewide'] = 1;
238  } elseif ( $this->blockType === 'partial' ) {
239  $conds['ipb_sitewide'] = 0;
240  }
241 
242  return new BlockListPager(
243  $this->getContext(),
244  $this->blockActionInfo,
245  $this->blockRestrictionStore,
246  $this->blockUtils,
247  $this->commentStore,
248  $this->linkBatchFactory,
249  $this->getLinkRenderer(),
250  $this->dbProvider,
251  $this->rowCommentFormatter,
252  $this->getSpecialPageFactory(),
253  $conds
254  );
255  }
256 
261  protected function showList( BlockListPager $pager ) {
262  $out = $this->getOutput();
263 
264  // Check for other blocks, i.e. global/tor blocks
265  $otherBlockLink = [];
266  $this->getHookRunner()->onOtherBlockLogLink( $otherBlockLink, $this->target );
267 
268  // Show additional header for the local block only when other blocks exists.
269  // Not necessary in a standard installation without such extensions enabled
270  if ( count( $otherBlockLink ) ) {
271  $out->addHTML(
272  Html::element( 'h2', [], $this->msg( 'ipblocklist-localblock' )->text() ) . "\n"
273  );
274  }
275 
276  if ( $pager->getNumRows() ) {
277  $out->addParserOutputContent( $pager->getFullOutput() );
278  } elseif ( $this->target ) {
279  $out->addWikiMsg( 'ipblocklist-no-results' );
280  } else {
281  $out->addWikiMsg( 'ipblocklist-empty' );
282  }
283 
284  if ( count( $otherBlockLink ) ) {
285  $out->addHTML(
287  'h2',
288  [],
289  $this->msg( 'ipblocklist-otherblocks', count( $otherBlockLink ) )->parse()
290  ) . "\n"
291  );
292  $list = '';
293  foreach ( $otherBlockLink as $link ) {
294  $list .= Html::rawElement( 'li', [], $link ) . "\n";
295  }
296  $out->addHTML( Html::rawElement(
297  'ul',
298  [ 'class' => 'mw-ipblocklist-otherblocks' ],
299  $list
300  ) . "\n" );
301  }
302  }
303 
304  protected function getGroupName() {
305  return 'users';
306  }
307 
313  protected function getDB() {
314  return $this->dbProvider->getReplicaDatabase();
315  }
316 }
317 
321 class_alias( SpecialBlockList::class, 'SpecialBlockList' );
const LIST_OR
Definition: Defines.php:46
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:158
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:360
Defines the actions that can be blocked by a partial block.
Backend class for blocking utils.
Definition: BlockUtils.php:46
A DatabaseBlock (unlike a SystemBlock) is stored in the database, may give rise to autoblocks and may...
static getRangeCond( $start, $end=null)
Get a set of SQL conditions which will select range blocks encompassing a given range.
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.
This class is a collection of static functions that serve two purposes:
Definition: Html.php:57
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:239
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:264
getNumRows()
Get the number of rows in the result set.
Definition: IndexPager.php:737
getFullOutput()
Get the formatted result list, with navigation bars.
Definition: TablePager.php:116
Parent class for all special pages.
Definition: SpecialPage.php:65
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.
getAuthority()
Shortcut to get the Authority executing this instance.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
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, BlockRestrictionStore $blockRestrictionStore, IConnectionProvider $dbProvider, CommentStore $commentStore, BlockUtils $blockUtils, 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.
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:36