00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 if ( !defined( 'MEDIAWIKI' ) ) {
00027
00028 require_once ( 'ApiQueryBase.php' );
00029 }
00030
00036 class ApiQueryAllpages extends ApiQueryGeneratorBase {
00037
00038 public function __construct( $query, $moduleName ) {
00039 parent :: __construct( $query, $moduleName, 'ap' );
00040 }
00041
00042 public function execute() {
00043 $this->run();
00044 }
00045
00046 public function getCacheMode( $params ) {
00047 return 'public';
00048 }
00049
00050 public function executeGenerator( $resultPageSet ) {
00051 if ( $resultPageSet->isResolvingRedirects() )
00052 $this->dieUsage( 'Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params' );
00053
00054 $this->run( $resultPageSet );
00055 }
00056
00057 private function run( $resultPageSet = null ) {
00058 $db = $this->getDB();
00059
00060 $params = $this->extractRequestParams();
00061
00062
00063 $this->addTables( 'page' );
00064
00065 if ( $params['filterredir'] == 'redirects' )
00066 $this->addWhereFld( 'page_is_redirect', 1 );
00067 else if ( $params['filterredir'] == 'nonredirects' )
00068 $this->addWhereFld( 'page_is_redirect', 0 );
00069
00070 $this->addWhereFld( 'page_namespace', $params['namespace'] );
00071 $dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
00072 $from = ( is_null( $params['from'] ) ? null : $this->titlePartToKey( $params['from'] ) );
00073 $this->addWhereRange( 'page_title', $dir, $from, null );
00074
00075 if ( isset ( $params['prefix'] ) )
00076 $this->addWhere( 'page_title' . $db->buildLike( $this->titlePartToKey( $params['prefix'] ), $db->anyString() ) );
00077
00078 if ( is_null( $resultPageSet ) ) {
00079 $selectFields = array (
00080 'page_namespace',
00081 'page_title',
00082 'page_id'
00083 );
00084 } else {
00085 $selectFields = $resultPageSet->getPageTableFields();
00086 }
00087
00088 $this->addFields( $selectFields );
00089 $forceNameTitleIndex = true;
00090 if ( isset ( $params['minsize'] ) ) {
00091 $this->addWhere( 'page_len>=' . intval( $params['minsize'] ) );
00092 $forceNameTitleIndex = false;
00093 }
00094
00095 if ( isset ( $params['maxsize'] ) ) {
00096 $this->addWhere( 'page_len<=' . intval( $params['maxsize'] ) );
00097 $forceNameTitleIndex = false;
00098 }
00099
00100
00101 if ( !empty ( $params['prtype'] ) ) {
00102 $this->addTables( 'page_restrictions' );
00103 $this->addWhere( 'page_id=pr_page' );
00104 $this->addWhere( 'pr_expiry>' . $db->addQuotes( $db->timestamp() ) );
00105 $this->addWhereFld( 'pr_type', $params['prtype'] );
00106
00107 if ( isset ( $params['prlevel'] ) ) {
00108
00109 $prlevel = array_diff( $params['prlevel'], array( '', '*' ) );
00110
00111 if ( !empty( $prlevel ) )
00112 $this->addWhereFld( 'pr_level', $prlevel );
00113 }
00114 if ( $params['prfiltercascade'] == 'cascading' )
00115 $this->addWhereFld( 'pr_cascade', 1 );
00116 else if ( $params['prfiltercascade'] == 'noncascading' )
00117 $this->addWhereFld( 'pr_cascade', 0 );
00118
00119 $this->addOption( 'DISTINCT' );
00120
00121 $forceNameTitleIndex = false;
00122
00123 } else if ( isset ( $params['prlevel'] ) ) {
00124 $this->dieUsage( 'prlevel may not be used without prtype', 'params' );
00125 }
00126
00127 if ( $params['filterlanglinks'] == 'withoutlanglinks' ) {
00128 $this->addTables( 'langlinks' );
00129 $this->addJoinConds( array( 'langlinks' => array( 'LEFT JOIN', 'page_id=ll_from' ) ) );
00130 $this->addWhere( 'll_from IS NULL' );
00131 $forceNameTitleIndex = false;
00132 } else if ( $params['filterlanglinks'] == 'withlanglinks' ) {
00133 $this->addTables( 'langlinks' );
00134 $this->addWhere( 'page_id=ll_from' );
00135 $this->addOption( 'STRAIGHT_JOIN' );
00136
00137
00138 $this->addOption( 'GROUP BY', implode( ', ', $selectFields ) );
00139 $forceNameTitleIndex = false;
00140 }
00141
00142 if ( $forceNameTitleIndex )
00143 $this->addOption( 'USE INDEX', 'name_title' );
00144
00145 $limit = $params['limit'];
00146 $this->addOption( 'LIMIT', $limit + 1 );
00147 $res = $this->select( __METHOD__ );
00148
00149 $count = 0;
00150 $result = $this->getResult();
00151 while ( $row = $db->fetchObject( $res ) ) {
00152 if ( ++ $count > $limit ) {
00153
00154
00155 $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->page_title ) );
00156 break;
00157 }
00158
00159 if ( is_null( $resultPageSet ) ) {
00160 $title = Title :: makeTitle( $row->page_namespace, $row->page_title );
00161 $vals = array(
00162 'pageid' => intval( $row->page_id ),
00163 'ns' => intval( $title->getNamespace() ),
00164 'title' => $title->getPrefixedText() );
00165 $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
00166 if ( !$fit )
00167 {
00168 $this->setContinueEnumParameter( 'from', $this->keyToTitle( $row->page_title ) );
00169 break;
00170 }
00171 } else {
00172 $resultPageSet->processDbRow( $row );
00173 }
00174 }
00175 $db->freeResult( $res );
00176
00177 if ( is_null( $resultPageSet ) ) {
00178 $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'p' );
00179 }
00180 }
00181
00182 public function getAllowedParams() {
00183 global $wgRestrictionTypes, $wgRestrictionLevels;
00184
00185 return array (
00186 'from' => null,
00187 'prefix' => null,
00188 'namespace' => array (
00189 ApiBase :: PARAM_DFLT => 0,
00190 ApiBase :: PARAM_TYPE => 'namespace',
00191 ),
00192 'filterredir' => array (
00193 ApiBase :: PARAM_DFLT => 'all',
00194 ApiBase :: PARAM_TYPE => array (
00195 'all',
00196 'redirects',
00197 'nonredirects'
00198 )
00199 ),
00200 'minsize' => array (
00201 ApiBase :: PARAM_TYPE => 'integer',
00202 ),
00203 'maxsize' => array (
00204 ApiBase :: PARAM_TYPE => 'integer',
00205 ),
00206 'prtype' => array (
00207 ApiBase :: PARAM_TYPE => $wgRestrictionTypes,
00208 ApiBase :: PARAM_ISMULTI => true
00209 ),
00210 'prlevel' => array (
00211 ApiBase :: PARAM_TYPE => $wgRestrictionLevels,
00212 ApiBase :: PARAM_ISMULTI => true
00213 ),
00214 'prfiltercascade' => array (
00215 ApiBase :: PARAM_DFLT => 'all',
00216 ApiBase :: PARAM_TYPE => array (
00217 'cascading',
00218 'noncascading',
00219 'all'
00220 ),
00221 ),
00222 'limit' => array (
00223 ApiBase :: PARAM_DFLT => 10,
00224 ApiBase :: PARAM_TYPE => 'limit',
00225 ApiBase :: PARAM_MIN => 1,
00226 ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
00227 ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
00228 ),
00229 'dir' => array (
00230 ApiBase :: PARAM_DFLT => 'ascending',
00231 ApiBase :: PARAM_TYPE => array (
00232 'ascending',
00233 'descending'
00234 )
00235 ),
00236 'filterlanglinks' => array(
00237 ApiBase :: PARAM_TYPE => array(
00238 'withlanglinks',
00239 'withoutlanglinks',
00240 'all'
00241 ),
00242 ApiBase :: PARAM_DFLT => 'all'
00243 )
00244 );
00245 }
00246
00247 public function getParamDescription() {
00248 return array (
00249 'from' => 'The page title to start enumerating from.',
00250 'prefix' => 'Search for all page titles that begin with this value.',
00251 'namespace' => 'The namespace to enumerate.',
00252 'filterredir' => 'Which pages to list.',
00253 'dir' => 'The direction in which to list',
00254 'minsize' => 'Limit to pages with at least this many bytes',
00255 'maxsize' => 'Limit to pages with at most this many bytes',
00256 'prtype' => 'Limit to protected pages only',
00257 'prlevel' => 'The protection level (must be used with apprtype= parameter)',
00258 'prfiltercascade' => 'Filter protections based on cascadingness (ignored when apprtype isn\'t set)',
00259 'filterlanglinks' => 'Filter based on whether a page has langlinks',
00260 'limit' => 'How many total pages to return.'
00261 );
00262 }
00263
00264 public function getDescription() {
00265 return 'Enumerate all pages sequentially in a given namespace';
00266 }
00267
00268 public function getPossibleErrors() {
00269 return array_merge( parent::getPossibleErrors(), array(
00270 array( 'code' => 'params', 'info' => 'Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator' ),
00271 array( 'code' => 'params', 'info' => 'prlevel may not be used without prtype' ),
00272 ) );
00273 }
00274
00275 protected function getExamples() {
00276 return array (
00277 'Simple Use',
00278 ' Show a list of pages starting at the letter "B"',
00279 ' api.php?action=query&list=allpages&apfrom=B',
00280 'Using as Generator',
00281 ' Show info about 4 pages starting at the letter "T"',
00282 ' api.php?action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info',
00283 ' Show content of first 2 non-redirect pages begining at "Re"',
00284 ' api.php?action=query&generator=allpages&gaplimit=2&gapfilterredir=nonredirects&gapfrom=Re&prop=revisions&rvprop=content'
00285 );
00286 }
00287
00288 public function getVersion() {
00289 return __CLASS__ . ': $Id: ApiQueryAllpages.php 69932 2010-07-26 08:03:21Z tstarling $';
00290 }
00291 }