8

In a registration form with public signup possible, how do you set the user group for a particular form?

As a stop-gap I am attempting to use the following code:

function init()
{
    craft()->on('users.saveUser', function(Event $event)
    {
        $user = $event->params['user'];

        if( $user->leader == true )
        {
            craft()->userGroups->assignUserToGroups($user->id, array(2));
        }   
    });
}

I created a field (lightswitch) called leader to enable me to check the value after saving the user and adding them to the group. The above code is not working though.

Using var_dump($user->leader) I can see the true and false being returned on user, and also the $user->id is returning the user's id, but the group (2) is not being assigned. Think I am missing something obvious. Thanks.

  • Also, I understand this could be a security concern since a user may be able to change the value but want to do it anyway. – Luke Holder Aug 11 '14 at 11:14
  • So, this exact code works for me. Did something possibly change in the year since this question was asked? – Peter Tell Dec 31 '15 at 3:27
6

If you're looking for a Craft 3 solution, I just got this set up on a project and hope it helps someone else out.

First you'll need to add a custom field to your form. If you want your user to choose which field, then go with a dropdown or radio button and adjust the plugin logic below. My scenario required me using a hidden field and auto-filling in the value based on a query parameter in the url.

<input type="hidden" name="myHiddenInput" value="1">

In your custom plugin's primary class, use this service at the top of your file:

use craft\services\Users;

and then in the init() function add this event and adjust the code to your liking:

Event::on(
    Users::class,
    Users::EVENT_AFTER_ASSIGN_USER_TO_DEFAULT_GROUP,
    function(UserAssignGroupEvent $event) {

        // get your hidden input value, 1 for true, 0 for false
        $isInDifferentGroup = Craft::$app->getRequest()->post('myHiddenInput');

        if ($isInDifferentGroup) {
            $differentGroup = Craft::$app->userGroups->getGroupByHandle('differentGroupHandle');

            $userId = $event->user->id;
            $customGroupId = $differentGroup->id;

            // add more group ids to array in 2nd param to add user to multiple groups
            Craft::$app->getUsers()->assignUserToGroups($userId, [$customGroupId]);
        }
    }
);

Shout-out to Oliver Stark from fortrabbit for helping me with this.

4

I literally just worked through this problem last week. Ran into the same issue, so I reached out to P&T.

Turns out there is a "catch"... For a new user, the $_POST['groups'] value is passed as an empty array. And because of the order that it's processed, that empty array will actually overwrite what you've set manually.

After working through it with Brad, this is the solution that worked for me:

public function init() {
    parent::init();
    craft()->on('users.saveUser', function(Event $event) {
        // If new user
        if ($event->params['isNewUser']) {
            // If "groups" is in POST
            if (isset($_POST['groups'])) {
                // If not an array, it's an empty string
                if (!is_array($_POST['groups'])) {
                    // Set it to an array with the user group ID
                    $_POST['groups'] = array(2);
                } else {
                    // Merge in the user group ID with any existing ones.
                    $_POST['groups'] = array_merge($_POST['groups'], array(2));
                }
            }
        }
    });
}
  • anyway to do it without setting the post var? wondering why my code is not working. – Luke Holder Aug 12 '14 at 6:27
  • Not at the moment. Brad and I worked through it a few different ways, this was the only way that truly worked. – Lindsey D Aug 12 '14 at 6:36
  • Where are you putting this code? – Matt Green Sep 6 '14 at 4:15
  • Hey @Matt, I'm not sure of your specific situation... but last night I built a plugin to solve my problem: github.com/lindseydiloreto/craft-autoassignusergroup . After you've installed the plugin, go to Settings > Auto-Assign User Group to specify what group(s) a new user should be assigned to. Email me (support@doublesecretagency.com) if you have any questions. – Lindsey D Sep 6 '14 at 4:55
  • ahhh. I see. Thanks, I simply just need to allow new users to select options which will assign them to the group they select, (needs to be secure so I'll get creative). I will use this as a base to start from thanks! – Matt Green Sep 6 '14 at 5:10
1

Just wanted to add some additional info for anyone who comes across this thread. I also needed to check if, and handle accordingly if a user belonged to a specific group upon registration from my plugin.

Here is what that looks like:

MyPlugin.php

craft()->on('users.onSaveUser', function (Event $event) {
    if (craft()->request->isCpRequest()) {
        error_log((craft()->config->get('devMode')) ? 'User is getting created from CP.' : '');

        if (isset($_POST['groups'])) {
            if (empty($_POST['groups'])) {
                // User does not have a user group.
            } else {
                foreach ($_POST['groups'] as $group) {
                    if ($group == 1) {
                        $this->_registerAccount($event);
                    } else {
                        // Not who I'm looking for.
                    }
                }
            }
        }
    } else {
        error_log((craft()->config->get('devMode')) ? 'User is getting created from the front-end.' : '');

        $this->_registerAccount($event);
    }
});
1

If you disable the email confirmation on your site, you can also use this: (But Ryan's answer still better though)

Event::on(Users::class, Users::EVENT_AFTER_ACTIVATE_USER, function (UserEvent $e) {

    //Tapping into the post to get the user group's handle
    $selectedUserGroupHandle = Craft::$app->request->post('user-group');

    //Find the corresponding user group
    $userGroup = UserGroup::find()->where(['handle' => $selectedUserGroupHandle])->one();

    //We've found the user group
    if ($userGroup){

        $groupIds = [
            $userGroup->id
        ];

        $user = $e->user;

        //This is legacy code from the UsersController.php
        Craft::$app->getUsers()->assignUserToGroups($user->id, $groupIds);
    }

});

You will need a custom input field (or select or whatever) on your form to post the user group's handle. In my case, that was user-group.

<input type="hidden" name="user-group" value="yourUserGroupHandle">

p.s.:

use craft\events\UserEvent;
use craft\records\UserGroup;
use craft\services\Users;
1

Surprised not to see the Groupie plugin referenced anywhere here, which does exactly this: https://github.com/kinoli/groupie

(I am not the developer of it, just a happy user!)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.