Unverified Commit 96014160 authored by alexpott's avatar alexpott

Issue #3008431 by tim.plunkett, phenaproxima, Wim Leers: A context object for...

Issue #3008431 by tim.plunkett, phenaproxima, Wim Leers: A context object for a specific entity type will not match a generic requirement for any entity
parent b6779d93
......@@ -312,14 +312,36 @@ public function getDataDefinition() {
return $definition;
}
/**
* Checks if this definition's data type matches that of the given context.
*
* @param \Drupal\Core\Plugin\Context\ContextInterface $context
* The context to test against.
*
* @return bool
* TRUE if the data types match, otherwise FALSE.
*/
protected function dataTypeMatches(ContextInterface $context) {
$this_type = $this->getDataType();
$that_type = $context->getContextDefinition()->getDataType();
return (
// 'any' means all data types are supported.
$this_type === 'any' ||
$this_type === $that_type ||
// Allow a more generic data type like 'entity' to be fulfilled by a more
// specific data type like 'entity:user'. However, if this type is more
// specific, do not consider a more generic type to be a match.
strpos($that_type, "$this_type:") === 0
);
}
/**
* {@inheritdoc}
*/
public function isSatisfiedBy(ContextInterface $context) {
$definition = $context->getContextDefinition();
// If the data types do not match, this context is invalid unless the
// expected data type is any, which means all data types are supported.
if ($this->getDataType() != 'any' && $definition->getDataType() != $this->getDataType()) {
if (!$this->dataTypeMatches($context)) {
return FALSE;
}
......
......@@ -29,6 +29,7 @@ protected function setUp() {
$namespaces = new \ArrayObject([
'Drupal\\Core\\TypedData' => $this->root . '/core/lib/Drupal/Core/TypedData',
'Drupal\\Core\\Validation' => $this->root . '/core/lib/Drupal/Core/Validation',
'Drupal\\Tests\\Core\\Plugin\\Fixtures' => $this->root . '/core/tests/Drupal/Tests/Core/Plugin/Fixtures',
]);
$cache_backend = new NullBackend('cache');
$module_handler = $this->prophesize(ModuleHandlerInterface::class);
......@@ -60,6 +61,7 @@ protected function setUp() {
* (optional) The value to set on the context, defaults to NULL.
*
* @covers ::isSatisfiedBy
* @covers ::dataTypeMatches
* @covers ::getSampleValues
* @covers ::getConstraintObjects
*
......@@ -116,6 +118,16 @@ public function providerTestIsSatisfiedBy() {
new InheritedContextDefinition('any'),
new ContextDefinition('any'),
];
$data['specific definition, generic requirement'] = [
TRUE,
new ContextDefinition('test_data_type'),
new ContextDefinition('test_data_type:a_variant'),
];
$data['generic definition, specific requirement'] = [
FALSE,
new ContextDefinition('test_data_type:a_variant'),
new ContextDefinition('test_data_type'),
];
return $data;
}
......
......@@ -13,6 +13,7 @@
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\EntityContext;
use Drupal\Core\Plugin\Context\EntityContextDefinition;
use Drupal\Core\TypedData\TypedDataManager;
......@@ -95,19 +96,20 @@ protected function setUp() {
* @param mixed $value
* (optional) The value to set on the context, defaults to NULL.
*/
protected function assertRequirementIsSatisfied($expected, EntityContextDefinition $requirement, EntityContextDefinition $definition, $value = NULL) {
protected function assertRequirementIsSatisfied($expected, ContextDefinition $requirement, ContextDefinition $definition, $value = NULL) {
$context = new EntityContext($definition, $value);
$this->assertSame($expected, $requirement->isSatisfiedBy($context));
}
/**
* @covers ::isSatisfiedBy
* @covers ::dataTypeMatches
* @covers ::getSampleValues
* @covers ::getConstraintObjects
*
* @dataProvider providerTestIsSatisfiedBy
*/
public function testIsSatisfiedBy($expected, EntityContextDefinition $requirement, EntityContextDefinition $definition, $value = NULL) {
public function testIsSatisfiedBy($expected, ContextDefinition $requirement, ContextDefinition $definition, $value = NULL) {
$entity_storage = $this->prophesize(EntityStorageInterface::class);
$content_entity_storage = $this->prophesize(ContentEntityStorageInterface::class);
$this->entityTypeManager->getStorage('test_config')->willReturn($entity_storage->reveal());
......@@ -169,12 +171,23 @@ public function providerTestIsSatisfiedBy() {
EntityContextDefinition::fromEntityType($config),
EntityContextDefinition::fromEntityType($config),
];
$data['generic entity requirement, specific context'] = [
TRUE,
new ContextDefinition('entity'),
EntityContextDefinition::fromEntityType($config),
];
$data['specific requirement, generic entity context'] = [
FALSE,
EntityContextDefinition::fromEntityType($content),
new ContextDefinition('entity'),
];
return $data;
}
/**
* @covers ::isSatisfiedBy
* @covers ::dataTypeMatches
* @covers ::getSampleValues
* @covers ::getConstraintObjects
*
......@@ -271,6 +284,7 @@ public function providerTestIsSatisfiedByGenerateBundledEntity() {
/**
* @covers ::isSatisfiedBy
* @covers ::dataTypeMatches
* @covers ::getSampleValues
* @covers ::getConstraintObjects
*
......
<?php
namespace Drupal\Tests\Core\Plugin\Fixtures\Plugin\DataType;
use Drupal\Core\TypedData\TypedData;
/**
* Provides a test data type.
*
* @DataType(
* id = "test_data_type",
* label = @Translation("Test data type"),
* deriver = "Drupal\Tests\Core\Plugin\Fixtures\Plugin\DataType\TestDataTypeDeriver"
* )
*/
class TestDataType extends TypedData {
/**
* Required by the parent class.
*
* @var mixed
*/
protected $value;
}
<?php
namespace Drupal\Tests\Core\Plugin\Fixtures\Plugin\DataType;
use Drupal\Component\Plugin\Derivative\DeriverBase;
/**
* Provides a deriver that returns a plugin for the bare ID and one variant.
*/
class TestDataTypeDeriver extends DeriverBase {
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
foreach (['', 'a_variant'] as $item) {
$this->derivatives[$item] = $base_plugin_definition;
$this->derivatives[$item]['provider'] = 'core';
}
return $this->derivatives;
}
}
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