Neos\Flow\Validation\ValidatorResolver::buildBaseValidatorConjunction PHP Method

buildBaseValidatorConjunction() protected method

The base validation rules are those which were declared directly in a class (typically a model) through some validate annotations on properties. If a property holds a class for which a base validator exists, that property will be checked as well, regardless of a validate annotation Additionally, if a custom validator was defined for the class in question, it will be added to the end of the conjunction. A custom validator is found if it follows the naming convention "Replace '\Model\' by '\Validator\' and append 'Validator'". Example: $targetClassName is Neos\Foo\Domain\Model\Quux, then the validator will be found if it has the name Neos\Foo\Domain\Validator\QuuxValidator
protected buildBaseValidatorConjunction ( string $indexKey, string $targetClassName, array $validationGroups ) : void
$indexKey string The key to use as index in $this->baseValidatorConjunctions; calculated from target class name and validation groups
$targetClassName string The data type to build the validation conjunction for. Needs to be the fully qualified class name.
$validationGroups array The validation groups to build the validator for
return void
    protected function buildBaseValidatorConjunction($indexKey, $targetClassName, array $validationGroups)
    {
        $conjunctionValidator = new ConjunctionValidator();
        $this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator;
        if (!TypeHandling::isSimpleType($targetClassName) && class_exists($targetClassName)) {
            // Model based validator
            $classSchema = $this->reflectionService->getClassSchema($targetClassName);
            if ($classSchema !== null && $classSchema->isAggregateRoot()) {
                $objectValidator = new AggregateBoundaryValidator(array());
            } else {
                $objectValidator = new GenericObjectValidator([]);
            }
            $conjunctionValidator->addValidator($objectValidator);
            foreach ($this->reflectionService->getClassPropertyNames($targetClassName) as $classPropertyName) {
                $classPropertyTagsValues = $this->reflectionService->getPropertyTagsValues($targetClassName, $classPropertyName);
                if (!isset($classPropertyTagsValues['var'])) {
                    throw new \InvalidArgumentException(sprintf('There is no @var annotation for property "%s" in class "%s".', $classPropertyName, $targetClassName), 1363778104);
                }
                try {
                    $parsedType = TypeHandling::parseType(trim(implode('', $classPropertyTagsValues['var']), ' \\'));
                } catch (InvalidTypeException $exception) {
                    throw new \InvalidArgumentException(sprintf(' @var annotation of ' . $exception->getMessage(), 'class "' . $targetClassName . '", property "' . $classPropertyName . '"'), 1315564744, $exception);
                }
                if ($this->reflectionService->isPropertyAnnotatedWith($targetClassName, $classPropertyName, Flow\IgnoreValidation::class)) {
                    continue;
                }
                $propertyTargetClassName = $parsedType['type'];
                if (TypeHandling::isCollectionType($propertyTargetClassName) === true) {
                    $collectionValidator = $this->createValidator(Validator\CollectionValidator::class, ['elementType' => $parsedType['elementType'], 'validationGroups' => $validationGroups]);
                    $objectValidator->addPropertyValidator($classPropertyName, $collectionValidator);
                } elseif (!TypeHandling::isSimpleType($propertyTargetClassName) && $this->objectManager->isRegistered($propertyTargetClassName) && $this->objectManager->getScope($propertyTargetClassName) === Configuration::SCOPE_PROTOTYPE) {
                    $validatorForProperty = $this->getBaseValidatorConjunction($propertyTargetClassName, $validationGroups);
                    if (count($validatorForProperty) > 0) {
                        $objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty);
                    }
                }
                $validateAnnotations = $this->reflectionService->getPropertyAnnotations($targetClassName, $classPropertyName, Flow\Validate::class);
                foreach ($validateAnnotations as $validateAnnotation) {
                    if (count(array_intersect($validateAnnotation->validationGroups, $validationGroups)) === 0) {
                        // In this case, the validation groups for the property do not match current validation context
                        continue;
                    }
                    $newValidator = $this->createValidator($validateAnnotation->type, $validateAnnotation->options);
                    if ($newValidator === null) {
                        throw new Exception\NoSuchValidatorException('Invalid validate annotation in ' . $targetClassName . '::' . $classPropertyName . ': Could not resolve class name for  validator "' . $validateAnnotation->type . '".', 1241098027);
                    }
                    $objectValidator->addPropertyValidator($classPropertyName, $newValidator);
                }
            }
            if (count($objectValidator->getPropertyValidators()) === 0) {
                $conjunctionValidator->removeValidator($objectValidator);
            }
        }
        $this->addCustomValidators($targetClassName, $conjunctionValidator);
    }