PageRenderTime 54ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/simplegroups/controllers/admin/simplegroups/reports.php

https://github.com/fayazv/Taarifa_Web
PHP | 2072 lines | 1542 code | 277 blank | 253 comment | 243 complexity | db5cd95d3921decab9f34a21d67264f9 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-3.0, BSD-3-Clause, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Reports Controller.
  4. * This controller will take care of adding and editing reports in the Admin section.
  5. *
  6. * PHP version 5
  7. * LICENSE: This source file is subject to LGPL license
  8. * that is available through the world-wide-web at the following URI:
  9. * http://www.gnu.org/copyleft/lesser.html
  10. * @author Ushahidi Team <team@ushahidi.com>
  11. * @package Ushahidi - http://source.ushahididev.com
  12. * @module Admin Reports Controller
  13. * @copyright Ushahidi - http://www.ushahidi.com
  14. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License (LGPL)
  15. */
  16. class Reports_Controller extends Admin_simplegroup_Controller {
  17. function __construct() {
  18. parent::__construct();
  19. $this->template->this_page = 'reports';
  20. }
  21. /**
  22. * Lists the reports.
  23. * @param int $page
  24. */
  25. function index($page = 1) {
  26. $this->template->content = new View('simplegroups/reports');
  27. $this->template->content->title = Kohana::lang('ui_admin.reports');
  28. // check, has the form been submitted?
  29. $form_error = FALSE;
  30. $form_saved = FALSE;
  31. $form_action = "";
  32. $this->handle_post_variables();
  33. $db = new Database;
  34. $this->template->content = $this->setup_report_table($this->template->content);
  35. $this->template->content->form_error = $form_error;
  36. $this->template->content->form_saved = $form_saved;
  37. $this->template->content->form_action = $form_action;
  38. $this->template->content->category_array = $this->setup_category_dropdown_filter();
  39. // Status Tab
  40. if (!empty($_GET['status'])) {
  41. $status = $_GET['status'];
  42. }
  43. else {
  44. $status = 'all';
  45. }
  46. $this->template->content->status = $status;
  47. // Javascript Header
  48. $this->template->js = new View('simplegroups/reports_js');
  49. }
  50. //creates the table of messages
  51. private function setup_report_table($view) {
  52. /////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. //Setup the filters and such.
  54. if (!empty($_GET['status'])) {
  55. $status = strtolower($_GET['status']);
  56. // Verified
  57. if ($status == 'v') {
  58. $filter = 'incident.incident_status = 1';
  59. }
  60. // In triage (been verified)
  61. elseif ($status == 't') {
  62. $filter = 'incident.incident_status = 2';
  63. }
  64. // Assigned / being fixed
  65. elseif ($status == 'f') {
  66. $filter = 'incident.incident_status = 3';
  67. }
  68. // In dispute
  69. elseif ($status == 'd') {
  70. $filter = 'incident.incident_status = 4';
  71. }
  72. // Finished
  73. elseif($status == 'e') {
  74. $filter = 'incident.incident_status = 5';
  75. }
  76. else {
  77. $status = "0";
  78. $filter = '1=1';
  79. }
  80. }
  81. else {
  82. $status = "0";
  83. $filter = "1=1";
  84. }
  85. // Get Search Keywords (If Any)
  86. if (isset($_GET['k']))
  87. {
  88. // Brute force input sanitization
  89. // Phase 1 - Strip the search string of all non-word characters
  90. $keyword_raw = preg_replace('/[^\w+]\w*/', '', $_GET['k']);
  91. // Strip any HTML tags that may have been missed in Phase 1
  92. $keyword_raw = strip_tags($keyword_raw);
  93. // Phase 3 - Invoke Kohana's XSS cleaning mechanism just incase an outlier wasn't caught
  94. // in the first 2 steps
  95. $keyword_raw = $this->input->xss_clean($keyword_raw);
  96. $filter .= " AND (".$this->_get_searchstring($keyword_raw).")";
  97. }
  98. else {
  99. $keyword_raw = "";
  100. }
  101. // Category ID
  102. $category_ids=array();
  103. if( isset($_GET['c']) AND ! empty($_GET['c']) ) {
  104. $category_ids = explode(",", $_GET['c']); //get rid of that trailing ","
  105. }
  106. else {
  107. $category_ids = array("0");
  108. }
  109. // logical operator
  110. $logical_operator = "or";
  111. if( isset($_GET['lo']) AND ! empty($_GET['lo']) ) {
  112. $logical_operator = $_GET['lo'];
  113. }
  114. $show_unapproved="3"; //1 show only approved, 2 show only unapproved, 3 show all
  115. //figure out if we're showing unapproved stuff or what.
  116. if (isset($_GET['u']) AND !empty($_GET['u'])) {
  117. $show_unapproved = (int) $_GET['u'];
  118. }
  119. $approved_text = "";
  120. if($show_unapproved == 1) {
  121. $approved_text = "incident.incident_active = 1 ";
  122. }
  123. else if ($show_unapproved == 2) {
  124. $approved_text = "incident.incident_active = 0 ";
  125. }
  126. else if ($show_unapproved == 3) {
  127. $approved_text = " (incident.incident_active = 0 OR incident.incident_active = 1) ";
  128. }
  129. // Start Date
  130. $start_date = (isset($_GET['s']) AND !empty($_GET['s'])) ? (int) $_GET['s'] : "0";
  131. // End Date
  132. $end_date = (isset($_GET['e']) AND !empty($_GET['e'])) ? (int) $_GET['e'] : "0";
  133. $filter .= ($start_date) ? " AND incident.incident_date >= '" . date("Y-m-d H:i:s", $start_date) . "'" : "";
  134. $filter .= ($end_date) ? " AND incident.incident_date <= '" . date("Y-m-d H:i:s", $end_date) . "'" : "";
  135. $location_where = "";
  136. // Break apart location variables, if necessary
  137. $southwest = array();
  138. if (isset($_GET['sw'])) {
  139. $southwest = explode(",",$_GET['sw']);
  140. }
  141. $northeast = array();
  142. if (isset($_GET['ne'])) {
  143. $northeast = explode(",",$_GET['ne']);
  144. }
  145. if ( count($southwest) == 2 AND count($northeast) == 2 ) {
  146. $lon_min = (float) $southwest[0];
  147. $lon_max = (float) $northeast[0];
  148. $lat_min = (float) $southwest[1];
  149. $lat_max = (float) $northeast[1];
  150. $location_where = ' AND (location.latitude >='.$lat_min.' AND location.latitude <='.$lat_max.' AND location.longitude >='.$lon_min.' AND location.longitude <='.$lon_max.') ';
  151. }
  152. $group_where = " (simplegroups_groups_incident.simplegroups_groups_id = ".$this->group->id.") ";
  153. ////////////////////////////////////////////////////////////////////////////////////////////
  154. //Get the incidents and the number of incidents
  155. $reports_count = groups::get_reports_count($category_ids, $approved_text, $location_where. " AND ". $filter. " AND ". $group_where
  156. , $logical_operator);
  157. // Pagination
  158. $pagination = new Pagination(array(
  159. 'directory' => 'simplegroups/pagination',
  160. 'style' => 'ajax_classic',
  161. 'query_string' => 'page',
  162. 'items_per_page' => (int) Kohana::config('settings.items_per_page_admin'),
  163. 'total_items' => $reports_count
  164. ));
  165. $incidents = groups::get_reports($category_ids, $approved_text, $location_where. " AND ". $filter. " AND ". $group_where,
  166. $logical_operator,
  167. "incident.incident_date", "DESC",
  168. (int) Kohana::config('settings.items_per_page_admin'), $pagination->sql_offset
  169. );
  170. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  171. //Setup the Location information for each incident
  172. $location_ids = array();
  173. foreach ($incidents as $incident) {
  174. $location_ids[] = $incident->location_id;
  175. }
  176. //check if location_ids is not empty
  177. if( count($location_ids ) > 0 ) {
  178. $locations_result = ORM::factory('location')->in('id',implode(',',$location_ids))->find_all();
  179. $locations = array();
  180. foreach ($locations_result as $loc) {
  181. $locations[$loc->id] = $loc->location_name;
  182. }
  183. }
  184. else {
  185. $locations = array();
  186. }
  187. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  188. //use this to make a mapping of simplegroup categories to reports
  189. $incidents_ids = array();
  190. foreach($incidents as $incident) {
  191. $incidents_ids[] = $incident->id;
  192. }
  193. $category_mapping = array();
  194. //make sure there are some messages
  195. if(count($incidents_ids) > 0) {
  196. $incident_categories = ORM::factory('simplegroups_category')
  197. ->select("simplegroups_category.*, simplegroups_incident_category.incident_id AS incident_id")
  198. ->join('simplegroups_incident_category', 'simplegroups_category.id', 'simplegroups_incident_category.simplegroups_category_id')
  199. ->in("simplegroups_incident_category.incident_id", implode(',', $incidents_ids))
  200. ->where('simplegroups_category.simplegroups_groups_id', $this->group->id)
  201. ->find_all();
  202. foreach($incident_categories as $incident_category) {
  203. $category_mapping[$incident_category->incident_id][] = $incident_category;
  204. }
  205. }
  206. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  207. //Gets a list of countries to better specify the location
  208. $countries = array();
  209. foreach (ORM::factory('country')->orderby('country')->find_all() as $country) {
  210. // Create a list of all categories
  211. $this_country = $country->country;
  212. if (strlen($this_country) > 35)
  213. {
  214. $this_country = substr($this_country, 0, 35) . "...";
  215. }
  216. $countries[$country->id] = $this_country;
  217. }
  218. $view->locations = $locations;
  219. $view->category_mapping = $category_mapping;
  220. $view->countries = $countries;
  221. $view->incidents = $incidents;
  222. $view->pagination = $pagination;
  223. $view->total_items = $pagination->total_items;
  224. return $view;
  225. }//end of setup_report_table
  226. private function setup_category_dropdown_filter()
  227. {
  228. //create category array for drop down filter list
  229. $category_array = array(0=>"Show All");
  230. $category_array[strtoupper("---".$this->group->name." Categories---")] = array();
  231. $categories = ORM::factory('simplegroups_category')
  232. ->where('simplegroups_groups_id', $this->group->id)
  233. ->where('applies_to_report', 1)
  234. ->where('parent_id', 0)
  235. ->find_all();
  236. foreach($categories as $category)
  237. {
  238. //first, check and see if we're dealing with a kid category
  239. if ($category->children->count() > 0)
  240. {
  241. $parent_array = array();
  242. foreach ($category->children as $child)
  243. {
  244. $parent_array["sg_".$child->id] = $child->category_title;
  245. }
  246. $category_array[$category->category_title] = $parent_array;
  247. }
  248. else
  249. {
  250. $category_array["sg_".$category->id] = $category->category_title;
  251. }
  252. }//end loop
  253. $category_array["---GLOBAL CATEGORIES---"] = array();
  254. $categories = ORM::factory('category')->find_all();
  255. foreach($categories as $category)
  256. {
  257. //first, check and see if we're dealing with a kid category
  258. if ($category->children->count() > 0)
  259. {
  260. $parent_array = array();
  261. foreach ($category->children as $child)
  262. {
  263. $parent_array[$child->id] = $child->category_title;
  264. }
  265. $category_array[$category->category_title] = $parent_array;
  266. }
  267. else
  268. {
  269. $category_array[$category->id] = $category->category_title;
  270. }
  271. }//end loop
  272. return $category_array;
  273. }
  274. // ajax call to delete the group
  275. function delete($gid, $pid) {
  276. if(request::is_ajax()) {
  277. $this->template->content= "othing yet";
  278. /* $this->auto_render = false; //Disable the auto renderer, we don want a layout in our ajax response
  279. $result = ORM::factory('simplegroups_groups_incident', (int) $id)->delete(); //delete the group
  280. echo json_encode($result); //return a json encoded result */
  281. }
  282. else {
  283. $this->template->content= "othing yet";
  284. }
  285. }
  286. //ajax calls to updated the report list come in here
  287. function get_table()
  288. {
  289. $this->template = "";
  290. $this->auto_render = FALSE;
  291. $this->handle_post_variables();
  292. $table_view = View::factory('simplegroups/reports/reports_table');
  293. $table_view = $this->setup_report_table($table_view);
  294. $table_view->render(TRUE);
  295. }//end get_table()
  296. private function handle_post_variables()
  297. {
  298. if ($_POST)
  299. {
  300. $post = Validation::factory($_POST);
  301. // Add some filters
  302. $post->pre_filter('trim', TRUE);
  303. // Add some rules, the input field, followed by a list of checks, carried out in order
  304. $post->add_rules('action','required', 'alpha', 'length[1,1]');
  305. $post->add_rules('incident_id.*','required','numeric');
  306. if ($post->validate())
  307. {
  308. if ($post->action == 'a') // Approve Action
  309. {
  310. foreach($post->incident_id as $item)
  311. {
  312. $update = new Incident_Model($item);
  313. if ($update->loaded == true)
  314. {
  315. if( $update->incident_active == 0 )
  316. {
  317. $update->incident_active = '1';
  318. }
  319. else {
  320. $update->incident_active = '0';
  321. }
  322. // Tag this as a report that needs to be sent out as an alert
  323. if ($update->incident_alert_status != '2')
  324. { // 2 = report that has had an alert sent
  325. $update->incident_alert_status = '1';
  326. }
  327. $update->save();
  328. $verify = new Verify_Model();
  329. $verify->incident_id = $item;
  330. $verify->verified_status = '1';
  331. $verify->user_id = $_SESSION['auth_user']->id; // Record 'Verified By' Action
  332. $verify->verified_date = date("Y-m-d H:i:s",time());
  333. $verify->save();
  334. // Action::report_approve - Approve a Report
  335. Event::run('ushahidi_action.report_approve', $update);
  336. }
  337. }
  338. $form_action = strtoupper(Kohana::lang('ui_admin.approved'));
  339. }
  340. elseif ($post->action == 'u') // Unapprove Action
  341. {
  342. foreach($post->incident_id as $item)
  343. {
  344. $update = new Incident_Model($item);
  345. if ($update->loaded == true) {
  346. $update->incident_active = '0';
  347. // If Alert hasn't been sent yet, disable it
  348. if ($update->incident_alert_status == '1')
  349. {
  350. $update->incident_alert_status = '0';
  351. }
  352. $update->save();
  353. $verify = new Verify_Model();
  354. $verify->incident_id = $item;
  355. $verify->verified_status = '0';
  356. $verify->user_id = $_SESSION['auth_user']->id; // Record 'Verified By' Action
  357. $verify->verified_date = date("Y-m-d H:i:s",time());
  358. $verify->save();
  359. // Action::report_unapprove - Unapprove a Report
  360. Event::run('ushahidi_action.report_unapprove', $update);
  361. }
  362. }
  363. $form_action = strtoupper(Kohana::lang('ui_admin.unapproved'));
  364. }
  365. elseif ($post->action == 'v') // Verify Action
  366. {
  367. foreach($post->incident_id as $item)
  368. {
  369. $update = new Incident_Model($item);
  370. $verify = new Verify_Model();
  371. if ($update->loaded == true) {
  372. if ($update->incident_verified == '1')
  373. {
  374. $update->incident_verified = '0';
  375. $verify->verified_status = '0';
  376. }
  377. else {
  378. $update->incident_verified = '1';
  379. $verify->verified_status = '2';
  380. }
  381. $update->save();
  382. $verify->incident_id = $item;
  383. $verify->user_id = $_SESSION['auth_user']->id; // Record 'Verified By' Action
  384. $verify->verified_date = date("Y-m-d H:i:s",time());
  385. $verify->save();
  386. }
  387. }
  388. $form_action = "VERIFIED";
  389. }
  390. elseif ($post->action == 'd') //Delete Action
  391. {
  392. foreach($post->incident_id as $item)
  393. {
  394. $update = new Incident_Model($item);
  395. if ($update->loaded == true)
  396. {
  397. $incident_id = $update->id;
  398. //Just delete the association with the group and the incident, don't delete the
  399. //incident itself. You never know when you might need it.
  400. ORM::factory("simplegroups_groups_incident")
  401. ->where('incident_id',$incident_id)
  402. ->where('simplegroups_groups_id', $this->group->id)
  403. ->delete_all();
  404. }
  405. }
  406. $form_action = strtoupper(Kohana::lang('ui_admin.deleted'));
  407. }
  408. $form_saved = TRUE;
  409. }
  410. else
  411. {
  412. $form_error = TRUE;
  413. }
  414. }
  415. }//end method
  416. /**
  417. * Edit a report
  418. * @param bool|int $id The id no. of the report
  419. * @param bool|string $saved
  420. */
  421. function edit( $id = false, $saved = false ) {
  422. $db = new Database();
  423. $this->template->content = new View('admin/reports_edit');
  424. $this->template->content = View::factory('simplegroups/reports_edit');
  425. $this->template->content->title = Kohana::lang('ui_admin.create_report');
  426. // setup and initialize form field names
  427. $form = array(
  428. 'location_id' => '',
  429. 'form_id' => '',
  430. 'locale' => '',
  431. 'incident_title' => '',
  432. 'incident_description' => '',
  433. 'incident_date' => '',
  434. 'incident_hour' => '',
  435. 'incident_minute' => '',
  436. 'incident_ampm' => '',
  437. 'latitude' => '',
  438. 'longitude' => '',
  439. 'geometry' => array(),
  440. 'location_name' => '',
  441. 'country_id' => '',
  442. 'incident_category' => array(),
  443. 'incident_group_category' => array(),
  444. 'incident_news' => array(),
  445. 'incident_video' => array(),
  446. 'incident_photo' => array(),
  447. 'incident_status' => array(),
  448. 'phone_number' => '',
  449. 'person_first' => '',
  450. 'person_last' => '',
  451. 'person_email' => '',
  452. 'custom_field' => array(),
  453. 'incident_active' => '',
  454. 'incident_verified' => '',
  455. //'incident_source' => '',
  456. //'incident_information' => '',
  457. 'incident_zoom' => ''
  458. );
  459. // copy the form as errors, so the errors will be stored with keys corresponding to the form field names
  460. $errors = $form;
  461. $form_error = FALSE;
  462. $form_saved = $saved;
  463. // Initialize Default Values
  464. $form['locale'] = Kohana::config('locale.language');
  465. //$form['latitude'] = Kohana::config('settings.default_lat');
  466. //$form['longitude'] = Kohana::config('settings.default_lon');
  467. $form['country_id'] = Kohana::config('settings.default_country');
  468. $form['incident_date'] = date("m/d/Y",time());
  469. $form['incident_hour'] = date('h');
  470. $form['incident_minute'] = date('i');
  471. $form['incident_ampm'] = date('a');
  472. // initialize custom field array
  473. $form['custom_field'] = $this->_get_custom_form_fields($id,'',true);
  474. $number_of_message_sender = null;
  475. // Locale (Language) Array
  476. $this->template->content->locale_array = Kohana::config('locale.all_languages');
  477. // Create Categories
  478. $this->template->content->categories = $this->_get_categories();
  479. $this->template->content->group_categories = $this->_get_group_categories();
  480. $this->template->content->new_categories_form = $this->_new_categories_form_arr();
  481. $this->template->content->group_name = $this->group->name;
  482. // Time formatting
  483. $this->template->content->hour_array = $this->_hour_array();
  484. $this->template->content->minute_array = $this->_minute_array();
  485. $this->template->content->ampm_array = $this->_ampm_array();
  486. $this->template->content->stroke_width_array = $this->_stroke_width_array();
  487. // Get Countries
  488. $countries = array();
  489. foreach (ORM::factory('country')->orderby('country')->find_all() as $country) {
  490. // Create a list of all categories
  491. $this_country = $country->country;
  492. if (strlen($this_country) > 35)
  493. {
  494. $this_country = substr($this_country, 0, 35) . "...";
  495. }
  496. $countries[$country->id] = $this_country;
  497. }
  498. $this->template->content->countries = $countries;
  499. //GET custom forms
  500. $forms = array();
  501. foreach (ORM::factory('form')->where('form_active',1)->find_all() as $custom_forms)
  502. {
  503. $forms[$custom_forms->id] = $custom_forms->form_title;
  504. }
  505. $this->template->content->forms = $forms;
  506. // Retrieve thumbnail photos (if edit);
  507. //XXX: fix _get_thumbnails
  508. $this->template->content->incident = $this->_get_thumbnails($id);
  509. // Are we creating this report from SMS/Email/Twitter?
  510. // If so retrieve message
  511. if ( isset($_GET['mid']) && !empty($_GET['mid']) ) {
  512. $message_id = $_GET['mid'];
  513. $service_id = "";
  514. $message = ORM::factory('message', $message_id);
  515. //figure out the group number that sent the message
  516. $number_items = ORM::factory("simplegroups_groups_number")
  517. ->join("simplegroups_groups_message", "simplegroups_groups_message.number_id", "simplegroups_groups_numbers.id")
  518. ->where("simplegroups_groups_message.message_id", $message_id)
  519. ->find_all();
  520. foreach($number_items as $number_item) {
  521. $number_of_message_sender = $number_item;
  522. }
  523. if ($message->loaded == true && $message->message_type == 1) {
  524. $service_id = $message->reporter->service_id;
  525. // Has a report already been created for this Message?
  526. if ($message->incident_id != 0) {
  527. // Redirect to report
  528. url::redirect('admin/simplegroups/reports/edit/'. $message->incident_id);
  529. }
  530. $this->template->content->show_messages = true;
  531. $incident_description = $message->message;
  532. if (!empty($message->message_detail)) {
  533. $incident_description .= "\n\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n"
  534. . $message->message_detail;
  535. }
  536. $form['incident_description'] = $incident_description;
  537. $form['incident_date'] = date('m/d/Y', strtotime($message->message_date));
  538. $form['incident_hour'] = date('h', strtotime($message->message_date));
  539. $form['incident_minute'] = date('i', strtotime($message->message_date));
  540. $form['incident_ampm'] = date('a', strtotime($message->message_date));
  541. $form['person_first'] = $message->reporter->reporter_first;
  542. $form['person_last'] = $message->reporter->reporter_last;
  543. // Does the sender of this message have a location?
  544. if ($message->reporter->location->loaded) {
  545. $form['latitude'] = $message->reporter->location->latitude;
  546. $form['longitude'] = $message->reporter->location->longitude;
  547. $form['location_name'] = $message->reporter->location->location_name;
  548. }
  549. // Retrieve Last 5 Messages From this account
  550. $this->template->content->all_messages = ORM::factory('message')
  551. ->where('reporter_id', $message->reporter_id)
  552. ->orderby('message_date', 'desc')
  553. ->limit(5)
  554. ->find_all();
  555. }
  556. else {
  557. $message_id = "";
  558. $this->template->content->show_messages = false;
  559. }
  560. }
  561. else {
  562. $this->template->content->show_messages = false;
  563. }
  564. // Are we creating this report from a Newsfeed?
  565. if ( isset($_GET['fid']) && !empty($_GET['fid']) )
  566. {
  567. $feed_item_id = $_GET['fid'];
  568. $feed_item = ORM::factory('feed_item', $feed_item_id);
  569. if ($feed_item->loaded == true)
  570. {
  571. // Has a report already been created for this Feed item?
  572. if ($feed_item->incident_id != 0)
  573. {
  574. // Redirect to report
  575. url::redirect('admin/simplegroups/reports/edit/'. $feed_item->incident_id);
  576. }
  577. $form['incident_title'] = $feed_item->item_title;
  578. $form['incident_description'] = $feed_item->item_description;
  579. $form['incident_date'] = date('m/d/Y', strtotime($feed_item->item_date));
  580. $form['incident_hour'] = date('h', strtotime($feed_item->item_date));
  581. $form['incident_minute'] = date('i', strtotime($feed_item->item_date));
  582. $form['incident_ampm'] = date('a', strtotime($feed_item->item_date));
  583. // News Link
  584. $form['incident_news'][0] = $feed_item->item_link;
  585. // Does this newsfeed have a geolocation?
  586. if ($feed_item->location_id)
  587. {
  588. $form['location_id'] = $feed_item->location_id;
  589. $form['latitude'] = $feed_item->location->latitude;
  590. $form['longitude'] = $feed_item->location->longitude;
  591. $form['location_name'] = $feed_item->location->location_name;
  592. }
  593. }
  594. else
  595. {
  596. $feed_item_id = "";
  597. }
  598. }
  599. // check, has the form been submitted, if so, setup validation
  600. if ($_POST)
  601. {
  602. // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things
  603. $post = Validation::factory(array_merge($_POST,$_FILES));
  604. // Add some filters
  605. $post->pre_filter('trim', TRUE);
  606. // Add some rules, the input field, followed by a list of checks, carried out in order
  607. // $post->add_rules('locale','required','alpha_dash','length[5]');
  608. $post->add_rules('location_id','numeric');
  609. $post->add_rules('message_id','numeric');
  610. $post->add_rules('incident_title','required', 'length[3,200]');
  611. $post->add_rules('incident_description','required');
  612. $post->add_rules('incident_status','required');
  613. $post->add_rules('incident_date','required','date_mmddyyyy');
  614. $post->add_rules('incident_hour','required','between[1,12]');
  615. $post->add_rules('incident_minute','required','between[0,59]');
  616. if ($_POST['incident_ampm'] != "am" && $_POST['incident_ampm'] != "pm")
  617. {
  618. $post->add_error('incident_ampm','values');
  619. }
  620. $post->add_rules('latitude','required','between[-90,90]'); // Validate for maximum and minimum latitude values
  621. $post->add_rules('longitude','required','between[-180,180]'); // Validate for maximum and minimum longitude values
  622. $post->add_rules('location_name','required', 'length[3,200]');
  623. //XXX: Hack to validate for no checkboxes checked
  624. if (!isset($_POST['incident_category'])) {
  625. $post->incident_category = "";
  626. $post->add_error('incident_category','required');
  627. }
  628. else
  629. {
  630. $post->add_rules('incident_category.*','required','numeric');
  631. }
  632. // Validate only the fields that are filled in
  633. if (!empty($_POST['incident_news']))
  634. {
  635. foreach ($_POST['incident_news'] as $key => $url) {
  636. if (!empty($url) AND !(bool) filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED))
  637. {
  638. $post->add_error('incident_news','url');
  639. }
  640. }
  641. }
  642. // Validate only the fields that are filled in
  643. if (!empty($_POST['incident_video']))
  644. {
  645. foreach ($_POST['incident_video'] as $key => $url) {
  646. if (!empty($url) AND !(bool) filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED))
  647. {
  648. $post->add_error('incident_video','url');
  649. }
  650. }
  651. }
  652. // Validate photo uploads
  653. $post->add_rules('incident_photo', 'upload::valid', 'upload::type[gif,jpg,png]', 'upload::size[2M]');
  654. // Validate Personal Information
  655. if (!empty($_POST['person_first']))
  656. {
  657. $post->add_rules('person_first', 'length[3,100]');
  658. }
  659. if (!empty($_POST['person_last']))
  660. {
  661. $post->add_rules('person_last', 'length[3,100]');
  662. }
  663. if (!empty($_POST['person_email']))
  664. {
  665. $post->add_rules('person_email', 'email', 'length[3,100]');
  666. }
  667. // Validate Custom Fields
  668. if (isset($post->custom_field) && !$this->_validate_custom_form_fields($post->custom_field))
  669. {
  670. $post->add_error('custom_field', 'values');
  671. }
  672. $post->add_rules('incident_active','required', 'between[0,1]');
  673. $post->add_rules('incident_verified','required', 'length[0,1]');
  674. //$post->add_rules('incident_source','numeric', 'length[1,1]');
  675. //$post->add_rules('incident_information','numeric', 'length[1,1]');
  676. // Action::report_submit_admin - Report Posted
  677. Event::run('ushahidi_action.report_submit_admin', $post);
  678. // Test to see if things passed the rule checks
  679. if ($post->validate())
  680. {
  681. // Yes! everything is valid
  682. $location_id = $post->location_id;
  683. // STEP 1: SAVE LOCATION
  684. $location = new Location_Model($location_id);
  685. $location->location_name = $post->location_name;
  686. $location->latitude = $post->latitude;
  687. $location->longitude = $post->longitude;
  688. $location->location_date = date("Y-m-d H:i:s",time());
  689. $location->save();
  690. // STEP 2: SAVE INCIDENT
  691. $incident = new Incident_Model($id);
  692. $incident->location_id = $location->id;
  693. //$incident->locale = $post->locale;
  694. $incident->form_id = $post->form_id;
  695. $incident->user_id = $_SESSION['auth_user']->id;
  696. $incident->incident_title = $post->incident_title;
  697. $incident->incident_description = $post->incident_description;
  698. $incident->incident_status = $post->incident_status;
  699. $incident_date=explode("/",$post->incident_date);
  700. // where the $_POST['date'] is a value posted by form in mm/dd/yyyy format
  701. $incident_date=$incident_date[2]."-".$incident_date[0]."-".$incident_date[1];
  702. $incident_time = $post->incident_hour . ":" . $post->incident_minute . ":00 " . $post->incident_ampm;
  703. $incident->incident_date = date( "Y-m-d H:i:s", strtotime($incident_date . " " . $incident_time) );
  704. $is_new = false;
  705. // Is this new or edit?
  706. if ($id) // edit
  707. {
  708. $incident->incident_datemodify = date("Y-m-d H:i:s",time());
  709. }
  710. else // new
  711. {
  712. $incident->incident_dateadd = date("Y-m-d H:i:s",time());
  713. $is_new = true;
  714. }
  715. // Is this an Email, SMS, Twitter submitted report?
  716. //XXX: We may get rid of incident_mode altogether... ???
  717. //$_POST
  718. if(!empty($service_id))
  719. {
  720. if ($service_id == 1)
  721. { // SMS
  722. $incident->incident_mode = 2;
  723. }
  724. elseif ($service_id == 2)
  725. { // Email
  726. $incident->incident_mode = 3;
  727. }
  728. elseif ($service_id == 3)
  729. { // Twitter
  730. $incident->incident_mode = 4;
  731. }
  732. elseif ($service_id == 4)
  733. { // Laconica
  734. $incident->incident_mode = 5;
  735. }
  736. }
  737. // Incident Evaluation Info
  738. $incident->incident_active = $post->incident_active;
  739. $incident->incident_verified = $post->incident_verified;
  740. //$incident->incident_source = $post->incident_source;
  741. //$incident->incident_information = $post->incident_information;
  742. //$incident->incident_zoom = (int) $post->incident_zoom;
  743. //Save
  744. $incident->save();
  745. // Tag this as a report that needs to be sent out as an alert
  746. if ($incident->incident_active == '1' AND $incident->incident_alert_status != '2')
  747. { // 2 = report that has had an alert sent
  748. $incident->incident_alert_status = '1';
  749. $incident->save();
  750. }
  751. // Remove alert if report is unactivated and alert hasn't yet been sent
  752. if ($incident->incident_active == '0' AND $incident->incident_alert_status == '1')
  753. {
  754. $incident->incident_alert_status = '0';
  755. $incident->save();
  756. }
  757. // Record Approval/Verification Action
  758. $verify = new Verify_Model();
  759. $verify->incident_id = $incident->id;
  760. $verify->user_id = $_SESSION['auth_user']->id; // Record 'Verified By' Action
  761. $verify->verified_date = date("Y-m-d H:i:s",time());
  762. if ($post->incident_active == 1)
  763. {
  764. $verify->verified_status = '1';
  765. }
  766. elseif ($post->incident_verified == 1)
  767. {
  768. $verify->verified_status = '2';
  769. }
  770. elseif ($post->incident_active == 1 && $post->incident_verified == 1)
  771. {
  772. $verify->verified_status = '3';
  773. }
  774. else
  775. {
  776. $verify->verified_status = '0';
  777. }
  778. $verify->save();
  779. //STEP 2.5: SAVE THE GROUP ASSOCIATION
  780. if($is_new)
  781. {
  782. $group_incident = ORM::factory("simplegroups_groups_incident");
  783. $group_incident->incident_id = $incident->id;
  784. $group_incident->simplegroups_groups_id = $this->group->id;
  785. if($number_of_message_sender)
  786. {
  787. $group_incident->number_id = $number_of_message_sender->id;
  788. }
  789. $group_incident->save();
  790. }
  791. // STEP 2b: SAVE INCIDENT GEOMETRIES
  792. ORM::factory('geometry')->where('incident_id',$incident->id)->delete_all();
  793. if (isset($post->geometry))
  794. {
  795. foreach($post->geometry as $item)
  796. {
  797. if(!empty($item))
  798. {
  799. //Decode JSON
  800. $item = json_decode($item);
  801. //++ TODO - validate geometry
  802. $geometry = (isset($item->geometry)) ? mysql_escape_string($item->geometry) : "";
  803. $label = (isset($item->label)) ? mysql_escape_string(substr($item->label, 0, 150)) : "";
  804. $comment = (isset($item->comment)) ? mysql_escape_string(substr($item->comment, 0, 255)) : "";
  805. $color = (isset($item->color)) ? mysql_escape_string(substr($item->color, 0, 6)) : "";
  806. $strokewidth = (isset($item->strokewidth) AND (float) $item->strokewidth) ? (float) $item->strokewidth : "2.5";
  807. if ($geometry)
  808. {
  809. //++ Can't Use ORM for this
  810. $sql = "INSERT INTO ".Kohana::config('database.default.table_prefix')."geometry (
  811. incident_id, geometry, geometry_label, geometry_comment, geometry_color, geometry_strokewidth )
  812. VALUES( ".$incident->id.",
  813. GeomFromText( '".$geometry."' ),'".$label."','".$comment."','".$color."','".$strokewidth."')";
  814. $db->query($sql);
  815. }
  816. }
  817. }
  818. }
  819. // STEP 3: SAVE CATEGORIES
  820. ORM::factory('Incident_Category')->where('incident_id',$incident->id)->delete_all(); // Delete Previous Entries
  821. foreach($post->incident_category as $item)
  822. {
  823. $incident_category = new Incident_Category_Model();
  824. $incident_category->incident_id = $incident->id;
  825. $incident_category->category_id = $item;
  826. $incident_category->save();
  827. }
  828. // STEP 3.1: SAVE GROUP CATEGORIES
  829. ORM::factory('simplegroups_incident_category')->where('incident_id',$incident->id)->delete_all(); // Delete Previous Entries
  830. if(isset($post->incident_group_category))
  831. {
  832. foreach($post->incident_group_category as $item)
  833. {
  834. $incident_group_category = ORM::factory('simplegroups_incident_category');
  835. $incident_group_category->incident_id = $incident->id;
  836. $incident_group_category->simplegroups_category_id = $item;
  837. $incident_group_category->save();
  838. }
  839. }
  840. // STEP 4: SAVE MEDIA
  841. ORM::factory('Media')->where('incident_id',$incident->id)->where('media_type <> 1')->delete_all(); // Delete Previous Entries
  842. // a. News
  843. foreach($post->incident_news as $item)
  844. {
  845. if(!empty($item))
  846. {
  847. $news = new Media_Model();
  848. $news->location_id = $location->id;
  849. $news->incident_id = $incident->id;
  850. $news->media_type = 4; // News
  851. $news->media_link = $item;
  852. $news->media_date = date("Y-m-d H:i:s",time());
  853. $news->save();
  854. }
  855. }
  856. // b. Video
  857. foreach($post->incident_video as $item)
  858. {
  859. if(!empty($item))
  860. {
  861. $video = new Media_Model();
  862. $video->location_id = $location->id;
  863. $video->incident_id = $incident->id;
  864. $video->media_type = 2; // Video
  865. $video->media_link = $item;
  866. $video->media_date = date("Y-m-d H:i:s",time());
  867. $video->save();
  868. }
  869. }
  870. // c. Photos
  871. $filenames = upload::save('incident_photo');
  872. $i = 1;
  873. foreach ($filenames as $filename) {
  874. $new_filename = $incident->id . "_" . $i . "_" . time();
  875. // Resize original file... make sure its max 408px wide
  876. Image::factory($filename)->save(Kohana::config('upload.directory', TRUE) . $new_filename . ".jpg");
  877. // Create thumbnail
  878. Image::factory($filename)->resize(70,41,Image::HEIGHT)
  879. ->save(Kohana::config('upload.directory', TRUE) . $new_filename . "_t.jpg");
  880. // Remove the temporary file
  881. unlink($filename);
  882. // Save to DB
  883. $photo = new Media_Model();
  884. $photo->location_id = $location->id;
  885. $photo->incident_id = $incident->id;
  886. $photo->media_type = 1; // Images
  887. $photo->media_link = $new_filename . ".jpg";
  888. $photo->media_thumb = $new_filename . "_t.jpg";
  889. $photo->media_date = date("Y-m-d H:i:s",time());
  890. $photo->save();
  891. $i++;
  892. }
  893. // STEP 5: SAVE PERSONAL INFORMATION
  894. ORM::factory('Incident_Person')->where('incident_id',$incident->id)->delete_all(); // Delete Previous Entries
  895. $person = new Incident_Person_Model();
  896. $person->location_id = $location->id;
  897. $person->incident_id = $incident->id;
  898. $person->person_first = $post->person_first;
  899. $person->person_last = $post->person_last;
  900. $person->person_email = $post->person_email;
  901. $person->person_date = date("Y-m-d H:i:s",time());
  902. $person->save();
  903. if($is_new) //if it's new forward this to the groups main site, if they have one
  904. {
  905. groups::forward_incident_to_own_instance($incident->id, $this->group->id);
  906. }
  907. // STEP 6a: SAVE LINK TO REPORTER MESSAGE
  908. // We're creating a report from a message with this option
  909. if(isset($message_id) && $message_id != "")
  910. {
  911. $savemessage = ORM::factory('message', $message_id);
  912. if ($savemessage->loaded == true)
  913. {
  914. $savemessage->incident_id = $incident->id;
  915. $savemessage->save();
  916. }
  917. }
  918. // STEP 6b: SAVE LINK TO NEWS FEED
  919. // We're creating a report from a newsfeed with this option
  920. if(isset($feed_item_id) && $feed_item_id != "")
  921. {
  922. $savefeed = ORM::factory('feed_item', $feed_item_id);
  923. if ($savefeed->loaded == true)
  924. {
  925. $savefeed->incident_id = $incident->id;
  926. $savefeed->location_id = $location->id;
  927. $savefeed->save();
  928. }
  929. }
  930. // STEP 7: SAVE CUSTOM FORM FIELDS
  931. if(isset($post->custom_field))
  932. {
  933. foreach($post->custom_field as $key => $value)
  934. {
  935. $form_response = ORM::factory('form_response')
  936. ->where('form_field_id', $key)
  937. ->where('incident_id', $incident->id)
  938. ->find();
  939. if ($form_response->loaded == true)
  940. {
  941. $form_response->form_field_id = $key;
  942. $form_response->form_response = $value;
  943. $form_response->save();
  944. }
  945. else
  946. {
  947. $form_response = new Form_Response_Model();
  948. $form_response->form_field_id = $key;
  949. $form_response->incident_id = $incident->id;
  950. $form_response->form_response = $value;
  951. $form_response->save();
  952. }
  953. }
  954. }
  955. // Action::report_edit - Edited a Report
  956. Event::run('ushahidi_action.report_edit', $incident);
  957. // SAVE AND CLOSE?
  958. if ($post->save == 1) // Save but don't close
  959. {
  960. url::redirect('admin/simplegroups/reports/edit/'. $incident->id .'/saved');
  961. }
  962. else // Save and close
  963. {
  964. url::redirect('admin/simplegroups/reports/');
  965. }
  966. }
  967. // No! We have validation errors, we need to show the form again, with the errors
  968. else
  969. {
  970. // repopulate the form fields
  971. $form = arr::overwrite($form, $post->as_array());
  972. // populate the error fields, if any
  973. $errors = arr::overwrite($errors, $post->errors('report'));
  974. $form_error = TRUE;
  975. }
  976. }
  977. else
  978. {
  979. if ( $id )
  980. {
  981. //make sure the group user is allowed to see this report
  982. $count = ORM::factory("simplegroups_groups_incident")
  983. ->where(array("incident_id"=> $id, "simplegroups_groups_id"=>$this->group->id))
  984. ->count_all();
  985. if($count == 0) {
  986. url::redirect(url::site().'admin/simplegroups/reports');
  987. }
  988. // Retrieve Current Incident
  989. $incident = ORM::factory('incident', $id);
  990. if ($incident->loaded == true) {
  991. // Retrieve Categories
  992. $incident_category = array();
  993. foreach($incident->incident_category as $category) {
  994. $incident_category[] = $category->category_id;
  995. }
  996. // Retrieve Group Categories
  997. $incident_group_category = array();
  998. $incident_group_categories = ORM::factory("simplegroups_category")
  999. ->join("simplegroups_incident_category", "simplegroups_category.id", "simplegroups_incident_category.simplegroups_category_id")
  1000. ->where("simplegroups_incident_category.incident_id", $id)
  1001. ->find_all();
  1002. foreach($incident_group_categories as $category)
  1003. {
  1004. $incident_group_category[] = $category->id;
  1005. }
  1006. // Retrieve Media
  1007. $incident_news = array();
  1008. $incident_video = array();
  1009. $incident_photo = array();
  1010. foreach($incident->media as $media)
  1011. {
  1012. if ($media->media_type == 4)
  1013. {
  1014. $incident_news[] = $media->media_link;
  1015. }
  1016. elseif ($media->media_type == 2)
  1017. {
  1018. $incident_video[] = $media->media_link;
  1019. }
  1020. elseif ($media->media_type == 1)
  1021. {
  1022. $incident_photo[] = $media->media_link;
  1023. }
  1024. }
  1025. // Get Geometries via SQL query as ORM can't handle Spatial Data
  1026. $sql = "SELECT AsText(geometry) as geometry, geometry_label,
  1027. geometry_comment, geometry_color, geometry_strokewidth
  1028. FROM ".Kohana::config('database.default.table_prefix')."geometry
  1029. WHERE incident_id=".$id;
  1030. $query = $db->query($sql);
  1031. foreach ( $query as $item ) {
  1032. $form['geometry'][] = $item;
  1033. }
  1034. // Combine Everything
  1035. $incident_arr = array
  1036. (
  1037. 'location_id' => $incident->location->id,
  1038. 'form_id' => $incident->form_id,
  1039. 'locale' => $incident->locale,
  1040. 'incident_title' => $incident->incident_title,
  1041. 'incident_description' => $incident->incident_description,
  1042. 'incident_date' => date('m/d/Y', strtotime($incident->incident_date)),
  1043. 'incident_hour' => date('h', strtotime($incident->incident_date)),
  1044. 'incident_minute' => date('i', strtotime($incident->incident_date)),
  1045. 'incident_ampm' => date('a', strtotime($incident->incident_date)),
  1046. 'latitude' => $incident->location->latitude,
  1047. 'longitude' => $incident->location->longitude,
  1048. 'location_name' => $incident->location->location_name,
  1049. 'country_id' => $incident->location->country_id,
  1050. 'incident_category' => $incident_category,
  1051. 'incident_group_category' => $incident_group_category,
  1052. 'incident_news' => $incident_news,
  1053. 'incident_video' => $incident_video,
  1054. 'incident_photo' => $incident_photo,
  1055. 'person_first' => $incident->incident_person->person_first,
  1056. 'person_last' => $incident->incident_person->person_last,
  1057. 'person_email' => $incident->incident_person->person_email,
  1058. 'custom_field' => $this->_get_custom_form_fields($id,$incident->form_id,true),
  1059. 'incident_active' => $incident->incident_active,
  1060. 'incident_verified' => $incident->incident_verified,
  1061. 'incident_status' => $incident->incident_status,
  1062. //'incident_source' => $incident->incident_source,
  1063. //'incident_information' => $incident->incident_information,
  1064. //'incident_zoom' => Kohana::config('settings.default_zoom')
  1065. );
  1066. // Merge To Form Array For Display
  1067. $form = arr::overwrite($form, $incident_arr);
  1068. }
  1069. else
  1070. {
  1071. // Redirect
  1072. url::redirect('admin/simplegroups/reports/');
  1073. }
  1074. }//end of if($id)
  1075. else
  1076. { //this is a new report with no id
  1077. //check to see if we need to add some group categories that default on
  1078. //first find out what's out there.
  1079. //check and see if we need to tag this with a catgory
  1080. //find all the categories for this group with tag by default turned on
  1081. $categories = ORM::factory("simplegroups_category")
  1082. ->where("simplegroups_groups_id", $this->group->id)
  1083. ->where("selected_by_default", "1")
  1084. ->where("applies_to_report", "1")
  1085. ->find_all();
  1086. $default_categories = array();
  1087. foreach($categories as $category)
  1088. {
  1089. $default_categories[$category->id] = $category->id;
  1090. }
  1091. if(isset($message) && $message->loaded)
  1092. {
  1093. //if a messge was used in the creation of this report we're gonna copy the appropriate categories over
  1094. //figure out what…

Large files files are truncated, but you can click here to view the full file