protected function buildBaseValidatorConjunction($indexKey, $targetClassName, array $validationGroups = array()) { $conjunctionValidator = new \TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator(); $this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator; if (class_exists($targetClassName)) { // Model based validator /** @var \TYPO3\CMS\Extbase\Validation\Validator\GenericObjectValidator $objectValidator */ $objectValidator = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Validation\\Validator\\GenericObjectValidator', array()); 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); } // ONLY THING DIFFERENT THAN PARENT IMPLEMENTATION if (isset($classPropertyTagsValues['ignorevalidation'])) { continue; } try { $parsedType = \TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::parseType(trim(implode('', $classPropertyTagsValues['var']), ' \\')); } catch (\TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException $exception) { throw new \InvalidArgumentException(sprintf(' @var annotation of ' . $exception->getMessage(), 'class "' . $targetClassName . '", property "' . $classPropertyName . '"'), 1315564744, $exception); } $propertyTargetClassName = $parsedType['type']; if (\TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::isCollectionType($propertyTargetClassName) === TRUE) { $collectionValidator = $this->createValidator('TYPO3\\CMS\\Extbase\\Validation\\Validator\\CollectionValidator', array('elementType' => $parsedType['elementType'], 'validationGroups' => $validationGroups)); $objectValidator->addPropertyValidator($classPropertyName, $collectionValidator); } elseif (class_exists($propertyTargetClassName) && !\TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::isCoreType($propertyTargetClassName) && $this->objectManager->isRegistered($propertyTargetClassName) && $this->objectManager->getScope($propertyTargetClassName) === \TYPO3\CMS\Extbase\Object\Container\Container::SCOPE_PROTOTYPE) { $validatorForProperty = $this->getBaseValidatorConjunction($propertyTargetClassName, $validationGroups); if (count($validatorForProperty) > 0) { $objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty); } } $validateAnnotations = array(); // @todo: Resolve annotations via reflectionService once its available if (isset($classPropertyTagsValues['validate']) && is_array($classPropertyTagsValues['validate'])) { foreach ($classPropertyTagsValues['validate'] as $validateValue) { $parsedAnnotations = $this->parseValidatorAnnotation($validateValue); foreach ($parsedAnnotations['validators'] as $validator) { array_push($validateAnnotations, array('argumentName' => $parsedAnnotations['argumentName'], 'validatorName' => $validator['validatorName'], 'validatorOptions' => $validator['validatorOptions'])); } } } foreach ($validateAnnotations as $validateAnnotation) { // @todo: Respect validationGroups $newValidator = $this->createValidator($validateAnnotation['validatorName'], $validateAnnotation['validatorOptions']); 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->addValidator($objectValidator); } } $this->addCustomValidators($targetClassName, $conjunctionValidator); }
/** * Adds (defines) a specific property and its type. * * @param string $name Name of the property * @param string $type Type of the property * @param bool $lazy Whether the property should be lazy-loaded when reconstituting * @param string $cascade Strategy to cascade the object graph. * @return void */ public function addProperty($name, $type, $lazy = FALSE, $cascade = '') { $type = TypeHandlingUtility::parseType($type); $this->properties[$name] = array('type' => $type['type'], 'elementType' => $type['elementType'], 'lazy' => $lazy, 'cascade' => $cascade); }
/** * Return the type of a given sub-property inside the $targetType * * @param string $targetType * @param string $propertyName * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration * @return string * @api */ public function getTypeOfChildProperty($targetType, $propertyName, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration) { $parsedTargetType = \TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::parseType($targetType); return $parsedTargetType['elementType']; }
/** * Converts the given parameter reflection into an information array * * @param ParameterReflection $parameter The parameter to reflect * @param int $parameterPosition * @param MethodReflection|NULL $method * @return array Parameter information array */ protected function convertParameterReflectionToArray(ParameterReflection $parameter, $parameterPosition, MethodReflection $method = null) { $parameterInformation = ['position' => $parameterPosition, 'byReference' => $parameter->isPassedByReference(), 'array' => $parameter->isArray(), 'optional' => $parameter->isOptional(), 'allowsNull' => $parameter->allowsNull()]; $parameterClass = $parameter->getClass(); $parameterInformation['class'] = $parameterClass !== null ? $parameterClass->getName() : null; if ($parameter->isDefaultValueAvailable()) { $parameterInformation['defaultValue'] = $parameter->getDefaultValue(); } if ($parameterClass !== null) { $parameterInformation['type'] = $parameterClass->getName(); } elseif ($method !== null) { $methodTagsAndValues = $this->getMethodTagsValues($method->getDeclaringClass()->getName(), $method->getName()); if (isset($methodTagsAndValues['param']) && isset($methodTagsAndValues['param'][$parameterPosition])) { $explodedParameters = explode(' ', $methodTagsAndValues['param'][$parameterPosition]); if (count($explodedParameters) >= 2) { if (TypeHandlingUtility::isSimpleType($explodedParameters[0])) { // ensure that short names of simple types are resolved correctly to the long form // this is important for all kinds of type checks later on $typeInfo = TypeHandlingUtility::parseType($explodedParameters[0]); $parameterInformation['type'] = $typeInfo['type']; } else { $parameterInformation['type'] = $explodedParameters[0]; } } } } if (isset($parameterInformation['type']) && $parameterInformation['type'][0] === '\\') { $parameterInformation['type'] = substr($parameterInformation['type'], 1); } return $parameterInformation; }
/** * Adds (defines) a specific property and its type. * * @param string $type Type of the property (see PARSE_TYPE_PATTERN) * @throws \InvalidArgumentException * @return array An array with information about the type */ public function parseType($type) { return TypeHandlingUtility::parseType($type); }