MediaWiki
REL1_21
|
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 }