PageRenderTime 1147ms CodeModel.GetById 4ms RepoModel.GetById 1ms app.codeStats 1ms

/WikiZam/includes/api/ApiQueryBlocks.php

https://github.com/Seizam/seizamcore
PHP | 312 lines | 251 code | 24 blank | 37 comment | 35 complexity | 6067af18243cdb52b74b66031eb57823 MD5 | raw file
  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. if ( !defined( 'MEDIAWIKI' ) ) {
  27. // Eclipse helper - will be ignored in production
  28. require_once( 'ApiQueryBase.php' );
  29. }
  30. /**
  31. * Query module to enumerate all user blocks
  32. *
  33. * @ingroup API
  34. */
  35. class ApiQueryBlocks extends ApiQueryBase {
  36. /**
  37. * @var Array
  38. */
  39. protected $usernames;
  40. public function __construct( $query, $moduleName ) {
  41. parent::__construct( $query, $moduleName, 'bk' );
  42. }
  43. public function execute() {
  44. global $wgUser, $wgContLang;
  45. $params = $this->extractRequestParams();
  46. $this->requireMaxOneParameter( $params, 'users', 'ip' );
  47. $prop = array_flip( $params['prop'] );
  48. $fld_id = isset( $prop['id'] );
  49. $fld_user = isset( $prop['user'] );
  50. $fld_userid = isset( $prop['userid'] );
  51. $fld_by = isset( $prop['by'] );
  52. $fld_byid = isset( $prop['byid'] );
  53. $fld_timestamp = isset( $prop['timestamp'] );
  54. $fld_expiry = isset( $prop['expiry'] );
  55. $fld_reason = isset( $prop['reason'] );
  56. $fld_range = isset( $prop['range'] );
  57. $fld_flags = isset( $prop['flags'] );
  58. $result = $this->getResult();
  59. $this->addTables( 'ipblocks' );
  60. $this->addFields( 'ipb_auto' );
  61. $this->addFieldsIf ( 'ipb_id', $fld_id );
  62. $this->addFieldsIf( array( 'ipb_address', 'ipb_user' ), $fld_user || $fld_userid );
  63. $this->addFieldsIf( 'ipb_by_text', $fld_by );
  64. $this->addFieldsIf( 'ipb_by', $fld_byid );
  65. $this->addFieldsIf( 'ipb_timestamp', $fld_timestamp );
  66. $this->addFieldsIf( 'ipb_expiry', $fld_expiry );
  67. $this->addFieldsIf( 'ipb_reason', $fld_reason );
  68. $this->addFieldsIf( array( 'ipb_range_start', 'ipb_range_end' ), $fld_range );
  69. $this->addFieldsIf( array( 'ipb_anon_only', 'ipb_create_account', 'ipb_enable_autoblock',
  70. 'ipb_block_email', 'ipb_deleted', 'ipb_allow_usertalk' ),
  71. $fld_flags );
  72. $this->addOption( 'LIMIT', $params['limit'] + 1 );
  73. $this->addTimestampWhereRange( 'ipb_timestamp', $params['dir'], $params['start'], $params['end'] );
  74. if ( isset( $params['ids'] ) ) {
  75. $this->addWhereFld( 'ipb_id', $params['ids'] );
  76. }
  77. if ( isset( $params['users'] ) ) {
  78. foreach ( (array)$params['users'] as $u ) {
  79. $this->prepareUsername( $u );
  80. }
  81. $this->addWhereFld( 'ipb_address', $this->usernames );
  82. $this->addWhereFld( 'ipb_auto', 0 );
  83. }
  84. if ( isset( $params['ip'] ) ) {
  85. list( $ip, $range ) = IP::parseCIDR( $params['ip'] );
  86. if ( $ip && $range ) {
  87. // We got a CIDR range
  88. if ( $range < 16 )
  89. $this->dieUsage( 'CIDR ranges broader than /16 are not accepted', 'cidrtoobroad' );
  90. $lower = wfBaseConvert( $ip, 10, 16, 8, false );
  91. $upper = wfBaseConvert( $ip + pow( 2, 32 - $range ) - 1, 10, 16, 8, false );
  92. } else {
  93. $lower = $upper = IP::toHex( $params['ip'] );
  94. }
  95. $prefix = substr( $lower, 0, 4 );
  96. $db = $this->getDB();
  97. $this->addWhere( array(
  98. 'ipb_range_start' . $db->buildLike( $prefix, $db->anyString() ),
  99. "ipb_range_start <= '$lower'",
  100. "ipb_range_end >= '$upper'",
  101. 'ipb_auto' => 0
  102. ) );
  103. }
  104. if ( !$wgUser->isAllowed( 'hideuser' ) ) {
  105. $this->addWhereFld( 'ipb_deleted', 0 );
  106. }
  107. // Purge expired entries on one in every 10 queries
  108. if ( !mt_rand( 0, 10 ) ) {
  109. Block::purgeExpired();
  110. }
  111. $res = $this->select( __METHOD__ );
  112. $count = 0;
  113. foreach ( $res as $row ) {
  114. if ( ++$count > $params['limit'] ) {
  115. // We've had enough
  116. $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ipb_timestamp ) );
  117. break;
  118. }
  119. $block = array();
  120. if ( $fld_id ) {
  121. $block['id'] = $row->ipb_id;
  122. }
  123. if ( $fld_user && !$row->ipb_auto ) {
  124. $block['user'] = $row->ipb_address;
  125. }
  126. if ( $fld_userid && !$row->ipb_auto ) {
  127. $block['userid'] = $row->ipb_user;
  128. }
  129. if ( $fld_by ) {
  130. $block['by'] = $row->ipb_by_text;
  131. }
  132. if ( $fld_byid ) {
  133. $block['byid'] = $row->ipb_by;
  134. }
  135. if ( $fld_timestamp ) {
  136. $block['timestamp'] = wfTimestamp( TS_ISO_8601, $row->ipb_timestamp );
  137. }
  138. if ( $fld_expiry ) {
  139. $block['expiry'] = $wgContLang->formatExpiry( $row->ipb_expiry, TS_ISO_8601 );
  140. }
  141. if ( $fld_reason ) {
  142. $block['reason'] = $row->ipb_reason;
  143. }
  144. if ( $fld_range && !$row->ipb_auto ) {
  145. $block['rangestart'] = IP::hexToQuad( $row->ipb_range_start );
  146. $block['rangeend'] = IP::hexToQuad( $row->ipb_range_end );
  147. }
  148. if ( $fld_flags ) {
  149. // For clarity, these flags use the same names as their action=block counterparts
  150. if ( $row->ipb_auto ) {
  151. $block['automatic'] = '';
  152. }
  153. if ( $row->ipb_anon_only ) {
  154. $block['anononly'] = '';
  155. }
  156. if ( $row->ipb_create_account ) {
  157. $block['nocreate'] = '';
  158. }
  159. if ( $row->ipb_enable_autoblock ) {
  160. $block['autoblock'] = '';
  161. }
  162. if ( $row->ipb_block_email ) {
  163. $block['noemail'] = '';
  164. }
  165. if ( $row->ipb_deleted ) {
  166. $block['hidden'] = '';
  167. }
  168. if ( $row->ipb_allow_usertalk ) {
  169. $block['allowusertalk'] = '';
  170. }
  171. }
  172. $fit = $result->addValue( array( 'query', $this->getModuleName() ), null, $block );
  173. if ( !$fit ) {
  174. $this->setContinueEnumParameter( 'start', wfTimestamp( TS_ISO_8601, $row->ipb_timestamp ) );
  175. break;
  176. }
  177. }
  178. $result->setIndexedTagName_internal( array( 'query', $this->getModuleName() ), 'block' );
  179. }
  180. protected function prepareUsername( $user ) {
  181. if ( !$user ) {
  182. $this->dieUsage( 'User parameter may not be empty', 'param_user' );
  183. }
  184. $name = User::isIP( $user )
  185. ? $user
  186. : User::getCanonicalName( $user, 'valid' );
  187. if ( $name === false ) {
  188. $this->dieUsage( "User name {$user} is not valid", 'param_user' );
  189. }
  190. $this->usernames[] = $name;
  191. }
  192. public function getAllowedParams() {
  193. return array(
  194. 'start' => array(
  195. ApiBase::PARAM_TYPE => 'timestamp'
  196. ),
  197. 'end' => array(
  198. ApiBase::PARAM_TYPE => 'timestamp',
  199. ),
  200. 'dir' => array(
  201. ApiBase::PARAM_TYPE => array(
  202. 'newer',
  203. 'older'
  204. ),
  205. ApiBase::PARAM_DFLT => 'older'
  206. ),
  207. 'ids' => array(
  208. ApiBase::PARAM_TYPE => 'integer',
  209. ApiBase::PARAM_ISMULTI => true
  210. ),
  211. 'users' => array(
  212. ApiBase::PARAM_ISMULTI => true
  213. ),
  214. 'ip' => null,
  215. 'limit' => array(
  216. ApiBase::PARAM_DFLT => 10,
  217. ApiBase::PARAM_TYPE => 'limit',
  218. ApiBase::PARAM_MIN => 1,
  219. ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
  220. ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
  221. ),
  222. 'prop' => array(
  223. ApiBase::PARAM_DFLT => 'id|user|by|timestamp|expiry|reason|flags',
  224. ApiBase::PARAM_TYPE => array(
  225. 'id',
  226. 'user',
  227. 'userid',
  228. 'by',
  229. 'byid',
  230. 'timestamp',
  231. 'expiry',
  232. 'reason',
  233. 'range',
  234. 'flags'
  235. ),
  236. ApiBase::PARAM_ISMULTI => true
  237. )
  238. );
  239. }
  240. public function getParamDescription() {
  241. return array(
  242. 'start' => 'The timestamp to start enumerating from',
  243. 'end' => 'The timestamp to stop enumerating at',
  244. 'dir' => $this->getDirectionDescription( $this->getModulePrefix() ),
  245. 'ids' => 'Pipe-separated list of block IDs to list (optional)',
  246. 'users' => 'Pipe-separated list of users to search for (optional)',
  247. 'ip' => array( 'Get all blocks applying to this IP or CIDR range, including range blocks.',
  248. 'Cannot be used together with bkusers. CIDR ranges broader than /16 are not accepted' ),
  249. 'limit' => 'The maximum amount of blocks to list',
  250. 'prop' => array(
  251. 'Which properties to get',
  252. ' id - Adds the ID of the block',
  253. ' user - Adds the username of the blocked user',
  254. ' userid - Adds the user ID of the blocked user',
  255. ' by - Adds the username of the blocking user',
  256. ' byid - Adds the user ID of the blocking user',
  257. ' timestamp - Adds the timestamp of when the block was given',
  258. ' expiry - Adds the timestamp of when the block expires',
  259. ' reason - Adds the reason given for the block',
  260. ' range - Adds the range of IPs affected by the block',
  261. ' flags - Tags the ban with (autoblock, anononly, etc)',
  262. ),
  263. );
  264. }
  265. public function getDescription() {
  266. return 'List all blocked users and IP addresses';
  267. }
  268. public function getPossibleErrors() {
  269. return array_merge( parent::getPossibleErrors(), array(
  270. $this->getRequireOnlyOneParameterErrorMessages( array( 'users', 'ip' ) ),
  271. array( 'code' => 'cidrtoobroad', 'info' => 'CIDR ranges broader than /16 are not accepted' ),
  272. array( 'code' => 'param_user', 'info' => 'User parameter may not be empty' ),
  273. array( 'code' => 'param_user', 'info' => 'User name user is not valid' ),
  274. ) );
  275. }
  276. protected function getExamples() {
  277. return array(
  278. 'api.php?action=query&list=blocks',
  279. 'api.php?action=query&list=blocks&bkusers=Alice|Bob'
  280. );
  281. }
  282. public function getHelpUrls() {
  283. return 'https://www.mediawiki.org/wiki/API:Blocks';
  284. }
  285. public function getVersion() {
  286. return __CLASS__ . ': $Id$';
  287. }
  288. }