From 500027aeb27e3f7ac456647558157751bbc1707b Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Sun, 7 Apr 2019 09:41:59 +0900 Subject: [PATCH] Issue #3046243 by tim.plunkett, jibran, dpi: Regression: Optional context values may throw exceptions if unsatisfied (cherry picked from commit 2cceb4a9029009140e34e6597b6e5e76cceab2d0) --- .../Core/Plugin/Context/ContextHandler.php | 30 +++++++++++++++---- .../Tests/Core/Plugin/ContextHandlerTest.php | 9 +++--- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php index c4a41b8e917a..587fe66b1f9a 100644 --- a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php +++ b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php @@ -5,6 +5,7 @@ use Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface; use Drupal\Component\Plugin\Exception\ContextException; use Drupal\Component\Plugin\Exception\MissingValueContextException; +use Drupal\Component\Plugin\Exception\PluginException; use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Plugin\ContextAwarePluginInterface; @@ -110,19 +111,36 @@ public function applyContextMapping(ContextAwarePluginInterface $plugin, $contex // Collect required contexts that exist but are missing a value. $missing_value[] = $plugin_context_id; } + + // Proceed to the next definition. + continue; + } + + try { + $context = $plugin->getContext($context_id); + } + catch (ContextException $e) { + $context = NULL; + } + // @todo Remove in https://www.drupal.org/project/drupal/issues/3046342. + catch (PluginException $e) { + $context = NULL; } - elseif (($context = $plugin->getContext($context_id)) && $context->hasContextValue()) { + + if ($context && $context->hasContextValue()) { // Ignore mappings if the plugin has a value for a missing context. unset($mappings[$plugin_context_id]); + continue; } - elseif ($plugin_context_definition->isRequired()) { + + if ($plugin_context_definition->isRequired()) { // Collect required contexts that are missing. $missing_value[] = $plugin_context_id; + continue; } - else { - // Ignore mappings for optional missing context. - unset($mappings[$plugin_context_id]); - } + + // Ignore mappings for optional missing context. + unset($mappings[$plugin_context_id]); } // If there are any mappings that were not satisfied, throw an exception. diff --git a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php index 05935e11fe8b..115a8c83f49b 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php @@ -18,7 +18,6 @@ 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; @@ -379,9 +378,9 @@ public function testApplyContextMappingMissingRequired() { ->method('setContext'); // No context, so no cacheability metadata can be passed along. - $plugin->expects($this->once()) + $plugin->expects($this->any()) ->method('getContext') - ->willReturn(new Context($context_definition)); + ->willThrowException(new ContextException()); $this->setExpectedException(MissingValueContextException::class, 'Required contexts without a value: hit'); $this->contextHandler->applyContextMapping($plugin, $contexts); @@ -415,9 +414,9 @@ public function testApplyContextMappingMissingNotRequired() { ->method('setContext'); // No context, so no cacheability metadata can be passed along. - $plugin->expects($this->once()) + $plugin->expects($this->any()) ->method('getContext') - ->willReturn(new Context($context_definition)); + ->willThrowException(new ContextException()); $this->contextHandler->applyContextMapping($plugin, $contexts); } -- GitLab