/** * 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); }