Merge "API: Overhaul ApiResult, make format=xml not throw, and add json formatversion"
[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 protected function getCurrentUserInfo() {
55 global $wgContLang;
56
57 $user = $this->getUser();
58 $result = $this->getResult();
59 $vals = array();
60 $vals['id'] = intval( $user->getId() );
61 $vals['name'] = $user->getName();
62
63 if ( $user->isAnon() ) {
64 $vals['anon'] = '';
65 }
66
67 if ( isset( $this->prop['blockinfo'] ) ) {
68 if ( $user->isBlocked() ) {
69 $block = $user->getBlock();
70 $vals['blockid'] = $block->getId();
71 $vals['blockedby'] = $block->getByName();
72 $vals['blockedbyid'] = $block->getBy();
73 $vals['blockreason'] = $user->blockedFor();
74 $vals['blockedtimestamp'] = wfTimestamp( TS_ISO_8601, $block->mTimestamp );
75 $vals['blockexpiry'] = $wgContLang->formatExpiry(
76 $block->getExpiry(), TS_ISO_8601, 'infinite'
77 );
78 }
79 }
80
81 if ( isset( $this->prop['hasmsg'] ) && $user->getNewtalk() ) {
82 $vals['messages'] = '';
83 }
84
85 if ( isset( $this->prop['groups'] ) ) {
86 $vals['groups'] = $user->getEffectiveGroups();
87 ApiResult::setIndexedTagName( $vals['groups'], 'g' ); // even if empty
88 }
89
90 if ( isset( $this->prop['implicitgroups'] ) ) {
91 $vals['implicitgroups'] = $user->getAutomaticGroups();
92 ApiResult::setIndexedTagName( $vals['implicitgroups'], 'g' ); // even if empty
93 }
94
95 if ( isset( $this->prop['rights'] ) ) {
96 // User::getRights() may return duplicate values, strip them
97 $vals['rights'] = array_values( array_unique( $user->getRights() ) );
98 ApiResult::setIndexedTagName( $vals['rights'], 'r' ); // even if empty
99 }
100
101 if ( isset( $this->prop['changeablegroups'] ) ) {
102 $vals['changeablegroups'] = $user->changeableGroups();
103 ApiResult::setIndexedTagName( $vals['changeablegroups']['add'], 'g' );
104 ApiResult::setIndexedTagName( $vals['changeablegroups']['remove'], 'g' );
105 ApiResult::setIndexedTagName( $vals['changeablegroups']['add-self'], 'g' );
106 ApiResult::setIndexedTagName( $vals['changeablegroups']['remove-self'], 'g' );
107 }
108
109 if ( isset( $this->prop['options'] ) ) {
110 $vals['options'] = $user->getOptions();
111 }
112
113 if ( isset( $this->prop['preferencestoken'] ) ) {
114 $p = $this->getModulePrefix();
115 $this->setWarning(
116 "{$p}prop=preferencestoken has been deprecated. Please use action=query&meta=tokens instead."
117 );
118 }
119 if ( isset( $this->prop['preferencestoken'] ) &&
120 !$this->lacksSameOriginSecurity() &&
121 $user->isAllowed( 'editmyoptions' )
122 ) {
123 $vals['preferencestoken'] = $user->getEditToken( '', $this->getMain()->getRequest() );
124 }
125
126 if ( isset( $this->prop['editcount'] ) ) {
127 // use intval to prevent null if a non-logged-in user calls
128 // api.php?format=jsonfm&action=query&meta=userinfo&uiprop=editcount
129 $vals['editcount'] = intval( $user->getEditCount() );
130 }
131
132 if ( isset( $this->prop['ratelimits'] ) ) {
133 $vals['ratelimits'] = $this->getRateLimits();
134 }
135
136 if ( isset( $this->prop['realname'] ) && !in_array( 'realname', $this->getConfig()->get( 'HiddenPrefs' ) ) ) {
137 $vals['realname'] = $user->getRealName();
138 }
139
140 if ( $user->isAllowed( 'viewmyprivateinfo' ) ) {
141 if ( isset( $this->prop['email'] ) ) {
142 $vals['email'] = $user->getEmail();
143 $auth = $user->getEmailAuthenticationTimestamp();
144 if ( !is_null( $auth ) ) {
145 $vals['emailauthenticated'] = wfTimestamp( TS_ISO_8601, $auth );
146 }
147 }
148 }
149
150 if ( isset( $this->prop['registrationdate'] ) ) {
151 $regDate = $user->getRegistration();
152 if ( $regDate !== false ) {
153 $vals['registrationdate'] = wfTimestamp( TS_ISO_8601, $regDate );
154 }
155 }
156
157 if ( isset( $this->prop['acceptlang'] ) ) {
158 $langs = $this->getRequest()->getAcceptLang();
159 $acceptLang = array();
160 foreach ( $langs as $lang => $val ) {
161 $r = array( 'q' => $val );
162 ApiResult::setContentValue( $r, 'code', $lang );
163 $acceptLang[] = $r;
164 }
165 ApiResult::setIndexedTagName( $acceptLang, 'lang' );
166 $vals['acceptlang'] = $acceptLang;
167 }
168
169 if ( isset( $this->prop['unreadcount'] ) ) {
170 $dbr = $this->getQuery()->getNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
171
172 $count = $dbr->selectRowCount(
173 'watchlist',
174 '1',
175 array(
176 'wl_user' => $user->getId(),
177 'wl_notificationtimestamp IS NOT NULL',
178 ),
179 __METHOD__,
180 array( 'LIMIT' => self::WL_UNREAD_LIMIT )
181 );
182
183 if ( $count >= self::WL_UNREAD_LIMIT ) {
184 $vals['unreadcount'] = self::WL_UNREAD_LIMIT . '+';
185 } else {
186 $vals['unreadcount'] = $count;
187 }
188 }
189
190 return $vals;
191 }
192
193 protected function getRateLimits() {
194 $user = $this->getUser();
195 if ( !$user->isPingLimitable() ) {
196 return array(); // No limits
197 }
198
199 // Find out which categories we belong to
200 $categories = array();
201 if ( $user->isAnon() ) {
202 $categories[] = 'anon';
203 } else {
204 $categories[] = 'user';
205 }
206 if ( $user->isNewbie() ) {
207 $categories[] = 'ip';
208 $categories[] = 'subnet';
209 if ( !$user->isAnon() ) {
210 $categories[] = 'newbie';
211 }
212 }
213 $categories = array_merge( $categories, $user->getGroups() );
214
215 // Now get the actual limits
216 $retval = array();
217 foreach ( $this->getConfig()->get( 'RateLimits' ) as $action => $limits ) {
218 foreach ( $categories as $cat ) {
219 if ( isset( $limits[$cat] ) && !is_null( $limits[$cat] ) ) {
220 $retval[$action][$cat]['hits'] = intval( $limits[$cat][0] );
221 $retval[$action][$cat]['seconds'] = intval( $limits[$cat][1] );
222 }
223 }
224 }
225
226 return $retval;
227 }
228
229 public function getAllowedParams() {
230 return array(
231 'prop' => array(
232 ApiBase::PARAM_DFLT => null,
233 ApiBase::PARAM_ISMULTI => true,
234 ApiBase::PARAM_TYPE => array(
235 'blockinfo',
236 'hasmsg',
237 'groups',
238 'implicitgroups',
239 'rights',
240 'changeablegroups',
241 'options',
242 'preferencestoken',
243 'editcount',
244 'ratelimits',
245 'email',
246 'realname',
247 'acceptlang',
248 'registrationdate',
249 'unreadcount',
250 ),
251 ApiBase::PARAM_HELP_MSG => array(
252 'apihelp-query+userinfo-param-prop',
253 self::WL_UNREAD_LIMIT - 1,
254 self::WL_UNREAD_LIMIT . '+',
255 ),
256 )
257 );
258 }
259
260 protected function getExamplesMessages() {
261 return array(
262 'action=query&meta=userinfo'
263 => 'apihelp-query+userinfo-example-simple',
264 'action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg'
265 => 'apihelp-query+userinfo-example-data',
266 );
267 }
268
269 public function getHelpUrls() {
270 return 'https://www.mediawiki.org/wiki/API:Meta#userinfo_.2F_ui';
271 }
272 }