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