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
Issue fork distributions_recipes-3302666
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:
- 3302666-pluralize
changes, plain diff MR !32
- 3302666-add-the-ability
changes, plain diff MR !30
Comments
Comment #3
alexpottComment #6
alexpottUpdated issue summary for latest approach.
Comment #7
alexpottComment #8
bircherVery nice UX!
For cases where the pluralization can not be done by simply adding a
sor 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
Comment #9
bircherActually it might even be better to just allow the whole pluralized string. In most cases a s suffices.
so
Comment #11
alexpott@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.
Comment #12
alexpottWe can use \Symfony\Component\String\Inflector\EnglishInflector::pluralize to generate plurals so the default TRUE will normally suffice.
Comment #14
alexpottMerged this - going to update the recipe docs now.