/**
  * Checks if the value is a UUID or an array but should be an object, i.e.
  * the argument's data type class schema is set. If that is the case, this
  * method tries to look up the corresponding object instead.
  *
  * Additionally, it maps arrays to objects in case it is a normal object.
  *
  * @param mixed $value The value of an argument
  * @return mixed
  * @author Robert Lemke <*****@*****.**>
  * @author Karsten Dambekalns <*****@*****.**>
  * @author Bastian Waidelich <*****@*****.**>
  * @author Sebastian Kurfürst <*****@*****.**>
  */
 protected function transformValue($value)
 {
     if ($value === NULL) {
         return NULL;
     }
     if (!class_exists($this->dataType)) {
         return $value;
     }
     $transformedValue = NULL;
     if ($this->dataTypeClassSchema !== NULL) {
         // The target object is an Entity or ValueObject.
         if (is_string($value) && preg_match(self::PATTERN_MATCH_UUID, $value) === 1) {
             $this->origin = self::ORIGIN_PERSISTENCE;
             $transformedValue = $this->persistenceManager->getObjectByIdentifier($value);
         } elseif (is_array($value)) {
             if (array_keys($value) === array('__identity')) {
                 // If there is only an __identity array _and nothing else_, then the property mapper will not clone the object.
                 $this->origin = self::ORIGIN_PERSISTENCE;
             } else {
                 $this->origin = self::ORIGIN_PERSISTENCE_AND_MODIFIED;
             }
             $transformedValue = $this->propertyMapper->map(array_keys($value), $value, $this->dataType);
         }
     } else {
         if (!is_array($value)) {
             throw new \F3\FLOW3\MVC\Exception\InvalidArgumentValueException('The value was a simple type, so we could not map it to an object. Maybe the @entity or @valueobject annotations are missing?', 1251730701);
         }
         $this->origin = self::ORIGIN_NEWLY_CREATED;
         $transformedValue = $this->propertyMapper->map(array_keys($value), $value, $this->dataType);
     }
     if (!$transformedValue instanceof $this->dataType) {
         throw new \F3\FLOW3\MVC\Exception\InvalidArgumentValueException('The value must be of type "' . $this->dataType . '", but was of type "' . (is_object($transformedValue) ? get_class($transformedValue) : gettype($transformedValue)) . '".', 1251730701);
     }
     return $transformedValue;
 }
 /**
  * Finds an object matching the given UUID.
  *
  * @param string $uuid The UUID of the object to find
  * @return object The matching object if found, otherwise NULL
  * @author Karsten Dambekalns <*****@*****.**>
  * @api
  */
 public function findByUUID($uuid)
 {
     $object = $this->persistenceManager->getObjectByIdentifier($uuid);
     if (is_a($object, $this->objectType)) {
         return $object;
     } else {
         return NULL;
     }
 }
 /**
  * Renders a hidden form field containing the technical identity of the given object.
  *
  * @return string A hidden field containing the Identity (UUID in FLOW3, uid in Extbase) of the given object or NULL if the object is unknown to the persistence framework
  * @author Robert Lemke <*****@*****.**>
  * @author Karsten Dambekalns <*****@*****.**>
  * @author Bastian Waidelich <*****@*****.**>
  * @see \F3\FLOW3\MVC\Controller\Argument::setValue()
  */
 protected function renderHiddenIdentityField($object, $name)
 {
     if (!is_object($object) || !$object instanceof \F3\FLOW3\Persistence\Aspect\DirtyMonitoringInterface || $object->FLOW3_Persistence_isNew() && !$object->FLOW3_Persistence_isClone()) {
         return '';
     }
     $identifier = $this->persistenceManager->getIdentifierByObject($object);
     if ($identifier === NULL) {
         return chr(10) . '<!-- Object of type ' . get_class($object) . ' is without identity -->' . chr(10);
     }
     $name = $this->prefixFieldName($name) . '[__identity]';
     $this->registerFieldNameForFormTokenGeneration($name);
     return chr(10) . '<input type="hidden" name="' . $name . '" value="' . $identifier . '" />' . chr(10);
 }
 /**
  * Transforms strings with UUIDs or arrays with UUIDs/identity properties
  * into the requested type, if possible.
  *
  * @param mixed $propertyValue The value to transform, string or array
  * @param string $targetType The type to transform to
  * @param string $propertyName In case of an error we add this to the error message
  * @return object The object, when no transformation was possible this may return NULL as well
  */
 protected function transformToObject($propertyValue, $targetType, $propertyName)
 {
     if (is_string($propertyValue) && preg_match(self::PATTERN_MATCH_UUID, $propertyValue) === 1) {
         $object = $this->persistenceManager->getObjectByIdentifier($propertyValue);
         if ($object === FALSE) {
             $this->mappingResults->addError($this->objectManager->getObject('F3\\FLOW3\\Error\\Error', 'Querying the repository for the specified object with UUID ' . $propertyValue . ' was not successful.', 1249379517), $propertyName);
         }
     } elseif (is_array($propertyValue)) {
         if (isset($propertyValue['__identity'])) {
             $existingObject = is_array($propertyValue['__identity']) ? $this->findObjectByIdentityProperties($propertyValue['__identity'], $targetType) : $this->persistenceManager->getObjectByIdentifier($propertyValue['__identity']);
             if ($existingObject === FALSE) {
                 throw new \F3\FLOW3\Property\Exception\TargetNotFoundException('Querying the repository for the specified object was not successful.', 1237305720);
             }
             unset($propertyValue['__identity']);
             if (count($propertyValue) === 0) {
                 $object = $existingObject;
             } elseif ($existingObject !== NULL) {
                 $newObject = clone $existingObject;
                 if ($this->map(array_keys($propertyValue), $propertyValue, $newObject)) {
                     $object = $newObject;
                 }
             }
         } else {
             if (isset($this->objectConverters[$targetType])) {
                 $conversionResult = $this->objectConverters[$targetType]->convertFrom($propertyValue);
                 if ($conversionResult instanceof \F3\FLOW3\Error\Error) {
                     $this->mappingResults->addError($conversionResult, $propertyName);
                     return NULL;
                 } elseif (is_object($conversionResult) || $conversionResult === NULL) {
                     return $conversionResult;
                 }
             }
             $newObject = $this->objectManager->getObject($targetType);
             if ($this->map(array_keys($propertyValue), $propertyValue, $newObject)) {
                 return $newObject;
             }
             throw new \F3\FLOW3\Property\Exception\InvalidTargetException('Values could not be mapped to new object of type ' . $targetType . ' for property "' . $propertyName . '". (Map errors: ' . implode(' - ', $this->mappingResults->getErrors()) . ')', 1259770027);
         }
     } else {
         throw new \InvalidArgumentException('transformToObject() accepts only strings and arrays.', 1251814355);
     }
     return $object;
 }
 /**
  * Recursively iterates through the specified routeValues and turns objects
  * into an arrays containing the UUID of the domain object.
  *
  * @param array $routeValues The routeValues to be iterated over
  * @return array The modified routeValues array
  * @author Bastian Waidelich <*****@*****.**>
  */
 protected function convertDomainObjectsToIdentityArrays(array $routeValues)
 {
     foreach ($routeValues as $routeValueKey => $routeValue) {
         if (is_object($routeValue)) {
             $uuid = $this->persistenceManager->getIdentifierByObject($routeValue);
             if ($uuid === FALSE) {
                 throw new \F3\FLOW3\MVC\Exception\InvalidArgumentValueException('Route value "' . $routeValueKey . '" is an object but is unknown to the persistence manager.', 1242417960);
             }
             $routeValues[$routeValueKey] = array('__identity' => $uuid);
         } elseif (is_array($routeValue)) {
             $routeValues[$routeValueKey] = $this->convertDomainObjectsToIdentityArrays($routeValue);
         }
     }
     return $routeValues;
 }
 /**
  * Executes the number of matching objects for the query
  *
  * @return integer The number of matching objects
  * @author Karsten Dambekalns <*****@*****.**>
  * @api
  */
 public function count()
 {
     return $this->persistenceManager->getBackend()->getObjectCountByQuery($this);
 }