Problem/Motivation

The ConfigActions API added in #3284025: Add configuration actions API allows methods on config entities to be attributed and made callable via the config actions API.

A classic use case will be the ability to add permissions to a user role using \Drupal\user\Entity\Role::grantPermission() and the entity_method:user_role:grantPermission action. The signature of this method is:

  /**
   * Grant permissions to the role.
   *
   * @param string $permission
   *   The permission to grant.
   *
   * @return $this
   */
  public function grantPermission($permission);

Therefore we can only add one permission at a time. To translate this into a recipe it looks something like:

config:
  actions:
    user.role.editor:
      grantPermission: 'delete any article content'

It would be ideal if we can tell the config action system to turn the following structure

config:
  actions:
    user.role.editor:
      grantPermission:
        - 'delete any article content'
        - 'edit any article content'

into multiple calls to ::grantPermission() to add the two permissions.

Proposed resolution

Allow the \Drupal\Core\Config\Action\Attribute\ActionMethod attribute to carry extra data about how to handle arrays of arguments. Add logic to \Drupal\Core\Config\Action\Plugin\ConfigAction\Deriver\EntityMethodDeriver and \Drupal\Core\Config\Action\Plugin\ConfigAction\EntityMethod to support this.

The EntityMethodDeriver adds an extra pluralized actions for all entity method where the pluralize attribute property is not set to false. The default behaviour is to add an additional action with the letter 's' appended. The pluralized name can be completely overridden by setting the attribute property to a string.

Methods can configure this on the attribute itself:

  #[ActionMethod(pluralize: 'addRoleMultiple')]
  public function addRole($role) {

This will create an action called addRoleMultiple as well as the normal addRole action

The default behaviour will use \Symfony\Component\String\Inflector\EnglishInflector::pluralize() to generate a plural form.

  #[ActionMethod()]
  public function grantPermission($permission) {

This will create an action called grantPermissions as well as the normal grantPermission action. Something like addProperty will become addProperties.

To disable pluralized actions

  #[ActionMethod(pluralize: FALSE)]
  public function setRole($role) {

This will only create an action called setRole.

For recipes this means that granting multiple permissions to a role becomes:

config:
  actions:
    user.role.editor:
      grantPermissions:
        - 'delete any article content'
        - 'edit any article content'

Remaining tasks

User interface changes

API changes

Data model changes

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

alexpott created an issue. See original summary.

alexpott’s picture

Issue summary: View changes
Status: Active » Needs review

alexpott’s picture

Issue summary: View changes

Updated issue summary for latest approach.

alexpott’s picture

Issue summary: View changes
bircher’s picture

Very nice UX!

For cases where the pluralization can not be done by simply adding a s or another word, I guess a developer can always add a second method to their config entity and set #[ActionMethod(pluralize: FALSE)] on both and then just foreach call the singular method. This gives all the control but makes the plural case easy in most cases.

The alternative would be to not only specify the addition but the whole plugin shorthand

bircher’s picture

Actually it might even be better to just allow the whole pluralized string. In most cases a s suffices.
so

#[ActionMethod(pluralize: 'addProperties')]
public function addProperty($role) {}

alexpott credited bircher.

alexpott’s picture

Issue summary: View changes

@bircher had a great idea to make the pluralize accept TRUE or a complete override and not just an append. Updated the code and issue summary to reflect this.

alexpott’s picture

Issue summary: View changes

We can use \Symfony\Component\String\Inflector\EnglishInflector::pluralize to generate plurals so the default TRUE will normally suffice.

  • alexpott committed 4db4723 on 10.0.x
    Issue #3302666 by alexpott, bircher: Add the ability to call the same...
alexpott’s picture

Status: Needs review » Fixed

Merged this - going to update the recipe docs now.

Status: Fixed » Closed (fixed)

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