From 35ddee690b3fc834c0adc52af7e713ff7ac8c5bb Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Tue, 26 Mar 2019 11:22:52 +0000 Subject: [PATCH] Issue #3029625 by tim.plunkett: Do not throw an exception when a context is missing while applying context mapping to a plugin if that context was previously set (cherry picked from commit 8c90cbfdf787249213c9b6766cd5f5d7e5cad8b6) --- .../Core/Plugin/Context/ContextHandler.php | 4 ++++ .../Core/Plugin/ContextHandlerTest.php | 19 +++++++++++++++++++ .../Tests/Core/Plugin/ContextHandlerTest.php | 11 +++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php index eb8b628276fb..c4a41b8e917a 100644 --- a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php +++ b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php @@ -111,6 +111,10 @@ public function applyContextMapping(ContextAwarePluginInterface $plugin, $contex $missing_value[] = $plugin_context_id; } } + elseif (($context = $plugin->getContext($context_id)) && $context->hasContextValue()) { + // Ignore mappings if the plugin has a value for a missing context. + unset($mappings[$plugin_context_id]); + } elseif ($plugin_context_definition->isRequired()) { // Collect required contexts that are missing. $missing_value[] = $plugin_context_id; diff --git a/core/tests/Drupal/KernelTests/Core/Plugin/ContextHandlerTest.php b/core/tests/Drupal/KernelTests/Core/Plugin/ContextHandlerTest.php index 09ab7af9fe94..a3a43d871c18 100644 --- a/core/tests/Drupal/KernelTests/Core/Plugin/ContextHandlerTest.php +++ b/core/tests/Drupal/KernelTests/Core/Plugin/ContextHandlerTest.php @@ -42,6 +42,25 @@ public function testApplyContextMapping() { $this->assertSame($context, $result); } + /** + * @covers ::applyContextMapping + */ + public function testApplyContextMappingAlreadyApplied() { + $entity = EntityTest::create([]); + $context_definition = EntityContextDefinition::fromEntity($entity); + $context = EntityContext::fromEntity($entity); + + $definition = ['context_definitions' => ['a_context_id' => $context_definition]]; + $plugin = new TestContextAwarePlugin([], 'test_plugin_id', $definition); + $plugin->setContext('a_context_id', $context); + (new ContextHandler())->applyContextMapping($plugin, []); + + $result = $plugin->getContext('a_context_id'); + + $this->assertInstanceOf(EntityContext::class, $result); + $this->assertSame($context, $result); + } + } /** diff --git a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php index 3cf6a1d45d34..05935e11fe8b 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php @@ -18,6 +18,7 @@ use Drupal\Core\DependencyInjection\ClassResolverInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Plugin\Context\Context; use Drupal\Core\Plugin\Context\ContextDefinition; use Drupal\Core\Plugin\Context\ContextHandler; use Drupal\Core\Plugin\ContextAwarePluginInterface; @@ -378,8 +379,9 @@ public function testApplyContextMappingMissingRequired() { ->method('setContext'); // No context, so no cacheability metadata can be passed along. - $plugin->expects($this->never()) - ->method('getContext'); + $plugin->expects($this->once()) + ->method('getContext') + ->willReturn(new Context($context_definition)); $this->setExpectedException(MissingValueContextException::class, 'Required contexts without a value: hit'); $this->contextHandler->applyContextMapping($plugin, $contexts); @@ -413,8 +415,9 @@ public function testApplyContextMappingMissingNotRequired() { ->method('setContext'); // No context, so no cacheability metadata can be passed along. - $plugin->expects($this->never()) - ->method('getContext'); + $plugin->expects($this->once()) + ->method('getContext') + ->willReturn(new Context($context_definition)); $this->contextHandler->applyContextMapping($plugin, $contexts); } -- GitLab