Commit fda020ec authored by alexpott's avatar alexpott

Issue #2378585 by EclipseGc, tim.plunkett: Multiple context requirements...

Issue #2378585 by EclipseGc, tim.plunkett: Multiple context requirements cannot be satisfied by a single value
parent e27f0077
......@@ -130,9 +130,9 @@ public function validateContexts();
*
* @return array
* A mapping of the expected assignment names to their context names. For
* example, if one of the $contexts is named 'current_user', but the plugin
* expects a context named 'user', then this map would contain
* 'current_user' => 'user'.
* example, if one of the $contexts is named 'user.current_user', but the
* plugin expects a context named 'user', then this map would contain
* 'user' => 'user.current_user'.
*/
public function getContextMapping();
......@@ -141,9 +141,9 @@ public function getContextMapping();
*
* @param array $context_mapping
* A mapping of the expected assignment names to their context names. For
* example, if one of the $contexts is named 'current_user', but the plugin
* expects a context named 'user', then this map would contain
* 'current_user' => 'user'.
* example, if one of the $contexts is named 'user.current_user', but the
* plugin expects a context named 'user', then this map would contain
* 'user' => 'user.current_user'.
*
* @return $this
*/
......
......@@ -73,22 +73,20 @@ public function getMatchingContexts(array $contexts, ContextDefinitionInterface
*/
public function applyContextMapping(ContextAwarePluginInterface $plugin, $contexts, $mappings = array()) {
$mappings += $plugin->getContextMapping();
$plugin_contexts = $plugin->getContextDefinitions();
// Loop through each context and set it on the plugin if it matches one of
// the contexts expected by the plugin.
foreach ($contexts as $name => $context) {
// Loop through each of the expected contexts.
foreach (array_keys($plugin->getContextDefinitions()) as $plugin_context_id) {
// If this context was given a specific name, use that.
$assigned_name = isset($mappings[$name]) ? $mappings[$name] : $name;
if (isset($plugin_contexts[$assigned_name])) {
$context_id = isset($mappings[$plugin_context_id]) ? $mappings[$plugin_context_id] : $plugin_context_id;
if (!empty($contexts[$context_id])) {
// This assignment has been used, remove it.
unset($mappings[$name]);
$plugin->setContextValue($assigned_name, $context->getContextValue());
unset($mappings[$plugin_context_id]);
$plugin->setContextValue($plugin_context_id, $contexts[$context_id]->getContextValue());
}
}
// If there are any mappings that were not satisfied, throw an exception.
if (!empty($mappings)) {
throw new ContextException(String::format('Assigned contexts were not satisfied: @mappings', array('@mappings' => implode(',', $mappings))));
throw new ContextException(String::format('Assigned contexts were not satisfied: @mappings', ['@mappings' => implode(',', array_keys($mappings))]));
}
}
......
......@@ -70,9 +70,9 @@ public function getMatchingContexts(array $contexts, ContextDefinitionInterface
* match the plugin's context definitions.
* @param array $mappings
* (optional) A mapping of the expected assignment names to their context
* names. For example, if one of the $contexts is named 'entity', but the
* plugin expects a context named 'node', then this map would contain
* 'entity' => 'node'.
* names. For example, if one of the $contexts is named 'current_user', but the
* plugin expects a context named 'user', then this map would contain
* 'user' => 'current_user'.
*
* @throws \Drupal\Component\Plugin\Exception\ContextException
* Thrown when a context assignment was not satisfied.
......
......@@ -55,7 +55,7 @@ public function setContext($name, ComponentContextInterface $context) {
*/
public function getContextMapping() {
$configuration = $this instanceof ConfigurablePluginInterface ? $this->getConfiguration() : $this->configuration;
return isset($configuration['context_mapping']) ? array_flip($configuration['context_mapping']) : [];
return isset($configuration['context_mapping']) ? $configuration['context_mapping'] : [];
}
/**
......
<?php
/**
* @file
* Contains \Drupal\condition_test\Plugin\Condition\ConditionTestDualUser.
*/
namespace Drupal\condition_test\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
/**
* Provides a condition that requires two users.
*
* @Condition(
* id = "condition_test_dual_user",
* label = @Translation("Dual user"),
* context = {
* "user1" = @ContextDefinition("entity:user", label = @Translation("User 1")),
* "user2" = @ContextDefinition("entity:user", label = @Translation("User 2"))
* }
* )
*/
class ConditionTestDualUser extends ConditionPluginBase {
/**
* {@inheritdoc}
*/
public function evaluate() {
$user1 = $this->getContextValue('user1');
$user2 = $this->getContextValue('user2');
return $user1->id() === $user2->id();
}
/**
* {@inheritdoc}
*/
public function summary() {
return $this->t('This condition has two users.');
}
}
<?php
/**
* @file
* Contains \Drupal\condition_test\Tests\ConditionTestDualUserTest.
*/
namespace Drupal\condition_test\Tests;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\simpletest\KernelTestBase;
use Drupal\user\Entity\User;
/**
* Tests a condition that requires two users.
*
* @group condition_test
*/
class ConditionTestDualUserTest extends KernelTestBase {
/**
* An anonymous user for testing purposes.
*
* @var \Drupal\user\Entity\User
*/
protected $anonymous;
/**
* An authenticated user for testing purposes.
*
* @var \Drupal\user\Entity\User
*/
protected $authenticated;
/**
* {@inheritdoc}
*/
public static $modules = ['system', 'user', 'condition_test'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('system', 'sequences');
$this->installEntitySchema('user');
$this->anonymous = User::create(['uid' => 0]);
$this->authenticated = User::create(['uid' => 1]);
}
/**
* Tests the dual user condition.
*/
public function testConditions() {
$this->doTestIdenticalUser();
$this->doTestDifferentUser();
}
/**
* Tests with both contexts mapped to the same user.
*/
protected function doTestIdenticalUser() {
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
$condition = \Drupal::service('plugin.manager.condition')
->createInstance('condition_test_dual_user')
// Map the anonymous user to both contexts.
->setContextMapping([
'user1' => 'anonymous',
'user2' => 'anonymous',
]);
$definition = new ContextDefinition('entity:user');
$contexts['anonymous'] = (new Context($definition))->setContextValue($this->anonymous);
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
$this->assertTrue($condition->execute());
}
/**
* Tests with each context mapped to different users.
*/
protected function doTestDifferentUser() {
/** @var \Drupal\Core\Condition\ConditionPluginBase $condition */
$condition = \Drupal::service('plugin.manager.condition')
->createInstance('condition_test_dual_user')
->setContextMapping([
'user1' => 'anonymous',
'user2' => 'authenticated',
]);
$definition = new ContextDefinition('entity:user');
$contexts['anonymous'] = (new Context($definition))->setContextValue($this->anonymous);
$contexts['authenticated'] = (new Context($definition))->setContextValue($this->authenticated);
\Drupal::service('context.handler')->applyContextMapping($condition, $contexts);
$this->assertFalse($condition->execute());
}
}
......@@ -305,7 +305,7 @@ public function testApplyContextMappingConfigurableAssigned() {
->method('setContextValue')
->with('hit', array('foo'));
$this->contextHandler->applyContextMapping($plugin, $contexts, array('name' => 'hit'));
$this->contextHandler->applyContextMapping($plugin, $contexts, ['hit' => 'name']);
}
/**
......@@ -333,7 +333,7 @@ public function testApplyContextMappingConfigurableAssignedMiss() {
$plugin->expects($this->never())
->method('setContextValue');
$this->contextHandler->applyContextMapping($plugin, $contexts, array('name' => 'miss'));
$this->contextHandler->applyContextMapping($plugin, $contexts, ['miss' => 'name']);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment