MediaWiki
REL1_19
|
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 00210 class BlockListPager extends TablePager { 00211 protected $conds; 00212 protected $page; 00213 00218 function __construct( $page, $conds ) { 00219 $this->page = $page; 00220 $this->conds = $conds; 00221 $this->mDefaultDirection = true; 00222 parent::__construct( $page->getContext() ); 00223 } 00224 00225 function getFieldNames() { 00226 static $headers = null; 00227 00228 if ( $headers == array() ) { 00229 $headers = array( 00230 'ipb_timestamp' => 'blocklist-timestamp', 00231 'ipb_target' => 'blocklist-target', 00232 'ipb_expiry' => 'blocklist-expiry', 00233 'ipb_by' => 'blocklist-by', 00234 'ipb_params' => 'blocklist-params', 00235 'ipb_reason' => 'blocklist-reason', 00236 ); 00237 foreach( $headers as $key => $val ) { 00238 $headers[$key] = $this->msg( $val )->text(); 00239 } 00240 } 00241 00242 return $headers; 00243 } 00244 00245 function formatValue( $name, $value ) { 00246 static $msg = null; 00247 if ( $msg === null ) { 00248 $msg = array( 00249 'anononlyblock', 00250 'createaccountblock', 00251 'noautoblockblock', 00252 'emailblock', 00253 'blocklist-nousertalk', 00254 'unblocklink', 00255 'change-blocklink', 00256 'infiniteblock', 00257 ); 00258 $msg = array_combine( $msg, array_map( array( $this, 'msg' ), $msg ) ); 00259 } 00260 00262 $row = $this->mCurrentRow; 00263 00264 $formatted = ''; 00265 00266 switch( $name ) { 00267 case 'ipb_timestamp': 00268 $formatted = $this->getLanguage()->userTimeAndDate( $value, $this->getUser() ); 00269 break; 00270 00271 case 'ipb_target': 00272 if( $row->ipb_auto ){ 00273 $formatted = $this->msg( 'autoblockid', $row->ipb_id )->parse(); 00274 } else { 00275 list( $target, $type ) = Block::parseTarget( $row->ipb_address ); 00276 switch( $type ){ 00277 case Block::TYPE_USER: 00278 case Block::TYPE_IP: 00279 $formatted = Linker::userLink( $target->getId(), $target ); 00280 $formatted .= Linker::userToolLinks( 00281 $target->getId(), 00282 $target, 00283 false, 00284 Linker::TOOL_LINKS_NOBLOCK 00285 ); 00286 break; 00287 case Block::TYPE_RANGE: 00288 $formatted = htmlspecialchars( $target ); 00289 } 00290 } 00291 break; 00292 00293 case 'ipb_expiry': 00294 $formatted = $this->getLanguage()->formatExpiry( $value, /* User preference timezone */ true ); 00295 if( $this->getUser()->isAllowed( 'block' ) ){ 00296 if( $row->ipb_auto ){ 00297 $links[] = Linker::linkKnown( 00298 SpecialPage::getTitleFor( 'Unblock' ), 00299 $msg['unblocklink'], 00300 array(), 00301 array( 'wpTarget' => "#{$row->ipb_id}" ) 00302 ); 00303 } else { 00304 $links[] = Linker::linkKnown( 00305 SpecialPage::getTitleFor( 'Unblock', $row->ipb_address ), 00306 $msg['unblocklink'] 00307 ); 00308 $links[] = Linker::linkKnown( 00309 SpecialPage::getTitleFor( 'Block', $row->ipb_address ), 00310 $msg['change-blocklink'] 00311 ); 00312 } 00313 $formatted .= ' ' . Html::rawElement( 00314 'span', 00315 array( 'class' => 'mw-blocklist-actions' ), 00316 $this->msg( 'parentheses' )->rawParams( 00317 $this->getLanguage()->pipeList( $links ) )->escaped() 00318 ); 00319 } 00320 break; 00321 00322 case 'ipb_by': 00323 if ( isset( $row->by_user_name ) ) { 00324 $formatted = Linker::userLink( $value, $row->by_user_name ); 00325 $formatted .= Linker::userToolLinks( $value, $row->by_user_name ); 00326 } else { 00327 $formatted = htmlspecialchars( $row->ipb_by_text ); // foreign user? 00328 } 00329 break; 00330 00331 case 'ipb_reason': 00332 $formatted = Linker::commentBlock( $value ); 00333 break; 00334 00335 case 'ipb_params': 00336 $properties = array(); 00337 if ( $row->ipb_anon_only ) { 00338 $properties[] = $msg['anononlyblock']; 00339 } 00340 if ( $row->ipb_create_account ) { 00341 $properties[] = $msg['createaccountblock']; 00342 } 00343 if ( $row->ipb_user && !$row->ipb_enable_autoblock ) { 00344 $properties[] = $msg['noautoblockblock']; 00345 } 00346 00347 if ( $row->ipb_block_email ) { 00348 $properties[] = $msg['emailblock']; 00349 } 00350 00351 if ( !$row->ipb_allow_usertalk ) { 00352 $properties[] = $msg['blocklist-nousertalk']; 00353 } 00354 00355 $formatted = $this->getLanguage()->commaList( $properties ); 00356 break; 00357 00358 default: 00359 $formatted = "Unable to format $name"; 00360 break; 00361 } 00362 00363 return $formatted; 00364 } 00365 00366 function getQueryInfo() { 00367 $info = array( 00368 'tables' => array( 'ipblocks', 'user' ), 00369 'fields' => array( 00370 'ipb_id', 00371 'ipb_address', 00372 'ipb_user', 00373 'ipb_by', 00374 'ipb_by_text', 00375 'user_name AS by_user_name', 00376 'ipb_reason', 00377 'ipb_timestamp', 00378 'ipb_auto', 00379 'ipb_anon_only', 00380 'ipb_create_account', 00381 'ipb_enable_autoblock', 00382 'ipb_expiry', 00383 'ipb_range_start', 00384 'ipb_range_end', 00385 'ipb_deleted', 00386 'ipb_block_email', 00387 'ipb_allow_usertalk', 00388 ), 00389 'conds' => $this->conds, 00390 'join_conds' => array( 'user' => array( 'LEFT JOIN', 'user_id = ipb_by' ) ) 00391 ); 00392 00393 # Is the user allowed to see hidden blocks? 00394 if ( !$this->getUser()->isAllowed( 'hideuser' ) ){ 00395 $info['conds']['ipb_deleted'] = 0; 00396 } 00397 00398 return $info; 00399 } 00400 00401 public function getTableClass(){ 00402 return 'TablePager mw-blocklist'; 00403 } 00404 00405 function getIndexField() { 00406 return 'ipb_timestamp'; 00407 } 00408 00409 function getDefaultSort() { 00410 return 'ipb_timestamp'; 00411 } 00412 00413 function isFieldSortable( $name ) { 00414 return false; 00415 } 00416 00421 function preprocessResults( $result ){ 00422 wfProfileIn( __METHOD__ ); 00423 # Do a link batch query 00424 $lb = new LinkBatch; 00425 $lb->setCaller( __METHOD__ ); 00426 00427 $userids = array(); 00428 00429 foreach ( $result as $row ) { 00430 $userids[] = $row->ipb_by; 00431 00432 # Usernames and titles are in fact related by a simple substitution of space -> underscore 00433 # The last few lines of Title::secureAndSplit() tell the story. 00434 $name = str_replace( ' ', '_', $row->ipb_address ); 00435 $lb->add( NS_USER, $name ); 00436 $lb->add( NS_USER_TALK, $name ); 00437 } 00438 00439 $ua = UserArray::newFromIDs( $userids ); 00440 foreach( $ua as $user ){ 00441 $name = str_replace( ' ', '_', $user->getName() ); 00442 $lb->add( NS_USER, $name ); 00443 $lb->add( NS_USER_TALK, $name ); 00444 } 00445 00446 $lb->execute(); 00447 wfProfileOut( __METHOD__ ); 00448 } 00449 } 00450 00456 class HTMLBlockedUsersItemSelect extends HTMLSelectField { 00465 function validate( $value, $alldata ) { 00466 if ( $value == '' ) { 00467 return true; 00468 } 00469 00470 // Let folks pick an explicit limit not from our list, as long as it's a real numbr. 00471 if ( !in_array( $value, $this->mParams['options'] ) && $value == intval( $value ) && $value > 0 ) { 00472 // This adds the explicitly requested limit value to the drop-down, 00473 // then makes sure it's sorted correctly so when we output the list 00474 // later, the custom option doesn't just show up last. 00475 $this->mParams['options'][ $this->mParent->getLanguage()->formatNum( $value ) ] = intval($value); 00476 asort( $this->mParams['options'] ); 00477 } 00478 00479 return true; 00480 } 00481 00482 }