This has some relation to http://drupal.org/node/1204358

hook_og_membership_insert is described as "This hook is invoked after the OG membership is inserted into the database." But running user_save from within this hook reveals that og isn't quite done yet because it will save the user object again and overwrite any changes that were made. This specifically came up while attempting to add a role to the user when that user is added to a group.

To test:
1. Create a test module with an implementation of hook_og_membership_insert
2. Load the user object if the etid is a user.
3. Change some property of the user and run user_save.
4. In the interface, add a user to a group.
5. Note that the user property has not changed.
5. Further confirmation of the issue is seen if a hook_user_update is used. You can dpm the $account info and see that this hook fires twice and that the user_save in hook_og_membership_insert fires before og resaves the user object.

Example code.

function testmodule_og_membership_insert($membership) {
  if ($membership->entity_type == 'user') {
    $account = user_load($membership->etid);
    user_save($account, array('name' => 'sally'));
  }
}

/**
 * Implements hook_user_update().
 */
function testmodule_user_update(&$edit, $account, $category) {
  dpm($account);
}

Comments

loze’s picture

I'm trying to do the same thing. Did you ever figure this out?

lliss’s picture

I think I came up with some ridiculous work around. Let me dig into that code and see if I can find it.

lliss’s picture

As a side note, I can't believe that this has been un-addressed for more than a year.

hefox’s picture

Opened a support request for this, #2032797: How to change an entity during hook_og_membership_*, found a semi workaround (edit the og field info to add/remove the membership group)

ericras’s picture

Version: 7.x-1.3 » 7.x-2.x-dev
RoySegall’s picture

Indeed the field of the membership on the user is empty but the membership of the user is kept.

RoySegall’s picture

Try to use this:

function testmodule_og_membership_insert($membership) {
  if ($membership->entity_type == 'user') {
    $membership->skip_membership = TRUE;
    $account = user_load($membership->etid);
    user_save($account, array('name' => 'sally'));
  }
}
jlcerrada’s picture

Issue summary: View changes

Hi folks, has anyone found a solution for this problem?

indigoxela’s picture

Hi,
try to register an additional callback to make sure og has really finished its job.

I ran into a similar problem and the only solution was drupal_register_shutdown_function()

A code sample:

<?php
function mymodule_og_membership_insert($og_membership) {
  drupal_register_shutdown_function('_mymodule_postinsert', $og_membership);
}
function _mymodule_postinsert($og_membership) {
  // do whatever you need here...
}
?>
Sophie.SK’s picture

I've managed to get this working with hook_og_membership_insert() by using entity_metadata_wrapper():

function mymodule_og_membership_insert($og_membership) {
  // Get the user being added to the group.
  $account = user_load($og_membership->etid);
  $user_wrapper = entity_metadata_wrapper('user', $account);

  // Update a profile field.
  $user_wrapper->field_newsletter_subscription->set(1);

  // Save the user.
  $user_wrapper->save();
}

However, if I add the same code to hook_og_membership_delete, the insert code gets run again, before the delete - thereby causing a new membership to be created as the old one is deleted. The user doesn't get removed from the group.

I suspect that's something to do with my $user_wrapper->save() acting on an entity that still has the membership attached to it rather than an updated one.

Will do some further investigation ...