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