Example #1
0
 public function invalidrestresourceAction()
 {
     $this->_helper->layout->disableLayout();
     $this->_helper->viewRenderer->setNoRender();
     $entry = RestAPIHelper::wrapResponse("", null, null, -1, null, null, RestErrorEnum::RE_INVALID_RESOURCE, null);
     $this->getResponse()->clearAllHeaders();
     header('Content-type: text/xml');
     header("HTTP/1.0 400 Bad Response");
     header("Status: 400 Bad Response");
     header("X-AppDB-REST-Resource-Invalid: 1");
     echo $entry;
 }
Example #2
0
 public function fetchAll($filter = null, $format = '', $xmldetailed = false)
 {
     if ($format === "xml") {
         $ores = parent::fetchAll(null);
         $ids = array();
         foreach ($ores as $i) {
             $ids[] = $i->void;
         }
         $res = new Default_Model_VOs();
         $res->filter->id->in($ids);
         if ($filter !== null) {
             $res->filter->chain($filter, "AND");
         }
         $res->filter->orderBy("name");
         $res->refresh("xml", $xmldetailed);
         $ret = $res->items;
         for ($ic = 0; $ic < count($ret); $ic++) {
             $i = $ret[$ic];
             $ii = '<e xmlns:vo="' . RestAPIHelper::XMLNS_VO() . "\" xmlns:discipline=\"" . RestAPIHelper::XMLNS_DISCIPLINE() . "\">{$i}</e>";
             $x = new SimpleXMLElement($ii);
             $x = $x->xpath("//vo:vo");
             $x = $x[0];
             $xid = strval($x->attributes()->id);
             foreach ($ores as $j) {
                 if ($j->void == $xid) {
                     $i = str_replace("<vo:vo ", "<vo:vo relation=\"" . strtolower(str_replace("VO ", "", $j->role)) . "\" ", $i);
                     $ret[$ic] = $i;
                     break;
                 }
             }
         }
         return $ret;
     } else {
         return parent::fetchAll($filter, $format, $xmldetailed);
     }
 }
Example #3
0
 public function get()
 {
     if (parent::get() !== false) {
         $s = file_get_contents(APPLICATION_PATH . "/apiroutes.xml");
         $s = str_replace("/:version/", "/" . RestAPIHelper::VERSION . "/", $s);
         $s = str_replace("\t", "", $s);
         $s = preg_replace('/>\\s+/', '>', $s);
         $s = preg_replace('/<\\s+/', '<', $s);
         $xslt = RestAPIHelper::getFolder(RestFolderEnum::FE_XSL_FOLDER) . "/apiroutes.xsl";
         $xsl = new DOMDocument();
         $xsl->load($xslt);
         $xml = new DOMDocument();
         $xml->loadXML($s, LIBXML_NSCLEAN | LIBXML_COMPACT);
         $proc = new XSLTProcessor();
         $proc->registerPHPFunctions();
         $proc->importStylesheet($xsl);
         $s = $proc->transformToXml($xml);
         $xml = new SimpleXMLElement($s);
         $xml->registerXPathNamespace('appdb', 'http://appdb.egi.eu/api/' . RestAPIHelper::VERSION . '/appdb');
         $x = $xml->xpath("//appdb:resource");
         $s = array();
         while (list(, $node) = each($x)) {
             $s[] = trim($node->asXML());
         }
         $this->_pageOffset = 0;
         $this->_pageLength = count($s);
         $this->_total = count($s);
         $s = RestAPIHelper::wrapResponse($s, "resource", "list", count($s));
         return new XMLRestResponse($s, $this);
     } else {
         return false;
     }
 }
Example #4
0
 private function getRecord($id, $prefix)
 {
     if ($id == "" || $prefix == "") {
         return $this->getError("badArgument", "The request is missing required arguments");
     } else {
         if ($prefix == "oa_dc") {
             if (substr($id, 0, 17) == "oai:appdb.egi.eu:") {
                 $item = substr($id, 17);
                 while (substr($item, 0, 1) == "/") {
                     $item = substr($item, 1);
                 }
                 $items = explode("/", $item);
                 $resource = $items[0];
                 $itemid = $items[1];
                 switch ($resource) {
                     case "applications":
                         $res = new RestAppItem(array("id" => $itemid));
                         break;
                     case "people":
                         $res = new RestPplItem(array("id" => $itemid));
                         break;
                     default:
                         return $this->buildResponse($this->getError("badArgument", "Requested invalid resource"), "GetRecord", $prefix);
                 }
                 debug_log("[OaiController::getRecord]: Getting " . "http://" . $_SERVER["APPLICATION_API_HOSTNAME"] . "/rest/latest/{$item}");
                 $res = strval($res->get());
                 $res = $this->buildResponse($res, "GetRecord", $prefix);
                 $xf = RestAPIHelper::getFolder(RestFolderEnum::FE_XSL_FOLDER) . "oai-applications.xsl";
                 $xsl = new DOMDocument();
                 $xsl->load($xf);
                 $proc = new XSLTProcessor();
                 $proc->registerPHPFunctions();
                 $proc->importStylesheet($xsl);
                 $xml = new DOMDocument();
                 $xml->loadXML($res, LIBXML_NSCLEAN | LIBXML_COMPACT);
                 $xml = $proc->transformToXml($xml);
                 return $xml;
             } else {
                 return $this->buildResponse($this->getError("idDoesNotExist", "Item not found"));
             }
         } else {
             return $this->buildResponse($this->getError("cannotDisseminateFormat", "The metadata format identified by the value given for the metadataPrefix argument is not supported by the item or by the repository."));
         }
     }
 }
Example #5
0
 /**  
  * implementation of abstract parse() operation from RestXMLParser.
  *
  * @xml SimpleXMLElement the root element of the application XML representation
  * 
  * @return Default_Model_Researcher
  * @access public
  */
 public function parse($xml)
 {
     if (!is_null($this->_user)) {
         $person = new Default_Model_Researcher();
         try {
             $xml = new SimpleXMLElement($xml);
         } catch (Exception $e) {
             $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
             $this->_extError = $e->getMessage();
             return $person;
         }
         $xmli = $xml->xpath('//person:person');
         if (count($xmli) === 0) {
             $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
             return $person;
         }
         $xml = $xmli[0];
         if ($this->_parent->getMethod() === RestMethodEnum::RM_POST) {
             if ($xml->attributes()->id) {
                 $person->id = strval($xml->attributes()->id);
             } else {
                 $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
                 $this->_extError = 'Resource ID missing';
                 return $person;
             }
         }
         if ($xml->attributes()->nodissemination) {
             $person->noDissemination = strval($xml->attributes()->nodissemination) === "true" ? true : false;
         }
         if ($xml->attributes()->cname) {
             $person->cname = strval($xml->attributes()->cname);
         }
         $firstname = $this->el($xml, "person:firstname");
         if (!is_null($firstname) && trim(strval($firstname)) !== "") {
             $person->firstName = trim(strval($firstname));
         }
         $lastname = $this->el($xml, "person:lastname");
         if (!is_null($lastname) && trim(strval($lastname)) !== "") {
             $person->lastName = trim(strval($lastname));
         }
         $gender = $this->el($xml, "person:gender");
         if (!is_null($gender)) {
             if (trim(strval($gender->attributes(RestAPIHelper::XMLNS_XSI())->nil)) === "true") {
                 $person->gender = 'n/a';
             } elseif (trim(strval($gender)) !== "") {
                 if (trim(strtolower(strval($gender))) === "male") {
                     $person->gender = "male";
                 } elseif (trim(strtolower(strval($gender))) === "female") {
                     $person->gender = "female";
                 }
             }
         }
         if ($this->_parent->getMethod() === RestMethodEnum::RM_PUT) {
             $person->dateInclusion = date("Y-m-d");
             $person->addedByID = $this->_parent->getUser()->id;
         }
         $person->lastUpdated = date('Y-m-d');
         $institute = trim(strval($this->el($xml, "person:institute")));
         if (!is_null($institute)) {
             $person->institution = trim(strval($institute));
         }
         $country = $this->el($xml, "regional:country");
         if (!is_null($country) && trim(strval($country->attributes()->id)) !== "") {
             $person->countryID = trim(strval($country->attributes()->id));
         }
         $role = $this->el($xml, "person:role");
         if (!is_null($role) && trim(strval($role->attributes()->id)) !== "") {
             $person->positionTypeID = trim(strval($role->attributes()->id));
         }
         $image = $this->el($xml, "person:image");
         $removeImageCache = false;
         if (!is_null($image)) {
             if (trim(strval($image->attributes(RestAPIHelper::XMLNS_XSI())->nil)) === "true") {
                 $person->clearImage();
                 $removeImageCache = true;
             } else {
                 if (!is_null($image->attributes()->type) && trim(strval($image->attributes()->type)) === "base64") {
                     // image is given as byte64 encoded string
                     if (trim(strval($image)) != '') {
                         $person->image = pg_escape_bytea(trim(strval($image)));
                         $removeImageCache = true;
                     }
                 } else {
                     // image is given as URL
                     if (trim(parse_url(strval($image), PHP_URL_SCHEME)) == '') {
                         // no URL scheme present; assume uploaded file though
                         // portal's uploadimage action in AppsController
                         if (trim(strval($image)) != '') {
                             try {
                                 $person->image = pg_escape_bytea(base64_encode(file_get_contents(APPLICATION_PATH . "/../public/" . trim(strval($image)))));
                                 $removeImageCache = true;
                             } catch (Exception $e) {
                                 $this->_error = RestErrorEnum::RE_BACKEND_ERROR;
                                 $this->_extError = $e->getMessage();
                                 return $person;
                             }
                         }
                     } else {
                         // URL scheme present; assume remote file
                         if (trim(strval($image)) != '') {
                             try {
                                 $person->image = pg_escape_bytea(base64_encode(file_get_contents(trim(strval($image)))));
                                 $removeImageCache = true;
                             } catch (Exception $e) {
                                 $this->_error = RestErrorEnum::RE_BACKEND_ERROR;
                                 $this->_extError = $e->getMessage();
                                 return $person;
                             }
                         }
                     }
                 }
             }
         }
         if ($removeImageCache === true) {
             if ($person->id != '' && file_exists(APPLICATION_PATH . "/../cache/ppl-image-" . $person->id . ".png")) {
                 unlink(APPLICATION_PATH . "/../cache/ppl-image-" . $person->id . ".png");
             }
         }
         $person->save();
         if ($this->_parent->getMethod() === RestMethodEnum::RM_POST) {
             //remove existing contact info
             $conts = new Default_Model_Contacts();
             $conts->filter->researcherid->equals($person->id);
             $conts->refresh();
             for ($i = count($conts->items) - 1; $i >= 0; $i--) {
                 $conts->remove($conts->items[$i]);
             }
         }
         //add new contact info
         $cts = new Default_Model_ContactTypes();
         $cts->refresh();
         $xmli = $xml->xpath("//person:contact");
         $conts2 = new Default_Model_Contacts();
         foreach ($xmli as $x) {
             if (trim(strval($x)) !== '') {
                 $cont = new Default_Model_Contact();
                 $cont->researcherID = $person->id;
                 $ct = trim(strval($x->attributes()->type));
                 $ctid = null;
                 for ($i = 0; $i < count($cts->items); $i++) {
                     if (strtolower($ct) == strtolower($cts->items[$i]->description)) {
                         $ctid = $cts->items[$i]->id;
                         break;
                     }
                 }
                 if (!is_null($ctid)) {
                     $cont->contactTypeID = $ctid;
                 } else {
                     $cont->contactTypeID = 7;
                     //e-mail by default
                 }
                 $cont->data = trim(strval($x));
                 if (strval($x->attributes()->primary) === "true") {
                     $cont->isPrimary = true;
                 }
                 $conts2->filter->data->equals($cont->data)->and($conts2->filter->contacttypeid->equals(7))->and($conts2->filter->researcherid->notequals($person->id));
                 $conts2->refresh("xml");
                 if (count($conts2->items) == 0) {
                     $cont->save();
                 } else {
                     $this->_error = RestErrorEnum::RE_BACKEND_ERROR;
                     $this->_extError = "e-mail address `" . $cont->data . "' already exists";
                     return $person;
                 }
             }
         }
         if ($this->_parent->getMethod() === RestMethodEnum::RM_POST || $this->_parent->getMethod() === RestMethodEnum::RM_PUT) {
             $xrels = $xml->xpath("person:relation");
             $ps = new Default_Model_Researchers();
             $ps->filter->id->equals($person->id);
             $p = null;
             if (count($ps->items) > 0) {
                 $p = $ps->items[0];
             }
             if ($p !== null) {
                 $rels = array();
                 if (count($xml->xpath('person:relation[@xsi:nil="true"]')) === 0) {
                     foreach ($xrels as $x) {
                         $targuid = trim(strval($x->attributes()->targetguid));
                         $subguid = trim(strval($x->attributes()->subjectguid));
                         $rel = array("id" => trim(strval($x->attributes()->id)), "parentid" => trim(strval($x->attributes()->parentid)));
                         if ($targuid === "") {
                             $rel["subjectguid"] = $subguid;
                         } else {
                             if ($subguid === "") {
                                 $rel["targetguid"] = $targuid;
                             }
                         }
                         if ($rel["parentid"] === "") {
                             $rel["parentid"] = null;
                         }
                         $rels[] = $rel;
                     }
                 }
                 try {
                     $res = PersonRelations::syncRelations($p->guid, $this->_user->id, $rels);
                 } catch (Exception $ex) {
                     $res = $ex->getMessage();
                 }
                 if (is_string($res)) {
                     $this->_error = RestErrorEnum::RE_BACKEND_ERROR;
                     $this->_extError = $res;
                     return $p;
                 }
             }
         }
     }
     $this->_error = RestErrorEnum::RE_OK;
     return $person;
 }
<?php

include_once '../class/StringHelper.class.php';
include_once '../class/RestAPIHelper.class.php';
include_once 'config.php';
$action = StringHelper::ifPostNotExistThenNull('action');
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
switch ($action) {
    case 'addNewFeatureRequest':
        $title = StringHelper::ifPostNotExistThenNull('title');
        $description = StringHelper::ifPostNotExistThenNull('description');
        $client = StringHelper::ifPostNotExistThenNull('client');
        $priority = StringHelper::ifPostNotExistThenNull('priority');
        $date = StringHelper::ifPostNotExistThenNull('date');
        $url = StringHelper::ifPostNotExistThenNull('url');
        $product = StringHelper::ifPostNotExistThenNull('product');
        $url = RestAPIHelper::createLocalRESTAPIUrl(BASE_FOLDER . '/api/requests.php/request');
        $data = array('title' => $title, 'description' => $description, 'client' => $client, 'priority' => $priority, 'date' => $date, 'url' => $url, 'product' => $product);
        $jsonResult = RestAPIHelper::CallAPI("POST", $url, json_encode($data));
        if ($jsonResult->status == 'fail') {
            header("Location: " . "../index.php?msg=" . $jsonResult->reason);
        } else {
            header("Location: " . "../index.php");
        }
        break;
    default:
        break;
}
Example #7
0
 /**
  * realization of logAction() from iRestAPILogger.
  */
 public function logAction($event, $target, $id, $old, $new, $disposition = null)
 {
     if ($this->_logfile != '') {
         if (strval($old) != strval($new)) {
             $now = new DateTime();
             $f = fopen($this->_logfile, "a");
             if ($f !== false) {
                 error_log('Acquiring exclusive lock on logfile "' . $this->_logfile . '"');
                 if (flock($f, LOCK_EX)) {
                     $userid = $this->_userid != "" ? ' userid="' . $this->_userid . '"' : '';
                     $username = $this->_userid != "" ? ' username="******"' : '';
                     $usercontact = $this->_userid != "" ? is_null($this->getUser()->primaryContact) ? '' : ' usercontact="' . $this->getUser()->primaryContact . '"' : '';
                     $dispo = $disposition === null ? "" : ' disposition="' . $disposition . '"';
                     fwrite($f, '<action target="' . $target . '" id="' . $id . '" event="' . $event . '"' . $userid . $username . $usercontact . $dispo . ' apiver="' . RestAPIHelper::getVersion() . '" timestamp="' . $now->format('Ydm H:i:s') . '">' . "\n");
                     if ($old != "") {
                         fwrite($f, '<oldvalue>' . base64_encode(bzcompress($old)) . '</oldvalue>' . "\n");
                     }
                     if ($new != "") {
                         fwrite($f, '<newvalue>' . base64_encode(bzcompress($new)) . '</newvalue>' . "\n");
                     }
                     fwrite($f, '</action>' . "\n");
                     flock($f, LOCK_UN);
                     fclose($f);
                 } else {
                     error_log('Could not acquire exclusive write log for logfile "' . $this->_logfile . '". Will not log API action.');
                 }
             } else {
                 error_log('Could not write API log entry in logfile "' . $this->_logfile . '"');
             }
         }
     }
 }
Example #8
0
 private function gridops_is_down()
 {
     @exec(APPLICATION_PATH . "/../bin/gridops_down");
     if (file_exists(RestAPIHelper::getFolder(RestFolderEnum::FE_CACHE_FOLDER) . "/gridops_downtime")) {
         return true;
     } else {
         return false;
     }
 }
Example #9
0
 public function onError($errorDesc)
 {
     echo RestAPIHelper::responseHead("unknown", $error = "Internal Server Error", $exterror = $errorDesc) . RestAPIHelper::responseTail();
 }
Example #10
0
 public function hidePrivateData($data)
 {
     return $data;
     $xf = RestAPIHelper::getFolder(RestFolderEnum::FE_XSL_FOLDER) . 'virtualization.private.xsl';
     $xsl = new DOMDocument();
     $xsl->load($xf);
     $proc = new XSLTProcessor();
     $proc->registerPHPFunctions();
     $proc->importStylesheet($xsl);
     $xml = new DOMDocument();
     $xml->loadXML($data, LIBXML_NSCLEAN | LIBXML_COMPACT);
     $res = $proc->transformToXml($xml);
     return $res;
 }
Example #11
0
 public function newproxy()
 {
     $apiroutes = new SimpleXMLElement(APPLICATION_PATH . "/apiroutes.xml", 0, true);
     $pars = array();
     $postdata = null;
     $method = strtolower($this->getRequest()->getMethod());
     $error = null;
     $extError = null;
     if ($method === "post") {
         $postdata = $_POST['data'];
         if (isset($_POST['resource']) && trim($_POST['resource']) === "broker") {
             if ($this->session->isLocked()) {
                 $this->session->unLock();
             }
             session_write_close();
             $res = $_POST['resource'];
         } else {
             $res = $this->_getParam("resource");
         }
     } else {
         $res = $this->_getParam("resource");
     }
     $url = preg_replace('/\\?.*/', '', $res);
     $qs = explode("&", preg_replace('/.*\\?/', '', $res));
     $rx = RestBroker::matchResource($url, $apiroutes, $pars);
     if (is_null($rx)) {
         // FIXME: workaround for erroneous proxy resource notation (double URL-encoded)
         // FIXME: should be fixed at the source
         $res = urldecode($res);
         $url = preg_replace('/\\?.*/', '', $res);
         $qs = explode("&", preg_replace('/.*\\?/', '', $res));
         $rx = RestBroker::matchResource($url, $apiroutes, $pars);
         if (!is_null($rx)) {
             // FIXME: workaround for erroneous people canonical URLs with query strings
             if ($rx->resource == "RestPplItem" && ($method = "get")) {
                 $qs = null;
             }
         }
     } else {
         // FIXME: workaround for erroneous people canonical URLs with query strings
         if ($rx->resource == "RestPplItem" && ($method = "get")) {
             $qs = null;
         }
     }
     if (is_array($qs)) {
         foreach ($qs as $q) {
             $i = explode("=", $q);
             if (count($i) > 1) {
                 $pars[$i[0]] = urldecode($i[1]);
             }
         }
     }
     if (!is_null($postdata)) {
         $pars['data'] = $postdata;
     }
     $routeXslt = null;
     switch (strtolower($method)) {
         case "get":
             $method = RestMethodEnum::RM_GET;
             break;
         case "put":
             $method = RestMethodEnum::RM_PUT;
             break;
         case "post":
             $method = RestMethodEnum::RM_POST;
             break;
         case "delete":
             $method = RestMethodEnum::RM_DELETE;
             break;
         case "options":
             $method = RestMethodEnum::RM_OPTIONS;
             break;
         default:
             $method = RestMethodEnum::RM_GET;
             break;
     }
     $ret = "";
     if (!is_null($rx)) {
         try {
             $resclass = strval($rx->resource);
             $this->session = new Zend_Session_Namespace('default');
             if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '') {
                 $src = base64_encode($_SERVER['REMOTE_ADDR']);
             } else {
                 $src = '';
             }
             $pars['src'] = $src;
             if (isset($_SERVER['SERVER_ADDR']) && $_SERVER['SERVER_ADDR'] != '') {
                 $srv = base64_encode($_SERVER['SERVER_ADDR']);
             } else {
                 $srv = '';
             }
             $pars['remoteaddr'] = $srv;
             $apikey = $userid = $passwd = '';
             if ($this->session->userid !== null) {
                 $userid = $this->session->userid;
                 if (isset($_COOKIE['SimpleSAMLAuthToken'])) {
                     $passwd = $_COOKIE['SimpleSAMLAuthToken'];
                 } else {
                     error_log("Warning: auth token cookie ('SimpleSAMLAuthToken') is undefined!");
                 }
                 $apiconf = Zend_Registry::get("api");
                 $apikey = $apiconf["key"];
             }
             $pars['userid'] = $userid;
             $pars['passwd'] = $passwd;
             $pars['apikey'] = $apikey;
             $pars['sessionid'] = session_id();
             $pars['cid'] = 0;
             if ($userid != '') {
                 $_GET['userid'] = $userid;
             }
             $res = new $resclass($pars);
             $fmt = $rx->xpath("format");
             if (count($fmt) > 0) {
                 foreach ($fmt as $f) {
                     if (strval($f) === "xml") {
                         if (strval($f->attributes()->xslt) != '') {
                             $routeXslt = strval($f->attributes()->xslt);
                         }
                         break;
                     }
                 }
             }
         } catch (Exception $e) {
             $error = RestErrorEnum::toString(RestErrorEnum::RE_INVALID_REPRESENTATION);
             $extError = "Could not instantiate REST resource for request `" . $res . "'";
             $this->getResponse()->clearAllHeaders();
             $this->getResponse()->setRawHeader("HTTP/1.0 400 Bad Request");
             $this->getResponse()->setHeader("Status", "400 Bad Request");
             if ($extError != "") {
                 error_log($error . '\\n' . $extError);
                 echo $error . '\\n' . $extError;
             } else {
                 error_log($error);
                 echo $error;
             }
             return;
         }
     } else {
         $error = RestErrorEnum::toString(RestErrorEnum::RE_INVALID_REPRESENTATION);
         $extError = "Could not resolve REST resource for request `" . $res . "'";
         $this->getResponse()->clearAllHeaders();
         $this->getResponse()->setRawHeader("HTTP/1.0 400 Bad Request");
         $this->getResponse()->setHeader("Status", "400 Bad Request");
         if ($extError != "") {
             error_log($error . '\\n' . $extError);
             echo $error . '\\n' . $extError;
         } else {
             error_log($error);
             echo $error;
         }
         return;
     }
     $s_method = strtolower(RestMethodEnum::toString($method));
     $_res = $res->{$s_method}();
     if ($_res !== false) {
         if ($_res->isFragment()) {
             $res = $_res->finalize();
         } else {
             $res = $_res;
         }
         if (!is_null($routeXslt)) {
             $res = $res->transform(RestAPIHelper::getFolder(RestFolderEnum::FE_XSL_FOLDER) . $routeXslt);
         }
         echo $res;
     } else {
         $error = RestErrorEnum::toString($res->getError());
         $extError = $res->getExtError();
         $this->getResponse()->clearAllHeaders();
         $this->getResponse()->setRawHeader("HTTP/1.0 400 Bad Request");
         $this->getResponse()->setHeader("Status", "400 Bad Request");
         if ($extError != "") {
             error_log($error . '\\n' . $extError);
             echo $error . '\\n' . $extError;
         } else {
             error_log($error);
             echo $error;
         }
     }
 }
Example #12
0
 /**
  * implementation of abstract parse() operation from RestXMLParser.
  * @xml SimpleXMLElement the root element of the dataset XML representation
  * 
  * @return Default_Model_Dataset
  * @access public
  */
 public function parse($xml)
 {
     global $application;
     $ds = null;
     if (!is_null($this->_user)) {
         $ds = new Default_Model_DatasetVersion();
         try {
             $xml = new SimpleXMLElement($xml);
         } catch (Exception $e) {
             $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
             return $ds;
         }
         $this->_xml = $xml;
         // basic properties
         $xmli = $xml->xpath('//dataset:version');
         if (count($xmli) === 0) {
             $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
             return $ds;
         }
         $xml = $xmli[0];
         if ($this->_parent->getMethod() === RestMethodEnum::RM_PUT && (strval($xml->attributes()->version) == "" || strval($xml->attributes()->datasetid) == "" && $this->_parent->getParam("id") == "")) {
             $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
             $this->_extError = "One ore more required entities or attributes are missing or contain no data.";
             return $ds;
         }
         if ($this->_parent->getMethod() === RestMethodEnum::RM_PUT) {
             // do not modify version string, parent dataset for existing entry; set only for PUT (insert)
             $ds->version = strval($xml->attributes()->version);
             if ($this->_parent->getParam("id") == "") {
                 $ds->datasetID = intval(strval($xml->attributes()->datasetid));
             } else {
                 $ds->datasetID = intval($this->_parent->getParam("id"));
             }
         }
         if ($this->_parent->getMethod() === RestMethodEnum::RM_POST) {
             if ($xml->attributes()->id) {
                 $ds->id = intval(strval($xml->attributes()->id));
                 $db = $application->getBootstrap()->getResource('db');
                 $db->setFetchMode(Zend_Db::FETCH_OBJ);
                 $r = $db->query('SELECT guid FROM dataset_versions WHERE id = ' . $ds->id)->fetchAll();
                 if (count($r) > 0) {
                     $ds->guid = $r[0]->guid;
                 }
             } else {
                 $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
                 return $ds;
             }
         }
         if ($this->_parent->getMethod() === RestMethodEnum::RM_PUT) {
             $ds->addedByID = $this->_parent->getUser()->id;
         }
         if (!is_null($this->el($xml, "dataset:size"))) {
             $ds->size = strval($this->el($xml, "dataset:size"));
             if ($ds->size == "") {
                 $ds->size = null;
             }
         }
         if (!is_null($this->el($xml, "dataset:notes"))) {
             $ds->notes = strval($this->el($xml, "dataset:notes"));
         }
         if (!is_null($this->el($xml, 'dataset:parent_version[@xsi:nil="true"]'))) {
             $ds->parentID = 0;
         } elseif (!is_null($this->el($xml, "dataset:parent_version"))) {
             $ds->parentID = $this->el($xml, "dataset:parent_version")->attributes()->id;
             if ($ds->parentID == "") {
                 $this->_error = RestErrorEnum::RE_INVALID_REPRESENTATION;
                 return $ds;
             } else {
                 $datasets = new Default_Model_DatasetVersions();
                 $datasets->filter->id->numequals($ds->parentID);
                 if (count($datasets->items) == 0) {
                     $this->_error = RestErrorEnum::RE_ITEM_NOT_FOUND;
                     $this->_extError = "Parent dataset version not found";
                     return $ds;
                 }
             }
         }
         $ds->save();
         // Also save locations if they exist
         if (count($xml->xpath('//dataset:location[@xsi:nil="true"]')) > 0) {
             if ($ds->id != "") {
                 $locations = new Default_Model_DatasetLocations();
                 $locations->filter->dataset_version_id->numequals($ds->id);
                 if (count($locations->items) > 0) {
                     foreach ($locations->items as $loc) {
                         $locres = new RestDatasetLocationItem(array_merge($this->_parent->getParams(), array('data' => $data, 'vid' => $ds->id, 'lid' => $loc->id)));
                         $locres->delete();
                     }
                 }
             }
         } else {
             $xmlloc = $xml->xpath("//dataset:location");
             if (count($xmlloc) > 0) {
                 if ($ds->id != "") {
                     // keep track of existing locations
                     $db = $application->getBootstrap()->getResource('db');
                     $db->setFetchMode(Zend_Db::FETCH_OBJ);
                     $existing = $db->query("SELECT id FROM dataset_locations WHERE dataset_version_id = " . $ds->id)->fetchAll();
                     $eids = array();
                     foreach ($existing as $e) {
                         $eids[] = $e->id;
                     }
                 }
                 foreach ($xmlloc as $x) {
                     $data = RestAPIHelper::responseHead("dataset") . $x->asXML() . RestAPIHelper::responseTail();
                     $locres = new RestDatasetLocationList(array_merge($this->_parent->getParams(), array('data' => $data, 'vid' => $ds->id)));
                     if (isset($x->attributes()->id)) {
                         for ($eiter = count($eids) - 1; $eiter >= 0; $eiter = $eiter - 1) {
                             // remove submitted locations from array of existing locations
                             if (isset($eids[$eiter])) {
                                 if ($eids[$eiter] == $x->attributes()->id) {
                                     // DO NOT USE "unset"; does not work properly
                                     $eids[$eiter] = -1;
                                 }
                             }
                         }
                     }
                     if ($this->_parent->getMethod() === RestMethodEnum::RM_PUT) {
                         $locres->put();
                     } else {
                         if (isset($x->attributes()->id)) {
                             $locres->post();
                         } else {
                             $locres->put();
                         }
                     }
                     $this->_error = $locres->getError();
                     $this->_extError = $locres->getExtError();
                     if ($this->_error != RestErrorEnum::RE_OK) {
                         break;
                     }
                 }
                 if ($ds->id != "") {
                     // remove remaining existing locations, they were not submitted
                     foreach ($eids as $e) {
                         if ($e != "" && $e != -1) {
                             $locres = new RestDatasetLocationItem(array_merge($this->_parent->getParams(), array('data' => $data, 'vid' => $ds->id, 'lid' => $e)));
                             $locres->delete();
                         }
                     }
                 }
             }
         }
     }
     return $ds;
 }