diff --git a/src/Plugin/DataType/DynamicEntityReference.php b/src/Plugin/DataType/DynamicEntityReference.php index 62ddcec..637df5d 100644 --- a/src/Plugin/DataType/DynamicEntityReference.php +++ b/src/Plugin/DataType/DynamicEntityReference.php @@ -69,6 +69,7 @@ class DynamicEntityReference extends EntityReference { * need validation. */ public function getConstraints() { + /* @var \Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceFieldItemList $field */ $field = $this->parent->parent; $values = $this->parent->getValue(); // We cannot validate the bundle until we know the target-type of this diff --git a/src/Plugin/Field/FieldType/DynamicEntityReferenceFieldItemList.php b/src/Plugin/Field/FieldType/DynamicEntityReferenceFieldItemList.php index 12f76ab..8bd818b 100644 --- a/src/Plugin/Field/FieldType/DynamicEntityReferenceFieldItemList.php +++ b/src/Plugin/Field/FieldType/DynamicEntityReferenceFieldItemList.php @@ -129,24 +129,4 @@ class DynamicEntityReferenceFieldItemList extends EntityReferenceFieldItemList { return $default_value; } - /** - * {@inheritdoc} - * - * When we validate the list, we make sure to give each item a chance to - * validate itself, as depending on the selected target type, we might need - * to apply bundle validation. - */ - public function validate() { - $return = NULL; - foreach ($this->list as $item) { - if (!$return) { - $return = $item->validate(); - } - else { - $return->addAll($item->validate()); - } - } - return $return; - } - } diff --git a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php index e0ea192..a1792ad 100644 --- a/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php +++ b/src/Plugin/Field/FieldType/DynamicEntityReferenceItem.php @@ -472,17 +472,4 @@ class DynamicEntityReferenceItem extends ConfigurableEntityReferenceItem { return $target_types; } - /** - * {@inheritdoc} - * - * When we validate the item, we make sure to validate the entity property, as - * depending on the selected target type, we might need to apply bundle - * validation. - */ - public function validate() { - $return = parent::validate(); - $return->addAll($this->get('entity')->validate()); - return $return; - } - } diff --git a/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraint.php b/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraint.php index 7d8a669..6c6b8a6 100644 --- a/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraint.php +++ b/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraint.php @@ -28,5 +28,6 @@ class ValidDynamicReferenceConstraint extends Constraint { */ public $wrongIDMessage = 'The referenced entity (%type: %id) does not exist.'; public $wrongTypeMessage = 'The referenced entity type (%type) is not allowed for this field.'; + public $wrongBundleMessage = 'The entity must be of bundle %bundle.'; } diff --git a/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraintValidator.php b/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraintValidator.php index 70e822b..5767bb2 100644 --- a/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraintValidator.php +++ b/src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraintValidator.php @@ -40,7 +40,43 @@ class ValidDynamicReferenceConstraintValidator extends ConstraintValidator { $referenced_entity = $value->get('entity')->getValue(); if (!$referenced_entity) { $this->context->addViolation($constraint->wrongIDMessage, array('%type' => $type, '%id' => $id)); + return; + } + // Get the handler settings for the target type of this item. + $target_type_settings = $value->getParent()->getSetting($type); + if (isset($target_type_settings['handler_settings']['target_bundles'])) { + if (!in_array($referenced_entity->bundle(), $target_type_settings['handler_settings']['target_bundles'], TRUE)) { + $this->context->addViolation($constraint->wrongBundleMessage, array('%bundle' => $referenced_entity->bundle())); + return; + } } + } + /** + * {@inheritdoc} + * + * The field-item list and the field-item refer validation of bundles to the + * entity property, as depending on the selected target-type, the bundle may + * need validation. + */ + public function getConstraints() { + /* @var \Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceFieldItemList $field */ + $field = $this->parent->parent; + $values = $this->parent->getValue(); + // We cannot validate the bundle until we know the target-type of this + // item. + if (isset($values['target_type'])) { + $target_type = $values['target_type']; + // Get the handler settings for the target type of this item. + $target_type_settings = $field->getSetting($target_type); + if (isset($target_type_settings['handler_settings']['target_bundles'])) { + // Add the constraint to limit the bundles of this item. + $this->definition->addConstraint('Bundle', ['bundle' => $target_type_settings['handler_settings']['target_bundles']]); + } + } + $constraints = parent::getConstraints(); + return $constraints; + } + } diff --git a/src/Tests/DynamicEntityReferenceFieldTest.php b/src/Tests/DynamicEntityReferenceFieldTest.php index 812837c..d33e111 100644 --- a/src/Tests/DynamicEntityReferenceFieldTest.php +++ b/src/Tests/DynamicEntityReferenceFieldTest.php @@ -116,7 +116,9 @@ class DynamicEntityReferenceFieldTest extends EntityUnitTestBase { $violations = $entity->{$this->fieldName}->validate(); $this->assertEqual($violations->count(), 0, 'Validation passes.'); - $entity = entity_create($this->entityType, array('type' => $this->bundle)); + $entity = $entity_manager + ->getStorage($this->entityType) + ->create(['type' => $this->bundle]); $entity->{$this->fieldName}->entity = $referenced_entity; $violations = $entity->{$this->fieldName}->validate(); $this->assertEqual($violations->count(), 0, 'Validation passes.'); @@ -142,12 +144,14 @@ class DynamicEntityReferenceFieldTest extends EntityUnitTestBase { $this->assertEqual($violations[0]->getMessage(), t('The referenced entity type (%type) is not allowed for this field.', array('%type' => $entity->getEntityTypeId(), '%id' => -1))); // Test an invalid bundle. - $dud_referenced_entity = entity_create($this->referencedEntityType, array('type' => 'dud')); + $dud_referenced_entity = $entity_manager + ->getStorage($this->referencedEntityType) + ->create(['type' => 'dud']); $dud_referenced_entity->save(); $entity->{$this->fieldName}->entity = $dud_referenced_entity; $violations = $entity->{$this->fieldName}->validate(); $this->assertEqual($violations->count(), 1, 'Validation throws a violation.'); - $this->assertEqual($violations[0]->getMessage(), t('The entity must be of bundle %bundle.', array('%bundle' => 'entity_test'))); + $this->assertEqual($violations[0]->getMessage(), t('The entity must be of bundle %bundle.', array('%bundle' => 'dud'))); } /**