public static function deserializeTemporaryIds(Schema $schema, $serializedIds) { $temporaryIdMap = new TemporaryIdMap(); foreach (explode("\n", $serializedIds) as $entry) { $elements = explode(" ", $entry); if (count($elements) == 3) { $entity = $schema->getObjectEntity($elements[0]); $temporaryIdMap->setId($entity, $elements[1], $elements[2]); } } return $temporaryIdMap; }
private function processQueryParams(Schema $schema, $mainEntity) { // Get rid of any 'PHPSESSION' and cookie params. RestUrlParams::extractValue($this->params, session_name()); // Create/restore the temporaryIdMap. $storedTemporaryIds = NULL; if (isset($_SESSION[$this->sessionId])) { $storedTemporaryIds = TemporaryIdMap::deserializeTemporaryIds($schema, $_SESSION[$this->sessionId]); } $this->temporaryIdMap = new TemporaryIdMap($storedTemporaryIds); // Validate that prefixed parameters refer to existing entities. foreach ($this->params as $paramName => &$paramValue) { if (RestUrlParams::isFetchParam($paramName)) { continue; } $paramNameParts = explode(RestUrlParams::ENTITY_SEPARATOR, $paramName); $entity = NULL; $queryParam = NULL; if (count($paramNameParts) == 1) { if ($mainEntity == NULL) { // error_log("Ignoring unknown query parameter: '$paramName=$paramValue'."); unset($this->params[$paramName]); continue; } $entity = $mainEntity; $queryParam = $paramNameParts[0]; } else { // Check if the specified entity exists. $entity = $schema->getObjectEntity($paramNameParts[0], false); if ($entity == NULL) { throw new Exception("Unknown entity '{$paramNameParts['0']}' in query parameters.", RestResponse::CLIENT_ERROR); } $queryParam = $paramNameParts[1]; } // If one or more ID's are specified... if (strcasecmp($queryParam, RestUrlParams::ID) == 0) { // ...then substitute any temporary ID with its persisted counterpart. $persistedIds = array(); foreach (explode(RestUrlParams::ID_SEPARATOR, $paramValue) as $id) { $persistedIds[] = $this->temporaryIdMap->getPersistedId($entity, $id); } $paramValue = implode(RestUrlParams::ID_SEPARATOR, $persistedIds); } } }
private function determineModifyingAction(DOMElement $xmlElement, ObjectEntity $entity, &$id, TemporaryIdMap $temporaryIdMap) { $modifyingAction = NULL; $persistedId = $temporaryIdMap->getPersistedId($entity, $id, FALSE); // If a temporary id was specified that has a 'known' persisted version... if ($persistedId != NULL and strcasecmp($persistedId, $id) != 0) { // ...then replace the temporary id with that persisted version. $id = $persistedId; $xmlElement->setAttribute(XmlConstants::ID, $id); } // Check if it's a reference-only node. if ($xmlElement->childNodes->length == 0 and $id == NULL) { throw new Exception("Reference to '{$xmlElement->nodeName}' contains no @id attribute.", RestResponse::CLIENT_ERROR); } if ($xmlElement->hasAttribute(XmlConstants::DELETED) === TRUE) { $modifyingAction = ParsedObject::DELETED; // Ensure that objects that are to be deleted have a persisted id. if ($id == NULL) { throw new Exception("Cannot delete '" . $entity->getName() . "' if no @id attribute is specified.", RestResponse::CLIENT_ERROR); } else { if ($persistedId == NULL) { // A temporary, non-persisted object must be deleted. throw new Exception("Cannot delete '" . $entity->getName() . "' with non-persisted id '{$id}'.", RestResponse::CLIENT_ERROR); } } } else { if ($xmlElement->childNodes->length > 0) { // Check if the id has been mapped to a persisted id in an earlier request. if ($persistedId != NULL) { $modifyingAction = ParsedObject::CHANGED; } else { $modifyingAction = ParsedObject::CREATED; // Generate a temporary id for new objects if necessary. if ($id == NULL) { // If so, then generate a temporary id. $id = TemporaryIdMap::generateTemporaryId(); $xmlElement->setAttribute(XmlConstants::ID, $id); } } } else { if ($id == NULL) { // It's a reference-only node. throw new Exception("Reference to '{$xmlElement->nodeName}' contains no @id attribute.", RestResponse::CLIENT_ERROR); } } } return $modifyingAction; }
/** * Checks each foreign key property if it contains a temporary id and substitutes it with its persisted value, * if that is available in $temporaryIdMap. * * @param TemporaryIdMap $temporaryIdMap */ public function substituteTemporaryIds(TemporaryIdMap $temporaryIdMap) { // For each relationship... foreach ($this->entity->getRelationships() as $relationship) { // ...of which I am the holder of the foreign key... if ($relationship->getFkEntity() == $this->entity) { $foreignEntity = $relationship->getOppositeEntity($this->entity); $fkName = $relationship->getFkColumnName($foreignEntity); // ...and who's foreign key property is present in the set of values... if (array_key_exists($fkName, $this->propertyValues)) { // ...check if it contains a temporary key. $persistedId = $temporaryIdMap->getPersistedId($foreignEntity, $this->propertyValues[$fkName], FALSE); if ($persistedId != NULL) { // If so, then substitute it! $this->propertyValues[$fkName] = $persistedId; } } } } }