Migrate Organic Groups Membership

image

In a previous blog, we discussed Function1’s latest Drupal project: migrating a Jive system running on PostgreSQL database to Drupal.  The target Drupal site was using the Organic Groups module to organize content (the usual node types: blog, story, page, discussion, etc.) in Spaces (the Organic Group lingo for a “Group”). In migrating content to Drupal we used the migrate module. Adding space/group memberships was a little tricky and we thought of sharing what we learned.

Let’s quickly state the obvious:

Migrate Users

That was straight forward and plenty of documentation on that. Just make sure you instantiate the "MigrateDestiantionUser()" object as in:

$this->destination = new MigrateDestinationUser($options);

Actually contrary to common belief, to import the users’ avatars, you don't need two migration classes: one to import the avatars, followed by a second migration to import the users while assigning the avatars to the user node from the prior migration. Instead, you can assign the avatars to the users in one step while migrating the users as in:

$this->addFieldMapping('name', 'username');
$this->addFieldMapping('field_user_display_name', 'displayname');
$this->addFieldMapping('mail', 'email');
$this->addFieldMapping('status', 'userenabled');
$this->addFieldMapping('created', 'creationdate');
$this->addFieldMapping('timezone')->defaultValue('America/New_York');
$this->addFieldMapping('avatar', 'avatarfile');
 
while "avatar" is a Drupal field of tpe "file"; because the alternative would be referencing a prior avatar migration from the users’ migration (an extraneous step) as in:
 
$this->addFieldMapping('avatar', 'avatarfile')->sourceMigration(array('AvatarsMigration'));

Migrate Groups

That was also straight forward, instantiate the "MigrateDestinationNode()" and pass the machine name for the node of type “space” as in:

$this->destination = new MigrateDestinationNode('space_name'); 

Set the group access to either "public" or "private" where "public" = ‘0’ and "private" = ‘1’ as in:

$this->addFieldMapping('group_access', 'grouptype');

If you need to assign a featured image to the space, you can do something like:

$this->addFieldMapping('featured_image', 'featured_image');
$this->addFieldMapping('featured_image:file_class')->defaultValue('MigrateFileUri');
$this->addFieldMapping('featured_image:destination_dir')->defaultValue('public://');
$this->addFieldMapping('featured_image:file_replace')->defaultValue('FILE_EXISTS_REPLACE');
$this->addFieldMapping('featured_image:preserve_files')->defaultValue(FALSE);
$this->addFieldMapping('featured_image:source_dir')->defaultValue($import_path);

Set Groups Membership

After migrating the users and spaces we can then assign the organic groups memberships. Obviously the source will need to include the foreign keys for users and groups and it is just a 2-column data source and the mapping will need to reflect that as in:
 
$this->map = new MigrateSQLMap($this->machineName,
            array(
                'groupid' => array(
                    'type' => 'int',
                    'unsigned' => TRUE,
                    'not null' => TRUE,
                    'description' => 'Group ID',
                    'alias' => 'GroupsMembers',
                ),
                'userid' => array(
                    'type' => 'int',
                    'unsigned' => TRUE,
                    'not null' => TRUE,
                    'description' => 'User ID',
                    'alias' => 'UsersMembers',
                ),
            ),
            MigrateDestinationOGMembership::getKeySchema()
);

and then instantiate the "MigrateDestinationOGMembership()" class as in:

$this->destination = new MigrateDestinationOGMembership();

We then need to set the spaces and users membership as in:

// Groups Reference
$this->addFieldMapping('group_type')->defaultValue('node');
$this->addFieldMapping('gid', 'groupid')->sourceMigration(array('GroupsMigration'));

// Users Reference
$this->addFieldMapping('entity_type')->defaultValue('user');
$this->addFieldMapping('etid', 'userid')->sourceMigration(array('UsersMigraton')); 

But that was not sufficient and it turned out that we needed to set the user's state to "active" member by setting the OG_STATE_ACTIVE flag and that was the missing piece that we had to figure out.

$this->addFieldMapping('state')->defaultValue(OG_STATE_ACTIVE);

Lastly, we can set basic space properties:

// Set user group membership type: Member = '0' and Admin = '1'
$this->addFieldMapping('is_admin', 'membertypeid');
// Set the space creation date
$this->addFieldMapping('created', 'creationdate');
 
As seen, migrating content from a legacy content management system (CMS) is relatively simplified with the migrate module, especially when the source data is in some database structure (Oracle, MSSQL, PostgreSQL, or MySQL). Even when migrating a flat structure (CSV) to Drupal nodes, it is worthwhile importing it first in some database store and use that as source instead. That extra step is not a wasted effort since it will payoff later, especially if you’ll need to write custom views and perform extraneous data manipulation on the source data. 
 
Hopefully that was helpful and if you have any questions, feel free to contact us.
 
Thanks.

Subscribe to Our Newsletter

Stay In Touch