/** * Tests whether XML Report element matches ORM objects provided for download * @test * @depends testReadDownloadXML * @param array $domnodes DOMNodeList Objects */ public function testCheckReportsXML(array $domnodes) { $d_reports = $domnodes[2]; // Ensure that the DOMNodeList Object is not empty $this->assertGreaterThan(0, $d_reports->length, 'Reports Element MUST exist.'); // Contents of <Reports> element $reports_element = $d_reports->item(0); /* Report Check */ // If we have no reports on this deployment if (count($this->incident) == 0) { // Ensure the customforms element has the following message $this->assertEquals('There are no reports on this deployment.', $d_reports->item(0)->nodeValue); } else { // Grab individual Report $incident = $this->incident[0]; // Grab contents of <report> element $report_element = $reports_element->getElementsByTagName('report'); // Test to see if the <report> element exists $this->assertGreaterThan(0, $report_element->length, 'Report element does not exist for deployment with reports'); /* Report Check */ // Test report id $id = $report_element->item(0)->getAttribute('id'); $this->assertEquals($incident->id, $id, 'Report id does not match/attribute does not exist'); // Test Report approval status $approved = $report_element->item(0)->getAttribute('approved'); $this->assertEquals($incident->incident_active, $approved, 'Report active status does not match/attribute does not exist'); // Test Report verified status $verified = $report_element->item(0)->getAttribute('verified'); $this->assertEquals($incident->incident_verified, $verified, 'Report verified status does not match/attribute does not exist'); // Test Report mode status $mode = $report_element->item(0)->getAttribute('mode'); $this->assertEquals($incident->incident_mode, $mode, 'Report mode does not match/attribute does not exist'); // Test Report form_name // Grab Default form object $default_form = ORM::factory('form', 1); $expected_form = $incident->form->loaded ? $incident->form->form_title : $default_form->form_title; $form_name = xml::get_node_text($report_element->item(0), 'form_name', FALSE); $this->assertEquals($expected_form, $form_name, 'Report form_name does not match/attribute does not exist'); // Test Report Title $title = xml::get_node_text($report_element->item(0), 'title'); $this->assertEquals($incident->incident_title, $title, 'Report title does not match/element does not exist'); // Test Report Date $date = xml::get_node_text($report_element->item(0), 'date'); $this->assertEquals($incident->incident_date, $date, 'Report date does not match/element does not exist'); // Test Report Dateadd $date_add = xml::get_node_text($report_element->item(0), 'dateadd'); $this->assertEquals($incident->incident_dateadd, $date_add, 'Report dateadd does not match/element does not exist'); // Test report description $description = xml::get_node_text($report_element->item(0), 'description'); // If download report description option is selected by user if (in_array(2, $this->post['data_include'])) { $this->assertEquals($incident->incident_description, $description, 'Report description does not match/element does not exist'); } else { $this->assertEquals(FALSE, $description, 'Report description element should not exist'); } /* Location Check */ $locations_element = $report_element->item(0)->getElementsByTagName('location'); $location = $incident->location; // Include location option has been selected if (in_array(1, $this->post['data_include'])) { // Make sure the <location> element exists $this->assertGreaterThan(0, $locations_element->length, 'Report location element SHOULD exist'); // Test location name $location_name = xml::get_node_text($locations_element->item(0), 'name'); $this->assertEquals($location->location_name, $location_name, 'Location name does not match/element does not exist'); // Test Latitude $latitude = xml::get_node_text($locations_element->item(0), 'latitude'); $this->assertEquals($location->latitude, $latitude, 'Latitude does not match/element does not exist'); // Test longitude $longitude = xml::get_node_text($locations_element->item(0), 'longitude'); $this->assertEquals($location->longitude, $longitude, 'Longitude does not match/element does not exist'); } else { $this->assertEquals(0, $locations_element->length, "Report location element should not exist"); } /* Media Check */ $incident_media = ORM::Factory('media')->where('media_type = 2 OR media_type = 4')->where('incident_id', $incident->id)->find_all(); $media_element = $report_element->item(0)->getElementsByTagName('media'); if (count($incident_media) > 0) { $media_count = count($incident_media); $media_index = rand(0, $media_count - 1); // Make sure the media element exists $this->assertGreaterThan(0, $media_element->length, 'The media element SHOULD exist'); // Grab contents of media <item> element $media_item = $media_element->item(0)->getElementsByTagName('item'); // Grab random individual media item $this_media = $incident_media[$media_index]; if ($this_media->media_type == 2 or $this_media->media_type == 4) { // Make sure the <item> element exists $this->assertEquals('item', $media_item->item($media_index)->tagName, 'The media item element SHOULD exist'); // Test Media Type $media_type = $media_item->item($media_index)->getAttribute('type'); $this->assertEquals($this_media->media_type, $media_type, 'Media type does not match/ attribute does not exist'); // Test media active $media_active = $media_item->item($media_index)->getAttribute('active'); $this->assertEquals($this_media->media_active, $media_active, 'Media active does not match/ attribute does not exist'); // Test Media date $media_date = xml::get_node_text($media_item->item($media_index), 'date', FALSE); $this->assertEquals($this_media->media_date, $media_date, 'Media date does not match/ attribute does not exist'); // Test media link $media_link = $media_item->item($media_index)->nodeValue; $this->assertEquals($this_media->media_link, $media_link, 'Media link does not match/ element does not exist'); } else { // Make sure the <item> element does NOT exists for this particular media item $this->assertNull($media_item->item($media_index), 'The media item element SHOULD NOT exist'); } } else { // Make sure the media element does NOT exist $this->assertEquals(0, $media_element->length, 'The media element should NOT exist'); } /* Personal info check */ $person_info_element = $report_element->item(0)->getElementsByTagName('personal_info'); $incident_person = $incident->incident_person; // Include personal info option selected? if (in_array(7, $this->post['data_include'])) { // If we actually have an incident_person for this report if ($incident_person->loaded) { // Make sure the <personalinfo> element exists $this->assertGreaterThan(0, $person_info_element->length, 'Report personal-info element SHOULD exist'); // Test First Name $firstname = xml::get_node_text($person_info_element->item(0), 'first_name'); $this->assertEquals($incident_person->person_first, $firstname, 'Person first name does not match/ element does not exist'); // Test last name $lastname = xml::get_node_text($person_info_element->item(0), 'last_name'); $this->assertEquals($incident_person->person_last, $lastname, 'Person last name does not match/ element does not exist'); // Test Email $email = xml::get_node_text($person_info_element->item(0), 'email'); $this->assertEquals($incident_person->person_email, $email, 'Person email does not match/ element does not exist'); } else { $this->assertEquals(0, $person_info_element->length, "Report personal-info element should not exist"); } } else { $this->assertEquals(0, $person_info_element->length, "Report personal-info element should not exist"); } /* Incident Category check */ $report_categories_element = $report_element->item(0)->getElementsByTagName('report_categories'); $incident_categories = $incident->incident_category; $incident_cat_count = count($incident_categories); $cat_index = rand(0, $incident_cat_count - 1); // Include categories option selected? if (in_array(3, $this->post['data_include'])) { // Make sure the <reportcategories> element exists $this->assertGreaterThan(0, $report_categories_element->length, "Report categories element should exist"); // Pick a random incident category $this_cat = $incident_categories[$cat_index]; $report_cat_element = $report_categories_element->item(0)->getElementsByTagName('category'); // Test incident_category title $incident_cat = $report_cat_element->item($cat_index)->nodeValue; $this->assertEquals($this_cat->category->category_title, $incident_cat, 'Incident_category does not match/element does not exist'); } else { $this->assertEquals(0, $report_cat_element->length, "Report categories element should not exist"); } /* Custom response check */ $custom_responses_element = $report_element->item(0)->getElementsByTagName('custom_fields'); $sql = "SELECT form_field.*, form_response.form_response\n\t\t\t\t\tFROM form_field\n\t\t\t\t\tLEFT JOIN roles ON (roles.id = field_ispublic_visible)\n\t\t\t\t\tLEFT JOIN\n\t\t\t\t\t\tform_response ON (\n\t\t\t\t\t\t\tform_response.form_field_id = form_field.id AND\n\t\t\t\t\t\t\tform_response.incident_id = :incident_id\n\t\t\t\t\t\t)\n\t\t\t\t\tWHERE form_id = :form_id " . "ORDER BY field_position ASC"; $customresponses = Database::instance()->query($sql, array(':form_id' => $incident->form_id, ':incident_id' => $incident->id)); // Grab response count $response_count = count($customresponses); // Include custom fields option selected? if (in_array(6, $this->post['data_include'])) { // If we have custom field responses for this incident if ($response_count > 0) { // Make sure the <customfields> element exists $this->assertGreaterThan(0, $custom_responses_element->length, "Report custom responses element should exist"); // Grab a random custom response by generating a random index to select based on field count $response_index = rand(0, $response_count - 1); $this_response = $customresponses[$response_index]; // Grab contents of <field> element $field_element = $custom_responses_element->item(0)->getElementsByTagName('field'); // Make sure a form_response has actually been provided if ($this_response->form_response != '') { // Make sure the <field> element exists $this->assertNotNull($field_element->item($response_index), 'Custom Field response element should exist'); // Test Field Name $field_name = xml::get_node_text($field_element->item($response_index), 'name', FALSE); $this->assertEquals($this_response->field_name, $field_name, 'Response field name does not match/attribute does not exist'); // Test Field Response $response = $field_element->item($response_index)->nodeValue; $this->assertEquals($this_response->form_response, $response, 'Custom response does not match/element does not exist'); } else { $this->assertNull($field_element->item($response_index), 'Custom Field response element should NOT exist'); } } else { $this->assertEquals(0, $custom_responses_element->length, 'Custom Field response element should NOT exist'); } } else { $this->assertEquals(0, $custom_responses_element->length, "Report custom responses element should not exist"); } } }
/** * Import Reports via XML * @param DOMNodeList Object $report * @return bool */ public function import_reports($reports) { /* Import individual reports */ foreach ($reports->getElementsByTagName('report') as $report) { $this->totalreports++; // Get Report id $report_id = $report->getAttribute('id'); // Check if this incident already exists in the db if (isset($report_id) and isset($this->incident_ids[$report_id])) { $this->notices[] = Kohana::lang('import.incident_exists') . $report_id; } else { /* Step 1: Location information */ $locations = $report->getElementsByTagName('location'); // If location information has been provided if ($locations->length > 0) { $report_location = $locations->item(0); // Location Name $location_name = xml::get_node_text($report_location, 'name'); // Longitude $longitude = xml::get_node_text($report_location, 'longitude'); // Latitude $latitude = xml::get_node_text($report_location, 'latitude'); if ($location_name) { // For geocoding purposes $location_geocoded = map::geocode($location_name); // Save the location $new_location = new Location_Model(); $new_location->location_name = $location_name ? $location_name : NULL; $new_location->location_date = $this->time; // If longitude/latitude values are present if ($latitude and $longitude) { $new_location->latitude = $latitude ? $latitude : 0; $new_location->longitude = $longitude ? $longitude : 0; } else { // Get geocoded lat/lon values $new_location->latitude = $location_geocoded ? $location_geocoded['latitude'] : $latitude; $new_location->longitude = $location_geocoded ? $location_geocoded['longitude'] : $longitude; } $new_location->country_id = $location_geocoded ? $location_geocoded['country_id'] : 0; $new_location->save(); // Add this location to array of imported locations $this->locations_added[] = $new_location->id; } } /* Step 2: Save Report */ // Report Title $report_title = xml::get_node_text($report, 'title'); // Report Date $report_date = xml::get_node_text($report, 'date'); // Missing report title or report date? if (!$report_title or !$report_date) { $this->errors[] = Kohana::lang('import.xml.incident_title_date') . $this->totalreports; } // If report date is not in the required format if (!strtotime($report_date)) { $this->errors[] = Kohana::lang('import.incident_date') . $this->totalreports . ': ' . html::escape($report_date); } else { // Approval status? $approved = $report->getAttribute('approved'); $report_approved = (isset($approved) and in_array($approved, $this->allowable)) ? $approved : 0; // Verified Status? $verified = $report->getAttribute('verified'); $report_verified = (isset($verified) and in_array($verified, $this->allowable)) ? $verified : 0; // Report mode? $allowed_modes = array(1, 2, 3, 4); $mode = $report->getAttribute('mode'); $report_mode = (isset($mode) and in_array($mode, $allowed_modes)) ? $mode : 1; // Report Form $report_form = xml::get_node_text($report, 'form_name', FALSE); if ($report_form) { if (!isset($this->existing_forms[utf8::strtoupper($report_form)])) { $this->notices[] = Kohana::lang('import.xml.no_form_exists') . $this->totalreports . ': "' . $report_form . '"'; } $form_id = isset($this->existing_forms[utf8::strtoupper($report_form)]) ? $this->existing_forms[utf8::strtoupper($report_form)] : 1; } // Report Date added $dateadd = xml::get_node_text($report, 'dateadd'); // Report Description $report_description = xml::get_node_text($report, 'description'); $new_report = new Incident_Model(); $new_report->location_id = isset($new_location) ? $new_location->id : 0; $new_report->user_id = 0; $new_report->incident_title = $report_title; $new_report->incident_description = $report_description ? $report_description : ''; $new_report->incident_date = date("Y-m-d H:i:s", strtotime($report_date)); $new_report->incident_dateadd = ($dateadd and strtotime($dateadd)) ? $dateadd : $this->time; $new_report->incident_active = $report_approved; $new_report->incident_verified = $report_verified; $new_report->incident_mode = $report_mode; $new_report->form_id = isset($form_id) ? $form_id : 1; $new_report->save(); // Increment imported rows counter $this->importedreports++; // Add this report to array of reports added during import $this->incidents_added[] = $new_report->id; /* Step 3: Save Report Categories*/ // Report Categories exist? $reportcategories = $report->getElementsByTagName('report_categories'); if ($reportcategories->length > 0) { $report_categories = $reportcategories->item(0); foreach ($report_categories->getElementsByTagName('category') as $r_category) { $category = trim($r_category->nodeValue); $report_category = (isset($category) and $category != '') ? $category : ''; if ($report_category != '' and isset($this->existing_categories[utf8::strtoupper($report_category)])) { // Save the incident category $new_incident_category = new Incident_Category_Model(); $new_incident_category->incident_id = $new_report->id; $new_incident_category->category_id = $this->existing_categories[utf8::strtoupper($report_category)]; $new_incident_category->save(); // Add this to array of incident categories added $this->incident_categories_added[] = $new_incident_category->id; } if ($report_category != '' and !isset($this->existing_categories[utf8::strtoupper($report_category)])) { $this->notices[] = Kohana::lang('import.xml.no_category_exists') . $this->totalreports . ': "' . $report_category . '"'; } } } /* Step 4: Save Custom form field responses for this report */ // Report Custom Fields $this_form = $new_report->form_id; $reportfields = $report->getElementsByTagName('custom_fields'); if ($reportfields->length > 0) { $report_fields = $reportfields->item(0); $custom_fields = $report_fields->getElementsByTagName('field'); if ($custom_fields->length > 0) { foreach ($custom_fields as $field) { // Field Name $field_name = $field->hasAttribute('name') ? xml::get_node_text($field, 'name', FALSE) : FALSE; if ($field_name) { // If this field exists in the form listed for this report if (isset($this->existing_fields[utf8::strtoupper($field_name)][$this_form])) { // Get field type and default values $match_field_id = $this->existing_fields[utf8::strtoupper($field_name)][$this_form]; // Grab form field object $match_fields = ORM::Factory('form_field', $match_field_id); $match_field_type = $match_fields->field_type; $match_field_defaults = $match_fields->field_default; // Grab form responses $field_response = trim($field->nodeValue); if ($field_response != '') { // Initialize form response model $new_form_response = new Form_Response_Model(); $new_form_response->incident_id = $new_report->id; $new_form_response->form_field_id = $match_field_id; // For radio buttons, checkbox fields and drop downs, make sure form responses are // within bounds of allowable options for that field // Split field defaults into individual values $field_defaults = explode(',', $match_field_defaults); /* Radio buttons and Drop down fields which take single responses */ if ($match_field_type == 5 or $match_field_type == 7) { foreach ($field_defaults as $match_field_default) { // Carry out a case insensitive string comparison $new_form_response->form_response = strcasecmp($match_field_default, $field_response) == 0 ? $match_field_default : NULL; } } // Checkboxes which if ($match_field_type == 6) { // Split user responses into individual value $responses = explode(',', $field_response); $values = array(); foreach ($match_field_defaults as $match_field_default) { foreach ($responses as $response) { $values[] = strcasecmp($match_field_default, $response) == 0 ? $match_field_default : NULL; } } // Concatenate checkbox values into a string, separated by a comma $new_form_response->form_response = implode(",", $values); } else { $new_form_response->form_response = $field_response; } // Only save if form response is not empty if ($new_form_response->form_response != NULL) { $new_form_response->save(); } // Add this to array of form responses added $this->incident_responses_added[] = $new_form_response->id; } } else { $this->notices[] = Kohana::lang('import.xml.form_field_no_match') . $this->totalreports . ': "' . $field_name . '" on form "' . $new_report->form->form_title . '"'; } } } } } /* Step 5: Save incident persons for this report */ // Report Personal Information $personal_info = $report->getElementsByTagName('personal_info'); // If personal info exists if ($personal_info->length > 0) { $report_info = $personal_info->item(0); // First Name $firstname = xml::get_node_text($report_info, 'first_name'); // Last Name $lastname = xml::get_node_text($report_info, 'last_name'); // Email $r_email = xml::get_node_text($report_info, 'email'); $email = ($r_email and valid::email($r_email)) ? $r_email : NULL; $new_incident_person = new Incident_Person_Model(); $new_incident_person->incident_id = $new_report->id; $new_incident_person->person_date = $new_report->incident_dateadd; // Make sure that at least one of the personal info field entries is provided if ($firstname or $lastname or $email != NULL) { $new_incident_person->person_first = $firstname ? $firstname : NULL; $new_incident_person->person_last = $lastname ? $firstname : NULL; $new_incident_person->person_email = $email; $new_incident_person->save(); // Add this to array of incident persons added during import $this->incident_persons_added[] = $new_incident_person->id; } } /* Step 6: Save media links for this report */ // Report Media $media = $report->getElementsByTagName('media'); if ($media->length > 0) { $media = $media->item(0); foreach ($media->getElementsByTagName('item') as $media_element) { $media_link = trim($media_element->nodeValue); $media_date = $media_element->getAttribute('date'); if (!empty($media_link)) { $media_item = new Media_Model(); $media_item->location_id = isset($new_location) ? $new_location->id : 0; $media_item->incident_id = $new_report->id; $media_item->media_type = $media_element->getAttribute('type'); $media_item->media_link = $media_link; $media_item->media_date = !empty($media_date) ? $media_date : $new_report->incident_date; $media_item->save(); } } } } } } // end individual report import // If we have errors, return FALSE, else TRUE return count($this->errors) === 0; }