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