MediaWiki  REL1_19
ApiQueryAllLinks.php
Go to the documentation of this file.
00001 <?php
00032 class ApiQueryAllLinks extends ApiQueryGeneratorBase {
00033 
00034         public function __construct( $query, $moduleName ) {
00035                 parent::__construct( $query, $moduleName, 'al' );
00036         }
00037 
00038         public function execute() {
00039                 $this->run();
00040         }
00041 
00042         public function getCacheMode( $params ) {
00043                 return 'public';
00044         }
00045 
00046         public function executeGenerator( $resultPageSet ) {
00047                 $this->run( $resultPageSet );
00048         }
00049 
00054         private function run( $resultPageSet = null ) {
00055                 $db = $this->getDB();
00056                 $params = $this->extractRequestParams();
00057 
00058                 $prop = array_flip( $params['prop'] );
00059                 $fld_ids = isset( $prop['ids'] );
00060                 $fld_title = isset( $prop['title'] );
00061 
00062                 if ( $params['unique'] ) {
00063                         if ( !is_null( $resultPageSet ) ) {
00064                                 $this->dieUsage( $this->getModuleName() . ' cannot be used as a generator in unique links mode', 'params' );
00065                         }
00066                         if ( $fld_ids ) {
00067                                 $this->dieUsage( $this->getModuleName() . ' cannot return corresponding page ids in unique links mode', 'params' );
00068                         }
00069                         $this->addOption( 'DISTINCT' );
00070                 }
00071 
00072                 $this->addTables( 'pagelinks' );
00073                 $this->addWhereFld( 'pl_namespace', $params['namespace'] );
00074 
00075                 if ( !is_null( $params['from'] ) && !is_null( $params['continue'] ) ) {
00076                         $this->dieUsage( 'alcontinue and alfrom cannot be used together', 'params' );
00077                 }
00078                 if ( !is_null( $params['continue'] ) ) {
00079                         $arr = explode( '|', $params['continue'] );
00080                         if ( count( $arr ) != 2 ) {
00081                                 $this->dieUsage( 'Invalid continue parameter', 'badcontinue' );
00082                         }
00083                         $from = $this->getDB()->strencode( $this->titleToKey( $arr[0] ) );
00084                         $id = intval( $arr[1] );
00085                         $this->addWhere(
00086                                 "pl_title > '$from' OR " .
00087                                 "(pl_title = '$from' AND " .
00088                                 "pl_from > $id)"
00089                         );
00090                 }
00091 
00092                 $from = ( is_null( $params['from'] ) ? null : $this->titlePartToKey( $params['from'] ) );
00093                 $to = ( is_null( $params['to'] ) ? null : $this->titlePartToKey( $params['to'] ) );
00094                 $this->addWhereRange( 'pl_title', 'newer', $from, $to );
00095 
00096                 if ( isset( $params['prefix'] ) ) {
00097                         $this->addWhere( 'pl_title' . $db->buildLike( $this->titlePartToKey( $params['prefix'] ), $db->anyString() ) );
00098                 }
00099 
00100                 $this->addFields( 'pl_title' );
00101                 $this->addFieldsIf( 'pl_from', !$params['unique'] );
00102 
00103                 $this->addOption( 'USE INDEX', 'pl_namespace' );
00104                 $limit = $params['limit'];
00105                 $this->addOption( 'LIMIT', $limit + 1 );
00106 
00107                 if ( !$params['unique'] ) {
00108                         $this->addOption( 'ORDER BY', 'pl_title, pl_from' );
00109                 }
00110 
00111                 $res = $this->select( __METHOD__ );
00112 
00113                 $pageids = array();
00114                 $count = 0;
00115                 $result = $this->getResult();
00116                 foreach ( $res as $row ) {
00117                         if ( ++ $count > $limit ) {
00118                                 // We've reached the one extra which shows that there are additional pages to be had. Stop here...
00119                                 // TODO: Security issue - if the user has no right to view next title, it will still be shown
00120                                 if ( $params['unique'] ) {
00121                                         $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->pl_title ) );
00122                                 } else {
00123                                         $this->setContinueEnumParameter( 'continue', $this->keyToTitle( $row->pl_title ) . "|" . $row->pl_from );
00124                                 }
00125                                 break;
00126                         }
00127 
00128                         if ( is_null( $resultPageSet ) ) {
00129                                 $vals = array();
00130                                 if ( $fld_ids ) {
00131                                         $vals['fromid'] = intval( $row->pl_from );
00132                                 }
00133                                 if ( $fld_title ) {
00134                                         $title = Title::makeTitle( $params['namespace'], $row->pl_title );
00135                                         ApiQueryBase::addTitleInfo( $vals, $title );
00136                                 }
00137                                 $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
00138                                 if ( !$fit ) {
00139                                         if ( $params['unique'] ) {
00140                                                 $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->pl_title ) );
00141                                         } else {
00142                                                 $this->setContinueEnumParameter( 'continue', $this->keyToTitle( $row->pl_title ) . "|" . $row->pl_from );
00143                                         }
00144                                         break;
00145                                 }
00146                         } else {
00147                                 $pageids[] = $row->pl_from;
00148                         }
00149                 }
00150 
00151                 if ( is_null( $resultPageSet ) ) {
00152                         $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'l' );
00153                 } else {
00154                         $resultPageSet->populateFromPageIDs( $pageids );
00155                 }
00156         }
00157 
00158         public function getAllowedParams() {
00159                 return array(
00160                         'continue' => null,
00161                         'from' => null,
00162                         'to' => null,
00163                         'prefix' => null,
00164                         'unique' => false,
00165                         'prop' => array(
00166                                 ApiBase::PARAM_ISMULTI => true,
00167                                 ApiBase::PARAM_DFLT => 'title',
00168                                 ApiBase::PARAM_TYPE => array(
00169                                         'ids',
00170                                         'title'
00171                                 )
00172                         ),
00173                         'namespace' => array(
00174                                 ApiBase::PARAM_DFLT => 0,
00175                                 ApiBase::PARAM_TYPE => 'namespace'
00176                         ),
00177                         'limit' => array(
00178                                 ApiBase::PARAM_DFLT => 10,
00179                                 ApiBase::PARAM_TYPE => 'limit',
00180                                 ApiBase::PARAM_MIN => 1,
00181                                 ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
00182                                 ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
00183                         )
00184                 );
00185         }
00186 
00187         public function getParamDescription() {
00188                 $p = $this->getModulePrefix();
00189                 return array(
00190                         'from' => 'The page title to start enumerating from',
00191                         'to' => 'The page title to stop enumerating at',
00192                         'prefix' => 'Search for all page titles that begin with this value',
00193                         'unique' => "Only show unique links. Cannot be used with generator or {$p}prop=ids",
00194                         'prop' => array(
00195                                 'What pieces of information to include',
00196                                 " ids    - Adds pageid of where the link is from (Cannot be used with {$p}unique)",
00197                                 ' title  - Adds the title of the link',
00198                         ),
00199                         'namespace' => 'The namespace to enumerate',
00200                         'limit' => 'How many total links to return',
00201                         'continue' => 'When more results are available, use this to continue',
00202                 );
00203         }
00204 
00205         public function getDescription() {
00206                 return 'Enumerate all links that point to a given namespace';
00207         }
00208 
00209         public function getPossibleErrors() {
00210                 $m = $this->getModuleName();
00211                 return array_merge( parent::getPossibleErrors(), array(
00212                         array( 'code' => 'params', 'info' => "{$m} cannot be used as a generator in unique links mode" ),
00213                         array( 'code' => 'params', 'info' => "{$m} cannot return corresponding page ids in unique links mode" ),
00214                         array( 'code' => 'params', 'info' => 'alcontinue and alfrom cannot be used together' ),
00215                         array( 'code' => 'badcontinue', 'info' => 'Invalid continue parameter' ),
00216                 ) );
00217         }
00218 
00219         public function getExamples() {
00220                 return array(
00221                         'api.php?action=query&list=alllinks&alunique=&alfrom=B',
00222                 );
00223         }
00224 
00225         public function getHelpUrls() {
00226                 return 'https://www.mediawiki.org/wiki/API:Alllinks';
00227         }
00228 
00229         public function getVersion() {
00230                 return __CLASS__ . ': $Id$';
00231         }
00232 }