Listing Users Based on an Extended Field

Select and display users based on the content of an extended field in the User Profile


If you want to show a list of users with, or without, their personal information, one of the easiest ways to do it is to use Shaun McCormick's Peoples extra. Peoples will show information about users selected by User Group and will let you you sort the users by any field. One of the things Peoples will *not* do, though, is let you select users based on an extended field.

A MODX user recently requested this on the MODX Forums, so I'm devoting this blog post to creating a snippet to do it and demonstrating a little about how MODX snippets work along the way. The following snippet will select users based on an extended field and will show any information about them contained in their User Profile (including any extended fields). Note that the snippet selects users *only* by extended field. To select users in a different way, you'd have to use a different snippet.

The snippet tag will look something like this:

[[ShowUsers?
    &searchField=`Qualified`
    &value=`ANY`
    &active=`1`
    &tpl=`MyShowUsersTpl`
]]

All the properties are required except the "active" property. The "searchField" property tells the snippet which extended field we are selecting by — in other words it contains the name of the extended field you want to search by. The "value" property is the desired value of that field. It can be set to "ANY" to allow any value. You'd use this if you wanted to include only users for whom the extended field exists.

In the example above, any active users for whom the 'Qualified' extended field exists will be selected. If we had used &value=`professional` , only users with the 'Qualified' extended field set to 'Professional' would be selected.

The "active" property defaults to 1, which means only active users will be shown. If it is set to 0, all users will be shown (unlike the Peoples snippet where a value of 0 shows only inactive users). The "tpl" property gives the name of our Tpl chunk and it defaults to "ShowUsersTpl" .

The Tpl chunk might look like this:

    <p><b>USER: [[+username]]</b></p>
    <ul>
        <li>FULLNAME: [[+fullname]]</li>
        <li>STATUS: [[+status]]</li>
        <li>EMAIL: [[+email]]</li>
    </ul>

The snippet will set placeholders for the useful fields in the User object (the password fields, for example, are not set), all fields in the User Profile Object and all Extended fields. Be careful, the names of the placeholders have to match the names of actual fields. For a list of the available fields, look at these links:

For the Extended fields, the names will be the ones you used when you created the extended fields.

This snippet could be made slightly more efficient. I've done it this way to make the code a little easier to understand. Comments in the code explain how it works.

<?php
/* ShowUsers snippet */
$output = '';

/* Get the properties sent in the snippet tag */
$searchField = $modx->getOption('searchField', $scriptProperties, '');
$value = $modx->getOption('value', $scriptProperties, '');
$active = $modx->getOption('active', $scriptProperties, 1);
$tpl = $modx->getOption('tpl', $scriptProperties, 'ShowUsersTpl');

/* Make sure the searchField is set */
if (empty($searchField)) {
    return 'searchField is not set';
}

/* Remove any leading or trailing spaces */
$searchField = trim($searchField);
$value = trim($value);

/* Get all User Profiles */
$profiles = $modx->getCollection('modUserProfile');

/* Loop though the Profiles and select qualified users */

foreach ($profiles as $profile) {
    /* Get the extended fields */
    $extended = $profile->get('extended');

    /* Ignore users if their search field is not
       set or there are no extended fields */
    if (! $extended || (!isset($extended[$searchField]))) {
        continue;
    }

    /* Ignore users where value doesn't match
       unless value = ANY */
    if (strcasecmp($value, 'ANY')) {
        if (strcasecmp($value, trim($extended[$searchField]))) {
           continue;
        }
    }


    /* Now that we have a qualified user Profile
    we'll get the user object */

    $userObj = $profile->getOne('User');

    /* Ignore inactive users if 'active' is 1 */
    if ($active && ($userObj->get('active') == 0)) {
        continue;
    }

    /* Now we have a fully qualified user to show */

    /* Put user information into the fields array */
    $fields = array();
    $fields['username'] = $userObj->get('username');
    $fields['id'] = $userObj->get('id');
    $fields['active'] = $userObj->get('active');
    $fields['sudo'] = $userObj->get('sudo');
    /* Add in the User Profile fields */
    $profileFields = $profile->toArray();
    $fields = array_merge($fields, $profile->toArray());
    /* Add in the extended fields */
    $fields = array_merge($fields, $extended);

    /* Add the processed Tpl chunk to the output */
    $output .= $modx->getChunk($tpl, $fields);
}
return $output;

The code and comments are fairly self-explanatory, but one point deserves a mention. Normally, when searching for users, we get the User object first and then get the associated User Profile. In this snippet, we're doing it the other way around because we're searching on the basis of something in the User Profile. We get the User Profile, make sure we want the user, then get the Profile's associated User object with $profile->getOne('User').



Comments (0)


Please login to comment.

  (Login)