[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/api/ -> ApiQueryAllPages.php (source)

   1  <?php
   2  /**
   3   *
   4   *
   5   * Created on Sep 25, 2006
   6   *
   7   * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
   8   *
   9   * This program is free software; you can redistribute it and/or modify
  10   * it under the terms of the GNU General Public License as published by
  11   * the Free Software Foundation; either version 2 of the License, or
  12   * (at your option) any later version.
  13   *
  14   * This program is distributed in the hope that it will be useful,
  15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17   * GNU General Public License for more details.
  18   *
  19   * You should have received a copy of the GNU General Public License along
  20   * with this program; if not, write to the Free Software Foundation, Inc.,
  21   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22   * http://www.gnu.org/copyleft/gpl.html
  23   *
  24   * @file
  25   */
  26  
  27  /**
  28   * Query module to enumerate all available pages.
  29   *
  30   * @ingroup API
  31   */
  32  class ApiQueryAllPages extends ApiQueryGeneratorBase {
  33  
  34  	public function __construct( ApiQuery $query, $moduleName ) {
  35          parent::__construct( $query, $moduleName, 'ap' );
  36      }
  37  
  38  	public function execute() {
  39          $this->run();
  40      }
  41  
  42  	public function getCacheMode( $params ) {
  43          return 'public';
  44      }
  45  
  46      /**
  47       * @param ApiPageSet $resultPageSet
  48       * @return void
  49       */
  50  	public function executeGenerator( $resultPageSet ) {
  51          if ( $resultPageSet->isResolvingRedirects() ) {
  52              $this->dieUsage(
  53                  'Use "gapfilterredir=nonredirects" option instead of "redirects" ' .
  54                      'when using allpages as a generator',
  55                  'params'
  56              );
  57          }
  58  
  59          $this->run( $resultPageSet );
  60      }
  61  
  62      /**
  63       * @param ApiPageSet $resultPageSet
  64       * @return void
  65       */
  66  	private function run( $resultPageSet = null ) {
  67          $db = $this->getDB();
  68  
  69          $params = $this->extractRequestParams();
  70  
  71          // Page filters
  72          $this->addTables( 'page' );
  73  
  74          if ( !is_null( $params['continue'] ) ) {
  75              $cont = explode( '|', $params['continue'] );
  76              $this->dieContinueUsageIf( count( $cont ) != 1 );
  77              $op = $params['dir'] == 'descending' ? '<' : '>';
  78              $cont_from = $db->addQuotes( $cont[0] );
  79              $this->addWhere( "page_title $op= $cont_from" );
  80          }
  81  
  82          if ( $params['filterredir'] == 'redirects' ) {
  83              $this->addWhereFld( 'page_is_redirect', 1 );
  84          } elseif ( $params['filterredir'] == 'nonredirects' ) {
  85              $this->addWhereFld( 'page_is_redirect', 0 );
  86          }
  87  
  88          $this->addWhereFld( 'page_namespace', $params['namespace'] );
  89          $dir = ( $params['dir'] == 'descending' ? 'older' : 'newer' );
  90          $from = ( $params['from'] === null
  91              ? null
  92              : $this->titlePartToKey( $params['from'], $params['namespace'] ) );
  93          $to = ( $params['to'] === null
  94              ? null
  95              : $this->titlePartToKey( $params['to'], $params['namespace'] ) );
  96          $this->addWhereRange( 'page_title', $dir, $from, $to );
  97  
  98          if ( isset( $params['prefix'] ) ) {
  99              $this->addWhere( 'page_title' . $db->buildLike(
 100                  $this->titlePartToKey( $params['prefix'], $params['namespace'] ),
 101                  $db->anyString() ) );
 102          }
 103  
 104          if ( is_null( $resultPageSet ) ) {
 105              $selectFields = array(
 106                  'page_namespace',
 107                  'page_title',
 108                  'page_id'
 109              );
 110          } else {
 111              $selectFields = $resultPageSet->getPageTableFields();
 112          }
 113  
 114          $this->addFields( $selectFields );
 115          $forceNameTitleIndex = true;
 116          if ( isset( $params['minsize'] ) ) {
 117              $this->addWhere( 'page_len>=' . intval( $params['minsize'] ) );
 118              $forceNameTitleIndex = false;
 119          }
 120  
 121          if ( isset( $params['maxsize'] ) ) {
 122              $this->addWhere( 'page_len<=' . intval( $params['maxsize'] ) );
 123              $forceNameTitleIndex = false;
 124          }
 125  
 126          // Page protection filtering
 127          if ( count( $params['prtype'] ) || $params['prexpiry'] != 'all' ) {
 128              $this->addTables( 'page_restrictions' );
 129              $this->addWhere( 'page_id=pr_page' );
 130              $this->addWhere( "pr_expiry > {$db->addQuotes( $db->timestamp() )} OR pr_expiry IS NULL" );
 131  
 132              if ( count( $params['prtype'] ) ) {
 133                  $this->addWhereFld( 'pr_type', $params['prtype'] );
 134  
 135                  if ( isset( $params['prlevel'] ) ) {
 136                      // Remove the empty string and '*' from the prlevel array
 137                      $prlevel = array_diff( $params['prlevel'], array( '', '*' ) );
 138  
 139                      if ( count( $prlevel ) ) {
 140                          $this->addWhereFld( 'pr_level', $prlevel );
 141                      }
 142                  }
 143                  if ( $params['prfiltercascade'] == 'cascading' ) {
 144                      $this->addWhereFld( 'pr_cascade', 1 );
 145                  } elseif ( $params['prfiltercascade'] == 'noncascading' ) {
 146                      $this->addWhereFld( 'pr_cascade', 0 );
 147                  }
 148              }
 149              $forceNameTitleIndex = false;
 150  
 151              if ( $params['prexpiry'] == 'indefinite' ) {
 152                  $this->addWhere( "pr_expiry = {$db->addQuotes( $db->getInfinity() )} OR pr_expiry IS NULL" );
 153              } elseif ( $params['prexpiry'] == 'definite' ) {
 154                  $this->addWhere( "pr_expiry != {$db->addQuotes( $db->getInfinity() )}" );
 155              }
 156  
 157              $this->addOption( 'DISTINCT' );
 158          } elseif ( isset( $params['prlevel'] ) ) {
 159              $this->dieUsage( 'prlevel may not be used without prtype', 'params' );
 160          }
 161  
 162          if ( $params['filterlanglinks'] == 'withoutlanglinks' ) {
 163              $this->addTables( 'langlinks' );
 164              $this->addJoinConds( array( 'langlinks' => array( 'LEFT JOIN', 'page_id=ll_from' ) ) );
 165              $this->addWhere( 'll_from IS NULL' );
 166              $forceNameTitleIndex = false;
 167          } elseif ( $params['filterlanglinks'] == 'withlanglinks' ) {
 168              $this->addTables( 'langlinks' );
 169              $this->addWhere( 'page_id=ll_from' );
 170              $this->addOption( 'STRAIGHT_JOIN' );
 171              // We have to GROUP BY all selected fields to stop
 172              // PostgreSQL from whining
 173              $this->addOption( 'GROUP BY', $selectFields );
 174              $forceNameTitleIndex = false;
 175          }
 176  
 177          if ( $forceNameTitleIndex ) {
 178              $this->addOption( 'USE INDEX', 'name_title' );
 179          }
 180  
 181          $limit = $params['limit'];
 182          $this->addOption( 'LIMIT', $limit + 1 );
 183          $res = $this->select( __METHOD__ );
 184  
 185          //Get gender information
 186          if ( MWNamespace::hasGenderDistinction( $params['namespace'] ) ) {
 187              $users = array();
 188              foreach ( $res as $row ) {
 189                  $users[] = $row->page_title;
 190              }
 191              GenderCache::singleton()->doQuery( $users, __METHOD__ );
 192              $res->rewind(); //reset
 193          }
 194  
 195          $count = 0;
 196          $result = $this->getResult();
 197          foreach ( $res as $row ) {
 198              if ( ++$count > $limit ) {
 199                  // We've reached the one extra which shows that there are
 200                  // additional pages to be had. Stop here...
 201                  $this->setContinueEnumParameter( 'continue', $row->page_title );
 202                  break;
 203              }
 204  
 205              if ( is_null( $resultPageSet ) ) {
 206                  $title = Title::makeTitle( $row->page_namespace, $row->page_title );
 207                  $vals = array(
 208                      'pageid' => intval( $row->page_id ),
 209                      'ns' => intval( $title->getNamespace() ),
 210                      'title' => $title->getPrefixedText()
 211                  );
 212                  $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $vals );
 213                  if ( !$fit ) {
 214                      $this->setContinueEnumParameter( 'continue', $row->page_title );
 215                      break;
 216                  }
 217              } else {
 218                  $resultPageSet->processDbRow( $row );
 219              }
 220          }
 221  
 222          if ( is_null( $resultPageSet ) ) {
 223              $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'p' );
 224          }
 225      }
 226  
 227  	public function getAllowedParams() {
 228          return array(
 229              'from' => null,
 230              'continue' => null,
 231              'to' => null,
 232              'prefix' => null,
 233              'namespace' => array(
 234                  ApiBase::PARAM_DFLT => NS_MAIN,
 235                  ApiBase::PARAM_TYPE => 'namespace',
 236              ),
 237              'filterredir' => array(
 238                  ApiBase::PARAM_DFLT => 'all',
 239                  ApiBase::PARAM_TYPE => array(
 240                      'all',
 241                      'redirects',
 242                      'nonredirects'
 243                  )
 244              ),
 245              'minsize' => array(
 246                  ApiBase::PARAM_TYPE => 'integer',
 247              ),
 248              'maxsize' => array(
 249                  ApiBase::PARAM_TYPE => 'integer',
 250              ),
 251              'prtype' => array(
 252                  ApiBase::PARAM_TYPE => Title::getFilteredRestrictionTypes( true ),
 253                  ApiBase::PARAM_ISMULTI => true
 254              ),
 255              'prlevel' => array(
 256                  ApiBase::PARAM_TYPE => $this->getConfig()->get( 'RestrictionLevels' ),
 257                  ApiBase::PARAM_ISMULTI => true
 258              ),
 259              'prfiltercascade' => array(
 260                  ApiBase::PARAM_DFLT => 'all',
 261                  ApiBase::PARAM_TYPE => array(
 262                      'cascading',
 263                      'noncascading',
 264                      'all'
 265                  ),
 266              ),
 267              'limit' => array(
 268                  ApiBase::PARAM_DFLT => 10,
 269                  ApiBase::PARAM_TYPE => 'limit',
 270                  ApiBase::PARAM_MIN => 1,
 271                  ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
 272                  ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
 273              ),
 274              'dir' => array(
 275                  ApiBase::PARAM_DFLT => 'ascending',
 276                  ApiBase::PARAM_TYPE => array(
 277                      'ascending',
 278                      'descending'
 279                  )
 280              ),
 281              'filterlanglinks' => array(
 282                  ApiBase::PARAM_TYPE => array(
 283                      'withlanglinks',
 284                      'withoutlanglinks',
 285                      'all'
 286                  ),
 287                  ApiBase::PARAM_DFLT => 'all'
 288              ),
 289              'prexpiry' => array(
 290                  ApiBase::PARAM_TYPE => array(
 291                      'indefinite',
 292                      'definite',
 293                      'all'
 294                  ),
 295                  ApiBase::PARAM_DFLT => 'all'
 296              ),
 297          );
 298      }
 299  
 300  	public function getParamDescription() {
 301          $p = $this->getModulePrefix();
 302  
 303          return array(
 304              'from' => 'The page title to start enumerating from',
 305              'continue' => 'When more results are available, use this to continue',
 306              'to' => 'The page title to stop enumerating at',
 307              'prefix' => 'Search for all page titles that begin with this value',
 308              'namespace' => 'The namespace to enumerate',
 309              'filterredir' => 'Which pages to list',
 310              'dir' => 'The direction in which to list',
 311              'minsize' => 'Limit to pages with at least this many bytes',
 312              'maxsize' => 'Limit to pages with at most this many bytes',
 313              'prtype' => 'Limit to protected pages only',
 314              'prlevel' => "The protection level (must be used with {$p}prtype= parameter)",
 315              'prfiltercascade'
 316                  => "Filter protections based on cascadingness (ignored when {$p}prtype isn't set)",
 317              'filterlanglinks' => array(
 318                  'Filter based on whether a page has langlinks',
 319                  'Note that this may not consider langlinks added by extensions.',
 320              ),
 321              'limit' => 'How many total pages to return.',
 322              'prexpiry' => array(
 323                  'Which protection expiry to filter the page on',
 324                  ' indefinite - Get only pages with indefinite protection expiry',
 325                  ' definite - Get only pages with a definite (specific) protection expiry',
 326                  ' all - Get pages with any protections expiry'
 327              ),
 328          );
 329      }
 330  
 331  	public function getDescription() {
 332          return 'Enumerate all pages sequentially in a given namespace.';
 333      }
 334  
 335  	public function getExamples() {
 336          return array(
 337              'api.php?action=query&list=allpages&apfrom=B' => array(
 338                  'Simple Use',
 339                  'Show a list of pages starting at the letter "B"',
 340              ),
 341              'api.php?action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info' => array(
 342                  'Using as Generator',
 343                  'Show info about 4 pages starting at the letter "T"',
 344              ),
 345              'api.php?action=query&generator=allpages&gaplimit=2&' .
 346                  'gapfilterredir=nonredirects&gapfrom=Re&prop=revisions&rvprop=content'
 347                  => array( 'Show content of first 2 non-redirect pages beginning at "Re"' )
 348          );
 349      }
 350  
 351  	public function getHelpUrls() {
 352          return 'https://www.mediawiki.org/wiki/API:Allpages';
 353      }
 354  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1