MediaWiki  REL1_24
SpecialBlockList.php
Go to the documentation of this file.
00001 <?php
00029 class SpecialBlockList extends SpecialPage {
00030     protected $target;
00031 
00032     protected $options;
00033 
00034     function __construct() {
00035         parent::__construct( 'BlockList' );
00036     }
00037 
00043     public function execute( $par ) {
00044         $this->setHeaders();
00045         $this->outputHeader();
00046         $out = $this->getOutput();
00047         $lang = $this->getLanguage();
00048         $out->setPageTitle( $this->msg( 'ipblocklist' ) );
00049         $out->addModuleStyles( 'mediawiki.special' );
00050 
00051         $request = $this->getRequest();
00052         $par = $request->getVal( 'ip', $par );
00053         $this->target = trim( $request->getVal( 'wpTarget', $par ) );
00054 
00055         $this->options = $request->getArray( 'wpOptions', array() );
00056 
00057         $action = $request->getText( 'action' );
00058 
00059         if ( $action == 'unblock' || $action == 'submit' && $request->wasPosted() ) {
00060             # B/C @since 1.18: Unblock interface is now at Special:Unblock
00061             $title = SpecialPage::getTitleFor( 'Unblock', $this->target );
00062             $out->redirect( $title->getFullURL() );
00063 
00064             return;
00065         }
00066 
00067         # Just show the block list
00068         $fields = array(
00069             'Target' => array(
00070                 'type' => 'text',
00071                 'label-message' => 'ipaddressorusername',
00072                 'tabindex' => '1',
00073                 'size' => '45',
00074                 'default' => $this->target,
00075             ),
00076             'Options' => array(
00077                 'type' => 'multiselect',
00078                 'options' => array(
00079                     $this->msg( 'blocklist-userblocks' )->text() => 'userblocks',
00080                     $this->msg( 'blocklist-tempblocks' )->text() => 'tempblocks',
00081                     $this->msg( 'blocklist-addressblocks' )->text() => 'addressblocks',
00082                     $this->msg( 'blocklist-rangeblocks' )->text() => 'rangeblocks',
00083                 ),
00084                 'flatlist' => true,
00085             ),
00086             'Limit' => array(
00087                 'type' => 'limitselect',
00088                 'label-message' => 'table_pager_limit_label',
00089                 'options' => array(
00090                     $lang->formatNum( 20 ) => 20,
00091                     $lang->formatNum( 50 ) => 50,
00092                     $lang->formatNum( 100 ) => 100,
00093                     $lang->formatNum( 250 ) => 250,
00094                     $lang->formatNum( 500 ) => 500,
00095                 ),
00096                 'name' => 'limit',
00097                 'default' => 50,
00098             ),
00099         );
00100         $context = new DerivativeContext( $this->getContext() );
00101         $context->setTitle( $this->getPageTitle() ); // Remove subpage
00102         $form = new HTMLForm( $fields, $context );
00103         $form->setMethod( 'get' );
00104         $form->setWrapperLegendMsg( 'ipblocklist-legend' );
00105         $form->setSubmitTextMsg( 'ipblocklist-submit' );
00106         $form->prepareForm();
00107 
00108         $form->displayForm( '' );
00109         $this->showList();
00110     }
00111 
00112     function showList() {
00113         # Purge expired entries on one in every 10 queries
00114         if ( !mt_rand( 0, 10 ) ) {
00115             Block::purgeExpired();
00116         }
00117 
00118         $conds = array();
00119         # Is the user allowed to see hidden blocks?
00120         if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
00121             $conds['ipb_deleted'] = 0;
00122         }
00123 
00124         if ( $this->target !== '' ) {
00125             list( $target, $type ) = Block::parseTarget( $this->target );
00126 
00127             switch ( $type ) {
00128                 case Block::TYPE_ID:
00129                 case Block::TYPE_AUTO:
00130                     $conds['ipb_id'] = $target;
00131                     break;
00132 
00133                 case Block::TYPE_IP:
00134                 case Block::TYPE_RANGE:
00135                     list( $start, $end ) = IP::parseRange( $target );
00136                     $dbr = wfGetDB( DB_SLAVE );
00137                     $conds[] = $dbr->makeList(
00138                         array(
00139                             'ipb_address' => $target,
00140                             Block::getRangeCond( $start, $end )
00141                         ),
00142                         LIST_OR
00143                     );
00144                     $conds['ipb_auto'] = 0;
00145                     break;
00146 
00147                 case Block::TYPE_USER:
00148                     $conds['ipb_address'] = $target->getName();
00149                     $conds['ipb_auto'] = 0;
00150                     break;
00151             }
00152         }
00153 
00154         # Apply filters
00155         if ( in_array( 'userblocks', $this->options ) ) {
00156             $conds['ipb_user'] = 0;
00157         }
00158         if ( in_array( 'tempblocks', $this->options ) ) {
00159             $conds['ipb_expiry'] = 'infinity';
00160         }
00161         if ( in_array( 'addressblocks', $this->options ) ) {
00162             $conds[] = "ipb_user != 0 OR ipb_range_end > ipb_range_start";
00163         }
00164         if ( in_array( 'rangeblocks', $this->options ) ) {
00165             $conds[] = "ipb_range_end = ipb_range_start";
00166         }
00167 
00168         # Check for other blocks, i.e. global/tor blocks
00169         $otherBlockLink = array();
00170         wfRunHooks( 'OtherBlockLogLink', array( &$otherBlockLink, $this->target ) );
00171 
00172         $out = $this->getOutput();
00173 
00174         # Show additional header for the local block only when other blocks exists.
00175         # Not necessary in a standard installation without such extensions enabled
00176         if ( count( $otherBlockLink ) ) {
00177             $out->addHTML(
00178                 Html::element( 'h2', array(), $this->msg( 'ipblocklist-localblock' )->text() ) . "\n"
00179             );
00180         }
00181 
00182         $pager = new BlockListPager( $this, $conds );
00183         if ( $pager->getNumRows() ) {
00184             $out->addParserOutputContent( $pager->getFullOutput() );
00185         } elseif ( $this->target ) {
00186             $out->addWikiMsg( 'ipblocklist-no-results' );
00187         } else {
00188             $out->addWikiMsg( 'ipblocklist-empty' );
00189         }
00190 
00191         if ( count( $otherBlockLink ) ) {
00192             $out->addHTML(
00193                 Html::rawElement(
00194                     'h2',
00195                     array(),
00196                     $this->msg( 'ipblocklist-otherblocks', count( $otherBlockLink ) )->parse()
00197                 ) . "\n"
00198             );
00199             $list = '';
00200             foreach ( $otherBlockLink as $link ) {
00201                 $list .= Html::rawElement( 'li', array(), $link ) . "\n";
00202             }
00203             $out->addHTML( Html::rawElement(
00204                 'ul',
00205                 array( 'class' => 'mw-ipblocklist-otherblocks' ),
00206                 $list
00207             ) . "\n" );
00208         }
00209     }
00210 
00211     protected function getGroupName() {
00212         return 'users';
00213     }
00214 }
00215 
00216 class BlockListPager extends TablePager {
00217     protected $conds;
00218     protected $page;
00219 
00224     function __construct( $page, $conds ) {
00225         $this->page = $page;
00226         $this->conds = $conds;
00227         $this->mDefaultDirection = IndexPager::DIR_DESCENDING;
00228         parent::__construct( $page->getContext() );
00229     }
00230 
00231     function getFieldNames() {
00232         static $headers = null;
00233 
00234         if ( $headers === null ) {
00235             $headers = array(
00236                 'ipb_timestamp' => 'blocklist-timestamp',
00237                 'ipb_target' => 'blocklist-target',
00238                 'ipb_expiry' => 'blocklist-expiry',
00239                 'ipb_by' => 'blocklist-by',
00240                 'ipb_params' => 'blocklist-params',
00241                 'ipb_reason' => 'blocklist-reason',
00242             );
00243             foreach ( $headers as $key => $val ) {
00244                 $headers[$key] = $this->msg( $val )->text();
00245             }
00246         }
00247 
00248         return $headers;
00249     }
00250 
00251     function formatValue( $name, $value ) {
00252         static $msg = null;
00253         if ( $msg === null ) {
00254             $msg = array(
00255                 'anononlyblock',
00256                 'createaccountblock',
00257                 'noautoblockblock',
00258                 'emailblock',
00259                 'blocklist-nousertalk',
00260                 'unblocklink',
00261                 'change-blocklink',
00262                 'infiniteblock',
00263             );
00264             $msg = array_combine( $msg, array_map( array( $this, 'msg' ), $msg ) );
00265         }
00266 
00268         $row = $this->mCurrentRow;
00269 
00270         $formatted = '';
00271 
00272         switch ( $name ) {
00273             case 'ipb_timestamp':
00274                 $formatted = $this->getLanguage()->userTimeAndDate( $value, $this->getUser() );
00275                 break;
00276 
00277             case 'ipb_target':
00278                 if ( $row->ipb_auto ) {
00279                     $formatted = $this->msg( 'autoblockid', $row->ipb_id )->parse();
00280                 } else {
00281                     list( $target, $type ) = Block::parseTarget( $row->ipb_address );
00282                     switch ( $type ) {
00283                         case Block::TYPE_USER:
00284                         case Block::TYPE_IP:
00285                             $formatted = Linker::userLink( $target->getId(), $target );
00286                             $formatted .= Linker::userToolLinks(
00287                                 $target->getId(),
00288                                 $target,
00289                                 false,
00290                                 Linker::TOOL_LINKS_NOBLOCK
00291                             );
00292                             break;
00293                         case Block::TYPE_RANGE:
00294                             $formatted = htmlspecialchars( $target );
00295                     }
00296                 }
00297                 break;
00298 
00299             case 'ipb_expiry':
00300                 $formatted = $this->getLanguage()->formatExpiry( $value, /* User preference timezone */true );
00301                 if ( $this->getUser()->isAllowed( 'block' ) ) {
00302                     if ( $row->ipb_auto ) {
00303                         $links[] = Linker::linkKnown(
00304                             SpecialPage::getTitleFor( 'Unblock' ),
00305                             $msg['unblocklink'],
00306                             array(),
00307                             array( 'wpTarget' => "#{$row->ipb_id}" )
00308                         );
00309                     } else {
00310                         $links[] = Linker::linkKnown(
00311                             SpecialPage::getTitleFor( 'Unblock', $row->ipb_address ),
00312                             $msg['unblocklink']
00313                         );
00314                         $links[] = Linker::linkKnown(
00315                             SpecialPage::getTitleFor( 'Block', $row->ipb_address ),
00316                             $msg['change-blocklink']
00317                         );
00318                     }
00319                     $formatted .= ' ' . Html::rawElement(
00320                         'span',
00321                         array( 'class' => 'mw-blocklist-actions' ),
00322                         $this->msg( 'parentheses' )->rawParams(
00323                             $this->getLanguage()->pipeList( $links ) )->escaped()
00324                     );
00325                 }
00326                 break;
00327 
00328             case 'ipb_by':
00329                 if ( isset( $row->by_user_name ) ) {
00330                     $formatted = Linker::userLink( $value, $row->by_user_name );
00331                     $formatted .= Linker::userToolLinks( $value, $row->by_user_name );
00332                 } else {
00333                     $formatted = htmlspecialchars( $row->ipb_by_text ); // foreign user?
00334                 }
00335                 break;
00336 
00337             case 'ipb_reason':
00338                 $formatted = Linker::formatComment( $value );
00339                 break;
00340 
00341             case 'ipb_params':
00342                 $properties = array();
00343                 if ( $row->ipb_anon_only ) {
00344                     $properties[] = $msg['anononlyblock'];
00345                 }
00346                 if ( $row->ipb_create_account ) {
00347                     $properties[] = $msg['createaccountblock'];
00348                 }
00349                 if ( $row->ipb_user && !$row->ipb_enable_autoblock ) {
00350                     $properties[] = $msg['noautoblockblock'];
00351                 }
00352 
00353                 if ( $row->ipb_block_email ) {
00354                     $properties[] = $msg['emailblock'];
00355                 }
00356 
00357                 if ( !$row->ipb_allow_usertalk ) {
00358                     $properties[] = $msg['blocklist-nousertalk'];
00359                 }
00360 
00361                 $formatted = $this->getLanguage()->commaList( $properties );
00362                 break;
00363 
00364             default:
00365                 $formatted = "Unable to format $name";
00366                 break;
00367         }
00368 
00369         return $formatted;
00370     }
00371 
00372     function getQueryInfo() {
00373         $info = array(
00374             'tables' => array( 'ipblocks', 'user' ),
00375             'fields' => array(
00376                 'ipb_id',
00377                 'ipb_address',
00378                 'ipb_user',
00379                 'ipb_by',
00380                 'ipb_by_text',
00381                 'by_user_name' => 'user_name',
00382                 'ipb_reason',
00383                 'ipb_timestamp',
00384                 'ipb_auto',
00385                 'ipb_anon_only',
00386                 'ipb_create_account',
00387                 'ipb_enable_autoblock',
00388                 'ipb_expiry',
00389                 'ipb_range_start',
00390                 'ipb_range_end',
00391                 'ipb_deleted',
00392                 'ipb_block_email',
00393                 'ipb_allow_usertalk',
00394             ),
00395             'conds' => $this->conds,
00396             'join_conds' => array( 'user' => array( 'LEFT JOIN', 'user_id = ipb_by' ) )
00397         );
00398 
00399         # Is the user allowed to see hidden blocks?
00400         if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
00401             $info['conds']['ipb_deleted'] = 0;
00402         }
00403 
00404         return $info;
00405     }
00406 
00407     public function getTableClass() {
00408         return parent::getTableClass() . ' mw-blocklist';
00409     }
00410 
00411     function getIndexField() {
00412         return 'ipb_timestamp';
00413     }
00414 
00415     function getDefaultSort() {
00416         return 'ipb_timestamp';
00417     }
00418 
00419     function isFieldSortable( $name ) {
00420         return false;
00421     }
00422 
00427     function preprocessResults( $result ) {
00428         wfProfileIn( __METHOD__ );
00429         # Do a link batch query
00430         $lb = new LinkBatch;
00431         $lb->setCaller( __METHOD__ );
00432 
00433         $userids = array();
00434 
00435         foreach ( $result as $row ) {
00436             $userids[] = $row->ipb_by;
00437 
00438             # Usernames and titles are in fact related by a simple substitution of space -> underscore
00439             # The last few lines of Title::secureAndSplit() tell the story.
00440             $name = str_replace( ' ', '_', $row->ipb_address );
00441             $lb->add( NS_USER, $name );
00442             $lb->add( NS_USER_TALK, $name );
00443         }
00444 
00445         $ua = UserArray::newFromIDs( $userids );
00446         foreach ( $ua as $user ) {
00447             $name = str_replace( ' ', '_', $user->getName() );
00448             $lb->add( NS_USER, $name );
00449             $lb->add( NS_USER_TALK, $name );
00450         }
00451 
00452         $lb->execute();
00453         wfProfileOut( __METHOD__ );
00454     }
00455 }