The problem: During Drupal admin work, for example after importing a bulk of posts from another source, you might want to assign many of them to Drupal group (provided by the Organic Groups module). In the admin backend, there is no other way than editing every node individually and entering the group's name into the "Groups: Your groups" or "Groups: Other groups" fields. There has to be a faster way for this, though.

My solution with SQL

I'm going to solve this on the database level, as all the other options do not (yet) work for me, see below.

  1. Create a backup of your Drupal database.
  2. Save this little script into a new PHP file on your server:

    <?php
      // PHP Script to generate a set of SQL statements that assign a set of posts
      // to a group in Drupal 7.

      // Node ID of the group to assign the nodes below to.
      $group_id = "366";

      // Node IDs of the nodes to assign to group with node ID $group_id.
      // (One mode to get the right set relatively fast is by copying the "System" column
      // from the "URL aliases" Drupal view at http://example.com/admin/config/search/path .)
      $node_ids = array(183, 357, 358, 360, 361); //
     
      foreach ($node_ids as $node_id) {
        echo("INSERT
          INTO og_membership (type, etid, entity_type, gid, group_type, state, created, field_name, language)
          VALUES ('og_membership_type_default', $node_id, 'node', $group_id, 'node', 1, 1359419168, 'og_group_ref', 'en');\n\n"
        );
      }
    ?>

  3. Adapt the script to contain the proper group node ID and the proper node IDs for nodes you want to assign to this group.
  4. Execute the script with: php generate-bulkassign-sql.php.
  5. Clear the Drupal cache by calling this in your website's document root directory: drush cc. Else, you might not see some changes as Drupal would read from the cache instead where possible.

Non-Working or Should-Be-Working Alternatives

Views Bulk Operations and og_actions

Views Bulk Operations is a Drupal module that can execute a configurable action on a selected set of content nodes. The node-to-group mass assignment should be possible together with the og_actions module, providing relevant VBO actions for groups, and whose functionality is said to be integrated into the core og (Organic Groups) module as of Drupal 6 [source]. However, the relevant action "Modify Group Content" action resp. "Add the node to the specified group…" action did not show up for me. So there seems to be no pure UI way (for me) to mass-assign content to a group in Drupal 7.

Views Bulk Operations and "Execute arbitrary PHP script"

There is another way to use Views Bulk Operations: together with own PHP code that performs the action on every entity (here: node) it is called on. An introduction to this technique is at "Copying data between fields with VBO".

In "Administration -> Configuration -> System -> Actions" (http://example.com/admin/config/system/actions/manage) there is a way to create an advanced action "Execute arbitrary PHP script", specifying your own PHP code to be executed on every node you call this action on. However any action I would create this way would not show up in the list of actions on top of the content items list in the admin backend, where I would normally select some content items, select that action from the dropdown and click "Update". Other advanced actions that I created did however show up, for example those created via the convert module.

Once the action shows up correctly, one would use this PHP code to get the action done (note: untested, maybe still buggy):

<?php
  // Script to assign one node to a pre-defined group via "Execute arbitrary PHP script" action.
  //
  // Intended to be used with the VBO feature, see: http://drupal.org/node/570220
  // PHP code to be copied into the "Execute arbitrary PHP script" field
  // without the <?php ? > code wrapper!

  $gid = 6; // Node ID of the group to assign content to.

  // Source and explanations: http://drupal.org/node/1249396#comment-6778598
  // API docs: http://api.drupalize.me/api/drupal/function/og_group/7
  og_group($gid, array('entity' => $entity));

  node_save($entity);
?>

PHP script to assign all nodes to a group at once

The most comfortable way to run a short own script inside the Drupal environment is drush php-script. It will bootstrap the Drupal context for you, so you have access to Drupal classes and functions just as when inside a custom module. See also this introduction to drush php-script.

I tried to run this PHP code with the drush php-script technique, but so far it does not work ("Error: Class name must be a valid object or a string in <drupal-dir>/includes/common.inc line 7752"):

<?php
  // Script to assign a set of nodes to a pre-defined group.
  //
  // Intended to be used with the "drush php-script" command.

  $group_id = 1; // Node ID of the group to assign content to.
  $group_type = "node"; // Entity type of this group, for example "node", "comment".

  $node_ids = array(
    3, 238, 346, 123
  );

  foreach ($node_ids as $node_id) {
    $entity = node_load($node_id);

    // Source and explanations: http://drupal.org/node/1249396#comment-6778598
    // API docs: http://api.drupalize.me/api/drupal/function/og_group/7
    og_group($group_id, array('entity' => $entity));

    node_save($entity);

    // $is_member_after = og_is_member($group_type, $group_id, $entity_type = "node", $entity, $states = array(OG_STATE_ACTIVE));
    // echo("Assigned node $node_id to group $group_id. Member state now: $is_member_after.");
  }

?>

Automating the manual form editing with drupal_form_submit()

This is a new idea that I did not yet try. Like above, one would use drush php-script to execute a little PHP script, but the script would fill and submit the "node edit" form instead of dealing with the Organic Groups API directly. There is a working example for creating groups this way (not assigning nodes to groups though).

3 thoughts on “How to bulk assign nodes to groups in Drupal 7?

  1. Good solution, thank you.
    I have about 10000 nodes, and I need to put them into 5 different groups. All I have as mark for group is the path alias (http://mysite/groupname/node). I try make view with path in the fields and execute “Add the node to the specified group…” action depends on path, but that didnt work. I would like to try your solution with php file, but I need to filter nodes by its path alias (http://mysite/groupname1/node1 to group1, http://mysite/groupname2/node2 to group2). Is it possible?

  2. Sure it’s possible. My script expects an array of node IDs in $node_ids, so you would have to convert your path aliases to node IDs first with some Drupal function (never did this, but it’s certainly possible). But note that my script in the “PHP script to assign all nodes to a group at once” section did not yet work with drush, so it’s just a stub for your own developments.

Leave a reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>