Problem/Motivation

Coming from #2677574: All Blocks removed from regions after checking "Show Global blocks".

If an admin submits a block layout form that is empty (has no blocks), all blocks in all themes are left in a broken state (they do not appear through the admin UI).

Steps to reproduce

  • Install Drupal core with the "Standard" install profile.
  • Enable the "Stark" theme, setting it as default.
  • At Admin > Structure > Block layout (admin/structure/block), delete all blocks for the Stark theme. After deleting the blocks, click the "Save blocks" button.
  • Navigate to Admin > Structure > Block layout > Bartik (admin/structure/block/list/bartik). Note that all blocks have disappeared. The following screenshot illustrates the resulting page.

Source of bug

In BlockListBuilder::submitForm() we pass a form state value directly to a ::loadMultiple() call and then iterate through the resulting entities, making changes to each:

  $entities = $this->storage->loadMultiple(array_keys($form_state->getValue('blocks')));
  /** @var \Drupal\block\BlockInterface[] $entities */
  foreach ($entities as $entity_id => $entity) {

In the case that there are no blocks present on the form:

  • An empty string is returned from $form_state->getValue('blocks'), and so all items in the storage are loaded, iterated, modified (including weight and region properties set to NULL), and saved.
  • Without a region value, blocks don't show up in the UI.

Mitigating factors

Because of the block cloning that occurs when a theme is initially installed (see block_theme_initialize(), it's uncommon to have a theme enabled with no blocks; and, if there are no blocks, there is no reason to submit the form.

However, the bug can easily be triggered by contrib modules modifying the block management form. Specifically, the Block Visibility Groups module provides an enhancement that includes filtering blocks to show only those in a given visibility group (initially, none). See #2677574: All Blocks removed from regions after checking "Show Global blocks".

Proposed resolution

Examine the value returned by $form_state->getValue('blocks') and pass to ::loadMultiple() only if not empty.

Remaining tasks

User interface changes

API changes

Data model changes

Comments

nedjo created an issue. See original summary.

nedjo’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new1.84 KB
nedjo’s picture

Issue summary: View changes
StatusFileSize
new1.84 KB
new714 bytes

Value returned from $form_state->getValue('blocks') if no blocks are present is an empty string (not NULL), so testing for empty() rather than is_null().

nedjo’s picture

Title: Submitting empty block layout form results in breakage for all block entities (and other config) » Submitting empty block layout form results in breakage for all block entities
Issue summary: View changes

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ranjith_kumar_k_u’s picture

StatusFileSize
new1.65 KB

Re-rolled for 9.3

Status: Needs review » Needs work

The last submitted patch, 15: 2779321-15.patch, failed testing. View results

meenakshi_j’s picture

Status: Needs work » Needs review
StatusFileSize
new1.48 KB
new619 bytes

fixed the fails.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Bug Smash Initiative, +Needs tests, +Novice

Verified the issue when deleting all blocks you can't save the form.

Though I did not see the blocks from other themes go away.

This will 100% need a test case but it should be super simple

smustgrave’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
StatusFileSize
new899 bytes
new1.01 KB
new2.49 KB

Adding a test case

The last submitted patch, 21: 2779321-21-tests-only.patch, failed testing. View results

deepalij’s picture

Assigned: Unassigned » deepalij

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

deepalij’s picture

Version: 10.1.x-dev » 9.5.x-dev
Assigned: deepalij » Unassigned
Manibharathi E R’s picture

StatusFileSize
new843.6 KB
new833.33 KB

Patch #21 Tested and Applied successfully on Drupal 9.5.x.

Steps:
1. Install Drupal
2. Enable the "Stark" theme, setting it as default.
3. At Admin > Structure > Block layout (admin/structure/block), delete all blocks for the Stark theme. After deleting the blocks, click the "Save blocks" button.
4. Getting the PHP type Error.
5. Apply the patch
6. Click the "save blocks button" its redirect blocks listing page.

kristen pol’s picture

Version: 9.5.x-dev » 10.1.x-dev

Not sure why this was moved to 9.5 in #25. Note that the patch in #21 applies (with fuzz) to 10.0.x and 10.1.x.

kristens-mbp:drupal10 kristenpol$ patch -p1 < 2779321-21.patch 
patching file core/modules/block/src/BlockListBuilder.php
patching file core/modules/block/tests/src/Functional/BlockUiTest.php
Hunk #1 succeeded at 107 with fuzz 2 (offset 3 lines).
kristen pol’s picture

+++ b/core/modules/block/src/BlockListBuilder.php
@@ -379,13 +379,18 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
+    // Passing an empty value to ::loadMultiple would load all items from the
+    // storage.

Nitpick: I would make this comment one line and not note the method (loadMultiple) in it.

pooja saraah’s picture

StatusFileSize
new2.48 KB
new2.03 KB

Addressed the comment #28
Attached patch against Drupal 10.1.x

bebalachandra’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new251.66 KB
new311.78 KB
new319.99 KB

Reproduced problem according to steps given in problem statement. Tested on 10.1 referring to #26 #27 #28 #29.
Getting error while saving changes to blocks in stark theme(attached screenshot)
After installing #29 patch error which was generating while saving changes resolved.
Also the breakdown of all other themes block also resolved and looks good with 10.1
Moving this issue to RTBC.
Attached screenshot for reference

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I think we should fix this slightly differently. If we press save and there is nothing to do I think we should tell the user. With the current fix we're going to tell the user 'The block settings have been updated.' when we've done nothing. Is that correct? I think we could consider changing the ::validateForm() method to tell the user it's not going to do anything. Something like this:

    if (empty($form_state->getValue('blocks'))) {
      $form_state->setErrorByName('blocks', 'No blocks settings to update.');
    }
mukhtarm’s picture

StatusFileSize
new13 KB
new16.22 KB

Adding the patch by addressing the comment #31

akram khan’s picture

StatusFileSize
new2.74 KB
new1.7 KB

Address #31

akram khan’s picture

StatusFileSize
new2.73 KB
new1.69 KB

Updated patch and address #31 fixed code of #30.
Fixing CCF #33 Needs Review

akram khan’s picture

Status: Needs work » Needs review
supriyak’s picture

StatusFileSize
new99.37 KB
new577.52 KB

Patch #34 Tested and Applied successfully on Drupal 10.1.x.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Tested #34 and it worked.

See that feedback from #31 has been addressed also.

  • catch committed e9d8f47 on 10.0.x
    Issue #2779321 by nedjo, Akram Khan, smustgrave, Meenakshi_j, pooja...
  • catch committed e95548b on 10.1.x
    Issue #2779321 by nedjo, Akram Khan, smustgrave, Meenakshi_j, pooja...
  • catch committed a817950 on 9.5.x
    Issue #2779321 by nedjo, Akram Khan, smustgrave, Meenakshi_j, pooja...
catch’s picture

Version: 10.1.x-dev » 9.5.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x.

Note I didn't add commit credit for duplicated manual testing, once is plenty.

berdir’s picture

After-the-commit review, coming here because this requires a reroll of #2910353: Prevent saving config entities when configuration overrides are applied

The committed patch is a little bit strange, because I don't think the submitForm() changes are necessary now that the validation is in place, because you can't end up there with an empty block list?

Additionally, loadMultiple() only returns all entities if you explicitly pass NULL. An empty array is a no-op and returns nothing. I suppose the form value really is null. FWIW, in PHP 8, array_keys(NULL) is actually a type error, so in Drupal 10, the worst that could happen there is a fatal error and not breaking all your config (yay stricter type handling).

I don't think it's worth reopening this to revert the submitForm() changes, but happy to do so if others/catch think that makes sense.

catch’s picture

StatusFileSize
new1.42 KB

That's a good point with the submitForm changes. Here's a patch that just reverts that hunk, if that passes I may commit as-is since it's just an unnecessary hunk that we otherwise could have removed from the original patch on commit.

alexpott’s picture

+++ b/core/modules/block/src/BlockListBuilder.php
@@ -372,20 +372,27 @@ public function getDefaultOperations(EntityInterface $entity) {
+    if (empty($form_state->getValue('blocks'))) {
+      $form_state->setErrorByName('blocks', 'No blocks settings to update.');
+    }

We also need a follow-up here to wrap the UI text in $this->t().

Plus we could add testing that this message appears.

berdir’s picture

Status: Fixed » Needs work

Failed but that test looks unrelated?

Setting to needs work for #42. The test comment should then also be updated to that you actually can not save?

catch’s picture

Status: Needs work » Needs review
StatusFileSize
new1.73 KB
new2.92 KB

This is tipping into follow-up issue territory now, but here's those changes.

berdir’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Let's do a quick commit here and forget it ever happened :)

Committed and pushed b5b2951668 to 10.1.x and 60ce4e1407 to 10.0.x and 9b61f274e7 to 9.5.x. Thanks!

  • alexpott committed b5b2951 on 10.1.x
    Issue #2779321 by nedjo, Akram Khan, smustgrave, catch, Meenakshi_j,...

  • alexpott committed 60ce4e1 on 10.0.x
    Issue #2779321 by nedjo, Akram Khan, smustgrave, catch, Meenakshi_j,...

  • alexpott committed 9b61f27 on 9.5.x
    Issue #2779321 by nedjo, Akram Khan, smustgrave, catch, Meenakshi_j,...

Status: Fixed » Closed (fixed)

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