Beispiel #1
0
 /**
  * Ext Direct does not provide named arguments by now, so we have
  * to map them by reflecting on the action parameters.
  *
  * @param RequestInterface $dispatchRequest
  * @param Transaction $transaction
  * @return array The mapped arguments
  */
 protected function getArgumentsFromTransaction(\F3\FLOW3\MVC\RequestInterface $dispatchRequest, \F3\ExtJS\ExtDirect\Transaction $transaction)
 {
     if (!$transaction->getDirectRequest()->isFormPost()) {
         $controllerClass = $dispatchRequest->getControllerObjectName();
         $parameters = $this->reflectionService->getMethodParameters($controllerClass, $dispatchRequest->getControllerActionName() . 'Action');
         return $transaction->mapDataToParameters($parameters);
     } else {
         // TODO Reuse setArgumentsFromRawRequestData from Web/RequestBuilder
     }
 }
 /**
  * Implementation of the arguments initilization in the action controller:
  * Automatically registers arguments of the current action
  *
  * Don't override this method - use initializeAction() instead.
  *
  * @return void
  * @author Robert Lemke <*****@*****.**>
  * @see initializeArguments()
  */
 protected function initializeActionMethodArguments()
 {
     $methodParameters = $this->reflectionService->getMethodParameters(get_class($this), $this->actionMethodName);
     foreach ($methodParameters as $parameterName => $parameterInfo) {
         $dataType = NULL;
         if (isset($parameterInfo['type'])) {
             $dataType = $parameterInfo['type'];
         } elseif ($parameterInfo['array']) {
             $dataType = 'array';
         }
         if ($dataType === NULL) {
             throw new \F3\FLOW3\MVC\Exception\InvalidArgumentTypeException('The argument type for parameter $' . $parameterName . ' of method ' . get_class($this) . '->' . $this->actionMethodName . '() could not be detected.', 1253175643);
         }
         $defaultValue = isset($parameterInfo['defaultValue']) ? $parameterInfo['defaultValue'] : NULL;
         $this->arguments->addNewArgument($parameterName, $dataType, $parameterInfo['optional'] === FALSE, $defaultValue);
     }
 }
 /**
  * Detects and registers any validators for arguments:
  * - by the data type specified in the @param annotations
  * - additional validators specified in the @validate annotations of a method
  *
  * @param string $className
  * @param string $methodName
  * @return array An Array of ValidatorConjunctions for each method parameters.
  * @author Robert Lemke <*****@*****.**>
  * @author Sebastian Kurfürst <*****@*****.**>
  */
 public function buildMethodArgumentsValidatorConjunctions($className, $methodName)
 {
     $validatorConjunctions = array();
     $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName);
     if (!count($methodParameters)) {
         // early return in case no parameters were found.
         return $validatorConjunctions;
     }
     foreach ($methodParameters as $parameterName => $methodParameter) {
         $validatorConjunction = $this->createValidator('F3\\FLOW3\\Validation\\Validator\\ConjunctionValidator');
         if (strpos($methodParameter['type'], '\\') === FALSE) {
             $typeValidator = $this->createValidator($methodParameter['type']);
         } elseif (strpos($methodParameter['type'], '\\Model\\') !== FALSE) {
             $possibleValidatorClassName = str_replace('\\Model\\', '\\Validator\\', $methodParameter['type']) . 'Validator';
             $typeValidator = $this->createValidator($possibleValidatorClassName);
         } else {
             $typeValidator = NULL;
         }
         if ($typeValidator !== NULL) {
             $validatorConjunction->addValidator($typeValidator);
         }
         $validatorConjunctions[$parameterName] = $validatorConjunction;
     }
     $methodTagsValues = $this->reflectionService->getMethodTagsValues($className, $methodName);
     if (isset($methodTagsValues['validate'])) {
         foreach ($methodTagsValues['validate'] as $validateValue) {
             $parsedAnnotation = $this->parseValidatorAnnotation($validateValue);
             foreach ($parsedAnnotation['validators'] as $validatorConfiguration) {
                 $newValidator = $this->createValidator($validatorConfiguration['validatorName'], $validatorConfiguration['validatorOptions']);
                 if ($newValidator === NULL) {
                     throw new \F3\FLOW3\Validation\Exception\NoSuchValidatorException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Could not resolve class name for  validator "' . $validatorConfiguration['validatorName'] . '".', 1239853109);
                 }
                 if (isset($validatorConjunctions[$parsedAnnotation['argumentName']])) {
                     $validatorConjunctions[$parsedAnnotation['argumentName']]->addValidator($newValidator);
                 } else {
                     throw new \F3\FLOW3\Validation\Exception\InvalidValidationConfigurationException('Invalid validate annotation in ' . $className . '->' . $methodName . '(): Validator specified for argument name "' . $parsedAnnotation['argumentName'] . '", but this argument does not exist.', 1253172726);
                 }
             }
         }
     }
     return $validatorConjunctions;
 }
 /**
  * Maps the given properties to the target object WITHOUT VALIDATING THE RESULT.
  * If the properties could be set, this method returns TRUE, otherwise FALSE.
  * Returning TRUE does not mean that the target object is valid and secure!
  *
  * Only use this method if you're sure that you don't need validation!
  *
  * @param array $propertyNames Names of the properties to map.
  * @param mixed $source Source containing the properties to map to the target object. Must either be an array, ArrayObject or any other object.
  * @param object $target The target object
  * @param array $optionalPropertyNames Names of optional properties. If a property is specified here and it doesn't exist in the source, no error is issued.
  * @return boolean TRUE if the properties could be mapped, otherwise FALSE
  * @see mapAndValidate()
  * @author Robert Lemke <*****@*****.**>
  * @api
  */
 public function map(array $propertyNames, $source, &$target, $optionalPropertyNames = array())
 {
     if (!is_object($source) && !is_array($source)) {
         throw new \F3\FLOW3\Property\Exception\InvalidSourceException('The source object must be a valid object or array, ' . gettype($target) . ' given.', 1187807099);
     }
     if (is_string($target) && strpos($target, '\\') !== FALSE) {
         return $this->transformToObject($source, $target, '--none--');
     }
     $this->mappingResults = $this->objectManager->getObject('F3\\FLOW3\\Property\\MappingResults');
     if (!is_object($target) && !is_array($target)) {
         throw new \F3\FLOW3\Property\Exception\InvalidTargetException('The target must be a valid object, class name or array, ' . gettype($target) . ' given.', 1187807099);
     }
     if (is_object($target)) {
         $targetClassSchema = $this->reflectionService->getClassSchema($target);
     } else {
         $targetClassSchema = NULL;
     }
     foreach ($propertyNames as $propertyName) {
         $propertyValue = NULL;
         if (is_array($source) || $source instanceof \ArrayAccess) {
             if (isset($source[$propertyName])) {
                 $propertyValue = $source[$propertyName];
             }
         } elseif (\F3\FLOW3\Reflection\ObjectAccess::isPropertyGettable($source, $propertyName)) {
             $propertyValue = \F3\FLOW3\Reflection\ObjectAccess::getProperty($source, $propertyName);
         }
         if ($propertyValue === NULL && !in_array($propertyName, $optionalPropertyNames)) {
             $this->mappingResults->addError($this->objectManager->getObject('F3\\FLOW3\\Error\\Error', "Required property '{$propertyName}' does not exist in source.", 1236785359), $propertyName);
         } else {
             if (method_exists($target, \F3\FLOW3\Reflection\ObjectAccess::buildSetterMethodName($propertyName)) && is_callable(array($target, \F3\FLOW3\Reflection\ObjectAccess::buildSetterMethodName($propertyName)))) {
                 $targetClassName = $target instanceof \F3\FLOW3\AOP\ProxyInterface ? $target->FLOW3_AOP_Proxy_getProxyTargetClassName() : get_class($target);
                 $methodParameters = $this->reflectionService->getMethodParameters($targetClassName, \F3\FLOW3\Reflection\ObjectAccess::buildSetterMethodName($propertyName));
                 $methodParameter = current($methodParameters);
                 $targetPropertyType = \F3\FLOW3\Utility\TypeHandling::parseType($methodParameter['type']);
             } elseif ($targetClassSchema !== NULL && $targetClassSchema->hasProperty($propertyName)) {
                 $targetPropertyType = $targetClassSchema->getProperty($propertyName);
             } elseif ($targetClassSchema !== NULL) {
                 $this->mappingResults->addError($this->objectManager->getObject('F3\\FLOW3\\Error\\Error', "Property '{$propertyName}' does not exist in target class schema.", 1251813614), $propertyName);
                 continue;
             }
             if (isset($targetPropertyType)) {
                 if (in_array($targetPropertyType['type'], array('array', 'ArrayObject', 'SplObjectStorage')) && strpos($targetPropertyType['elementType'], '\\') !== FALSE) {
                     $objects = array();
                     foreach ($propertyValue as $value) {
                         $objects[] = $this->transformToObject($value, $targetPropertyType['elementType'], $propertyName);
                     }
                     if ($targetPropertyType['type'] === 'ArrayObject') {
                         $propertyValue = new \ArrayObject($objects);
                     } elseif ($targetPropertyType['type'] === 'SplObjectStorage') {
                         $propertyValue = new \SplObjectStorage();
                         foreach ($objects as $object) {
                             $propertyValue->attach($object);
                         }
                     } else {
                         $propertyValue = $objects;
                     }
                 } elseif (strpos($targetPropertyType['type'], '\\') !== FALSE) {
                     $propertyValue = $this->transformToObject($propertyValue, $targetPropertyType['type'], $propertyName);
                 }
             }
             if (is_array($target)) {
                 $target[$propertyName] = $propertyValue;
             } elseif (\F3\FLOW3\Reflection\ObjectAccess::setProperty($target, $propertyName, $propertyValue) === FALSE) {
                 $this->mappingResults->addError($this->objectManager->getObject('F3\\FLOW3\\Error\\Error', "Property '{$propertyName}' could not be set.", 1236783102), $propertyName);
             }
         }
     }
     return !$this->mappingResults->hasErrors();
 }