/** * Use remote Ushahidi deployments API to get Incident Data * Limit to 20 not to kill remote server */ private function _parse_json($sharing_id = NULL, $sharing_url = NULL) { if (!$sharing_id or !$sharing_url) { return false; } $timeout = 5; $limit = 20; $since_id = 0; $modified_ids = array(); // this is an array of our primary keys $more_reports_to_pull = TRUE; while ($more_reports_to_pull == TRUE) { $api_url = "/api?task=incidents&limit=" . $limit . "&resp=json&orderfield=incidentid&sort=0&by=sinceid&id=" . $since_id; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, sharing_helper::clean_url($sharing_url) . $api_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $json = curl_exec($ch); curl_close($ch); $all_data = json_decode($json, false); if (!$all_data) { return false; } if (!isset($all_data->payload->incidents)) { return false; } // Parse Incidents Into Database $count = 0; foreach ($all_data->payload->incidents as $incident) { // See if this incident already exists so we can edit it $item_check = ORM::factory('sharing_incident')->where('sharing_id', $sharing_id)->where('incident_id', $incident->incident->incidentid)->find(); if ($item_check->loaded == TRUE) { $item = ORM::factory('sharing_incident', $item_check->id); } else { $item = ORM::factory('sharing_incident'); } $item->sharing_id = $sharing_id; $item->incident_id = $incident->incident->incidentid; $item->incident_title = $incident->incident->incidenttitle; $item->latitude = $incident->incident->locationlatitude; $item->longitude = $incident->incident->locationlongitude; $item->incident_date = $incident->incident->incidentdate; $item->save(); // Save the primary key of the row we touched. We will be deleting ones that weren't touched. $modified_ids[] = $item->id; // Save the highest pulled incident id so we can grab the next set from that id on $since_id = $incident->incident->incidentid; // Save count so we know if we need to pull any more reports or not $count++; } if ($count < $limit) { $more_reports_to_pull = FALSE; } } // Delete the reports that are no longer being displayed on the shared site ORM::factory('sharing_incident')->notin('id', $modified_ids)->where('sharing_id', $sharing_id)->delete_all(); }
/** * Read in new layer JSON from shared connection * @param int $sharing_id - ID of the new Share Layer */ public function index($sharing_id = FALSE) { $json = ''; $json_item = array(); $json_features = array(); $sharing_data = ""; $clustering = Kohana::config('settings.allow_clustering'); if ($sharing_id) { // Get This Sharing ID Color $sharing = ORM::factory('sharing')->find($sharing_id); if (!$sharing->loaded) { throw new Kohana_404_Exception(); } $sharing_url = sharing_helper::clean_url($sharing->sharing_url); $sharing_color = $sharing->sharing_color; if ($clustering) { // Database $db = new Database(); // Start Date $start_date = (isset($_GET['s']) and !empty($_GET['s'])) ? (int) $_GET['s'] : "0"; // End Date $end_date = (isset($_GET['e']) and !empty($_GET['e'])) ? (int) $_GET['e'] : "0"; // SouthWest Bound $southwest = (isset($_GET['sw']) and !empty($_GET['sw'])) ? $_GET['sw'] : "0"; $northeast = (isset($_GET['ne']) and !empty($_GET['ne'])) ? $_GET['ne'] : "0"; // Get Zoom Level $zoomLevel = (isset($_GET['z']) and !empty($_GET['z'])) ? (int) $_GET['z'] : 8; //$distance = 60; $distance = (10000000 >> $zoomLevel) / 100000; $filter = ""; $filter .= $start_date ? " AND incident_date >= '" . date("Y-m-d H:i:s", $start_date) . "'" : ""; $filter .= $end_date ? " AND incident_date <= '" . date("Y-m-d H:i:s", $end_date) . "'" : ""; if ($southwest and $northeast) { list($latitude_min, $longitude_min) = explode(',', $southwest); list($latitude_max, $longitude_max) = explode(',', $northeast); $filter .= " AND latitude >=" . (double) $latitude_min . " AND latitude <=" . (double) $latitude_max; $filter .= " AND longitude >=" . (double) $longitude_min . " AND longitude <=" . (double) $longitude_max; } $filter .= " AND sharing_id = " . (int) $sharing_id; $query = $db->query("SELECT * FROM `" . $this->table_prefix . "sharing_incident` WHERE 1=1 {$filter} ORDER BY incident_id ASC "); $markers = $query->result_array(FALSE); $clusters = array(); // Clustered $singles = array(); // Non Clustered // Loop until all markers have been compared while (count($markers)) { $marker = array_pop($markers); $cluster = array(); // Compare marker against all remaining markers. foreach ($markers as $key => $target) { // This function returns the distance between two markers, at a defined zoom level. // $pixels = $this->_pixelDistance($marker['latitude'], $marker['longitude'], // $target['latitude'], $target['longitude'], $zoomLevel); $pixels = abs($marker['longitude'] - $target['longitude']) + abs($marker['latitude'] - $target['latitude']); // echo $pixels."<BR>"; // If two markers are closer than defined distance, remove compareMarker from array and add to cluster. if ($pixels < $distance) { unset($markers[$key]); $target['distance'] = $pixels; $cluster[] = $target; } } // If a marker was added to cluster, also add the marker we were comparing to. if (count($cluster) > 0) { $cluster[] = $marker; $clusters[] = $cluster; } else { $singles[] = $marker; } } // Create Json foreach ($clusters as $cluster) { // Calculate cluster center $bounds = $this->calculate_center($cluster); $cluster_center = array_values($bounds['center']); $southwest = $bounds['sw']['longitude'] . ',' . $bounds['sw']['latitude']; $northeast = $bounds['ne']['longitude'] . ',' . $bounds['ne']['latitude']; // Number of Items in Cluster $cluster_count = count($cluster); $link = $sharing_url . "/reports/index/?c=0&sw=" . $southwest . "&ne=" . $northeast; $item_name = $this->get_title(Kohana::lang('ui_main.reports_count', $cluster_count), $link); $json_item = array(); $json_item['type'] = 'Feature'; $json_item['properties'] = array('name' => $item_name, 'link' => $link, 'category' => array(0), 'color' => $sharing_color, 'icon' => '', 'thumb' => '', 'timestamp' => 0, 'count' => $cluster_count); $json_item['geometry'] = array('type' => 'Point', 'coordinates' => $cluster_center); array_push($json_features, $json_item); } foreach ($singles as $single) { $link = $sharing_url . "/reports/view/" . $single['id']; $item_name = $this->get_title(html::strip_tags($single['incident_title']), $link); $json_item = array(); $json_item['type'] = 'Feature'; $json_item['properties'] = array('name' => $item_name, 'link' => $link, 'category' => array(0), 'color' => $sharing_color, 'icon' => '', 'timestamp' => 0, 'count' => 1); $json_item['geometry'] = array('type' => 'Point', 'coordinates' => array($single['longitude'], $single['latitude'])); array_push($json_features, $json_item); } } else { // Retrieve all markers $markers = ORM::factory('sharing_incident')->where('sharing_id', $sharing_id)->find_all(); foreach ($markers as $marker) { $link = $sharing_url . "/reports/view/" . $marker->incident_id; $item_name = $this->get_title($marker->incident_title, $link); $json_item = array(); $json_item['type'] = 'Feature'; $json_item['properties'] = array('id' => $marker->incident_id, 'name' => $item_name, 'link' => $link, 'color' => $sharing_color, 'icon' => '', 'timestamp' => strtotime($marker->incident_date)); $json_item['geometry'] = array('type' => 'Point', 'coordinates' => array($marker->longitude, $marker->latitude)); array_push($json_features, $json_item); } } Event::run('ushahidi_filter.json_share_features', $json_features); $json = json_encode(array("type" => "FeatureCollection", "features" => $json_features)); } header('Content-type: application/json; charset=utf-8'); echo $json; }
/** * Alter color if we're showing chared markers on main page */ public function json_alter_params() { $params = Event::$data; // Category ID $category_id = (isset($_GET['c']) and intval($_GET['c']) > 0) ? intval($_GET['c']) : 0; // We're going to assume the category id is always valid. // Get sharing site info // Check we're filtered to a single country site if (!empty($_GET['sharing'])) { if (count($_GET['sharing']) == 1 and $site_id = intval(current($_GET['sharing']))) { // Check the sharing site is active $site = ORM::factory('sharing_site')->where('site_active', 1)->find($site_id); if ($site->loaded) { $site_url = sharing_helper::clean_url($site->site_url); // Only set color if all categories, category color overrides site color if (!$category_id) { $params['color'] = $site->site_color; } $params['icon'] = ""; } } } Event::$data = $params; }
/** * Use remote Ushahidi deployments API to get Category Data */ private function _process_site_categories($site) { $modified_ids = array(); // this is an array of our primary keys $UshApiLib_Site_Info = new UshApiLib_Site_Info(sharing_helper::clean_url($site->site_url) . "/api", $site->site_username, $site->site_password); $params = new UshApiLib_Categories_Task_Parameter(); if (isset($_GET['debug']) and $_GET['debug'] == 1) { echo "<strong>Query String:</strong> " . Kohana::debug($params->get_query_string()) . "<br/><br/>"; } $task = new UshApiLib_Categories_Task($params, $UshApiLib_Site_Info); $response = $task->execute(); if ($response->getError_code()) { if (isset($_GET['debug']) and $_GET['debug'] == 1) { echo "Error Code: " . $response->getError_code() . " Message: " . $response->getError_message() . "<BR /><BR />"; } return; } // Grab existing items $existing_items = ORM::factory('sharing_category')->with('category')->where('sharing_site_id', $site->id)->find_all(); // Build array of existing items, key'd by remote id $array = array(); foreach ($existing_items as $item) { $array[$item->remote_category_id] = $item; } $existing_items = $array; // First pass - parent categories foreach ($response->getCategories() as $remote_category_id => $category_info) { $remote_category = $category_info['category']; // skip child categories if ($remote_category->parent_id != 0) { continue; } $sharing_category = $this->_save_category($remote_category_id, $category_info, $site->id, $existing_items); if (!$sharing_category) { continue; } $existing_items[$remote_category_id] = $sharing_category; // Save the primary key of the row we touched. We will be deleting ones that weren't touched. $modified_ids[] = $sharing_category->id; } // 2nd pass: child categories foreach ($response->getCategories() as $remote_category_id => $category_info) { $remote_category = $category_info['category']; // skip top level categories if ($remote_category->parent_id == 0) { continue; } // Find the sharing_category that matches the parent if (!isset($existing_items[$remote_category->parent_id])) { continue; } // Skip if parent missing $parent = $existing_items[$remote_category->parent_id]; $sharing_category = $this->_save_category($remote_category_id, $category_info, $site->id, $existing_items, $parent); if (!$sharing_category) { continue; } $existing_items[$remote_category_id] = $sharing_category; // Save the primary key of the row we touched. We will be deleting ones that weren't touched. $modified_ids[] = $sharing_category->id; } // Delete the reports that are no longer being displayed on the shared site if (count($modified_ids) > 0) { $modified_ids = array_map('intval', $modified_ids); // Hide categories when deleted/hidden on main site // We can't tell the difference between deleted/hidden from the API $result = Database::instance()->query('UPDATE category SET category_visible = 0 WHERE id IN (SELECT category_id FROM sharing_category WHERE id NOT IN (' . implode(',', $modified_ids) . ') AND sharing_site_id = ?)', $site->id); // @todo save hidden state so we only hide a category once, and it can be made visible by admin } }
function index() { $this->template->content = new View('admin/manage/sharing/main'); $this->template->content->title = Kohana::lang('ui_admin.settings'); // What to display if (isset($_GET['status']) && !empty($_GET['status'])) { $status = $_GET['status']; if (strtolower($status) == 's') { $filter = 'sharing_type = 2'; } elseif (strtolower($status) == 'r') { $filter = 'sharing_type = 1'; } else { $status = "0"; $filter = '1=1'; } } else { $status = "0"; $filter = "1=1"; } // Setup and initialize form field names $form = array('sharing_name' => '', 'sharing_url' => '', 'sharing_color' => '', 'sharing_active' => ''); // 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 = ""; if ($_POST) { $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); // Add Action if ($post->action == 'a') { // Clean the url before we do anything else $post->sharing_url = sharing_helper::clean_url($post->sharing_url); // Add some rules, the input field, followed by a list of checks, carried out in order $post->add_rules('sharing_name', 'required', 'length[3,150]'); $post->add_rules('sharing_url', 'required', 'url', 'length[3,255]'); $post->add_rules('sharing_color', 'required', 'length[6,6]'); $post->add_callbacks('sharing_url', array($this, 'url_exists_chk')); } if ($post->validate()) { $sharing_id = $post->sharing_id; $sharing = new Sharing_Model($sharing_id); // Delete Action if ($post->action == 'd') { $sharing->delete($sharing_id); $form_saved = TRUE; $form_action = utf8::strtoupper(Kohana::lang('ui_admin.deleted')); } else { if ($post->action == 'h') { if ($sharing->loaded) { $sharing->sharing_active = 0; $sharing->save(); $form_saved = TRUE; $form_action = utf8::strtoupper(Kohana::lang('ui_main.hidden')); } } else { if ($post->action == 'v') { if ($sharing->loaded) { $sharing->sharing_active = 1; $sharing->save(); $form_saved = TRUE; $form_action = utf8::strtoupper(Kohana::lang('ui_admin.shown')); } } elseif ($post->action == 'a') { $sharing->sharing_name = $post->sharing_name; $sharing->sharing_url = $post->sharing_url; $sharing->sharing_color = $post->sharing_color; $sharing->save(); $form_saved = TRUE; $form_action = utf8::strtoupper(Kohana::lang('ui_admin.created_edited')); } } } } else { // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::overwrite($errors, $post->errors('sharing')); $form_error = TRUE; } } // Pagination $pagination = new Pagination(array('query_string' => 'page', 'items_per_page' => $this->items_per_page, 'total_items' => ORM::factory('sharing')->where($filter)->count_all())); $shares = ORM::factory('sharing')->where($filter)->orderby('sharing_name', 'asc')->find_all($this->items_per_page, $pagination->sql_offset); $this->template->content->form_error = $form_error; $this->template->content->form_saved = $form_saved; $this->template->content->form_action = $form_action; $this->template->content->pagination = $pagination; $this->template->content->total_items = $pagination->total_items; $this->template->content->shares = $shares; $this->template->content->errors = $errors; // Status Tab $this->template->content->status = $status; // Javascript Header $this->template->colorpicker_enabled = TRUE; $this->template->js = new View('admin/manage/sharing/sharing_js'); }