Problem/Motivation

If you try to update a Group role definition (to change the associated role for instance), you can't because a constraint error is raised.

Steps to reproduce

* Create a group type,
* Add a group role, give a name, set the outsider scope, pick a role, save it
* Edit the group definition, change the target role, try to save.
* A violation constraint is raised:
"The xxxx group type already has a group role within the outsider scope for the yyyyy global role".

That's annoying! :)

Proposed resolution

Patch the constraint to let users edit group roles.

Issue fork group-3311119

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Artusamak created an issue. See original summary.

artusamak’s picture

Status: Needs work » Needs review

The issue was that the machine name of the group role ID was incorrect. Check MR for details.

The condition may not be written the best way, please update the statement if necessary. ;-)

artusamak’s picture

It looks like it's more complicated than that. The $group_role->id() may return the machine name OR the machine name prefixed by the group type.

lobsterr’s picture

Status: Needs review » Needs work
Related issues: +#3310499: Impossible to save group role

I came with the same idea, but this approach wont work with roles created programmatically. They can have different IDs. My idea is to set the prefix for roles in the preSave method and check if it is already there or not.
Also implement the method for prefix similar to this: https://git.drupalcode.org/project/group/-/blob/3.0.x/src/Entity/Storage/GroupRelationshipTypeStorage.php#L132

artusamak’s picture

It looks like an architectural issue to have an id() method not being consistent for the value it returns. :/

lobsterr’s picture

It happens, because we want to have id unique per group type and we want to have group type prefix there. That is why I propose to do it in one place on preSave and use a single method like "getRelationshipTypeId" to get a correct id for the Role.

kristiaanvandeneynde’s picture

This fixes things:

        if (!$group_role->isNew() && count($existing_pairs) === 1 && reset($existing_pairs) == $group_role->getOriginalId()) {

Re #6 constraints get called from all over the place, including (and most likely) forms. In GroupRoleForm, when validation runs, the ID is not yet complete. For all intents and purposes the group role ID is consistent outside of the role form.

Switching the code to getOriginalId() is the least impactful way of fixing this bug. A browser test would be awesome, if anyone could write one that visits the role form, saves a new role, then visits the edit form and tries to save again, that would be awesome.

kristiaanvandeneynde’s picture

Status: Needs work » Needs review
StatusFileSize
new1.15 KB

Could write the test as a followup and cover the entire form in one go.

lobsterr’s picture

It is a quite possible, that in some cases the roles can be create programmatically and in this case user can give any id to the role.
For exmaple:

    $group_role = GroupRole::create(
      [
        'id' => 'mymymy',
        'label' => 'mymymy',
        'scope' => 'outsider',
        'global_role' => 'administrator',
        'group_type' => 'gt',
      ]
    );
    $group_role->save();

As result we get a warning when edit this role:

Warning: Undefined array key 1 in Drupal\group\Entity\Form\GroupRoleForm->form() (line 43 of modules/contrib/group/src/Entity/Form/GroupRoleForm.php).

From other point of you GroupRole is config entity, we don't create config entities on the production environment (except webforms).

This what I was talking about in the chat. That is why I wanted to handle it is on the preSave. So, we will always will have the same format of IDs for the roles, generated based on ID and group type ID.

kristiaanvandeneynde’s picture

StatusFileSize
new3.32 KB

Okay, the whole ID changing is deliberately a form only behavior. So let's keep it there. You are right that the form did not support manually created roles (via code), so let's just simplify the form:

  • New roles via UI get group type prefixed
  • Existing roles via UI get nothing special done to them

Should leave all existing roles alone then.

lobsterr’s picture

Status: Needs review » Needs work

@kristiaanvandeneynde, I got an error, when edit any role create through UI:

"The machine-readable name must contain only lowercase letters, numbers, and underscores.", This what we tried to avoid by replacing ID:

    if ($group_role->id()) {
      [, $group_role_id] = explode('-', $group_role->id(), 2);
    }

But this code was removed

kristiaanvandeneynde’s picture

Yeah the patch was a quick POC, might have missed sth. The goal remains the same, though: keep the form-specific stuff limited to the form. Any code outside of the form should not be aware of it.

kristiaanvandeneynde’s picture

Status: Needs work » Needs review
StatusFileSize
new3.6 KB

This just turns existing roles' ID into a value field. Doesn't show in the UI at all any more as we don't allow changing it either way. No more ID voodoo other than new roles not having to type the group type ID (and it getting saved in the submit handler). Existing roles don't get any special behavior.

lobsterr’s picture

StatusFileSize
new7.33 KB
new4.13 KB

Everything is fine now. I added a few tests to cover all cases, what we have here.

kristiaanvandeneynde’s picture

Status: Needs review » Fixed

Thanks for the tests!

Status: Fixed » Closed (fixed)

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