Redirecting Users On Login VI

Redirect users based on a User Group setting, but control the order in which group memberships are tested


In the last article, we saw how to redirect users after login based on user group membership, but without a user group setting or a user setting. In this one, we'll return to the user group settings, but control the order in which they are checked. Since we don't know who the user is until *after* they've logged in, we need to put the code in a plugin connected to the OnWebLogin System Event.


Redirecting Users Based on a User Group Setting

In this article, we'll redirect the user after login based on a resource ID stored in a user group setting, but we'll control the order in which the groups are checked. If you don't need that, you can use the method from two articles ago. As a reminder, we'll first look at how to create a user group setting.


Creating a User Group Setting

You might think that you could do this by going to Content -> User Groups on the Manager's Top Menu. Unfortunately, user group settings aren't available there at this writing. Here's what you need to do:

  • Go to System (Gear Icon) -> Access Control Lists
  • Click on the "User Groups & and Users" tab if you're not there already
  • Right-click on a user group and select "Update User Group"
  • Click on the the Settings tab, then on the "Create New" button
  • Enter LoginResource in both the Key and Name fields
  • In the Value field, put the ID of the resource you'd like to forward the group's users to on login
  • Click on the Save button at the upper right to save the user group
  • Repeat for any other groups

The Plugin Code

To use user group settings, but control the order in which they are checked, we'll need to get the settings directly from the database. We'll also check for a user setting before we check the groups. That will allow us to override the plugin's behavior for individual users by creating a LoginResource user setting for them.

/* LoginRedirect plugin */

/* Set ID of default page to redirect to */
$default = 12;

/* Set up array of groups to check - in the order we want them checked  */
$groups = array(
    'Editors',
    'Publishers',
    'Members',
);


$sendTo = $default;

/* Check for a user setting */
$userId = $user->get('id');
$searchCriteria = array(
    'user' => $userId,
    'key' => 'LoginResource',
);
$userSetting = $modx->getObject('modUserSetting', $searchCriteria);

if ($userSetting) {
    $docId = $userSetting->get('value');
} else {
    /* No user setting, check groups */
    foreach($groups as $groupName) {
        $group = $modx->getObject('modUserGroup', array('name' => $groupName));
        if ($group) {
            $groupId = $group->get('id');

            /* See if user is a member */
            if ($user->isMember($groupName)) {

                    /* Get setting value */
                    $settingCriteria = array(
                        'key' => 'LoginResource',
                        'group' => $groupId,
                    );
                    $setting = $modx->getObject('[LoginRedirect plugin] modUserGroupSetting', $settingCriteria);
                    if ($setting) {
                        $value = $setting->get('value');
                        if (! empty($value)) {
                            $sendTo = (int) $value;
                            break;
                        }
                    } else {
                        $modx->log(modX::LOG_LEVEL_ERROR, '[LoginRedirect plugin] Could not find LoginResource user group setting for user group: ' . $groupName);
                    }
            }
        } else {
            $modx->log(modX::LOG_LEVEL_ERROR, 'Could not find user group: ' . $groupName);
        }
    }
}

/* Create the URL */
$url = $modx->makeUrl($sendTo, "", "", "full");

/* Forward the User */
$modx->sendRedirect($url);

The comments in the code above explain what it's doing. This code is nested somewhat deeply because each step requires the previous step to be successful. If we didn't test all the results with if, we'd get PHP errors when we tried to use non-existent objects in the next code section. With the tests, if any test fails, the code will fall through to the bottom and the default setting will be used. If all the necessary objects are found and the user is a member of the group currently being checked, the break; statement will short-circuit the foreach() loop and the user will be forwarded immediately. As in the earlier article, you can remove the break; statement to have the setting from the *last* group the user is a member of be used for the redirect.

Notice that we've also added a couple of messages for the MODX error log. With this code, if you misspelled one of the user group names or forgot to create a user group setting, you'd have a hard time knowing about it, so we write a quick message to the error log to let you know when a group or setting is not found.

Error log messages look complex if you're not used to seeing them, but they're actually pretty simple. They always look like this: $modx->log(modX::LOG_LEVEL_ERROR, ... );. The three dots are replaced with the message you want in the log. Notice that we have put the name of our plugin in brackets at the beginning of the message. This is good form. It's frustrating to see a message in the log and have no idea what plugin or snippet put it there.


Coming Up

One drawback of this method is that it retrieves each user group object just to get its ID. This simplifies the initial array, but since we know the user group IDs ahead of time (they're in parentheses next to the user group names on the way to creating the user group settings), we can speed things up quite a bit by just including them in the plugin and skipping the retrieval of the user group object. We'll make that improvement in the next article.

 



Comments (0)


Please login to comment.

  (Login)