Commit 944203f4 authored by catch's avatar catch

Issue #2976356 by phenaproxima, amateescu, Sam152: Add a validation constraint...

Issue #2976356 by phenaproxima, amateescu, Sam152: Add a validation constraint to check if an entity has a field
parent 4784ac3d
<?php
namespace Drupal\Core\Entity\Plugin\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Checks if a value is an entity that has a specific field.
*
* @Constraint(
* id = "EntityHasField",
* label = @Translation("Entity has field", context = "Validation"),
* type = { "entity" },
* )
*/
class EntityHasFieldConstraint extends Constraint {
/**
* The default violation message.
*
* @var string
*/
public $message = 'The entity must have the %field_name field.';
/**
* The violation message for non-fieldable entities.
*
* @var string
*/
public $notFieldableMessage = 'The entity does not support fields.';
/**
* The field name option.
*
* @var string
*/
public $field_name;
/**
* {@inheritdoc}
*/
public function getDefaultOption() {
return 'field_name';
}
/**
* {@inheritdoc}
*/
public function getRequiredOptions() {
return (array) $this->getDefaultOption();
}
}
<?php
namespace Drupal\Core\Entity\Plugin\Validation\Constraint;
use Drupal\Core\Entity\FieldableEntityInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the EntityHasField constraint.
*/
class EntityHasFieldConstraintValidator extends ConstraintValidator {
/**
* {@inheritdoc}
*/
public function validate($entity, Constraint $constraint) {
if (!isset($entity)) {
return;
}
/** @var \Drupal\Core\Entity\Plugin\Validation\Constraint\EntityHasFieldConstraint $constraint */
if (!($entity instanceof FieldableEntityInterface)) {
$this->context->addViolation($constraint->notFieldableMessage);
return;
}
if (!$entity->hasField($constraint->field_name)) {
$this->context->addViolation($constraint->message, [
'%field_name' => $constraint->field_name,
]);
}
}
}
<?php
namespace Drupal\KernelTests\Core\Entity;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
/**
* @covers \Drupal\Core\Entity\Plugin\Validation\Constraint\EntityHasFieldConstraintValidator
*
* @group Entity
*/
class EntityHasFieldConstraintValidatorTest extends EntityKernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['entity_test_constraints'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installEntitySchema('entity_test_constraints');
$this->createUser();
}
public function testValidation() {
$this->state->set('entity_test_constraints.build', [
'EntityHasField' => 'body',
]);
/** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
$entity_type_manager = $this->container->get('entity_type.manager');
$entity_type_manager->clearCachedDefinitions();
// Clear the typed data cache so that the entity has the correct constraints
// during validation.
$this->container->get('typed_data_manager')->clearCachedDefinitions();
$storage = $entity_type_manager->getStorage('entity_test_constraints');
/** @var \Drupal\entity_test\Entity\EntityTestConstraints $entity */
$entity = $storage->create();
// We should get a violation if we try to validate the entity before the
// field has been created.
$violations = $entity->validate();
$this->assertCount(1, $violations);
$this->assertEquals($violations[0]->getMessage(), 'The entity must have the <em class="placeholder">body</em> field.');
$storage->save($entity);
// Create the field.
$field_storage = FieldStorageConfig::create([
'type' => 'string',
'entity_type' => $entity->getEntityTypeId(),
'field_name' => 'body',
]);
$field_storage->save();
FieldConfig::create([
'field_storage' => $field_storage,
'bundle' => $entity->bundle(),
])->save();
// Now that the field has been created, there should be no violations.
$this->assertCount(0, $storage->loadUnchanged(1)->validate());
}
}
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