Issue #3393099 by kim.pepper, smustgrave, xjm, alexpott, longwave: Move ExecutionContext, ExecutionContextFactory, and ConstraintViolationBuilder from TypedData to Validation namespace
parent
f316821d4a
commit
36f2784c1d
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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.');
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue