38 (?P<validatorName>[a-z0-9:.\\\\]+)
41 (?P<validatorOptions>(?:\s*[a-z0-9]+\s*=\s*(?:
43 |\'(?:\\\\\'|[^\'])*\'
56 (?P<optionName>[a-z0-9]+)
60 |\'(?:\\\\\'|[^\'])*\'
105 public function createValidator($validatorType, array $validatorOptions = [])
113 $validator = $this->objectManager->get($validatorObjectName, $validatorOptions);
117 throw new Exception\NoSuchValidatorException(
'The validator "' . $validatorObjectName .
'" does not implement TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface!', 1300694875);
121 }
catch (NoSuchValidatorException $e) {
122 GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__)->debug($e->getMessage());
138 if (!array_key_exists($targetClassName, $this->baseValidatorConjunctions)) {
142 return $this->baseValidatorConjunctions[$targetClassName];
163 'Method ' . __METHOD__ .
' is deprecated and will be removed in TYPO3 v10.0.',
168 $validatorConjunctions = [];
170 if ($methodParameters ===
null) {
171 $methodParameters = $this->reflectionService
172 ->getClassSchema($className)
173 ->getMethod($methodName)[
'params'] ?? [];
175 if (empty($methodParameters)) {
176 return $validatorConjunctions;
179 foreach ($methodParameters as $parameterName => $methodParameter) {
181 $validatorConjunction = $this->
createValidator(ConjunctionValidator::class);
183 if (!array_key_exists(
'type', $methodParameter)) {
184 throw new Exception\InvalidTypeHintException(
'Missing type information, probably no @param annotation for parameter "$' . $parameterName .
'" in ' . $className .
'->' . $methodName .
'()', 1281962564);
187 if (strpbrk($methodParameter[
'type'],
'\\') ===
false) {
190 $typeValidator =
null;
193 if ($typeValidator !==
null) {
194 $validatorConjunction->addValidator($typeValidator);
196 $validatorConjunctions[$parameterName] = $validatorConjunction;
199 if ($methodValidateAnnotations ===
null) {
201 $methodValidateAnnotations = array_map(
function ($validateAnnotation) {
203 'type' => $validateAnnotation[
'validatorName'],
204 'options' => $validateAnnotation[
'validatorOptions'],
205 'argumentName' => $validateAnnotation[
'argumentName'],
207 }, $validateAnnotations);
210 foreach ($methodValidateAnnotations as $annotationParameters) {
211 $newValidator = $this->
createValidator($annotationParameters[
'type'], $annotationParameters[
'options']);
212 if ($newValidator ===
null) {
213 throw new Exception\NoSuchValidatorException(
'Invalid validate annotation in ' . $className .
'->' . $methodName .
'(): Could not resolve class name for validator "' . $annotationParameters[
'type'] .
'".', 1239853109);
215 if (isset($validatorConjunctions[$annotationParameters[
'argumentName']])) {
216 $validatorConjunctions[$annotationParameters[
'argumentName']]->addValidator($newValidator);
217 } elseif (strpos($annotationParameters[
'argumentName'],
'.') !==
false) {
218 $objectPath = explode(
'.', $annotationParameters[
'argumentName']);
219 $argumentName = array_shift($objectPath);
222 throw new Exception\InvalidValidationConfigurationException(
'Invalid validate annotation in ' . $className .
'->' . $methodName .
'(): Validator specified for argument name "' . $annotationParameters[
'argumentName'] .
'", but this argument does not exist.', 1253172726);
226 return $validatorConjunctions;
241 'Method ' . __METHOD__ .
' is deprecated and will be removed in TYPO3 v10.0.',
245 $rootObjectValidator = $this->objectManager->get(\
TYPO3\CMS\
Extbase\Validation\Validator\GenericObjectValidator::class, []);
246 $parentObjectValidator = $rootObjectValidator;
248 while (count($objectPath) > 1) {
249 $subObjectValidator = $this->objectManager->get(\
TYPO3\CMS\
Extbase\Validation\Validator\GenericObjectValidator::class, []);
250 $subPropertyName = array_shift($objectPath);
251 $parentObjectValidator->addPropertyValidator($subPropertyName, $subObjectValidator);
252 $parentObjectValidator = $subObjectValidator;
255 $parentObjectValidator->addPropertyValidator(array_shift($objectPath), $propertyValidator);
257 return $rootObjectValidator;
284 $conjunctionValidator =
new ConjunctionValidator();
285 $this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator;
289 $classSchema = $this->reflectionService->getClassSchema($targetClassName);
293 $objectValidator = $this->objectManager->get(\
TYPO3\CMS\
Extbase\Validation\Validator\GenericObjectValidator::class, []);
294 foreach ($classSchema->getProperties() as $classPropertyName => $classPropertyDefinition) {
296 $classPropertyTagsValues = $classPropertyDefinition[
'tags'];
298 if (!isset($classPropertyTagsValues[
'var'])) {
299 throw new \InvalidArgumentException(sprintf(
'There is no @var annotation for property "%s" in class "%s".', $classPropertyName, $targetClassName), 1363778104);
302 $propertyTargetClassName = $classPropertyDefinition[
'type'];
307 \
TYPO3\CMS\
Extbase\Validation\Validator\CollectionValidator::class,
309 'elementType' => $classPropertyDefinition[
'elementType'],
310 'validationGroups' => $validationGroups
313 $objectValidator->addPropertyValidator($classPropertyName, $collectionValidator);
314 } elseif (class_exists($propertyTargetClassName) && !
TypeHandlingUtility::isCoreType($propertyTargetClassName) && $this->objectManager->isRegistered($propertyTargetClassName) && $this->objectManager->getScope($propertyTargetClassName) === \
TYPO3\CMS\
Extbase\Object\Container\Container::SCOPE_PROTOTYPE) {
316 if ($validatorForProperty !==
null && $validatorForProperty->count() > 0) {
317 $objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty);
322 foreach ($classPropertyDefinition[
'validators'] as $validatorDefinition) {
330 $newValidator = $this->
createValidator($validatorDefinition[
'className'], $validatorDefinition[
'options']);
331 if ($newValidator ===
null) {
332 throw new Exception\NoSuchValidatorException(
'Invalid validate annotation in ' . $targetClassName .
'::' . $classPropertyName .
': Could not resolve class name for validator "' . $validatorDefinition[
'className'] .
'".', 1241098027);
334 $objectValidator->addPropertyValidator($classPropertyName, $newValidator);
338 if (!empty($objectValidator->getPropertyValidators())) {
339 $conjunctionValidator->addValidator($objectValidator);
359 protected function addCustomValidators($targetClassName, ConjunctionValidator &$conjunctionValidator)
365 if ($customValidator !==
null) {
366 $conjunctionValidator->addValidator($customValidator);
383 'Method ' . __METHOD__ .
' is deprecated and will be removed in TYPO3 v10.0.',
388 if ($validateValue[0] ===
'$') {
389 $parts = explode(
' ', $validateValue, 2);
390 $validatorConfiguration = [
'argumentName' => ltrim($parts[0],
'$'),
'validators' => []];
391 preg_match_all(self::PATTERN_MATCH_VALIDATORS, $parts[1], $matches, PREG_SET_ORDER);
393 $validatorConfiguration = [
'validators' => []];
394 preg_match_all(self::PATTERN_MATCH_VALIDATORS, $validateValue, $matches, PREG_SET_ORDER);
396 foreach ($matches as $match) {
397 $validatorOptions = [];
398 if (isset($match[
'validatorOptions'])) {
401 $validatorConfiguration[
'validators'][] = [
'validatorName' => $match[
'validatorName'],
'validatorOptions' => $validatorOptions];
403 return $validatorConfiguration;
417 'Method ' . __METHOD__ .
' is deprecated and will be removed in TYPO3 v10.0.',
421 $validatorOptions = [];
422 $parsedValidatorOptions = [];
423 preg_match_all(self::PATTERN_MATCH_VALIDATOROPTIONS, $rawValidatorOptions, $validatorOptions, PREG_SET_ORDER);
424 foreach ($validatorOptions as $validatorOption) {
425 $parsedValidatorOptions[trim($validatorOption[
'optionName'])] = trim($validatorOption[
'optionValue']);
427 array_walk($parsedValidatorOptions, [$this,
'unquoteString']);
428 return $parsedValidatorOptions;
443 'Method ' . __METHOD__ .
' is deprecated and will be removed in TYPO3 v10.0.',
447 switch ($quotedValue[0]) {
449 $quotedValue = str_replace(
'\\"',
'"', trim($quotedValue,
'"'));
452 $quotedValue = str_replace(
'\\\'',
'\'', trim($quotedValue,
'\''));
455 $quotedValue = str_replace(
'\\\\',
'\\', $quotedValue);
470 if (strpos($validatorName,
':') !==
false) {
473 list($extensionName, $extensionValidatorName) = explode(
':', $validatorName);
475 if ($validatorName !== $extensionName && $extensionValidatorName !==
'') {
477 if (strpos($extensionName,
'.') !==
false) {
478 $extensionNameParts = explode(
'.', $extensionName);
479 $extensionName = array_pop($extensionNameParts);
480 $vendorName = implode(
'\\', $extensionNameParts);
481 $possibleClassName = $vendorName .
'\\' . $extensionName .
'\\Validation\\Validator\\' . $extensionValidatorName;
485 $possibleClassName =
'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->
getValidatorType($validatorName);
487 } elseif (strpbrk($validatorName,
'\\') ===
false) {
489 $possibleClassName =
'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->
getValidatorType($validatorName);
493 $possibleClassName = $validatorName;
494 if (!empty($possibleClassName) && $possibleClassName[0] ===
'\\') {
495 $possibleClassName = substr($possibleClassName, 1);
499 if (substr($possibleClassName, - strlen(
'Validator')) !==
'Validator') {
500 $possibleClassName .=
'Validator';
503 if (class_exists($possibleClassName)) {
504 $possibleClassNameInterfaces = class_implements($possibleClassName);
505 if (!in_array(\
TYPO3\CMS\
Extbase\Validation\Validator\ValidatorInterface::class, $possibleClassNameInterfaces)) {
507 throw new NoSuchValidatorException(
'Validator class ' . $validatorName .
' must implement \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface', 1365776838);
509 $resolvedValidatorName = $possibleClassName;
511 throw new NoSuchValidatorException(
'Validator class ' . $validatorName .
' does not exist', 1365799920);
514 return $resolvedValidatorName;
542 $type = ucfirst($type);
558 $validateAnnotations = [];
559 $methodTagsValues = $this->reflectionService->getClassSchema($className)->getMethod($methodName)[
'tags'] ?? [];
560 if (isset($methodTagsValues[
'validate']) && is_array($methodTagsValues[
'validate'])) {
561 foreach ($methodTagsValues[
'validate'] as $validateValue) {
564 foreach ($parsedAnnotations[
'validators'] as
$validator) {
565 $validateAnnotations[] = [
566 'argumentName' => $parsedAnnotations[
'argumentName'],
568 'validatorOptions' =>
$validator[
'validatorOptions']
574 return $validateAnnotations;