00001 <?php 00002 00010 class RandomPage extends SpecialPage { 00011 private $namespaces; // namespaces to select pages from 00012 00013 function __construct( $name = 'Randompage' ){ 00014 global $wgContentNamespaces; 00015 00016 $this->namespaces = $wgContentNamespaces; 00017 00018 parent::__construct( $name ); 00019 } 00020 00021 public function getNamespaces() { 00022 return $this->namespaces; 00023 } 00024 00025 public function setNamespace ( $ns ) { 00026 if( !$ns || $ns < NS_MAIN ) $ns = NS_MAIN; 00027 $this->namespaces = array( $ns ); 00028 } 00029 00030 // select redirects instead of normal pages? 00031 // Overriden by SpecialRandomredirect 00032 public function isRedirect(){ 00033 return false; 00034 } 00035 00036 public function execute( $par ) { 00037 global $wgOut, $wgContLang; 00038 00039 if ($par) 00040 $this->setNamespace( $wgContLang->getNsIndex( $par ) ); 00041 00042 $title = $this->getRandomTitle(); 00043 00044 if( is_null( $title ) ) { 00045 $this->setHeaders(); 00046 $wgOut->addWikiMsg( strtolower( $this->mName ) . '-nopages', $wgContLang->getNsText( $this->namespace ) ); 00047 return; 00048 } 00049 00050 $query = $this->isRedirect() ? 'redirect=no' : ''; 00051 $wgOut->redirect( $title->getFullUrl( $query ) ); 00052 } 00053 00054 00059 public function getRandomTitle() { 00060 $randstr = wfRandom(); 00061 $row = $this->selectRandomPageFromDB( $randstr ); 00062 00063 /* If we picked a value that was higher than any in 00064 * the DB, wrap around and select the page with the 00065 * lowest value instead! One might think this would 00066 * skew the distribution, but in fact it won't cause 00067 * any more bias than what the page_random scheme 00068 * causes anyway. Trust me, I'm a mathematician. :) 00069 */ 00070 if( !$row ) 00071 $row = $this->selectRandomPageFromDB( "0" ); 00072 00073 if( $row ) 00074 return Title::makeTitleSafe( $row->page_namespace, $row->page_title ); 00075 else 00076 return null; 00077 } 00078 00079 private function selectRandomPageFromDB( $randstr ) { 00080 global $wgExtraRandompageSQL; 00081 $fname = 'RandomPage::selectRandomPageFromDB'; 00082 00083 $dbr = wfGetDB( DB_SLAVE ); 00084 00085 $use_index = $dbr->useIndexClause( 'page_random' ); 00086 $page = $dbr->tableName( 'page' ); 00087 00088 $ns = implode( ",", $this->namespaces ); 00089 $redirect = $this->isRedirect() ? 1 : 0; 00090 00091 $extra = $wgExtraRandompageSQL ? "AND ($wgExtraRandompageSQL)" : ""; 00092 $sql = "SELECT page_title, page_namespace 00093 FROM $page $use_index 00094 WHERE page_namespace IN ( $ns ) 00095 AND page_is_redirect = $redirect 00096 AND page_random >= $randstr 00097 $extra 00098 ORDER BY page_random"; 00099 00100 $sql = $dbr->limitResult( $sql, 1, 0 ); 00101 $res = $dbr->query( $sql, $fname ); 00102 return $dbr->fetchObject( $res ); 00103 } 00104 }