iframe_consent-1.0.x-dev/src/Plugin/Validation/Constraint/IframeConsentDomainConstraintValidator.php
src/Plugin/Validation/Constraint/IframeConsentDomainConstraintValidator.php
<?php
declare(strict_types=1);
namespace Drupal\iframe_consent\Plugin\Validation\Constraint;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\iframe_consent\IframeConsentDomainInterface;
use Drupal\iframe_consent\Service\IframeConsentHelperInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
/**
* Validates the Domain constraint.
*/
final class IframeConsentDomainConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
/**
* Constructs the object.
*/
public function __construct(
private readonly IframeConsentHelperInterface $iframeConsentHelper,
) {}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self {
return new self(
$container->get('iframe_consent.helper'),
);
}
/**
* {@inheritdoc}
*/
public function validate(mixed $item, Constraint $constraint): void {
if (!$item instanceof FieldItemList) {
throw new \InvalidArgumentException(
sprintf('The validated value must be instance of \Drupal\Core\Field\FieldItemList, %s was given.', get_debug_type($item))
);
}
// Extract the domain value from the field.
$domains = $item->getValue();
foreach ($domains as $domain) {
$domain = $domain['value'] ?? '';
// Check if domain is empty.
if (empty($domain)) {
$this->context->addViolation($constraint->emptyMessage);
return;
}
// Ensure the domain starts with https.
$sanitized_domain = $this->iframeConsentHelper->cleanUri($domain);
if ($sanitized_domain !== $domain) {
$this->context->addViolation($constraint->httpsMessage, ['%domain' => $domain]);
return;
}
// Apply the same transformation as in the helper to get the same domain
// in all cases.
if ($this->iframeConsentHelper->cleanUri($domain) !== $domain) {
$this->context->addViolation($constraint->formatMessage, ['%domain' => $domain]);
return;
}
// Get the entity being validated.
$entity = $this->context->getRoot()->getValue();
// Query for existing entities with the same domain.
$query = $this->iframeConsentHelper->entityTypeManager->getQuery()
->accessCheck(TRUE)
->condition('domain', $domain);
// Exclude the current entity from the check if it's not new.
if ($entity instanceof IframeConsentDomainInterface && !$entity->isNew()) {
$query->condition('id', $entity->id(), '!=');
}
$existing_entities = $query->execute();
// Set error if duplicate domain is found.
if (!empty($existing_entities)) {
$this->context->addViolation($constraint->duplicateMessage, ['%domain' => $domain]);
}
}
}
}
