MediaWiki
REL1_24
|
00001 <?php 00029 class SpecialProtectedpages extends SpecialPage { 00030 protected $IdLevel = 'level'; 00031 protected $IdType = 'type'; 00032 00033 public function __construct() { 00034 parent::__construct( 'Protectedpages' ); 00035 } 00036 00037 public function execute( $par ) { 00038 $this->setHeaders(); 00039 $this->outputHeader(); 00040 $this->getOutput()->addModuleStyles( 'mediawiki.special' ); 00041 00042 // Purge expired entries on one in every 10 queries 00043 if ( !mt_rand( 0, 10 ) ) { 00044 Title::purgeExpiredRestrictions(); 00045 } 00046 00047 $request = $this->getRequest(); 00048 $type = $request->getVal( $this->IdType ); 00049 $level = $request->getVal( $this->IdLevel ); 00050 $sizetype = $request->getVal( 'sizetype' ); 00051 $size = $request->getIntOrNull( 'size' ); 00052 $ns = $request->getIntOrNull( 'namespace' ); 00053 $indefOnly = $request->getBool( 'indefonly' ) ? 1 : 0; 00054 $cascadeOnly = $request->getBool( 'cascadeonly' ) ? 1 : 0; 00055 $noRedirect = $request->getBool( 'noredirect' ) ? 1 : 0; 00056 00057 $pager = new ProtectedPagesPager( 00058 $this, 00059 array(), 00060 $type, 00061 $level, 00062 $ns, 00063 $sizetype, 00064 $size, 00065 $indefOnly, 00066 $cascadeOnly, 00067 $noRedirect 00068 ); 00069 00070 $this->getOutput()->addHTML( $this->showOptions( 00071 $ns, 00072 $type, 00073 $level, 00074 $sizetype, 00075 $size, 00076 $indefOnly, 00077 $cascadeOnly, 00078 $noRedirect 00079 ) ); 00080 00081 if ( $pager->getNumRows() ) { 00082 $this->getOutput()->addParserOutputContent( $pager->getFullOutput() ); 00083 } else { 00084 $this->getOutput()->addWikiMsg( 'protectedpagesempty' ); 00085 } 00086 } 00087 00099 protected function showOptions( $namespace, $type = 'edit', $level, $sizetype, 00100 $size, $indefOnly, $cascadeOnly, $noRedirect 00101 ) { 00102 $title = $this->getPageTitle(); 00103 00104 return Xml::openElement( 'form', array( 'method' => 'get', 'action' => wfScript() ) ) . 00105 Xml::openElement( 'fieldset' ) . 00106 Xml::element( 'legend', array(), $this->msg( 'protectedpages' )->text() ) . 00107 Html::hidden( 'title', $title->getPrefixedDBkey() ) . "\n" . 00108 $this->getNamespaceMenu( $namespace ) . " \n" . 00109 $this->getTypeMenu( $type ) . " \n" . 00110 $this->getLevelMenu( $level ) . " \n" . 00111 "<br /><span style='white-space: nowrap'>" . 00112 $this->getExpiryCheck( $indefOnly ) . " \n" . 00113 $this->getCascadeCheck( $cascadeOnly ) . " \n" . 00114 $this->getRedirectCheck( $noRedirect ) . " \n" . 00115 "</span><br /><span style='white-space: nowrap'>" . 00116 $this->getSizeLimit( $sizetype, $size ) . " \n" . 00117 "</span>" . 00118 " " . Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "\n" . 00119 Xml::closeElement( 'fieldset' ) . 00120 Xml::closeElement( 'form' ); 00121 } 00122 00130 protected function getNamespaceMenu( $namespace = null ) { 00131 return Html::rawElement( 'span', array( 'style' => 'white-space: nowrap;' ), 00132 Html::namespaceSelector( 00133 array( 00134 'selected' => $namespace, 00135 'all' => '', 00136 'label' => $this->msg( 'namespace' )->text() 00137 ), array( 00138 'name' => 'namespace', 00139 'id' => 'namespace', 00140 'class' => 'namespaceselector', 00141 ) 00142 ) 00143 ); 00144 } 00145 00150 protected function getExpiryCheck( $indefOnly ) { 00151 return Xml::checkLabel( 00152 $this->msg( 'protectedpages-indef' )->text(), 00153 'indefonly', 00154 'indefonly', 00155 $indefOnly 00156 ) . "\n"; 00157 } 00158 00163 protected function getCascadeCheck( $cascadeOnly ) { 00164 return Xml::checkLabel( 00165 $this->msg( 'protectedpages-cascade' )->text(), 00166 'cascadeonly', 00167 'cascadeonly', 00168 $cascadeOnly 00169 ) . "\n"; 00170 } 00171 00176 protected function getRedirectCheck( $noRedirect ) { 00177 return Xml::checkLabel( 00178 $this->msg( 'protectedpages-noredirect' )->text(), 00179 'noredirect', 00180 'noredirect', 00181 $noRedirect 00182 ) . "\n"; 00183 } 00184 00190 protected function getSizeLimit( $sizetype, $size ) { 00191 $max = $sizetype === 'max'; 00192 00193 return Xml::radioLabel( 00194 $this->msg( 'minimum-size' )->text(), 00195 'sizetype', 00196 'min', 00197 'wpmin', 00198 !$max 00199 ) . 00200 ' ' . 00201 Xml::radioLabel( 00202 $this->msg( 'maximum-size' )->text(), 00203 'sizetype', 00204 'max', 00205 'wpmax', 00206 $max 00207 ) . 00208 ' ' . 00209 Xml::input( 'size', 9, $size, array( 'id' => 'wpsize' ) ) . 00210 ' ' . 00211 Xml::label( $this->msg( 'pagesize' )->text(), 'wpsize' ); 00212 } 00213 00219 protected function getTypeMenu( $pr_type ) { 00220 $m = array(); // Temporary array 00221 $options = array(); 00222 00223 // First pass to load the log names 00224 foreach ( Title::getFilteredRestrictionTypes( true ) as $type ) { 00225 // Messages: restriction-edit, restriction-move, restriction-create, restriction-upload 00226 $text = $this->msg( "restriction-$type" )->text(); 00227 $m[$text] = $type; 00228 } 00229 00230 // Third pass generates sorted XHTML content 00231 foreach ( $m as $text => $type ) { 00232 $selected = ( $type == $pr_type ); 00233 $options[] = Xml::option( $text, $type, $selected ) . "\n"; 00234 } 00235 00236 return "<span style='white-space: nowrap'>" . 00237 Xml::label( $this->msg( 'restriction-type' )->text(), $this->IdType ) . ' ' . 00238 Xml::tags( 'select', 00239 array( 'id' => $this->IdType, 'name' => $this->IdType ), 00240 implode( "\n", $options ) ) . "</span>"; 00241 } 00242 00248 protected function getLevelMenu( $pr_level ) { 00249 // Temporary array 00250 $m = array( $this->msg( 'restriction-level-all' )->text() => 0 ); 00251 $options = array(); 00252 00253 // First pass to load the log names 00254 foreach ( $this->getConfig()->get( 'RestrictionLevels' ) as $type ) { 00255 // Messages used can be 'restriction-level-sysop' and 'restriction-level-autoconfirmed' 00256 if ( $type != '' && $type != '*' ) { 00257 $text = $this->msg( "restriction-level-$type" )->text(); 00258 $m[$text] = $type; 00259 } 00260 } 00261 00262 // Third pass generates sorted XHTML content 00263 foreach ( $m as $text => $type ) { 00264 $selected = ( $type == $pr_level ); 00265 $options[] = Xml::option( $text, $type, $selected ); 00266 } 00267 00268 return "<span style='white-space: nowrap'>" . 00269 Xml::label( $this->msg( 'restriction-level' )->text(), $this->IdLevel ) . ' ' . 00270 Xml::tags( 'select', 00271 array( 'id' => $this->IdLevel, 'name' => $this->IdLevel ), 00272 implode( "\n", $options ) ) . "</span>"; 00273 } 00274 00275 protected function getGroupName() { 00276 return 'maintenance'; 00277 } 00278 } 00279 00284 class ProtectedPagesPager extends TablePager { 00285 public $mForm, $mConds; 00286 private $type, $level, $namespace, $sizetype, $size, $indefonly, $cascadeonly, $noredirect; 00287 00288 function __construct( $form, $conds = array(), $type, $level, $namespace, 00289 $sizetype = '', $size = 0, $indefonly = false, $cascadeonly = false, $noredirect = false 00290 ) { 00291 $this->mForm = $form; 00292 $this->mConds = $conds; 00293 $this->type = ( $type ) ? $type : 'edit'; 00294 $this->level = $level; 00295 $this->namespace = $namespace; 00296 $this->sizetype = $sizetype; 00297 $this->size = intval( $size ); 00298 $this->indefonly = (bool)$indefonly; 00299 $this->cascadeonly = (bool)$cascadeonly; 00300 $this->noredirect = (bool)$noredirect; 00301 parent::__construct( $form->getContext() ); 00302 } 00303 00304 function preprocessResults( $result ) { 00305 # Do a link batch query 00306 $lb = new LinkBatch; 00307 $userids = array(); 00308 00309 foreach ( $result as $row ) { 00310 $lb->add( $row->page_namespace, $row->page_title ); 00311 // field is nullable, maybe null on old protections 00312 if ( $row->log_user !== null ) { 00313 $userids[] = $row->log_user; 00314 } 00315 } 00316 00317 // fill LinkBatch with user page and user talk 00318 if ( count( $userids ) ) { 00319 $userCache = UserCache::singleton(); 00320 $userCache->doQuery( $userids, array(), __METHOD__ ); 00321 foreach ( $userids as $userid ) { 00322 $name = $userCache->getProp( $userid, 'name' ); 00323 if ( $name !== false ) { 00324 $lb->add( NS_USER, $name ); 00325 $lb->add( NS_USER_TALK, $name ); 00326 } 00327 } 00328 } 00329 00330 $lb->execute(); 00331 } 00332 00333 function getFieldNames() { 00334 static $headers = null; 00335 00336 if ( $headers == array() ) { 00337 $headers = array( 00338 'log_timestamp' => 'protectedpages-timestamp', 00339 'pr_page' => 'protectedpages-page', 00340 'pr_expiry' => 'protectedpages-expiry', 00341 'log_user' => 'protectedpages-performer', 00342 'pr_params' => 'protectedpages-params', 00343 'log_comment' => 'protectedpages-reason', 00344 ); 00345 foreach ( $headers as $key => $val ) { 00346 $headers[$key] = $this->msg( $val )->text(); 00347 } 00348 } 00349 00350 return $headers; 00351 } 00352 00359 function formatValue( $field, $value ) { 00361 $row = $this->mCurrentRow; 00362 00363 $formatted = ''; 00364 00365 switch ( $field ) { 00366 case 'log_timestamp': 00367 // when timestamp is null, this is a old protection row 00368 if ( $value === null ) { 00369 $formatted = Html::rawElement( 00370 'span', 00371 array( 'class' => 'mw-protectedpages-unknown' ), 00372 $this->msg( 'protectedpages-unknown-timestamp' )->escaped() 00373 ); 00374 } else { 00375 $formatted = $this->getLanguage()->userTimeAndDate( $value, $this->getUser() ); 00376 } 00377 break; 00378 00379 case 'pr_page': 00380 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); 00381 if ( !$title ) { 00382 $formatted = Html::element( 00383 'span', 00384 array( 'class' => 'mw-invalidtitle' ), 00385 Linker::getInvalidTitleDescription( 00386 $this->getContext(), 00387 $row->page_namespace, 00388 $row->page_title 00389 ) 00390 ); 00391 } else { 00392 $formatted = Linker::link( $title ); 00393 } 00394 if ( !is_null( $row->page_len ) ) { 00395 $formatted .= $this->getLanguage()->getDirMark() . 00396 ' ' . Html::rawElement( 00397 'span', 00398 array( 'class' => 'mw-protectedpages-length' ), 00399 Linker::formatRevisionSize( $row->page_len ) 00400 ); 00401 } 00402 break; 00403 00404 case 'pr_expiry': 00405 $formatted = $this->getLanguage()->formatExpiry( $value, /* User preference timezone */true ); 00406 $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); 00407 if ( $this->getUser()->isAllowed( 'protect' ) && $title ) { 00408 $changeProtection = Linker::linkKnown( 00409 $title, 00410 $this->msg( 'protect_change' )->escaped(), 00411 array(), 00412 array( 'action' => 'unprotect' ) 00413 ); 00414 $formatted .= ' ' . Html::rawElement( 00415 'span', 00416 array( 'class' => 'mw-protectedpages-actions' ), 00417 $this->msg( 'parentheses' )->rawParams( $changeProtection )->escaped() 00418 ); 00419 } 00420 break; 00421 00422 case 'log_user': 00423 // when timestamp is null, this is a old protection row 00424 if ( $row->log_timestamp === null ) { 00425 $formatted = Html::rawElement( 00426 'span', 00427 array( 'class' => 'mw-protectedpages-unknown' ), 00428 $this->msg( 'protectedpages-unknown-performer' )->escaped() 00429 ); 00430 } else { 00431 $username = UserCache::singleton()->getProp( $value, 'name' ); 00432 if ( LogEventsList::userCanBitfield( 00433 $row->log_deleted, 00434 LogPage::DELETED_USER, 00435 $this->getUser() 00436 ) ) { 00437 if ( $username === false ) { 00438 $formatted = htmlspecialchars( $value ); 00439 } else { 00440 $formatted = Linker::userLink( $value, $username ) 00441 . Linker::userToolLinks( $value, $username ); 00442 } 00443 } else { 00444 $formatted = $this->msg( 'rev-deleted-user' )->escaped(); 00445 } 00446 if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) { 00447 $formatted = '<span class="history-deleted">' . $formatted . '</span>'; 00448 } 00449 } 00450 break; 00451 00452 case 'pr_params': 00453 $params = array(); 00454 // Messages: restriction-level-sysop, restriction-level-autoconfirmed 00455 $params[] = $this->msg( 'restriction-level-' . $row->pr_level )->escaped(); 00456 if ( $row->pr_cascade ) { 00457 $params[] = $this->msg( 'protect-summary-cascade' )->text(); 00458 } 00459 $formatted = $this->getLanguage()->commaList( $params ); 00460 break; 00461 00462 case 'log_comment': 00463 // when timestamp is null, this is an old protection row 00464 if ( $row->log_timestamp === null ) { 00465 $formatted = Html::rawElement( 00466 'span', 00467 array( 'class' => 'mw-protectedpages-unknown' ), 00468 $this->msg( 'protectedpages-unknown-reason' )->escaped() 00469 ); 00470 } else { 00471 if ( LogEventsList::userCanBitfield( 00472 $row->log_deleted, 00473 LogPage::DELETED_COMMENT, 00474 $this->getUser() 00475 ) ) { 00476 $formatted = Linker::formatComment( $value !== null ? $value : '' ); 00477 } else { 00478 $formatted = $this->msg( 'rev-deleted-comment' )->escaped(); 00479 } 00480 if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) { 00481 $formatted = '<span class="history-deleted">' . $formatted . '</span>'; 00482 } 00483 } 00484 break; 00485 00486 default: 00487 throw new MWException( "Unknown field '$field'" ); 00488 } 00489 00490 return $formatted; 00491 } 00492 00493 function getQueryInfo() { 00494 $conds = $this->mConds; 00495 $conds[] = 'pr_expiry > ' . $this->mDb->addQuotes( $this->mDb->timestamp() ) . 00496 'OR pr_expiry IS NULL'; 00497 $conds[] = 'page_id=pr_page'; 00498 $conds[] = 'pr_type=' . $this->mDb->addQuotes( $this->type ); 00499 00500 if ( $this->sizetype == 'min' ) { 00501 $conds[] = 'page_len>=' . $this->size; 00502 } elseif ( $this->sizetype == 'max' ) { 00503 $conds[] = 'page_len<=' . $this->size; 00504 } 00505 00506 if ( $this->indefonly ) { 00507 $infinity = $this->mDb->addQuotes( $this->mDb->getInfinity() ); 00508 $conds[] = "pr_expiry = $infinity OR pr_expiry IS NULL"; 00509 } 00510 if ( $this->cascadeonly ) { 00511 $conds[] = 'pr_cascade = 1'; 00512 } 00513 if ( $this->noredirect ) { 00514 $conds[] = 'page_is_redirect = 0'; 00515 } 00516 00517 if ( $this->level ) { 00518 $conds[] = 'pr_level=' . $this->mDb->addQuotes( $this->level ); 00519 } 00520 if ( !is_null( $this->namespace ) ) { 00521 $conds[] = 'page_namespace=' . $this->mDb->addQuotes( $this->namespace ); 00522 } 00523 00524 return array( 00525 'tables' => array( 'page', 'page_restrictions', 'log_search', 'logging' ), 00526 'fields' => array( 00527 'pr_id', 00528 'page_namespace', 00529 'page_title', 00530 'page_len', 00531 'pr_type', 00532 'pr_level', 00533 'pr_expiry', 00534 'pr_cascade', 00535 'log_timestamp', 00536 'log_user', 00537 'log_comment', 00538 'log_deleted', 00539 ), 00540 'conds' => $conds, 00541 'join_conds' => array( 00542 'log_search' => array( 00543 'LEFT JOIN', array( 00544 'ls_field' => 'pr_id', 'ls_value = pr_id' 00545 ) 00546 ), 00547 'logging' => array( 00548 'LEFT JOIN', array( 00549 'ls_log_id = log_id' 00550 ) 00551 ) 00552 ) 00553 ); 00554 } 00555 00556 public function getTableClass() { 00557 return parent::getTableClass() . ' mw-protectedpages'; 00558 } 00559 00560 function getIndexField() { 00561 return 'pr_id'; 00562 } 00563 00564 function getDefaultSort() { 00565 return 'pr_id'; 00566 } 00567 00568 function isFieldSortable( $field ) { 00569 // no index for sorting exists 00570 return false; 00571 } 00572 }