36 (?P<validatorName>[a-z0-9_:.\\\\]+) 39 (?P<validatorOptions>(?:\s*[a-z0-9]+\s*=\s*(?: 41 |\'(?:\\\\\'|[^\'])*\' 53 (?P<optionName>[a-z0-9]+) 57 |\'(?:\\\\\'|[^\'])*\' 88 public function createValidator($validatorType, array $validatorOptions = array()) {
95 $validator = $this->objectManager->get($validatorObjectName, $validatorOptions);
97 if (!($validator instanceof \
TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface)) {
98 throw new Exception\NoSuchValidatorException(
'The validator "' . $validatorObjectName .
'" does not implement TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface!', 1300694875);
118 if (!array_key_exists($targetClassName, $this->baseValidatorConjunctions)) {
119 $this->buildBaseValidatorConjunction($targetClassName, $targetClassName);
122 return $this->baseValidatorConjunctions[$targetClassName];
140 $validatorConjunctions = array();
142 if ($methodParameters === NULL) {
143 $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName);
145 if (count($methodParameters) === 0) {
146 return $validatorConjunctions;
149 foreach ($methodParameters as $parameterName => $methodParameter) {
150 $validatorConjunction = $this->
createValidator(
'TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator');
152 if (!array_key_exists(
'type', $methodParameter)) {
153 throw new Exception\InvalidTypeHintException(
'Missing type information, probably no @param annotation for parameter "$' . $parameterName .
'" in ' . $className .
'->' . $methodName .
'()', 1281962564);
157 if (strpbrk($methodParameter[
'type'],
'_\\') === FALSE) {
160 $typeValidator = NULL;
163 if ($typeValidator !== NULL) {
164 $validatorConjunction->addValidator($typeValidator);
166 $validatorConjunctions[$parameterName] = $validatorConjunction;
169 if ($methodValidateAnnotations === NULL) {
171 $methodValidateAnnotations = array_map(
function($validateAnnotation) {
173 'type' => $validateAnnotation[
'validatorName'],
174 'options' => $validateAnnotation[
'validatorOptions'],
175 'argumentName' => $validateAnnotation[
'argumentName'],
177 }, $validateAnnotations);
180 foreach ($methodValidateAnnotations as $annotationParameters) {
181 $newValidator = $this->
createValidator($annotationParameters[
'type'], $annotationParameters[
'options']);
182 if ($newValidator === NULL) {
183 throw new Exception\NoSuchValidatorException(
'Invalid validate annotation in ' . $className .
'->' . $methodName .
'(): Could not resolve class name for validator "' . $annotationParameters[
'type'] .
'".', 1239853109);
185 if (isset($validatorConjunctions[$annotationParameters[
'argumentName']])) {
186 $validatorConjunctions[$annotationParameters[
'argumentName']]->addValidator($newValidator);
187 } elseif (strpos($annotationParameters[
'argumentName'],
'.') !== FALSE) {
188 $objectPath = explode(
'.', $annotationParameters[
'argumentName']);
189 $argumentName = array_shift($objectPath);
190 $validatorConjunctions[$argumentName]->addValidator($this->
buildSubObjectValidator($objectPath, $newValidator));
192 throw new Exception\InvalidValidationConfigurationException(
'Invalid validate annotation in ' . $className .
'->' . $methodName .
'(): Validator specified for argument name "' . $annotationParameters[
'argumentName'] .
'", but this argument does not exist.', 1253172726);
196 return $validatorConjunctions;
208 $rootObjectValidator = $this->objectManager->get(
'TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator', array());
209 $parentObjectValidator = $rootObjectValidator;
211 while (count($objectPath) > 1) {
212 $subObjectValidator = $this->objectManager->get(
'TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator', array());
213 $subPropertyName = array_shift($objectPath);
214 $parentObjectValidator->addPropertyValidator($subPropertyName, $subObjectValidator);
215 $parentObjectValidator = $subObjectValidator;
218 $parentObjectValidator->addPropertyValidator(array_shift($objectPath), $propertyValidator);
220 return $rootObjectValidator;
246 protected function buildBaseValidatorConjunction($indexKey, $targetClassName, array $validationGroups = array()) {
247 $conjunctionValidator = new \TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator();
248 $this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator;
254 $objectValidator = $this->objectManager->get(
'TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator', array());
255 foreach ($this->reflectionService->getClassPropertyNames($targetClassName) as $classPropertyName) {
256 $classPropertyTagsValues = $this->reflectionService->getPropertyTagsValues($targetClassName, $classPropertyName);
258 if (!isset($classPropertyTagsValues[
'var'])) {
259 throw new \InvalidArgumentException(sprintf(
'There is no @var annotation for property "%s" in class "%s".', $classPropertyName, $targetClassName), 1363778104);
263 }
catch (\
TYPO3\CMS\Extbase\Utility\
Exception\InvalidTypeException $exception) {
264 throw new \InvalidArgumentException(sprintf(
' @var annotation of ' . $exception->getMessage(),
'class "' . $targetClassName .
'", property "' . $classPropertyName .
'"'), 1315564744, $exception);
266 $propertyTargetClassName = $parsedType[
'type'];
270 $collectionValidator = $this->
createValidator(
'TYPO3\CMS\Extbase\Validation\Validator\CollectionValidator', array(
'elementType' => $parsedType[
'elementType'],
'validationGroups' => $validationGroups));
271 $objectValidator->addPropertyValidator($classPropertyName, $collectionValidator);
274 if (count($validatorForProperty) > 0) {
275 $objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty);
280 $validateAnnotations = array();
282 if (isset($classPropertyTagsValues[
'validate']) && is_array($classPropertyTagsValues[
'validate'])) {
283 foreach ($classPropertyTagsValues[
'validate'] as $validateValue) {
286 foreach ($parsedAnnotations[
'validators'] as $validator) {
287 array_push($validateAnnotations, array(
288 'argumentName' => $parsedAnnotations[
'argumentName'],
289 'validatorName' => $validator[
'validatorName'],
290 'validatorOptions' => $validator[
'validatorOptions']
296 foreach ($validateAnnotations as $validateAnnotation) {
298 $newValidator = $this->
createValidator($validateAnnotation[
'validatorName'], $validateAnnotation[
'validatorOptions']);
299 if ($newValidator === NULL) {
300 throw new Exception\NoSuchValidatorException(
'Invalid validate annotation in ' . $targetClassName .
'::' . $classPropertyName .
': Could not resolve class name for validator "' . $validateAnnotation->type .
'".', 1241098027);
302 $objectValidator->addPropertyValidator($classPropertyName, $newValidator);
306 if (count($objectValidator->getPropertyValidators()) > 0) {
307 $conjunctionValidator->addValidator($objectValidator);
330 $addedValidatorClassName = NULL;
334 $customValidator = $this->
createValidator($possibleValidatorClassName);
335 if ($customValidator !== NULL) {
337 $addedValidatorClassName = get_class($customValidator);
351 if ($validateValue[0] ===
'$') {
352 $parts = explode(
' ', $validateValue, 2);
353 $validatorConfiguration = array(
'argumentName' => ltrim($parts[0],
'$'),
'validators' => array());
354 preg_match_all(self::PATTERN_MATCH_VALIDATORS, $parts[1], $matches, PREG_SET_ORDER);
356 $validatorConfiguration = array(
'validators' => array());
357 preg_match_all(self::PATTERN_MATCH_VALIDATORS, $validateValue, $matches, PREG_SET_ORDER);
359 foreach ($matches as $match) {
360 $validatorOptions = array();
361 if (isset($match[
'validatorOptions'])) {
364 $validatorConfiguration[
'validators'][] = array(
'validatorName' => $match[
'validatorName'],
'validatorOptions' => $validatorOptions);
366 return $validatorConfiguration;
377 $validatorOptions = array();
378 $parsedValidatorOptions = array();
379 preg_match_all(self::PATTERN_MATCH_VALIDATOROPTIONS, $rawValidatorOptions, $validatorOptions, PREG_SET_ORDER);
380 foreach ($validatorOptions as $validatorOption) {
381 $parsedValidatorOptions[trim($validatorOption[
'optionName'])] = trim($validatorOption[
'optionValue']);
383 array_walk($parsedValidatorOptions, array($this,
'unquoteString'));
384 return $parsedValidatorOptions;
397 switch ($quotedValue[0]) {
399 $quotedValue = str_replace(
'\\"',
'"', trim($quotedValue,
'"'));
402 $quotedValue = str_replace(
'\\\'',
'\'', trim($quotedValue,
'\''));
405 $quotedValue = str_replace(
'\\\\',
'\\', $quotedValue);
418 if (strpos($validatorName,
':') !== FALSE || strpbrk($validatorName,
'_\\') === FALSE) {
423 list($extensionName, $extensionValidatorName) = explode(
':', $validatorName);
425 if ($validatorName !== $extensionName && strlen($extensionValidatorName) > 0) {
429 if (strpos($extensionName,
'.') !== FALSE) {
430 $extensionNameParts = explode(
'.', $extensionName);
431 $extensionName = array_pop($extensionNameParts);
432 $vendorName = implode(
'\\', $extensionNameParts);
433 $possibleClassName = $vendorName .
'\\' . $extensionName .
'\\Validation\\Validator\\' . $extensionValidatorName;
435 $possibleClassName =
'Tx_' . $extensionName .
'_Validation_Validator_' . $extensionValidatorName;
441 $possibleClassName =
'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->
getValidatorType($validatorName);
448 $possibleClassName = $validatorName;
451 if (substr($possibleClassName, - strlen(
'Validator')) !==
'Validator') {
452 $possibleClassName .=
'Validator';
455 if (class_exists($possibleClassName)) {
456 $possibleClassNameInterfaces = class_implements($possibleClassName);
457 if (!in_array(
'TYPO3\\CMS\\Extbase\\Validation\\Validator\\ValidatorInterface', $possibleClassNameInterfaces)) {
459 throw new NoSuchValidatorException(
'Validator class ' . $validatorName .
' must implement \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface', 1365776838);
461 $resolvedValidatorName = $possibleClassName;
466 return $resolvedValidatorName;
493 $type = ucfirst($type);
507 $validateAnnotations = array();
508 $methodTagsValues = $this->reflectionService->getMethodTagsValues($className, $methodName);
509 if (isset($methodTagsValues[
'validate']) && is_array($methodTagsValues[
'validate'])) {
510 foreach ($methodTagsValues[
'validate'] as $validateValue) {
513 foreach ($parsedAnnotations[
'validators'] as $validator) {
514 array_push($validateAnnotations, array(
515 'argumentName' => $parsedAnnotations[
'argumentName'],
516 'validatorName' => $validator[
'validatorName'],
517 'validatorOptions' => $validator[
'validatorOptions']
523 return $validateAnnotations;
const PATTERN_MATCH_VALIDATORS
buildMethodArgumentsValidatorConjunctions($className, $methodName, array $methodParameters=NULL, array $methodValidateAnnotations=NULL)
static devLog($msg, $extKey, $severity=0, $dataVar=FALSE)
const PATTERN_MATCH_VALIDATOROPTIONS
getBaseValidatorConjunction($targetClassName)
getMethodValidateAnnotations($className, $methodName)
addCustomValidators($targetClassName, ConjunctionValidator &$conjunctionValidator)
parseValidatorAnnotation($validateValue)
static translateModelNameToValidatorName($modelName)
buildSubObjectValidator(array $objectPath, \TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $propertyValidator)
$baseValidatorConjunctions
createValidator($validatorType, array $validatorOptions=array())
resolveValidatorObjectName($validatorName)
const SYSLOG_SEVERITY_INFO
parseValidatorOptions($rawValidatorOptions)
static isCollectionType($type)
addValidator(\TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface $validator)
static isSimpleType($type)
unquoteString(&$quotedValue)