Merge "Accessor to get EditPage parent revision ID"
[lhc/web/wiklou.git] / includes / api / ApiQueryUserInfo.php
1 <?php
2 /**
3 *
4 *
5 * Created on July 30, 2007
6 *
7 * Copyright © 2007 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 get information about the currently logged-in user
29 *
30 * @ingroup API
31 */
32 class ApiQueryUserInfo extends ApiQueryBase {
33
34 const WL_UNREAD_LIMIT = 1000;
35
36 private $prop = array();
37
38 public function __construct( ApiQuery $query, $moduleName ) {
39 parent::__construct( $query, $moduleName, 'ui' );
40 }
41
42 public function execute() {
43 $params = $this->extractRequestParams();
44 $result = $this->getResult();
45
46 if ( !is_null( $params['prop'] ) ) {
47 $this->prop = array_flip( $params['prop'] );
48 }
49
50 $r = $this->getCurrentUserInfo();
51 $result->addValue( 'query', $this->getModuleName(), $r );
52 }
53
54 /**
55 * Get basic info about a given block
56 * @param Block $block
57 * @return array Array containing several keys:
58 * - blockid - ID of the block
59 * - blockedby - username of the blocker
60 * - blockedbyid - user ID of the blocker
61 * - blockreason - reason provided for the block
62 * - blockedtimestamp - timestamp for when the block was placed/modified
63 * - blockexpiry - expiry time of the block
64 */
65 public static function getBlockInfo( Block $block ) {
66 global $wgContLang;
67 $vals = array();
68 $vals['blockid'] = $block->getId();
69 $vals['blockedby'] = $block->getByName();
70 $vals['blockedbyid'] = $block->getBy();
71 $vals['blockreason'] = $block->mReason;
72 $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->mTimestamp );
73 $vals['blockexpiry'] = $wgContLang->formatExpiry(
74 $block->getExpiry(), TS_ISO_8601, 'infinite'
75 );
76 return $vals;
77 }
78
79 protected function getCurrentUserInfo() {
80 $user = $this->getUser();
81 $vals = array();
82 $vals['id'] = intval( $user->getId() );
83 $vals['name'] = $user->getName();
84
85 if ( $user->isAnon() ) {
86 $vals['anon'] = true;
87 }
88
89 if ( isset( $this->prop['blockinfo'] ) && $user->isBlocked() ) {
90 $vals = array_merge( $vals, self::getBlockInfo( $user->getBlock() ) );
91 }
92
93 if ( isset( $this->prop['hasmsg'] ) ) {
94 $vals['messages'] = $user->getNewtalk();
95 }
96
97 if ( isset( $this->prop['groups'] ) ) {
98 $vals['groups'] = $user->getEffectiveGroups();
99 ApiResult::setArrayType( $vals['groups'], 'array' ); // even if empty
100 ApiResult::setIndexedTagName( $vals['groups'], 'g' ); // even if empty
101 }
102
103 if ( isset( $this->prop['implicitgroups'] ) ) {
104 $vals['implicitgroups'] = $user->getAutomaticGroups();
105 ApiResult::setArrayType( $vals['implicitgroups'], 'array' ); // even if empty
106 ApiResult::setIndexedTagName( $vals['implicitgroups'], 'g' ); // even if empty
107 }
108
109 if ( isset( $this->prop['rights'] ) ) {
110 // User::getRights() may return duplicate values, strip them
111 $vals['rights'] = array_values( array_unique( $user->getRights() ) );
112 ApiResult::setArrayType( $vals['rights'], 'array' ); // even if empty
113 ApiResult::setIndexedTagName( $vals['rights'], 'r' ); // even if empty
114 }
115
116 if ( isset( $this->prop['changeablegroups'] ) ) {
117 $vals['changeablegroups'] = $user->changeableGroups();
118 ApiResult::setIndexedTagName( $vals['changeablegroups']['add'], 'g' );
119 ApiResult::setIndexedTagName( $vals['changeablegroups']['remove'], 'g' );
120 ApiResult::setIndexedTagName( $vals['changeablegroups']['add-self'], 'g' );
121 ApiResult::setIndexedTagName( $vals['changeablegroups']['remove-self'], 'g' );
122 }
123
124 if ( isset( $this->prop['options'] ) ) {
125 $vals['options'] = $user->getOptions();
126 $vals['options'][ApiResult::META_BC_BOOLS] = array_keys( $vals['options'] );
127 }
128
129 if ( isset( $this->prop['preferencestoken'] ) ) {
130 $p = $this->getModulePrefix();
131 $this->setWarning(
132 "{$p}prop=preferencestoken has been deprecated. Please use action=query&meta=tokens instead."
133 );
134 }
135 if ( isset( $this->prop['preferencestoken'] ) &&
136 !$this->lacksSameOriginSecurity() &&
137 $user->isAllowed( 'editmyoptions' )
138 ) {
139 $vals['preferencestoken'] = $user->getEditToken( '', $this->getMain()->getRequest() );
140 }
141
142 if ( isset( $this->prop['editcount'] ) ) {
143 // use intval to prevent null if a non-logged-in user calls
144 // api.php?format=jsonfm&action=query&meta=userinfo&uiprop=editcount
145 $vals['editcount'] = intval( $user->getEditCount() );
146 }
147
148 if ( isset( $this->prop['ratelimits'] ) ) {
149 $vals['ratelimits'] = $this->getRateLimits();
150 }
151
152 if ( isset( $this->prop['realname'] ) &&
153 !in_array( 'realname', $this->getConfig()->get( 'HiddenPrefs' ) )
154 ) {
155 $vals['realname'] = $user->getRealName();
156 }
157
158 if ( $user->isAllowed( 'viewmyprivateinfo' ) ) {
159 if ( isset( $this->prop['email'] ) ) {
160 $vals['email'] = $user->getEmail();
161 $auth = $user->getEmailAuthenticationTimestamp();
162 if ( !is_null( $auth ) ) {
163 $vals['emailauthenticated'] = wfTimestamp( TS_ISO_8601, $auth );
164 }
165 }
166 }
167
168 if ( isset( $this->prop['registrationdate'] ) ) {
169 $regDate = $user->getRegistration();
170 if ( $regDate !== false ) {
171 $vals['registrationdate'] = wfTimestamp( TS_ISO_8601, $regDate );
172 }
173 }
174
175 if ( isset( $this->prop['acceptlang'] ) ) {
176 $langs = $this->getRequest()->getAcceptLang();
177 $acceptLang = array();
178 foreach ( $langs as $lang => $val ) {
179 $r = array( 'q' => $val );
180 ApiResult::setContentValue( $r, 'code', $lang );
181 $acceptLang[] = $r;
182 }
183 ApiResult::setIndexedTagName( $acceptLang, 'lang' );
184 $vals['acceptlang'] = $acceptLang;
185 }
186
187 if ( isset( $this->prop['unreadcount'] ) ) {
188 $dbr = $this->getQuery()->getNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
189
190 $count = $dbr->selectRowCount(
191 'watchlist',
192 '1',
193 array(
194 'wl_user' => $user->getId(),
195 'wl_notificationtimestamp IS NOT NULL',
196 ),
197 __METHOD__,
198 array( 'LIMIT' => self::WL_UNREAD_LIMIT )
199 );
200
201 if ( $count >= self::WL_UNREAD_LIMIT ) {
202 $vals['unreadcount'] = self::WL_UNREAD_LIMIT . '+';
203 } else {
204 $vals['unreadcount'] = $count;
205 }
206 }
207
208 return $vals;
209 }
210
211 protected function getRateLimits() {
212 $retval = array(
213 ApiResult::META_TYPE => 'assoc',
214 );
215
216 $user = $this->getUser();
217 if ( !$user->isPingLimitable() ) {
218 return $retval; // No limits
219 }
220
221 // Find out which categories we belong to
222 $categories = array();
223 if ( $user->isAnon() ) {
224 $categories[] = 'anon';
225 } else {
226 $categories[] = 'user';
227 }
228 if ( $user->isNewbie() ) {
229 $categories[] = 'ip';
230 $categories[] = 'subnet';
231 if ( !$user->isAnon() ) {
232 $categories[] = 'newbie';
233 }
234 }
235 $categories = array_merge( $categories, $user->getGroups() );
236
237 // Now get the actual limits
238 foreach ( $this->getConfig()->get( 'RateLimits' ) as $action => $limits ) {
239 foreach ( $categories as $cat ) {
240 if ( isset( $limits[$cat] ) && !is_null( $limits[$cat] ) ) {
241 $retval[$action][$cat]['hits'] = intval( $limits[$cat][0] );
242 $retval[$action][$cat]['seconds'] = intval( $limits[$cat][1] );
243 }
244 }
245 }
246
247 return $retval;
248 }
249
250 public function getAllowedParams() {
251 return array(
252 'prop' => array(
253 ApiBase::PARAM_ISMULTI => true,
254 ApiBase::PARAM_TYPE => array(
255 'blockinfo',
256 'hasmsg',
257 'groups',
258 'implicitgroups',
259 'rights',
260 'changeablegroups',
261 'options',
262 'preferencestoken',
263 'editcount',
264 'ratelimits',
265 'email',
266 'realname',
267 'acceptlang',
268 'registrationdate',
269 'unreadcount',
270 ),
271 ApiBase::PARAM_HELP_MSG_PER_VALUE => array(
272 'unreadcount' => array(
273 'apihelp-query+userinfo-paramvalue-prop-unreadcount',
274 self::WL_UNREAD_LIMIT - 1,
275 self::WL_UNREAD_LIMIT . '+',
276 ),
277 ),
278 )
279 );
280 }
281
282 protected function getExamplesMessages() {
283 return array(
284 'action=query&meta=userinfo'
285 => 'apihelp-query+userinfo-example-simple',
286 'action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg'
287 => 'apihelp-query+userinfo-example-data',
288 );
289 }
290
291 public function getHelpUrls() {
292 return 'https://www.mediawiki.org/wiki/API:Userinfo';
293 }
294 }