/** * 设置分组 */ public function set_batch() { if ($this->get_method() != 'POST') { $this->send_response(405, NULL, Kohana::lang('contact.method_not_exist')); } $data = $this->get_data(); $ids = !empty($data['ids']) ? explode(',', $data['ids']) : array(); $category_ids = !empty($data['category_ids']) ? explode(',', $data['category_ids']) : array(); if (empty($ids)) { $this->send_response(400, NULL, Kohana::lang('contact.contact_ids_empty')); } if ($category_ids) { $categories = $this->model->get_categories($this->user_id); if (!empty($category_ids)) { if (array_diff($category_ids, array_keys($categories))) { $this->send_response(400, NULL, Kohana::lang('contact.group_not_exist')); } } } $result = array(); $update_ids = $this->model->set_contact_category($this->user_id, $category_ids, $ids); if ($update_ids) { $now = api::get_now_time(); foreach ($update_ids as $id) { $result[] = array('id' => (int) $id, 'modified_at' => $now); } } $this->send_response(200, $result, '', FALSE); }
/** * Generates a category tree view - recursively iterates * * @return string */ public static function get_category_tree_view() { // To hold the category data $category_data = array(); // Database table prefix $table_prefix = Kohana::config('database.default.table_prefix'); // Database instance $db = new Database(); // Fetch all the top level parent categories foreach (Category_Model::get_categories() as $category) { self::_extend_category_data($category_data, $category); } // NOTES: Emmanuel Kala - Aug 5, 2011 // Initialize the report totals for the parent categories just in case // the deployment does not have sub-categories in which case the query // below won't return a result self::_init_parent_category_report_totals($category_data, $table_prefix); // Query to fetch the report totals for the parent categories $sql = "SELECT c2.id, COUNT(DISTINCT ic.incident_id) AS report_count " . "FROM " . $table_prefix . "category c, " . $table_prefix . "category c2, " . $table_prefix . "incident_category ic " . "INNER JOIN " . $table_prefix . "incident i ON (ic.incident_id = i.id) " . "WHERE (ic.category_id = c.id OR ic.category_id = c2.id) " . "AND c.parent_id = c2.id " . "AND i.incident_active = 1 " . "AND c2.category_visible = 1 " . "AND c.category_visible = 1 " . "AND c2.parent_id = 0 " . "AND c2.category_title != \"Trusted Reports\" " . "GROUP BY c2.id " . "ORDER BY c2.id ASC"; // Update the report_count field of each top-level category foreach ($db->query($sql) as $category_total) { // Check if the category exists if (array_key_exists($category_total->id, $category_data)) { // Update $category_data[$category_total->id]['report_count'] = $category_total->report_count; } } // Fetch the other categories $sql = "SELECT c.id, c.parent_id, c.category_title, c.category_color, COUNT(c.id) report_count " . "FROM " . $table_prefix . "category c " . "INNER JOIN " . $table_prefix . "incident_category ic ON (ic.category_id = c.id) " . "INNER JOIN " . $table_prefix . "incident i ON (ic.incident_id = i.id) " . "WHERE c.category_visible = 1 " . "AND i.incident_active = 1 " . "GROUP BY c.category_title " . "ORDER BY c.category_title ASC"; // Add child categories foreach ($db->query($sql) as $category) { // Extend the category data array self::_extend_category_data($category_data, $category); if (array_key_exists($category->parent_id, $category_data)) { // Add children $category_data[$category->parent_id]['children'][$category->id] = array('category_title' => $category->category_title, 'parent_id' => $category->parent_id, 'category_color' => $category->category_color, 'report_count' => $category->report_count, 'children' => array()); } } // Generate and return the HTML return self::_generate_treeview_html($category_data); }
/** * 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"; }
/** * 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"; }
/** * 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' => '', '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['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(); // 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); // Are we creating this report from a Checkin? if (isset($_GET['cid']) and !empty($_GET['cid'])) { $checkin_id = (int) $_GET['cid']; $checkin = ORM::factory('checkin', $checkin_id); if ($checkin->loaded) { // Has a report already been created for this Checkin? if ((int) $checkin->incident_id > 0) { // Redirect to report url::redirect('members/reports/edit/' . $checkin->incident_id); } $incident_description = $checkin->checkin_description; $incident_title = text::limit_chars(strip_tags($incident_description), 100, "...", true); $form['incident_title'] = $incident_title; $form['incident_description'] = $incident_description; $form['incident_date'] = date('m/d/Y', strtotime($checkin->checkin_date)); $form['incident_hour'] = date('h', strtotime($checkin->checkin_date)); $form['incident_minute'] = date('i', strtotime($checkin->checkin_date)); $form['incident_ampm'] = date('a', strtotime($checkin->checkin_date)); // Does the sender of this message have a location? if ($checkin->location->loaded) { $form['location_id'] = $checkin->location_id; $form['latitude'] = $checkin->location->latitude; $form['longitude'] = $checkin->location->longitude; $form['location_name'] = $checkin->location->location_name; } } } // 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(); 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); // If creating a report from a checkin if (isset($checkin_id) and $checkin_id != "") { $checkin = ORM::factory('checkin', $checkin_id); if ($checkin->loaded) { $checkin->incident_id = $incident->id; $checkin->save(); // Attach all the media items in this checkin to the report foreach ($checkin->media as $media) { $media->incident_id = $incident->id; $media->save(); } } } // Action::report_add / report_submit_members - Added a New Report //++ Do we need two events for this? Or will one suffice? //Event::run('ushahidi_action.report_add', $incident); Event::run('ushahidi_action.report_submit_members', $post); // 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=" . $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, '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 $disp_custom_fields = customforms::get_custom_form_fields($id, $form['form_id'], FALSE); $this->template->content->disp_custom_fields = $disp_custom_fields; // Retrieve Previous & Next Records $previous = ORM::factory('incident')->where('id < ', $id)->orderby('id', 'desc')->find(); $previous_url = $previous->loaded ? url::base() . 'members/reports/edit/' . $previous->id : url::base() . 'members/reports/'; $next = ORM::factory('incident')->where('id > ', $id)->orderby('id', 'desc')->find(); $next_url = $next->loaded ? url::base() . 'members/reports/edit/' . $next->id : url::base() . 'members/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 = FALSE; $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(); // Pack Javascript $myPacker = new javascriptpacker($this->template->js, 'Normal', FALSE, FALSE); $this->template->js = $myPacker->pack(); }
function index() { $this->template->content = new View('admin/manage/actions/main'); $this->template->content->title = Kohana::lang('ui_admin.actions'); $this->template->map_enabled = TRUE; $this->template->treeview_enabled = TRUE; $this->template->js = new View('admin/manage/actions/actions_js'); $this->template->js->default_map = Kohana::config('settings.default_map'); $this->template->js->default_zoom = Kohana::config('settings.default_zoom'); $this->template->js->latitude = Kohana::config('settings.default_lat'); $this->template->js->longitude = Kohana::config('settings.default_lon'); // TODO: Figure out what to do with this $this->template->js->incident_zoom = array(); $this->template->js->geometries = array(); $trigger_options = $this->_trigger_options(); $response_options = $this->_response_options(); $trigger_advanced_options = $this->_trigger_advanced_options(); $advanced_option_areas = $this->_advanced_option_areas(); $response_advanced_options = $this->_response_advanced_options(); $response_advanced_option_areas = $this->_response_advanced_option_areas(); $trigger_allowed_responses = $this->_trigger_allowed_responses(); // Setup and initialize form field names $form = array('geometry' => '', 'action_trigger' => '', 'action_user' => '', 'action_location_specific' => '', 'action_keywords' => '', 'action_category' => array(), 'action_on_specific_count' => '', 'action_on_specific_count_collective' => '', 'action_days_of_the_week' => array(), 'action_specific_days' => array(), 'action_between_times_hour_1' => '', 'action_between_times_hour_2' => '', 'action_between_times_minute_1' => '', 'action_between_times_minute_2' => '', 'action_response' => '', 'action_email_send_address' => '', 'action_email_send_address_specific' => '', 'action_email_subject' => '', 'action_email_body' => '', 'action_add_category' => array(), 'action_verify' => '', 'action_badge' => ''); // Process form submission if ($_POST) { $post = Validation::factory($_POST); // Trim all of the fields to get rid of errant spaces $post->pre_filter('trim', TRUE); $expected_qualifier_fields = $trigger_advanced_options[$post['action_trigger']]; $expected_response_fields = $response_advanced_options[$post['action_response']]; $expected_fileds = array_merge($expected_qualifier_fields, $expected_response_fields); // Since our form is dynamic, we need to set validation dynamically foreach ($expected_fileds as $field) { $this->_form_field_rules($field, $post); } if ($post->validate()) { $qualifiers = array(); foreach ($expected_qualifier_fields as $field) { $form_field = 'action_' . $field; // 1. Standard field population if (isset($post->{$form_field})) { $qualifiers[$field] = $post->{$form_field}; } // 2. Check additional field population // Populate additional geometry field if ($field == 'location' && $post->{$form_field} == 'specific') { // Add geometry if this is a specific location $qualifiers['geometry'] = $post->geometry; } // Populate additional specific count collective boolean if ($field == 'on_specific_count') { // Grab if we are counting everyone or just the individual users themselves $qualifiers['on_specific_count_collective'] = $post->action_on_specific_count_collective; } // Change the specific_days field to an array of timestamps if ($field == 'specific_days') { // Grab if we are counting everyone or just the individual users themselves $qualifiers['specific_days'] = explode(',', $qualifiers['specific_days']); foreach ($qualifiers['specific_days'] as $key => $specific_day) { $qualifiers['specific_days'][$key] = strtotime($specific_day); } if ($qualifiers['specific_days'][0] == false) { // Just get rid of it if we aren't using it unset($qualifiers['specific_days']); } } // Grab dropdowns for between_times if ($field == 'between_times') { // Do everything for between times here if ($post->action_between_times_hour_1 != 0 or $post->action_between_times_minute_1 != 0 or $post->action_between_times_hour_2 != 0 or $post->action_between_times_minute_2 != 0) { // We aren't all zeroed out so the user is not ignoring between_times. Now we need // to calculate seconds into the day for each and put the lower count in the first // variable and the higher in the second so the check in the hook doesn't have to // do so much work. Also, set between_times to true so the hook knows to check it. $qualifiers['between_times'] = 1; $time1 = (int) $post->action_between_times_hour_1 * 3600 + (int) $post->action_between_times_minute_1 * 60; $time2 = (int) $post->action_between_times_hour_2 * 3600 + (int) $post->action_between_times_minute_2 * 60; if ($time1 < $time2) { $qualifiers['between_times_1'] = $time1; $qualifiers['between_times_2'] = $time2; } else { $qualifiers['between_times_1'] = $time2; $qualifiers['between_times_2'] = $time1; } } else { // Between_times is being ignored, set it that way here $qualifiers['between_times'] = 0; } } } $qualifiers = serialize($qualifiers); $response_vars = array(); foreach ($expected_response_fields as $field) { $form_field = 'action_' . $field; if (isset($post->{$form_field})) { $r_var = $post->{$form_field}; if ($field == 'email_send_address' and $post->{$form_field} == '1') { // Then set as the specific email address so we know where to send it $r_var = $post->action_email_send_address_specific; } // This is the array we're building to pass on the data we need // to perform the response when qualifiers are all passed $response_vars[$field] = $r_var; } } $response_vars = serialize($response_vars); $action = ORM::factory('actions'); $action->action = $post->action_trigger; $action->qualifiers = $qualifiers; $action->response = $post->action_response; $action->response_vars = $response_vars; $action->active = 1; $action->save(); } else { // TODO: Proper Validation $errors = $post->errors(); foreach ($errors as $key => $val) { echo $key . ' failed rule ' . $val . '<br />'; } } } // 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 = FALSE; $form_action = ""; $sharing_id = ""; // Defined actions by the user that already exist in the system $this->template->content->actions = $this->_get_actions(); $this->template->content->total_items = $this->template->content->actions->count(); $this->template->content->trigger_options = $trigger_options; $this->template->content->response_options = $response_options; $this->template->content->trigger_advanced_options = $trigger_advanced_options; $this->template->content->advanced_option_areas = $advanced_option_areas; $this->template->content->response_advanced_options = $response_advanced_options; $this->template->content->response_advanced_option_areas = $response_advanced_option_areas; $this->template->content->trigger_allowed_responses = $trigger_allowed_responses; // Build user options list $this->template->content->user_options = $this->_user_options(); // Grab categories for category advanced options $this->template->content->categories = Category_Model::get_categories(0, FALSE, FALSE); // Grab badges for dropdown $this->template->content->badges = Badge_Model::badge_names(); // Timezone $this->template->content->site_timezone = Kohana::config('settings.site_timezone'); // Days of the week $this->template->content->days = array('mon' => Kohana::lang('datetime.monday.full'), 'tue' => Kohana::lang('datetime.tuesday.full'), 'wed' => Kohana::lang('datetime.wednesday.full'), 'thu' => Kohana::lang('datetime.thursday.full'), 'fri' => Kohana::lang('datetime.friday.full'), 'sat' => Kohana::lang('datetime.saturday.full'), 'sun' => Kohana::lang('datetime.sunday.full')); $this->template->content->form = $form; $this->template->content->form_error = $form_error; $this->template->content->form_saved = $form_saved; $this->template->content->form_action = $form_action; $this->template->content->errors = $errors; // Enable date picker $this->template->datepicker_enabled = TRUE; }
/** * 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_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(0, TRUE, FALSE); $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; } //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; } } 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_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(); }
public function index() { // First, are we allowed to subscribe for alerts via web? if (!Kohana::config('settings.allow_alerts')) { url::redirect(url::site() . 'main'); } $this->template->header->this_page = $this->themes->this_page = 'alerts'; $this->template->content = new View('alerts'); // Load the alert radius map view $alert_radius_view = new View('alert_radius_view'); $alert_radius_view->show_usage_info = TRUE; $alert_radius_view->enable_find_location = TRUE; $this->template->content->alert_radius_view = $alert_radius_view; // Display Mobile Option? $this->template->content->show_mobile = TRUE; $settings = ORM::factory('settings', 1); if (!Kohana::config("settings.sms_provider")) { // Hide Mobile $this->template->content->show_mobile = FALSE; } // Retrieve default country, latitude, longitude $default_country = Kohana::config('settings.default_country'); // Retrieve Country Cities $this->template->content->cities = $this->_get_cities($default_country); // Get all active top level categories $this->template->content->categories = Category_Model::get_categories(0, FALSE, TRUE); // Setup and initialize form field names $form = array('alert_mobile' => '', 'alert_mobile_yes' => '', 'alert_email' => '', 'alert_email_yes' => '', 'alert_lat' => '', 'alert_lon' => '', 'alert_radius' => '', 'alert_country' => '', 'alert_confirmed' => ''); if ($this->user) { $form['alert_email'] = $this->user->email; } // 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 Alert confirmed hidden value $this->template->content->countries = $countries; // 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 = FALSE; // If there is a post and $_POST is not empty if ($post = $this->input->post()) { $alert_orm = new Alert_Model(); if ($alert_orm->validate($post)) { // Yes! everything is valid // Save alert and send out confirmation code if (!empty($post->alert_mobile)) { alert::_send_mobile_alert($post, $alert_orm); $this->session->set('alert_mobile', $post->alert_mobile); } if (!empty($post->alert_email)) { alert::_send_email_alert($post, $alert_orm); $this->session->set('alert_email', $post->alert_email); } url::redirect('alerts/confirm'); } else { // repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // populate the error fields, if any $errors = arr::overwrite($errors, $post->errors('alerts')); if (array_key_exists('alert_recipient', $post->errors('alerts'))) { $errors = array_merge($errors, $post->errors('alerts')); } $form_error = TRUE; } } else { $form['alert_lat'] = Kohana::config('settings.default_lat'); $form['alert_lon'] = Kohana::config('settings.default_lon'); $form['alert_radius'] = 20; $form['alert_category'] = array(); } $this->template->content->form_error = $form_error; // Initialize Default Value for Hidden Field Country Name, just incase Reverse Geo coding yields no result $form['alert_country'] = $countries[$default_country]; $this->template->content->form = $form; $this->template->content->errors = $errors; $this->template->content->form_saved = $form_saved; // Javascript Header $this->themes->map_enabled = TRUE; $this->themes->js = new View('alerts_js'); $this->themes->treeview_enabled = TRUE; $this->themes->js->default_map = Kohana::config('settings.default_map'); $this->themes->js->default_zoom = Kohana::config('settings.default_zoom'); $this->themes->js->latitude = $form['alert_lat']; $this->themes->js->longitude = $form['alert_lon']; // Rebuild Header Block $this->template->header->header_block = $this->themes->header_block(); $this->template->footer->footer_block = $this->themes->footer_block(); }