Special:Randompage with no parameters now selects a random page from any namespace...
[lhc/web/wiklou.git] / includes / SpecialRandompage.php
1 <?php
2
3 /**
4 * Special page to direct the user to a random page
5 *
6 * @addtogroup SpecialPage
7 * @author Rob Church <robchur@gmail.com>, Ilmari Karonen
8 * @license GNU General Public Licence 2.0 or later
9 */
10
11 /**
12 * Main execution point
13 * @param $par Namespace to select the page from
14 */
15 function wfSpecialRandompage( $par = null ) {
16 global $wgOut, $wgContLang;
17
18 $rnd = new RandomPage();
19
20 if ( $par == null ) {
21 // Select a random content namespace to use.
22 global $wgContentNamespaces;
23 $n = array_rand( $wgContentNamespaces );
24 $rnd->setNamespace( $wgContentNamespaces[$n] );
25 }
26 else {
27 $rnd->setNamespace( $wgContLang->getNsIndex( $par ) );
28 }
29
30 $rnd->setRedirect( false );
31
32 $title = $rnd->getRandomTitle();
33
34 if( is_null( $title ) ) {
35 $wgOut->addWikiText( wfMsg( 'randompage-nopages' ) );
36 return;
37 }
38
39 $wgOut->reportTime();
40 $wgOut->redirect( $title->getFullUrl() );
41 }
42
43
44 /**
45 * Special page to direct the user to a random page
46 *
47 * @addtogroup SpecialPage
48 */
49 class RandomPage {
50 private $namespace = NS_MAIN; // namespace to select pages from
51 private $redirect = false; // select redirects instead of normal pages?
52
53 public function getNamespace ( ) {
54 return $this->namespace;
55 }
56 public function setNamespace ( $ns ) {
57 if( $ns < NS_MAIN ) $ns = NS_MAIN;
58 $this->namespace = $ns;
59 }
60 public function getRedirect ( ) {
61 return $this->redirect;
62 }
63 public function setRedirect ( $redirect ) {
64 $this->redirect = $redirect;
65 }
66
67 /**
68 * Choose a random title.
69 * @return Title object (or null if nothing to choose from)
70 */
71 public function getRandomTitle ( ) {
72 $randstr = wfRandom();
73 $row = $this->selectRandomPageFromDB( $randstr );
74
75 /* If we picked a value that was higher than any in
76 * the DB, wrap around and select the page with the
77 * lowest value instead! One might think this would
78 * skew the distribution, but in fact it won't cause
79 * any more bias than what the page_random scheme
80 * causes anyway. Trust me, I'm a mathematician. :)
81 */
82 if( !$row )
83 $row = $this->selectRandomPageFromDB( "0" );
84
85 if( $row )
86 return Title::makeTitleSafe( $this->namespace, $row->page_title );
87 else
88 return null;
89 }
90
91 private function selectRandomPageFromDB ( $randstr ) {
92 global $wgExtraRandompageSQL;
93 $fname = 'RandomPage::selectRandomPageFromDB';
94
95 $dbr = wfGetDB( DB_SLAVE );
96
97 $use_index = $dbr->useIndexClause( 'page_random' );
98 $page = $dbr->tableName( 'page' );
99
100 $ns = (int) $this->namespace;
101 $redirect = $this->redirect ? 1 : 0;
102
103 $extra = $wgExtraRandompageSQL ? "AND ($wgExtraRandompageSQL)" : "";
104 $sql = "SELECT page_title
105 FROM $page $use_index
106 WHERE page_namespace = $ns
107 AND page_is_redirect = $redirect
108 AND page_random >= $randstr
109 $extra
110 ORDER BY page_random";
111
112 $sql = $dbr->limitResult( $sql, 1, 0 );
113 $res = $dbr->query( $sql, $fname );
114 return $dbr->fetchObject( $res );
115 }
116 }
117
118 ?>