[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

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

   1  <?php
   2  /**
   3   *
   4   *
   5   * Created on Sep 10, 2007
   6   *
   7   * Copyright © 2007 Roan Kattouw "<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 user blocks
  29   *
  30   * @ingroup API
  31   */
  32  class ApiQueryBlocks extends ApiQueryBase {
  33  
  34      /**
  35       * @var array
  36       */
  37      protected $usernames;
  38  
  39  	public function __construct( ApiQuery $query, $moduleName ) {
  40          parent::__construct( $query, $moduleName, 'bk' );
  41      }
  42  
  43  	public function execute() {
  44          global $wgContLang;
  45  
  46          $db = $this->getDB();
  47          $params = $this->extractRequestParams();
  48          $this->requireMaxOneParameter( $params, 'users', 'ip' );
  49  
  50          $prop = array_flip( $params['prop'] );
  51          $fld_id = isset( $prop['id'] );
  52          $fld_user = isset( $prop['user'] );
  53          $fld_userid = isset( $prop['userid'] );
  54          $fld_by = isset( $prop['by'] );
  55          $fld_byid = isset( $prop['byid'] );
  56          $fld_timestamp = isset( $prop['timestamp'] );
  57          $fld_expiry = isset( $prop['expiry'] );
  58          $fld_reason = isset( $prop['reason'] );
  59          $fld_range = isset( $prop['range'] );
  60          $fld_flags = isset( $prop['flags'] );
  61  
  62          $result = $this->getResult();
  63  
  64          $this->addTables( 'ipblocks' );
  65          $this->addFields( array( 'ipb_auto', 'ipb_id' ) );
  66  
  67          $this->addFieldsIf( array( 'ipb_address', 'ipb_user' ), $fld_user || $fld_userid );
  68          $this->addFieldsIf( 'ipb_by_text', $fld_by );
  69          $this->addFieldsIf( 'ipb_by', $fld_byid );
  70          $this->addFieldsIf( 'ipb_timestamp', $fld_timestamp );
  71          $this->addFieldsIf( 'ipb_expiry', $fld_expiry );
  72          $this->addFieldsIf( 'ipb_reason', $fld_reason );
  73          $this->addFieldsIf( array( 'ipb_range_start', 'ipb_range_end' ), $fld_range );
  74          $this->addFieldsIf( array( 'ipb_anon_only', 'ipb_create_account', 'ipb_enable_autoblock',
  75              'ipb_block_email', 'ipb_deleted', 'ipb_allow_usertalk' ),
  76              $fld_flags );
  77  
  78          $this->addOption( 'LIMIT', $params['limit'] + 1 );
  79          $this->addTimestampWhereRange(
  80              'ipb_timestamp',
  81              $params['dir'],
  82              $params['start'],
  83              $params['end']
  84          );
  85          // Include in ORDER BY for uniqueness
  86          $this->addWhereRange( 'ipb_id', $params['dir'], null, null );
  87  
  88          if ( !is_null( $params['continue'] ) ) {
  89              $cont = explode( '|', $params['continue'] );
  90              $this->dieContinueUsageIf( count( $cont ) != 2 );
  91              $op = ( $params['dir'] == 'newer' ? '>' : '<' );
  92              $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
  93              $continueId = (int)$cont[1];
  94              $this->dieContinueUsageIf( $continueId != $cont[1] );
  95              $this->addWhere( "ipb_timestamp $op $continueTimestamp OR " .
  96                  "(ipb_timestamp = $continueTimestamp AND " .
  97                  "ipb_id $op= $continueId)"
  98              );
  99          }
 100  
 101          if ( isset( $params['ids'] ) ) {
 102              $this->addWhereFld( 'ipb_id', $params['ids'] );
 103          }
 104          if ( isset( $params['users'] ) ) {
 105              foreach ( (array)$params['users'] as $u ) {
 106                  $this->prepareUsername( $u );
 107              }
 108              $this->addWhereFld( 'ipb_address', $this->usernames );
 109              $this->addWhereFld( 'ipb_auto', 0 );
 110          }
 111          if ( isset( $params['ip'] ) ) {
 112              $blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
 113              if ( IP::isIPv4( $params['ip'] ) ) {
 114                  $type = 'IPv4';
 115                  $cidrLimit = $blockCIDRLimit['IPv4'];
 116                  $prefixLen = 0;
 117              } elseif ( IP::isIPv6( $params['ip'] ) ) {
 118                  $type = 'IPv6';
 119                  $cidrLimit = $blockCIDRLimit['IPv6'];
 120                  $prefixLen = 3; // IP::toHex output is prefixed with "v6-"
 121              } else {
 122                  $this->dieUsage( 'IP parameter is not valid', 'param_ip' );
 123              }
 124  
 125              # Check range validity, if it's a CIDR
 126              list( $ip, $range ) = IP::parseCIDR( $params['ip'] );
 127              if ( $ip !== false && $range !== false && $range < $cidrLimit ) {
 128                  $this->dieUsage(
 129                      "$type CIDR ranges broader than /$cidrLimit are not accepted",
 130                      'cidrtoobroad'
 131                  );
 132              }
 133  
 134              # Let IP::parseRange handle calculating $upper, instead of duplicating the logic here.
 135              list( $lower, $upper ) = IP::parseRange( $params['ip'] );
 136  
 137              # Extract the common prefix to any rangeblock affecting this IP/CIDR
 138              $prefix = substr( $lower, 0, $prefixLen + floor( $cidrLimit / 4 ) );
 139  
 140              # Fairly hard to make a malicious SQL statement out of hex characters,
 141              # but it is good practice to add quotes
 142              $lower = $db->addQuotes( $lower );
 143              $upper = $db->addQuotes( $upper );
 144  
 145              $this->addWhere( array(
 146                  'ipb_range_start' . $db->buildLike( $prefix, $db->anyString() ),
 147                  'ipb_range_start <= ' . $lower,
 148                  'ipb_range_end >= ' . $upper,
 149                  'ipb_auto' => 0
 150              ) );
 151          }
 152  
 153          if ( !is_null( $params['show'] ) ) {
 154              $show = array_flip( $params['show'] );
 155  
 156              /* Check for conflicting parameters. */
 157              if ( ( isset( $show['account'] ) && isset( $show['!account'] ) )
 158                  || ( isset( $show['ip'] ) && isset( $show['!ip'] ) )
 159                  || ( isset( $show['range'] ) && isset( $show['!range'] ) )
 160                  || ( isset( $show['temp'] ) && isset( $show['!temp'] ) )
 161              ) {
 162                  $this->dieUsageMsg( 'show' );
 163              }
 164  
 165              $this->addWhereIf( 'ipb_user = 0', isset( $show['!account'] ) );
 166              $this->addWhereIf( 'ipb_user != 0', isset( $show['account'] ) );
 167              $this->addWhereIf( 'ipb_user != 0 OR ipb_range_end > ipb_range_start', isset( $show['!ip'] ) );
 168              $this->addWhereIf( 'ipb_user = 0 AND ipb_range_end = ipb_range_start', isset( $show['ip'] ) );
 169              $this->addWhereIf( 'ipb_expiry = ' .
 170                  $db->addQuotes( $db->getInfinity() ), isset( $show['!temp'] ) );
 171              $this->addWhereIf( 'ipb_expiry != ' .
 172                  $db->addQuotes( $db->getInfinity() ), isset( $show['temp'] ) );
 173              $this->addWhereIf( 'ipb_range_end = ipb_range_start', isset( $show['!range'] ) );
 174              $this->addWhereIf( 'ipb_range_end > ipb_range_start', isset( $show['range'] ) );
 175          }
 176  
 177          if ( !$this->getUser()->isAllowed( 'hideuser' ) ) {
 178              $this->addWhereFld( 'ipb_deleted', 0 );
 179          }
 180  
 181          // Purge expired entries on one in every 10 queries
 182          if ( !mt_rand( 0, 10 ) ) {
 183              Block::purgeExpired();
 184          }
 185  
 186          $res = $this->select( __METHOD__ );
 187  
 188          $count = 0;
 189          foreach ( $res as $row ) {
 190              if ( ++$count > $params['limit'] ) {
 191                  // We've had enough
 192                  $this->setContinueEnumParameter( 'continue', "$row->ipb_timestamp|$row->ipb_id" );
 193                  break;
 194              }
 195              $block = array();
 196              if ( $fld_id ) {
 197                  $block['id'] = $row->ipb_id;
 198              }
 199              if ( $fld_user && !$row->ipb_auto ) {
 200                  $block['user'] = $row->ipb_address;
 201              }
 202              if ( $fld_userid && !$row->ipb_auto ) {
 203                  $block['userid'] = $row->ipb_user;
 204              }
 205              if ( $fld_by ) {
 206                  $block['by'] = $row->ipb_by_text;
 207              }
 208              if ( $fld_byid ) {
 209                  $block['byid'] = $row->ipb_by;
 210              }
 211              if ( $fld_timestamp ) {
 212                  $block['timestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
 213              }
 214              if ( $fld_expiry ) {
 215                  $block['expiry'] = $wgContLang->formatExpiry( $row->ipb_expiry, TS_ISO_8601 );
 216              }
 217              if ( $fld_reason ) {
 218                  $block['reason'] = $row->ipb_reason;
 219              }
 220              if ( $fld_range && !$row->ipb_auto ) {
 221                  $block['rangestart'] = IP::formatHex( $row->ipb_range_start );
 222                  $block['rangeend'] = IP::formatHex( $row->ipb_range_end );
 223              }
 224              if ( $fld_flags ) {
 225                  // For clarity, these flags use the same names as their action=block counterparts
 226                  if ( $row->ipb_auto ) {
 227                      $block['automatic'] = '';
 228                  }
 229                  if ( $row->ipb_anon_only ) {
 230                      $block['anononly'] = '';
 231                  }
 232                  if ( $row->ipb_create_account ) {
 233                      $block['nocreate'] = '';
 234                  }
 235                  if ( $row->ipb_enable_autoblock ) {
 236                      $block['autoblock'] = '';
 237                  }
 238                  if ( $row->ipb_block_email ) {
 239                      $block['noemail'] = '';
 240                  }
 241                  if ( $row->ipb_deleted ) {
 242                      $block['hidden'] = '';
 243                  }
 244                  if ( $row->ipb_allow_usertalk ) {
 245                      $block['allowusertalk'] = '';
 246                  }
 247              }
 248              $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $block );
 249              if ( !$fit ) {
 250                  $this->setContinueEnumParameter( 'continue', "$row->ipb_timestamp|$row->ipb_id" );
 251                  break;
 252              }
 253          }
 254          $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'block' );
 255      }
 256  
 257  	protected function prepareUsername( $user ) {
 258          if ( !$user ) {
 259              $this->dieUsage( 'User parameter may not be empty', 'param_user' );
 260          }
 261          $name = User::isIP( $user )
 262              ? $user
 263              : User::getCanonicalName( $user, 'valid' );
 264          if ( $name === false ) {
 265              $this->dieUsage( "User name {$user} is not valid", 'param_user' );
 266          }
 267          $this->usernames[] = $name;
 268      }
 269  
 270  	public function getAllowedParams() {
 271          return array(
 272              'start' => array(
 273                  ApiBase::PARAM_TYPE => 'timestamp'
 274              ),
 275              'end' => array(
 276                  ApiBase::PARAM_TYPE => 'timestamp',
 277              ),
 278              'dir' => array(
 279                  ApiBase::PARAM_TYPE => array(
 280                      'newer',
 281                      'older'
 282                  ),
 283                  ApiBase::PARAM_DFLT => 'older'
 284              ),
 285              'ids' => array(
 286                  ApiBase::PARAM_TYPE => 'integer',
 287                  ApiBase::PARAM_ISMULTI => true
 288              ),
 289              'users' => array(
 290                  ApiBase::PARAM_ISMULTI => true
 291              ),
 292              'ip' => null,
 293              'limit' => array(
 294                  ApiBase::PARAM_DFLT => 10,
 295                  ApiBase::PARAM_TYPE => 'limit',
 296                  ApiBase::PARAM_MIN => 1,
 297                  ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
 298                  ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
 299              ),
 300              'prop' => array(
 301                  ApiBase::PARAM_DFLT => 'id|user|by|timestamp|expiry|reason|flags',
 302                  ApiBase::PARAM_TYPE => array(
 303                      'id',
 304                      'user',
 305                      'userid',
 306                      'by',
 307                      'byid',
 308                      'timestamp',
 309                      'expiry',
 310                      'reason',
 311                      'range',
 312                      'flags'
 313                  ),
 314                  ApiBase::PARAM_ISMULTI => true
 315              ),
 316              'show' => array(
 317                  ApiBase::PARAM_TYPE => array(
 318                      'account',
 319                      '!account',
 320                      'temp',
 321                      '!temp',
 322                      'ip',
 323                      '!ip',
 324                      'range',
 325                      '!range',
 326                  ),
 327                  ApiBase::PARAM_ISMULTI => true
 328              ),
 329              'continue' => null,
 330          );
 331      }
 332  
 333  	public function getParamDescription() {
 334          $blockCIDRLimit = $this->getConfig()->get( 'BlockCIDRLimit' );
 335          $p = $this->getModulePrefix();
 336  
 337          return array(
 338              'start' => 'The timestamp to start enumerating from',
 339              'end' => 'The timestamp to stop enumerating at',
 340              'dir' => $this->getDirectionDescription( $p ),
 341              'ids' => 'List of block IDs to list (optional)',
 342              'users' => 'List of users to search for (optional)',
 343              'ip' => array(
 344                  'Get all blocks applying to this IP or CIDR range, including range blocks.',
 345                  "Cannot be used together with bkusers. CIDR ranges broader than " .
 346                      "IPv4/{$blockCIDRLimit['IPv4']} or IPv6/{$blockCIDRLimit['IPv6']} " .
 347                      "are not accepted"
 348              ),
 349              'limit' => 'The maximum amount of blocks to list',
 350              'prop' => array(
 351                  'Which properties to get',
 352                  ' id         - Adds the ID of the block',
 353                  ' user       - Adds the username of the blocked user',
 354                  ' userid     - Adds the user ID of the blocked user',
 355                  ' by         - Adds the username of the blocking user',
 356                  ' byid       - Adds the user ID of the blocking user',
 357                  ' timestamp  - Adds the timestamp of when the block was given',
 358                  ' expiry     - Adds the timestamp of when the block expires',
 359                  ' reason     - Adds the reason given for the block',
 360                  ' range      - Adds the range of IPs affected by the block',
 361                  ' flags      - Tags the ban with (autoblock, anononly, etc)',
 362              ),
 363              'show' => array(
 364                  'Show only items that meet this criteria.',
 365                  "For example, to see only indefinite blocks on IPs, set {$p}show=ip|!temp"
 366              ),
 367              'continue' => 'When more results are available, use this to continue',
 368          );
 369      }
 370  
 371  	public function getDescription() {
 372          return 'List all blocked users and IP addresses.';
 373      }
 374  
 375  	public function getExamples() {
 376          return array(
 377              'api.php?action=query&list=blocks',
 378              'api.php?action=query&list=blocks&bkusers=Alice|Bob'
 379          );
 380      }
 381  
 382  	public function getHelpUrls() {
 383          return 'https://www.mediawiki.org/wiki/API:Blocks';
 384      }
 385  }


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