Joomla 2.5/1.7: Automatically assign users to a group based on email

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!

Comments

Joomla 2.5/1.7: Automatically assign users to a group based on email — 27 Comments

  1. My DomainRestriction plugin already does this and more. It’s been in the JED since March 2011.

  2. I still learing joomla.
    I created a hidden field in my login module. I have to different pages where people can register. But how do I store that ID in the database without modifing the core files?
    In other words how do I get my groupID from the module to the component?
    Or is there a way to save the groupID in a plugin after registration?
    Or can I modify the New User Registration Group value in my module?

    • A generic hidden field will get stripped by Joomla core, this is for security purposes. Any fields that it doesn’t expect are simple ignored before any processing occurs.

      I haven’t worked with 2.7/3.0 yet, but I believe they address this issue (and make it easier to automate groups/roles) with the now enhanced roles and acl implementation.

  3. Hello, nice post. Please if you can help me with similare and very simple thing. But I dnot know how I can make it.  I have two front user group. Registered group and Competition group . Is it possible to make one button on web when Registered group like to be Competition group tu push button and they will be in Competition group also. Thank you for answer, best regards Petr

  4. thank u all for the great responses.

    I’m indeed using a third party login. I’m using the community builder login, but i am new at this. So could anyone tell me in which file i need to write the code? And if i need to modify the code?

    I am also going to use the plugin “social login”. I would like to put these (google, facebook, twitter) logins into 1 group. Do i need to use the code (and location) that Sunny Patel wrote down here and does it also imply not only google, but facebook and twitter aslo.

    Gerald

  5.  Hi guys,

    Ok, so I disabled Jomsocial and IT WORKS in the base J2.5.4. I cannot for the life of me figure out how to get it working with Jomsocial though. I have tried to edit the JOOMLA_ROOT/plugins/user/joomla/joomla.php file as Sunny Patel pointed out, but no luck. I have also tried to edit JOOMLA_ROOT/plugins/user/jomsocialuser/jomsocialuser.php, but no luck either. This very well might be the place to make these edits, but I am just not familiar enough with php to grasp it.

    I have a kind of unique situation that I need to accomplish, but I am not very experienced in php scripting. If anyone thinks they could help me out – please, please, please do. I have literally spent 20 plus hours trying to figure out how to get this to work. I am ready to mail out a case of beer or cash reward for someone to figure this out for me because it’s driving me nuts.

    I am using Jomsocial 2.61 and Joomla 2.5.4 with LoginRadius module for “Log in with Google, FB, ect.” functionality.

    What I am trying to accomplish:
    1. New jomsocial registrations, signin with FB, signin with google, default to “2” (registered), unless;
    2. If the email domain is “exampledomain.com”, then the user group “14” is added in addition with user group “2”. (The domain is a google apps domain if this makes a difference, but not gmail.com).

    Ideally, if a user registers and is defaulted to usergroup “2”, then say they update their joomla user email to “exampledomain.com” than user group “14” is added. Does this make sense?

    If anyone can help me please let me know as soon as you can…thanks so much.

  6. I tried to implement this, but found that it wasn’t working for me when people would login through their Google account (in essence, bypassing the form). I found where I could do this at a deeper level so that it would incorporate all types of login/registrations. JOOMLA_ROOT/plugins/user/joomla/joomla.php (I’m on J1.7) inside the &_getUser function just before it decides to try to autoregister or login replaced the code with the following (like in the image). Most of this is changing line 249 and after so that it looks like this: 

    $defaultUserGroups = array($config->get(‘new_usertype’, 2)); //Get params from Gmail Auth Plugin and add those users that login to the ‘Authors’ group $gmailParams = new JRegistry(); $gmailParams->loadString(JPluginHelper::getPlugin(‘authentication’, ‘gmail’)->params); foreach( explode( “,”, $gmailParams->get(‘suffix’, ”) ) as $domain ) { if( strpos(strtolower($user[’email’]), strtolower(trim($domain))) !== false ) { $defaultUserGroups[] = 3; break; } }And the last instance->set to the following since it’s already an array:
    $instance->set(‘groups’ , $defaultUserGroups);

    If you decide to copy the foreach loop, be sure to do something similar if you have the GMail Authentication plugin active as I’ve changed it to allow multiple domains.

    • Spot on, thanks for pointing this out and adding code to address it!

      If you are using any third party mechanisms that override your login/registration behavior, the files I changed in the original post may be overridden by the third party solution, and as Sunny Patel noted, under those circumstances the code change will not effect your site behavior.

  7. Great post imperialWicket! I am having issues though. I am using Joomla 2.5.4 and this is not working for me.

    The user is assigned to the “Registered” default group. Any idea? Am I missing something?

    The group is ID #14
     

      •  Thanks so much imperialWicket! I have been trying to figure this out almost non-stop since my first post. Still nothing. I am using Jomsocial too if that make a difference? Sorry I am new to this and it is driving me crazy! You are my closet hope to figureing this out.  Thank you!!

        • It seems to work for me in a basic install, and I think it’s probably Jomsocial (good thinking to point that out).  You may want to try Sunny Patel’s solution (in these comments) that resolved inconsistencies when using the Gmail Authorization plugin.  

           I haven’t validated that it works in Jomsocial, but the key would be if Jomsocial uses the default database tables that Joomla uses, then they are likely using the lower level user registration processes.  You need to change the code appropriately, but it’s a similar structure and goes in /plugins/user/joomla/joomla.php .

  8.  Hello,

    I don’t have much experience with php configuration, so i folowed this post but it isn’t work for me. I have created a group called students and this id is 9. As test i want an adress ending with gmail.com to be assigned to this group.

    I wrote the string into the php file (see attachment) but when is register its beeing place in the default group. so what am i doing wrong?

    PS. im using joomla 1.7

    Please help!!

  9. How would this be done using another pre-existing registration field: say the username.

    My users all register using usernames I’ve sent them on ID cards, then they have to input their unique ID into the username field when signing up. Can I change the code above to say that:

    “If the number is between 1 and 5000 > send user to Group A – else if the number is between 5001 and 1000 > send user to group B”

    I know basic PHP and so I have already changed “($data[’email’])” to “($data[‘username’])”

    but ho do i get the ‘if’ commands to choose a number between say 1 and 5000?

    Thanks for this great article by the way! It’s been a great help!

    Ray

    • PHP is pretty good at determining if a string is a number.  So long as your username value is actually a number, this should work (in place of the original ‘if’ construct from above):

      if($data[‘username’] = 5001){
        $data[‘groups’][] = INSERT YOUR GROUP B ID;
      }

      You might see strange behavior if your username isn’t a number.  Hope this helps, good luck!

      •  Cool thanks for this. I remember in my PHP class that the teacher said that PHP can be forgiving with integers. So if the username is ABC11043 it’ll recognise the ‘11043’ part.

        Thanks again for this! It’s a big help! 🙂

        • No, PHP isn’t that good.  If you store an integer value (‘11043’), PHP doesn’t need you to tell it that it is an integer, however, a mixed value (‘abc11043’) is a string – it just happens to contain an integer.  Something like this might be handy:

          // A sample username with numeric padding$testString = ‘username1125’;// Regular expression that identifies only numbers$regex = ‘/[^0-9]/’;// PHP’s regular expression search/replaceecho preg_replace($regex, ”, $testString);

          See the PHP manual for more data on preg_replace.

          •  Thanks for this! I got it working by using substrings:

            // Convert the Username to all lower case for safe alpha compare.
            $lowerUsername = strtolower($data[‘username’]);

            // Grabs first 3 characters
            $letters = substr($lowerUsername, 0, 3);

            // Grab from 4th character to the end of the string
            // no matter how long the string
            $numbers = substr($lowerUsername, 3, (strLen($lowerUsername)-3));

            // First check the letters
            if($letters == “abc”)    {

              // Now convert the number string to a real number
              $intNumber = intVal($numbers);

              // This is checking ABC00001 to ABC50000
              if($intNumber >= 00001 and $intNumber = 55001 and $intNumber <= 60000) {
            $data['groups'][] = NEXT GROUP ID;
            }
            }

            Thanks for all your help! 🙂

  10. How would you change this script if say instead of the using the email address you used a custom field for perhaps a number code to gain access to higher level ACL. Could that be done?

    • It could, but it would be a bit awkward. Joomla validates the form fields against the database fields, so you would actually need to update the user model and the database table to include a ‘registrationCode’ value in order to use this technique.  Otherwise the registrationCode value gets sent to the controller, and then stripped during the model->validation() process. 

      There are a couple of extensions (like JomSocial) that ease the addition of fields to registration, but they make this technique much more difficult. 

      Custom registration fields keeps surfacing in the Joomla roadmap, hopefully it will come about soon and this type of functionality will find its way into the core.  Right now the process would be to add a new field and then use that field to validate with the technique in this post.  Just be sure that you don’t require the field, and that you allow empty or null values in the db.

      • Could you add a Group Name during registration of a user? I would like a team leader to build a roster and when the team leader registers he assigns a team name that goes with an ID the falls within Registered range of IDs… I would have a controlled form to only allowed contacted team leaders to access… Can a group ID be created at the frontend?

        • You could, but it goes into the same conundrum as custom fields mentioned earlier in this thread. The default user login behavior strips unknown fields from the form.

          Rather than hacking apart the default user component, I would lean toward writing a custom component (I haven’t found an existing component that quite covers this, but haven’t looked recently) that offers a registration replacement and can better handle such requests.