Problem/Motivation

Over in #2248369: [meta] Deploying configuration that depends on content we're discussing issues deploying config that depends on content that depends on config, ala block -> custom block -> custom block type.
We need a more robust way to handle missing custom block uuids and other block plugins.
Now that #1822048: Introduce a generic fallback plugin mechanism is in, we can re-use the generic fallback functionality

Proposed resolution

Use generic fallback functionality

Remaining tasks

Do it

User interface changes

None

API changes

None yet

Comments

Status: Needs review » Needs work

The last submitted patch, custom-block-fallback.1.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.47 KB
new5.32 KB

Status: Needs review » Needs work

The last submitted patch, 2: custom-block-fallback.2.patch, failed testing.

catch’s picture

So from #2248369: [meta] Deploying configuration that depends on content I ought to just test it.., but it's my impression that it's impossible to create a custom block in staging, then export it to production and have it work.

With reference fields, you can create the content on production, sync the database back to staging, then create the configuration entities. Because the content entities already exist on production, the stage will work fine.

With custom blocks, it's not possible to create the custom block content entity on production, without also creating a block configuration entity at the same time. This means any workflow which requires config to go staging -> production becomes impossible.

I'm not really keen on expanding the 'broken handlers' concept to other modules in core, we already have an issue to remove that in views #1822048: Introduce a generic fallback plugin mechanism. Additionally if the situation is as described above, every staged custom block is going to be 'broken' by design - just it'll have broken handlers instead of random PHP errors.

catch’s picture

Title: Allow custom block to handle missing content more gracefully » Impossible to deploy custom blocks due to config -> content -> config dependency
Priority: Normal » Critical

Clarifying the issue title and bumping to critical.

catch’s picture

I think we should make it so that the blocks UI allows you to create a block content entity without also creating the plugin instance.

That would bring the problem to the same level as #2248369: [meta] Deploying configuration that depends on content where you can do the following:

1. Create the content entity on production

2. Sync the database back to staging/dev

3. Create the configuration that depends on the content entity.

4. Successfully sync the configuration to production since the dependency is met

Which is not great but at least possible.

catch’s picture

Status: Needs work » Closed (duplicate)

Spoke to Tim Plunkett in irc, I hadn't realised the UI is already a two-step form and there's no requirement to place a custom block.

So this means the horrible workflow in #6 is doable now. Closing as duplicate since there's nothing specific here we can't cover in the other issue.

larowlan’s picture

Category: Bug report » Task
Priority: Critical » Normal
Issue summary: View changes
Status: Closed (duplicate) » Active

Now that #1822048: Introduce a generic fallback plugin mechanism is in, we can utilize that - retitling appropriately

larowlan’s picture

Title: Impossible to deploy custom blocks due to config -> content -> config dependency » Implement fallback plugin for Block Content derivatives
larowlan’s picture

Title: Implement fallback plugin for Block Content derivatives » Implement fallback plugin for Block plugins
Issue summary: View changes
larowlan’s picture

Status: Active » Needs review
StatusFileSize
new5.34 KB
tim.plunkett’s picture

  1. +++ b/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php
    @@ -0,0 +1,54 @@
    +*  id = "broken",
    +*  admin_label = @Translation("Broken/Missing"),
    +*  category = @Translation("Block"),
    

    These are normally indented two spaces.

  2. +++ b/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php
    @@ -0,0 +1,54 @@
    +      '#type' => 'markup',
    

    Overkill, this is the default #type

  3. +++ b/core/modules/block_content/tests/modules/block_content_test/config/install/block.block.foobargorilla.yml
    @@ -0,0 +1,31 @@
    +id: foobargorilla
    

    :)

Status: Needs review » Needs work

The last submitted patch, 11: block-fallback-2249303.1.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.79 KB
new5.89 KB

Fixes #12 and fails

Status: Needs review » Needs work

The last submitted patch, 14: block-fallback-2249303.2.patch, failed testing.

vijaycs85’s picture

Status: Needs work » Needs review
StatusFileSize
new6 KB
new666 bytes

we got another block_content inside settings...

tim.plunkett’s picture

+++ b/core/modules/block_content/tests/modules/block_content_test/config/install/block.block.foobargorilla.yml
@@ -0,0 +1,31 @@
+  view_mode: default
+  block_content:
+    view_mode: default

This looks like the view_mode ended up on the wrong level. Why did this pass?
Shouldn't it have caused a missing schema error?

I'm not picky about where it ends up, either level.

larowlan’s picture

We need to remove the nested field values in BlockContentBlock::blockForm - will tackle later today

larowlan’s picture

StatusFileSize
new3.8 KB
new7.82 KB

Fixes #17

Status: Needs review » Needs work

The last submitted patch, 19: block-fallback-2249303.19.patch, failed testing.

larowlan’s picture

StatusFileSize
new983 bytes
new8.08 KB
larowlan’s picture

Status: Needs work » Needs review
andypost’s picture

  1. +++ b/core/lib/Drupal/Component/Plugin/FallbackPluginManagerInterface.php
    @@ -21,7 +21,7 @@
    +   *   The id of an existing plugin to use when the a plugin does not exist.
    

    s/"the a"/the

  2. +++ b/core/lib/Drupal/Core/Block/BlockManager.php
    @@ -108,7 +109,16 @@ public function getSortedDefinitions() {
    +    // Do not display the 'broken' plugin in the UI.
    +    unset($definitions['broken']);
    

    maybe it's ok to display them to allow their deletion at least?

  3. +++ b/core/modules/block_content/src/Tests/BlockContentPageViewTest.php
    @@ -33,6 +33,9 @@ public function testPageEdit() {
    +    $this->assertRaw(t('This block is broken or missing. You may be missing content or you might need to enable the original module.'));
    +
    

    no need in extra line

arla’s picture

Great, this seems to work well in a real case at hand.

  1. +++ b/core/lib/Drupal/Component/Plugin/FallbackPluginManagerInterface.php
    @@ -21,7 +21,7 @@
    +   *   The id of an existing plugin to use when the a plugin does not exist.
    

    Nitpick: double article "the a".

  2. +++ b/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php
    @@ -0,0 +1,53 @@
    +  public function blockForm($form, FormStateInterface $form_state) {
    

    Nitpick: typehinting the $form parameter with array seems to be preferrable.

tim.plunkett’s picture

#24.2, the parent class doesn't use that typehint, so this class cannot.

Once the other nitpicks are in, this is RTBC.

larowlan’s picture

StatusFileSize
new1.77 KB
new7.91 KB
tim.plunkett’s picture

StatusFileSize
new69.97 KB
+++ b/core/lib/Drupal/Core/Block/BlockManager.php
@@ -109,8 +109,6 @@ public function getSortedDefinitions() {
-    // Do not display the 'broken' plugin in the UI.
-    unset($definitions['broken']);

This is not in getDefinitions, but getSortedDefinitions. This is really only used for the candidate blocks. Unsetting here would not prevent it from appearing in the list of placed blocks.

larowlan’s picture

StatusFileSize
new448 bytes
new8.03 KB

that was my original fear too

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new8.08 KB
new500 bytes

Thanks!

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 96dd466 and pushed to 8.0.x. Thanks!

diff --git a/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php b/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php
index 1452b86..df61f3b 100644
--- a/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php
+++ b/core/lib/Drupal/Core/Block/Plugin/Block/Broken.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Block\Plugin\Block;
 
-use Drupal\Component\Utility\Xss;
 use Drupal\Core\Block\BlockBase;
 use Drupal\Core\Form\FormStateInterface;

Removed unnecessary use on commit.

  • alexpott committed 96dd466 on 8.0.x
    Issue #2249303 by larowlan, tim.plunkett, vijaycs85: Implement fallback...

Status: Fixed » Closed (fixed)

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

wim leers’s picture

Component: custom_block.module » block.module