예제 #1
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();
     // If user doesn't have access, redirect to dashboard
     if (!$this->auth->has_permission("reports_edit")) {
         url::redirect('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
     // JP: added additional form data for advanced settings
     $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_zoom' => '', 'form_data' => array());
     // 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');
     // JP: If we are editing an existing report, given by $id,
     // we need to make sure we are using the correct form id.
     // Otherwise, we use the id of the default report (1).
     if ($id and Incident_Model::is_valid_incident($id, FALSE)) {
         $form['form_id'] = ORM::factory('incident', $id)->form_id;
     } else {
         $form['form_id'] = 1;
     }
     // Initialize custom field array
     $form_id = $form['form_id'];
     $form['custom_field'] = customforms::get_custom_form_fields($id, $form_id, TRUE);
     // JP: Grab additional form information for advanced settings
     $form['form_data'] = customforms::get_custom_form($form_id);
     // Locale (Language) Array
     $this->template->content->locale_array = Kohana::config('locale.all_languages');
     // Create 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 (customforms::get_custom_forms(FALSE) 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, FALSE) ? 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 message itself have a location?
             if ($message->latitude != NULL and $message->longitude != NULL) {
                 $form['latitude'] = $message->latitude;
                 $form['longitude'] = $message->longitude;
             } elseif ($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;
             }
             // Events to manipulate an already known location
             Event::run('ushahidi_action.location_from', $message_from = $message->message_from);
             // Filter location name
             Event::run('ushahidi_filter.location_name', $form['location_name']);
             // Filter //location find
             Event::run('ushahidi_filter.location_find', $form['location_find']);
             // 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;
             }
             // HT: new code
             $feed_item_categories = ORM::factory('feed_item_category')->where('feed_item_id', $feed_item->id)->select_list('id', 'category_id');
             if ($feed_item_categories) {
                 foreach ($feed_item_categories as $feed_item_category) {
                     $form['incident_category'][] = $feed_item_category;
                 }
             }
             // HT: end of new code
         } 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, FALSE)) {
             $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
          */
         // JP: Make sure we are using the correct form ID so that the page does not revert to the default form if it is reloaded.
         $form_id = $post['form_id'];
         // JP: Ensure that the advanced settings are correct.
         $form['form_data'] = customforms::get_custom_form($form_id);
         // JP: Add the description_active boolean to our post data so the appropriate validation rules can be added
         $post['description_active'] = $form['form_data']->description_active;
         // Action::report_submit_admin - Report Posted
         Event::run('ushahidi_action.report_submit_admin', $post);
         // Validate
         if (reports::validate($post)) {
             // 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);
             // JP: Before we save the incident, we need to check if the report is currently active or inactive. (Used in step 2a.)
             $currently_active = $incident->incident_active;
             reports::save_report($post, $incident, $location->id);
             // JP: STEP 2a: If enabled, update report notifications.
             if (Kohana::config('settings.enable_report_notifications')) {
                 $active_on_form = $post->incident_active;
                 if ($currently_active != $active_on_form) {
                     if ($currently_active < $active_on_form) {
                         $action = 'a';
                     } else {
                         if ($currently_active > $active_on_form) {
                             $action = 'u';
                         }
                     }
                     reports::send_notifications($action, $incident);
                 }
             }
             // STEP 2b: Record Approval/Verification Action
             reports::verify_approve($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?
             switch ($post->save) {
                 case 1:
                 case 'dontclose':
                     // Save but don't close
                     url::redirect('admin/reports/edit/' . $incident->id . '/saved');
                     break;
                 case 'addnew':
                     // Save and add new
                     url::redirect('admin/reports/edit/0/saved');
                     break;
                 default:
                     // 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::merge($errors, $post->errors('report'));
             // JP: replace default Report Title and Description names with custom names in the error listing.
             if ($errors['incident_title'] and !empty($form['form_data']->report_title_name)) {
                 $errors['incident_title'] = str_replace(Kohana::lang('ui_main.reports_title'), $form['form_data']->report_title_name, $errors['incident_title']);
             }
             if ($errors['incident_description'] and !empty($form['form_data']->description_name)) {
                 $errors['incident_description'] = str_replace(Kohana::lang('ui_main.reports_description'), $form['form_data']->description_name, $errors['incident_description']);
             }
             $form_error = TRUE;
         }
     } else {
         if (Incident_Model::is_valid_incident($id, FALSE)) {
             // 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 = ?";
                 $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, 'custom_field' => customforms::get_custom_form_fields($id, $incident->form_id, TRUE, 'submit'), 'incident_active' => $incident->incident_active, 'incident_verified' => $incident->incident_verified, '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']);
     // 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('admin/reports/edit/' . $previous->id) : url::site('admin/reports/');
     $next = ORM::factory('incident')->where('id > ', $id)->orderby('id', 'desc')->find();
     $next_url = $next->loaded ? url::site('admin/reports/edit/' . $next->id) : url::site('admin/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 = TRUE;
     $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['latitude']) {
         $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();
     $this->template->content->new_category_toggle_js = $this->_new_category_toggle_js();
     // Pack Javascript
     $myPacker = new javascriptpacker($this->themes->js, 'Normal', FALSE, FALSE);
     $this->themes->js = $myPacker->pack();
 }