Add comment about why we pick a random number in PHP and use it as a
[lhc/web/wiklou.git] / includes / SpecialRandompage.php
1 <?php
2 /**
3 * @version # $Id$
4 * @package MediaWiki
5 * @subpackage SpecialPage
6 */
7
8 /**
9 * Constructor
10 */
11 function wfSpecialRandompage() {
12 global $wgOut, $wgTitle, $wgArticle, $wgExtraRandompageSQL;
13 $fname = 'wfSpecialRandompage';
14
15 # NOTE! We use a literal constant in the SQL instead of the RAND()
16 # function because RAND() will return a different value for every row
17 # in the table. That's both very slow and returns results heavily
18 # biased towards low values, as rows later in the table will likely
19 # never be reached for comparison.
20 #
21 # Using a literal constant means the whole thing gets optimized on
22 # the index, and the comparison is both fast and fair.
23 $rand = mt_rand() / mt_getrandmax();
24
25 # interpolation and sprintf() can muck up with locale-specific decimal separator
26 $randstr = number_format( $rand, 12, ".", "" );
27
28 $db =& wfGetDB( DB_SLAVE );
29 $use_index = $db->useIndexClause( 'cur_random' );
30 $cur = $db->tableName( 'cur' );
31
32 if ( $wgExtraRandompageSQL ) {
33 $extra = "AND ($wgExtraRandompageSQL)";
34 } else {
35 $extra = '';
36 }
37 $sqlget = "SELECT cur_id,cur_title
38 FROM $cur $use_index
39 WHERE cur_namespace=0 AND cur_is_redirect=0 $extra
40 AND cur_random>$randstr
41 ORDER BY cur_random
42 LIMIT 1";
43 $res = $db->query( $sqlget, $fname );
44
45 $title = null;
46 if( $s = $db->fetchObject( $res ) ) {
47 $title =& Title::makeTitle( NS_MAIN, $s->cur_title );
48 }
49 if( is_null( $title ) ) {
50 # That's not supposed to happen :)
51 $title =& Title::newFromText( wfMsg( 'mainpage' ) );
52 }
53 $wgOut->reportTime(); # for logfile
54 $wgOut->redirect( $title->getFullUrl() );
55 }
56
57 ?>