BlockManager is too eager in providing fallback to "Broken" block: it obscures genuine problems

Created on 28 July 2023, about 1 year ago
Updated 18 February 2024, 7 months ago

Problem/Motivation

πŸ“Œ Implement fallback plugin for Block plugins Fixed introduced:

  1. \Drupal\Core\Block\Plugin\Block\Broken
  2. class BlockManager extends DefaultPluginManager implements BlockManagerInterface, FallbackPluginManagerInterface {
    …
      public function getFallbackPluginId($plugin_id, array $configuration = []) {
        return 'broken';
      }
    …
    }
    

Which means that ANY invalid block plugin ID in a block config entity automatically falls back to this broken block plugin.

The primary purpose was to make it possible to install block config entities while the corresponding block_content content entity does not yet exist, and hence allow referencing block_content:<UUID> block plugins to automatically fall back to the broken plugin ID.

But … this is VERY broad. Too broad in many cases. So broad that it makes validating block config entities less meaningful 😞 This became clear in #3362457-17: Fix all PluginExistsConstraint constraint violations in tests β†’ .

But changing this is hard now, because there could be other block plugins in contrib/custom that have similar 🌱 [meta] Deploying configuration that depends on content Active -style needs. Still, we should aim to narrow this.

Steps to reproduce

See #3362457-17: Fix all PluginExistsConstraint constraint violations in tests β†’ : run \Drupal\Tests\block\Kernel\BlockValidationTest::testInvalidPluginId() and observe how a nonsencial plugin ID does not trigger any validation errors.

For contrast, see \Drupal\Tests\editor\Kernel\EditorValidationTest::testInvalidPluginId(), where a validation error is triggered.

Proposed resolution

  1. Simple but more disruptive:
      public function getFallbackPluginId($plugin_id, array $configuration = []) {
        // Provide fallback for `block_content:*` blocks.
        // @see \Drupal\block_content\Plugin\Block\BlockContentBlock
        // @see \Drupal\block_content\Plugin\Derivative\BlockContent
        if (str_starts_with($plugin_id, 'block_content:')) {
          return 'broken';
        }
    
        // No fallback for anything else.
        return $plugin_id;
      }
    
  2. More complex but less disruptive:
      public function getFallbackPluginId($plugin_id, array $configuration = []) {
        // Provide fallback for content-dependent block plugins.
        // @see \Drupal\block_content\Plugin\Block\BlockContentBlock
        // @see \Drupal\block_content\Plugin\Derivative\BlockContent
        foreach ($this->getContentDependentBlockPluginTypes() as $base_plugin_id) {
          if (str_starts_with($plugin_id, "$base_plugin_id:")) {
            return 'broken';
          }
        }
    
        // No fallback for anything else.
        return $plugin_id;
      }

    This needs some mechanism to identify the content-dependent block plugin types to allow contrib/custom block types to get the same behavior. Suggestion: do this via an annotation on block plugin types.

Remaining tasks

TBD

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Release notes snippet

TBD

πŸ› Bug report
Status

Active

Version

11.0 πŸ”₯

Component
BlockΒ  β†’

Last updated 1 day ago

Created by

πŸ‡§πŸ‡ͺBelgium wim leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Live updates comments and jobs are added and updated live.
  • Usability

    Makes Drupal easier to use. Preferred over UX, D7UX, etc.

Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024