87 $parms = explode(
'/', $par );
88 $symsForAll = [
'*',
'user' ];
90 if ( $parms[0] !=
'' &&
91 ( in_array( $par, $userGroupManager->
listAllGroups() ) || in_array( $par, $symsForAll ) )
93 $this->requestedGroup = $par;
94 $un = $request->getText(
'username' );
95 } elseif ( count( $parms ) == 2 ) {
96 $this->requestedGroup = $parms[0];
99 $this->requestedGroup = $request->getVal(
'group' );
100 $un = ( $par !=
'' ) ? $par : $request->getText(
'username' );
103 if ( in_array( $this->requestedGroup, $symsForAll ) ) {
104 $this->requestedGroup =
'';
106 $this->editsOnly = $request->getBool(
'editsOnly' );
107 $this->temporaryGroupsOnly = $request->getBool(
'temporaryGroupsOnly' );
108 $this->temporaryAccountsOnly = $request->getBool(
'temporaryAccountsOnly' );
109 $this->creationSort = $request->getBool(
'creationSort' );
111 $this->mDefaultDirection = $request->getBool(
'desc' )
112 ? IndexPager::DIR_DESCENDING
113 : IndexPager::DIR_ASCENDING;
115 $this->requestedUser =
'';
118 $username = Title::makeTitleSafe(
NS_USER, $un );
120 if ( $username !==
null ) {
121 $this->requestedUser = $username->getText();
127 parent::__construct();
128 $this->userGroupManager = $userGroupManager;
129 $this->hookRunner =
new HookRunner( $hookContainer );
130 $this->linkBatchFactory = $linkBatchFactory;
131 $this->userIdentityLookup = $userIdentityLookup;
133 $this->tempUserConfig = $tempUserConfig;
152 $conds[] = $this->hideUserUtils->getExpression( $dbr );
166 $deleted =
'MAX(' . $dbr->buildIntegerCast(
167 $this->hideUserUtils->getExpression( $dbr,
'user_id', HideUserUtils::HIDDEN_USERS )
171 if ( $this->requestedGroup !=
'' || $this->temporaryGroupsOnly ) {
172 $cond = $dbr->expr(
'ug_expiry',
'>=', $dbr->timestamp() );
173 if ( !$this->temporaryGroupsOnly ) {
174 $cond = $cond->or(
'ug_expiry',
'=',
null );
179 if ( $this->temporaryAccountsOnly && $this->tempUserConfig->isKnown() ) {
180 $conds[] = $this->tempUserConfig->getMatchCondition(
181 $dbr,
'user_name', IExpression::LIKE
185 if ( $this->requestedGroup !=
'' ) {
189 if ( $this->requestedUser !=
'' ) {
190 # Sorted either by account creation or name
191 if ( $this->creationSort ) {
192 $userIdentity = $this->userIdentityLookup->getUserIdentityByName( $this->requestedUser );
193 if ( $userIdentity && $userIdentity->isRegistered() ) {
194 $conds[] = $dbr->expr(
'user_id',
'>=', $userIdentity->getId() );
197 $conds[] = $dbr->expr(
'user_name',
'>=', $this->requestedUser );
201 if ( $this->editsOnly ) {
202 $conds[] = $dbr->expr(
'user_editcount',
'>', 0 );
209 'block_with_target' => [
215 'user_name' => $this->creationSort ?
'MAX(user_name)' :
'user_name',
216 'user_id' => $this->creationSort ?
'user_id' :
'MAX(user_id)',
217 'edits' =>
'MAX(user_editcount)',
218 'creation' =>
'MIN(user_registration)',
219 'deleted' => $deleted,
220 'sitewide' =>
'MAX(bl_sitewide)'
223 'GROUP BY' => $this->creationSort ?
'user_id' :
'user_name',
226 'user_groups' => [
'LEFT JOIN',
'user_id=ug_user' ],
227 'block_with_target' => [
231 $dbr->expr(
'bl_expiry',
'>=', $dbr->timestamp() ),
234 'block' => [
'JOIN',
'bl_target=bt_id' ]
239 $this->hookRunner->onSpecialListusersQueryInfo( $this, $query );
249 if ( $row->user_id == 0 ) { # T18487
253 $userName = $row->user_name;
255 $ulinks = Linker::userLink( $row->user_id, $userName );
256 $ulinks .= Linker::userToolLinksRedContribs(
270 if ( !$this->including && count( $ugms ) > 0 ) {
272 foreach ( $ugms as $ugm ) {
275 $groups = $lang->commaList( $list );
278 $item = $lang->specialList( $ulinks, $groups );
280 if ( $row->deleted ) {
281 $item =
"<span class=\"deleted\">$item</span>";
286 $count = $this->
msg(
'usereditcount' )->numParams( $row->edits )->escaped();
287 $edits = $this->
msg(
'word-separator' )->escaped() . $this->
msg(
'brackets', $count )->escaped();
291 # Some rows may be null
292 if ( !$this->including && $row->creation ) {
294 $d = $lang->userDate( $row->creation, $user );
295 $t = $lang->userTime( $row->creation, $user );
296 $created = $this->
msg(
'usercreated', $d, $t, $row->user_name )->escaped();
297 $created =
' ' . $this->
msg(
'parentheses' )->rawParams( $created )->escaped();
300 $blocked = $row->deleted !==
null && $row->sitewide ===
'1' ?
301 ' ' . $this->
msg(
'listusers-blocked', $userName )->escaped() :
304 $this->hookRunner->onSpecialListusersFormatRow( $item, $row );
306 return Html::rawElement(
'li', [],
"{$item}{$edits}{$created}{$blocked}" );
311 $batch = $this->linkBatchFactory->newLinkBatch()->setCaller( __METHOD__ );
313 # Give some pointers to make user links
314 foreach ( $this->mResult as $row ) {
316 $batch->addUser( $user );
317 $userIds[] = $user->getId();
321 $queryBuilder = $this->userGroupManager->newQueryBuilder( $this->
getDatabase() );
322 $groupRes = $queryBuilder->where( [
'ug_user' => $userIds ] )
323 ->caller( __METHOD__ )
327 foreach ( $groupRes as $row ) {
328 $ugm = $this->userGroupManager->newGroupMembershipFromRow( $row );
329 if ( !$ugm->isExpired() ) {
330 $cache[$row->ug_user][$row->ug_group] = $ugm;
331 $groups[$row->ug_group] =
true;
337 $this->hookRunner->onUsersPagerDoBatchLookups( $this->
getDatabase(), $userIds, $cache, $groups );
339 $this->userGroupCache = $cache;
342 foreach ( $groups as $group => $unused ) {
343 $groupPage = UserGroupMembership::getGroupPage( $group );
345 $batch->addObj( $groupPage );
350 $this->mResult->rewind();
357 $self = explode(
'/', $this->
getTitle()->getPrefixedDBkey(), 2 )[0];
359 $groupOptions = [ $this->
msg(
'group-all' )->text() =>
'' ];
360 foreach ( $this->getAllGroups() as $group => $groupText ) {
361 if ( array_key_exists( $groupText, $groupOptions ) ) {
362 LoggerFactory::getInstance(
'translation-problem' )->error(
363 'The group {group_one} has the same translation as {group_two} for {lang}. ' .
364 '{group_one} will not be displayed in group dropdown of the UsersPager.',
366 'group_one' => $group,
367 'group_two' => $groupOptions[$groupText],
373 $groupOptions[ $groupText ] = $group;
378 'class' => HTMLUserTextField::class,
379 'label' => $this->
msg(
'listusersfrom' )->text(),
380 'name' =>
'username',
384 'label' => $this->
msg(
'group' )->text(),
387 'class' => HTMLSelectField::class,
388 'options' => $groupOptions,
392 'label' => $this->
msg(
'listusers-editsonly' )->text(),
393 'name' =>
'editsOnly',
397 'temporaryGroupsOnly' => [
399 'label' => $this->
msg(
'listusers-temporarygroupsonly' )->text(),
400 'name' =>
'temporaryGroupsOnly',
401 'id' =>
'temporaryGroupsOnly',
407 if ( $this->tempUserConfig->isKnown() ) {
408 $formDescriptor = array_merge( $formDescriptor, [
409 'temporaryAccountsOnly' => [
411 'label' => $this->
msg(
'listusers-temporaryaccountsonly' )->text(),
412 'name' =>
'temporaryAccountsOnly',
413 'id' =>
'temporaryAccountsOnly',
414 'default' => $this->temporaryAccountsOnly
420 $formDescriptor = array_merge( $formDescriptor, [
423 'label' => $this->
msg(
'listusers-creationsort' )->text(),
424 'name' =>
'creationSort',
425 'id' =>
'creationSort',
426 'default' => $this->creationSort
430 'label' => $this->
msg(
'listusers-desc' )->text(),
433 'default' => $this->mDefaultDirection
435 'limithiddenfield' => [
436 'class' => HTMLHiddenField::class,
438 'default' => $this->mLimit
442 $beforeSubmitButtonHookOut =
'';
443 $this->hookRunner->onSpecialListusersHeaderForm( $this, $beforeSubmitButtonHookOut );
445 if ( $beforeSubmitButtonHookOut !==
'' ) {
446 $formDescriptor[
'beforeSubmitButtonHookOut' ] = [
447 'class' => HTMLInfoField::class,
449 'default' => $beforeSubmitButtonHookOut
453 $formDescriptor[
'submit' ] = [
454 'class' => HTMLSubmitField::class,
455 'buttonlabel-message' =>
'listusers-submit',
458 $beforeClosingFieldsetHookOut =
'';
459 $this->hookRunner->onSpecialListusersHeader( $this, $beforeClosingFieldsetHookOut );
461 if ( $beforeClosingFieldsetHookOut !==
'' ) {
462 $formDescriptor[
'beforeClosingFieldsetHookOut' ] = [
463 'class' => HTMLInfoField::class,
465 'default' => $beforeClosingFieldsetHookOut
469 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor, $this->
getContext() );
472 ->setTitle( Title::newFromText(
$self ) )
473 ->setId(
'mw-listusers-form' )
474 ->setFormIdentifier(
'mw-listusers-form' )
475 ->suppressDefaultSubmit()
476 ->setWrapperLegendMsg(
'listusers' );
477 return $htmlForm->prepareForm()->getHTML(
true );