Merge "Don't check namespace in SpecialWantedtemplates"
[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'] ) && !in_array( 'realname', $this->getConfig()->get( 'HiddenPrefs' ) ) ) {
153 $vals['realname'] = $user->getRealName();
154 }
155
156 if ( $user->isAllowed( 'viewmyprivateinfo' ) ) {
157 if ( isset( $this->prop['email'] ) ) {
158 $vals['email'] = $user->getEmail();
159 $auth = $user->getEmailAuthenticationTimestamp();
160 if ( !is_null( $auth ) ) {
161 $vals['emailauthenticated'] = wfTimestamp( TS_ISO_8601, $auth );
162 }
163 }
164 }
165
166 if ( isset( $this->prop['registrationdate'] ) ) {
167 $regDate = $user->getRegistration();
168 if ( $regDate !== false ) {
169 $vals['registrationdate'] = wfTimestamp( TS_ISO_8601, $regDate );
170 }
171 }
172
173 if ( isset( $this->prop['acceptlang'] ) ) {
174 $langs = $this->getRequest()->getAcceptLang();
175 $acceptLang = array();
176 foreach ( $langs as $lang => $val ) {
177 $r = array( 'q' => $val );
178 ApiResult::setContentValue( $r, 'code', $lang );
179 $acceptLang[] = $r;
180 }
181 ApiResult::setIndexedTagName( $acceptLang, 'lang' );
182 $vals['acceptlang'] = $acceptLang;
183 }
184
185 if ( isset( $this->prop['unreadcount'] ) ) {
186 $dbr = $this->getQuery()->getNamedDB( 'watchlist', DB_SLAVE, 'watchlist' );
187
188 $count = $dbr->selectRowCount(
189 'watchlist',
190 '1',
191 array(
192 'wl_user' => $user->getId(),
193 'wl_notificationtimestamp IS NOT NULL',
194 ),
195 __METHOD__,
196 array( 'LIMIT' => self::WL_UNREAD_LIMIT )
197 );
198
199 if ( $count >= self::WL_UNREAD_LIMIT ) {
200 $vals['unreadcount'] = self::WL_UNREAD_LIMIT . '+';
201 } else {
202 $vals['unreadcount'] = $count;
203 }
204 }
205
206 return $vals;
207 }
208
209 protected function getRateLimits() {
210 $retval = array(
211 ApiResult::META_TYPE => 'assoc',
212 );
213
214 $user = $this->getUser();
215 if ( !$user->isPingLimitable() ) {
216 return $retval; // No limits
217 }
218
219 // Find out which categories we belong to
220 $categories = array();
221 if ( $user->isAnon() ) {
222 $categories[] = 'anon';
223 } else {
224 $categories[] = 'user';
225 }
226 if ( $user->isNewbie() ) {
227 $categories[] = 'ip';
228 $categories[] = 'subnet';
229 if ( !$user->isAnon() ) {
230 $categories[] = 'newbie';
231 }
232 }
233 $categories = array_merge( $categories, $user->getGroups() );
234
235 // Now get the actual limits
236 foreach ( $this->getConfig()->get( 'RateLimits' ) as $action => $limits ) {
237 foreach ( $categories as $cat ) {
238 if ( isset( $limits[$cat] ) && !is_null( $limits[$cat] ) ) {
239 $retval[$action][$cat]['hits'] = intval( $limits[$cat][0] );
240 $retval[$action][$cat]['seconds'] = intval( $limits[$cat][1] );
241 }
242 }
243 }
244
245 return $retval;
246 }
247
248 public function getAllowedParams() {
249 return array(
250 'prop' => array(
251 ApiBase::PARAM_DFLT => null,
252 ApiBase::PARAM_ISMULTI => true,
253 ApiBase::PARAM_TYPE => array(
254 'blockinfo',
255 'hasmsg',
256 'groups',
257 'implicitgroups',
258 'rights',
259 'changeablegroups',
260 'options',
261 'preferencestoken',
262 'editcount',
263 'ratelimits',
264 'email',
265 'realname',
266 'acceptlang',
267 'registrationdate',
268 'unreadcount',
269 ),
270 ApiBase::PARAM_HELP_MSG_PER_VALUE => array(
271 'unreadcount' => array(
272 'apihelp-query+userinfo-paramvalue-prop-unreadcount',
273 self::WL_UNREAD_LIMIT - 1,
274 self::WL_UNREAD_LIMIT . '+',
275 ),
276 ),
277 )
278 );
279 }
280
281 protected function getExamplesMessages() {
282 return array(
283 'action=query&meta=userinfo'
284 => 'apihelp-query+userinfo-example-simple',
285 'action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg'
286 => 'apihelp-query+userinfo-example-data',
287 );
288 }
289
290 public function getHelpUrls() {
291 return 'https://www.mediawiki.org/wiki/API:Userinfo';
292 }
293 }