<?php declare(strict_types=1);namespace Shopware\Core\Framework\Validation;use Shopware\Core\Framework\Log\Package;use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;use Symfony\Component\Validator\ConstraintViolation;use Symfony\Component\Validator\ConstraintViolationList;use Symfony\Component\Validator\Validator\ValidatorInterface;#[Package('core')]class DataValidator{ /** * @var ValidatorInterface */ private $validator; /** * @internal */ public function __construct(ValidatorInterface $validator) { $this->validator = $validator; } public function getViolations(array $data, DataValidationDefinition $definition, string $path = ''): ConstraintViolationList { $violations = new ConstraintViolationList(); $violations->addAll($this->validateProperties($data, $definition, $path)); $violations->addAll($this->validateSubDefinitions($data, $definition, $path)); $violations->addAll($this->validateListDefinitions($data, $definition, $path)); return $violations; } public function validate(array $data, DataValidationDefinition $definition, string $path = ''): void { $violations = $this->getViolations($data, $definition, $path); if ($violations->count() === 0) { return; } throw new ConstraintViolationException($violations, $data); } private function validateProperties(array $data, DataValidationDefinition $definition, string $path): ConstraintViolationList { $constraintViolations = new ConstraintViolationList(); foreach ($definition->getProperties() as $propertyName => $constraints) { $value = $data[$propertyName] ?? null; $violations = $this->validator->validate($value, $constraints); /** @var ConstraintViolation $violation */ foreach ($violations as $violation) { $constraintViolations->add( new ConstraintViolation( $violation->getMessage(), $violation->getMessageTemplate(), $violation->getParameters(), $violation->getRoot(), $path . '/' . $propertyName, $violation->getInvalidValue(), $violation->getPlural(), $violation->getCode(), $violation->getConstraint(), $violation->getCause() ) ); } } return $constraintViolations; } private function validateSubDefinitions(array $data, DataValidationDefinition $definition, string $path): ConstraintViolationList { $constraintViolations = new ConstraintViolationList(); foreach ($definition->getSubDefinitions() as $propertyName => $subDefinition) { $value = $data[$propertyName] ?? []; $constraintViolations->addAll( $this->getViolations($value, $subDefinition, $path . '/' . $propertyName) ); } return $constraintViolations; } private function validateListDefinitions(array $data, DataValidationDefinition $definition, string $path): ConstraintViolationList { $constraintViolations = new ConstraintViolationList(); foreach ($definition->getListDefinitions() as $propertyName => $subDefinition) { $values = $data[$propertyName] ?? []; $i = 0; foreach ($values as $item) { $constraintViolations->addAll( $this->getViolations($item, $subDefinition, $path . '/' . $propertyName . '/' . $i) ); ++$i; } } return $constraintViolations; }}