Problem/Motivation
This is kind of a strange bug where new block instances are overwriting existing block instances because we do not provide a mechanism for checking for these existing block instances when saving a new block instance.
Steps to Reproduce
To reproduce, simply go to /admin/structure/block/list/ and click on +Place blocks.
- Choose to place a block that already contains an instance in the current theme.
- For this example: System Help (Note that an instance of System Help with a machine name of 'help' already exists in the 'Help' region.)
- Put a new instance of System Help in the 'Header' region and make its machine_name 'help'
- After saving your new block instance, you'll see that you still only have one 'System Help' block, but now it is placed in the 'Header' region.
You could even do this with another block type - perhaps place a 'Syndicate' block in a region but make its machine_name equal to 'help' - saving this will remove your old 'System Help' block and replace it with a 'Syndicate' block.
Or watch this video to see this in action: http://screencast.com/t/zRvySXYffdV
Proposed resolution
Create a test that will check for an existing block with the same name, prevent the new block from saving if a duplicate is found, and provide an error message giving the user the opportunity to give the new block a different machine name and resave.
Comment | File | Size | Author |
---|---|---|---|
#16 | validation_error.png | 20.81 KB | xjm |
#12 | block-1998664-12.patch | 3.73 KB | marcingy |
#11 | block-1998664-11.patch | 3.05 KB | marcingy |
#10 | block-1998664-10.patch | 1.87 KB | marcingy |
Comments
Comment #1
saltednutxjm says this is critical. I concur.
Comment #2
xjmComment #3
dcam CreditAttribution: dcam commentedSo what is the expected behavior in this scenario? I was thinking of writing tests for it, but I don't know what the result should be.
Comment #4
dcam CreditAttribution: dcam commentedhttp://drupal.org/node/1427826 contains instructions for updating the issue summary with the summary template.
Comment #5
dnmurray CreditAttribution: dnmurray commentedWriting a test that will fail if a block with the same name already exists and it moves or disappears after the save. Assuming that the patch to fix the bug will prevent the save due to the duplicate block name.
Comment #6
jasonyarringtonRemoved needs issue summary update tag
Comment #7
adamdicarlo CreditAttribution: adamdicarlo commented@dnmurray Please visit http://core.drupalofficehours.org/task/2362 (logged in) and indicate that you're working on this so those of us in the code sprint know this task isn't available.
Thanks!
Comment #8
saltednutRelated: #1874822: Add functional test coverage for placing multiple blocks
Comment #9
marcingy CreditAttribution: marcingy commentedWorking on this hopefully will have test and fix up for review today, initial test will be appearing shortly.
Comment #10
marcingy CreditAttribution: marcingy commentedTest only patch this should fail.
Comment #11
marcingy CreditAttribution: marcingy commentedThis fixes the test but smells very wrong.
Comment #12
marcingy CreditAttribution: marcingy commentedA some what better version that allows for machine name to be given a prefix, which is the issue here as blocks are prefixed with theme name.
Comment #13
tim.plunkettThis sounds like a dupe of #1887654: Creating a config entity with an existing machine name shouldn't work, at least the underlying bug.
Comment #14
xjmOh, that's where that issue went. Still, though, I think this can go in as-is to fix the data loss issue. We can generalize it later with #1887654: Creating a config entity with an existing machine name shouldn't work and #2019709: Add an option to machine name elements to increment with a delta instead of failing validation, but this seems fine to me to at least prevent the blithe overwriting through the UI.
Comment #15
xjm#12: block-1998664-12.patch queued for re-testing.
Comment #16
xjmPatch in action:
Comment #17
tim.plunkettI don't know that form.inc should know/care about "configuration entities".
And the test coverage for this API addition to FAPI should have standalone tests, not coupled to the block UI.
Comment #18
xjmWell, such tests won't work since this fix is only FAPI validation...
Comment #19
xjmAh, to clarify #17, I didn't notice that the validation is being done in
form.inc
. @tim.plunkett and I agreed that since the prefixing is a Block-only behavior that we probably want to remove anyway, let's just move the validation into the block form instead. (So the tests are correct, but the fix is too general.)Comment #20
marcingy CreditAttribution: marcingy commentedSo the patch in https://drupal.org/node/1998664#comment-7483306 instead? Which is a block only version of the validation patch.
Comment #21
tstoecklerField UI does this by adding a #field_prefix to the form element and then manually prepending that in the validate() step. Field UI also adds a < span dir="ltr" > because machine names are always English and, thus, should always be displayed in ltr regardless of the rest of the page. The fact that AFAIK only Field UI does this, however, is a hint IMO that #type machine_name should probably handle that automatically. So I would support adding an #id_prefix property (although it should probably be renamed, as the form type is machine_name) or re-using the #field_prefix for that, if that's possible (although probably not, because of the < span > thing). Field UI could be used as a sample implementation of that as well.
On the other hand, that does sort of seem like scope-screep, since this is a critical bug. Can't the Blocks UI simply add the prefix in validate() as well? Then we can figure out the broader issue in a follow-up.
Comment #22
tstoecklerAhh, I'm sorry I didn't read the issue properly. The Blocks UI already adds the prefix correctly. This is about the #exists callback not getting the correct ID....
Hmm...
Comment #23
sdboyer CreditAttribution: sdboyer commentednote that, while this will still be a problem, this becomes vastly less of a user WTF when #2022897: Shift responsibility for creating unique config id/machine name off of (views) block plugins and onto BlockFormController goes in.
Comment #24
yched CreditAttribution: yched commentedIsn't that an instance of #2041887: check that id does not exist before saving a new ConfigEntity ?
Comment #25
xjmRelated: #2041887: check that id does not exist before saving a new ConfigEntity
Comment #26
tim.plunkettBack in June, when this was close, it was fine to keep this separate. At this point, it's out of date enough that we should just mark it a dupe of #1887654: Creating a config entity with an existing machine name shouldn't work
Comment #26.0
tim.plunkettUpdated the issue summary.