100 $parms = explode(
'/', $par );
101 $symsForAll = [
'*',
'user' ];
103 if ( $parms[0] !=
'' &&
104 ( in_array( $par, $userGroupManager->
listAllGroups() ) || in_array( $par, $symsForAll ) )
106 $this->requestedGroup = $par;
107 $un = $request->getText(
'username' );
108 } elseif ( count( $parms ) == 2 ) {
109 $this->requestedGroup = $parms[0];
112 $this->requestedGroup = $request->getVal(
'group' );
113 $un = ( $par !=
'' ) ? $par : $request->getText(
'username' );
116 if ( in_array( $this->requestedGroup, $symsForAll ) ) {
117 $this->requestedGroup =
'';
119 $this->editsOnly = $request->getBool(
'editsOnly' );
120 $this->temporaryGroupsOnly = $request->getBool(
'temporaryGroupsOnly' );
121 $this->creationSort = $request->getBool(
'creationSort' );
123 $this->mDefaultDirection = $request->getBool(
'desc' )
127 $this->requestedUser =
'';
130 $username = Title::makeTitleSafe(
NS_USER, $un );
132 if ( $username !==
null ) {
133 $this->requestedUser = $username->getText();
139 parent::__construct();
140 $this->linkBatchFactory = $linkBatchFactory;
141 $this->hookRunner =
new HookRunner( $hookContainer );
142 $this->userGroupManager = $userGroupManager;
161 $conds[] =
'ipb_deleted IS NULL OR ipb_deleted = 0';
166 if ( $this->requestedGroup !=
'' || $this->temporaryGroupsOnly ) {
167 $conds[] =
'ug_expiry >= ' .
$dbr->addQuotes(
$dbr->timestamp() ) .
168 ( !$this->temporaryGroupsOnly ?
' OR ug_expiry IS NULL' :
'' );
171 if ( $this->requestedGroup !=
'' ) {
172 $conds[
'ug_group'] = $this->requestedGroup;
175 if ( $this->requestedUser !=
'' ) {
176 # Sorted either by account creation or name
177 if ( $this->creationSort ) {
178 $conds[] =
'user_id >= ' . intval(
User::idFromName( $this->requestedUser ) );
180 $conds[] =
'user_name >= ' .
$dbr->addQuotes( $this->requestedUser );
184 if ( $this->editsOnly ) {
185 $conds[] =
'user_editcount > 0';
188 $options[
'GROUP BY'] = $this->creationSort ?
'user_id' :
'user_name';
191 'tables' => [
'user',
'user_groups',
'ipblocks' ],
193 'user_name' => $this->creationSort ?
'MAX(user_name)' :
'user_name',
194 'user_id' => $this->creationSort ?
'user_id' :
'MAX(user_id)',
195 'edits' =>
'MAX(user_editcount)',
196 'creation' =>
'MIN(user_registration)',
197 'ipb_deleted' =>
'MAX(ipb_deleted)',
198 'ipb_sitewide' =>
'MAX(ipb_sitewide)'
200 'options' => $options,
202 'user_groups' => [
'LEFT JOIN',
'user_id=ug_user' ],
213 $this->hookRunner->onSpecialListusersQueryInfo( $this, $query );
223 if ( $row->user_id == 0 ) { # T18487
227 $userName = $row->user_name;
244 if ( !$this->including && count( $ugms ) > 0 ) {
246 foreach ( $ugms as $ugm ) {
249 $groups =
$lang->commaList( $list );
252 $item =
$lang->specialList( $ulinks, $groups );
254 if ( $row->ipb_deleted ) {
255 $item =
"<span class=\"deleted\">$item</span>";
259 if ( !$this->including && $this->
getConfig()->
get(
'Edititis' ) ) {
260 $count = $this->
msg(
'usereditcount' )->numParams( $row->edits )->escaped();
261 $edits = $this->
msg(
'word-separator' )->escaped() . $this->
msg(
'brackets', $count )->escaped();
265 # Some rows may be null
266 if ( !$this->including && $row->creation ) {
268 $d =
$lang->userDate( $row->creation, $user );
269 $t =
$lang->userTime( $row->creation, $user );
270 $created = $this->
msg(
'usercreated', $d,
$t, $row->user_name )->escaped();
271 $created =
' ' . $this->
msg(
'parentheses' )->rawParams( $created )->escaped();
274 $blocked = $row->ipb_deleted !==
null && $row->ipb_sitewide ===
'1' ?
275 ' ' . $this->
msg(
'listusers-blocked', $userName )->escaped() :
278 $this->hookRunner->onSpecialListusersFormatRow( $item, $row );
280 return Html::rawElement(
'li', [],
"{$item}{$edits}{$created}{$blocked}" );
284 $batch = $this->linkBatchFactory->newLinkBatch();
286 # Give some pointers to make user links
287 foreach ( $this->mResult as $row ) {
288 $batch->add(
NS_USER, $row->user_name );
290 $userIds[] = $row->user_id;
295 $groupsQueryInfo = $this->userGroupManager->getQueryInfo();
296 $groupRes =
$dbr->select(
297 $groupsQueryInfo[
'tables'],
298 $groupsQueryInfo[
'fields'],
299 [
'ug_user' => $userIds ],
301 $groupsQueryInfo[
'joins']
305 foreach ( $groupRes as $row ) {
306 $ugm = $this->userGroupManager->newGroupMembershipFromRow( $row );
307 if ( !$ugm->isExpired() ) {
308 $cache[$row->ug_user][$row->ug_group] = $ugm;
309 $groups[$row->ug_group] =
true;
315 $this->hookRunner->onUsersPagerDoBatchLookups(
$dbr, $userIds,
$cache, $groups );
317 $this->userGroupCache =
$cache;
320 foreach ( $groups as $group => $unused ) {
321 $groupPage = UserGroupMembership::getGroupPage( $group );
323 $batch->addObj( $groupPage );
328 $this->mResult->rewind();
335 $self = explode(
'/', $this->
getTitle()->getPrefixedDBkey(), 2 )[0];
337 $groupOptions = [ $this->
msg(
'group-all' )->text() =>
'' ];
338 foreach ( $this->
getAllGroups() as $group => $groupText ) {
339 $groupOptions[ $groupText ] = $group;
344 'class' => HTMLUserTextField::class,
345 'label' => $this->
msg(
'listusersfrom' )->text(),
346 'name' =>
'username',
347 'default' => $this->requestedUser,
350 'label' => $this->
msg(
'group' )->text(),
352 'default' => $this->requestedGroup,
353 'class' => HTMLSelectField::class,
354 'options' => $groupOptions,
358 'label' => $this->
msg(
'listusers-editsonly' )->text(),
359 'name' =>
'editsOnly',
361 'default' => $this->editsOnly
363 'temporaryGroupsOnly' => [
365 'label' => $this->
msg(
'listusers-temporarygroupsonly' )->text(),
366 'name' =>
'temporaryGroupsOnly',
367 'id' =>
'temporaryGroupsOnly',
368 'default' => $this->temporaryGroupsOnly
372 'label' => $this->
msg(
'listusers-creationsort' )->text(),
373 'name' =>
'creationSort',
374 'id' =>
'creationSort',
375 'default' => $this->creationSort
379 'label' => $this->
msg(
'listusers-desc' )->text(),
382 'default' => $this->mDefaultDirection
384 'limithiddenfield' => [
385 'class' => HTMLHiddenField::class,
387 'default' => $this->mLimit
391 $beforeSubmitButtonHookOut =
'';
392 $this->hookRunner->onSpecialListusersHeaderForm( $this, $beforeSubmitButtonHookOut );
394 if ( $beforeSubmitButtonHookOut !==
'' ) {
395 $formDescriptor[
'beforeSubmitButtonHookOut' ] = [
396 'class' => HTMLInfoField::class,
398 'default' => $beforeSubmitButtonHookOut
402 $formDescriptor[
'submit' ] = [
403 'class' => HTMLSubmitField::class,
404 'buttonlabel-message' =>
'listusers-submit',
407 $beforeClosingFieldsetHookOut =
'';
408 $this->hookRunner->onSpecialListusersHeader( $this, $beforeClosingFieldsetHookOut );
410 if ( $beforeClosingFieldsetHookOut !==
'' ) {
411 $formDescriptor[
'beforeClosingFieldsetHookOut' ] = [
412 'class' => HTMLInfoField::class,
414 'default' => $beforeClosingFieldsetHookOut
418 $htmlForm = HTMLForm::factory(
'ooui', $formDescriptor, $this->
getContext() );
421 ->setAction( Title::newFromText(
$self )->getLocalURL() )
422 ->setId(
'mw-listusers-form' )
423 ->setFormIdentifier(
'mw-listusers-form' )
424 ->suppressDefaultSubmit()
425 ->setWrapperLegendMsg(
'listusers' );
426 return $htmlForm->prepareForm()->getHTML(
true );
452 $query = parent::getDefaultQuery();
453 if ( $this->requestedGroup !=
'' ) {
454 $query[
'group'] = $this->requestedGroup;
456 if ( $this->requestedUser !=
'' ) {
457 $query[
'username'] = $this->requestedUser;
459 $this->hookRunner->onSpecialListusersDefaultQuery( $this, $query );