pm-4.1.x-dev/src/Plugin/Validation/Constraint/PmExclusiveChildConstraintValidator.php
src/Plugin/Validation/Constraint/PmExclusiveChildConstraintValidator.php
<?php
declare(strict_types=1);
namespace Drupal\pm\Plugin\Validation\Constraint;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemList;
use Drupal\pm\Service\PmConfig;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the Exclusive Child constraint.
*/
final class PmExclusiveChildConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
/**
* Constructs the object.
*/
public function __construct(
private readonly EntityTypeManagerInterface $entityTypeManager,
private readonly PmConfig $pmConfig
) {}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self {
return new self(
$container->get('entity_type.manager'),
$container->get('pm.config')
);
}
/**
* {@inheritdoc}
*/
public function validate(mixed $item, Constraint $constraint): void {
if (!$item instanceof EntityReferenceFieldItemList) {
throw new \InvalidArgumentException(
sprintf('The validated value must be instance of \Drupal\Core\Field\EntityReferenceFieldItemList, %s was given.', get_debug_type($item))
);
}
$entity = $item->getEntity();
$child_ref_field_name = $this->pmConfig->getChildReferenceFieldName($entity->getEntityTypeId(), $entity->bundle());
$storage = $this
->entityTypeManager
->getStorage($entity->getEntityTypeId());
$referenced_items = $item->referencedEntities();
$parent_id = $entity->id();
foreach ($referenced_items as $referenced_item) {
$ref_id = $referenced_item->id();
$count = $storage
->getQuery()
->accessCheck(FALSE)
->condition('id', $parent_id, '<>')
->condition($child_ref_field_name, $ref_id)
->count()
->execute();
if ($count) {
$this->context->addViolation($constraint->message, [
'%label' => $referenced_item->label(),
'%id' => $referenced_item->id(),
'%parent_label' => $entity->getEntityType()->getLabel(),
]);
}
}
}
}
