MediaWiki  REL1_24
ApiQueryRandom.php
Go to the documentation of this file.
00001 <?php
00002 
00033 class ApiQueryRandom extends ApiQueryGeneratorBase {
00034     private $pageIDs;
00035 
00036     public function __construct( ApiQuery $query, $moduleName ) {
00037         parent::__construct( $query, $moduleName, 'rn' );
00038     }
00039 
00040     public function execute() {
00041         $this->run();
00042     }
00043 
00044     public function executeGenerator( $resultPageSet ) {
00045         $this->run( $resultPageSet );
00046     }
00047 
00056     protected function prepareQuery( $randstr, $limit, $namespace, &$resultPageSet, $redirect ) {
00057         $this->resetQueryParams();
00058         $this->addTables( 'page' );
00059         $this->addOption( 'LIMIT', $limit );
00060         $this->addWhereFld( 'page_namespace', $namespace );
00061         $this->addWhereRange( 'page_random', 'newer', $randstr, null );
00062         $this->addWhereFld( 'page_is_redirect', $redirect );
00063         if ( is_null( $resultPageSet ) ) {
00064             $this->addFields( array( 'page_id', 'page_title', 'page_namespace' ) );
00065         } else {
00066             $this->addFields( $resultPageSet->getPageTableFields() );
00067         }
00068     }
00069 
00074     protected function runQuery( $resultPageSet = null ) {
00075         $res = $this->select( __METHOD__ );
00076         $count = 0;
00077         foreach ( $res as $row ) {
00078             $count++;
00079             if ( is_null( $resultPageSet ) ) {
00080                 // Prevent duplicates
00081                 if ( !in_array( $row->page_id, $this->pageIDs ) ) {
00082                     $fit = $this->getResult()->addValue(
00083                         array( 'query', $this->getModuleName() ),
00084                         null, $this->extractRowInfo( $row ) );
00085                     if ( !$fit ) {
00086                         // We can't really query-continue a random list.
00087                         // Return an insanely high value so
00088                         // $count < $limit is false
00089                         return 1E9;
00090                     }
00091                     $this->pageIDs[] = $row->page_id;
00092                 }
00093             } else {
00094                 $resultPageSet->processDbRow( $row );
00095             }
00096         }
00097 
00098         return $count;
00099     }
00100 
00105     public function run( $resultPageSet = null ) {
00106         $params = $this->extractRequestParams();
00107         $result = $this->getResult();
00108         $this->pageIDs = array();
00109 
00110         $this->prepareQuery(
00111             wfRandom(),
00112             $params['limit'],
00113             $params['namespace'],
00114             $resultPageSet,
00115             $params['redirect']
00116         );
00117         $count = $this->runQuery( $resultPageSet );
00118         if ( $count < $params['limit'] ) {
00119             /* We got too few pages, we probably picked a high value
00120              * for page_random. We'll just take the lowest ones, see
00121              * also the comment in Title::getRandomTitle()
00122              */
00123             $this->prepareQuery(
00124                 0,
00125                 $params['limit'] - $count,
00126                 $params['namespace'],
00127                 $resultPageSet,
00128                 $params['redirect']
00129             );
00130             $this->runQuery( $resultPageSet );
00131         }
00132 
00133         if ( is_null( $resultPageSet ) ) {
00134             $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'page' );
00135         }
00136     }
00137 
00138     private function extractRowInfo( $row ) {
00139         $title = Title::makeTitle( $row->page_namespace, $row->page_title );
00140         $vals = array();
00141         $vals['id'] = intval( $row->page_id );
00142         ApiQueryBase::addTitleInfo( $vals, $title );
00143 
00144         return $vals;
00145     }
00146 
00147     public function getCacheMode( $params ) {
00148         return 'public';
00149     }
00150 
00151     public function getAllowedParams() {
00152         return array(
00153             'namespace' => array(
00154                 ApiBase::PARAM_TYPE => 'namespace',
00155                 ApiBase::PARAM_ISMULTI => true
00156             ),
00157             'limit' => array(
00158                 ApiBase::PARAM_TYPE => 'limit',
00159                 ApiBase::PARAM_DFLT => 1,
00160                 ApiBase::PARAM_MIN => 1,
00161                 ApiBase::PARAM_MAX => 10,
00162                 ApiBase::PARAM_MAX2 => 20
00163             ),
00164             'redirect' => false,
00165         );
00166     }
00167 
00168     public function getParamDescription() {
00169         return array(
00170             'namespace' => 'Return pages in these namespaces only',
00171             'limit' => 'Limit how many random pages will be returned',
00172             'redirect' => 'Load a random redirect instead of a random page'
00173         );
00174     }
00175 
00176     public function getDescription() {
00177         return array(
00178             'Get a set of random pages.',
00179             'NOTE: Pages are listed in a fixed sequence, only the starting point is random.',
00180             '      This means that if, for example, "Main Page" is the first random page on',
00181             '      your list, "List of fictional monkeys" will *always* be second, "List of',
00182             '      people on stamps of Vanuatu" third, etc.',
00183             'NOTE: If the number of pages in the namespace is lower than rnlimit, you will',
00184             '      get fewer pages. You will not get the same page twice.'
00185         );
00186     }
00187 
00188     public function getExamples() {
00189         return 'api.php?action=query&list=random&rnnamespace=0&rnlimit=2';
00190     }
00191 
00192     public function getHelpUrls() {
00193         return 'https://www.mediawiki.org/wiki/API:Random';
00194     }
00195 }