Problem/Motivation
#2249303: Implement fallback plugin for Block plugins introduced:
\Drupal\Core\Block\Plugin\Block\Broken-
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 #2248369: [meta] Deploying configuration that depends on content-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
- 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; } - 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
Comments
Comment #2
andypostAs event now processed, the issue looks doable
Comment #3
andypost