I think it would be nice to have a drush user-list command, that prints out a table with users.

The attached patch provides the command, like:
drush user-list - Full list of all users
drush user-list --names=admin,tester - Users by the name of admin or tester
drush user-list --roles=editor,publisher - Users with the role editor or publisher
drush user-list --status=blocked --roles=blogger - Blocked users with the role blogger
drush user-list --emails=nospam@please.com,me@myself.com - Users with the specified emails

Shortcut is drush uli

Please do test and report!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Manuel Garcia’s picture

Here is a git format-patch origin/master --stdout version of the patch

jonhattan’s picture

Status: Needs review » Needs work

A preliminary review:

+++ b/commands/user/user.drush.inc
@@ -159,6 +159,23 @@ function user_drush_command() {
+    'callback' => 'drush_user_list',

There's no need to define this. Drush will infer that same function name from the command name.

+++ b/commands/user/user.drush.inc
@@ -159,6 +159,23 @@ function user_drush_command() {
+    'aliases' => array('ulis'),

the alias for user-login is 'uli'. Perhaps it results confusing.

+++ b/commands/user/user.drush.inc
@@ -159,6 +159,23 @@ function user_drush_command() {
+      'names' => 'A comma separated list of names to filter by',
+      'emails' => 'A comma separated list of emails to filter by',
+      'roles' => 'A comma sepparated list of roles to filter by',
+      'status' => 'Filter by status of the account. Can be active or blocked',

roles and status seems useful but I don't see the utility for names and emails given that they fit the exact match. You can use user-information command to get all the info for a user based on uid, name or mail. Also it is useful to filter users that had never login (spam accounts).

+++ b/commands/user/user.drush.inc
@@ -481,6 +498,104 @@ function drush_user_login($name = NULL) {
+  $names = (!empty($names)) ? explode(',', $names) : $names;

you can use this function to explode csv:
http://api.drush.ws/api/function/_convert_csv_to_array/master

+++ b/commands/user/user.drush.inc
@@ -481,6 +498,104 @@ function drush_user_login($name = NULL) {
+    $uid_query = db_query("SELECT uid FROM {users} AS users $query_mod");

This raises a warning if $query_mod was not defined. Also you may use
http://api.drush.ws/api/function/drush_db_select/master

+++ b/commands/user/user.drush.inc
@@ -481,6 +498,104 @@ function drush_user_login($name = NULL) {
+  $header = array('UID', 'Name', 'Email', 'Roles', 'Status');

dt('Name') etc

+++ b/commands/user/user.drush.inc
@@ -481,6 +498,104 @@ function drush_user_login($name = NULL) {
+    $user = user_load(array('uid' => $uid));

IMO this is killer. In general you can build a complex query from the given options. See watchdog command for reference.

Also may be of interest to implement --pipe support.

Manuel Garcia’s picture

Status: Needs work » Needs review
FileSize
3.31 KB

Thanks for the review!

Here is a rework of the previous patch:
1. Removed name and email options
2. Removed the callback
3. Renamed the alias to ulst (I accept suggestions here!)
4. Using http://api.drush.ws/api/function/_convert_csv_to_array/master where appropiate

For the user_load, I've removed it into a drush_db_select that takes the options into account when building the WHERE's. I honestly don't know if this will be faster or not with tons of users, since the $user object is cached. If it isn't cached, then yes it should be faster I suppose.

I haven't managed to use drush_db_select for finding the uid's of the roles specified in the option, I guess Ishould do two queries since drush_db_select doesnt do joins, or at least I don't know how. So that part could use some loving I guess.

Any input is welcome!

greg.1.anderson’s picture

Haven't tried it yet, but I like this idea. I might suggest uls (like "ls" for users) as the command alias.

Manuel Garcia’s picture

Status: Needs review » Needs work
FileSize
3.79 KB

Some more progress on this:

1. Changed the alias to drush uls as suggested in #4.
2. Added a check for when the speficied role does not have any users associated with it, which was throwing an SQL error. It now returns early with a drush_set_error() message.

The biggest change in this patch is that I moved this query:
$query = db_query("SELECT ur.uid FROM {users_roles} AS ur INNER JOIN {role} AS r on ur.rid = r.rid WHERE r.name IN ($roleplaceholder)", $roles);
into two drush_db_select()'s for compatibility. If anyone knows how to use this function with a JOIN it might be faster perhaps, do let me know!

In coment #2 it's suggested that it "Also may be of interest to implement --pipe support.". No clue how to do that, though willing to learn, any pointers?

Manuel Garcia’s picture

Status: Needs work » Needs review

I've just tested the command with 58563 users in the db... it sure took some time, although it finished.

I think we need to figure out a way to either limit this to a safe ammount by hardcoding it, or warn the user or bring pagination into drush somehow... suggestions welcome!

tunic’s picture

Status: Needs review » Needs work

Nice work, I've tested and seems to works fine, although not tested with a Drupal with a huge ammount of users.

Initially I thought that could be useful to query users based on email but not with exact match but with partial match. However main use for this feature would be to detect test users (finding test*@* users or *@devserver*) but I guess this can be accomplished better with a simple query using sql-query so it's no worth to pollute drush comand list and options ;)

For pipe you have to use drush_print_pip function. It seems that you have to always put pipe info using that function and drush will only show if --pipe param is added. Well, manuee and me we have figured out talking on IRC but I leave here for reference purposes.

Manuel Garcia’s picture

Status: Needs work » Needs review
FileSize
3.93 KB

Yeah didn't know about that function and i just happened to read it on other drush commands... yay!

Anyway, here is an updated version of the patch, with --pipe command, and a minor PHP 5.3 notice nuked.

Manuel Garcia’s picture

As jonhattan suggested, this new patch will give you only the emails when runing with --pipe.

It also fixes another php 5.3 notice introduced in the last patch.

Manuel Garcia’s picture

Coding standards... (ran it through coder php script)

uwguy’s picture

Just wanted to toss out that it failed for my PgSQL8.3/Drupal 7.4 site after applying drush-user-list-1199080-6.patch to Drush 4.4.

WD php: PDOException: SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at [error]
or near "%" at character 75: SELECT users_roles.rid AS rid
FROM
{users_roles} users_roles
WHERE (uid = %d) ; Array
(
[0] => 6
)
in drush_db_select() (line 1858 of /data/drush44/includes/drush.inc).

I'll try posting an update if I get something working too.

Manuel Garcia’s picture

The patch is against master uwguy, not drush 4.4

moshe weitzman’s picture

db_placeholder() is only available for D6. See #508756: RIP db_placeholders(). Please fix and test for D7.

I'm kind of thinking that this should be a query mechanism for the other user commands. What I imagine is that the results table gets fed into drush_choice and you can operate on any row from there. This is probably hard to implement, but sounds cool :)

Not totally sure this belongs in core. Thinking about it.

greg.1.anderson’s picture

If the other user commands use (or in the future might use) the user-list command, then user-list needs to be in core if the other user commands are in core.

I am a little unhappy about the scattering of the site-admin commands, with some in core, some in extras, and some, like drush role off by themselves in small extensions.

I think that we should accept all site configuration commands that deal with configuration options for Drupal core in drush core, and put them all in a 'site-admin' folder. Failing that, I think we should move them all to extras, or make a new project, drush_site_admin to hold them. Configuration options for contrib modules belong with the contrib modules themselves, but we should not allow all of the Drupal core config commands to continue to be scattered.

Manuel Garcia’s picture

Status: Needs review » Needs work
moshe weitzman’s picture

I can sympathize with this frustration. I experience it too. But I can think of no other way. Consider some niche commands that deal with forum module (i.e. drupal core) that let you move comments from one thread to another. Thats vital when you need it, but very few drupal sites need it. You want that in Drush core? I can think of commands that are too obscure for drush_site_admin admin as well (poll vote management).

The point is, not everyone needs the same stuff and mainstream maintainers don't want to manage niche code. Creating another bucket but that does not completely solve the problem.

It is quite possible that the frustration stems from a disgreement about whether role and user-list commands are broadly useful or not. Again, these sorts of disagreements are inevitable when a maintainer highly values code that he does not have to maintain :)

Having said all that, I do have a dream to split all drupal code out of drush. All the drupal code would live in a drupal extension. Others might make a wordpress extension, and so on. Patches welcome. It would be the most awesome patch since #335360: Drush does NOT have to be a module!.

-moshe

greg.1.anderson’s picture

I actually use drush sql-sync to copy my bugzilla database, so I can see the utility of #16. If I ever used wordpress or joomla, I might consider it. :)

I do see your point about commands that are core but obscure; my metric of 'if it's core, it must be common' is not accurate. If we could convince the Drupal core maintainers that they should maintain drush commands for everything... c.f. above comment about highly valued code that one does not have to maintain ;). And so the controversy lives on. Maybe all I really need is a section on drush.ws/resources that lists all of the drush extensions that do site management for Drupal core.

jonhattan’s picture

Issue tags: +Release blocker

Depends on #1364808: Proposal for an output formats engine.

I'd also like to see a drush_drupal extension (and drush_wp) being drush the core of all of this.

In the meantime I think user-list worth core.

moshe weitzman’s picture

Issue tags: -Release blocker

remove tag

Manuel Garcia’s picture

While I agree there is much room for discussion on what core modules should drush core support, in the case of the user module, I think it's justified that it should be in drush core.... correct me if I'm wrong but, I don't see any drupal sites being launched without the user module enabled...

Perhaps we should support what modules the current "Minimal" installation profile enables? Just an idea, and well, this is probably not the proper issue to discuss it seriously anyway... =)

msonnabaum’s picture

This command definitely needs work, but I think it should go in.

There's a big difference between supporting everything that ships with core and supporting the required core modules. This command especially could be a very useful utility command.

Here's what I'd like to see changed:

- Break out the fetching of the users from the command callback. It's pretty long and hard to follow as it is.
- Support D7. Maybe use EntityFieldQuery for that part.
- Support the typical "format" options found in cache-get.

svenaas’s picture

I'd like to see this added as well; it would be very useful.

hawkeye126’s picture

Version: » 7.x-5.8

I applied this as a custom command and it works great although I got these errors:

array_flip(): Can only flip STRING and INTEGER values! entity.inc:355  [warning]
array_flip(): Can only flip STRING and INTEGER values! entity.inc:355  [warning]
array_flip(): Can only flip STRING and INTEGER values! entity.inc:355  [warning]
array_flip(): Can only flip STRING and INTEGER values! entity.inc:355  [warning]
array_flip(): Can only flip STRING and INTEGER values! entity.inc:355  [warning]

To clear these warnings I had to change u

$user = user_load(array('uid' => $uid)); //Brings back error

to

$users = user_load_multiple(array(), array('uid' => $uid));
$user = reset($users);
matason’s picture

I'd like to add the ability to use drush user-list to see who's online.

I'll most likely have some time next week to work on it.

greg.1.anderson’s picture

Version: 7.x-5.8 » 8.x-6.x-dev

Help here is greatly appreciated. Future patches should utilize the new output formatters in Drush 6. See the drush topic documentation, and #1862950: drush site-alias should indicate the current alias set by drush use.

moshe weitzman’s picture

I'll add that we have views-execute in Drush core now. Thats a way to get listings of users and loads of other stuff. It handles paging, querying, etc. I think this is Won't Fix but willing to discuss more.

greg.1.anderson’s picture

Maybe user-list could just be a thin wrapper around views-execute, then?

greg.1.anderson’s picture

Side comment: views-execute is currently only implemented for D8.

greg.1.anderson’s picture

Status: Needs work » Closed (won't fix)
Issue tags: +Needs migration

This issue was marked closed (won't fix) because Drush has moved to Github.

If this feature is still desired, you may copy it to our Github project. For best results, create a Pull Request that has been updated for the master branch. Post a link here to the PR, and please also change the status of this issue to closed (duplicate).

Please ask support questions on Drupal Answers.

kenorb’s picture

Issue summary: View changes
Status: Closed (won't fix) » Closed (duplicate)