[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |