MediaWiki
REL1_19
|
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 ( $par ) { 00060 $this->setNamespace( $wgContLang->getNsIndex( $par ) ); 00061 } 00062 00063 $title = $this->getRandomTitle(); 00064 00065 if( is_null( $title ) ) { 00066 $this->setHeaders(); 00067 $this->getOutput()->addWikiMsg( strtolower( $this->getName() ) . '-nopages', 00068 $this->getNsList(), count( $this->namespaces ) ); 00069 return; 00070 } 00071 00072 $redirectParam = $this->isRedirect() ? array( 'redirect' => 'no' ) : array(); 00073 $query = array_merge( $this->getRequest()->getValues(), $redirectParam ); 00074 unset( $query['title'] ); 00075 $this->getOutput()->redirect( $title->getFullUrl( $query ) ); 00076 } 00077 00083 private function getNsList() { 00084 global $wgContLang; 00085 $nsNames = array(); 00086 foreach( $this->namespaces as $n ) { 00087 if( $n === NS_MAIN ) { 00088 $nsNames[] = wfMsgNoTrans( 'blanknamespace' ); 00089 } else { 00090 $nsNames[] = $wgContLang->getNsText( $n ); 00091 } 00092 } 00093 return $wgContLang->commaList( $nsNames ); 00094 } 00095 00100 public function getRandomTitle() { 00101 $randstr = wfRandom(); 00102 $title = null; 00103 if ( !wfRunHooks( 'SpecialRandomGetRandomTitle', array( &$randstr, &$this->isRedir, &$this->namespaces, 00104 &$this->extra, &$title ) ) ) { 00105 return $title; 00106 } 00107 $row = $this->selectRandomPageFromDB( $randstr ); 00108 00109 /* If we picked a value that was higher than any in 00110 * the DB, wrap around and select the page with the 00111 * lowest value instead! One might think this would 00112 * skew the distribution, but in fact it won't cause 00113 * any more bias than what the page_random scheme 00114 * causes anyway. Trust me, I'm a mathematician. :) 00115 */ 00116 if( !$row ) { 00117 $row = $this->selectRandomPageFromDB( "0" ); 00118 } 00119 00120 if( $row ) { 00121 return Title::makeTitleSafe( $row->page_namespace, $row->page_title ); 00122 } else { 00123 return null; 00124 } 00125 } 00126 00127 protected function getQueryInfo( $randstr ) { 00128 $redirect = $this->isRedirect() ? 1 : 0; 00129 00130 return array( 00131 'tables' => array( 'page' ), 00132 'fields' => array( 'page_title', 'page_namespace' ), 00133 'conds' => array_merge( array( 00134 'page_namespace' => $this->namespaces, 00135 'page_is_redirect' => $redirect, 00136 'page_random >= ' . $randstr 00137 ), $this->extra ), 00138 'options' => array( 00139 'ORDER BY' => 'page_random', 00140 'USE INDEX' => 'page_random', 00141 'LIMIT' => 1, 00142 ), 00143 'join_conds' => array() 00144 ); 00145 } 00146 00147 private function selectRandomPageFromDB( $randstr, $fname = __METHOD__ ) { 00148 $dbr = wfGetDB( DB_SLAVE ); 00149 00150 $query = $this->getQueryInfo( $randstr ); 00151 $res = $dbr->select( 00152 $query['tables'], 00153 $query['fields'], 00154 $query['conds'], 00155 $fname, 00156 $query['options'], 00157 $query['join_conds'] 00158 ); 00159 00160 return $dbr->fetchObject( $res ); 00161 } 00162 }