/** * Tests customforms::validate_custom_form_fields() * * @dataProvider providerTestValidateCustomFormFields */ public function testValidateCustomFormFields($valid_data, $invalid_data) { // Setup validation objects for the valid custom forms data $valid_validator = Validation::factory($valid_data)->pre_filter('trim', TRUE); // Get the return value for validation of valid date $errors = customforms::validate_custom_form_fields($valid_validator); // Assert that validation of the valid data returns no errors $this->assertEquals(0, count($errors), "Some errors have been found" . Kohana::debug($errors)); // Set up validation for the invalid custom forms data $invalid_validator = Validation::factory($invalid_data)->pre_filter('trim', TRUE); // Get the return value for validation of invalid data $errors = customforms::validate_custom_form_fields($invalid_validator); // Assert that the validation of the invalid data returns some errors $this->assertEquals(TRUE, count($errors) > 0, "Expected to encounter errors. None found: " . count($errors)); // Garbage collection unset($valid_validator, $invalid_validator, $errors); }
/** * Ajax call to update Incident Reporting Form * JP: added custom advanced settings data to JSON */ public function switch_form() { $this->template = ""; $this->auto_render = FALSE; isset($_POST['form_id']) ? $form_id = $_POST['form_id'] : ($form_id = "1"); isset($_POST['incident_id']) ? $incident_id = $_POST['incident_id'] : ($incident_id = ""); $form_data = array(); $selected_form = customforms::get_custom_form($form_id); $form_data['report_title_name'] = $selected_form->report_title_name; $form_data['description_name'] = $selected_form->description_name; $form_data['description_active'] = $selected_form->description_active; $form_data['fields'] = customforms::switcheroo($incident_id, $form_id); echo json_encode(array("status" => "success", "response" => $form_data)); }
/** * Test CSV Download * @test */ public function testDownloadCSV() { // Test to ensure validation passed $this->assertEquals(TRUE, download::validate($this->post), 'Report download validation failed'); // If we have no reports if (count($this->incident) == 0) { $this->markTestSkipped('There are no reports, CSV Download test skipped'); } $expected_csv_content = "\"#\",\"FORM #\",\"INCIDENT TITLE\",\"INCIDENT DATE\""; // Include location information? if (in_array(1, $this->post['data_include'])) { $expected_csv_content .= ",\"LOCATION\""; } // Include description information? if (in_array(2, $this->post['data_include'])) { $expected_csv_content .= ",\"DESCRIPTION\""; } // Include category information? if (in_array(3, $this->post['data_include'])) { $expected_csv_content .= ",\"CATEGORY\""; } // Include latitude information? if (in_array(4, $this->post['data_include'])) { $expected_csv_content .= ",\"LATITUDE\""; } // Include longitude information? if (in_array(5, $this->post['data_include'])) { $expected_csv_content .= ",\"LONGITUDE\""; } // Include custom forms information? if (in_array(6, $this->post['data_include'])) { foreach ($this->custom_forms as $field_name) { $expected_csv_content .= ",\"" . $field_name['field_name'] . "-" . $field_name['form_id'] . "\""; } } // Include personal information? if (in_array(7, $this->post['data_include'])) { $expected_csv_content .= ",\"FIRST NAME\",\"LAST NAME\",\"EMAIL\""; } $expected_csv_content .= ",\"APPROVED\",\"VERIFIED\""; $expected_csv_content .= "\r\n"; // Add Report information $report = $this->incident[0]; // Report id, form_id, title, and date $expected_csv_content .= '"' . $report->id . '",' . '"' . $report->form_id . '",' . '"' . $report->incident_title . '",' . '"' . $report->incident_date . '"'; // Include location information? if (in_array(1, $this->post['data_include'])) { $expected_csv_content .= ',"' . $report->location->location_name . '"'; } // Include description information? if (in_array(2, $this->post['data_include'])) { $expected_csv_content .= ',"' . $report->incident_description . '"'; } // Include category information? if (in_array(3, $this->post['data_include'])) { $cat = array(); foreach ($report->incident_category as $category) { if ($category->category->category_title) { $cat[] = $category->category->category_title; } } $expected_csv_content .= ',"' . implode($cat, ',') . '"'; } // Include latitude information? if (in_array(4, $this->post['data_include'])) { $expected_csv_content .= ',"' . $report->location->latitude . '"'; } // Include longitude information? if (in_array(5, $this->post['data_include'])) { $expected_csv_content .= ',"' . $report->location->longitude . '"'; } // Include custom forms information? if (in_array(6, $this->post['data_include'])) { $custom_fields = customforms::get_custom_form_fields($report->id, '', false); if (!empty($custom_fields)) { foreach ($custom_fields as $custom_field) { $expected_csv_content .= ',"' . $custom_field['field_response'] . '"'; } } else { foreach ($this->custom_forms as $custom) { $expected_csv_content .= ',""'; } } } // Include personal information? if (in_array(7, $this->post['data_include'])) { $person = $report->incident_person; if ($person->loaded) { $expected_csv_content .= ',"' . $person->person_first . '"' . ',"' . $person->person_last . '"' . ',"' . $person->person_email . '"'; } else { $expected_csv_content .= ',""' . ',""' . ',""'; } } // Approved status if ($report->incident_active) { $expected_csv_content .= ",\"YES\""; } else { $expected_csv_content .= ",\"NO\""; } // Verified Status if ($report->incident_verified) { $expected_csv_content .= ",\"YES\""; } else { $expected_csv_content .= ",\"NO\""; } // End Expected output $expected_csv_content .= "\r\n"; // Grab actual output $actual_csv_content = download::download_csv($this->post, $this->incident, $this->custom_forms); // Test CSV Output $this->assertEquals($expected_csv_content, $actual_csv_content, 'CSV Download failed. Content mismatch'); }
private function add_data_to_incident($incident_array, $incident) { /*static $incident_type; if (!$incident_type) { $incident_type = ORM::factory('service')->select_list('id','service_name'); } if ($incident_array['incident_id']) { $incident_array['incident_id'] = array($incident_array['incident_id'] => array( 'api_url' => url::site(rest_controller::$api_base_url.'/incidents/'.$incident_array['incident_id']), 'url' => url::site('/reports/view/'.$incident_array['incident_id']) )); }*/ // Add categories $incident_array['category'] = array(); foreach ($incident->category as $category) { // Only include visible categories unless we're an admin if ($this->admin or $category->category_visible) { $category_data = $category->as_array(); $category_data['category_image'] = $category_data['category_image'] ? url::convert_uploaded_to_abs($category_data['category_image']) : $category_data['category_image']; $category_data['category_image_thumb'] = $category_data['category_image_thumb'] ? url::convert_uploaded_to_abs($category_data['category_image_thumb']) : $category_data['category_image_thumb']; $category_data['api_url'] = url::site(rest_controller::$api_base_url . '/categories/' . $category_data['id']); $incident_array['category'][] = $category_data; } } // Add location // @todo filter on location_visible $incident_array['location'] = $incident->location->as_array(); // format date in ISO standard $incident_array['location']['location_date'] = $incident_array['location']['location_date'] != null ? date('c', strtotime($incident_array['location']['location_date'])) : null; // Add incident_person if ($this->admin) { $incident_array['incident_person'] = $incident->incident_person->as_array(); //@todo sanitize // format date in ISO standard $incident_array['incident_person']['person_date'] = $incident_array['incident_person']['person_date'] != null ? date('c', strtotime($incident_array['incident_person']['person_date'])) : null; } else { // @todo check what should be public $incident_array['incident_person'] = array('id' => $incident->incident_person->id, 'person_first' => $incident->incident_person->person_first, 'person_last' => $incident->incident_person->person_last); } // Add user? if ($this->admin) { $incident_array['user'] = $incident->user->as_array(); //@todo sanitize unset($incident_array['user']['password']); unset($incident_array['user']['code']); // format date in ISO standard $incident_array['user']['updated'] = $incident_array['user']['updated'] != null ? date('c', strtotime($incident_array['user']['updated'])) : null; } else { // @todo check what should be public $incident_array['user'] = array('id' => $incident->user->id, 'name' => $incident->user->name, 'username' => $incident->user->username); } // Add media? $incident_array['media'] = array(); foreach ($incident->media as $media) { // Only include visible categories unless we're an admin if ($this->admin or $media->media_active) { $media_data = $media->as_array(); if ($media->media_link and !valid::url($media->media_link)) { $media_data['media_link'] = url::convert_uploaded_to_abs($media_data['media_link']); $media_data['media_medium'] = url::convert_uploaded_to_abs($media_data['media_medium']); $media_data['media_thumb'] = url::convert_uploaded_to_abs($media_data['media_thumb']); } // format date in ISO standard $media_data['media_date'] = $media_data['media_date'] != null ? date('c', strtotime($media_data['media_date'])) : null; $incident_array['media'][] = $media_data; } } // Initialize custom field array - only supporting default form $incident_array['custom_field'] = customforms::get_custom_form_fields($incident_array['id'], 1, true); $incident_array['api_url'] = url::site(rest_controller::$api_base_url . '/incidents/' . $incident_array['id']); $incident_array['updated_at'] = $incident->incident_datemodify == null ? $incident->incident_dateadd : $incident->incident_datemodify; $incident_array['updated_at'] = date_create($incident_array['updated_at'])->format(DateTime::W3C); // format all dates in ISO standard $incident_array['incident_datemodify'] = $incident->incident_datemodify != null ? date_create($incident_array['incident_datemodify'])->format(DateTime::W3C) : null; $incident_array['incident_dateadd'] = $incident->incident_dateadd != null ? date_create($incident_array['incident_dateadd'])->format(DateTime::W3C) : null; $incident_array['incident_date'] = $incident->incident_date != null ? date_create($incident_array['incident_date'])->format(DateTime::W3C) : null; return $incident_array; }
/** * Download Reports in XML format * @param Validation $post Validation object with the download criteria * @param array $incidents reports to be downloaded * @param array $categories deployment categories * @param array $custom_forms Custom form field structure and values */ public static function download_xml($post, $incidents, $categories, $custom_forms) { // Adding XML Content $writer = new XMLWriter(); $writer->openMemory(); $writer->startDocument('1.0', 'UTF-8'); $writer->setIndent(TRUE); /* Category Element/Attribute maps */ // Category map $category_map = array('attributes' => array('color' => 'category_color', 'visible' => 'category_visible', 'trusted' => 'category_trusted'), 'elements' => array('title' => 'category_title', 'description' => 'category_description')); // Array of category elements $category_elements = array('color', 'visible', 'trusted', 'title', 'description', 'parent'); /* Category translation Element/Attribute maps */ // Translation map $translation_map = array('attributes' => array('locale' => 'locale'), 'elements' => array('translation_title' => 'category_title', 'translation_description' => 'category_description')); // Array of translation elements $translation_elements = array('locale', 'translation_title', 'translation_description'); /* Form element/attribute maps */ // Forms map $form_map = array('attributes' => array('active' => 'form_active'), 'elements' => array('title' => 'form_title', 'description' => 'form_description')); // Forms element $form_elements = array('active', 'title', 'description'); /* Custom fields element/attribute maps */ // Field elements $form_field_elements = array('type', 'required', 'visible_by', 'submit_by', 'datatype', 'hidden', 'name', 'default'); /* Reports element/attribute maps */ // Report map $report_map = array('attributes' => array('id' => 'id', 'approved' => 'incident_active', 'verified' => 'incident_verified', 'mode' => 'incident_mode'), 'elements' => array('title' => 'incident_title', 'date' => 'incident_date', 'dateadd' => 'incident_dateadd')); // Report elements $report_elements = array('id', 'approved', 'verified', 'form_name', 'mode', 'title', 'date', 'dateadd'); // Location Map $location_map = array('attributes' => array(), 'elements' => array('name' => 'location_name', 'longitude' => 'longitude', 'latitude' => 'latitude')); // Location elements $location_elements = array('name', 'longitude', 'latitude'); // Media Map $media_map = array('attributes' => array('type' => 'media_type', 'active' => 'media_active', 'date' => 'media_date'), 'elements' => array()); // Media elements $media_elements = array('type', 'active', 'date'); // Personal info map $person_map = array('attributes' => array(), 'elements' => array('first_name' => 'person_first', 'last_name' => 'person_last', 'email' => 'person_email')); // Personal info elements $person_elements = array('first_name', 'last_name', 'email'); // Incident Category map $incident_category_map = array('attributes' => array(), 'elements' => array('category' => 'category_title')); // Incident Category elements $incident_category_elements = array('category'); // Ensure column order is always the same sort($post->data_include); /* Start Import Tag*/ $writer->startElement('UshahidiReports'); foreach ($post->data_include as $item) { switch ($item) { case 3: /* Start Categories element */ $writer->startElement('categories'); if (count($categories) > 0) { foreach ($categories as $category) { // Begin individual category tag $writer->startElement('category'); // Generate category element map $category_element_map = xml::generate_element_attribute_map($category, $category_map); if ($category->parent_id > 0) { // Category's parent $parent = ORM::factory('category', $category->parent_id); // If parent category exists if ($parent->loaded) { // Add to array of category_element_map for purposes of generating tags $category_element_map['elements']['parent'] = $parent->category_title; } } // Generate individual category tags xml::generate_tags($writer, $category_element_map, $category_elements); // Category Translation $translations = ORM::factory('category_lang')->where('category_id', $category->id)->find_all(); // If translations exist if (count($translations) > 0) { $writer->startElement('translations'); foreach ($translations as $translation) { // Begin individual translation element $writer->startElement('translation'); // Generate translation element map $translation_element_map = xml::generate_element_attribute_map($translation, $translation_map); // Generate translation tags xml::generate_tags($writer, $translation_element_map, $translation_elements); // End individual category translation tag $writer->endElement(); } $writer->endElement(); } $writer->endElement(); } } else { $writer->text('There are no categories on this deployment.'); } /* Close Categories Element */ $writer->endElement(); break; case 6: /* Start Customforms Element */ $writer->startElement('custom_forms'); // If we have custom forms if (count($custom_forms) > 0) { foreach ($custom_forms as $form) { // Custom Form element $writer->startElement('form'); // Generate form elements map $form_element_map = xml::generate_element_attribute_map($form, $form_map); // Generate form element tags xml::generate_tags($writer, $form_element_map, $form_elements); // Get custom fields associated with this form $form_fields = customforms::get_custom_form_fields(FALSE, $form->id, FALSE); foreach ($form_fields as $field) { // Make sure this custom form field belongs to the current form if ($field['form_id'] == $form->id) { // Custom Form Fields $writer->startElement('field'); $form_field_map = array('attributes' => array('type' => $field['field_type'], 'required' => $field['field_required'], 'visible_by' => $field['field_ispublic_visible'], 'submit_by' => $field['field_ispublic_submit']), 'elements' => array()); /* Get custom form field options */ $options = ORM::factory('form_field_option')->where('form_field_id', $field['field_id'])->find_all(); foreach ($options as $option) { if ($option->option_name == 'field_datatype') { // Data type i.e Free, Numeric, Email, Phone? $form_field_map['attributes']['datatype'] = $option->option_value; } if ($option->option_name == 'field_hidden') { // Hidden Field? $form_field_map['attributes']['hidden'] = $option->option_value; } } // Field name $form_field_map['elements']['name'] = $field['field_name']; // Default Value if ($field['field_default'] != '') { $form_field_map['elements']['default'] = $field['field_default']; } // Generate custom fields tags xml::generate_tags($writer, $form_field_map, $form_field_elements); // Close Custom form field element $writer->endElement(); } } // Close Custom Form Element $writer->endElement(); } } else { $writer->text('There are no custom forms on this deployment.'); } /* End Custom Forms Element */ $writer->endElement(); break; } } /* Start Reports Element*/ $writer->startElement('reports'); // If we have reports on this deployment if (count($incidents) > 0) { foreach ($incidents as $incident) { // Start Individual report $writer->startElement('report'); // Generate report map $report_element_map = xml::generate_element_attribute_map($incident, $report_map); // Grab Default form title $default_form = ORM::factory('form', 1); // Form this incident belongs to? $form_name = $incident->form->loaded ? $incident->form->form_title : $default_form->form_title; // Add it to report element map $report_element_map['attributes']['form_name'] = $form_name; // Generate report tags xml::generate_tags($writer, $report_element_map, $report_elements); foreach ($post->data_include as $item) { switch ($item) { // Report Description case 2: $writer->startElement('description'); $writer->text($incident->incident_description); $writer->endElement(); break; // Report Location // Report Location case 1: $writer->startElement('location'); // Generate location map $location_map_element = xml::generate_element_attribute_map($incident->location, $location_map); // Generate location tags xml::generate_tags($writer, $location_map_element, $location_elements); // Close location tag $writer->endElement(); break; case 7: // Report Personal information $incident_person = $incident->incident_person; if ($incident_person->loaded) { $writer->startElement('personal_info'); // Generate incident person element map $person_element_map = xml::generate_element_attribute_map($incident_person, $person_map); // Generate incident person element tags xml::generate_tags($writer, $person_element_map, $person_elements); // Close personal info tag $writer->endElement(); } break; case 3: // Report Category $writer->startElement('report_categories'); foreach ($incident->incident_category as $category) { // Generate Incident Category Element Map $incident_category_element_map = xml::generate_element_attribute_map($category->category, $incident_category_map); // Generate Incident Category Tags xml::generate_tags($writer, $incident_category_element_map, $incident_category_elements); } $writer->endElement(); break; case 6: // Report Fields $customresponses = customforms::get_custom_form_fields($incident->id, $incident->form_id, FALSE); if (!empty($customresponses)) { $writer->startElement('custom_fields'); foreach ($customresponses as $customresponse) { // If we don't have an empty form response if ($customresponse['field_response'] != '') { $writer->startElement('field'); $writer->startAttribute('name'); $writer->text($customresponse['field_name']); $writer->endAttribute(); $writer->text($customresponse['field_response']); $writer->endElement(); } } $writer->endElement(); } break; } } // Report Media $reportmedia = $incident->media; if (count($reportmedia) > 0) { $writer->startElement('media'); foreach ($reportmedia as $media) { // Videos and news links only if ($media->media_type == 2 or $media->media_type == 4) { $writer->startElement('item'); // Generate media elements map $media_element_map = xml::generate_element_attribute_map($media, $media_map); // Generate media elements xml::generate_tags($writer, $media_element_map, $media_elements); $writer->endAttribute(); $writer->text($media->media_link); // Close item tag $writer->endElement(); } } $writer->endElement(); } // Close individual report $writer->endElement(); } } else { $writer->text('There are no reports on this deployment.'); } /* Close reports Element */ $writer->endElement(); /* Close import tag */ $writer->endElement(); // Close the document $writer->endDocument(); // Print return $writer->outputMemory(TRUE); }
/** * Ajax call to update Incident Reporting Form */ public function switch_form() { $this->template = ""; $this->auto_render = FALSE; isset($_POST['form_id']) ? $form_id = $_POST['form_id'] : ($form_id = "1"); isset($_POST['incident_id']) ? $incident_id = $_POST['incident_id'] : ($incident_id = ""); $form_fields = customforms::switcheroo($incident_id, $form_id); echo json_encode(array("status" => "success", "response" => $form_fields)); }
/** * Download Reports in CSV format */ public function download() { // If user doesn't have access, redirect to dashboard if (!$this->auth->has_permission("reports_download")) { url::redirect(url::site() . 'admin/dashboard'); } $this->template->content = new View('admin/reports/download'); $this->template->content->title = Kohana::lang('ui_admin.download_reports'); $errors = $form = array('format' => '', 'data_active' => array(), 'data_verified' => array(), 'data_include' => array(), 'from_date' => '', 'to_date' => '', 'form_auth_token' => ''); // Default to all selected $form['data_active'] = array(0, 1); $form['data_verified'] = array(0, 1); $form['data_include'] = array(1, 2, 3, 4, 5, 6, 7); $form_error = FALSE; // Check, has the form been submitted, if so, setup validation if ($_POST) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = array_merge($_POST, $_FILES); // Test to see if things passed the rule checks if (download::validate($post)) { // Set filter $filter = '( '; // Report Type Filter $show_active = FALSE; $show_inactive = FALSE; $show_verified = FALSE; $show_not_verified = FALSE; if (in_array(1, $post->data_active)) { $show_active = TRUE; } if (in_array(0, $post->data_active)) { $show_inactive = TRUE; } if (in_array(1, $post->data_verified)) { $show_verified = TRUE; } if (in_array(0, $post->data_verified)) { $show_not_verified = TRUE; } // Handle active or not active if ($show_active && !$show_inactive) { $filter .= ' incident_active = 1 '; } elseif (!$show_active && $show_inactive) { $filter .= ' incident_active = 0 '; } elseif ($show_active && $show_inactive) { $filter .= ' (incident_active = 1 OR incident_active = 0) '; } elseif (!$show_active && !$show_inactive) { // Equivalent to 1 = 0 $filter .= ' (incident_active = 0 AND incident_active = 1) '; } $filter .= ' AND '; // Handle verified if ($show_verified && !$show_not_verified) { $filter .= ' incident_verified = 1 '; } elseif (!$show_verified && $show_not_verified) { $filter .= ' incident_verified = 0 '; } elseif ($show_verified && $show_not_verified) { $filter .= ' (incident_verified = 0 OR incident_verified = 1) '; } elseif (!$show_verified && !$show_not_verified) { $filter .= ' (incident_verified = 0 AND incident_verified = 1) '; } $filter .= ') '; // Report Date Filter if (!empty($post->from_date)) { $filter .= " AND incident_date >= '" . date("Y-m-d H:i:s", strtotime($post->from_date)) . "' "; } if (!empty($post->to_date)) { $filter .= " AND incident_date <= '" . date("Y-m-d H:i:s", strtotime($post->to_date)) . "' "; } // Retrieve reports $incidents = ORM::factory('incident')->where($filter)->orderby('incident_dateadd', 'desc')->find_all(); // Retrieve categories $categories = Category_Model::get_categories(FALSE, FALSE, FALSE); // Retrieve Forms $forms = ORM::Factory('form')->find_all(); // Retrieve Custom forms $custom_forms = customforms::get_custom_form_fields(); // If CSV format is selected if ($post->format == 'csv') { $report_csv = download::download_csv($post, $incidents, $custom_forms); // Output to browser header("Content-type: text/x-csv"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Disposition: attachment; filename=" . time() . ".csv"); header("Content-Length: " . strlen($report_csv)); echo $report_csv; exit; } // If XML format is selected if ($post->format == 'xml') { header('Content-type: text/xml; charset=UTF-8'); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Disposition: attachment; filename=" . time() . ".xml"); $content = download::download_xml($post, $incidents, $categories, $forms); echo $content; exit; } } else { // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::merge($errors, $post->errors('report')); $form_error = TRUE; } } $this->template->content->form = $form; $this->template->content->errors = $errors; $this->template->content->form_error = $form_error; // Javascript Header $this->themes->js = new View('admin/reports/download_js'); $this->themes->js->calendar_img = url::base() . "media/img/icon-calendar.gif"; }
/** * Validation of form fields * * @param array $post Values to be validated * @param bool $admin_section Whether the validation is for the admin section */ public static function validate(array &$post, $admin_section = FALSE) { // Exception handling if (!isset($post) or !is_array($post)) { return FALSE; } // Create validation object $post = Validation::factory($post)->pre_filter('trim', TRUE); $post->add_rules('incident_title', 'required', 'length[3,200]'); $post->add_rules('incident_description', 'required'); $post->add_rules('incident_date', 'required', 'date_mmddyyyy'); $post->add_rules('incident_hour', 'required', 'between[1,12]'); $post->add_rules('incident_minute', 'required', 'between[0,59]'); if ($post->incident_ampm != "am" and $post->incident_ampm != "pm") { $post->add_error('incident_ampm', 'values'); } // Validate for maximum and minimum latitude values $post->add_rules('latitude', 'required', 'between[-90,90]'); // Validate for maximum and minimum longitude values $post->add_rules('longitude', 'required', 'between[-180,180]'); $post->add_rules('location_name', 'required', 'length[3,200]'); //XXX: Hack to validate for no checkboxes checked if (!isset($post->incident_category)) { $post->incident_category = ""; $post->add_error('incident_category', 'required'); } else { $post->add_rules('incident_category.*', 'required', 'numeric'); } // Validate only the fields that are filled in if (!empty($post->incident_news)) { foreach ($post->incident_news as $key => $url) { if (!empty($url) and !(bool) filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)) { $post->add_error('incident_news', 'url'); } } } // Validate only the fields that are filled in if (!empty($post->incident_video)) { foreach ($post->incident_video as $key => $url) { if (!empty($url) and !(bool) filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)) { $post->add_error('incident_video', 'url'); } } } // If deployment is a single country deployment, check that the location mapped is in the default country if (!Kohana::config('settings.multi_country')) { $country = Country_Model::get_country_by_name($post->country_name); if ($country and $country->id != Kohana::config('settings.default_country')) { $post->add_error('country_name', 'single_country'); } } // Validate photo uploads $post->add_rules('incident_photo', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[2M]'); // Validate Personal Information if (!empty($post->person_first)) { $post->add_rules('person_first', 'length[3,100]'); } if (!empty($post->person_last)) { $post->add_rules('person_last', 'length[2,100]'); } if (!empty($post->person_email)) { $post->add_rules('person_email', 'email', 'length[3,100]'); } // Extra validation rules for the admin section if ($admin_section) { $post->add_rules('location_id', 'numeric'); $post->add_rules('message_id', 'numeric'); $post->add_rules('incident_active', 'required', 'between[0,1]'); $post->add_rules('incident_verified', 'required', 'between[0,1]'); $post->add_rules('incident_zoom', 'numeric'); } // Custom form fields validation $errors = customforms::validate_custom_form_fields($post); // Check if any errors have been returned if (count($errors) > 0) { foreach ($errors as $field_name => $error) { $post->add_error($field_name, $error); } } //> END custom form fields validation // Return return $post->validate(); }
/** * JP: Download Reports in HTML format * @param Validation $post Validation object with the download criteria * @param array $incidents Reports to be downloaded * @param array $custom_forms Custom form field structure and values * @return string HTML content */ public static function download_html($post, $incidents, $custom_forms) { $h = array(); $h[] = '<!DOCTYPE html>'; $h[] = ' <head>'; $h[] = ' <title>'; $h[] = ' Downloaded Reports'; $h[] = ' </title>'; $h[] = ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'; $h[] = ' <style>'; $h[] = ' table { border-collapse: collapse; }'; $h[] = ' table thead tr { background: #CCCCCC; }'; $h[] = ' table thead tr th, table tbody tr td { padding: 0.75em; border: 1px solid #AAAAAA; }'; $h[] = ' table tbody tr.even, table tbody tr.alt, table tbody tr:nth-of-type(even) { background: #DDDDDD; }'; $h[] = ' </style>'; $h[] = ' </head>'; $h[] = ' <body>'; $h[] = ' <table>'; $h[] = ' <thead>'; $h[] = ' <tr>'; $table_headers = array("#", "FORM #", "TITLE", "DATE"); $item_map = array(1 => 'LOCATION', 2 => 'DESCRIPTION', 3 => 'CATEGORY', 4 => 'LATITUDE', 5 => 'LONGITUDE', 7 => array('FIRST NAME', 'LAST NAME', 'EMAIL')); // Ensure column order is always the same sort($post->data_include); foreach ($post->data_include as $item) { if ((int) $item == 6) { foreach ($custom_forms as $field_name) { $table_headers[] = $field_name['field_name'] . "-" . $field_name['form_id']; } } elseif (is_array($item_map[$item])) { foreach ($item_map[$item] as $i) { $table_headers[] = $i; } } elseif (array_key_exists($item, $item_map)) { $table_headers[] = $item_map[$item]; } } $table_headers[] = 'APPROVED'; $table_headers[] = 'VERIFIED'; // Incase a plugin would like to add some custom fields Event::run('ushahidi_filter.report_download_table_header', $html_headers); foreach ($table_headers as $header) { $h[] = ' <th>'; $h[] = ' ' . $header; $h[] = ' </th>'; } $h[] = ' </tr>'; $h[] = ' </thead>'; $h[] = ' <tbody>'; foreach ($incidents as $incident) { $table_data = array(); $table_data[] = $incident->id; $table_data[] = $incident->form_id; $table_data[] = $incident->incident_title; $table_data[] = $incident->incident_date; foreach ($post->data_include as $item) { switch ($item) { case 1: $table_data[] = $incident->location->location_name; break; case 2: $table_data[] = $incident->incident_description; break; case 3: $cat_titles = array(); foreach ($incident->incident_category as $category) { if ($category->category->category_title) { $cat_titles[] = $category->category->category_title; } } $table_data[] = implode(', ', $cat_titles); break; case 4: $table_data[] = $incident->location->latitude; break; case 5: $table_data[] = $incident->location->longitude; break; case 6: $incident_id = $incident->id; $custom_fields = customforms::get_custom_form_fields($incident_id, NULL, FALSE); if (!empty($custom_fields)) { foreach ($custom_fields as $custom_field) { $table_data[] = $custom_field['field_response']; } } else { foreach ($custom_forms as $custom) { $table_data[] = ''; } } break; case 7: $incident_person = $incident->incident_person; if ($incident_person->loaded) { $table_data[] = $incident_person->person_first; $table_data[] = $incident_person->person_last; $table_data[] = $incident_person->person_email; } else { $table_data[] = ''; $table_data[] = ''; $table_data[] = ''; } break; } } $table_data[] = $incident->incident_active ? 'YES' : 'NO'; $table_data[] = $incident->incident_verified ? 'YES' : 'NO'; // Incase a plugin would like to add some custom data for an incident $event_data = array("table_data" => $table_data, "incident" => $incident); Event::run('ushahidi_filter.report_download_html_incident', $event_data); $table_data = $event_data['table_data']; $h[] = ' <tr>'; foreach ($table_data as $data) { $h[] = ' <td>'; $h[] = ' ' . $data; $h[] = ' </td>'; } $h[] = ' </tr>'; } $h[] = ' </tbody>'; $h[] = ' </table>'; $h[] = ' </body>'; $h[] = '</html>'; return implode("\n", $h); }
/** * Function to import a report form a row in the CSV file * @param array $row * @return bool */ function import_report($row) { // If the date is not in proper date format if (!strtotime($row['INCIDENT DATE'])) { $this->errors[] = Kohana::lang('import.incident_date') . ($this->rownumber + 1) . ': ' . $row['INCIDENT DATE']; } // If a value of Yes or No is NOT set for approval status for the imported row if (isset($row["APPROVED"]) and !in_array(utf8::strtoupper($row["APPROVED"]), array('NO', 'YES'))) { $this->errors[] = Kohana::lang('import.csv.approved') . ($this->rownumber + 1); } // If a value of Yes or No is NOT set for verified status for the imported row if (isset($row["VERIFIED"]) and !in_array(utf8::strtoupper($row["VERIFIED"]), array('NO', 'YES'))) { $this->errors[] = Kohana::lang('import.csv.verified') . ($this->rownumber + 1); } if (count($this->errors)) { return false; } // STEP 1: SAVE LOCATION if (isset($row['LOCATION'])) { $location = new Location_Model(); $location->location_name = isset($row['LOCATION']) ? $row['LOCATION'] : ''; // For Geocoding purposes $location_geocoded = map::geocode($location->location_name); // If we have LATITUDE and LONGITUDE use those if (isset($row['LATITUDE']) and isset($row['LONGITUDE'])) { $location->latitude = isset($row['LATITUDE']) ? $row['LATITUDE'] : 0; $location->longitude = isset($row['LONGITUDE']) ? $row['LONGITUDE'] : 0; } else { $location->latitude = $location_geocoded ? $location_geocoded['latitude'] : 0; $location->longitude = $location_geocoded ? $location_geocoded['longitude'] : 0; } $location->country_id = $location_geocoded ? $location_geocoded['country_id'] : 0; $location->location_date = $this->time; $location->save(); $this->locations_added[] = $location->id; } // STEP 2: SAVE INCIDENT $incident = new Incident_Model(); $incident->location_id = isset($row['LOCATION']) ? $location->id : 0; $incident->user_id = 0; $incident->form_id = (isset($row['FORM #']) and Form_Model::is_valid_form($row['FORM #'])) ? $row['FORM #'] : 1; $incident->incident_title = $row['INCIDENT TITLE']; $incident->incident_description = isset($row['DESCRIPTION']) ? $row['DESCRIPTION'] : ''; $incident->incident_date = date("Y-m-d H:i:s", strtotime($row['INCIDENT DATE'])); $incident->incident_dateadd = $this->time; $incident->incident_active = (isset($row['APPROVED']) and utf8::strtoupper($row['APPROVED']) == 'YES') ? 1 : 0; $incident->incident_verified = (isset($row['VERIFIED']) and utf8::strtoupper($row['VERIFIED']) == 'YES') ? 1 : 0; $incident->save(); $this->incidents_added[] = $incident->id; // STEP 3: Save Personal Information if (isset($row['FIRST NAME']) or isset($row['LAST NAME']) or isset($row['EMAIL'])) { $person = new Incident_Person_Model(); $person->incident_id = $incident->id; $person->person_first = isset($row['FIRST NAME']) ? $row['FIRST NAME'] : ''; $person->person_last = isset($row['LAST NAME']) ? $row['LAST NAME'] : ''; $person->person_email = (isset($row['EMAIL']) and valid::email($row['EMAIL'])) ? $row['EMAIL'] : ''; $person->person_date = date("Y-m-d H:i:s", time()); // Make sure that you're not importing an empty record i.e at least one field has been recorded // If all fields are empty i.e you have an empty record, don't save if (!empty($person->person_first) or !empty($person->person_last) or !empty($person->person_email)) { $person->save(); // Add to array of incident persons added $this->incident_persons_added[] = $person->id; } } // STEP 4: SAVE CATEGORIES // If CATEGORY column exists if (isset($row['CATEGORY'])) { $categorynames = explode(',', trim($row['CATEGORY'])); // Trim whitespace from array values $categorynames = array_map('trim', $categorynames); // Get rid of duplicate category entries in a row $categories = array_unique(array_map('strtolower', $categorynames)); // Add categories to incident foreach ($categories as $categoryname) { // Convert the first string character of the category name to Uppercase $categoryname = utf8::ucfirst($categoryname); // For purposes of adding an entry into the incident_category table $incident_category = new Incident_Category_Model(); $incident_category->incident_id = $incident->id; // If category name exists, add entry in incident_category table if ($categoryname != '') { // Check if the category exists (made sure to convert to uppercase for comparison) if (!isset($this->existing_categories[utf8::strtoupper($categoryname)])) { $this->notices[] = Kohana::lang('import.new_category') . $categoryname; $category = new Category_Model(); $category->category_title = $categoryname; // We'll just use black for now. Maybe something random? $category->category_color = '000000'; // because all current categories are of type '5' $category->category_visible = 1; $category->category_description = $categoryname; $category->category_position = count($this->existing_categories); $category->save(); $this->categories_added[] = $category->id; // Now category_id is known: This time, and for the rest of the import. $this->existing_categories[utf8::strtoupper($categoryname)] = $category->id; } $incident_category->category_id = $this->existing_categories[utf8::strtoupper($categoryname)]; $incident_category->save(); $this->incident_categories_added[] = $incident_category->id; } } } // STEP 5: Save Custom form fields responses // Check for form_id $form_id = (isset($row['FORM #']) and Form_Model::is_valid_form($row['FORM #'])) ? $row['FORM #'] : 1; // Get custom form fields for this particular form $custom_titles = customforms::get_custom_form_fields('', $form_id, false); // Do custom form fields exist on this deployment? if (!empty($custom_titles)) { foreach ($custom_titles as $field_name) { // Check if the column exists in the CSV $rowname = utf8::strtoupper($field_name['field_name']); if (isset($row[$rowname . '-' . $form_id])) { $response = $row[$rowname . '-' . $form_id]; // Grab field_id and field_type $field_id = $field_name['field_id']; $field_type = $field_name['field_type']; // Initialize form response model $form_response = new Form_Response_Model(); $form_response->incident_id = $incident->id; $form_response->form_field_id = $field_id; // If form response exists if ($response != '') { /* Handling case sensitivity issues with custom form field upload */ // Check if the field is a radio button, checkbox OR dropdown field if ($field_type == '5' or $field_type == '6' or $field_type == '7') { // Get field option values $field_values = $field_name['field_default']; // Split field options into individual values $options = explode(",", $field_values); // Since radio button and dropdown fields take single responses if ($field_type == '5' or $field_type == '7') { foreach ($options as $option) { // Carry out a case insensitive comparison between individual field options and csv response // If there's a match, store field option value from the db if (strcasecmp($option, $response) == 0) { $form_response->form_response = $option; } } } // For checkboxes, which accomodate multiple responses if ($field_type == '6') { // Split user responses into single values $csvresponses = explode(",", $response); $values = array(); foreach ($options as $option) { foreach ($csvresponses as $csvresponse) { // Carry out a case insensitive comparison between individual field options and csv response // If there's a match if (strcasecmp($option, $csvresponse) == 0) { // Store field option value from the db $values[] = $option; } } } // Concatenate checkbox values into a string, separated by a comma $form_response->form_response = implode(",", $values); } } else { $form_response->form_response = $response; } // If form_response is provided based on conditions set above, Save the form response if ($form_response->form_response != '') { $form_response->save(); // Add to array of field responses added $this->incident_responses_added[] = $form_response->id; } } } } } return true; }
foreach ($incidents as $incident) { $incident_id = $incident->id; $incident_title = text::limit_chars(html::strip_tags($incident->incident_title), 25, '...', True); $incident_date = $incident->incident_date; $incident_date = date('M j Y', strtotime($incident->incident_date)); $incident_location = $incident->location->location_name; // How the person feels is a concat of categories on the report $how_feel = ''; foreach ($incident->category as $category) { $how_feel .= $category->category_title . ', '; } $how_feel = trim($how_feel, ', '); // Why they feel this way and how they would change it are custom form fields $why_feel = ''; $change_place = ''; $custom_data = customforms::get_custom_form_fields($incident_id); foreach ($custom_data as $custom) { switch ($custom['field_id']) { case '1': $why_feel = text::limit_chars(html::strip_tags($custom['field_response']), 100, '...', True); case '2': $change_place = text::limit_chars(html::strip_tags($custom['field_response']), 100, '...', True); } } $incident_image = false; foreach ($incident->media as $media) { if ($media->media_type == 1) { $incident_image = url::convert_uploaded_to_abs($media->media_thumb); } } ?>
/** * Generic function to get reports by given set of parameters * * @param string $where SQL where clause * @return string XML or JSON string */ public function _get_incidents($where = array()) { // STEP 1. // Get the incidents $items = Incident_Model::get_incidents($where, $this->list_limit, $this->order_field, $this->sort); //No record found. if ($items->count() == 0) { return $this->response(4, $this->error_messages); } // Records found - proceed // Set the no. of records returned $this->record_count = $items->count(); // Will hold the XML/JSON string to return $ret_json_or_xml = ''; $json_reports = array(); $json_report_media = array(); $json_report_categories = array(); $json_incident_media = array(); $upload_path = str_replace("media/uploads/", "", Kohana::config('upload.relative_directory') . "/"); //XML elements $xml = new XmlWriter(); $xml->openMemory(); $xml->startDocument('1.0', 'UTF-8'); $xml->startElement('response'); $xml->startElement('payload'); $xml->writeElement('domain', $this->domain); $xml->startElement('incidents'); // Records found, proceed // Store the incident ids $incidents_ids = array(); $custom_field_items = array(); foreach ($items as $item) { $incident_ids[] = $item->incident_id; $thiscustomfields = customforms::get_custom_form_fields($item->incident_id, null, false, "view"); if (!empty($thiscustomfields)) { $custom_field_items[$item->incident_id] = $thiscustomfields; } } // // STEP 2. // Fetch the incident categories // // Execute the query $incident_categories = ORM::factory('category')->select('category.*, incident_category.incident_id')->join('incident_category', 'category.id', 'incident_category.category_id')->in('incident_category.incident_id', $incident_ids)->find_all(); // To hold the incident category items $category_items = array(); // Fetch items into array foreach ($incident_categories as $incident_category) { $category_items[$incident_category->incident_id][] = $incident_category->as_array(); } // Free temporary variables from memory unset($incident_categories); // // STEP 3. // Fetch the media associated with all the incidents // $media_items_result = ORM::factory('media')->in('incident_id', $incident_ids)->find_all(); // To store the fetched media items $media_items = array(); // Fetch items into array foreach ($media_items_result as $media_item) { $media_item_array = $media_item->as_array(); if ($media_item->media_type == 1 and !empty($media_item->media_thumb)) { $media_item_array["media_thumb_url"] = url::convert_uploaded_to_abs($media_item->media_thumb); $media_item_array["media_link_url"] = url::convert_uploaded_to_abs($media_item->media_link); } $media_items[$media_item->incident_id][] = $media_item_array; } // Free temporary variables unset($media_items_result, $media_item_array); // // STEP 4. // Fetch the comments associated with the incidents // if ($this->comments) { // Execute the query $incident_comments = ORM::factory('comment')->in('incident_id', $incident_ids)->where('comment_spam', 0)->find_all(); // To hold the incident category items $comment_items = array(); // Fetch items into array foreach ($incident_comments as $incident_comment) { $comment_items[$incident_comment->incident_id][] = $incident_comment->as_array(); } // Free temporary variables from memory unset($incident_comments); } // // STEP 5. // Return XML // foreach ($items as $item) { // Build xml file $xml->startElement('incident'); $xml->writeElement('id', $item->incident_id); $xml->writeElement('title', $item->incident_title); $xml->writeElement('description', $item->incident_description); $xml->writeElement('date', $item->incident_date); $xml->writeElement('mode', $item->incident_mode); $xml->writeElement('active', $item->incident_active); $xml->writeElement('verified', $item->incident_verified); $xml->startElement('location'); $xml->writeElement('id', $item->location_id); $xml->writeElement('name', $item->location_name); $xml->writeElement('latitude', $item->latitude); $xml->writeElement('longitude', $item->longitude); $xml->endElement(); $xml->startElement('categories'); $json_report_categories[$item->incident_id] = array(); // Check if the incident id exists if (isset($category_items[$item->incident_id])) { foreach ($category_items[$item->incident_id] as $category_item) { if ($this->response_type == 'json' or $this->response_type == 'jsonp') { $json_report_categories[$item->incident_id][] = array("category" => array("id" => $category_item['id'], "title" => $category_item['category_title'])); } else { $xml->startElement('category'); $xml->writeElement('id', $category_item['id']); $xml->writeElement('title', $category_item['category_title']); $xml->endElement(); } } } // End categories $xml->endElement(); $xml->startElement('comments'); $json_report_comments[$item->incident_id] = array(); // Check if the incident id exists if (isset($comment_items[$item->incident_id])) { foreach ($comment_items[$item->incident_id] as $comment_item) { if ($this->response_type == 'json' or $this->response_type == 'jsonp') { $json_report_comments[$item->incident_id][] = array("comment" => $comment_item); } else { $xml->startElement('comment'); $xml->writeElement('id', $comment_item['id']); $xml->writeElement('comment_author', $comment_item['comment_author']); $xml->writeElement('comment_email', $comment_item['comment_email']); $xml->writeElement('comment_description', $comment_item['comment_description']); $xml->writeElement('comment_date', $comment_item['comment_date']); $xml->endElement(); } } } // End comments $xml->endElement(); $json_report_media[$item->incident_id] = array(); if (count($media_items) > 0) { if (isset($media_items[$item->incident_id]) and count($media_items[$item->incident_id]) > 0) { $xml->startElement('mediaItems'); foreach ($media_items[$item->incident_id] as $media_item) { if ($this->response_type == 'json' or $this->response_type == 'jsonp') { $json_media_array = array("id" => $media_item['id'], "type" => $media_item['media_type'], "link" => $media_item['media_link'], "thumb" => $media_item['media_thumb']); // If we are look at certain types of media, add some fields if ($media_item['media_type'] == 1 and isset($media_item['media_thumb_url'])) { // Give a full absolute URL to the image $json_media_array["thumb_url"] = $media_item['media_thumb_url']; $json_media_array["link_url"] = $media_item['media_link_url']; } $json_report_media[$item->incident_id][] = $json_media_array; } else { $xml->startElement('media'); if ($media_item['id'] != "") { $xml->writeElement('id', $media_item['id']); } if ($media_item['media_title'] != "") { $xml->writeElement('title', $media_item['media_title']); } if ($media_item['media_type'] != "") { $xml->writeElement('type', $media_item['media_type']); } if ($media_item['media_link'] != "") { $xml->writeElement('link', $upload_path . $media_item['media_link']); } if ($media_item['media_thumb'] != "") { $xml->writeElement('thumb', $upload_path . $media_item['media_thumb']); } if ($media_item['media_type'] == 1 and isset($media_item['media_thumb_url'])) { $xml->writeElement('thumb_url', $media_item['media_thumb_url']); $xml->writeElement('link_url', $media_item['media_link_url']); } $xml->endElement(); } } $xml->endElement(); // Media } } if (count($custom_field_items) > 0 and $this->response_type != 'json' and $this->response_type != 'jsonp') { if (isset($custom_field_items[$item->incident_id]) and count($custom_field_items[$item->incident_id]) > 0) { $xml->startElement('customFields'); foreach ($custom_field_items[$item->incident_id] as $field_item) { $xml->startElement('field'); foreach ($field_item as $fname => $fval) { $xml->writeElement($fname, $fval); } $xml->endElement(); // field } $xml->endElement(); // customFields } } $xml->endElement(); // End incident // Check for response type if ($this->response_type == 'json' or $this->response_type == 'jsonp') { $json_reports[] = array("incident" => array("incidentid" => $item->incident_id, "incidenttitle" => $item->incident_title, "incidentdescription" => $item->incident_description, "incidentdate" => $item->incident_date, "incidentmode" => $item->incident_mode, "incidentactive" => $item->incident_active, "incidentverified" => $item->incident_verified, "locationid" => $item->location_id, "locationname" => $item->location_name, "locationlatitude" => $item->latitude, "locationlongitude" => $item->longitude), "categories" => $json_report_categories[$item->incident_id], "media" => $json_report_media[$item->incident_id], "comments" => $json_report_comments[$item->incident_id], "customfields" => isset($custom_field_items[$item->incident_id]) ? $custom_field_items[$item->incident_id] : array()); } } // Create the JSON array $data = array("payload" => array("domain" => $this->domain, "incidents" => $json_reports), "error" => $this->api_service->get_error_msg(0)); if ($this->response_type == 'json' or $this->response_type == 'jsonp') { return $this->array_as_json($data); } else { $xml->endElement(); //end incidents $xml->endElement(); // end payload $xml->startElement('error'); $xml->writeElement('code', 0); $xml->writeElement('message', 'No Error'); $xml->endElement(); //end error $xml->endElement(); // end response return $xml->outputMemory(true); } }
?> </h4> <%- moment(incident_date).format('YYYY-MM-DD HH:mm:ss') %> </div> <div class="row"> <h4><?php echo Kohana::lang('ui_main.reports_description'); ?> </h4> <%= _(incident_description).escape().replace(/\n/g,'<br />') %> </div> <?php // Hack to render custom fields - only supports default form for now echo View::factory('reports/detail_custom_forms')->set('form_field_names', customforms::get_custom_form_fields(FALSE, 1, FALSE, 'view'))->set('show_empty', TRUE)->render(); ?> <h4><?php echo Kohana::lang('ui_main.personal_information'); ?> </h4> <div class="row"> <h4><?php echo Kohana::lang('ui_main.first_name'); ?> </h4> <%- incident_person.person_first != null ? incident_person.person_first : '' %> </div> <div class="row"> <h4><?php
/** * Validation of form fields * * @param array $post Values to be validated */ public static function validate(array &$post) { // Exception handling if (!isset($post) or !is_array($post)) { return FALSE; } // Create validation object $post = Validation::factory($post)->pre_filter('trim', TRUE)->add_rules('incident_title', 'required', 'length[3,200]')->add_rules('incident_description', 'required')->add_rules('incident_date', 'required', 'date_mmddyyyy')->add_rules('incident_hour', 'required', 'between[1,12]')->add_rules('incident_minute', 'required', 'between[0,59]')->add_rules('incident_ampm', 'required'); if (isset($post->incident_ampm) and $post->incident_ampm != "am" and $post->incident_ampm != "pm") { $post->add_error('incident_ampm', 'values'); } // Validate for maximum and minimum latitude values //$post->add_rules('latitude','required','between[-90,90]'); // Validate for maximum and minimum longitude values //$post->add_rules('longitude','required','between[-180,180]'); $post->add_rules('location_name', 'required', 'length[3,200]'); //XXX: Hack to validate for no checkboxes checked if (!isset($post->incident_category)) { $post->incident_category = ""; $post->add_error('incident_category', 'required'); } else { $post->add_rules('incident_category.*', 'required', 'numeric'); } // Validate only the fields that are filled in if (!empty($post->incident_news)) { foreach ($post->incident_news as $key => $url) { if (!empty($url) and !valid::url($url)) { $post->add_error('incident_news', 'url'); } } } // Validate only the fields that are filled in if (!empty($post->incident_video)) { foreach ($post->incident_video as $key => $url) { if (!empty($url) and !valid::url($url)) { $post->add_error('incident_video', 'url'); } } } // If deployment is a single country deployment, check that the location mapped is in the default country if (!Kohana::config('settings.multi_country') and isset($post->country_name)) { $country = Country_Model::get_country_by_name($post->country_name); if ($country and $country->id != Kohana::config('settings.default_country')) { $post->add_error('country_name', 'single_country', array(ORM::factory('country', Kohana::config('settings.default_country'))->country)); } } // Validate photo uploads $max_upload_size = Kohana::config('settings.max_upload_size'); $post->add_rules('incident_photo', 'upload::valid', 'upload::type[gif,jpg,png,jpeg]', "upload::size[" . $max_upload_size . "M]"); // Validate Personal Information if (!empty($post->person_first)) { $post->add_rules('person_first', 'length[2,100]'); } else { $post->person_first = ''; } if (!empty($post->person_last)) { $post->add_rules('person_last', 'length[2,100]'); } else { $post->person_last = ''; } if (!empty($post->person_email)) { $post->add_rules('person_email', 'email', 'length[3,100]'); } else { $post->person_email = ''; } $post->add_rules('location_id', 'numeric'); $post->add_rules('incident_active', 'between[0,1]'); $post->add_rules('incident_verified', 'between[0,1]'); $post->add_rules('incident_zoom', 'numeric'); // Custom form fields validation customforms::validate_custom_form_fields($post); //> END custom form fields validation // Return return $post->validate(); }
/** * Gets the form field meta values * */ private function _get_custom_form_meta() { $is_json = $this->_is_json(); if (!$this->api_service->verify_array_index($this->request, 'formid')) { return $this->set_error_message(array("error" => $this->api_service->get_error_msg(01, 'formid'))); } else { $this->formid = $this->request['formid']; } $form_meta = customforms::get_custom_form_fields(false, $this->formid); //Get the meta fields for the specified formId if (count($form_meta) == 0) { return $this->response(4); //We don't have any fields for this form } if ($is_json) { $json_item = array(); $json = array(); } else { $xml = new XmlWriter(); $xml->openMemory(); $xml->startDocument('1.0', 'UTF-8'); $xml->startElement('response'); $xml->startElement('payload'); $xml->writeElement('domain', $this->domain); $xml->startElement('customforms'); $xml->startElement("fields"); } foreach ($form_meta as $meta_val) { if ($is_json) { $json_item["fields"][] = $this->_meta_fields($meta_val); //return meta key array } else { $this->_meta_fields($meta_val, $xml); //write the xml nodes for the meta fields } } if ($is_json) { $json = array("payload" => array("customforms" => $json_item), "error" => $this->api_service->get_error_msg(0)); $json_item = null; return $this->array_as_json($json); //return json as response_data } else { $xml->endElement(); //end fields $xml->endElement(); //end customforms $xml->endElement(); //end payload $xml->startElement('error'); $xml->writeElement('code', 0); $xml->writeElement('message', 'No Error'); $xml->endElement(); //end error $xml->endElement(); //end response return $xml->outputMemory(true); //write out the xml stream as response_data } }
/** * Move Form Field Up or Down * Positioning in layout */ public function field_move() { $this->template = ""; $this->auto_render = FALSE; // Get the form id $form_id = (isset($_POST['form_id']) and intval($_POST['form_id']) > 0) ? intval($_POST['form_id']) : 0; // Get the field id $field_id = (isset($_POST['field_id']) and intval($_POST['field_id']) > 0) ? intval($_POST['field_id']) : 0; // Field position $field_position = isset($_POST['field_position']) ? $_POST['field_position'] : ""; $return_content = ""; if ($field_position == 'u' or $field_position == 'd') { // Load This Field $field = ORM::factory('form_field', $field_id); if ($field->loaded == TRUE) { // Get the total number of fields for the form $total_fields = ORM::factory('form_field')->where('form_id', $field->form_id)->count_all(); // Get current position $current_position = $field->field_position; if ($field_position == 'u' and $current_position > 1) { // Move down the fields whose position value is greater // than that of the selected field $sql = "UPDATE %sform_field SET field_position = %d WHERE field_position = %d"; $this->db->query(sprintf($sql, $this->table_prefix, $current_position, $current_position - 1)); // Move the selected field upwards $field->field_position = $current_position - 1; $field->save(); } elseif ($field_position == 'd' and $current_position != $total_fields) { // Move all other form fields upwards $sql = "UPDATE %sform_field SET field_position = %d WHERE field_position = %d"; $this->db->query(sprintf($sql, $this->table_prefix, $current_position, $current_position + 1)); // Move the selected field downwards - increase its field position in the database $field->field_position = $current_position + 1; $field->save(); } } } $return_content = customforms::get_current_fields($form_id, $this->user); echo json_encode(array("status" => "success", "response" => $return_content)); }
</label> <input type='text' name='incident_date' class='field-incident-date text' value='<%- moment(incident_date).format('YYYY-MM-DD') %>' /> <input type='text' name='incident_time' class='field-incident-time text' value='<%- moment(incident_date).format('HH:mm:ss') %>' /> </div> <div class="row"> <label for="incident_description"><?php echo Kohana::lang('ui_main.reports_description'); ?> </label> <textarea name="incident_description" class='field-incident-description' cols=80 rows=20><%- incident_description %></textarea> </div> <?php // Hack to render custom fields - only supports default form for now echo View::factory('reports/submit_custom_forms')->set('disp_custom_fields', customforms::get_custom_form_fields(FALSE, 1))->set('custom_field_mismatch', customforms::get_edit_mismatch(1))->render(); ?> <div class="row"> <h4><?php echo Kohana::lang('ui_main.personal_information'); ?> </h4> <label for="incident_person[person_first]"><?php echo Kohana::lang('ui_main.first_name'); ?> </label> <input type='text' name='incident_person[person_first]' class='field-person-first text' value='<%- incident_person.person_first != null ? incident_person.person_first : '' %>' /> </div> <div class="row"> <label for="incident_person[person_last]"><?php
/** * Download Reports in CSV format * JP: Added filter by search option. Also added HTML download. */ public function download() { // If user doesn't have access, redirect to dashboard if (!$this->auth->has_permission("reports_download")) { url::redirect(url::site() . 'admin/dashboard'); } $this->template->content = new View('admin/reports/download'); $this->template->content->title = Kohana::lang('ui_admin.download_reports'); $errors = $form = array('format' => '', 'data_active' => array(), 'data_verified' => array(), 'data_include' => array(), 'from_date' => '', 'to_date' => '', 'form_auth_token' => '', 'filter_search' => ''); // Default to all selected $form['data_active'] = array(0, 1); $form['data_verified'] = array(0, 1); $form['data_include'] = array(1, 2, 3, 4, 5, 6, 7); $form_error = FALSE; // Check, has the form been submitted, if so, setup validation if ($_POST) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = array_merge($_POST, $_FILES); // Test to see if things passed the rule checks if (download::validate($post)) { // Set filter $filter = '( '; // Report Type Filter $show_active = FALSE; $show_inactive = FALSE; $show_verified = FALSE; $show_not_verified = FALSE; $filter_search = FALSE; if (in_array(1, $post->data_active)) { $show_active = TRUE; } if (in_array(0, $post->data_active)) { $show_inactive = TRUE; } if (in_array(1, $post->data_verified)) { $show_verified = TRUE; } if (in_array(0, $post->data_verified)) { $show_not_verified = TRUE; } if (!empty($post->filter_search)) { $filter_search = TRUE; } // Handle active or not active if ($show_active && !$show_inactive) { $filter .= ' incident_active = 1 '; } elseif (!$show_active && $show_inactive) { $filter .= ' incident_active = 0 '; } elseif ($show_active && $show_inactive) { $filter .= ' (incident_active = 1 OR incident_active = 0) '; } elseif (!$show_active && !$show_inactive) { // Equivalent to 1 = 0 $filter .= ' (incident_active = 0 AND incident_active = 1) '; } $filter .= ' AND '; // Handle verified if ($show_verified && !$show_not_verified) { $filter .= ' incident_verified = 1 '; } elseif (!$show_verified && $show_not_verified) { $filter .= ' incident_verified = 0 '; } elseif ($show_verified && $show_not_verified) { $filter .= ' (incident_verified = 0 OR incident_verified = 1) '; } elseif (!$show_verified && !$show_not_verified) { $filter .= ' (incident_verified = 0 AND incident_verified = 1) '; } $filter .= ') '; // Report Date Filter if (!empty($post->from_date)) { $filter .= " AND incident_date >= '" . date("Y-m-d H:i:s", strtotime($post->from_date)) . "' "; } if (!empty($post->to_date)) { $filter .= " AND incident_date <= '" . date("Y-m-d H:i:s", strtotime($post->to_date)) . "' "; } // JP: Search Filter if ($filter_search) { $where_string = ""; $or = ""; // Stop words that we won't search for // Add words as needed!! $stop_words = array('the', 'and', 'a', 'to', 'of', 'in', 'i', 'is', 'that', 'it', 'on', 'you', 'this', 'for', 'but', 'with', 'are', 'have', 'be', 'at', 'or', 'as', 'was', 'so', 'if', 'out', 'not'); // Phase 1 - Fetch the search string and perform initial sanitization $keyword_raw = preg_replace('#/\\w+/#', '', $post->filter_search); // Phase 2 - Strip the search string of any HTML and PHP tags that may be present for additional safety $keyword_raw = strip_tags($keyword_raw); // Phase 3 - Apply Kohana's XSS cleaning mechanism $keyword_raw = $this->input->xss_clean($keyword_raw); // Database instance $db = new Database(); $keywords = explode(' ', $keyword_raw); if (is_array($keywords) and !empty($keywords)) { array_change_key_case($keywords, CASE_LOWER); $i = 0; foreach ($keywords as $value) { if (!in_array($value, $stop_words) and !empty($value)) { // Escape the string for query safety $chunk = $db->escape_str($value); if ($i > 0) { $or = ' OR '; } $where_string = $where_string . $or . "(incident_title LIKE '%{$chunk}%' OR incident_description LIKE '%{$chunk}%')"; $i++; } } } $filter .= " AND " . $where_string; } // Retrieve reports $incidents = ORM::factory('incident')->where($filter)->orderby('incident_dateadd', 'desc')->find_all(); // Retrieve categories $categories = Category_Model::get_categories(FALSE, FALSE, FALSE); // Retrieve Forms $forms = ORM::Factory('form')->find_all(); // Retrieve Custom forms $custom_forms = customforms::get_custom_form_fields(); // If CSV format is selected if ($post->format == 'csv') { $report_csv = download::download_csv($post, $incidents, $custom_forms); // Output to browser header("Content-type: text/x-csv"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Disposition: attachment; filename=" . time() . ".csv"); header("Content-Length: " . strlen($report_csv)); echo $report_csv; exit; } // If XML format is selected if ($post->format == 'xml') { header('Content-type: text/xml; charset=UTF-8'); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Disposition: attachment; filename=" . time() . ".xml"); $content = download::download_xml($post, $incidents, $categories, $forms); echo $content; exit; } // JP: If HTML format is selected... if ($post->format == 'html') { $content = download::download_html($post, $incidents, $custom_forms); header("Content-type: text/html; charset=UTF-8"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Disposition: attachment; filename=" . time() . ".html"); header("Content-Length: " . strlen($content)); echo $content; exit; } } else { // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::merge($errors, $post->errors('report')); $form_error = TRUE; } } $this->template->content->form = $form; $this->template->content->errors = $errors; $this->template->content->form_error = $form_error; // Javascript Header $this->themes->js = new View('admin/reports/download_js'); $this->themes->js->calendar_img = url::base() . "media/img/icon-calendar.gif"; }
/** * Function to import a report form a row in the CSV file * @param file $file * @return bool */ public function import($file) { /* For purposes of checking whether the data we're trying to import already exists */ // Pick out existing categories $this->existing_categories = ORM::factory('category')->select_list('category_title', 'id'); $temp_cat = array(); foreach ($this->existing_categories as $title => $id) { $temp_cat[utf8::strtoupper($title)] = $id; } $this->existing_categories = $temp_cat; // Pick out existing reports $this->incident_ids = ORM::factory('incident')->select_list('id', 'id'); // Pick out existing forms $this->existing_forms = ORM::factory('form')->select_list('form_title', 'id'); $temp_forms = array(); foreach ($this->existing_forms as $title => $id) { $temp_forms[utf8::strtoupper($title)] = $id; } $this->existing_forms = $temp_forms; // Pick out existing form fields $form_fields = customforms::get_custom_form_fields(FALSE, '', FALSE); $temp_fields = array(); foreach ($form_fields as $existing_field) { $field_name = $existing_field['field_name']; $form_id = $existing_field['form_id']; $field_id = $existing_field['field_id']; $temp_fields[utf8::strtoupper($field_name)][$form_id] = $field_id; } $this->existing_fields = $temp_fields; // For purposes of adding location time $this->time = date("Y-m-d H:i:s", time()); // Initialize DOMDocument $xml = new DOMDocument('1.0'); // Make sure we're not trying to open an empty file if (@$xml->load($file) !== FALSE) { $depcategories = $xml->getElementsByTagName('categories'); $depcustomforms = $xml->getElementsByTagName('custom_forms'); $depreports = $xml->getElementsByTagName('reports'); if ($depcategories->length == 0 and $depcustomforms->length == 0 and $depreports->length == 0) { $this->errors[] = Kohana::lang('import.xml.missing_elements'); } // If we're importing categories if ($depcategories->length > 0) { $categories = $depcategories->item(0); if ($categories->nodeValue != 'There are no categories on this deployment.') { if ($this->import_categories($categories) == false) { // Undo Data Import $this->rollback(); return false; } } else { $this->notices[] = Kohana::lang('import.xml.no_categories'); } } // If we're importing custom forms if ($depcustomforms->length > 0) { $customforms = $depcustomforms->item(0); if ($customforms->nodeValue != 'There are no custom forms on this deployment.') { if ($this->import_customforms($customforms) == false) { // Undo Data Import $this->rollback(); return FALSE; } } else { $this->notices[] = Kohana::lang('import.xml.no_custom_forms'); } } // If we are importing Reports if ($depreports->length > 0) { $reports = $depreports->item(0); if ($reports->nodeValue != 'There are no reports on this deployment.') { if ($this->import_reports($reports) == false) { // Undo Data Import $this->rollback(); return FALSE; } } else { $this->notices[] = Kohana::lang('import.xml.no_reports'); } } } else { $this->errors[] = Kohana::lang('import.xml.file_empty'); } // If we have errors, return FALSE, else TRUE return count($this->errors) === 0; }
/** * Edit a report * @param bool|int $id The id no. of the report * @param bool|string $saved */ public function edit($id = FALSE, $saved = FALSE) { $db = new Database(); $this->template->content = new View('members/reports_edit'); $this->template->content->title = Kohana::lang('ui_admin.create_report'); // Setup and initialize form field names $form = array('location_id' => '', 'form_id' => '1', 'locale' => '', 'incident_title' => '', 'incident_description' => '', 'incident_date' => '', 'incident_hour' => '', 'incident_minute' => '', 'incident_ampm' => '', 'latitude' => '', 'longitude' => '', 'geometry' => array(), 'location_name' => '', 'country_id' => '', 'country_name' => '', 'incident_category' => array(), 'incident_news' => array(), 'incident_video' => array(), 'incident_photo' => array(), 'person_first' => '', 'person_last' => '', 'person_email' => '', 'custom_field' => array(), 'incident_zoom' => '', 'incident_source' => '', 'incident_information' => ''); // Copy the form as errors, so the errors will be stored with keys // corresponding to the form field names $errors = $form; $form_error = FALSE; $form_saved = $saved == 'saved'; // Initialize Default Values $form['locale'] = Kohana::config('locale.language'); $form['latitude'] = Kohana::config('settings.default_lat'); $form['longitude'] = Kohana::config('settings.default_lon'); $form['country_id'] = Kohana::config('settings.default_country'); $form['incident_date'] = date("m/d/Y", time()); $form['incident_hour'] = date('h'); $form['incident_minute'] = date('i'); $form['incident_ampm'] = date('a'); // Initialize custom field array $form_id = $form['form_id']; $form['custom_field'] = customforms::get_custom_form_fields($id, $form_id, TRUE); // Locale (Language) Array $this->template->content->locale_array = Kohana::config('locale.all_languages'); // Time formatting $this->template->content->hour_array = $this->_hour_array(); $this->template->content->minute_array = $this->_minute_array(); $this->template->content->ampm_array = $this->_ampm_array(); $this->template->content->stroke_width_array = $this->_stroke_width_array(); // Get Countries $countries = array(); foreach (ORM::factory('country')->orderby('country')->find_all() as $country) { // Create a list of all categories $this_country = $country->country; if (strlen($this_country) > 35) { $this_country = substr($this_country, 0, 35) . "..."; } $countries[$country->id] = $this_country; } $this->template->content->countries = $countries; // Initialize Default Value for Hidden Field Country Name, just incase Reverse Geo coding yields no result $form['country_name'] = $countries[$form['country_id']]; //GET custom forms $forms = array(); foreach (ORM::factory('form')->where('form_active', 1)->find_all() as $custom_forms) { $forms[$custom_forms->id] = $custom_forms->form_title; } $this->template->content->forms = $forms; // Retrieve thumbnail photos (if edit); //XXX: fix _get_thumbnails $this->template->content->incident = $this->_get_thumbnails($id); // Check, has the form been submitted, if so, setup validation if ($_POST) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = array_merge($_POST, $_FILES); if (reports::validate($post)) { // STEP 1: SAVE LOCATION $location = new Location_Model(); reports::save_location($post, $location); // STEP 2: SAVE INCIDENT $incident = new Incident_Model($id); reports::save_report($post, $incident, $location->id); // STEP 2b: SAVE INCIDENT GEOMETRIES reports::save_report_geometry($post, $incident); // STEP 3: SAVE CATEGORIES reports::save_category($post, $incident); // STEP 4: SAVE MEDIA reports::save_media($post, $incident); // STEP 5: SAVE CUSTOM FORM FIELDS reports::save_custom_fields($post, $incident); // STEP 6: SAVE PERSONAL INFORMATION reports::save_personal_info($post, $incident); // Action::report_add / report_submit_members - Added a New Report Event::run('ushahidi_action.report_submit_members', $post); Event::run('ushahidi_action.report_edit', $incident); // SAVE AND CLOSE? if ($post->save == 1) { // Save but don't close url::redirect('members/reports/edit/' . $incident->id . '/saved'); } else { // Save and close url::redirect('members/reports/'); } } else { // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::overwrite($errors, $post->errors('report')); $form_error = TRUE; } } else { if ($id) { // Retrieve Current Incident $incident = ORM::factory('incident')->where('user_id', $this->user->id)->find($id); if ($incident->loaded == true) { // Retrieve Categories $incident_category = array(); foreach ($incident->incident_category as $category) { $incident_category[] = $category->category_id; } // Retrieve Media $incident_news = array(); $incident_video = array(); $incident_photo = array(); foreach ($incident->media as $media) { if ($media->media_type == 4) { $incident_news[] = $media->media_link; } elseif ($media->media_type == 2) { $incident_video[] = $media->media_link; } elseif ($media->media_type == 1) { $incident_photo[] = $media->media_link; } } // Get Geometries via SQL query as ORM can't handle Spatial Data $sql = "SELECT AsText(geometry) as geometry, geometry_label, \n\t\t\t\t\t\tgeometry_comment, geometry_color, geometry_strokewidth \n\t\t\t\t\t\tFROM " . Kohana::config('database.default.table_prefix') . "geometry \n\t\t\t\t\t\tWHERE incident_id = ?"; $query = $db->query($sql, $id); foreach ($query as $item) { $geometry = array("geometry" => $item->geometry, "label" => $item->geometry_label, "comment" => $item->geometry_comment, "color" => $item->geometry_color, "strokewidth" => $item->geometry_strokewidth); $form['geometry'][] = json_encode($geometry); } // Combine Everything $incident_arr = array('location_id' => $incident->location->id, 'form_id' => $incident->form_id, 'locale' => $incident->locale, 'incident_title' => $incident->incident_title, 'incident_description' => $incident->incident_description, 'incident_date' => date('m/d/Y', strtotime($incident->incident_date)), 'incident_hour' => date('h', strtotime($incident->incident_date)), 'incident_minute' => date('i', strtotime($incident->incident_date)), 'incident_ampm' => date('a', strtotime($incident->incident_date)), 'latitude' => $incident->location->latitude, 'longitude' => $incident->location->longitude, 'location_name' => $incident->location->location_name, 'country_id' => $incident->location->country_id, 'incident_category' => $incident_category, 'incident_news' => $incident_news, 'incident_video' => $incident_video, 'incident_photo' => $incident_photo, 'person_first' => $incident->incident_person->person_first, 'person_last' => $incident->incident_person->person_last, 'person_email' => $incident->incident_person->person_email, 'incident_source' => '', 'incident_information' => '', 'custom_field' => customforms::get_custom_form_fields($id, $incident->form_id, TRUE), 'incident_zoom' => $incident->incident_zoom); // Merge To Form Array For Display $form = arr::overwrite($form, $incident_arr); } else { // Redirect url::redirect('members/reports/'); } } } $this->template->content->id = $id; $this->template->content->form = $form; $this->template->content->errors = $errors; $this->template->content->form_error = $form_error; $this->template->content->form_saved = $form_saved; // Retrieve Custom Form Fields Structure $this->template->content->custom_forms = new View('reports/submit_custom_forms'); $disp_custom_fields = customforms::get_custom_form_fields($id, $form['form_id'], FALSE, "view"); $custom_field_mismatch = customforms::get_edit_mismatch($form['form_id']); // Quick hack to make sure view-only fields have data set foreach ($custom_field_mismatch as $id => $field) { $form['custom_field'][$id] = $disp_custom_fields[$id]['field_response']; } $this->template->content->custom_forms->disp_custom_fields = $disp_custom_fields; $this->template->content->custom_forms->custom_field_mismatch = $custom_field_mismatch; $this->template->content->custom_forms->form = $form; // Retrieve Previous & Next Records $previous = ORM::factory('incident')->where('id < ', $id)->orderby('id', 'desc')->find(); $previous_url = $previous->loaded ? url::site('members/reports/edit/' . $previous->id) : url::site() . 'members/reports/'; $next = ORM::factory('incident')->where('id > ', $id)->orderby('id', 'desc')->find(); $next_url = $next->loaded ? url::site('members/reports/edit/' . $next->id) : url::site('members/reports/'); $this->template->content->previous_url = $previous_url; $this->template->content->next_url = $next_url; // Javascript Header $this->themes->map_enabled = TRUE; $this->themes->colorpicker_enabled = TRUE; $this->themes->treeview_enabled = TRUE; $this->themes->json2_enabled = TRUE; $this->themes->js = new View('reports/submit_edit_js'); $this->themes->js->edit_mode = FALSE; $this->themes->js->default_map = Kohana::config('settings.default_map'); $this->themes->js->default_zoom = Kohana::config('settings.default_zoom'); if (!$form['latitude'] or !$form['longitude']) { $this->themes->js->latitude = Kohana::config('settings.default_lat'); $this->themes->js->longitude = Kohana::config('settings.default_lon'); } else { $this->themes->js->latitude = $form['latitude']; $this->themes->js->longitude = $form['longitude']; } $this->themes->js->incident_zoom = $form['incident_zoom']; $this->themes->js->geometries = $form['geometry']; // Inline Javascript $this->template->content->date_picker_js = $this->_date_picker_js(); $this->template->content->color_picker_js = $this->_color_picker_js(); // Pack Javascript $myPacker = new javascriptpacker($this->themes->js, 'Normal', FALSE, FALSE); $this->themes->js = $myPacker->pack(); }
/** * Edit a report * @param bool|int $id The id no. of the report * @param bool|string $saved */ public function edit($id = FALSE, $saved = FALSE) { $db = new Database(); // If user doesn't have access, redirect to dashboard if (!admin::permissions($this->user, "reports_edit")) { url::redirect(url::site() . 'admin/dashboard'); } $this->template->content = new View('admin/reports_edit'); $this->template->content->title = Kohana::lang('ui_admin.create_report'); // setup and initialize form field names $form = array('location_id' => '', 'form_id' => '', 'locale' => '', 'incident_title' => '', 'incident_description' => '', 'incident_date' => '', 'incident_hour' => '', 'incident_minute' => '', 'incident_ampm' => '', 'latitude' => '', 'longitude' => '', 'geometry' => array(), 'location_name' => '', 'country_id' => '', 'country_name' => '', 'incident_category' => array(), 'incident_news' => array(), 'incident_video' => array(), 'incident_photo' => array(), 'person_first' => '', 'person_last' => '', 'person_email' => '', 'custom_field' => array(), 'incident_active' => '', 'incident_verified' => '', 'incident_source' => '', 'incident_information' => '', 'incident_zoom' => ''); // Copy the form as errors, so the errors will be stored with keys corresponding to the form field names $errors = $form; $form_error = FALSE; $form_saved = $saved == 'saved'; // Initialize Default Values $form['locale'] = Kohana::config('locale.language'); //$form['latitude'] = Kohana::config('settings.default_lat'); //$form['longitude'] = Kohana::config('settings.default_lon'); $form['incident_date'] = date("m/d/Y", time()); $form['incident_hour'] = date('h'); $form['incident_minute'] = date('i'); $form['incident_ampm'] = date('a'); $form['country_id'] = Kohana::config('settings.default_country'); // initialize custom field array $form['custom_field'] = customforms::get_custom_form_fields($id, '', true); // Locale (Language) Array $this->template->content->locale_array = Kohana::config('locale.all_languages'); // Create Categories $this->template->content->categories = Category_Model::get_categories(); $this->template->content->new_categories_form = $this->_new_categories_form_arr(); // Time formatting $this->template->content->hour_array = $this->_hour_array(); $this->template->content->minute_array = $this->_minute_array(); $this->template->content->ampm_array = $this->_ampm_array(); $this->template->content->stroke_width_array = $this->_stroke_width_array(); // Get Countries $countries = array(); foreach (ORM::factory('country')->orderby('country')->find_all() as $country) { // Create a list of all countries $this_country = $country->country; if (strlen($this_country) > 35) { $this_country = substr($this_country, 0, 35) . "..."; } $countries[$country->id] = $this_country; } // Initialize Default Value for Hidden Field Country Name, just incase Reverse Geo coding yields no result $form['country_name'] = $countries[$form['country_id']]; $this->template->content->countries = $countries; //GET custom forms $forms = array(); foreach (ORM::factory('form')->where('form_active', 1)->find_all() as $custom_forms) { $forms[$custom_forms->id] = $custom_forms->form_title; } $this->template->content->forms = $forms; // Get the incident media $incident_media = Incident_Model::is_valid_incident($id) ? ORM::factory('incident', $id)->media : FALSE; $this->template->content->incident_media = $incident_media; // Are we creating this report from SMS/Email/Twitter? // If so retrieve message if (isset($_GET['mid']) and intval($_GET['mid']) > 0) { $message_id = intval($_GET['mid']); $service_id = ""; $message = ORM::factory('message', $message_id); if ($message->loaded and $message->message_type == 1) { $service_id = $message->reporter->service_id; // Has a report already been created for this Message? if ($message->incident_id != 0) { // Redirect to report url::redirect('admin/reports/edit/' . $message->incident_id); } $this->template->content->show_messages = true; $incident_description = $message->message; if (!empty($message->message_detail)) { $form['incident_title'] = $message->message; $incident_description = $message->message_detail; } $form['incident_description'] = $incident_description; $form['incident_date'] = date('m/d/Y', strtotime($message->message_date)); $form['incident_hour'] = date('h', strtotime($message->message_date)); $form['incident_minute'] = date('i', strtotime($message->message_date)); $form['incident_ampm'] = date('a', strtotime($message->message_date)); $form['person_first'] = $message->reporter->reporter_first; $form['person_last'] = $message->reporter->reporter_last; // Does the sender of this message have a location? if ($message->reporter->location->loaded) { $form['location_id'] = $message->reporter->location->id; $form['latitude'] = $message->reporter->location->latitude; $form['longitude'] = $message->reporter->location->longitude; $form['location_name'] = $message->reporter->location->location_name; } // Retrieve Last 5 Messages From this account $this->template->content->all_messages = ORM::factory('message')->where('reporter_id', $message->reporter_id)->orderby('message_date', 'desc')->limit(5)->find_all(); } else { $message_id = ""; $this->template->content->show_messages = false; } } else { $this->template->content->show_messages = false; } // Are we creating this report from a Newsfeed? if (isset($_GET['fid']) and intval($_GET['fid']) > 0) { $feed_item_id = intval($_GET['fid']); $feed_item = ORM::factory('feed_item', $feed_item_id); if ($feed_item->loaded) { // Has a report already been created for this Feed item? if ($feed_item->incident_id != 0) { // Redirect to report url::redirect('admin/reports/edit/' . $feed_item->incident_id); } $form['incident_title'] = $feed_item->item_title; $form['incident_description'] = $feed_item->item_description; $form['incident_date'] = date('m/d/Y', strtotime($feed_item->item_date)); $form['incident_hour'] = date('h', strtotime($feed_item->item_date)); $form['incident_minute'] = date('i', strtotime($feed_item->item_date)); $form['incident_ampm'] = date('a', strtotime($feed_item->item_date)); // News Link $form['incident_news'][0] = $feed_item->item_link; // Does this newsfeed have a geolocation? if ($feed_item->location_id) { $form['location_id'] = $feed_item->location_id; $form['latitude'] = $feed_item->location->latitude; $form['longitude'] = $feed_item->location->longitude; $form['location_name'] = $feed_item->location->location_name; } } else { $feed_item_id = ""; } } // Check, has the form been submitted, if so, setup validation if ($_POST) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = array_merge($_POST, $_FILES); // Check if the service id exists if (isset($service_id) and intval($service_id) > 0) { $post = array_merge($post, array('service_id' => $service_id)); } // Check if the incident id is valid an add it to the post data if (Incident_Model::is_valid_incident($id)) { $post = array_merge($post, array('incident_id' => $id)); } /** * NOTES - E.Kala July 27, 2011 * * Previously, the $post parameter for this event was a Validation * object. Now it's an array (i.e. the raw data without any validation rules applied to them). * As such, all plugins making use of this event shall have to be updated */ // Action::report_submit_admin - Report Posted Event::run('ushahidi_action.report_submit_admin', $post); // Validate if (reports::validate($post, TRUE)) { // Yes! everything is valid $location_id = $post->location_id; // STEP 1: SAVE LOCATION $location = new Location_Model($location_id); reports::save_location($post, $location); // STEP 2: SAVE INCIDENT $incident = new Incident_Model($id); reports::save_report($post, $incident, $location->id); // STEP 2b: Record Approval/Verification Action $verify = new Verify_Model(); reports::verify_approve($post, $verify, $incident); // STEP 2c: SAVE INCIDENT GEOMETRIES reports::save_report_geometry($post, $incident); // STEP 3: SAVE CATEGORIES reports::save_category($post, $incident); // STEP 4: SAVE MEDIA reports::save_media($post, $incident); // STEP 5: SAVE PERSONAL INFORMATION reports::save_personal_info($post, $incident); // STEP 6a: SAVE LINK TO REPORTER MESSAGE // We're creating a report from a message with this option if (isset($message_id) and intval($message_id) > 0) { $savemessage = ORM::factory('message', $message_id); if ($savemessage->loaded) { $savemessage->incident_id = $incident->id; $savemessage->save(); // Does Message Have Attachments? // Add Attachments $attachments = ORM::factory("media")->where("message_id", $savemessage->id)->find_all(); foreach ($attachments as $attachment) { $attachment->incident_id = $incident->id; $attachment->save(); } } } // STEP 6b: SAVE LINK TO NEWS FEED // We're creating a report from a newsfeed with this option if (isset($feed_item_id) and intval($feed_item_id) > 0) { $savefeed = ORM::factory('feed_item', $feed_item_id); if ($savefeed->loaded) { $savefeed->incident_id = $incident->id; $savefeed->location_id = $location->id; $savefeed->save(); } } // STEP 7: SAVE CUSTOM FORM FIELDS reports::save_custom_fields($post, $incident); // Action::report_edit - Edited a Report Event::run('ushahidi_action.report_edit', $incident); // SAVE AND CLOSE? if ($post->save == 1) { // Save but don't close url::redirect('admin/reports/edit/' . $incident->id . '/saved'); } else { // Save and close url::redirect('admin/reports/'); } } else { // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::overwrite($errors, $post->errors('report')); $form_error = TRUE; } } else { if (Incident_Model::is_valid_incident($id)) { // Retrieve Current Incident $incident = ORM::factory('incident', $id); if ($incident->loaded == true) { // Retrieve Categories $incident_category = array(); foreach ($incident->incident_category as $category) { $incident_category[] = $category->category_id; } // Retrieve Media $incident_news = array(); $incident_video = array(); $incident_photo = array(); foreach ($incident->media as $media) { if ($media->media_type == 4) { $incident_news[] = $media->media_link; } elseif ($media->media_type == 2) { $incident_video[] = $media->media_link; } elseif ($media->media_type == 1) { $incident_photo[] = $media->media_link; } } // Get Geometries via SQL query as ORM can't handle Spatial Data $sql = "SELECT AsText(geometry) as geometry, geometry_label, \n\t\t\t\t\t\tgeometry_comment, geometry_color, geometry_strokewidth \n\t\t\t\t\t\tFROM " . Kohana::config('database.default.table_prefix') . "geometry \n\t\t\t\t\t\tWHERE incident_id=" . $id; $query = $db->query($sql); foreach ($query as $item) { $geometry = array("geometry" => $item->geometry, "label" => $item->geometry_label, "comment" => $item->geometry_comment, "color" => $item->geometry_color, "strokewidth" => $item->geometry_strokewidth); $form['geometry'][] = json_encode($geometry); } // Combine Everything $incident_arr = array('location_id' => $incident->location->id, 'form_id' => $incident->form_id, 'locale' => $incident->locale, 'incident_title' => $incident->incident_title, 'incident_description' => $incident->incident_description, 'incident_date' => date('m/d/Y', strtotime($incident->incident_date)), 'incident_hour' => date('h', strtotime($incident->incident_date)), 'incident_minute' => date('i', strtotime($incident->incident_date)), 'incident_ampm' => date('a', strtotime($incident->incident_date)), 'latitude' => $incident->location->latitude, 'longitude' => $incident->location->longitude, 'location_name' => $incident->location->location_name, 'country_id' => $incident->location->country_id, 'incident_category' => $incident_category, 'incident_news' => $incident_news, 'incident_video' => $incident_video, 'incident_photo' => $incident_photo, 'person_first' => $incident->incident_person->person_first, 'person_last' => $incident->incident_person->person_last, 'person_email' => $incident->incident_person->person_email, 'custom_field' => customforms::get_custom_form_fields($id, $incident->form_id, true), 'incident_active' => $incident->incident_active, 'incident_verified' => $incident->incident_verified, 'incident_source' => $incident->incident_source, 'incident_information' => $incident->incident_information, 'incident_zoom' => $incident->incident_zoom); // Merge To Form Array For Display $form = arr::overwrite($form, $incident_arr); } else { // Redirect url::redirect('admin/reports/'); } } } $this->template->content->id = $id; $this->template->content->form = $form; $this->template->content->errors = $errors; $this->template->content->form_error = $form_error; $this->template->content->form_saved = $form_saved; // Retrieve Custom Form Fields Structure $this->template->content->custom_forms = new View('reports_submit_custom_forms'); $disp_custom_fields = customforms::get_custom_form_fields($id, $form['form_id'], FALSE, "view"); $custom_field_mismatch = customforms::get_edit_mismatch($form['form_id']); $this->template->content->custom_forms->disp_custom_fields = $disp_custom_fields; $this->template->content->custom_forms->custom_field_mismatch = $custom_field_mismatch; $this->template->content->custom_forms->form = $form; // Retrieve Previous & Next Records $previous = ORM::factory('incident')->where('id < ', $id)->orderby('id', 'desc')->find(); $previous_url = $previous->loaded ? url::base() . 'admin/reports/edit/' . $previous->id : url::base() . 'admin/reports/'; $next = ORM::factory('incident')->where('id > ', $id)->orderby('id', 'desc')->find(); $next_url = $next->loaded ? url::base() . 'admin/reports/edit/' . $next->id : url::base() . 'admin/reports/'; $this->template->content->previous_url = $previous_url; $this->template->content->next_url = $next_url; // Javascript Header $this->template->map_enabled = TRUE; $this->template->colorpicker_enabled = TRUE; $this->template->treeview_enabled = TRUE; $this->template->json2_enabled = TRUE; $this->template->js = new View('reports_submit_edit_js'); $this->template->js->edit_mode = TRUE; $this->template->js->default_map = Kohana::config('settings.default_map'); $this->template->js->default_zoom = Kohana::config('settings.default_zoom'); if (!$form['latitude'] or !$form['latitude']) { $this->template->js->latitude = Kohana::config('settings.default_lat'); $this->template->js->longitude = Kohana::config('settings.default_lon'); } else { $this->template->js->latitude = $form['latitude']; $this->template->js->longitude = $form['longitude']; } $this->template->js->incident_zoom = $form['incident_zoom']; $this->template->js->geometries = $form['geometry']; // Inline Javascript $this->template->content->date_picker_js = $this->_date_picker_js(); $this->template->content->color_picker_js = $this->_color_picker_js(); $this->template->content->new_category_toggle_js = $this->_new_category_toggle_js(); // Pack Javascript $myPacker = new javascriptpacker($this->template->js, 'Normal', false, false); $this->template->js = $myPacker->pack(); }
/** * Displays a report. * @param boolean $id If id is supplied, a report with that id will be * retrieved. */ public function view($id = FALSE) { $this->template->header->this_page = 'reports'; $this->template->content = new View('reports/detail'); // Load Akismet API Key (Spam Blocker) $api_akismet = Kohana::config('settings.api_akismet'); // Sanitize the report id before proceeding $id = intval($id); if ($id > 0) { $incident = ORM::factory('sharing_incident')->where('id', $id)->where('incident_active', 1)->find(); // Not Found if (!$incident->loaded) { url::redirect('reports/'); } // Comment Post? // Setup and initialize form field names $form = array('comment_author' => '', 'comment_description' => '', 'comment_email' => '', 'comment_ip' => '', 'captcha' => ''); $captcha = Captcha::factory(); $errors = $form; $form_error = FALSE; // Check, has the form been submitted, if so, setup validation if ($_POST and Kohana::config('settings.allow_comments')) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); // Add some rules, the input field, followed by a list of checks, carried out in order if (!$this->user) { $post->add_rules('comment_author', 'required', 'length[3,100]'); $post->add_rules('comment_email', 'required', 'email', 'length[4,100]'); } $post->add_rules('comment_description', 'required'); $post->add_rules('captcha', 'required', 'Captcha::valid'); // Test to see if things passed the rule checks if ($post->validate()) { // Yes! everything is valid if ($api_akismet != "") { // Run Akismet Spam Checker $akismet = new Akismet(); // Comment data $comment = array('website' => "", 'body' => $post->comment_description, 'user_ip' => $_SERVER['REMOTE_ADDR']); if ($this->user) { $comment['author'] = $this->user->name; $comment['email'] = $this->user->email; } else { $comment['author'] = $post->comment_author; $comment['email'] = $post->comment_email; } $config = array('blog_url' => url::site(), 'api_key' => $api_akismet, 'comment' => $comment); $akismet->init($config); if ($akismet->errors_exist()) { if ($akismet->is_error('AKISMET_INVALID_KEY')) { // throw new Kohana_Exception('akismet.api_key'); } elseif ($akismet->is_error('AKISMET_RESPONSE_FAILED')) { // throw new Kohana_Exception('akismet.server_failed'); } elseif ($akismet->is_error('AKISMET_SERVER_NOT_FOUND')) { // throw new Kohana_Exception('akismet.server_not_found'); } $comment_spam = 0; } else { $comment_spam = $akismet->is_spam() ? 1 : 0; } } else { // No API Key!! $comment_spam = 0; } $comment = new Comment_Model(); $comment->incident_id = 0; if ($this->user) { $comment->user_id = $this->user->id; $comment->comment_author = $this->user->name; $comment->comment_email = $this->user->email; } else { $comment->comment_author = strip_tags($post->comment_author); $comment->comment_email = strip_tags($post->comment_email); } $comment->comment_description = strip_tags($post->comment_description); $comment->comment_ip = $_SERVER['REMOTE_ADDR']; $comment->comment_date = date("Y-m-d H:i:s", time()); // Activate comment for now if ($comment_spam == 1) { $comment->comment_spam = 1; $comment->comment_active = 0; } else { $comment->comment_spam = 0; $comment->comment_active = Kohana::config('settings.allow_comments') == 1 ? 1 : 0; } $comment->save(); // link comment to sharing_incident $incident_comment = ORM::factory('sharing_incident_comment'); $incident_comment->comment_id = $comment->id; $incident_comment->sharing_incident_id = $incident->id; $incident_comment->save(); // Event::comment_add - Added a New Comment Event::run('ushahidi_action.comment_add', $comment); // Notify Admin Of New Comment $send = notifications::notify_admins("[" . Kohana::config('settings.site_name') . "] " . Kohana::lang('notifications.admin_new_comment.subject'), Kohana::lang('notifications.admin_new_comment.message') . "\n\n'" . utf8::strtoupper($incident->incident_title) . "'" . "\n" . url::base() . 'reports/sharing/view/' . $id); // Redirect url::redirect('reports/sharing/view/' . $id); } else { // No! We have validation errors, we need to show the form again, with the errors // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::overwrite($errors, $post->errors('comments')); $form_error = TRUE; } } // Filters $incident_title = $incident->incident_title; $incident_description = $incident->incident_description; Event::run('ushahidi_filter.report_title', $incident_title); Event::run('ushahidi_filter.report_description', $incident_description); $this->template->header->page_title .= $incident_title . Kohana::config('settings.title_delimiter'); // Add Features // hardcode geometries to empty $this->template->content->features_count = 0; $this->template->content->features = array(); $this->template->content->incident_id = $incident->id; $this->template->content->incident_title = $incident_title; $this->template->content->incident_description = $incident_description; $this->template->content->incident_location = $incident->location->location_name; $this->template->content->incident_latitude = $incident->location->latitude; $this->template->content->incident_longitude = $incident->location->longitude; $this->template->content->incident_date = date('M j Y', strtotime($incident->incident_date)); $this->template->content->incident_time = date('H:i', strtotime($incident->incident_date)); $this->template->content->incident_category = ORM::factory('sharing_incident_category')->where('sharing_incident_id', $incident->id)->find_all(); // Incident rating $rating = ORM::factory('rating')->join('incident', 'incident.id', 'rating.incident_id', 'INNER')->where('rating.incident_id', $incident->id)->find(); $this->template->content->incident_rating = $rating->rating == '' ? 0 : $rating->rating; // Retrieve Media $incident_news = array(); $incident_video = array(); $incident_photo = array(); foreach ($incident->media as $media) { if ($media->media_type == 4) { $incident_news[] = $media->media_link; } elseif ($media->media_type == 2) { $incident_video[] = $media->media_link; } elseif ($media->media_type == 1) { $incident_photo[] = array('large' => url::convert_uploaded_to_abs($media->media_link), 'thumb' => url::convert_uploaded_to_abs($media->media_thumb)); } } $this->template->content->incident_verified = $incident->incident_verified; // Retrieve Comments (Additional Information) $this->template->content->comments = ""; if (Kohana::config('settings.allow_comments')) { $this->template->content->comments = new View('reports/comments'); $incident_comments = array(); if ($id) { $incident_comments = Sharing_Incident_Model::get_comments($id); } $this->template->content->comments->incident_comments = $incident_comments; } } else { url::redirect('reports'); } // Add extra info to meta Event::add('ushahidi_action.report_display_media', array($this, 'report_display_media')); // Add Neighbors $this->template->content->incident_neighbors = Sharing_Incident_Model::get_neighbouring_incidents($id, TRUE, 0, 5); // News Source links $this->template->content->incident_news = $incident_news; // Video links $this->template->content->incident_videos = $incident_video; // Images $this->template->content->incident_photos = $incident_photo; // Create object of the video embed class $video_embed = new VideoEmbed(); $this->template->content->videos_embed = $video_embed; // Javascript Header $this->themes->map_enabled = TRUE; $this->themes->photoslider_enabled = TRUE; $this->themes->videoslider_enabled = TRUE; $this->themes->js = new View('reports/view_js'); $this->themes->js->incident_id = $incident->id; $this->themes->js->incident_json_url = 'json/share/single/' . $incident->id; $this->themes->js->default_map = Kohana::config('settings.default_map'); $this->themes->js->default_zoom = Kohana::config('settings.default_zoom'); $this->themes->js->latitude = $incident->location->latitude; $this->themes->js->longitude = $incident->location->longitude; $this->themes->js->incident_zoom = null; //$incident->incident_zoom; $this->themes->js->incident_photos = $incident_photo; // Initialize custom field array $this->template->content->custom_forms = new View('reports/detail_custom_forms'); $form_field_names = customforms::get_custom_form_fields($id, 1, FALSE, "view"); $this->template->content->custom_forms->form_field_names = $form_field_names; // Are we allowed to submit comments? $this->template->content->comments_form = ""; if (Kohana::config('settings.allow_comments')) { $this->template->content->comments_form = new View('reports/comments_form'); $this->template->content->comments_form->user = $this->user; $this->template->content->comments_form->form = $form; $this->template->content->comments_form->form_field_names = $form_field_names; $this->template->content->comments_form->captcha = $captcha; $this->template->content->comments_form->errors = $errors; $this->template->content->comments_form->form_error = $form_error; } // If the Admin is Logged in - Allow for an edit link $this->template->content->logged_in = $this->logged_in; // Rebuild Header Block $this->template->header->header_block = $this->themes->header_block(); $this->template->footer->footer_block = $this->themes->footer_block(); }
/** * Download Reports in CSV format */ public function download() { // If user doesn't have access, redirect to dashboard if (!admin::permissions($this->user, "reports_download")) { url::redirect(url::site() . 'admin/dashboard'); } $this->template->content = new View('admin/reports_download'); $this->template->content->title = Kohana::lang('ui_admin.download_reports'); $form = array('data_point' => '', 'data_include' => '', 'from_date' => '', 'to_date' => ''); $errors = $form; $form_error = FALSE; // Check, has the form been submitted, if so, setup validation if ($_POST) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); // Add some rules, the input field, followed by a list of checks, carried out in order $post->add_rules('data_point.*', 'required', 'numeric', 'between[1,4]'); //$post->add_rules('data_include.*','numeric','between[1,5]'); $post->add_rules('data_include.*', 'numeric', 'between[1,6]'); $post->add_rules('from_date', 'date_mmddyyyy'); $post->add_rules('to_date', 'date_mmddyyyy'); // Validate the report dates, if included in report filter if (!empty($_POST['from_date']) or !empty($_POST['to_date'])) { // Valid FROM Date? if (empty($_POST['from_date']) or strtotime($_POST['from_date']) > strtotime("today")) { $post->add_error('from_date', 'range'); } // Valid TO date? if (empty($_POST['to_date']) or strtotime($_POST['to_date']) > strtotime("today")) { $post->add_error('to_date', 'range'); } // TO Date not greater than FROM Date? if (strtotime($_POST['from_date']) > strtotime($_POST['to_date'])) { $post->add_error('to_date', 'range_greater'); } } // Test to see if things passed the rule checks if ($post->validate()) { // Add Filters $filter = " ( 1 !=1"; // Report Type Filter foreach ($post->data_point as $item) { if ($item == 1) { $filter .= " OR incident_active = 1 "; } if ($item == 2) { $filter .= " OR incident_verified = 1 "; } if ($item == 3) { $filter .= " OR incident_active = 0 "; } if ($item == 4) { $filter .= " OR incident_verified = 0 "; } } $filter .= ") "; // Report Date Filter if (!empty($post->from_date) and !empty($post->to_date)) { $filter .= " AND ( incident_date >= '" . date("Y-m-d H:i:s", strtotime($post->from_date)) . "' AND incident_date <= '" . date("Y-m-d H:i:s", strtotime($post->to_date)) . "' ) "; } // Retrieve reports $incidents = ORM::factory('incident')->where($filter)->orderby('incident_dateadd', 'desc')->find_all(); // Column Titles ob_start(); echo "#,INCIDENT TITLE,INCIDENT DATE"; foreach ($post->data_include as $item) { if ($item == 1) { echo ",LOCATION"; } if ($item == 2) { echo ",DESCRIPTION"; } if ($item == 3) { echo ",CATEGORY"; } if ($item == 4) { echo ",LATITUDE"; } if ($item == 5) { echo ",LONGITUDE"; } if ($item == 6) { $custom_titles = customforms::get_custom_form_fields('', '', false); foreach ($custom_titles as $field_name) { echo "," . $field_name['field_name']; } } } echo ",APPROVED,VERIFIED"; //Incase a plugin would like to add some custom fields $custom_headers = ""; Event::run('ushahidi_filter.report_download_csv_header', $custom_headers); echo $custom_headers; echo "\n"; foreach ($incidents as $incident) { echo '"' . $incident->id . '",'; echo '"' . $this->_csv_text($incident->incident_title) . '",'; echo '"' . $incident->incident_date . '"'; foreach ($post->data_include as $item) { switch ($item) { case 1: echo ',"' . $this->_csv_text($incident->location->location_name) . '"'; break; case 2: echo ',"' . $this->_csv_text($incident->incident_description) . '"'; break; case 3: echo ',"'; foreach ($incident->incident_category as $category) { if ($category->category->category_title) { echo $this->_csv_text($category->category->category_title) . ", "; } } echo '"'; break; case 4: echo ',"' . $this->_csv_text($incident->location->latitude) . '"'; break; case 5: echo ',"' . $this->_csv_text($incident->location->longitude) . '"'; break; case 6: $incident_id = $incident->id; $custom_fields = customforms::get_custom_form_fields($incident_id, '', false); if (!empty($custom_fields)) { foreach ($custom_fields as $custom_field) { echo ',"' . $this->_csv_text($custom_field['field_response']) . '"'; } } else { $custom_field = customforms::get_custom_form_fields('', '', false); foreach ($custom_field as $custom) { echo ',"' . $this->_csv_text("") . '"'; } } break; } } if ($incident->incident_active) { echo ",YES"; } else { echo ",NO"; } if ($incident->incident_verified) { echo ",YES"; } else { echo ",NO"; } //Incase a plugin would like to add some custom data for an incident $event_data = array("report_csv" => "", "incident" => $incident); Event::run('ushahidi_filter.report_download_csv_incident', $event_data); echo $event_data['report_csv']; echo "\n"; } $report_csv = ob_get_clean(); // Output to browser header("Content-type: text/x-csv"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Disposition: attachment; filename=" . time() . ".csv"); header("Content-Length: " . strlen($report_csv)); echo $report_csv; exit; } else { // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::overwrite($errors, $post->errors('report')); $form_error = TRUE; } } $this->template->content->form = $form; $this->template->content->errors = $errors; $this->template->content->form_error = $form_error; // Javascript Header $this->template->js = new View('admin/reports_download_js'); $this->template->js->calendar_img = url::base() . "media/img/icon-calendar.gif"; }
$ddoptions[$op] = $op; } } $html .= form::dropdown("custom_field[" . $field_id . ']', $ddoptions, $default, $id_name); break; } echo $html; echo "</div>"; } elseif ($field_property['field_type'] == 8) { //custom div if ($field_property['field_default'] != "") { echo "<div class=\"" . $field_property['field_default'] . "\" {$id_name}>"; } else { echo "<div class=\"custom_div\" {$id_name} >"; } $field_options = customforms::get_custom_field_options($field_id); if (isset($field_options['field_toggle']) && !isset($editor)) { if ($field_options['field_toggle'] >= 1) { echo "<script type=\"text/javascript\">\n\t\t\t\t\t\t\$(function(){\n\t\t\t\t\t\t\$('#custom_field_" . $field_id . "_link').click(function() {\n \t\t\t\t\t\t\t\$('#custom_field_" . $field_id . "_inner').toggle('slow', function() {\n \t\t\t\t\t\t// Animation complete.\n \t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t\t</script>"; echo "<a href=\"javascript:void(0);\" id=\"custom_field_" . $field_id . "_link\">"; echo "<h2>" . $field_property['field_name'] . "</h2>"; echo "</a>"; $inner_visibility = $field_options['field_toggle'] == 2 ? "none" : "visible"; echo "<div id=\"custom_field_" . $field_id . "_inner\" style=\"display:{$inner_visibility};\">"; } else { echo "<h2>" . $field_property['field_name'] . "</h2>"; echo "<div id=\"custom_field_" . $field_id . "_inner\">"; } } else { echo "<h2>" . $field_property['field_name'] . "</h2>"; echo "<div id=\"custom_field_" . $field_id . "_inner\">";
/** * Displays all reports. */ public function index() { // Cacheable Controller $this->is_cachable = TRUE; $this->template->header->this_page = 'reports'; $this->template->content = new View('reports'); $this->themes->js = new View('reports_js'); Kohana::log('info', 'decayimage::index _get_report_listing_view()'); // Store any exisitng URL parameters $this->themes->js->url_params = json_encode($_GET); // Enable the map $this->themes->map_enabled = TRUE; // Set the latitude and longitude $this->themes->js->latitude = Kohana::config('settings.default_lat'); $this->themes->js->longitude = Kohana::config('settings.default_lon'); $this->themes->js->default_map = Kohana::config('settings.default_map'); $this->themes->js->default_zoom = Kohana::config('settings.default_zoom'); // Load the alert radius view $alert_radius_view = new View('alert_radius_view'); $alert_radius_view->show_usage_info = FALSE; $alert_radius_view->enable_find_location = FALSE; $alert_radius_view->css_class = "rb_location-radius"; $this->template->content->alert_radius_view = $alert_radius_view; // Get locale $l = Kohana::config('locale.language.0'); // Get the report listing view $report_listing_view = $this->_get_report_listing_view($l); // Set the view $this->template->content->report_listing_view = $report_listing_view; // Load the category $category_id = (isset($_GET['c']) and intval($_GET['c']) > 0) ? intval($_GET['c']) : 0; $category = ORM::factory('category', $category_id); if ($category->loaded) { // Set the category title $this->template->content->category_title = Category_Lang_Model::category_title($category_id, $l); } else { $this->template->content->category_title = ""; } // Collect report stats $this->template->content->report_stats = new View('reports_stats'); // Total Reports $total_reports = Incident_Model::get_total_reports(TRUE); // Get the date of the oldest report if (isset($_GET['s']) and !empty($_GET['s']) and intval($_GET['s']) > 0) { $oldest_timestamp = intval($_GET['s']); } else { $oldest_timestamp = Incident_Model::get_oldest_report_timestamp(); } //Get the date of the latest report if (isset($_GET['e']) and !empty($_GET['e']) and intval($_GET['e']) > 0) { $latest_timestamp = intval($_GET['e']); } else { $latest_timestamp = Incident_Model::get_latest_report_timestamp(); } // Round the number of days up to the nearest full day $days_since = ceil((time() - $oldest_timestamp) / 86400); $avg_reports_per_day = $days_since < 1 ? $total_reports : round($total_reports / $days_since, 2); // Percent Verified $total_verified = Incident_Model::get_total_reports_by_verified(TRUE); $percent_verified = $total_reports == 0 ? '-' : round($total_verified / $total_reports * 100, 2) . '%'; // Category tree view $this->template->content->category_tree_view = category::get_category_tree_view(); // Additional view content $this->template->content->custom_forms_filter = new View('reports_submit_custom_forms'); $disp_custom_fields = customforms::get_custom_form_fields(); $this->template->content->custom_forms_filter->disp_custom_fields = $disp_custom_fields; $this->template->content->oldest_timestamp = $oldest_timestamp; $this->template->content->latest_timestamp = $latest_timestamp; $this->template->content->report_stats->total_reports = $total_reports; $this->template->content->report_stats->avg_reports_per_day = $avg_reports_per_day; $this->template->content->report_stats->percent_verified = $percent_verified; $this->template->content->services = Service_Model::get_array(); $this->template->header->header_block = $this->themes->header_block(); $this->template->footer->footer_block = $this->themes->footer_block(); }