ValidDynamicReferenceConstraintValidator.php in Dynamic Entity Reference 8
File
src/Plugin/Validation/Constraint/ValidDynamicReferenceConstraintValidator.php
View source
<?php
namespace Drupal\dynamic_entity_reference\Plugin\Validation\Constraint;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\dynamic_entity_reference\Plugin\Field\FieldType\DynamicEntityReferenceItem;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ValidDynamicReferenceConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
protected $selectionManager;
protected $entityTypeManager;
public function __construct(SelectionPluginManagerInterface $selection_manager, EntityTypeManagerInterface $entity_type_manager) {
$this->selectionManager = $selection_manager;
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.dynamic_entity_reference_selection'), $container
->get('entity_type.manager'));
}
public function validate($value, Constraint $constraint) {
if (!isset($value)) {
return;
}
$new_entities = [];
$target_ids = [];
$target_types = [];
$valid_target_types = DynamicEntityReferenceItem::getTargetTypes($value
->getFieldDefinition()
->getSettings());
foreach ($value as $delta => $item) {
if (!$item
->isEmpty() && ($item->target_id === NULL || $item->target_type === NULL)) {
$property = $item->target_id ? 'target_type' : 'target_id';
if (!$item->entity
->isNew()) {
$this->context
->buildViolation($constraint->nullMessage)
->setParameter('%property', $property)
->atPath((string) $delta . '.' . $property)
->addViolation();
continue;
}
$new_entities[$delta] = $item->entity;
}
$valid_type = empty($item->target_type) || !empty($item->target_type) && DynamicEntityReferenceItem::entityHasIntegerId($item->target_type) && in_array($item->target_type, $valid_target_types);
if (!$valid_type) {
if (isset($new_entities[$delta])) {
unset($new_entities[$delta]);
}
$this->context
->buildViolation($constraint->wrongTypeMessage)
->setParameter('%type', $item->target_type)
->atPath((string) $delta . '.target_type')
->setInvalidValue($item->target_type)
->addViolation();
continue;
}
if (!empty($item->target_id)) {
$target_ids[$delta] = $item->target_id;
}
$target_types[$delta] = $item->target_type;
}
$valid_entities = [];
$entity = !empty($value
->getParent()) ? $value
->getEntity() : NULL;
foreach ($new_entities as $delta => $new_entity) {
$handler = $this->selectionManager
->getSelectionHandler($value
->getFieldDefinition(), $entity, $target_types[$delta]);
if ($handler instanceof SelectionWithAutocreateInterface && ($new_entity
->getEntityTypeId() == $target_types[$delta] || empty($target_types[$delta]))) {
if (!$handler
->validateReferenceableNewEntities([
$new_entity,
])) {
$this->context
->buildViolation($constraint->invalidAutocreateMessage)
->setParameter('%type', $new_entity
->getEntityTypeId())
->setParameter('%label', $new_entity
->label())
->atPath((string) $delta . '.entity')
->setInvalidValue($new_entity)
->addViolation();
continue;
}
}
$valid_entities[$delta] = $new_entity;
}
foreach ($target_ids as $delta => $target_id) {
$definition = $this->entityTypeManager
->getDefinition($target_types[$delta]);
$existing_id = $this->entityTypeManager
->getStorage($target_types[$delta])
->getQuery()
->accessCheck(FALSE)
->condition($definition
->getKey('id'), $target_id)
->execute();
if (!$existing_id) {
$this->context
->buildViolation($constraint->nonExistingMessage)
->setParameter('%type', $target_types[$delta])
->setParameter('%id', $target_id)
->atPath((string) $delta . '.target_id')
->setInvalidValue($target_id)
->addViolation();
unset($target_ids[$delta]);
continue;
}
$valid_entities[$delta] = $this->entityTypeManager
->getStorage($target_types[$delta])
->load($target_id);
}
foreach ($valid_entities as $delta => $entity) {
if (array_key_exists('target_bundles', $value
->getFieldDefinition()
->getSetting($target_types[$delta])['handler_settings'])) {
$valid_bundle = FALSE;
$target_bundles = $value
->getFieldDefinition()
->getSetting($target_types[$delta])['handler_settings']['target_bundles'];
if ($target_bundles === []) {
$this->context
->buildViolation($constraint->noBundleAllowed)
->setParameter('%type', $target_types[$delta])
->atPath((string) $delta . '.entity')
->setInvalidValue($entity)
->addViolation();
if (isset($target_ids[$delta])) {
unset($target_ids[$delta]);
}
continue;
}
if ($target_bundles === NULL || in_array($entity
->bundle(), $target_bundles)) {
$valid_bundle = TRUE;
}
if (!$valid_bundle) {
$this->context
->buildViolation($constraint->wrongBundleMessage)
->setParameter('%label', $entity
->label())
->setParameter('%bundles', implode(', ', $target_bundles))
->atPath((string) $delta . '.entity')
->setInvalidValue($entity)
->addViolation();
if (isset($target_ids[$delta])) {
unset($target_ids[$delta]);
}
}
}
}
foreach ($target_ids as $delta => $id) {
$handler = $this->selectionManager
->getSelectionHandler($value
->getFieldDefinition(), $entity, $target_types[$delta]);
$valid_target_id = $handler
->validateReferenceableEntities([
$id,
]);
if (!$valid_target_id) {
$this->context
->buildViolation($constraint->message)
->setParameter('%type', $target_types[$delta])
->setParameter('%id', $id)
->atPath((string) $delta . '.target_id')
->setInvalidValue($id)
->addViolation();
}
}
}
}