As I said in the other issue I am working on hard coding user inheritance for my use case since I have to move forward but I've run into a bit of a snag when trying to grab the roles as they are revoked/granted.

My initial thought was to act on a user being added to a group so I figured I would use hook_entity_insert on group_membership entities but the membership didn't contain roles at that point like I expected it to. I'm only using gadd to allow members into groups so the offending code snippet appears to be

function gadd_add_member_form_submit($form, &$form_state) {
  global $user;

  $values = array(
    'gid' => $form_state['build_info']['args'][0]->gid,
    'uid' => $form_state['values']['uid'],
    'added_on' => REQUEST_TIME,
    'added_by' => $user->uid,
  );

  // Create and save the membership.
  $group_membership = entity_create('group_membership', $values);
  $group_membership->save();

  // Grant the predetermined roles.
  $group_membership->grantRoles(array_filter($form_state['values']['roles']));

  // Show a confirmation message.
  drupal_set_message(t('Added %user', array('%user' => $form_state['values']['user'])));
}

When I added roles to the values array it broke things. Looking into the code I can't tell why it breaks things so that plan is out the window. Though in my searches I did stumble upon the addMember() function which I think should be called to add the member instead of the code being used.

Since that wasn't working I figured well I can just propagate the new membership with no roles all the way down using entity_insert and since roles aren't added on creation of a membership they must trigger a hook_entity_update where I can generically act on all roles being granted/revoked. The problem I ran into here is that granting or revoking roles doesn't trigger a hook_entity_update like I expected it would. Which leaves me stuck.

Any suggestions on how to work around this? I'm still picking up drupal and php so perhaps I am missing another way that this could be accomplished but this seemed to me like the way to go about it.

Comments

ctrlADel’s picture

Issue summary: View changes
kristiaanvandeneynde’s picture

First off, I think for someone who just started out with php and Drupal, you're doing an excellent job figuring out what functions to use.

The following things came up while reading your post:

  • GroupMembership::grantRoles() indeed doesn't trigger a save. As the code currently stands, it would cause an endless loop if it were to try and save the membership.
  • Perhaps GroupMembership::grantRoles() and GroupMembership::revokeRoles() should only manipulate the roles property and then trigger a save. The problem is that a GroupMembership entity doesn't need to be saved to change the attached roles. So it all comes down to what you are expecting.
  • A GroupMembership entity needs to exist before we can use GroupMembership::grantRoles(), but GroupMembershipController::save() handles this for you when trying to create a membership with a roles property.
  • I could adjust the code in gadd and ginvite to incorporate this, but keep in mind that you should never rely on a new GroupMembership entity having the roles already. I simply cannot guarantee everyone will create their GroupMembership entities with a prefilled roles property.

Regarding Group::addMember(): That's a shorthand to add members with preset roles. It doesn't take care of setting custom properties such as invited_by, though. The cool thing is it can also update member roles. Perhaps it should be rewritten to drop the 'update' functionality and accept more GroupMembership parameters instead. Semantically I can see that making more sense.

ctrlADel’s picture

I think you are mistaking my ability to click around/google things as 'skill'.

The main thing I was getting at is that there is no way to tell when roles have been granted/revoked at any stage of a membership which makes hardcoding user inheritance and keeping roles in sync pretty much impossible. I solved the impossible though by doing what you said I shouldn't. I added $this->original = entity_load_unchanged('group_membership',$this->mid); to the very top of the GroupMembership::grantRoles() and GroupMembership::revokeRoles() and added $this->save(); to the very bottom of both and they didn't trigger infinite loops. So now they both trigger saves and provided an array of previous and current roles so I can determine what has changed.

With that solved I am well on my way to getting this user inheritance working.

kristiaanvandeneynde’s picture

Status: Active » Fixed

I've reworked the way the module handles the granting and revoking of roles. A GroupMembership is now always saved when either action takes place, because you are in essence altering the membership. (Even though a save isn't technically needed.)

Have fun with it :)

ctrlADel’s picture

Cheers. I just patched and it doesn't appear to have broken anything.

  • Commit aa295cc on 7.x-1.x, inheritance by kristiaanvandeneynde:
    Issue #2236269 by Vulsutyr, kristiaanvandeneynde: Acting on roles being...

Status: Fixed » Closed (fixed)

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