MediaWiki  master
ApiQueryUserInfo.php
Go to the documentation of this file.
1 <?php
24 
31 
33 
34  private const WL_UNREAD_LIMIT = 1000;
35 
37  private $params = [];
39  private $prop = [];
40 
41  public function __construct( ApiQuery $query, $moduleName ) {
42  parent::__construct( $query, $moduleName, 'ui' );
43  }
44 
45  public function execute() {
46  $this->params = $this->extractRequestParams();
47  $result = $this->getResult();
48 
49  if ( $this->params['prop'] !== null ) {
50  $this->prop = array_flip( $this->params['prop'] );
51  }
52 
53  $r = $this->getCurrentUserInfo();
54  $result->addValue( 'query', $this->getModuleName(), $r );
55  }
56 
69  public static function getCentralUserInfo( Config $config, User $user, $attachedWiki = null ) {
70  $providerIds = array_keys( $config->get( 'CentralIdLookupProviders' ) );
71 
72  $ret = [
73  'centralids' => [],
74  'attachedlocal' => [],
75  ];
76  ApiResult::setArrayType( $ret['centralids'], 'assoc' );
77  ApiResult::setArrayType( $ret['attachedlocal'], 'assoc' );
78  if ( $attachedWiki ) {
79  $ret['attachedwiki'] = [];
80  ApiResult::setArrayType( $ret['attachedwiki'], 'assoc' );
81  }
82 
83  $name = $user->getName();
84  foreach ( $providerIds as $providerId ) {
85  $provider = CentralIdLookup::factory( $providerId );
86  $ret['centralids'][$providerId] = $provider->centralIdFromName( $name );
87  $ret['attachedlocal'][$providerId] = $provider->isAttached( $user );
88  if ( $attachedWiki ) {
89  $ret['attachedwiki'][$providerId] = $provider->isAttached( $user, $attachedWiki );
90  }
91  }
92 
93  return $ret;
94  }
95 
96  protected function getCurrentUserInfo() {
97  $user = $this->getUser();
98  $vals = [];
99  $vals['id'] = (int)$user->getId();
100  $vals['name'] = $user->getName();
101 
102  if ( $user->isAnon() ) {
103  $vals['anon'] = true;
104  }
105 
106  if ( isset( $this->prop['blockinfo'] ) ) {
107  $block = $user->getBlock();
108  if ( $block ) {
109  $vals = array_merge( $vals, $this->getBlockDetails( $block ) );
110  }
111  }
112 
113  if ( isset( $this->prop['hasmsg'] ) ) {
114  $vals['messages'] = MediaWikiServices::getInstance()
115  ->getTalkPageNotificationManager()->userHasNewMessages( $user );
116  }
117 
118  if ( isset( $this->prop['groups'] ) ) {
119  $vals['groups'] = $user->getEffectiveGroups();
120  ApiResult::setArrayType( $vals['groups'], 'array' ); // even if empty
121  ApiResult::setIndexedTagName( $vals['groups'], 'g' ); // even if empty
122  }
123 
124  if ( isset( $this->prop['groupmemberships'] ) ) {
125  $ugms = $user->getGroupMemberships();
126  $vals['groupmemberships'] = [];
127  foreach ( $ugms as $group => $ugm ) {
128  $vals['groupmemberships'][] = [
129  'group' => $group,
130  'expiry' => ApiResult::formatExpiry( $ugm->getExpiry() ),
131  ];
132  }
133  ApiResult::setArrayType( $vals['groupmemberships'], 'array' ); // even if empty
134  ApiResult::setIndexedTagName( $vals['groupmemberships'], 'groupmembership' ); // even if empty
135  }
136 
137  if ( isset( $this->prop['implicitgroups'] ) ) {
138  $vals['implicitgroups'] = $user->getAutomaticGroups();
139  ApiResult::setArrayType( $vals['implicitgroups'], 'array' ); // even if empty
140  ApiResult::setIndexedTagName( $vals['implicitgroups'], 'g' ); // even if empty
141  }
142 
143  if ( isset( $this->prop['rights'] ) ) {
144  $vals['rights'] = $this->getPermissionManager()->getUserPermissions( $user );
145  ApiResult::setArrayType( $vals['rights'], 'array' ); // even if empty
146  ApiResult::setIndexedTagName( $vals['rights'], 'r' ); // even if empty
147  }
148 
149  if ( isset( $this->prop['changeablegroups'] ) ) {
150  $vals['changeablegroups'] = $user->changeableGroups();
151  ApiResult::setIndexedTagName( $vals['changeablegroups']['add'], 'g' );
152  ApiResult::setIndexedTagName( $vals['changeablegroups']['remove'], 'g' );
153  ApiResult::setIndexedTagName( $vals['changeablegroups']['add-self'], 'g' );
154  ApiResult::setIndexedTagName( $vals['changeablegroups']['remove-self'], 'g' );
155  }
156 
157  if ( isset( $this->prop['options'] ) ) {
158  $vals['options'] = $user->getOptions();
159  $vals['options'][ApiResult::META_BC_BOOLS] = array_keys( $vals['options'] );
160  }
161 
162  if ( isset( $this->prop['preferencestoken'] ) &&
163  !$this->lacksSameOriginSecurity() &&
164  $this->getPermissionManager()->userHasRight( $user, 'editmyoptions' )
165  ) {
166  $vals['preferencestoken'] = $user->getEditToken( '', $this->getMain()->getRequest() );
167  }
168 
169  if ( isset( $this->prop['editcount'] ) ) {
170  // use intval to prevent null if a non-logged-in user calls
171  // api.php?format=jsonfm&action=query&meta=userinfo&uiprop=editcount
172  $vals['editcount'] = (int)$user->getEditCount();
173  }
174 
175  if ( isset( $this->prop['ratelimits'] ) ) {
176  $vals['ratelimits'] = $this->getRateLimits();
177  }
178 
179  if ( isset( $this->prop['realname'] ) &&
180  !in_array( 'realname', $this->getConfig()->get( 'HiddenPrefs' ) )
181  ) {
182  $vals['realname'] = $user->getRealName();
183  }
184 
185  if ( $this->getPermissionManager()->userHasRight( $user, 'viewmyprivateinfo' ) &&
186  isset( $this->prop['email'] ) ) {
187  $vals['email'] = $user->getEmail();
188  $auth = $user->getEmailAuthenticationTimestamp();
189  if ( $auth !== null ) {
190  $vals['emailauthenticated'] = wfTimestamp( TS_ISO_8601, $auth );
191  }
192  }
193 
194  if ( isset( $this->prop['registrationdate'] ) ) {
195  $regDate = $user->getRegistration();
196  if ( $regDate !== false ) {
197  $vals['registrationdate'] = wfTimestamp( TS_ISO_8601, $regDate );
198  }
199  }
200 
201  if ( isset( $this->prop['acceptlang'] ) ) {
202  $langs = $this->getRequest()->getAcceptLang();
203  $acceptLang = [];
204  foreach ( $langs as $lang => $val ) {
205  $r = [ 'q' => $val ];
206  ApiResult::setContentValue( $r, 'code', $lang );
207  $acceptLang[] = $r;
208  }
209  ApiResult::setIndexedTagName( $acceptLang, 'lang' );
210  $vals['acceptlang'] = $acceptLang;
211  }
212 
213  if ( isset( $this->prop['unreadcount'] ) ) {
214  $store = MediaWikiServices::getInstance()->getWatchedItemStore();
215  $unreadNotifications = $store->countUnreadNotifications(
216  $user,
217  self::WL_UNREAD_LIMIT
218  );
219 
220  if ( $unreadNotifications === true ) {
221  $vals['unreadcount'] = self::WL_UNREAD_LIMIT . '+';
222  } else {
223  $vals['unreadcount'] = $unreadNotifications;
224  }
225  }
226 
227  if ( isset( $this->prop['centralids'] ) ) {
228  $vals += self::getCentralUserInfo(
229  $this->getConfig(), $this->getUser(), $this->params['attachedwiki']
230  );
231  }
232 
233  if ( isset( $this->prop['latestcontrib'] ) ) {
234  $ts = $this->getLatestContributionTime();
235  if ( $ts !== null ) {
236  $vals['latestcontrib'] = $ts;
237  }
238  }
239 
240  return $vals;
241  }
242 
243  protected function getRateLimits() {
244  $retval = [
245  ApiResult::META_TYPE => 'assoc',
246  ];
247 
248  $user = $this->getUser();
249  if ( !$user->isPingLimitable() ) {
250  return $retval; // No limits
251  }
252 
253  // Find out which categories we belong to
254  $categories = [];
255  if ( $user->isAnon() ) {
256  $categories[] = 'anon';
257  } else {
258  $categories[] = 'user';
259  }
260  if ( $user->isNewbie() ) {
261  $categories[] = 'ip';
262  $categories[] = 'subnet';
263  if ( !$user->isAnon() ) {
264  $categories[] = 'newbie';
265  }
266  }
267  $categories = array_merge( $categories, $user->getGroups() );
268 
269  // Now get the actual limits
270  foreach ( $this->getConfig()->get( 'RateLimits' ) as $action => $limits ) {
271  foreach ( $categories as $cat ) {
272  if ( isset( $limits[$cat] ) ) {
273  $retval[$action][$cat]['hits'] = (int)$limits[$cat][0];
274  $retval[$action][$cat]['seconds'] = (int)$limits[$cat][1];
275  }
276  }
277  }
278 
279  return $retval;
280  }
281 
285  protected function getLatestContributionTime() {
286  $user = $this->getUser();
287  $dbr = $this->getDB();
288 
289  if ( $user->getActorId() === null ) {
290  return null;
291  }
292  $res = $dbr->selectField( 'revision_actor_temp',
293  'MAX(revactor_timestamp)',
294  [ 'revactor_actor' => $user->getActorId() ],
295  __METHOD__
296  );
297 
298  return $res ? wfTimestamp( TS_ISO_8601, $res ) : null;
299  }
300 
301  public function getAllowedParams() {
302  return [
303  'prop' => [
304  ApiBase::PARAM_ISMULTI => true,
306  'blockinfo',
307  'hasmsg',
308  'groups',
309  'groupmemberships',
310  'implicitgroups',
311  'rights',
312  'changeablegroups',
313  'options',
314  'editcount',
315  'ratelimits',
316  'email',
317  'realname',
318  'acceptlang',
319  'registrationdate',
320  'unreadcount',
321  'centralids',
322  'preferencestoken',
323  'latestcontrib',
324  ],
326  'unreadcount' => [
327  'apihelp-query+userinfo-paramvalue-prop-unreadcount',
328  self::WL_UNREAD_LIMIT - 1,
329  self::WL_UNREAD_LIMIT . '+',
330  ],
331  ],
333  'preferencestoken' => [
334  'apiwarn-deprecation-withreplacement',
335  $this->getModulePrefix() . "prop=preferencestoken",
336  'action=query&meta=tokens',
337  ]
338  ],
339  ],
340  'attachedwiki' => null,
341  ];
342  }
343 
344  protected function getExamplesMessages() {
345  return [
346  'action=query&meta=userinfo'
347  => 'apihelp-query+userinfo-example-simple',
348  'action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg'
349  => 'apihelp-query+userinfo-example-data',
350  ];
351  }
352 
353  public function getHelpUrls() {
354  return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Userinfo';
355  }
356 }
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:67
ApiQuery
This is the main query class.
Definition: ApiQuery.php:37
ApiQueryUserInfo\getLatestContributionTime
getLatestContributionTime()
Definition: ApiQueryUserInfo.php:285
ApiQueryUserInfo\$params
array $params
Definition: ApiQueryUserInfo.php:37
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:154
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
ApiResult\META_TYPE
const META_TYPE
Key for the 'type' metadata item.
Definition: ApiResult.php:110
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1808
ApiQueryUserInfo
Query module to get information about the currently logged-in user.
Definition: ApiQueryUserInfo.php:30
ApiBase\PARAM_TYPE
const PARAM_TYPE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:71
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:565
ApiQueryUserInfo\WL_UNREAD_LIMIT
const WL_UNREAD_LIMIT
Definition: ApiQueryUserInfo.php:34
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:76
$res
$res
Definition: testCompression.php:57
ContextSource\getUser
getUser()
Stable to override.
Definition: ContextSource.php:131
ApiBase\PARAM_DEPRECATED_VALUES
const PARAM_DEPRECATED_VALUES
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:83
ApiBase\lacksSameOriginSecurity
lacksSameOriginSecurity()
Returns true if the current request breaks the same-origin policy.
Definition: ApiBase.php:493
$dbr
$dbr
Definition: testCompression.php:54
ApiResult\setContentValue
static setContentValue(array &$arr, $name, $value, $flags=0)
Add an output value to the array by name and mark as META_CONTENT.
Definition: ApiResult.php:466
Config
Interface for configuration instances.
Definition: Config.php:30
ApiQueryUserInfo\getAllowedParams
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
Definition: ApiQueryUserInfo.php:301
ApiResult\setArrayType
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
Definition: ApiResult.php:716
ApiQueryUserInfo\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.
Definition: ApiQueryUserInfo.php:344
Config\get
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
ApiQueryBase
This is a base class for all Query modules.
Definition: ApiQueryBase.php:37
ApiQueryBase\getDB
getDB()
Get the Query database connection (read-only) Stable to override.
Definition: ApiQueryBase.php:119
ApiResult\META_BC_BOOLS
const META_BC_BOOLS
Key for the 'BC bools' metadata item.
Definition: ApiResult.php:136
ApiQueryUserInfo\$prop
array $prop
Definition: ApiQueryUserInfo.php:39
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:717
ApiBlockInfoTrait
trait ApiBlockInfoTrait
Definition: ApiBlockInfoTrait.php:27
ApiBase\getModulePrefix
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition: ApiBase.php:452
ApiResult\setIndexedTagName
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:604
ApiBase\getPermissionManager
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition: ApiBase.php:637
ApiQueryUserInfo\getCurrentUserInfo
getCurrentUserInfo()
Definition: ApiQueryUserInfo.php:96
ApiQueryUserInfo\__construct
__construct(ApiQuery $query, $moduleName)
Definition: ApiQueryUserInfo.php:41
ApiQueryUserInfo\execute
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
Definition: ApiQueryUserInfo.php:45
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:444
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:70
ApiResult\formatExpiry
static formatExpiry( $expiry, $infinity='infinity')
Format an expiry timestamp for API output.
Definition: ApiResult.php:1193
ApiBase\getMain
getMain()
Get the main module.
Definition: ApiBase.php:460
ApiQueryUserInfo\getCentralUserInfo
static getCentralUserInfo(Config $config, User $user, $attachedWiki=null)
Get central user info.
Definition: ApiQueryUserInfo.php:69
ApiQueryUserInfo\getRateLimits
getRateLimits()
Definition: ApiQueryUserInfo.php:243
CentralIdLookup\factory
static factory( $providerId=null)
Fetch a CentralIdLookup.
Definition: CentralIdLookup.php:47
ApiBase\PARAM_HELP_MSG_PER_VALUE
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
Definition: ApiBase.php:140
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
ApiQueryUserInfo\getHelpUrls
getHelpUrls()
Return links to more detailed help pages about the module.
Definition: ApiQueryUserInfo.php:353
User\getName
getName()
Get the user name, or the IP of an anonymous user.
Definition: User.php:2054