Problem/Motivation

If you try to update any configurable actions that are created by the user module, like 'Add ROLE to selected users', you will hit a validation error with the machine name.

Steps to reproduce:

1. go to admin/config/system/actions
2. configure the 'Add the Administrator role to the selected users' action
3. Try to save it
4. You will see a validation error on the machine name field as the config name is 'user_add_role_action.administrator'

Proposed resolution

Either change the ID for the created action entities to not contain a '.' character to namespace them OR expand the machine name element to handle/allow dots, or make this configurable. I don't think it allows for this currently?

Remaining tasks

User interface changes

API changes

Data model changes

Comments

damiankloip created an issue. See original summary.

jeremy’s picture

Status: Active » Needs review
StatusFileSize
new799 bytes

Perhaps the simplest solution is to simply allow the periods. Patch attached.

damiankloip’s picture

StatusFileSize
new622 bytes
jeremy’s picture

StatusFileSize
new746 bytes

Adding updated error text to reflect that with this patch periods are allowed too.

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Allowing periods makes sense to me. Should we add a test here to avoid future regressions?

strykaizer’s picture

Assigned: Unassigned » strykaizer

Writing test

strykaizer’s picture

Assigned: strykaizer » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new963 bytes
new1.67 KB

Test only and patch with code from #4 attached

The last submitted patch, 7: TEST-ONLY-SHOULD-FAIL_actions_created_in-2553765-7.patch, failed testing.

catch’s picture

Issue tags: +D8 upgrade path

Will this also need an upgrade path if the action was already saved with the .?

The last submitted patch, 7: TEST-ONLY-SHOULD-FAIL_actions_created_in-2553765-7.patch, failed testing.

damiankloip’s picture

I don't think so, unless I'm missing something (highly probable). This just changes the validation, so ones saved with a '.' are fine, it just means you can now edit them?

kristiaanvandeneynde’s picture

Status: Needs review » Needs work

The user module seems to use a period to "namespace" its actions to keep people from creating an action with the same machine name. This is because it will delete any associated actions when a user role is deleted.

If you happened to be unfortunate enough to:

  • Create an action called user_add_role_action.myrole
  • Create a role called my_role (no action will be created)
  • Delete the role called my_role

Your custom action 'user_add_role_action.myrole' would be deleted by the user module even though it was never created by that module! I therefore suggest we do not allow the use of periods in the machine name, but instead disable the machine name field when editing so it doesn't need to run through validation.

heykarthikwithu’s picture

Status: Needs work » Needs review
StatusFileSize
new533 bytes

As per #12,
machine name doesn't need to run through validation, if at all this not created newly.

Status: Needs review » Needs work

The last submitted patch, 13: 2553765-13.patch, failed testing.

heykarthikwithu’s picture

Status: Needs work » Needs review
StatusFileSize
new570 bytes

re-rolled #13 patch.

kristiaanvandeneynde’s picture

Status: Needs review » Needs work

The element should be disabled, not just its validation. Right now, you allow anything to be entered into the machine name field.

Consider using the #disabled, #value and #element_validate key.

kristiaanvandeneynde’s picture

heykarthikwithu’s picture

Status: Needs work » Needs review
StatusFileSize
new529 bytes
new530 bytes

machine name will be disabled if it is not new.
'#disabled' => !$this->entity->isNew(),
and also will not be validated if machine name is not new.
'#element_validate' => !$this->entity->isNew() ?: [],

Status: Needs review » Needs work

The last submitted patch, 18: 2553765-18.patch, failed testing.

kristiaanvandeneynde’s picture

From the FAPI 8 reference:

Values: An array of function names to be called to validate this element (and/or its children).

So '#element_validate' => !$this->entity->isNew() ?: [], won't work. It assigns TRUE to the property when the entity isn't new and an empty array when it is. You should leave the property alone when the entity is new and specify an empty array when it isn't.

heykarthikwithu’s picture

Status: Needs work » Needs review
StatusFileSize
new572 bytes
new566 bytes

leaving the property alone when the entity is new and specify an empty array when it isn't.

kristiaanvandeneynde’s picture

StatusFileSize
new1.22 KB

Looks good, but this is the kind of "weird" code that gets tossed out in another issue unless you document why it was added in the first place. Attached is a patch with documentation added.

strykaizer’s picture

Hmm, I think we should always validate the machinename, even if its disabled. So #12 is prolly not an option, as disabled form items are also submitted (and therefore can be altered by javascript etc.)

Feel free to correct me if I'm wrong ;)

kristiaanvandeneynde’s picture

From FormBuilder::handleInputElement()

   // Setting #disabled to TRUE results in user input being ignored regardless
    // of how the element is themed or whether JavaScript is used to change the
    // control's attributes. However, it's good UI to let the user know that
    // input is not wanted for the control. HTML supports two attributes for:
    // this: http://www.w3.org/TR/html401/interact/forms.html#h-17.12. If a form
    // wants to start a control off with one of these attributes for UI
    // purposes, only, but still allow input to be processed if it's submitted,
    // it can set the desired attribute in #attributes directly rather than
    // using #disabled. However, developers should think carefully about the
    // accessibility implications of doing so: if the form expects input to be
    // enterable under some condition triggered by JavaScript, how would someone
    // who has JavaScript disabled trigger that condition? Instead, developers
    // should consider whether a multi-step form would be more appropriate
    // (#disabled can be changed from step to step). If one still decides to use
    // JavaScript to affect when a control is enabled, then it is best for
    // accessibility for the control to be enabled in the HTML, and disabled by
    // JavaScript on document ready.
    if (!empty($element['#disabled'])) {
      if (!empty($element['#allow_focus'])) {
        $element['#attributes']['readonly'] = 'readonly';
      }
      else {
        $element['#attributes']['disabled'] = 'disabled';
      }
    }

    // With JavaScript or other easy hacking, input can be submitted even for
    // elements with #access=FALSE or #disabled=TRUE. For security, these must
    // not be processed. Forms that set #disabled=TRUE on an element do not
    // expect input for the element, and even forms submitted with
    // self::submitForm() must not be able to get around this. Forms that set
    // #access=FALSE on an element usually allow access for some users, so forms
    // submitted with self::submitForm() may bypass access restriction and be
    // treated as high-privilege users instead.
    $process_input = empty($element['#disabled']) && (($form_state->isProgrammed() && $form_state->isBypassingProgrammedAccessChecks()) || ($form_state->isProcessingInput() && (!isset($element['#access']) || $element['#access'])));
kristiaanvandeneynde’s picture

Playing the devil's advocate here, but if core created these actions and core will delete them when the user roles are deleted: What good will editing them do? They may end up being deleted automatically because it would make sense to do so if they weren't modified. However, if you did modify them, an automatic deletion may really hurt your site.

Aside from the patch fixing the issue at hand, there's other approaches to this:

  1. Do not edit the actions created by core. This seems unacceptable because end users can't guess which ones can and can't be edited.
  2. Mark some actions as "fixed", i.e. not editable. This fixes the original report and the issue raised in approach 1. If you'd want an action that adds or removes mutliple roles, you could always create your own action.

That being said, implementing a system to mark action entities as fixed would require a lot more code than what the current patch contains.

strykaizer’s picture

Oh, thanks for that!

In that case, I can live with the change suggested. Its not the most pretty (core generating machinenames with dots, but not allowing them to be created), but neither is allowing dots and having certain actions (in a rare case) automagicly deleted.

Another option might be removing the dots in the generated "add x role to selected user" machinename, and delete those specific generated actions on role_deletion by using a custom event/hook and query. That way we keep machinenaming consistency and do not have a special case for Actions.

kristiaanvandeneynde’s picture

Status: Needs review » Closed (duplicate)