MediaWiki  REL1_19
SpecialRandompage.php
Go to the documentation of this file.
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 }