Issue #3393099 by kim.pepper, smustgrave, xjm, alexpott, longwave: Move ExecutionContext, ExecutionContextFactory, and ConstraintViolationBuilder from TypedData to Validation namespace

merge-requests/6829/head
Alex Pott 2024-02-29 08:22:58 +00:00
parent f316821d4a
commit 36f2784c1d
No known key found for this signature in database
GPG Key ID: BDA67E7EE836E5CE
13 changed files with 509 additions and 517 deletions

View File

@ -8,11 +8,11 @@ use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\TypedData\Validation\ExecutionContextFactory;
use Drupal\Core\TypedData\Validation\RecursiveValidator;
use Drupal\Core\Validation\ConstraintManager;
use Drupal\Core\Validation\ConstraintValidatorFactory;
use Drupal\Core\Validation\DrupalTranslator;
use Drupal\Core\Validation\ExecutionContextFactory;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**

View File

@ -5,12 +5,10 @@ namespace Drupal\Core\TypedData\Validation;
// phpcs:ignoreFile Portions of this file are a direct copy of
// \Symfony\Component\Validator\Violation\ConstraintViolationBuilder.
use Drupal\Core\Validation\ConstraintViolationBuilder as NewConstraintViolationBuilder;
use Drupal\Core\Validation\TranslatorInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Util\PropertyPath;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
/**
* Defines a constraint violation builder for the Typed Data validator.
@ -18,84 +16,7 @@ use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
* We do not use the builder provided by Symfony as it is marked internal.
*
*/
class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface {
/**
* The list of violations.
*
* @var \Symfony\Component\Validator\ConstraintViolationList
*/
protected $violations;
/**
* The violation message.
*
* @var string
*/
protected $message;
/**
* The message parameters.
*
* @var array
*/
protected $parameters;
/**
* The root path.
*
* @var mixed
*/
protected $root;
/**
* The invalid value caused the violation.
*
* @var mixed
*/
protected $invalidValue;
/**
* The property path.
*
* @var string
*/
protected $propertyPath;
/**
* The translator.
*
* @var \Drupal\Core\Validation\TranslatorInterface
*/
protected $translator;
/**
* The translation domain.
*
* @var string|false|null
*/
protected $translationDomain;
/**
* The number used
* @var int|null
*/
protected $plural;
/**
* @var Constraint
*/
protected $constraint;
/**
* @var mixed
*/
protected $code;
/**
* @var mixed
*/
protected $cause;
class ConstraintViolationBuilder extends NewConstraintViolationBuilder {
/**
* Constructs a new ConstraintViolationBuilder instance.
@ -119,152 +40,9 @@ class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface
* @param null $translationDomain
* (optional) The translation domain.
*/
public function __construct(ConstraintViolationList $violations, Constraint $constraint, $message, array $parameters, $root, $propertyPath, $invalidValue, TranslatorInterface $translator, $translationDomain = null)
{
$this->violations = $violations;
$this->message = $message;
$this->parameters = $parameters;
$this->root = $root;
$this->propertyPath = $propertyPath;
$this->invalidValue = $invalidValue;
$this->translator = $translator;
$this->translationDomain = $translationDomain;
$this->constraint = $constraint;
}
/**
* {@inheritdoc}
*/
public function atPath($path): static
{
$this->propertyPath = PropertyPath::append($this->propertyPath, $path);
return $this;
}
/**
* {@inheritdoc}
*/
public function setParameter($key, $value): static
{
$this->parameters[$key] = $value;
return $this;
}
/**
* {@inheritdoc}
*/
public function setParameters(array $parameters): static
{
$this->parameters = $parameters;
return $this;
}
/**
* {@inheritdoc}
*/
public function setTranslationDomain($translationDomain): static
{
$this->translationDomain = $translationDomain;
return $this;
}
/**
* {@inheritdoc}
*/
public function setInvalidValue($invalidValue): static
{
$this->invalidValue = $invalidValue;
return $this;
}
/**
* {@inheritdoc}
*/
public function setPlural($number): static
{
$this->plural = $number;
return $this;
}
/**
* {@inheritdoc}
*/
public function setCode($code): static
{
$this->code = $code;
return $this;
}
/**
* {@inheritdoc}
*/
public function setCause($cause): static
{
$this->cause = $cause;
return $this;
}
/**
* {@inheritdoc}
*
* phpcs:ignore Drupal.Commenting.FunctionComment.VoidReturn
* @return void
*/
public function addViolation()
{
if (null === $this->plural) {
$translatedMessage = $this->translator->trans(
$this->message,
$this->parameters,
$this->translationDomain
);
} else {
try {
$translatedMessage = $this->translator->transChoice(
$this->message,
$this->plural,
$this->parameters,
$this->translationDomain#
);
} catch (\InvalidArgumentException $e) {
$translatedMessage = $this->translator->trans(
$this->message,
$this->parameters,
$this->translationDomain
);
}
}
$this->violations->add(new ConstraintViolation(
$translatedMessage,
$this->message,
$this->parameters,
$this->root,
$this->propertyPath,
$this->invalidValue,
$this->plural,
$this->code,
$this->constraint,
$this->cause
));
}
/**
* {@inheritdoc}
*/
public function disableTranslation(): static
{
$this->translationDomain = false;
return $this;
public function __construct(ConstraintViolationList $violations, Constraint $constraint, $message, array $parameters, $root, $propertyPath, $invalidValue, TranslatorInterface $translator, $translationDomain = null) {
@trigger_error(__CLASS__ . ' is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Instead, use \Drupal\Core\Validation\ConstraintViolationBuilder. See https://www.drupal.org/node/3396238', E_USER_DEPRECATED);
parent::__construct($violations, $constraint, $message, $parameters, $root, $propertyPath, $invalidValue, $translator, $translationDomain);
}
}

View File

@ -2,15 +2,8 @@
namespace Drupal\Core\TypedData\Validation;
use Drupal\Core\Validation\ExecutionContext as NewExecutionContext;
use Drupal\Core\Validation\TranslatorInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Mapping\MetadataInterface;
use Symfony\Component\Validator\Util\PropertyPath;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
@ -20,92 +13,7 @@ use Symfony\Component\Validator\Validator\ValidatorInterface;
* this class is pretty much the same, but has some code style changes as well
* as exceptions for methods we don't support.
*/
class ExecutionContext implements ExecutionContextInterface {
/**
* @var \Symfony\Component\Validator\Validator\ValidatorInterface
*/
protected $validator;
/**
* The root value of the validated object graph.
*
* @var mixed
*/
protected $root;
/**
* @var \Drupal\Core\Validation\TranslatorInterface
*/
protected $translator;
/**
* @var string
*/
protected $translationDomain;
/**
* The violations generated in the current context.
*
* @var \Symfony\Component\Validator\ConstraintViolationList
*/
protected $violations;
/**
* The currently validated value.
*
* @var mixed
*/
protected $value;
/**
* The currently validated typed data object.
*
* @var \Drupal\Core\TypedData\TypedDataInterface
*/
protected $data;
/**
* The property path leading to the current value.
*
* @var string
*/
protected $propertyPath = '';
/**
* The current validation metadata.
*
* @var \Symfony\Component\Validator\Mapping\MetadataInterface|null
*/
protected $metadata;
/**
* The currently validated group.
*
* @var string|null
*/
protected $group;
/**
* The currently validated constraint.
*
* @var \Symfony\Component\Validator\Constraint|null
*/
protected $constraint;
/**
* Stores which objects have been validated in which group.
*
* @var array
*/
protected $validatedObjects = [];
/**
* Stores which class constraint has been validated for which object.
*
* @var array
*/
protected $validatedConstraints = [];
class ExecutionContext extends NewExecutionContext {
/**
* Creates a new ExecutionContext.
@ -119,168 +27,12 @@ class ExecutionContext implements ExecutionContextInterface {
* @param string $translationDomain
* (optional) The translation domain.
*
* @internal Called by \Drupal\Core\TypedData\Validation\ExecutionContextFactory.
* @internal Called by \Drupal\Core\Validation\ExecutionContextFactory.
* Should not be used in user code.
*/
public function __construct(ValidatorInterface $validator, $root, TranslatorInterface $translator, $translationDomain = NULL) {
$this->validator = $validator;
$this->root = $root;
$this->translator = $translator;
$this->translationDomain = $translationDomain;
$this->violations = new ConstraintViolationList();
}
/**
* {@inheritdoc}
*/
public function setNode($value, $object, MetadataInterface $metadata = NULL, $propertyPath): void {
$this->value = $value;
$this->data = $object;
$this->metadata = $metadata;
$this->propertyPath = (string) $propertyPath;
}
/**
* {@inheritdoc}
*/
public function setGroup($group): void {
$this->group = $group;
}
/**
* {@inheritdoc}
*/
public function setConstraint(Constraint $constraint): void {
$this->constraint = $constraint;
}
/**
* {@inheritdoc}
*
* phpcs:ignore Drupal.Commenting.FunctionComment.VoidReturn
* @return void
*/
public function addViolation($message, array $parameters = []) {
$this->violations->add(new ConstraintViolation($this->translator->trans($message, $parameters, $this->translationDomain), $message, $parameters, $this->root, $this->propertyPath, $this->value, NULL, NULL, $this->constraint));
}
/**
* {@inheritdoc}
*/
public function buildViolation($message, array $parameters = []): ConstraintViolationBuilderInterface {
return new ConstraintViolationBuilder($this->violations, $this->constraint, $message, $parameters, $this->root, $this->propertyPath, $this->value, $this->translator, $this->translationDomain);
}
/**
* {@inheritdoc}
*/
public function getViolations(): ConstraintViolationListInterface {
return $this->violations;
}
/**
* {@inheritdoc}
*/
public function getValidator(): ValidatorInterface {
return $this->validator;
}
/**
* {@inheritdoc}
*/
public function getRoot(): mixed {
return $this->root;
}
/**
* {@inheritdoc}
*/
public function getValue(): mixed {
return $this->value;
}
/**
* {@inheritdoc}
*/
public function getObject(): ?object {
return $this->data;
}
/**
* {@inheritdoc}
*/
public function getMetadata(): ?MetadataInterface {
return $this->metadata;
}
/**
* {@inheritdoc}
*/
public function getGroup(): ?string {
return Constraint::DEFAULT_GROUP;
}
/**
* {@inheritdoc}
*/
public function getClassName(): ?string {
return get_class($this->data);
}
/**
* {@inheritdoc}
*/
public function getPropertyName(): ?string {
return $this->data->getName();
}
/**
* {@inheritdoc}
*/
public function getPropertyPath($sub_path = ''): string {
return PropertyPath::append($this->propertyPath, $sub_path);
}
/**
* {@inheritdoc}
*/
public function markConstraintAsValidated($cache_key, $constraint_hash): void {
$this->validatedConstraints[$cache_key . ':' . $constraint_hash] = TRUE;
}
/**
* {@inheritdoc}
*/
public function isConstraintValidated($cache_key, $constraint_hash): bool {
return isset($this->validatedConstraints[$cache_key . ':' . $constraint_hash]);
}
/**
* {@inheritdoc}
*/
public function markGroupAsValidated($cache_key, $group_hash): void {
$this->validatedObjects[$cache_key][$group_hash] = TRUE;
}
/**
* {@inheritdoc}
*/
public function isGroupValidated($cache_key, $group_hash): bool {
return isset($this->validatedObjects[$cache_key][$group_hash]);
}
/**
* {@inheritdoc}
*/
public function markObjectAsInitialized($cache_key): void {
throw new \LogicException('\Symfony\Component\Validator\Context\ExecutionContextInterface::markObjectAsInitialized is unsupported.');
}
/**
* {@inheritdoc}
*/
public function isObjectInitialized($cache_key): bool {
throw new \LogicException('\Symfony\Component\Validator\Context\ExecutionContextInterface::isObjectInitialized is unsupported.');
@trigger_error(__CLASS__ . ' is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Instead, use \Drupal\Core\Validation\ExecutionContext. See https://www.drupal.org/node/3396238', E_USER_DEPRECATED);
parent::__construct($validator, $root, $translator, $translationDomain);
}
}

View File

@ -2,27 +2,15 @@
namespace Drupal\Core\TypedData\Validation;
use Drupal\Core\Validation\ExecutionContextFactory as NewExecutionContextFactory;
use Drupal\Core\Validation\TranslatorInterface;
use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Defines an execution factory for the Typed Data validator.
*
* We do not use the factory provided by Symfony as it is marked internal.
*/
class ExecutionContextFactory implements ExecutionContextFactoryInterface {
/**
* @var \Drupal\Core\Validation\TranslatorInterface
*/
protected $translator;
/**
* @var string|null
*/
protected $translationDomain;
class ExecutionContextFactory extends NewExecutionContextFactory {
/**
* Constructs a new ExecutionContextFactory instance.
@ -33,20 +21,8 @@ class ExecutionContextFactory implements ExecutionContextFactoryInterface {
* (optional) The translation domain.
*/
public function __construct(TranslatorInterface $translator, $translationDomain = NULL) {
$this->translator = $translator;
$this->translationDomain = $translationDomain;
}
/**
* {@inheritdoc}
*/
public function createContext(ValidatorInterface $validator, $root): ExecutionContextInterface {
return new ExecutionContext(
$validator,
$root,
$this->translator,
$this->translationDomain
);
@trigger_error(__CLASS__ . ' is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Instead, use \Drupal\Core\Validation\ExecutionContextFactory. See https://www.drupal.org/node/3396238', E_USER_DEPRECATED);
parent::__construct($translator, $translationDomain);
}
}

View File

@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Drupal\Core\Validation;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\TypedData\Validation\ExecutionContextFactory;
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
use Symfony\Component\Validator\Validator\RecursiveValidator;

View File

@ -0,0 +1,198 @@
<?php
namespace Drupal\Core\Validation;
// phpcs:ignoreFile Portions of this file are a direct copy of
// \Symfony\Component\Validator\Violation\ConstraintViolationBuilder.
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Util\PropertyPath;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
/**
* A constraint violation builder for the basic Symfony validator.
*
* We do not use the builder provided by Symfony as it is marked internal.
*
*/
class ConstraintViolationBuilder implements ConstraintViolationBuilderInterface {
/**
* The number used
*/
protected ?int $plural = NULL;
/**
* The code.
*/
protected mixed $code = NULL;
/**
* The cause.
*/
protected mixed $cause = NULL;
/**
* Constructs a new ConstraintViolationBuilder instance.
*
* @param \Symfony\Component\Validator\ConstraintViolationList $violations
* The violation list.
* @param \Symfony\Component\Validator\Constraint $constraint
* The constraint.
* @param string $message
* The message.
* @param array $parameters
* The message parameters.
* @param mixed $root
* The root.
* @param string $propertyPath
* The property string.
* @param mixed $invalidValue
* The invalid value.
* @param \Drupal\Core\Validation\TranslatorInterface $translator
* The translator.
* @param string|false|null $translationDomain
* (optional) The translation domain.
*/
public function __construct(
protected ConstraintViolationList $violations,
protected Constraint $constraint,
protected string $message,
protected array $parameters,
protected mixed $root,
protected string $propertyPath,
protected mixed $invalidValue,
protected TranslatorInterface $translator,
protected string | false | null $translationDomain = NULL
) {}
/**
* {@inheritdoc}
*/
public function atPath(mixed $path): static {
if (!is_string($path)) {
@\trigger_error('Passing the $path parameter as a non-string value to ' . __METHOD__ . '() is deprecated in drupal:10.3.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3396238', E_USER_DEPRECATED);
}
$this->propertyPath = PropertyPath::append($this->propertyPath, (string) $path);
return $this;
}
/**
* {@inheritdoc}
*/
public function setParameter(string $key, mixed $value): static {
$this->parameters[$key] = $value;
return $this;
}
/**
* {@inheritdoc}
*/
public function setParameters(array $parameters): static {
$this->parameters = $parameters;
return $this;
}
/**
* {@inheritdoc}
*/
public function setTranslationDomain(string $translationDomain): static {
$this->translationDomain = $translationDomain;
return $this;
}
/**
* {@inheritdoc}
*/
public function setInvalidValue(mixed $invalidValue): static {
$this->invalidValue = $invalidValue;
return $this;
}
/**
* {@inheritdoc}
*/
public function setPlural(int $number): static {
$this->plural = $number;
return $this;
}
/**
* {@inheritdoc}
*/
public function setCode(?string $code): static {
$this->code = $code;
return $this;
}
/**
* {@inheritdoc}
*/
public function setCause(mixed $cause): static {
$this->cause = $cause;
return $this;
}
/**
* {@inheritdoc}
*/
public function addViolation(): void {
if (NULL === $this->plural) {
$translatedMessage = $this->translator->trans(
$this->message,
$this->parameters,
$this->translationDomain
);
}
else {
try {
$translatedMessage = $this->translator->transChoice(
$this->message,
$this->plural,
$this->parameters,
$this->translationDomain#
);
}
catch (\InvalidArgumentException $e) {
$translatedMessage = $this->translator->trans(
$this->message,
$this->parameters,
$this->translationDomain
);
}
}
$this->violations->add(new ConstraintViolation(
$translatedMessage,
$this->message,
$this->parameters,
$this->root,
$this->propertyPath,
$this->invalidValue,
$this->plural,
$this->code,
$this->constraint,
$this->cause
));
}
/**
* {@inheritdoc}
*/
public function disableTranslation(): static {
$this->translationDomain = FALSE;
return $this;
}
}

View File

@ -0,0 +1,248 @@
<?php
namespace Drupal\Core\Validation;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Mapping\MetadataInterface;
use Symfony\Component\Validator\Mapping\PropertyMetadataInterface;
use Symfony\Component\Validator\Util\PropertyPath;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface;
/**
* Defines an execution context class.
*
* We do not use the context provided by Symfony as it is marked internal, so
* this class is pretty much the same, but has some code style changes as well
* as exceptions for methods we don't support.
*/
class ExecutionContext implements ExecutionContextInterface {
/**
* The violations generated in the current context.
*/
protected ConstraintViolationList $violations;
/**
* The currently validated value.
*/
protected mixed $value = NULL;
/**
* The currently validated object.
*/
protected ?object $object = NULL;
/**
* The property path leading to the current value.
*/
protected string $propertyPath = '';
/**
* The current validation metadata.
*/
protected ?MetadataInterface $metadata = NULL;
/**
* The currently validated group.
*/
protected ?string $group;
/**
* The currently validated constraint.
*/
protected ?Constraint $constraint;
/**
* Stores which objects have been validated in which group.
*/
protected array $validatedObjects = [];
/**
* Stores which class constraint has been validated for which object.
*/
protected array $validatedConstraints = [];
/**
* Creates a new ExecutionContext.
*
* @param \Symfony\Component\Validator\Validator\ValidatorInterface $validator
* The validator.
* @param mixed $root
* The root.
* @param \Drupal\Core\Validation\TranslatorInterface $translator
* The translator.
* @param string|null $translationDomain
* (optional) The translation domain.
*
* @internal Called by \Drupal\Core\Validation\ExecutionContextFactory.
* Should not be used in user code.
*/
public function __construct(
protected ValidatorInterface $validator,
protected mixed $root,
protected TranslatorInterface $translator,
protected ?string $translationDomain = NULL
) {
$this->violations = new ConstraintViolationList();
}
/**
* {@inheritdoc}
*/
public function setNode(mixed $value, ?object $object, ?MetadataInterface $metadata, string $propertyPath): void {
$this->value = $value;
$this->object = $object;
$this->metadata = $metadata;
$this->propertyPath = $propertyPath;
}
/**
* {@inheritdoc}
*/
public function setConstraint(Constraint $constraint): void {
$this->constraint = $constraint;
}
/**
* {@inheritdoc}
*
* phpcs:ignore Drupal.Commenting.FunctionComment.VoidReturn
*
* @return void
*/
public function addViolation(string $message, array $params = []) {
$this->violations->add(new ConstraintViolation($this->translator->trans($message, $params, $this->translationDomain), $message, $params, $this->root, $this->propertyPath, $this->value, NULL, NULL, $this->constraint));
}
/**
* {@inheritdoc}
*/
public function buildViolation(string $message, array $parameters = []): ConstraintViolationBuilderInterface {
return new ConstraintViolationBuilder($this->violations, $this->constraint, $message, $parameters, $this->root, $this->propertyPath, $this->value, $this->translator, $this->translationDomain);
}
/**
* {@inheritdoc}
*/
public function getViolations(): ConstraintViolationListInterface {
return $this->violations;
}
/**
* {@inheritdoc}
*/
public function getValidator(): ValidatorInterface {
return $this->validator;
}
/**
* {@inheritdoc}
*/
public function getRoot(): mixed {
return $this->root;
}
/**
* {@inheritdoc}
*/
public function getValue(): mixed {
return $this->value;
}
/**
* {@inheritdoc}
*/
public function getObject(): ?object {
return $this->object;
}
/**
* {@inheritdoc}
*/
public function getMetadata(): ?MetadataInterface {
return $this->metadata;
}
/**
* {@inheritdoc}
*/
public function getGroup(): ?string {
return Constraint::DEFAULT_GROUP;
}
/**
* {@inheritdoc}
*/
public function setGroup(?string $group): void {
$this->group = $group;
}
/**
* {@inheritdoc}
*/
public function getClassName(): ?string {
return get_class($this->object);
}
/**
* {@inheritdoc}
*/
public function getPropertyName(): ?string {
return $this->metadata instanceof PropertyMetadataInterface ? $this->metadata->getPropertyName() : NULL;
}
/**
* {@inheritdoc}
*/
public function getPropertyPath(string $subPath = ''): string {
return PropertyPath::append($this->propertyPath, $subPath);
}
/**
* {@inheritdoc}
*/
public function markConstraintAsValidated(string $cacheKey, string $constraintHash): void {
$this->validatedConstraints[$cacheKey . ':' . $constraintHash] = TRUE;
}
/**
* {@inheritdoc}
*/
public function isConstraintValidated(string $cacheKey, string $constraintHash): bool {
return isset($this->validatedConstraints[$cacheKey . ':' . $constraintHash]);
}
/**
* {@inheritdoc}
*/
public function markGroupAsValidated(string $cacheKey, string $groupHash): void {
$this->validatedObjects[$cacheKey][$groupHash] = TRUE;
}
/**
* {@inheritdoc}
*/
public function isGroupValidated(string $cacheKey, string $groupHash): bool {
return isset($this->validatedObjects[$cacheKey][$groupHash]);
}
/**
* {@inheritdoc}
*/
public function markObjectAsInitialized(string $cacheKey): void {
throw new \LogicException(ExecutionContextInterface::class . '::markObjectAsInitialized is unsupported.');
}
/**
* {@inheritdoc}
*/
public function isObjectInitialized(string $cacheKey): bool {
throw new \LogicException(ExecutionContextInterface::class . '::isObjectInitialized is unsupported.');
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace Drupal\Core\Validation;
use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
/**
* Defines an execution factory for the Symfony validator.
*
* We do not use the factory provided by Symfony as it is marked internal.
*/
class ExecutionContextFactory implements ExecutionContextFactoryInterface {
/**
* Constructs a new ExecutionContextFactory instance.
*
* @param \Drupal\Core\Validation\TranslatorInterface $translator
* The translator instance.
* @param string|null $translationDomain
* (optional) The translation domain.
*/
public function __construct(
protected TranslatorInterface $translator,
protected ?string $translationDomain = NULL) {
}
/**
* {@inheritdoc}
*/
public function createContext(ValidatorInterface $validator, mixed $root): ExecutionContextInterface {
return new ExecutionContext(
$validator,
$root,
$this->translator,
$this->translationDomain
);
}
}

View File

@ -91,7 +91,7 @@ class UniqueFieldValueValidator extends ConstraintValidator implements Container
->setParameter('@field_name', $field_label)
->setParameter('%value', $dupe);
if ($is_multiple) {
$violation->atPath($delta);
$violation->atPath((string) $delta);
}
$violation->addViolation();
}
@ -106,7 +106,7 @@ class UniqueFieldValueValidator extends ConstraintValidator implements Container
->setParameter('@entity_type', $entity_label)
->setParameter('@field_name', $field_label)
->setParameter('%value', $dupe)
->atPath($delta)
->atPath((string) $delta)
->addViolation();
}
}

View File

@ -58,7 +58,7 @@ class ValidKeysConstraintValidator extends ConstraintValidator {
foreach ($invalid_keys as $key) {
$this->context->buildViolation($constraint->invalidKeyMessage)
->setParameter('@key', $key)
->atPath($key)
->atPath((string) $key)
->setInvalidValue($key)
->addViolation();
}

View File

@ -4,7 +4,7 @@ declare(strict_types = 1);
namespace Drupal\ckeditor5\Plugin\Validation\Constraint;
use Drupal\Core\TypedData\Validation\ExecutionContext;
use Drupal\Core\Validation\ExecutionContext;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintViolationInterface;

View File

@ -4,7 +4,7 @@ namespace Drupal\file\Validation;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\TypedData\TypedDataManagerInterface;
use Drupal\Core\TypedData\Validation\ExecutionContextFactory;
use Drupal\Core\Validation\ExecutionContextFactory;
use Drupal\Core\TypedData\Validation\RecursiveValidator;
use Drupal\Core\Validation\ConstraintValidatorFactory;
use Drupal\Core\Validation\DrupalTranslator;

View File

@ -9,9 +9,9 @@ use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\TypedData\DataDefinition;
use Drupal\Core\TypedData\MapDataDefinition;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\Core\TypedData\Validation\ExecutionContextFactory;
use Drupal\Core\TypedData\Validation\RecursiveValidator;
use Drupal\Core\Validation\ConstraintManager;
use Drupal\Core\Validation\ExecutionContextFactory;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
@ -46,7 +46,7 @@ class RecursiveContextualValidatorTest extends UnitTestCase {
/**
* The execution context factory.
*
* @var \Drupal\Core\TypedData\Validation\ExecutionContextFactory
* @var \Drupal\Core\Validation\ExecutionContextFactory
*/
protected $contextFactory;