Sunday, September 26, 2010

Search for dotCMS users by group or role

You interact with dotCMS users in Velocity via the $cmsuser object, which is an instance of the com.dotmarketing.viewtools.CMSUsersWebAPI class and provides various methods for looking up user objects.

The searchUsersAndUsersProxy method lets you search for users by name, group name or role. Below is the code I use to search for all users who have the Administrator role and then output Name (email address) for each of them. I have only tested this on dotCMS 1.7.

#set($found = $cmsuser.searchUsersAndUsersProxy(null, null, null, [], false, ["Administrator"], true, null, 1, 1000))
<p>Found $found.get("users").size() Administrator users.</p>
#set($theUsers = $found.get("users"))
#foreach ($user in $theUsers)
   $user.fullName ($user.emailAddress)<br>
#end

Below are some important notes about this code.

  • This method is the only one in the class designed for pagination i.e. for displaying results one page at a time. The last two parameters are page - as in what "what page of results do you want to return?" - and pageSize - as in "how many results should be on this page?"
  • The limit argument for this method (pageSize) has slightly different semantics to the limit argument in other search techniques such as # results in the pullContent macro. In the latter, 0 means no limit on the results, but in searchUsersAndUsersProxy it really means 0! If you intend on pulling back all results in one page, use a number so big that you will never get that many users.

    At the time of writing, Facebook has more than 500,000,000 users, Twitter has more than 75,000,000 users, Hotmail has more than 360,000,000 users and Gmail has more than 170,000 users. I think 1,000 is well and truly more than the total number of Administrator users the site I am working on will ever have. A dotCMS JIRA bug was raised for this discrepancy and I posted a question to StackOverflow when I was trying to work why my original code wasn't working.
  • The fourth parameter, groupNames should be empty square brackets [] - which is an empty array/ArrayList for Velocity; which does not support the keyword null (my first guess as a Java programmer).
  • The fifth parameter, showUserGroups should be false. If true, you will get lots of duplicates (as you would if there was a full join between selecting users matching role X and any group).

I found this useful when I was working on a dotCMS form handler whose intention was to allow users of the site to submit feedback for review by the site administrators. I used the above technique to extract all of the administrator email addresses as recipients for the email (addresses which you will find are not displayed in the HTML source, if you read the post I linked to). I came across the issues mentioned above and tried to solve them in this post to the dotCMS Yahoo group: Getting email addresses of all users with the Administrator role.

For testing purposes, here is the SQL that will do the same job (get email addresses for every user with an Administrator role).

select user_.emailaddress
from user_
INNER JOIN users_roles
ON users_roles.userid = user_.userid
INNER JOIN role_
ON users_roles.roleid = role_.roleid
where role_.name = 'Administrator';

Pages that helped me write this post.

My dotCMS notes.