diff --git a/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php b/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php index 2d499fd7dd..dadb8b4f9d 100644 --- a/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php +++ b/core/lib/Drupal/Component/Plugin/ContextAwarePluginBase.php @@ -72,7 +72,7 @@ public function getContextDefinitions() { return $definition->getContextDefinitions(); } else { - return !empty($definition['context']) ? $definition['context'] : []; + return !empty($definition['context_definitions']) ? $definition['context_definitions'] : []; } } @@ -86,8 +86,8 @@ public function getContextDefinition($name) { return $definition->getContextDefinition($name); } } - elseif (!empty($definition['context'][$name])) { - return $definition['context'][$name]; + elseif (!empty($definition['context_definitions'][$name])) { + return $definition['context_definitions'][$name]; } throw new ContextException(sprintf("The %s context is not a valid context.", $name)); } diff --git a/core/lib/Drupal/Core/Annotation/ContextDefinition.php b/core/lib/Drupal/Core/Annotation/ContextDefinition.php index 9e28d5a6ed..6a46c01e5a 100644 --- a/core/lib/Drupal/Core/Annotation/ContextDefinition.php +++ b/core/lib/Drupal/Core/Annotation/ContextDefinition.php @@ -14,14 +14,14 @@ * interactions through providing limits, and mapping contexts to appropriate * plugins. Context definitions can be provided as such: * @code - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node") * } * @endcode * * To add a label to a context definition use the "label" key: * @code - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", label = @Translation("Node")) * } * @endcode @@ -29,7 +29,7 @@ * Contexts are required unless otherwise specified. To make an optional * context use the "required" key: * @code - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node")) * } * @endcode @@ -37,7 +37,7 @@ * To define multiple contexts, simply provide different key names in the * context array: * @code - * context = { + * context_definitions = { * "artist" = @ContextDefinition("entity:node", label = @Translation("Artist")), * "album" = @ContextDefinition("entity:node", label = @Translation("Album")) * } @@ -45,7 +45,7 @@ * * Specifying a default value for the context definition: * @code - * context = { + * context_definitions = { * "message" = @ContextDefinition("string", * label = @Translation("Message"), * default_value = @Translation("Checkout complete! Thank you for your purchase.") diff --git a/core/lib/Drupal/Core/Block/Annotation/Block.php b/core/lib/Drupal/Core/Block/Annotation/Block.php index 99d731d08b..cb694eb587 100644 --- a/core/lib/Drupal/Core/Block/Annotation/Block.php +++ b/core/lib/Drupal/Core/Block/Annotation/Block.php @@ -38,4 +38,26 @@ class Block extends Plugin { */ public $category = ''; + /** + * An array of context definitions describing the context used by the plugin. + * + * The array is keyed by context names. + * + * @var \Drupal\Core\Annotation\ContextDefinition[] + * + * @deprecated Providing context definitions via the "context" key is + * deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.0. Use + * the "context_definitions" key instead. + */ + public $context = []; + + /** + * An array of context definitions describing the context used by the plugin. + * + * The array is keyed by context names. + * + * @var \Drupal\Core\Annotation\ContextDefinition[] + */ + public $context_definitions = []; + } diff --git a/core/lib/Drupal/Core/Condition/Annotation/Condition.php b/core/lib/Drupal/Core/Condition/Annotation/Condition.php index b6686cf6b0..66a74d34ed 100644 --- a/core/lib/Drupal/Core/Condition/Annotation/Condition.php +++ b/core/lib/Drupal/Core/Condition/Annotation/Condition.php @@ -54,9 +54,22 @@ class Condition extends Plugin { * The array is keyed by context names. * * @var \Drupal\Core\Annotation\ContextDefinition[] + * + * @deprecated Providing context definitions via the "context" key is + * deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.0. Use + * the "context_definitions" key instead. */ public $context = []; + /** + * An array of context definitions describing the context used by the plugin. + * + * The array is keyed by context names. + * + * @var \Drupal\Core\Annotation\ContextDefinition[] + */ + public $context_definitions = []; + /** * The category under which the condition should listed in the UI. * diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php index c7517a9bdd..8967267be3 100644 --- a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php +++ b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php @@ -43,8 +43,8 @@ protected function getContextDefinitions($plugin_definition) { if ($plugin_definition instanceof ContextAwarePluginDefinitionInterface) { return $plugin_definition->getContextDefinitions(); } - if (is_array($plugin_definition) && isset($plugin_definition['context'])) { - return $plugin_definition['context']; + if (is_array($plugin_definition) && isset($plugin_definition['context_definitions'])) { + return $plugin_definition['context_definitions']; } return NULL; } diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php index c74fcbe958..a9a157a5d1 100644 --- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php +++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php @@ -3,6 +3,7 @@ namespace Drupal\Core\Plugin; use Drupal\Component\Assertion\Inspector; +use Drupal\Component\Plugin\ContextAwarePluginInterface as ComponentContextAwarePluginInterface; use Drupal\Component\Plugin\Definition\PluginDefinitionInterface; use Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface; use Drupal\Core\Cache\CacheableDependencyInterface; @@ -286,6 +287,7 @@ protected function findDefinitions() { $this->processDefinition($definition, $plugin_id); } $this->alterDefinitions($definitions); + $this->fixContextAwareDefinitions($definitions); // If this plugin was provided by a module that does not exist, remove the // plugin definition. foreach ($definitions as $plugin_id => $plugin_definition) { @@ -297,6 +299,38 @@ protected function findDefinitions() { return $definitions; } + /** + * Fix the definitions of context-aware plugins. + * + * @param array $definitions + * The array of plugin definitions. + * + * @todo Remove before Drupal 9.0.0. + */ + private function fixContextAwareDefinitions(array &$definitions) { + foreach ($definitions as $name => &$definition) { + if (is_array($definition) && is_subclass_of($definition['class'], ComponentContextAwarePluginInterface::class) && (!empty($definition['context']) || !empty($definition['context_definitions']))) { + // Ensure the new definition key is available. + if (!isset($definition['context_definitions'])) { + $definition['context_definitions'] = []; + } + + // If a context definition is defined with the old key, add it to the + // new key and trigger a deprecation error. + if (!empty($definition['context'])) { + $definition['context_definitions'] += $definition['context']; + @trigger_error('Providing context definitions via the "context" key is deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.0. Use the "context_definitions" key instead.', E_USER_DEPRECATED); + } + + // Copy the context definitions from the new key to the old key for + // backwards compatibility. + if (isset($definition['context'])) { + $definition['context'] = $definition['context_definitions']; + } + } + } + } + /** * Extracts the provider from a plugin definition. * diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php index e5017f5448..178643c2ec 100644 --- a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php +++ b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareBlock.php @@ -12,7 +12,7 @@ * @Block( * id = "test_context_aware", * admin_label = @Translation("Test context-aware block"), - * context = { + * context_definitions = { * "user" = @ContextDefinition("entity:user", required = FALSE) * } * ) diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareUnsatisfiedBlock.php b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareUnsatisfiedBlock.php index f70e8e2e6e..d0789e37a7 100644 --- a/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareUnsatisfiedBlock.php +++ b/core/modules/block/tests/modules/block_test/src/Plugin/Block/TestContextAwareUnsatisfiedBlock.php @@ -10,7 +10,7 @@ * @Block( * id = "test_context_aware_unsatisfied", * admin_label = @Translation("Test context-aware unsatisfied block"), - * context = { + * context_definitions = { * "user" = @ContextDefinition("entity:foobar") * } * ) diff --git a/core/modules/language/src/Plugin/Condition/Language.php b/core/modules/language/src/Plugin/Condition/Language.php index 52a89a2d0f..bbbce83745 100644 --- a/core/modules/language/src/Plugin/Condition/Language.php +++ b/core/modules/language/src/Plugin/Condition/Language.php @@ -15,7 +15,7 @@ * @Condition( * id = "language", * label = @Translation("Language"), - * context = { + * context_definitions = { * "language" = @ContextDefinition("language", label = @Translation("Language")) * } * ) diff --git a/core/modules/layout_builder/src/Plugin/Derivative/ExtraFieldBlockDeriver.php b/core/modules/layout_builder/src/Plugin/Derivative/ExtraFieldBlockDeriver.php index d6621c0f47..1a6bb6699b 100644 --- a/core/modules/layout_builder/src/Plugin/Derivative/ExtraFieldBlockDeriver.php +++ b/core/modules/layout_builder/src/Plugin/Derivative/ExtraFieldBlockDeriver.php @@ -100,7 +100,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { $context_definition = EntityContextDefinition::fromEntityType($entity_type) ->addConstraint('Bundle', [$bundle_id]); - $derivative['context'] = [ + $derivative['context_definitions'] = [ 'entity' => $context_definition, ]; diff --git a/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php b/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php index 57d2c1ec7c..ae6771b118 100644 --- a/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php +++ b/core/modules/layout_builder/src/Plugin/Derivative/FieldBlockDeriver.php @@ -120,7 +120,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { $context_definition = EntityContextDefinition::fromEntityTypeId($entity_type_id)->setLabel($entity_type_labels[$entity_type_id]); $context_definition->addConstraint('Bundle', [$bundle]); - $derivative['context'] = [ + $derivative['context_definitions'] = [ 'entity' => $context_definition, ]; diff --git a/core/modules/node/src/Plugin/Condition/NodeType.php b/core/modules/node/src/Plugin/Condition/NodeType.php index dcd2dc7d30..93e18c09ae 100644 --- a/core/modules/node/src/Plugin/Condition/NodeType.php +++ b/core/modules/node/src/Plugin/Condition/NodeType.php @@ -14,7 +14,7 @@ * @Condition( * id = "node_type", * label = @Translation("Node Bundle"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", label = @Translation("Node")) * } * ) diff --git a/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestDualUser.php b/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestDualUser.php index f331c731e9..81d3e7cea2 100644 --- a/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestDualUser.php +++ b/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestDualUser.php @@ -10,7 +10,7 @@ * @Condition( * id = "condition_test_dual_user", * label = @Translation("Dual user"), - * context = { + * context_definitions = { * "user1" = @ContextDefinition("entity:user", label = @Translation("User 1")), * "user2" = @ContextDefinition("entity:user", label = @Translation("User 2")) * } diff --git a/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestNoExistingType.php b/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestNoExistingType.php index ef00053fe3..f465916e84 100644 --- a/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestNoExistingType.php +++ b/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/ConditionTestNoExistingType.php @@ -10,7 +10,7 @@ * @Condition( * id = "condition_test_no_existing_type", * label = @Translation("No existing type"), - * context = { + * context_definitions = { * "no_existing_type" = @ContextDefinition("no_existing_type", label = @Translation("No existing type")), * } * ) diff --git a/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/OptionalContextCondition.php b/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/OptionalContextCondition.php index 061261c210..46f48d24a1 100644 --- a/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/OptionalContextCondition.php +++ b/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/OptionalContextCondition.php @@ -13,7 +13,7 @@ * @Condition( * id = "condition_test_optional_context", * label = @Translation("Optional context"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", label = @Translation("Node"), required = FALSE), * } * ) diff --git a/core/modules/user/src/Plugin/Condition/UserRole.php b/core/modules/user/src/Plugin/Condition/UserRole.php index 60b8b0e29c..11ee277970 100644 --- a/core/modules/user/src/Plugin/Condition/UserRole.php +++ b/core/modules/user/src/Plugin/Condition/UserRole.php @@ -11,7 +11,7 @@ * @Condition( * id = "user_role", * label = @Translation("User Role"), - * context = { + * context_definitions = { * "user" = @ContextDefinition("entity:user", label = @Translation("User")) * } * ) diff --git a/core/modules/views/src/Plugin/Derivative/ViewsBlock.php b/core/modules/views/src/Plugin/Derivative/ViewsBlock.php index f4da73d4bd..51993ae402 100644 --- a/core/modules/views/src/Plugin/Derivative/ViewsBlock.php +++ b/core/modules/views/src/Plugin/Derivative/ViewsBlock.php @@ -115,7 +115,7 @@ public function getDerivativeDefinitions($base_plugin_definition) { foreach ($display->getHandlers('argument') as $argument_name => $argument) { /** @var \Drupal\views\Plugin\views\argument\ArgumentPluginBase $argument */ if ($context_definition = $argument->getContextDefinition()) { - $this->derivatives[$delta]['context'][$argument_name] = $context_definition; + $this->derivatives[$delta]['context_definitions'][$argument_name] = $context_definition; } } diff --git a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php index b4e1eb5e35..3c49a6a2cb 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php @@ -220,7 +220,7 @@ public function providerTestFilterPluginDefinitionsByContexts() { $data[] = [FALSE, $plugins, $plugins]; $plugins = [ - 'expected_array_plugin' => ['context' => []], + 'expected_array_plugin' => ['context_definitions' => []], 'expected_object_plugin' => new ContextAwarePluginDefinition(), ]; // No context, all plugins available. @@ -228,7 +228,7 @@ public function providerTestFilterPluginDefinitionsByContexts() { $plugins = [ 'expected_array_plugin' => [ - 'context' => ['context1' => new ContextDefinition('string')], + 'context_definitions' => ['context1' => new ContextDefinition('string')], ], 'expected_object_plugin' => (new ContextAwarePluginDefinition()) ->addContextDefinition('context1', new ContextDefinition('string')), @@ -241,7 +241,7 @@ public function providerTestFilterPluginDefinitionsByContexts() { $mismatched_context_definition = (new ContextDefinition('expected_data_type'))->setConstraints(['mismatched_constraint_name' => 'mismatched_constraint_value']); $plugins = [ 'expected_array_plugin' => [ - 'context' => ['context1' => $mismatched_context_definition], + 'context_definitions' => ['context1' => $mismatched_context_definition], ], 'expected_object_plugin' => (new ContextAwarePluginDefinition()) ->addContextDefinition('context1', $mismatched_context_definition), @@ -253,7 +253,7 @@ public function providerTestFilterPluginDefinitionsByContexts() { $optional_mismatched_context_definition->setRequired(FALSE); $plugins = [ 'expected_array_plugin' => [ - 'context' => ['context1' => $optional_mismatched_context_definition], + 'context_definitions' => ['context1' => $optional_mismatched_context_definition], ], 'expected_object_plugin' => (new ContextAwarePluginDefinition()) ->addContextDefinition('context1', $optional_mismatched_context_definition), @@ -264,7 +264,7 @@ public function providerTestFilterPluginDefinitionsByContexts() { $expected_context_definition = (new ContextDefinition('string'))->setConstraints(['Blank' => []]); $plugins = [ 'expected_array_plugin' => [ - 'context' => ['context1' => $expected_context_definition], + 'context_definitions' => ['context1' => $expected_context_definition], ], 'expected_object_plugin' => (new ContextAwarePluginDefinition()) ->addContextDefinition('context1', $expected_context_definition), @@ -276,7 +276,7 @@ public function providerTestFilterPluginDefinitionsByContexts() { $optional_expected_context_definition->setRequired(FALSE); $plugins = [ 'expected_array_plugin' => [ - 'context' => ['context1' => $optional_expected_context_definition], + 'context_definitions' => ['context1' => $optional_expected_context_definition], ], 'expected_object_plugin' => (new ContextAwarePluginDefinition()) ->addContextDefinition('context1', $optional_expected_context_definition), @@ -287,10 +287,10 @@ public function providerTestFilterPluginDefinitionsByContexts() { $unexpected_context_definition = (new ContextDefinition('unexpected_data_type'))->setConstraints(['mismatched_constraint_name' => 'mismatched_constraint_value']); $plugins = [ 'unexpected_array_plugin' => [ - 'context' => ['context1' => $unexpected_context_definition], + 'context_definitions' => ['context1' => $unexpected_context_definition], ], 'expected_array_plugin' => [ - 'context' => ['context2' => new ContextDefinition('string')], + 'context_definitions' => ['context2' => new ContextDefinition('string')], ], 'unexpected_object_plugin' => (new ContextAwarePluginDefinition()) ->addContextDefinition('context1', $unexpected_context_definition), @@ -310,6 +310,34 @@ public function providerTestFilterPluginDefinitionsByContexts() { return $data; } + /** + * @covers ::filterPluginDefinitionsByContexts + * + * @group legacy + */ + public function testFilterPluginDefinitionsByContextsLegacy() { + $plugins = [ + 'unexpected_array_plugin' => [ + 'context' => ['context1' => (new ContextDefinition('unexpected_data_type'))->setConstraints(['mismatched_constraint_name' => 'mismatched_constraint_value'])], + ], + 'expected_array_plugin' => [ + 'context' => ['context2' => new ContextDefinition('string')], + ], + ]; + // Context only satisfies one plugin. + $expected = [ + 'expected_array_plugin' => $plugins['expected_array_plugin'], + ]; + + $context = $this->getMock('Drupal\Core\Plugin\Context\ContextInterface'); + $expected_context_definition = (new ContextDefinition('string')); + $context->expects($this->atLeastOnce()) + ->method('getContextDefinition') + ->willReturn($expected_context_definition); + + $this->assertSame($expected, $this->contextHandler->filterPluginDefinitionsByContexts([$context], $plugins)); + } + /** * @covers ::applyContextMapping */