/** * Test the is_valid_category method in Category_Model using a * valid category id * * @test * @dataProvider providerIsValidCategory * @param int $valid_category_id ID of a category exisitng in the database * @param int $invalid_category_id ID of a non-existent/non-numeric category */ public function testIsValidCategory($valid_category_id, $invalid_category_id) { // Test existence of valid category $this->assertEquals(TRUE, Category_Model::is_valid_category($valid_category_id)); // Assert invalidity and non-existence of invalid category $this->assertEquals(FALSE, Category_Model::is_valid_category($invalid_category_id)); }
/** * Generate geojson * * @param string $type type of geojson to generate. Valid options are: 'clusters' and 'markers' **/ protected function geojson($type) { $color = Kohana::config('settings.default_map_all'); $icon = ""; $markers = FALSE; if (Kohana::config('settings.default_map_all_icon_id')) { $icon_object = ORM::factory('media')->find(Kohana::config('settings.default_map_all_icon_id')); $icon = url::convert_uploaded_to_abs($icon_object->media_medium); } // Category ID $category_id = (isset($_GET['c']) and intval($_GET['c']) > 0) ? intval($_GET['c']) : 0; // Get the category colour if (Category_Model::is_valid_category($category_id)) { // Get the color & icon $cat = ORM::factory('category', $category_id); $color = $cat->category_color; $icon = ""; if ($cat->category_image) { $icon = url::convert_uploaded_to_abs($cat->category_image); } } $params = array('color' => $color, 'icon' => $icon); Event::run('ushahidi_filter.json_alter_params', $params); $color = $params['color']; $icon = $params['icon']; // Run event ushahidi_filter.json_replace_markers // This allows a plugin to completely replace $markers // If markers are added at this point we don't bother fetching incidents at all Event::run('ushahidi_filter.json_replace_markers', $markers); // Fetch the incidents if (!$markers) { $markers = (isset($_GET['page']) and intval($_GET['page']) > 0) ? reports::fetch_incidents(TRUE) : reports::fetch_incidents(); } // Run event ushahidi_filter.json_alter_markers // This allows a plugin to alter $markers // Plugins can add or remove markers as needed Event::run('ushahidi_filter.json_alter_markers', $markers); // Get geojson features array $function = "{$type}_geojson"; $json_features = $this->{$function}($markers, $category_id, $color, $icon); $this->render_geojson($json_features); }
/** * Get incidents within a certain lat,lon bounding box * * @param sw is the southwest lat,lon of the box * @param ne is the northeast lat,lon of the box * @param c is the categoryid */ private function _get_incidents_by_bounds($sw, $ne, $c = 0) { // Get location_ids if we are to filter by location $location_ids = array(); // Break apart location variables, if necessary $southwest = array(); if (isset($sw)) { $southwest = explode(",",$sw); } $northeast = array(); if (isset($ne)) { $northeast = explode(",",$ne); } if ( count($southwest) == 2 AND count($northeast) == 2 ) { $lon_min = (float) $southwest[0]; $lon_max = (float) $northeast[0]; $lat_min = (float) $southwest[1]; $lat_max = (float) $northeast[1]; $query = 'SELECT id FROM '.$this->table_prefix.'location WHERE latitude >='.$lat_min.' AND latitude <='.$lat_max.' AND longitude >='.$lon_min.' AND longitude <='.$lon_max; $items = $this->db->query($query); foreach ( $items as $item ) { $location_ids[] = $item->id; } } $location_id_in = '1=1'; if (count($location_ids) > 0) { $location_id_in = 'l.id IN ('.implode(',',$location_ids).')'; } $where = ' WHERE i.incident_active = 1 AND '.$location_id_in.' '; // Fix for pulling categories using the bounding box // Credits to Antonoio Lettieri http://github.com/alettieri // Check if the specified category id is valid if (Category_Model::is_valid_category($c)) { // Filter incidents by the specified category $join = "\nINNER JOIN ".$this->table_prefix."incident_category AS ic ON ic.incident_id = i.id "; $join .= "\nINNER JOIN ".$this->table_prefix."category AS c ON c.id=ic.category_id "; // Overwrite the current where clause in $where $where = $join."\nWHERE c.id = $c AND i.incident_active = 1 AND $location_id_in"; } $sortby = " GROUP BY i.id ORDER BY $this->order_field $this->sort"; $limit = " LIMIT 0, $this->list_limit"; return $this->_get_incidents($where.$sortby, $limit); }
/** * Get incidents within a certain lat,lon bounding box * * @param double $sw is the southwest lat,lon of the box * @param double $ne is the northeast lat,lon of the box * @param int $c is the categoryid * @return string XML or JSON string containing the fetched incidents */ private function _get_incidents_by_bounds($sw, $ne, $c = 0) { // Break apart location variables, if necessary $southwest = array(); if (isset($sw)) { $southwest = explode(",", $sw); } $northeast = array(); if (isset($ne)) { $northeast = explode(",", $ne); } // To hold the parameters $params = array(); if (count($southwest) == 2 and count($northeast) == 2) { $lon_min = (double) $southwest[0]; $lon_max = (double) $northeast[0]; $lat_min = (double) $southwest[1]; $lat_max = (double) $northeast[1]; // Add parameters array_push($params, 'l.latitude >= ' . $lat_min, 'l.latitude <= ' . $lat_max, 'l.longitude >= ' . $lon_min, 'l.longitude <= ' . $lon_max); } // Fix for pulling categories using the bounding box // Credits to Antonoio Lettieri http://github.com/alettieri // Check if the specified category id is valid if (Category_Model::is_valid_category($c)) { array_push($params, 'c.id = ' . $c); } return $this->_get_incidents($params); }
/** * Generate JSON in CLUSTER mode */ public function cluster() { // Database $db = new Database(); $json = ""; $json_item = ""; $json_array = array(); $geometry_array = array(); $color = Kohana::config('settings.default_map_all'); $icon = ""; // Get Zoom Level $zoomLevel = (isset($_GET['z']) and !empty($_GET['z'])) ? (int) $_GET['z'] : 8; //$distance = 60; $distance = (10000000 >> $zoomLevel) / 100000; // Fetch the incidents using the specified parameters $incidents = reports::fetch_incidents(); // Category ID $category_id = (isset($_GET['c']) and intval($_GET['c']) > 0) ? intval($_GET['c']) : 0; // Start date $start_date = (isset($_GET['s']) and intval($_GET['s']) > 0) ? intval($_GET['s']) : NULL; // End date $end_date = (isset($_GET['e']) and intval($_GET['e']) > 0) ? intval($_GET['e']) : NULL; if (Category_Model::is_valid_category($category_id)) { // Get the color $color = ORM::factory('category', $category_id)->category_color; } // Create markers by marrying the locations and incidents $markers = array(); foreach ($incidents as $incident) { $markers[] = array('id' => $incident->incident_id, 'incident_title' => $incident->incident_title, 'latitude' => $incident->latitude, 'longitude' => $incident->longitude, 'thumb' => ''); } $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']); // 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->_calculateCenter($cluster); $cluster_center = $bounds['center']; $southwest = $bounds['sw']; $northeast = $bounds['ne']; // Number of Items in Cluster $cluster_count = count($cluster); // Get the time filter $time_filter = (!empty($start_date) and !empty($end_date)) ? "&s=" . $start_date . "&e=" . $end_date : ""; // Build out the JSON string $json_item = "{"; $json_item .= "\"type\":\"Feature\","; $json_item .= "\"properties\": {"; $json_item .= "\"name\":\"" . str_replace(chr(10), ' ', str_replace(chr(13), ' ', "<a href=" . url::base() . "reports/index/?c=" . $category_id . "&sw=" . $southwest . "&ne=" . $northeast . $time_filter . ">" . $cluster_count . " Reports</a>")) . "\","; $json_item .= "\"link\": \"" . url::base() . "reports/index/?c=" . $category_id . "&sw=" . $southwest . "&ne=" . $northeast . $time_filter . "\", "; $json_item .= "\"category\":[0], "; $json_item .= "\"color\": \"" . $color . "\", "; $json_item .= "\"icon\": \"" . $icon . "\", "; $json_item .= "\"thumb\": \"\", "; $json_item .= "\"timestamp\": \"0\", "; $json_item .= "\"count\": \"" . $cluster_count . "\""; $json_item .= "},"; $json_item .= "\"geometry\": {"; $json_item .= "\"type\":\"Point\", "; $json_item .= "\"coordinates\":[" . $cluster_center . "]"; $json_item .= "}"; $json_item .= "}"; array_push($json_array, $json_item); } foreach ($singles as $single) { $json_item = "{"; $json_item .= "\"type\":\"Feature\","; $json_item .= "\"properties\": {"; $json_item .= "\"name\":\"" . str_replace(chr(10), ' ', str_replace(chr(13), ' ', "<a href=" . url::base() . "reports/view/" . $single['id'] . "/>" . str_replace('"', '\\"', $single['incident_title']) . "</a>")) . "\","; $json_item .= "\"link\": \"" . url::base() . "reports/view/" . $single['id'] . "\", "; $json_item .= "\"category\":[0], "; $json_item .= "\"color\": \"" . $color . "\", "; $json_item .= "\"icon\": \"" . $icon . "\", "; // $json_item .= "\"thumb\": \"".$single['thumb']."\", "; $json_item .= "\"timestamp\": \"0\", "; $json_item .= "\"count\": \"" . 1 . "\""; $json_item .= "},"; $json_item .= "\"geometry\": {"; $json_item .= "\"type\":\"Point\", "; $json_item .= "\"coordinates\":[" . $single['longitude'] . ", " . $single['latitude'] . "]"; $json_item .= "}"; $json_item .= "}"; array_push($json_array, $json_item); } $json = implode(",", $json_array); // // E.Kala July 27, 2011 // @todo Parking this geometry business for review // // if (count($geometry_array)) // { // $json = implode(",", $geometry_array).",".$json; // } header('Content-type: application/json; charset=utf-8'); $this->template->json = $json; }
/** * Add Edit Categories */ public function index() { $this->template->content = new View('admin/categories'); $this->template->content->title = Kohana::lang('ui_admin.categories'); // Locale (Language) Array $locales = locale::get_i18n(); // Setup and initialize form field names $form = array('action' => '', 'category_id' => '', 'parent_id' => '', 'category_title' => '', 'category_description' => '', 'category_color' => '', 'category_image' => '', 'category_image_thumb' => ''); // Add the different language form keys for fields foreach ($locales as $lang_key => $lang_name) { $form['category_title_' . $lang_key] = ''; } // 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 = ""; $parents_array = array(); // Check, has the form been submitted, if so, setup validation if ($_POST) { // Fetch the post data $post_data = array_merge($_POST, $_FILES); // Extract category-specific information $category_data = arr::extract($post_data, 'parent_id', 'category_title', 'category_description', 'category_color'); // Extract category image and category languages for independent validation $secondary_data = arr::extract($post_data, 'category_image', 'category_title_lang', 'action'); // Setup validation for the secondary data $post = Validation::factory($secondary_data)->pre_filter('trim', TRUE); // Add validation for the add/edit action if ($post->action == 'a') { $post->add_rules('category_image', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[50K]'); // Add the different language form keys for fields foreach ($locales as $lang_key => $lang_name) { $post->add_rules('category_title_lang[' . $lang_key . ']', 'length[3,80]'); } } // Category instance for the operation $category = (!empty($_POST['category_id']) and Category_Model::is_valid_category($_POST['category_id'])) ? new Category_Model($_POST['category_id']) : new Category_Model(); // Check the specified action if ($post->action == 'a') { // Test to see if things passed the rule checks if ($category->validate($category_data) and $post->validate()) { // Save the category $category->save(); // Get the category localization $languages = $category->loaded ? Category_Lang_Model::category_langs($category->id) : FALSE; $category_lang = isset($languages[$category->id]) ? $languages[$category->id] : FALSE; // Save localizations foreach ($post->category_title_lang as $lang_key => $localized_category_name) { $cl = isset($category_lang[$lang_key]['id']) ? ORM::factory('category_lang', $category_lang[$lang_key]['id']) : ORM::factory('category_lang'); $cl->category_title = $localized_category_name; $cl->locale = $lang_key; $cl->category_id = $category->id; $cl->save(); } // Upload Image/Icon $filename = upload::save('category_image'); if ($filename) { $new_filename = "category_" . $category->id . "_" . time(); // Resize Image to 32px if greater Image::factory($filename)->resize(32, 32, Image::HEIGHT)->save(Kohana::config('upload.directory', TRUE) . $new_filename . ".png"); // Create a 16x16 version too Image::factory($filename)->resize(16, 16, Image::HEIGHT)->save(Kohana::config('upload.directory', TRUE) . $new_filename . "_16x16.png"); // Remove the temporary file unlink($filename); // Delete Old Image $category_old_image = $category->category_image; if (!empty($category_old_image) and file_exists(Kohana::config('upload.directory', TRUE) . $category_old_image)) { unlink(Kohana::config('upload.directory', TRUE) . $category_old_image); } // Save $category->category_image = $new_filename . ".png"; $category->category_image_thumb = $new_filename . "_16x16.png"; $category->save(); } $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.added_edited')); // Empty $form array array_fill_keys($form, ''); } else { // Validation failed // Repopulate the form fields $form = arr::overwrite($form, array_merge($category_data->as_array(), $post->as_array())); // populate the error fields, if any $errors = arr::overwrite($errors, array_merge($category_data->errors('category'), $post->errors('category'))); $form_error = TRUE; } } elseif ($post->action == 'd') { // Delete action if ($category->loaded) { ORM::factory('category_lang')->where(array('category_id' => $category->id))->delete_all(); // @todo Delete the category image // Delete category itself - except if it is trusted ORM::factory('category')->where('category_trusted != 1')->delete($category->id); $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.deleted')); } } elseif ($post->action == 'v') { // Show/Hide Action if ($category->loaded) { $category->category_visible = $category->category_visible == 1 ? 0 : 1; $category->save(); $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.modified')); } } elseif ($post->action == 'i') { // Delete Image/Icon Action if ($category->loaded) { $category_image = $category->category_image; $category_image_thumb = $category->category_image_thumb; if (!empty($category_image) and file_exists(Kohana::config('upload.directory', TRUE) . $category_image)) { unlink(Kohana::config('upload.directory', TRUE) . $category_image); } if (!empty($category_image_thumb) and file_exists(Kohana::config('upload.directory', TRUE) . $category_image_thumb)) { unlink(Kohana::config('upload.directory', TRUE) . $category_image_thumb); } $category->category_image = NULL; $category->category_image_thumb = NULL; $category->save(); $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.modified')); } } } // Pagination $pagination = new Pagination(array('query_string' => 'page', 'items_per_page' => $this->items_per_page, 'total_items' => ORM::factory('category')->where('parent_id', '0')->count_all())); $categories = ORM::factory('category')->with('category_lang')->where('parent_id', '0')->orderby('category_position', 'asc')->orderby('category_title', 'asc')->find_all($this->items_per_page, $pagination->sql_offset); $parents_array = ORM::factory('category')->where('parent_id', '0')->select_list('id', 'category_title'); // add none to the list $parents_array[0] = "--- Top Level Category ---"; // Put "--- Top Level Category ---" at the top of the list ksort($parents_array); $this->template->content->form = $form; $this->template->content->errors = $errors; $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->categories = $categories; $this->template->content->parents_array = $parents_array; // Javascript Header $this->template->colorpicker_enabled = TRUE; $this->template->tablerowsort_enabled = TRUE; $this->template->js = new View('admin/categories_js'); $this->template->form_error = $form_error; $this->template->content->locale_array = $locales; $this->template->js->locale_array = $locales; }
/** * Add Edit Categories */ public function index() { $this->template->content = new View('admin/categories'); $this->template->content->title = Kohana::lang('ui_admin.categories'); // Locale (Language) Array $locales = ush_locale::get_i18n(); // Setup and initialize form field names $form = array('action' => '', 'category_id' => '', 'parent_id' => '', 'category_title' => '', 'category_description' => '', 'category_color' => '', 'category_image' => '', 'category_image_thumb' => '', 'form_auth_token' => ''); // Add the different language form keys for fields foreach ($locales as $lang_key => $lang_name) { $form['category_title_' . $lang_key] = ''; } // 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 = ""; $parents_array = array(); // Check, has the form been submitted, if so, setup validation if ($_POST) { // Fetch the post data $post_data = array_merge($_POST, $_FILES); // Extract category-specific information $category_data = arr::extract($post_data, 'parent_id', 'category_title', 'category_description', 'category_color'); // Extract category image and category languages for independent validation $secondary_data = arr::extract($post_data, 'category_image', 'category_title_lang', 'action'); // Setup validation for the secondary data $post = Validation::factory($secondary_data)->pre_filter('trim', TRUE); // Add validation for the add/edit action if ($post->action == 'a') { $post->add_rules('category_image', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[50K]'); // Add the different language form keys for fields foreach ($locales as $lang_key => $lang_name) { $post->add_rules('category_title_lang[' . $lang_key . ']', 'length[3,80]'); } } // Category instance for the operation $category = (!empty($_POST['category_id']) and Category_Model::is_valid_category($_POST['category_id'])) ? new Category_Model($_POST['category_id']) : new Category_Model(); // Check the specified action if ($post->action == 'a') { // Test to see if things passed the rule checks if ($category->validate($category_data) and $post->validate(FALSE)) { // Save the category $category->save(); // Get the category localization $languages = $category->loaded ? Category_Lang_Model::category_langs($category->id) : FALSE; $category_lang = isset($languages[$category->id]) ? $languages[$category->id] : FALSE; // Save localizations foreach ($post->category_title_lang as $lang_key => $localized_category_name) { $cl = isset($category_lang[$lang_key]['id']) ? ORM::factory('category_lang', $category_lang[$lang_key]['id']) : ORM::factory('category_lang'); $cl->category_title = $localized_category_name; $cl->locale = $lang_key; $cl->category_id = $category->id; $cl->save(); } // Upload Image/Icon $filename = upload::save('category_image'); if ($filename) { $new_filename = "category_" . $category->id . "_" . time(); // Name the files for the DB $cat_img_file = $new_filename . ".png"; $cat_img_thumb_file = $new_filename . "_16x16.png"; // Resize Image to 32px if greater Image::factory($filename)->resize(32, 32, Image::HEIGHT)->save(Kohana::config('upload.directory', TRUE) . $cat_img_file); // Create a 16x16 version too Image::factory($filename)->resize(16, 16, Image::HEIGHT)->save(Kohana::config('upload.directory', TRUE) . $cat_img_thumb_file); // Okay, now we have these three different files on the server, now check to see // if we should be dropping them on the CDN if (Kohana::config("cdn.cdn_store_dynamic_content")) { $cat_img_file = cdn::upload($cat_img_file); $cat_img_thumb_file = cdn::upload($cat_img_thumb_file); // We no longer need the files we created on the server. Remove them. $local_directory = rtrim(Kohana::config('upload.directory', TRUE), '/') . '/'; unlink($local_directory . $new_filename . ".png"); unlink($local_directory . $new_filename . "_16x16.png"); } // Remove the temporary file unlink($filename); // Delete Old Image $category_old_image = $category->category_image; if (!empty($category_old_image)) { if (file_exists(Kohana::config('upload.directory', TRUE) . $category_old_image)) { unlink(Kohana::config('upload.directory', TRUE) . $category_old_image); } elseif (Kohana::config("cdn.cdn_store_dynamic_content") and valid::url($category_old_image)) { cdn::delete($category_old_image); } } // Save $category->category_image = $cat_img_file; $category->category_image_thumb = $cat_img_thumb_file; $category->save(); Event::run('ushahidi_action.category_save', $post); } $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.added_edited')); // Empty $form array array_fill_keys($form, ''); } else { // Validation failed // Repopulate the form fields $form = arr::overwrite($form, array_merge($category_data->as_array(), $post->as_array())); // populate the error fields, if any $errors = arr::overwrite($errors, array_merge($category_data->errors('category'), $post->errors('category'))); $form_error = TRUE; } } elseif ($post->action == 'd' and $post->validate()) { // Delete action if ($category->loaded) { ORM::factory('category_lang')->where(array('category_id' => $category->id))->delete_all(); // Check for all subcategories tied to this category and make them top level $children = ORM::factory('category')->where('parent_id', $category->id)->find_all(); if ($children) { foreach ($children as $child) { $sub_cat = new Category_Model($child->id); $sub_cat->parent_id = 0; $sub_cat->save(); } } // Check for all reports tied to this category to be deleted $result = ORM::factory('incident_category')->where('category_id', $category->id)->find_all(); // If there are reports returned by the query if ($result) { foreach ($result as $orphan) { $orphan_incident_id = $orphan->incident_id; // Check if the report is tied to any other category $count = ORM::factory('incident_category')->where('incident_id', $orphan_incident_id)->count_all(); // If this report is tied to only one category(is uncategorized) if ($count == 1) { // Assign it to the special category for uncategorized reports $orphaned = ORM::factory('incident_category', $orphan->id); $orphaned->category_id = 5; $orphaned->save(); // Deactivate the report so that it's not accessible on the frontend $orphaned_report = ORM::factory('incident', $orphan_incident_id); $orphaned_report->incident_active = 0; $orphaned_report->save(); } else { ORM::factory('incident_category')->delete($orphan->id); } } } // @todo Delete the category image // Delete category itself - except if it is trusted ORM::factory('category')->where('category_trusted != 1')->delete($category->id); $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.deleted')); } } elseif ($post->action == 'v' and $post->validate()) { // Show/Hide Action if ($category->loaded) { // Check for all subcategories tied to this category $children = ORM::factory('category')->where('parent_id', $category->id)->find_all(); // Then show/hide subcategories based on status of parent category foreach ($children as $child) { $sub_cat = new Category_Model($child->id); $sub_cat->category_visible = $category->category_visible == 1 ? 0 : 1; $sub_cat->save(); } // Change status of the Parent Category $category->category_visible = $category->category_visible == 1 ? 0 : 1; $category->save(); $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.modified')); } } elseif ($post->action == 'i' and $post->validate()) { // Delete Image/Icon Action if ($category->loaded) { $category_image = $category->category_image; $category_image_thumb = $category->category_image_thumb; // Delete the main image if (!empty($category_image) and file_exists(Kohana::config('upload.directory', TRUE) . $category_image)) { unlink(Kohana::config('upload.directory', TRUE) . $category_image); } // Delete the thumb if (!empty($category_image_thumb) and file_exists(Kohana::config('upload.directory', TRUE) . $category_image_thumb)) { unlink(Kohana::config('upload.directory', TRUE) . $category_image_thumb); } $category->category_image = NULL; $category->category_image_thumb = NULL; $category->save(); $form_saved = TRUE; $form_action = strtoupper(Kohana::lang('ui_admin.modified')); } } } // Pagination $pagination = new Pagination(array('query_string' => 'page', 'items_per_page' => $this->items_per_page, 'total_items' => ORM::factory('category')->where('parent_id', '0')->count_all())); $categories = ORM::factory('category')->with('category_lang')->where('parent_id', '0')->orderby('category_title', 'asc')->find_all($this->items_per_page, $pagination->sql_offset); $parents_array = ORM::factory('category')->where('parent_id', '0')->where('category_trusted != 1')->select_list('id', 'category_title'); // add none to the list $parents_array[0] = "--- Top Level Category ---"; // Put "--- Top Level Category ---" at the top of the list ksort($parents_array); $this->template->content->form = $form; $this->template->content->errors = $errors; $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->categories = $categories; $this->template->content->parents_array = $parents_array; // Javascript Header $this->template->colorpicker_enabled = TRUE; $this->template->tablerowsort_enabled = TRUE; $this->template->js = new View('admin/categories_js'); $this->template->form_error = $form_error; $this->template->content->locale_array = $locales; $this->template->js->locale_array = $locales; }
/** * Get incidents within a certain lat,lon bounding box * * @param sw is the southwest lat,lon of the box * @param ne is the northeast lat,lon of the box * @param c is the categoryid */ private function _get_incidents_by_bounds($sw, $ne, $c = 0, $keyword = "") { // Get location_ids if we are to filter by location $location_ids = array(); // Break apart location variables, if necessary $southwest = array(); if (isset($sw)) { $southwest = explode(",", $sw); } $northeast = array(); if (isset($ne)) { $northeast = explode(",", $ne); } if (count($southwest) == 2 and count($northeast) == 2) { $lon_min = (double) $southwest[0]; $lon_max = (double) $northeast[0]; $lat_min = (double) $southwest[1]; $lat_max = (double) $northeast[1]; $query = 'SELECT id FROM ' . $this->table_prefix . 'location WHERE latitude >=' . $lat_min . ' AND latitude <=' . $lat_max . ' AND longitude >=' . $lon_min . ' AND longitude <=' . $lon_max; $items = $this->db->query($query); foreach ($items as $item) { $location_ids[] = $item->id; } } $location_id_in = '1=1'; if (count($location_ids) > 0) { $location_id_in = 'l.id IN (' . implode(',', $location_ids) . ')'; } $keyword_raw = isset($keyword) ? mysql_real_escape_string($keyword) : ""; $keyword_raw = strip_tags($keyword_raw); $keyword_raw = Input::instance()->xss_clean($keyword_raw); $keywords = explode(' ', $keyword_raw); $match = ""; if (is_array($keywords) && !empty($keywords) && $keyword_raw != "") { $match = " MATCH(i.incident_title,i.incident_description) AGAINST(\"*D+1:2,2:1 {$keyword_raw}\" IN BOOLEAN MODE) AND"; } $where = ' WHERE ' . $match . ' i.incident_active = 1 AND ' . $location_id_in . ' '; // Fix for pulling categories using the bounding box // Credits to Antonoio Lettieri http://github.com/alettieri // Check if the specified category id is valid if (Category_Model::is_valid_category($c)) { // Filter incidents by the specified category $join = "\nINNER JOIN " . $this->table_prefix . "incident_category AS ic ON ic.incident_id = i.id "; $join .= "\nINNER JOIN " . $this->table_prefix . "category AS c ON c.id=ic.category_id "; // Overwrite the current where clause in $where $where = $join . "\nWHERE {$match} c.id = {$c} AND i.incident_active = 1 AND {$location_id_in}"; } $sortby = " GROUP BY i.id ORDER BY {$this->order_field} {$this->sort}"; $limit = " LIMIT {$this->list_offset}, {$this->list_limit}"; return $this->_get_incidents($where . $sortby, $limit); }
/** * Generate JSON in CLUSTER mode */ public function cluster() { // Database $db = new Database(); $json = ''; $json_item = array(); $json_features = array(); $geometry_array = array(); $color = Kohana::config('settings.default_map_all'); $icon = ""; if (Kohana::config('settings.default_map_all_icon_id')) { $icon_object = ORM::factory('media')->find(Kohana::config('settings.default_map_all_icon_id')); $icon = url::convert_uploaded_to_abs($icon_object->media_medium); } // Get Zoom Level $zoomLevel = (isset($_GET['z']) and !empty($_GET['z'])) ? (int) $_GET['z'] : 8; //$distance = 60; $distance = (10000000 >> $zoomLevel) / 100000; // Fetch the incidents using the specified parameters $incidents = reports::fetch_incidents(); // Category ID $category_id = (isset($_GET['c']) and intval($_GET['c']) > 0) ? intval($_GET['c']) : 0; // Start date $start_date = (isset($_GET['s']) and intval($_GET['s']) > 0) ? intval($_GET['s']) : NULL; // End date $end_date = (isset($_GET['e']) and intval($_GET['e']) > 0) ? intval($_GET['e']) : NULL; if (Category_Model::is_valid_category($category_id)) { // Get the color & icon $cat = ORM::factory('category', $category_id); $color = $cat->category_color; if ($cat->category_image) { $icon = url::convert_uploaded_to_abs($cat->category_image); } } // Create markers by marrying the locations and incidents $markers = array(); foreach ($incidents as $incident) { $markers[] = array('id' => $incident->incident_id, 'incident_title' => $incident->incident_title, 'latitude' => $incident->latitude, 'longitude' => $incident->longitude, 'thumb' => ''); } $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']); // 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); // Get the time filter $time_filter = (!empty($start_date) and !empty($end_date)) ? "&s=" . $start_date . "&e=" . $end_date : ""; // Build out the JSON string $link = url::base() . "reports/index/?c=" . $category_id . "&sw=" . $southwest . "&ne=" . $northeast . $time_filter; $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($category_id), 'color' => $color, 'icon' => $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 = url::base() . "reports/view/" . $single['id']; $item_name = $this->get_title($single['incident_title'], $link); $json_item = array(); $json_item['type'] = 'Feature'; $json_item['properties'] = array('name' => $item_name, 'link' => $link, 'category' => array($category_id), 'color' => $color, 'icon' => $icon, 'thumb' => '', 'timestamp' => 0, 'count' => 1); $json_item['geometry'] = array('type' => 'Point', 'coordinates' => array($single['longitude'], $single['latitude'])); array_push($json_features, $json_item); } // // E.Kala July 27, 2011 // @todo Parking this geometry business for review // // if (count($geometry_array)) // { // $json = implode(",", $geometry_array).",".$json; // } Event::run('ushahidi_filter.json_cluster_features', $json_features); $json = json_encode(array("type" => "FeatureCollection", "features" => $json_features)); header('Content-type: application/json; charset=utf-8'); echo $json; }
public function _is_valid_category(Validation $array, $field) { // If category_id == 0 then it is the default decayimage icon if (!Category_Model::is_valid_category($array[$field]) && $array[$field] != 0) { $array->add_error($field, 'category_id'); } }