38 use Wikimedia\IPUtils;
57 private $blockActionInfo;
60 private $blockRestrictionStore;
66 private $commentStore;
69 private $linkBatchFactory;
72 private $rowCommentFormatter;
75 private $specialPageFactory;
78 private $formattedComments = [];
108 parent::__construct( $context, $linkRenderer );
109 $this->blockActionInfo = $blockActionInfo;
110 $this->blockRestrictionStore = $blockRestrictionStore;
111 $this->blockUtils = $blockUtils;
112 $this->commentStore = $commentStore;
113 $this->linkBatchFactory = $linkBatchFactory;
114 $this->rowCommentFormatter = $rowCommentFormatter;
115 $this->specialPageFactory = $specialPageFactory;
121 static $headers =
null;
123 if ( $headers ===
null ) {
125 'ipb_timestamp' =>
'blocklist-timestamp',
126 'ipb_target' =>
'blocklist-target',
127 'ipb_expiry' =>
'blocklist-expiry',
128 'ipb_by' =>
'blocklist-by',
129 'ipb_params' =>
'blocklist-params',
130 'ipb_reason' =>
'blocklist-reason',
132 foreach ( $headers as $key => $val ) {
133 $headers[$key] = $this->
msg( $val )->text();
148 if ( $msg ===
null ) {
151 'createaccountblock',
154 'blocklist-nousertalk',
158 'blocklist-editing-sitewide',
161 foreach (
$keys as $key ) {
162 $msg[$key] = $this->
msg( $key )->text();
165 '@phan-var string[] $msg';
177 case 'ipb_timestamp':
178 $formatted = htmlspecialchars( $language->userTimeAndDate( $value, $this->getUser() ) );
182 if ( $row->ipb_auto ) {
183 $formatted = $this->
msg(
'autoblockid', $row->ipb_id )->parse();
185 [ $target, ] = $this->blockUtils->parseBlockTarget( $row->ipb_address );
187 if ( is_string( $target ) ) {
188 if ( IPUtils::isValidRange( $target ) ) {
191 $formatted = $target;
196 $formatted = Linker::userLink( $target->getId(), $target->getName() );
197 $formatted .= Linker::userToolLinks(
201 Linker::TOOL_LINKS_NOBLOCK
208 $formatted = htmlspecialchars( $language->formatExpiry(
216 if ( $row->ipb_auto ) {
217 $links[] = $linkRenderer->makeKnownLink(
218 $this->specialPageFactory->getTitleForAlias(
'Unblock' ),
221 [
'wpTarget' =>
"#{$row->ipb_id}" ]
224 $links[] = $linkRenderer->makeKnownLink(
225 $this->specialPageFactory->getTitleForAlias(
'Unblock/' . $row->ipb_address ),
228 $links[] = $linkRenderer->makeKnownLink(
229 $this->specialPageFactory->getTitleForAlias(
'Block/' . $row->ipb_address ),
230 $msg[
'change-blocklink']
233 $formatted .=
' ' . Html::rawElement(
235 [
'class' =>
'mw-blocklist-actions' ],
236 $this->
msg(
'parentheses' )->rawParams(
237 $language->pipeList( $links ) )->escaped()
240 if ( $value !==
'infinity' ) {
242 $formatted .=
'<br />' . $this->
msg(
243 'ipb-blocklist-duration-left',
244 $language->formatDuration(
245 (
int)$timestamp->getTimestamp( TS_UNIX ) - MWTimestamp::time(),
259 $formatted = Linker::userLink( (
int)$value, $row->ipb_by_text );
260 $formatted .= Linker::userToolLinks( (
int)$value, $row->ipb_by_text );
270 if ( $row->ipb_sitewide ) {
271 $properties[] = htmlspecialchars( $msg[
'blocklist-editing-sitewide'] );
274 if ( !$row->ipb_sitewide && $this->restrictions ) {
275 $list = $this->getRestrictionListHTML( $row );
277 $properties[] = htmlspecialchars( $msg[
'blocklist-editing'] ) . $list;
281 if ( $row->ipb_anon_only ) {
282 $properties[] = htmlspecialchars( $msg[
'anononlyblock'] );
284 if ( $row->ipb_create_account ) {
285 $properties[] = htmlspecialchars( $msg[
'createaccountblock'] );
287 if ( $row->ipb_user && !$row->ipb_enable_autoblock ) {
288 $properties[] = htmlspecialchars( $msg[
'noautoblockblock'] );
291 if ( $row->ipb_block_email ) {
292 $properties[] = htmlspecialchars( $msg[
'emailblock'] );
295 if ( !$row->ipb_allow_usertalk ) {
296 $properties[] = htmlspecialchars( $msg[
'blocklist-nousertalk'] );
299 $formatted = Html::rawElement(
302 implode(
'', array_map(
static function ( $prop ) {
303 return Html::rawElement(
313 $formatted =
"Unable to format $name";
327 private function getRestrictionListHTML( stdClass $row ) {
331 foreach ( $this->restrictions as $restriction ) {
332 if ( $restriction->getBlockId() !== (
int)$row->ipb_id ) {
336 switch ( $restriction->getType() ) {
337 case PageRestriction::TYPE:
338 '@phan-var PageRestriction $restriction';
339 if ( $restriction->getTitle() ) {
340 $items[$restriction->getType()][] = Html::rawElement(
343 $linkRenderer->makeLink( $restriction->getTitle() )
347 case NamespaceRestriction::TYPE:
348 $text = $restriction->getValue() ===
NS_MAIN
349 ? $this->
msg(
'blanknamespace' )->text()
351 $restriction->getValue()
354 $items[$restriction->getType()][] = Html::rawElement(
357 $linkRenderer->makeLink(
358 $this->specialPageFactory->getTitleForAlias(
'Allpages' ),
362 'namespace' => $restriction->getValue()
368 case ActionRestriction::TYPE:
369 $actionName = $this->blockActionInfo->getActionFromId( $restriction->getValue() );
370 $enablePartialActionBlocks =
371 $this->
getConfig()->get( MainConfigNames::EnablePartialActionBlocks );
372 if ( $actionName && $enablePartialActionBlocks ) {
373 $items[$restriction->getType()][] = Html::rawElement(
376 $this->
msg(
'ipb-action-' .
377 $this->blockActionInfo->getActionFromId( $restriction->getValue() ) )->escaped()
384 if ( empty( $items ) ) {
389 foreach ( $items as $key => $value ) {
390 $sets[] = Html::rawElement(
393 $this->
msg(
'blocklist-editing-' . $key ) . Html::rawElement(
396 implode(
'', $value )
401 return Html::rawElement(
409 $commentQuery = $this->commentStore->getJoin(
'ipb_reason' );
412 'tables' => array_merge(
413 [
'ipblocks',
'ipblocks_by_actor' =>
'actor' ],
414 $commentQuery[
'tables']
420 'ipb_by' =>
'ipblocks_by_actor.actor_user',
421 'ipb_by_text' =>
'ipblocks_by_actor.actor_name',
425 'ipb_create_account',
426 'ipb_enable_autoblock',
432 'ipb_allow_usertalk',
434 ] + $commentQuery[
'fields'],
437 'ipblocks_by_actor' => [
'JOIN',
'actor_id=ipb_by_actor' ]
438 ] + $commentQuery[
'joins']
441 # Filter out any expired blocks
443 $info[
'conds'][] =
'ipb_expiry > ' . $db->addQuotes( $db->timestamp() );
445 # Is the user allowed to see hidden blocks?
446 if ( !$this->
getAuthority()->isAllowed(
'hideuser' ) ) {
447 $info[
'conds'][
'ipb_deleted'] = 0;
460 return (
int)
$dbr->selectField(
'ipblocks',
'COUNT(*)',
463 'ipb_expiry >= ' .
$dbr->addQuotes(
$dbr->timestamp() ),
470 return parent::getTableClass() .
' mw-blocklist';
474 return [ [
'ipb_timestamp',
'ipb_id' ] ];
491 $lb = $this->linkBatchFactory->newLinkBatch();
492 $lb->setCaller( __METHOD__ );
495 foreach ( $result as $row ) {
496 $lb->add(
NS_USER, $row->ipb_address );
499 if ( $row->ipb_by ??
null ) {
500 $lb->add(
NS_USER, $row->ipb_by_text );
504 if ( !$row->ipb_sitewide ) {
505 $partialBlocks[] = $row->ipb_id;
509 if ( $partialBlocks ) {
512 $this->restrictions = $this->blockRestrictionStore->loadByBlockId( $partialBlocks );
514 foreach ( $this->restrictions as $restriction ) {
515 if ( $restriction->getType() === PageRestriction::TYPE ) {
516 '@phan-var PageRestriction $restriction';
517 $title = $restriction->getTitle();
529 $this->formattedComments = $this->rowCommentFormatter->formatRows( $result,
'ipb_reason' );
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Library for creating and parsing MW-style timestamps.
A class containing constants representing the names of configuration variables.
Factory for handling the special page list and generating SpecialPage objects.
static newFromName( $name, $validate='valid')
Interface for objects which can provide a MediaWiki context on request.