MediaWiki  REL1_24
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 ( 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 }