Do I use DataWriter to set usergroups?


We are planning a migration from vBulletin to XenForo and as part of that we're going to change every users' user groups so that (apart from guests) all users have 'Registered' as their primary (and their previous primaries added as secondaries). We're also using it as a chance to consolidate some of the groups and simplify everything.

I know that the Batch User Update tool is there for exactly this purpose, but using it to change groups for all users has been prone to error and very time consuming when we have done a trial run. I have spent a little time trying to put together a script that changes the user groups based on a mapping we have defined.

I ran a few tests with a previous version, which was calling update() directly on the UserModel to update the primary and secondary user groups. Even though the tests were only on a small subset of our users and seemed to work, after a number of hours I found that all users had been moved into 'Registered' and our banned group. Strange.

Having read a bit more about this now, I have modified the code to user the User Datawriter, which I believe is the recommended method for updating usergroups. Is anyone able to tell me if changing usergroups in this way can be done, and if the code below looks plausible.


    public function usergroups() {   
        $userModel = XenForo_Model::create('XenForo_Model_User');
        $userDw = XenForo_DataWriter::create('XenForo_DataWriter_User');
        $registeredGroup = '2';
        $unregisteredGroup = '1';
        $users = $userModel->getAllUsers();

        foreach ($users as $user)
         $secondary_group_ids = array();
            if ($user['secondary_group_ids'] != ''){
                $secondary_group_ids = explode(",", $user['secondary_group_ids']);

            if ($user['user_group_id'] != $registeredGroup & $user['user_group_id'] != $unregisteredGroup){ 
                $secondary_group_ids[] = $user['user_group_id'];   
            $secondary_group_ids = array_filter(array_map(array('self','_mapUsergroups'), $secondary_group_ids

                $secondary_group_ids = implode(",", $secondary_group_ids);
                $secondary_group_ids = explode(",", $secondary_group_ids);

            $userDw->set('user_group_id', $registeredGroup);
The _mapUsergroups() function maps each usergroup ID to the new value it should have - sometimes one group goes to two which is returned as e.g. '2,51', hence the need to implode and explode the elements of the array again.
Hi @Daniel Hood,

Thanks for taking a look at the code.
Glad to here it looks like it should work. Do you think it's a sensible way of getting the users into their correct groups, or is there something else I would be better off doing?


Daniel Hood

Well-known member
Doing it at the same time as creating users would probably be more ideal but there's nothing wrong with this I suppose. It's just a one time thing, right? And your site isn't live when doing it so there's no real risk of your database locking up or slowing down.
Last edited:
That's right, it's just a one time thing, after the import and before the site is made live.
I had thought about editing the import process to assign the correct user groups at that point. I might have another look into that, it would be quicker and simpler.