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;
                 }
             }
         }
     }
 }