Access control advancements are the primary reason I moved many of my Joomla efforts beyond 1.5. One request that I hear repeatedly is to have access control automatically added when a user registers. In its most basic form, this is simple to accomplish in the administrative interface. Create a group, position it somewhere beneath 'Registered', and then generate an Access Level that is associated with only that group. Now under User Manager - Options, select the appropriate group under 'New User Registration Group'. Now when a new user registers, they are automatically added to that group, and given the corresponding Access Level.
Often this scenario is sufficient for the needs of a site. However, occasionally I get requests that some users are added to one group, while other users get added to a different group - often based on email. For example, anyone registering with an email ending in '*.edu' must be added to the education group, and anyone registering with an email ending in 'someDevCompany.com' must be added to the developer group. As I see it, there is not a great way to handle this scenario built in to the Joomla core. Also, most of the options where you would achieve this involve replicating or extending the core users component, which often adds confusion for your site administrators.
This solution is not elegant, and it requires some minimal PHP knowledge in order to expand, but it functions well, and stays out of your administrator's way. First make a couple groups and a couple corresponding access levels. We need to note the group ID values, we will use these in our code updates. In the User Manager, on the User Groups page, you can see the ID value in the far right column. If you are working with a fresh installation, the ID of your first new group is likely 10 or 13, depending on whether or not you elected to load the sample data. Note your group IDs and keep those handy, I will use IDs 13 and 14 to represent 'education' and 'developer' groups, respectively.
Now we need to add a few lines of code to the existing users component. The psuedo-code goes like this:
if the user's email ends in 'edu',
then add them to the education group (with id 13)
else if the user's email ends in 'someDevCompany.com',
then add them to the developer group (with id 14)
else add the user only to the Registered group
In order to have the least impact on existing code, we add this very close to the user saving event. Proceed to the JOOMLA_ROOT/components/com_users/models/registration.php file, and locate the 'register($temp)' function. You can also look for the 'bind' text, as we want to update the groups data immediately prior to the binding of form input to the user object. This is right around line 325 in Joomla 1.6 or greater. I am including the code before and after for reference, and we must add the following:
// Check if the user needs to activate their account.
if (($useractivation == 1) || ($useractivation == 2)) {
jimport('joomla.user.helper');
$data['activation'] = JUtility::getHash(JUserHelper::genRandomPassword());
$data['block'] = 1;
}
//*************BEGIN****************
// Convert the email to all lower case for safe alpha compare.
$lowerEmail = strtolower($data['email']);
// Add the appropriate group ID to the existing groups array.
if(strpos($lowerEmail,'.edu') !== false){
$data['groups'][] = 13;
}else if(strpos($lowerEmail,'someDevCompany.com') !== false){
$data['groups'][] = 14;
}
//**************END*****************
// Bind the data.
if (!$user->bind($data)) {
$this->setError(JText::sprintf('COM_USERS_REGISTRATION_BIND_FAILED', $user->getError()));
return false;
}
Notice that we are not replacing the '$data['groups']' array, just adding a value to the end of the existing array. This way, the user is added to both the 'Registered' group and the appropriate additional group. If you wanted to avoid setting multiple groups, you could instead create a new array, and add a single group id to the array based on your conditional checks. Then simply set '$data['groups'] = $yourNewArray;', and you are in business.
I hope this saves a few people some time. I will do my best to respond to any questions in the comments, and definitely feel free to post alternative solutions!