Problem/Motivation
Both BlockForm::submitForm() and EntityForm::save() save the entity.
Condition plugins with valid schemas are only correctly handled because BlockForm *saved the block twice*. Once explicitly in ::submitForm(), once in its parent ::save().
The flow was:
- condition is checked for default state, failed due to type mismatch
- saved in submitForm()
- values casted to correct type by Config::castValue
- condition is checked for default state, correctly removed
- saved in save()
Proposed resolution
In order to properly compare the values without saving the entity twice, the values must be cast before being compared.
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|
Issue fork drupal-2815829
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
Comment #2
tim.plunkettComment #4
tim.plunkettAs suspected after working on #2811519: Blocks do not appear after being placed with the Rules module enabled (or other missing schemata for Condition plugins), parts of core rely on this incorrect behavior.
Comment #5
tim.plunkettReposting the proposed fix from the other issue.
Comment #6
tim.plunkettReroll.
Comment #16
godotislate CreditAttribution: godotislate at Acquia commentedComment #17
tim.plunkettRerolling this
Comment #19
tim.plunkettSwitched to MR.
Comment #20
paulocsThis issue fixes the problem in #3114467: 'Negate' form value for condition plugins should be cast to boolean in validation. in a lower level.
Comment #21
godotislate CreditAttribution: godotislate at Acquia commentedComment #22
tim.plunkettGreat review @godotislate, thanks! I think the MR is much cleaner now.
And thanks for verifying @paulocs, that's a relief.
Comment #23
godotislate CreditAttribution: godotislate at Acquia commentedComment #26
godotislate CreditAttribution: godotislate at Digital Polygon commented@tim.plunkett Sorry, missed your last comment from months ago.
I retried with both Drupal 9.4.8 and 10.1.x-dev with Moderation Dashboard 2.1.1, and I don't see the error anymore. All other functionality seems to work correctly.
Setting back to Needs Review to kick off CI.
ETA. Looks like there'll need to be a new MR against 10.1.
Comment #28
godotislate CreditAttribution: godotislate at Digital Polygon commentedCreated new MR against 10.1 and tests passed. I'd say RTBC, but I guess it's technically my MR now.
Comment #29
bryanmanalo CreditAttribution: bryanmanalo at IOM - UN Migration commentedhttps://git.drupalcode.org/project/drupal/-/merge_requests/1456.patch I tried using this patch for 9.4.7 (and 9.4.8), but patch does not complete.
Attaching a screenshot.
Maybe I am misunderstanding how to use the new way to get patches? https://www.drupal.org/docs/develop/git/using-git-to-contribute-to-drupa...
Comment #30
smustgrave CreditAttribution: smustgrave at Mobomo commentedTesting https://git.drupalcode.org/project/drupal/-/merge_requests/2905
Checked that the tests fail without the fix and passes with the full MR.
Didn't see any merge conflicts (didn't rebase)
Comment #32
xjmComment #33
xjmLeft a few nitpicks and some questions on the MR. Thanks!
@smustgrave, how did you check that the test fails without the fix? If you did so locally, I'd paste your shell output to receive credit for that testing.
Comment #35
godotislate CreditAttribution: godotislate at Digital Polygon commentedComment #36
smustgrave CreditAttribution: smustgrave at Mobomo commentedSaving credit for @xjm for the review of MR 2905
Left some small changes on MR
Think a last step would be a CR for the new trait and it's usage.
Comment #37
godotislate CreditAttribution: godotislate at Digital Polygon commentedCR draft created: https://www.drupal.org/node/3392235
Comment #38
smustgrave CreditAttribution: smustgrave at Mobomo commentedRemoving tag.
Taking a look at the CR and it reads very well. Listing the methods is perfect I think.
Comment #39
alexpottThis is a surprising solution for a couple of reasons. We're adding a validateConfiguration() method to LazyPluginCollection and saying it needs to be called before saving but this is not really a validation. What should this method do if it gets invalid configuration? We're also adding a ConditionPluginCollection::getName() method that just seems odd. It's only there to provide a name for config schema to work. This change doesn't feel right but I've not really got an idea on how to fix this properly. The code in \Drupal\Core\Condition\ConditionPluginCollection::getConfiguration() that removes configuration if it matches the default doesn't really work the way the configuration system expects.
I guess I think the fix needs to happen on the form level as the incorrectly typed values are coming from there. This fix is currently implemented for all config entities in ConfigEntityBase::preSave().
There are two ways this makes things inconsistent:
1. Condition plugin config data is casted in ConfigEntityBase::preSave() rather than in \Drupal\Core\Config\Entity\ConfigEntityStorage::doSave()
2. Config plugins casting ignores the affects of trusting configuration data.
As said I'm not sure what the correct thing to do here is.
Comment #40
godotislate CreditAttribution: godotislate at Digital Polygon commented@alexpott
Updated the MR to do the casting at the form level (in submitConfigurationForm in ConditionPluginBase). Is this along this lines of what you were looking for?
Comment #41
godotislate CreditAttribution: godotislate at Digital Polygon commentedUpdated MR to address reviews and rebased for merge conflict.
Comment #42
flitt1 CreditAttribution: flitt1 commentedRewrite for Drupal 9.5.x.
Comment #43
smustgrave CreditAttribution: smustgrave at Mobomo commentedThank you @flitt1 but hiding #42, don't believe this will be backported and don't want it to be reviewed over the MR.
Believe feedback has been addressed. Only one i'm unsure is the point @xjm pointed out about the scheme change.
Comment #44
alexpottDiscussed this issue with @bircher and both of us have concerns about leveraging config schema in the plugin system to cast a plugin's configuration. This is because there's no guarantee that the a plugin config is going to be saved in the configuration system.
We were both wondering whether or not we could change the comparison from
===
to==
in \Drupal\Core\Condition\ConditionPluginCollection::getConfiguration() since we couldn't work out a situation where loose comparison would be a problem. Especially due to changes in PHP 8 type juggling.Comment #46
alexpottComment #47
godotislate CreditAttribution: godotislate at Digital Polygon commented@alexpott
Updated MR and reverted everything that had to do with casting.
Also, made this change and added tests.
Comment #48
alexpott@godotislate the changes look beautiful. It's lovely that this has become much simpler and the comment you added to ConditionPluginManager::getConfiguration() is fantastic. Eagerly waiting for this to be RTBC :)
Comment #49
alexpottAdding contribution credit.
Comment #50
smustgrave CreditAttribution: smustgrave at Mobomo commentedWent through the MR again and Thumbs upped threads I believe are resolved. Only 2 I didn't were the ones from @xjm.
Thanks for adding the comment
if ($default_config == $instance_config)
without reading the comment in #44 it was super clear why that decision was made.LGTM
Comment #51
tim.plunkettOne piece of feedback. Also there are 17 other unresolved threads that *were* resolved. @godotislate as the MR author, you can mark those as resolved.
Comment #52
tim.plunkett@alexpott pushed back on explicit test coverage for double-saving, but the last commit fixes things nicely enough
Comment #53
alexpottCommitted and pushed 24b8523c4a7 to 11.x and 1ea22bd454b to 10.2.x and 78b55658d95 to 10.1.x. Thanks!