Problem/Motivation
In user_user_role_insert
we create actions per user role being created. We do this like this:
$action = entity_create('action', array(
'id' => $add_id,
'type' => 'user',
'label' => t('Add the @label role to the selected users', array('@label' => $role->label())),
'configuration' => array(
'rid' => $role->id(),
),
'plugin' => 'user_add_role_action',
));
$action->trustData()->save();
At first sight the t()
looks wrong because it means config will be saved with the translated text - but actually I think this is fine since the configuration entity will have the language that the user has when they create the role. But what is more problematic is saving the escaped role label. This causes two problems - double escaping on admin/people
if the role label contains an &
and also potentially getting out of sync with the role label if that changes.
Proposed resolution
no idea yet
Remaining tasks
Find a solution.
User interface changes
None
API changes
?
Data model changes
?
Why is this an RC target?
- Escaping the role label during the creation of the action label leads to double escaping. This patch fixes 27 out of the 32 fails found by #2571065-14: Find escaping due to Twig autoescape. Without this patch going in we can't implement some sort of generic double escaping test for all of our WebTestBase tests.
- Not keeping the action label in sync with the action label could result in a very confusing UI experience (image if role labels are swapped - yes that would be dumb but we all do dumb things sometimes)
- The fix creates a generic solution for actions to add arguments for it's labels. Given how actions are created based on other config entities this is likely to be needed again
Comment | File | Size | Author |
---|---|---|---|
#43 | 2597608-nr-bot.txt | 132 bytes | needs-review-queue-bot |
#20 | 2597608-20.patch | 17.31 KB | alexpott |
#20 | 15-20-interdiff.txt | 1.29 KB | alexpott |
#15 | 2597608-15.patch | 17.24 KB | alexpott |
#15 | 14-15-interdiff.txt | 1.8 KB | alexpott |
Comments
Comment #2
alexpottHere's a stab at a solution that lets you keep the action label in sync with the role label.
There is one problem though if you install the Action module this lets you edit the label but because of the way
ActionFormBase
adds the label and then delegates to the plugin - the plugin can't affect the label form element - which we need to do otherwise the user will save the version with the label replaced.Comment #3
alexpottThis will solve a number of the escaping issues discovered by #2571065: Find escaping due to Twig autoescape which is how I came across this issue.
Comment #5
alexpottSo this makes the form work - but atm you actaully can't save such an action because of dots in the machine name!
Comment #7
alexpottFixing the tests
Comment #9
alexpottFix the last test fail and adding tests.
Comment #10
joelpittetI may be missing something here but doesn't this need the placeholder args?
Comment #11
alexpott@joelpittet you are missing something!
This does the replacement when the label is used - not when the configuration entity is saved - thereby allowing the role label to change and be reflected in the action label.
Comment #13
joelpittetOh wow that makes things complicated, I would have tried to fix that... bizarre.
Comment #14
alexpottImproved comments to explain the point @joelpittet raises in #10.
Also since calling
parent::label()
in a method other than label is super ugly - wrapped this in a protected method. The only reason do this is because the labelling system is super flexible... and alterable on the entity type...... if we didn't do this we could just do
$this->label
and access the property - and maybe we should just do this - sinceEntityTypeInterface::getLabelCallback()
is deprecated.Comment #15
alexpottThe idea of using
$this-label()
in #14 is a good one.Comment #16
dawehnerthat might be dawehner english but proper alexpott english, I'm not sure about that
This is technically an API change, right?
So yeah I'm wondering in which way we should separate the stored value from the resolved value ... maybe an getStoredValue() method, maybe don't change the label() behaviour but call out to a new method ...
Nitpick: its also xss filtered here
Comment #17
alexpottComment #18
xjmSo this is definitely a bug, but since it's confined to the creation and update of certain actions, I personally don't think it needs to be an RC target.
Comment #19
alexpottAdded information about why this should be an RC target.
Comment #20
alexpottRe #16
$this->label
to get the stored version is totally fine.Comment #21
dawehnerWell, its protected ...
Comment #22
effulgentsia CreditAttribution: effulgentsia at Acquia commentedThis makes sense as an RC target to me, for the reasons mentioned in the issue summary. In a conversation today, @xjm agreed as well thanks to the clarifications since #18.
Comment #23
effulgentsia CreditAttribution: effulgentsia at Acquia commentedI don't think we should add this to ActionInterface. Instead, I think we should make a new interface, such as
FormattableLabelInterface
orLabelWithPlaceholdersInterface
. Then action plugin implementations can opt-in to that interface or not. And it becomes a pattern we can use for other plugin types.I think we should always
PlainTextOutput::renderFromHtml()
action entity labels, not make it conditional on there being arguments.Doing the point above would allow us to remove this.
I don't like the competition of responsibility of the 'label' element between this and ActionFormBase::form(). Instead, what if we added
getLabelArgumentsDescription()
to LabelWithPlaceholdersInterface which could return the last sentence of the above description, and then ActionFormBase::form() could be responsible for setting the appropriate description based on whether the plugin implements LabelWithPlaceholdersInterface or not. That would also allow us to completely remove'original_label'
from this patch, because ActionFormBase::form() could set the default value to$this->entity->get('label')
.Comment #24
effulgentsia CreditAttribution: effulgentsia at Acquia commentedActually, maybe that's wrong. But I think we should do something differently from what the patch is doing, because the meaning of a user-entered "<" character within an action label should not depend on whether the action plugin supports label arguments or not.
Comment #25
effulgentsia CreditAttribution: effulgentsia at Acquia commentedSomething like:
might be closer to what we want, in which case, that could be conditional on $label_arguments, because the above should be a no-op when $label_arguments is empty.
In which case, I'm also unclear on why #23.3 is needed at all.
Comment #26
effulgentsia CreditAttribution: effulgentsia at Acquia commentedIf we do #25 (meaning, if the 'label' config property is intended to be interpreted as containing plain-text, not HTML), then we should also change:
to:
Because even though in this case, it might be unlikely that translators will add HTML here, the output of t() should always be treated as HTML, for consistency.
Comment #27
xjmComment #30
Julfabre CreditAttribution: Julfabre commentedUP
How can we help with the integration of this fix?
Comment #31
cilefen CreditAttribution: cilefen as a volunteer commentedConsider the last few review comments then write a patch.
Comment #40
LendudeManually tested this, and this is still an issue. I think you could easily work around this and manually set this straight in the config entity after it got created, if it wasn't for #3150316: Configured actions created by User module cannot be edited which makes this impossible through the UI currently.
Comment #43
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.