I'm having trouble importing user roles as text, and wondering if there's an additional step I'm missing.

In my Drupal 7.0-rc4 install I've created a custom role "Member", and I am attempting to import my users, some of whom will have the "Member" role.

My import table contains a column "subscr_role" which is either null or contains the text "Member". I'm mapping the field via the following:

$this->addFieldMapping('roles', 'subscr_role')->separator(',');

My migrate-import proceeds without error, but the roles don't appear correctly. When I go to the People List admin screen I see the following repeated numerous times above the user table.

Notice: Undefined index: 0 in user_admin_account() (line 206 of /home/patcms/public_html/modules/user/user.admin.inc).

I also see (probably corresponding) strange ul of roles with one empty role li under the roles column. So it almost appears as though I'm adding a blank role to users who should be receiving the "Member" role.

Should I be attempting to map the role name to some sort of object in the prepare method?

Comments

zabelc’s picture

After some digging and a fair bit of trial and error, I discovered the solution. The underlying problem appeared to be the entries in th array of roles expected by the account object. Each entry in the array must itself have been an array of role_id=>role_name.

Because I had set up my roles beforehand and because my source data contains role_name's, I needed to to map my role_names to role_id's before constructing a list. I did this in three steps:

  1. Create a field to hold a map of role_id's to role_names
    class MyMigration extends Migration {
    
      public $role_name_id_map;
    
    
  2. Create a map of role_name's to role_id's in the Migration's constructor:
    public function __construct() {
      // . . .Other Logic. . .
        $role_arr = user_roles(true);
        foreach($role_arr as $rid=>$rname){
          //print("ID($rid)=NAME($rname)\n");
          $this->role_name_id_map[$rname] = $rid;    
        }
    }
    
  3. Set up the field mapping
        $this->addFieldMapping('roles', 'subscr_role')->separator(',');
    
  4. In the prepare function convert the array of role_names from the mapping to an array of role_id=>role_name arrays.
      public function prepare(stdClass $account, stdClass $row) {
    
        $roles = array();
        if( isset($account->roles) ){
          foreach ($account->roles as $role){
            $rid = $this->role_name_id_map[$role];
            //print("User $account->name has role='$role' rid='$rid'\n");
            if( isset($rid) )
              $roles[$rid] = $role;
            else print("User $account->name has Unrecognized role='$role'\n");
          }
        }
        $account->roles=$roles;
      }
    
  5. I don't know if this is something that should be added to the user import plugin. If it is, and someone points me in the right direction, I could try to create a patch at will handle this...

mikeryan’s picture

Category: support » feature

The roles field should support an argument that roles are being passed by name rather than by rid (as they are by default).

moshe weitzman’s picture

Added text to fields() method indicating that we expect IDs, not names.

mikeryan’s picture

Component: Drush » Code
Assigned: Unassigned » mikeryan
Status: Active » Fixed

Knocked off another old easy feature request - there is now a role_names field on users, which can be used instead of roles if it's easier to express your roles by names rather than rid.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

jlemosy’s picture

I can't get either the 'roles' or 'role_names' options to work. I'm using the following code, which I've seen used in several examples of how I'm supposed to do this...

$this->addFieldMapping('roles')
     ->defaultValue(DRUPAL_AUTHENTICATED_RID);

...but no records are created in the 'users_roles' table when I migrate users, which is what I would assume is the intended result. Or am I not grasping the concept here? All my other migration data is working correctly and winds up in the right place; this is the only hiccup I've run into so far.

I'm using:

  • Drupal 7.14
  • Migrate 7.x-2.4

I hope someone can help explain what I'm doing wrong here. Any help would be appreciated.

Thanks!
James

jlemosy’s picture

Status: Closed (fixed) » Active
jlemosy’s picture

Version: 7.x-2.0-beta3 » 7.x-2.4
Category: feature » support
mikeryan’s picture

Status: Active » Closed (fixed)

Please do not reopen long-closed issues with related questions - open a fresh issue specific to your problem.

If you look at the migrated user through the admin UI, you'll see that they do have the 'authenticated user' role. Drupal does not store the authenticated role in users_roles, since every registered account has that role implicitly. All is as it should be.