diff --git a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php index c3f1fcd..efe7158 100644 --- a/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php +++ b/core/lib/Drupal/Core/Plugin/Context/ContextHandler.php @@ -87,16 +87,17 @@ public function applyContextMapping(ContextAwarePluginInterface $plugin, $contex // Collect contexts that exist but are missing a value. if ($plugin_context_definition->isRequired() && !$contexts[$context_id]->hasContextValue()) { $missing_value[] = $plugin_context_id; - continue; } - - if ($contexts[$context_id]->hasContextValue()) { + elseif ($contexts[$context_id]->hasContextValue()) { $plugin->setContextValue($plugin_context_id, $contexts[$context_id]->getContextValue()); } } elseif ($plugin_context_definition->isRequired()) { $missing_value[] = $plugin_context_id; - continue; + } + else { + // Ignore mappings for optional missing context. + unset($mappings[$plugin_context_id]); } } 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 new file mode 100644 index 0000000..986a66c --- /dev/null +++ b/core/modules/system/tests/modules/condition_test/src/Plugin/Condition/OptionalContextCondition.php @@ -0,0 +1,40 @@ +getContextValue('node'); + } + + /** + * {@inheritdoc} + */ + public function summary() { + return $this->t('Context with optional context.'); + } + +} diff --git a/core/modules/system/tests/modules/condition_test/src/Tests/OptionalContextConditionTest.php b/core/modules/system/tests/modules/condition_test/src/Tests/OptionalContextConditionTest.php new file mode 100644 index 0000000..f455905 --- /dev/null +++ b/core/modules/system/tests/modules/condition_test/src/Tests/OptionalContextConditionTest.php @@ -0,0 +1,74 @@ +createInstance('condition_test_optional_context') + ->setContextMapping([ + 'node' => 'node', + ]); + \Drupal::service('context.handler')->applyContextMapping($condition, []); + $this->assertTrue($condition->execute()); + } + + /** + * Tests with both contexts mapped to the same user. + */ + protected function testContextNoValue() { + /** @var \Drupal\Core\Condition\ConditionPluginBase $condition */ + $condition = \Drupal::service('plugin.manager.condition') + ->createInstance('condition_test_optional_context') + ->setContextMapping([ + 'node' => 'node', + ]); + $definition = new ContextDefinition('entity:node'); + $contexts['node'] = (new Context($definition)); + \Drupal::service('context.handler')->applyContextMapping($condition, $contexts); + $this->assertTrue($condition->execute()); + } + + /** + * Tests with both contexts mapped to the same user. + */ + protected function testContextAvailable() { + /** @var \Drupal\Core\Condition\ConditionPluginBase $condition */ + $condition = \Drupal::service('plugin.manager.condition') + ->createInstance('condition_test_optional_context') + ->setContextMapping([ + 'node' => 'node', + ]); + $definition = new ContextDefinition('entity:node'); + $node = Node::create(['type' => 'example']); + $contexts['node'] = (new Context($definition))->setContextValue($node); + \Drupal::service('context.handler')->applyContextMapping($condition, $contexts); + $this->assertFalse($condition->execute()); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php index a852f33..f5345af 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/ContextHandlerTest.php @@ -317,10 +317,10 @@ public function testApplyContextMappingMissingNotRequired() { $plugin = $this->getMock('Drupal\Tests\Core\Plugin\TestConfigurableContextAwarePluginInterface'); $plugin->expects($this->once()) ->method('getContextMapping') - ->willReturn([]); + ->willReturn(['optional' => 'missing']); $plugin->expects($this->once()) ->method('getContextDefinitions') - ->will($this->returnValue(array('hit' => $context_definition))); + ->will($this->returnValue(array('optional' => $context_definition))); $plugin->expects($this->never()) ->method('setContextValue');