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