public function parseXml() { global $global; require_once($global['approot']."inc/lib_uuid.inc"); // save xml for debugging? if($global['debugAndSaveXmlToFile'] == true) { $filename = date("Y_md_H-i-s.".getMicrotimeComponent())."___".mt_rand().".xml"; // 2012_0402_17-50-33.454312___437849328789.xml $path = $global['debugAndSaveXmlToFilePath'].$filename; file_put_contents($path, $this->theString); } // is this a supported XML type? if(!in_array((string)trim($this->xmlFormat), $global['enumXmlFormats'])) { return (int)400; } //$a = xml2array($this->theString); $aa = new XMLParser(); $aa->rawXML = $this->theString; $aa->parse(); if($aa->getError()) { return (int)403; // error code for failed to parse xml } $a = $aa->getArray(); // parse REUNITE4 XML if($this->xmlFormat == "REUNITE4") { $this->createUUID(); $this->arrival_reunite = true; $this->given_name = isset($a['person']['givenName']) ? $a['person']['givenName'] : null; $this->family_name = isset($a['person']['familyName']) ? $a['person']['familyName'] : null; $this->expiry_date = isset($a['person']['expiryDate']) ? $a['person']['expiryDate'] : null; $this->opt_status = isset($a['person']['status']) ? $a['person']['status'] : null; $this->last_updated = date('Y-m-d H:i:s'); $datetime = isset($a['person']['dateTimeSent']) ? $a['person']['dateTimeSent'] : null; $timezoneUTC = new DateTimeZone("UTC"); $timezoneLocal = new DateTimeZone(date_default_timezone_get()); $datetime2 = new DateTime(); $datetime2->setTimezone($timezoneUTC); $datetime2->setTimestamp(strtotime($datetime)); $datetime2->setTimezone($timezoneLocal); $this->creation_time = $datetime2->format('Y-m-d H:i:s'); $this->opt_gender = isset($a['person']['gender']) ? $a['person']['gender'] : null; $this->years_old = isset($a['person']['estimatedAge']) ? $a['person']['estimatedAge'] : null; $this->minAge = isset($a['person']['minAge']) ? $a['person']['minAge'] : null; $this->maxAge = isset($a['person']['maxAge']) ? $a['person']['maxAge'] : null; $this->other_comments = isset($a['person']['note']) ? $a['person']['note'] : null; // TEMP HACK KLUGE to stuff person location data into the person_status last_known_location field $kluge = ""; $kluge .= isset($a['person']['location']['street1']) ? $a['person']['location']['street1']."\n" : ""; $kluge .= isset($a['person']['location']['street2']) ? $a['person']['location']['street2']."\n" : ""; $kluge .= isset($a['person']['location']['neighborhood']) ? $a['person']['location']['neighborhood']."\n" : ""; $kluge .= isset($a['person']['location']['city']) ? $a['person']['location']['city']."\n" : ""; $kluge .= isset($a['person']['location']['region']) ? $a['person']['location']['region']."\n" : ""; $kluge .= isset($a['person']['location']['postalCode']) ? $a['person']['location']['postalCode']."\n" : ""; $kluge .= isset($a['person']['location']['country']) ? $a['person']['location']['country']."\n" : ""; if(trim($kluge) != "") { $this->last_seen = $kluge; } // only update the incident_id if not already set if($this->incident_id === null) { $q = " SELECT * FROM incident WHERE shortname = '".mysql_real_escape_string((string)$a['person']['eventShortname'])."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person get incident ((".$q."))"); } $this->incident_id = $result->fields["incident_id"]; } if(isset($a['person']['photos']['photo'])) { foreach($a['person']['photos'] as $photo) { if(trim($photo['data']) != "") { $i = new personImage(); $i->init(); $i->p_uuid = $this->p_uuid; $i->fileContentBase64 = $photo['data']; if(isset($photo['tags'])) { foreach($photo['tags'] as $tag) { $t = new personImageTag(); $t->init(); $t->image_id = $i->image_id; $t->tag_x = $tag['x']; $t->tag_y = $tag['y']; $t->tag_w = $tag['w']; $t->tag_h = $tag['h']; $t->tag_text = $tag['text']; $i->tags[] = $t; } } $this->images[] = $i; } } } // if there is actual voicenote data, save process it... if(isset($a['person']['voiceNote']['data']) && trim($a['person']['voiceNote']['data']) != "") { $v = new voiceNote(); $v->init(); // reserves a voicenote id for this note $v->p_uuid = $this->p_uuid; $v->dataBase64 = $a['person']['voiceNote']['data']; $v->length = $a['person']['voiceNote']['length']; $v->format = $a['person']['voiceNote']['format']; $v->sample_rate = $a['person']['voiceNote']['sampleRate']; $v->channels = $a['person']['voiceNote']['numberOfChannels']; $v->speaker = $a['person']['voiceNote']['speaker']; $this->voice_note = $v; } // check for p_uuid collision with already present data, return 401 error if p_uuid already exists $q = " SELECT count(*) FROM person_uuid WHERE p_uuid = '".mysql_real_escape_string((string)$this->p_uuid)."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person check p_uuid collision ((".$q."))"); } if(!$this->ignoreDupeUuid && (int)$result->fields['count(*)'] > 0 ) { return (int)401; } // check if reported p_uuid is valid (in range of sequence) ~ 402 error if not if(!shn_is_p_uuid_valid($this->p_uuid)) { return (int)402; } // check if the event is closed to reporting... if(!$this->isEventOpen()) { return (int)405; } // no errors return (int)$this->ecode; // parse REUNITE3 XML } elseif($this->xmlFormat == "REUNITE3") { $this->arrival_reunite = true; $this->p_uuid = $a['person']['p_uuid']; $this->given_name = $a['person']['givenName']; $this->family_name = $a['person']['familyName']; $this->expiry_date = $a['person']['expiryDate']; $this->opt_status = $a['person']['status']; $this->last_updated = date('Y-m-d H:i:s'); $this->creation_time = $a['person']['dateTimeSent']; $this->opt_gender = $a['person']['gender']; $this->years_old = $a['person']['estimatedAge']; $this->minAge = $a['person']['minAge']; $this->maxAge = $a['person']['maxAge']; $this->other_comments = $a['person']['note']; // only update the incident_id if not already set if($this->incident_id === null) { $this->incident_id = $a['person']['eventId']; } foreach($a['person']['photos'] as $photo) { if(trim($photo['data']) != "") { $i = new personImage(); $i->init(); $i->p_uuid = $this->p_uuid; $i->fileContentBase64 = $photo['data']; foreach($photo['tags'] as $tag) { $t = new personImageTag(); $t->init(); $t->image_id = $i->image_id; $t->tag_x = $tag['x']; $t->tag_y = $tag['y']; $t->tag_w = $tag['w']; $t->tag_h = $tag['h']; $t->tag_text = $tag['text']; $i->tags[] = $t; } if(!$i->invalid) { $this->images[] = $i; $this->ecode = 419; } } } // if there is actual voicenote data, save process it... if(trim($a['person']['voiceNote']['data']) != "") { $v = new voiceNote(); $v->init(); // reserves a voicenote id for this note $v->p_uuid = $this->p_uuid; $v->dataBase64 = $a['person']['voiceNote']['data']; $v->length = $a['person']['voiceNote']['length']; $v->format = $a['person']['voiceNote']['format']; $v->sample_rate = $a['person']['voiceNote']['sampleRate']; $v->channels = $a['person']['voiceNote']['numberOfChannels']; $v->speaker = $a['person']['voiceNote']['speaker']; $this->voice_note = $v; } // check for p_uuid collision with already present data, return 401 error if p_uuid already exists $q = " SELECT count(*) FROM person_uuid WHERE p_uuid = '".mysql_real_escape_string((string)$this->p_uuid)."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person check p_uuid collision ((".$q."))"); } if(!$this->ignoreDupeUuid && (int)$result->fields['count(*)'] > 0 ) { return (int)401; } // check if reported p_uuid is valid (in range of sequence) ~ 402 error if not if(!shn_is_p_uuid_valid($this->p_uuid)) { return (int)402; } // check if the event is closed to reporting... if(!$this->isEventOpen()) { return (int)405; } // no errors return (int)$this->ecode; // parse REUNITE2 XML } elseif($this->xmlFormat == "REUNITE2") { $this->arrival_reunite = true; // figure out the incident_id $shortName = strtolower($a['lpfContent']['person']['eventShortName']); $q = " SELECT * FROM incident WHERE shortname = '".mysql_real_escape_string((string)$shortName)."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person get incident ((".$q."))"); } if($result != NULL && !$result->EOF) { $this->incident_id = $result->fields['incident_id']; } else { return (int)406; } // extract other xml data $this->createUUID(); $this->given_name = $a['lpfContent']['person']['firstName']; $this->family_name = $a['lpfContent']['person']['familyName']; $this->opt_status = substr(strtolower($a['lpfContent']['person']['status']['healthStatus']), 0, 3); $this->last_updated = date('Y-m-d H:i:s'); $this->creation_time = $a['lpfContent']['person']['dateTimeSent']; $this->opt_gender = substr(strtolower($a['lpfContent']['person']['gender']), 0, 3); $this->years_old = $a['lpfContent']['person']['estimatedAgeInYears']; $this->minAge = $a['lpfContent']['person']['ageGroup']['minAge']; $this->maxAge = $a['lpfContent']['person']['ageGroup']['maxAge']; $this->other_comments = $a['lpfContent']['person']['notes']; // check if the event is closed to reporting... if(!$this->isEventOpen()) { return (int)405; } // no errors return (int)0; // parse TRIAGEPIC1 XML } elseif($this->xmlFormat == "TRIAGEPIC1") { $this->arrival_triagepic = true; $this->edxl = new personEdxl(); $this->edxl->init(); // when we have more than 1 contentObject, they are renamed to 0...x if(isset($a['EDXLDistribution'][0])) { $ix = 0; // when there is only 1 contentObject, we go by name } elseif(isset($a['EDXLDistribution']['contentObject'])) { $ix = "contentObject"; // all else, we fail and quit } else { return (int)403; // error code for failed to parse xml } $this->createUUID(); $this->family_name = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['lastName']; $this->given_name = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['firstName']; $eventName = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['eventName']; $q = " SELECT * FROM incident WHERE shortname = '".mysql_real_escape_string((string)$eventName)."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person get incident ((".$q."))"); } $this->incident_id = $result->fields["incident_id"]; $b = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['triageCategory']; if(($b == "Green") || ($b == "BH Green")) { $this->opt_status = "ali"; } elseif(($b == "Yellow") || ($b == "Red") || ($b == "Gray")) { $this->opt_status = "inj"; } elseif($b == "Black") { $this->opt_status = "dec"; } else { $this->opt_status = "unk"; } $this->last_updated = date('Y-m-d H:i:s'); // <dateTimeSent>2011-03-28T07:52:17Z</dateTimeSent> $datetime = $a['EDXLDistribution']['dateTimeSent']; $timezoneUTC = new DateTimeZone("UTC"); $timezoneLocal = new DateTimeZone(date_default_timezone_get()); $datetime2 = new DateTime(); $datetime2->setTimezone($timezoneUTC); $datetime2->setTimestamp(strtotime($datetime)); $datetime2->setTimezone($timezoneLocal); $this->creation_time = $datetime2->format('Y-m-d H:i:s'); $this->opt_gender = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['gender']; $peds = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['peds']; if($peds == "Y") { $this->minAge = 0; $this->maxAge = 17; } elseif($peds == "N") { $this->minAge = 18; $this->maxAge = 150; } elseif($peds == "Y,N") { $this->minAge = 0; $this->maxAge = 150; } $this->other_comments = $a['EDXLDistribution'][$ix]['contentDescription']; $orgId = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['organization']['orgId']; $q = " SELECT * FROM hospital WHERE npi = '".mysql_real_escape_string((string)$orgId)."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person get hospital ((".$q."))"); } $this->hospital_uuid = $result->fields["hospital_uuid"]; $this->last_seen = $result->fields["name"]." Hospital"; $this->edxl->content_descr = $a['EDXLDistribution'][$ix]['contentDescription']; $this->edxl->p_uuid = $this->p_uuid; $this->edxl->schema_version = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['version']; $this->edxl->login_machine = "n/a"; //null; HACK! cant be null $this->edxl->login_account = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['login']['userName']; $this->edxl->person_id = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['personId']; $this->edxl->event_name = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['eventName']; $this->edxl->event_long_name = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['eventLongName']; $this->edxl->org_name = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['organization']['orgName']; $this->edxl->org_id = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['organization']['orgId']; $this->edxl->last_name = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['lastName']; $this->edxl->first_name = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['firstName']; $this->edxl->gender = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['gender']; $this->edxl->peds = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['peds']; $this->edxl->triage_category = $a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['triageCategory']; $this->edxl->when_sent = $this->last_updated; $this->edxl->sender_id = $a['EDXLDistribution']['senderID']; $this->edxl->distr_id = $a['EDXLDistribution']['distributionID']; $this->edxl->distr_status = $a['EDXLDistribution']['distributionStatus']; $this->edxl->distr_type = $a['EDXLDistribution']['distributionType']; $this->edxl->combined_conf = $a['EDXLDistribution']['combinedConfidentiality']; $this->edxl->language = null; $this->edxl->when_here = $this->creation_time; $this->edxl->inbound = 1; //null; HACK! cant be null $this->edxl->type = "lpf"; $this->cleanInput(); // parse all images for($n = 0; $n < sizeof($a['EDXLDistribution']); $n++) { if(isset($a['EDXLDistribution'][$n]['nonXMLContent']) && $a['EDXLDistribution'][$n]['nonXMLContent'] != null) { $imageNode = $a['EDXLDistribution'][$n]['nonXMLContent']; $cd = $a['EDXLDistribution'][$n]['contentDescription']; $cd = str_replace($a['EDXLDistribution'][$ix]['xmlContent']['lpfContent']['person']['personId'], "", $cd); // remove patient id from the string $cd = str_replace($this->edxl->triage_category, "", $cd); // remove triage category from the string $cd = trim($cd); // remove preceding and trailing whitespace(s) // what we should now have left is in the format: "" or "sX" or "sX - caption" or "- caption" // primary no caption if($cd === "") { $primary = true; $caption = null; // secondary no caption } elseif(strpos($cd, "-") === false) { $primary = false; $caption = null; // has caption } else { $ecd = explode("-", $cd); // primary with caption if(trim($ecd[0]) == "") { $primary = true; $caption = $ecd[1]; // secondary with caption } else { $primary = false; $caption = trim($ecd[1]); } } // create sahana image if(trim($imageNode['contentData']) != "") { $i = new personImage(); $i->init(); $i->p_uuid = $this->p_uuid; $i->fileContentBase64 = $imageNode['contentData']; $i->decode(); $xmlSha1 = $imageNode['digest']; $realSha1 = sha1($i->fileContent); if(strcasecmp($realSha1, $xmlSha1) != 0) { //error_log("420 ERROR!! realSha1(".$realSha1.") xmlSha1(".$xmlSha1.")"); $i->invalid = true; $this->ecode = 420; } else { //error_log("strings match! realSha1(".$realSha1.") xmlSha1(".$xmlSha1.")"); } $i->original_filename = $imageNode['uri']; if($primary) { $i->principal = 1; } if($caption != null) { $t = new personImageTag(); $t->init(); $t->image_id = $i->image_id; $t->tag_x = 0; $t->tag_y = 0; $t->tag_w = 10; $t->tag_h = 10; $t->tag_text = $caption; $i->tags[] = $t; } if(!$i->invalid) { $this->images[] = $i; } } // create edxl image $this->edxl->mimeTypes[] = $imageNode['mimeType']; $this->edxl->uris[] = $imageNode['uri']; $this->edxl->contentDatas[] = $imageNode['contentData']; $this->edxl->image_ids[] = isset($i->image_id) ? $i->image_id : null; $this->edxl->image_sha1[] = isset($realSha1) ? $realSha1 : null; $this->edxl->image_co_ids[] = shn_create_uuid("edxl_co_header"); } } // check if the event is closed to reporting... if(!$this->isEventOpen()) { return (int)405; } // exit with success return (int)$this->ecode; // parse TRIAGEPIC0 XML } elseif($this->xmlFormat == "TRIAGEPIC0") { $this->arrival_triagepic = true; $this->edxl = new personEdxl(); $this->edxl->init(); $this->createUUID(); $this->family_name = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['lastName']; $this->given_name = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['firstName']; $eventName = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['eventName']; $q = " SELECT * FROM incident WHERE shortname = '".mysql_real_escape_string((string)$eventName)."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person get incident ((".$q."))"); } $this->incident_id = $result->fields["incident_id"]; $b = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['triageCategory']; if(($b == "Green") || ($b == "BH Green")) { $this->opt_status = "ali"; } elseif(($b == "Yellow") || ($b == "Red") || ($b == "Gray")) { $this->opt_status = "inj"; } elseif($b == "Black") { $this->opt_status = "dec"; } else { $this->opt_status = "unk"; } $this->last_updated = date('Y-m-d H:i:s'); // <dateTimeSent>2011-03-28T07:52:17Z</dateTimeSent> $datetime = $a['EDXLDistribution']['dateTimeSent']; $timezoneUTC = new DateTimeZone("UTC"); $timezoneLocal = new DateTimeZone(date_default_timezone_get()); $datetime2 = new DateTime(); $datetime2->setTimezone($timezoneUTC); $datetime2->setTimestamp(strtotime($datetime)); $datetime2->setTimezone($timezoneLocal); $this->creation_time = $datetime2->format('Y-m-d H:i:s'); $this->opt_gender = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['gender']; $peds = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['peds']; if($peds == "Y") { $this->minAge = 0; $this->maxAge = 17; } elseif($peds == "N") { $this->minAge = 18; $this->maxAge = 150; } elseif($peds == "Y,N") { $this->minAge = 0; $this->maxAge = 150; } $this->other_comments = $a['EDXLDistribution']['contentObject']['contentDescription']; $orgId = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['organization']['orgId']; $q = " SELECT * FROM hospital WHERE npi = '".mysql_real_escape_string((string)$orgId)."'; "; $result = $this->db->Execute($q); if($result === false) { daoErrorLog(__FILE__, __LINE__, __METHOD__, __CLASS__, __FUNCTION__, $this->db->ErrorMsg(), "person get hospital ((".$q."))"); } $this->hospital_uuid = $result->fields["hospital_uuid"]; $this->last_seen = $result->fields["name"]." Hospital"; $this->edxl->content_descr = $a['EDXLDistribution']['contentObject']['contentDescription']; $this->edxl->p_uuid = $this->p_uuid; $this->edxl->schema_version = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['version']; $this->edxl->login_machine = "n/a"; //null; HACK! cant be null $this->edxl->login_account = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['login']['username']; $this->edxl->person_id = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['personId']; $this->edxl->event_name = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['eventName']; $this->edxl->event_long_name = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['eventLongName']; $this->edxl->org_name = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['organization']['orgName']; $this->edxl->org_id = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['organization']['orgId']; $this->edxl->last_name = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['lastName']; $this->edxl->first_name = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['firstName']; $this->edxl->gender = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['gender']; $this->edxl->peds = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['peds']; $this->edxl->triage_category = $a['EDXLDistribution']['contentObject']['xmlContent']['embeddedXMLContent']['lpfContent']['person']['triageCategory']; $this->edxl->when_sent = $this->last_updated; $this->edxl->sender_id = $a['EDXLDistribution']['senderID']; $this->edxl->distr_id = $a['EDXLDistribution']['distributionID']; $this->edxl->distr_status = $a['EDXLDistribution']['distributionStatus']; $this->edxl->distr_type = $a['EDXLDistribution']['distributionType']; $this->edxl->combined_conf = $a['EDXLDistribution']['combinedConfidentiality']; $this->edxl->language = null; $this->edxl->when_here = $this->creation_time; $this->edxl->inbound = 1; //null; HACK! cant be null $this->edxl->type = "lpf"; $this->cleanInput(); // check if the event is closed to reporting... if(!$this->isEventOpen()) { return (int)405; } // exit with success return (int)0; // how did we get here? } else { return (int)9999; } }