MediaWiki
REL1_24
|
00001 <?php 00030 class RandomPage extends SpecialPage { 00031 private $namespaces; // namespaces to select pages from 00032 protected $isRedir = false; // should the result be a redirect? 00033 protected $extra = array(); // Extra SQL statements 00034 00035 public function __construct( $name = 'Randompage' ) { 00036 $this->namespaces = MWNamespace::getContentNamespaces(); 00037 parent::__construct( $name ); 00038 } 00039 00040 public function getNamespaces() { 00041 return $this->namespaces; 00042 } 00043 00044 public function setNamespace( $ns ) { 00045 if ( !$ns || $ns < NS_MAIN ) { 00046 $ns = NS_MAIN; 00047 } 00048 $this->namespaces = array( $ns ); 00049 } 00050 00051 // select redirects instead of normal pages? 00052 public function isRedirect() { 00053 return $this->isRedir; 00054 } 00055 00056 public function execute( $par ) { 00057 global $wgContLang; 00058 00059 if ( is_string( $par ) ) { 00060 // Testing for stringiness since we want to catch 00061 // the empty string to mean main namespace only. 00062 $this->setNamespace( $wgContLang->getNsIndex( $par ) ); 00063 } 00064 00065 $title = $this->getRandomTitle(); 00066 00067 if ( is_null( $title ) ) { 00068 $this->setHeaders(); 00069 // Message: randompage-nopages, randomredirect-nopages 00070 $this->getOutput()->addWikiMsg( strtolower( $this->getName() ) . '-nopages', 00071 $this->getNsList(), count( $this->namespaces ) ); 00072 00073 return; 00074 } 00075 00076 $redirectParam = $this->isRedirect() ? array( 'redirect' => 'no' ) : array(); 00077 $query = array_merge( $this->getRequest()->getValues(), $redirectParam ); 00078 unset( $query['title'] ); 00079 $this->getOutput()->redirect( $title->getFullURL( $query ) ); 00080 } 00081 00087 private function getNsList() { 00088 global $wgContLang; 00089 $nsNames = array(); 00090 foreach ( $this->namespaces as $n ) { 00091 if ( $n === NS_MAIN ) { 00092 $nsNames[] = $this->msg( 'blanknamespace' )->plain(); 00093 } else { 00094 $nsNames[] = $wgContLang->getNsText( $n ); 00095 } 00096 } 00097 00098 return $wgContLang->commaList( $nsNames ); 00099 } 00100 00105 public function getRandomTitle() { 00106 $randstr = wfRandom(); 00107 $title = null; 00108 00109 if ( !wfRunHooks( 00110 'SpecialRandomGetRandomTitle', 00111 array( &$randstr, &$this->isRedir, &$this->namespaces, &$this->extra, &$title ) 00112 ) ) { 00113 return $title; 00114 } 00115 00116 $row = $this->selectRandomPageFromDB( $randstr ); 00117 00118 /* If we picked a value that was higher than any in 00119 * the DB, wrap around and select the page with the 00120 * lowest value instead! One might think this would 00121 * skew the distribution, but in fact it won't cause 00122 * any more bias than what the page_random scheme 00123 * causes anyway. Trust me, I'm a mathematician. :) 00124 */ 00125 if ( !$row ) { 00126 $row = $this->selectRandomPageFromDB( "0" ); 00127 } 00128 00129 if ( $row ) { 00130 return Title::makeTitleSafe( $row->page_namespace, $row->page_title ); 00131 } 00132 00133 return null; 00134 } 00135 00136 protected function getQueryInfo( $randstr ) { 00137 $redirect = $this->isRedirect() ? 1 : 0; 00138 00139 return array( 00140 'tables' => array( 'page' ), 00141 'fields' => array( 'page_title', 'page_namespace' ), 00142 'conds' => array_merge( array( 00143 'page_namespace' => $this->namespaces, 00144 'page_is_redirect' => $redirect, 00145 'page_random >= ' . $randstr 00146 ), $this->extra ), 00147 'options' => array( 00148 'ORDER BY' => 'page_random', 00149 'LIMIT' => 1, 00150 ), 00151 'join_conds' => array() 00152 ); 00153 } 00154 00155 private function selectRandomPageFromDB( $randstr, $fname = __METHOD__ ) { 00156 $dbr = wfGetDB( DB_SLAVE ); 00157 00158 $query = $this->getQueryInfo( $randstr ); 00159 $res = $dbr->select( 00160 $query['tables'], 00161 $query['fields'], 00162 $query['conds'], 00163 $fname, 00164 $query['options'], 00165 $query['join_conds'] 00166 ); 00167 00168 return $dbr->fetchObject( $res ); 00169 } 00170 00171 protected function getGroupName() { 00172 return 'redirects'; 00173 } 00174 }