/**
  * Determine the type converter to be used. If no converter has been found, an exception is raised.
  *
  * @param mixed $source
  * @param string $targetType
  * @param PropertyMappingConfigurationInterface $configuration
  * @return TypeConverterInterface Type Converter which should be used to convert between $source and $targetType.
  * @throws Exception\TypeConverterException
  * @throws Exception\InvalidTargetException
  */
 protected function findTypeConverter($source, $targetType, PropertyMappingConfigurationInterface $configuration)
 {
     if ($configuration->getTypeConverter() !== null) {
         return $configuration->getTypeConverter();
     }
     if (!is_string($targetType)) {
         throw new Exception\InvalidTargetException('The target type was no string, but of type "' . gettype($targetType) . '"', 1297941727);
     }
     $normalizedTargetType = TypeHandling::normalizeType($targetType);
     $truncatedTargetType = TypeHandling::truncateElementType($normalizedTargetType);
     $converter = null;
     $sourceTypes = $this->determineSourceTypes($source);
     foreach ($sourceTypes as $sourceType) {
         if (TypeHandling::isSimpleType($truncatedTargetType)) {
             if (isset($this->typeConverters[$sourceType][$truncatedTargetType])) {
                 $converter = $this->findEligibleConverterWithHighestPriority($this->typeConverters[$sourceType][$truncatedTargetType], $source, $normalizedTargetType);
             }
         } else {
             $converter = $this->findFirstEligibleTypeConverterInObjectHierarchy($source, $sourceType, $normalizedTargetType);
         }
         if ($converter !== null) {
             return $converter;
         }
     }
     throw new Exception\TypeConverterException('No converter found which can be used to convert from "' . implode('" or "', $sourceTypes) . '" to "' . $normalizedTargetType . '".');
 }
 /**
  * Constructs this controller argument
  *
  * @param string $name Name of this argument
  * @param string $dataType The data type of this argument
  * @throws \InvalidArgumentException if $name is not a string or empty
  * @api
  */
 public function __construct($name, $dataType)
 {
     if (!is_string($name)) {
         throw new \InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
     }
     if (strlen($name) === 0) {
         throw new \InvalidArgumentException('$name must be a non-empty string, ' . strlen($name) . ' characters given.', 1232551853);
     }
     $this->name = $name;
     $this->dataType = TypeHandling::normalizeType($dataType);
 }
 /**
  * @param string $operand
  * @param string $value
  * @return boolean TRUE if $value is of type $operand; FALSE otherwise
  */
 protected function handleSimpleTypeOperand($operand, $value)
 {
     $operand = TypeHandling::normalizeType($operand);
     if ($operand === 'object') {
         return is_object($value);
     } elseif ($operand === 'string') {
         return is_string($value);
     } elseif ($operand === 'integer') {
         return is_integer($value);
     } elseif ($operand === 'boolean') {
         return is_bool($value);
     } elseif ($operand === 'float') {
         return is_float($value);
     } elseif ($operand === 'array') {
         return is_array($value);
     }
     return false;
 }
 /**
  * @test
  * @dataProvider normalizeTypes
  */
 public function normalizeTypesReturnsNormalizedType($type, $normalized)
 {
     $this->assertEquals(TypeHandling::normalizeType($type), $normalized);
 }
Esempio n. 5
0
 /**
  * Expand shortened class names in "var" and "param" annotations, taking use statements into account.
  *
  * @param ClassReflection $class
  * @param string $type the type inside var/param annotation
  * @return string the possibly expanded type
  */
 protected function expandType(ClassReflection $class, $type)
 {
     // expand "SomeType<SomeElementType>" to "\SomeTypeNamespace\SomeType<\ElementTypeNamespace\ElementType>"
     if (strpos($type, '<') !== false) {
         $typeParts = explode('<', $type);
         $type = $typeParts[0];
         $elementType = rtrim($typeParts[1], '>');
         return $this->expandType($class, $type) . '<' . $this->expandType($class, $elementType) . '>';
     }
     // skip simple types and types with fully qualified namespaces
     if ($type === 'mixed' || $type[0] === '\\' || TypeHandling::isSimpleType($type)) {
         return TypeHandling::normalizeType($type);
     }
     // we try to find the class relative to the current namespace...
     $possibleFullyQualifiedClassName = sprintf('%s\\%s', $class->getNamespaceName(), $type);
     if (class_exists($possibleFullyQualifiedClassName) || interface_exists($possibleFullyQualifiedClassName)) {
         return $possibleFullyQualifiedClassName;
     }
     // and then we try to find "use" statements for the class.
     $className = $class->getName();
     if (!isset($this->useStatementsForClassCache[$className])) {
         $this->useStatementsForClassCache[$className] = $this->getDoctrinePhpParser()->parseClass($class);
     }
     $useStatementsForClass = $this->useStatementsForClassCache[$className];
     // ... and try to expand them
     $typeParts = explode('\\', $type, 2);
     $lowercasedFirstTypePart = strtolower($typeParts[0]);
     if (isset($useStatementsForClass[$lowercasedFirstTypePart])) {
         $typeParts[0] = $useStatementsForClass[$lowercasedFirstTypePart];
         return implode('\\', $typeParts);
     }
     return $type;
 }
 /**
  * @param mixed $propertyValue
  * @param string $dataType
  * @return mixed
  * @throws PropertyException
  */
 protected function convertValue($propertyValue, $dataType)
 {
     $rawType = TypeHandling::truncateElementType($dataType);
     // This hardcoded handling is to circumvent rewriting PropertyMappers that convert objects. Usually they expect the source to be an object already and break if not.
     if (!TypeHandling::isSimpleType($rawType) && !is_object($propertyValue) && !is_array($propertyValue)) {
         return null;
     }
     if ($rawType === 'array') {
         $conversionTargetType = 'array<string>';
     } elseif (TypeHandling::isSimpleType($rawType)) {
         $conversionTargetType = TypeHandling::normalizeType($rawType);
     } else {
         $conversionTargetType = 'array';
     }
     $propertyMappingConfiguration = $this->createConfiguration($dataType);
     $convertedValue = $this->propertyMapper->convert($propertyValue, $conversionTargetType, $propertyMappingConfiguration);
     if ($convertedValue instanceof \Neos\Error\Messages\Error) {
         throw new PropertyException($convertedValue->getMessage(), $convertedValue->getCode());
     }
     return $convertedValue;
 }