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