PageRenderTime 65ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/application/controllers/admin/reports.php

https://github.com/fayazv/Taarifa_Web
PHP | 1614 lines | 1128 code | 242 blank | 244 comment | 139 complexity | 6e9e600e10dda021454d95595e57e9d7 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-3.0, BSD-3-Clause, LGPL-2.1
  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. * @subpackage Admin
  13. * @copyright Ushahidi - http://www.ushahidi.com
  14. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License (LGPL)
  15. */
  16. include "locationcode.php";
  17. class Reports_Controller extends Admin_Controller {
  18. public function __construct()
  19. {
  20. parent::__construct();
  21. $this->template->this_page = 'reports';
  22. }
  23. /**
  24. * Lists the reports.
  25. *
  26. * @param int $page
  27. */
  28. public function index($page = 1)
  29. {
  30. // If user doesn't have access, redirect to dashboard
  31. if ( ! admin::permissions($this->user, "reports_view"))
  32. {
  33. url::redirect(url::site().'admin/dashboard');
  34. }
  35. $this->template->content = new View('admin/reports');
  36. $this->template->content->title = Kohana::lang('ui_admin.reports');
  37. // To
  38. $params = array('all_reports' => TRUE);
  39. if (isset($_GET['status']))
  40. {
  41. $status = strtolower($_GET['status']);
  42. switch ($status) {
  43. case 'v':
  44. array_push($params, 'i.incident_verified = 0');
  45. break;
  46. case 't':
  47. array_push($params, 'i.incident_verified = 1 AND i.incident_status < 3');
  48. break;
  49. case 'f':
  50. array_push($params, 'i.incident_status = 3');
  51. break;
  52. case 'd':
  53. array_push($params, 'i.incident_status = 4');
  54. break;
  55. case 'e':
  56. array_push($params, 'i.incident_status = 5');
  57. break;
  58. case 'all':
  59. //$status = 'all';
  60. //array_push($params, 'i.incident_status <> 5');
  61. break;
  62. }
  63. }
  64. else $status = 'all';
  65. // Get Search Keywords (If Any)
  66. if (isset($_GET['k']))
  67. {
  68. // Brute force input sanitization
  69. // Phase 1 - Strip the search string of all non-word characters
  70. $keyword_raw = (isset($_GET['k']))? preg_replace('#/\w+/#', '', $_GET['k']) : "";
  71. // Strip any HTML tags that may have been missed in Phase 1
  72. $keyword_raw = strip_tags($keyword_raw);
  73. // Phase 3 - Invoke Kohana's XSS cleaning mechanism just incase an outlier wasn't caught
  74. // in the first 2 steps
  75. $keyword_raw = $this->input->xss_clean($keyword_raw);
  76. $filter = " AND (".$this->_get_searchstring($keyword_raw).")";
  77. }
  78. else
  79. {
  80. $keyword_raw = "";
  81. }
  82. // Check, has the form been submitted?
  83. $form_error = FALSE;
  84. $form_saved = FALSE;
  85. $form_action = "";
  86. if ($_POST)
  87. {
  88. $post = Validation::factory($_POST);
  89. // Add some filters
  90. $post->pre_filter('trim', TRUE);
  91. // Add some rules, the input field, followed by a list of checks, carried out in order
  92. $post->add_rules('action','required', 'alpha', 'length[1,1]');
  93. $post->add_rules('incident_id.*','required','numeric');
  94. if ($post->validate())
  95. {
  96. // Approve Action
  97. if ($post->action == 'a')
  98. {
  99. foreach($post->incident_id as $item)
  100. {
  101. $update = new Incident_Model($item);
  102. if ($update->loaded == TRUE)
  103. {
  104. $update->incident_active =($update->incident_active == 0) ? '1' : '0';
  105. // Tag this as a report that needs to be sent out as an alert
  106. if ($update->incident_alert_status != '2')
  107. {
  108. // 2 = report that has had an alert sent
  109. $update->incident_alert_status = '1';
  110. }
  111. $update->save();
  112. $verify = new Verify_Model();
  113. $verify->incident_id = $item;
  114. $verify->verified_status = '1';
  115. // Record 'Verified By' Action
  116. $verify->user_id = $_SESSION['auth_user']->id;
  117. $verify->verified_date = date("Y-m-d H:i:s",time());
  118. $verify->save();
  119. // Action::report_approve - Approve a Report
  120. Event::run('ushahidi_action.report_approve', $update);
  121. }
  122. }
  123. $form_action = strtoupper(Kohana::lang('ui_admin.approved'));
  124. }
  125. // Unapprove Action
  126. elseif ($post->action == 'u')
  127. {
  128. foreach ($post->incident_id as $item)
  129. {
  130. $update = new Incident_Model($item);
  131. if ($update->loaded == TRUE)
  132. {
  133. $update->incident_active = '0';
  134. // If Alert hasn't been sent yet, disable it
  135. if ($update->incident_alert_status == '1')
  136. {
  137. $update->incident_alert_status = '0';
  138. }
  139. $update->save();
  140. $verify = new Verify_Model();
  141. $verify->incident_id = $item;
  142. $verify->verified_status = '0';
  143. // Record 'Verified By' Action
  144. $verify->user_id = $_SESSION['auth_user']->id;
  145. $verify->verified_date = date("Y-m-d H:i:s",time());
  146. $verify->save();
  147. // Action::report_unapprove - Unapprove a Report
  148. Event::run('ushahidi_action.report_unapprove', $update);
  149. }
  150. }
  151. $form_action = strtoupper(Kohana::lang('ui_admin.unapproved'));
  152. }
  153. // Verify Action
  154. elseif ($post->action == 'v')
  155. {
  156. foreach ($post->incident_id as $item)
  157. {
  158. $update = new Incident_Model($item);
  159. $verify = new Verify_Model();
  160. if ($update->loaded == TRUE)
  161. {
  162. if ($update->incident_verified == '1')
  163. {
  164. $update->incident_verified = '0';
  165. $verify->verified_status = '0';
  166. }
  167. else
  168. {
  169. $update->incident_verified = '1';
  170. $verify->verified_status = '2';
  171. }
  172. $update->save();
  173. $verify->incident_id = $item;
  174. // Record 'Verified By' Action
  175. $verify->user_id = $_SESSION['auth_user']->id;
  176. $verify->verified_date = date("Y-m-d H:i:s",time());
  177. $verify->save();
  178. }
  179. }
  180. // Set the form action
  181. $form_action = strtoupper(Kohana::lang('ui_admin.verified_unverified'));
  182. }
  183. //Delete Action
  184. elseif ($post->action == 'd')
  185. {
  186. foreach($post->incident_id as $item)
  187. {
  188. $update = new Incident_Model($item);
  189. if ($update->loaded == TRUE)
  190. {
  191. $incident_id = $update->id;
  192. $location_id = $update->location_id;
  193. $update->delete();
  194. // Delete Location
  195. ORM::factory('location')->where('id',$location_id)->delete_all();
  196. // Delete Categories
  197. ORM::factory('incident_category')->where('incident_id',$incident_id)->delete_all();
  198. // Delete Translations
  199. ORM::factory('incident_lang')->where('incident_id',$incident_id)->delete_all();
  200. // Delete Photos From Directory
  201. foreach (ORM::factory('media')->where('incident_id',$incident_id)->where('media_type', 1) as $photo)
  202. {
  203. deletePhoto($photo->id);
  204. }
  205. // Delete Media
  206. ORM::factory('media')->where('incident_id',$incident_id)->delete_all();
  207. // Delete Sender
  208. ORM::factory('incident_person')->where('incident_id',$incident_id)->delete_all();
  209. // Delete relationship to SMS message
  210. $updatemessage = ORM::factory('message')->where('incident_id',$incident_id)->find();
  211. if ($updatemessage->loaded == TRUE)
  212. {
  213. $updatemessage->incident_id = 0;
  214. $updatemessage->save();
  215. }
  216. // Delete Comments
  217. ORM::factory('comment')->where('incident_id',$incident_id)->delete_all();
  218. // Delete form responses
  219. ORM::factory('form_response')->where('incident_id', $incident_id)->delete_all();
  220. // Action::report_delete - Deleted a Report
  221. Event::run('ushahidi_action.report_delete', $incident_id);
  222. }
  223. }
  224. $form_action = strtoupper(Kohana::lang('ui_admin.deleted'));
  225. }
  226. $form_saved = TRUE;
  227. }
  228. else
  229. {
  230. $form_error = TRUE;
  231. }
  232. }
  233. $all_reports = Incident_Model::get_incidents($params);
  234. // Pagination
  235. $pagination = new Pagination(array(
  236. 'query_string' => 'page',
  237. 'items_per_page' => $this->items_per_page,
  238. 'total_items' => $all_reports->count()
  239. )
  240. );
  241. Event::run('ushahidi_filter.pagination',$pagination);
  242. // Get the paginated reports
  243. $incidents = Incident_Model::get_incidents($params, $pagination);
  244. Event::run('ushahidi_filter.filter_incidents',$incidents);
  245. $this->template->content->countries = Country_Model::get_countries_list();
  246. $this->template->content->incidents = $incidents;
  247. $this->template->content->pagination = $pagination;
  248. $this->template->content->form_error = $form_error;
  249. $this->template->content->form_saved = $form_saved;
  250. $this->template->content->form_action = $form_action;
  251. // Total Reports
  252. $this->template->content->total_items = $pagination->total_items;
  253. // Status Tab
  254. $this->template->content->status = $status;
  255. // Javascript Header
  256. $this->template->js = new View('admin/reports_js');
  257. }
  258. /**
  259. * Edit a report
  260. * @param bool|int $id The id no. of the report
  261. * @param bool|string $saved
  262. */
  263. public function edit($id = FALSE, $saved = FALSE)
  264. {
  265. $db = new Database();
  266. // If user doesn't have access, redirect to dashboard
  267. if ( ! admin::permissions($this->user, "reports_edit"))
  268. {
  269. url::redirect(url::site().'admin/dashboard');
  270. }
  271. $this->template->content = new View('admin/reports_edit');
  272. $this->template->content->title = Kohana::lang('ui_admin.create_report');
  273. // setup and initialize form field names
  274. $form = array
  275. (
  276. 'location_id' => '',
  277. 'form_id' => '',
  278. 'locale' => '',
  279. 'incident_title' => '',
  280. 'incident_description' => '',
  281. 'incident_date' => '',
  282. 'incident_hour' => '',
  283. 'incident_minute' => '',
  284. 'incident_ampm' => '',
  285. 'incident_status' => '',
  286. 'phone_number' => '',
  287. 'latitude' => '',
  288. 'longitude' => '',
  289. 'geometry' => array(),
  290. 'location_name' => '',
  291. 'country_id' => '',
  292. 'country_name' =>'',
  293. 'incident_category' => array(),
  294. 'incident_news' => array(),
  295. 'incident_video' => array(),
  296. 'incident_photo' => array(),
  297. 'person_first' => '',
  298. 'person_last' => '',
  299. 'person_email' => '',
  300. 'custom_field' => array(),
  301. 'incident_active' => '',
  302. 'incident_verified' => '',
  303. 'incident_zoom' => ''
  304. );
  305. // Copy the form as errors, so the errors will be stored with keys corresponding to the form field names
  306. $errors = $form;
  307. $form_error = FALSE;
  308. $form_saved = ($saved == 'saved');
  309. // Initialize Default Values
  310. $form['locale'] = Kohana::config('locale.language');
  311. //$form['latitude'] = Kohana::config('settings.default_lat');
  312. //$form['longitude'] = Kohana::config('settings.default_lon');
  313. $form['incident_date'] = date("m/d/Y",time());
  314. $form['incident_hour'] = date('h');
  315. $form['incident_minute'] = date('i');
  316. $form['incident_ampm'] = date('a');
  317. $form['country_id'] = Kohana::config('settings.default_country');
  318. // initialize custom field array
  319. $form['custom_field'] = customforms::get_custom_form_fields($id,'',true);
  320. // Locale (Language) Array
  321. $this->template->content->locale_array = Kohana::config('locale.all_languages');
  322. // Create Categories
  323. $this->template->content->categories = Category_Model::get_categories();
  324. $this->template->content->new_categories_form = $this->_new_categories_form_arr();
  325. // Time formatting
  326. $this->template->content->hour_array = $this->_hour_array();
  327. $this->template->content->minute_array = $this->_minute_array();
  328. $this->template->content->ampm_array = $this->_ampm_array();
  329. $this->template->content->stroke_width_array = $this->_stroke_width_array();
  330. // Get Countries
  331. $countries = array();
  332. foreach (ORM::factory('country')->orderby('country')->find_all() as $country)
  333. {
  334. // Create a list of all countries
  335. $this_country = $country->country;
  336. if (strlen($this_country) > 35)
  337. {
  338. $this_country = substr($this_country, 0, 35) . "...";
  339. }
  340. $countries[$country->id] = $this_country;
  341. }
  342. // Initialize Default Value for Hidden Field Country Name, just incase Reverse Geo coding yields no result
  343. $form['country_name'] = $countries[$form['country_id']];
  344. $this->template->content->countries = $countries;
  345. //GET custom forms
  346. $forms = array();
  347. foreach (ORM::factory('form')->where('form_active',1)->find_all() as $custom_forms)
  348. {
  349. $forms[$custom_forms->id] = $custom_forms->form_title;
  350. }
  351. $this->template->content->forms = $forms;
  352. // Get the incident media
  353. $incident_media = Incident_Model::is_valid_incident($id)
  354. ? ORM::factory('incident', $id)->media
  355. : FALSE;
  356. $this->template->content->incident_media = $incident_media;
  357. // Are we creating this report from SMS/Email/Twitter?
  358. // If so retrieve message
  359. if ( isset($_GET['mid']) AND intval($_GET['mid']) > 0 ) {
  360. $message_id = intval($_GET['mid']);
  361. $service_id = "";
  362. $message = ORM::factory('message', $message_id);
  363. if ($message->loaded AND $message->message_type == 1)
  364. {
  365. $service_id = $message->reporter->service_id;
  366. // Has a report already been created for this Message?
  367. if ($message->incident_id != 0) {
  368. // Redirect to report
  369. url::redirect('admin/reports/edit/'. $message->incident_id);
  370. }
  371. $this->template->content->show_messages = true;
  372. $incident_description = $message->message;
  373. if ( ! empty($message->message_detail))
  374. {
  375. $form['incident_title'] = $message->message;
  376. $incident_description = $message->message_detail;
  377. }
  378. $form['incident_description'] = $incident_description;
  379. $form['incident_date'] = date('m/d/Y', strtotime($message->message_date));
  380. $form['incident_hour'] = date('h', strtotime($message->message_date));
  381. $form['incident_minute'] = date('i', strtotime($message->message_date));
  382. $form['incident_ampm'] = date('a', strtotime($message->message_date));
  383. $form['person_first'] = $message->reporter->reporter_first;
  384. $form['person_last'] = $message->reporter->reporter_last;
  385. // Does the sender of this message have a location?
  386. if ($message->reporter->location->loaded)
  387. {
  388. $form['location_id'] = $message->reporter->location->id;
  389. $form['latitude'] = $message->reporter->location->latitude;
  390. $form['longitude'] = $message->reporter->location->longitude;
  391. $form['location_name'] = $message->reporter->location->location_name;
  392. }else{
  393. //see if the message contains a hash followed by a 10 digit number
  394. $regex_pattern = "/#\d{10}/";
  395. preg_match_all($regex_pattern,$incident_description,$matches,1);
  396. if(count($matches[0]) == 1){
  397. //extract the number
  398. $id = substr($matches[0][0],1);
  399. //convert to a location code
  400. $pc = new LocationCode();
  401. $coords = $pc->id2coords($id);
  402. $form['latitude'] = $coords[0];
  403. $form['longitude'] = $coords[1];
  404. }
  405. }
  406. //Events to manipulate an already known location
  407. Event::run('ushahidi_action.location_from',$message_from = $message->message_from);
  408. //filter location name
  409. Event::run('ushahidi_filter.location_name',$form['location_name']);
  410. //filter //location find
  411. Event::run('ushahidi_filter.location_find',$form['location_find']);
  412. // Retrieve Last 5 Messages From this account
  413. $this->template->content->all_messages = ORM::factory('message')
  414. ->where('reporter_id', $message->reporter_id)
  415. ->orderby('message_date', 'desc')
  416. ->limit(5)
  417. ->find_all();
  418. }
  419. else
  420. {
  421. $message_id = "";
  422. $this->template->content->show_messages = false;
  423. }
  424. }
  425. else
  426. {
  427. $this->template->content->show_messages = false;
  428. }
  429. // Are we creating this report from a Newsfeed?
  430. if ( isset($_GET['fid']) AND intval($_GET['fid']) > 0 )
  431. {
  432. $feed_item_id = intval($_GET['fid']);
  433. $feed_item = ORM::factory('feed_item', $feed_item_id);
  434. if ($feed_item->loaded)
  435. {
  436. // Has a report already been created for this Feed item?
  437. if ($feed_item->incident_id != 0)
  438. {
  439. // Redirect to report
  440. url::redirect('admin/reports/edit/'. $feed_item->incident_id);
  441. }
  442. $form['incident_title'] = $feed_item->item_title;
  443. $form['incident_description'] = $feed_item->item_description;
  444. $form['incident_date'] = date('m/d/Y', strtotime($feed_item->item_date));
  445. $form['incident_hour'] = date('h', strtotime($feed_item->item_date));
  446. $form['incident_minute'] = date('i', strtotime($feed_item->item_date));
  447. $form['incident_ampm'] = date('a', strtotime($feed_item->item_date));
  448. // News Link
  449. $form['incident_news'][0] = $feed_item->item_link;
  450. // Does this newsfeed have a geolocation?
  451. if ($feed_item->location_id)
  452. {
  453. $form['location_id'] = $feed_item->location_id;
  454. $form['latitude'] = $feed_item->location->latitude;
  455. $form['longitude'] = $feed_item->location->longitude;
  456. $form['location_name'] = $feed_item->location->location_name;
  457. }
  458. }
  459. else
  460. {
  461. $feed_item_id = "";
  462. }
  463. }
  464. // Check, has the form been submitted, if so, setup validation
  465. if ($_POST)
  466. {
  467. // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things
  468. $post = array_merge($_POST, $_FILES);
  469. // Check if the service id exists
  470. if (isset($service_id) AND intval($service_id) > 0)
  471. {
  472. $post = array_merge($post, array('service_id' => $service_id));
  473. }
  474. // Check if the incident id is valid an add it to the post data
  475. if (Incident_Model::is_valid_incident($id))
  476. {
  477. $post = array_merge($post, array('incident_id' => $id));
  478. }
  479. /**
  480. * NOTES - E.Kala July 27, 2011
  481. *
  482. * Previously, the $post parameter for this event was a Validation
  483. * object. Now it's an array (i.e. the raw data without any validation rules applied to them).
  484. * As such, all plugins making use of this event shall have to be updated
  485. */
  486. // Action::report_submit_admin - Report Posted
  487. Event::run('ushahidi_action.report_submit_admin', $post);
  488. // Validate
  489. if (reports::validate($post, TRUE))
  490. {
  491. // Yes! everything is valid
  492. $location_id = $post->location_id;
  493. // STEP 1: SAVE LOCATION
  494. $location = new Location_Model($location_id);
  495. reports::save_location($post, $location);
  496. // STEP 2: SAVE INCIDENT
  497. $incident = new Incident_Model($id);
  498. reports::save_report($post, $incident, $location->id);
  499. // STEP 2b: Record Approval/Verification Action
  500. $verify = new Verify_Model();
  501. reports::verify_approve($post, $verify, $incident);
  502. // STEP 2c: SAVE INCIDENT GEOMETRIES
  503. reports::save_report_geometry($post, $incident);
  504. // STEP 3: SAVE CATEGORIES
  505. reports::save_category($post, $incident);
  506. // STEP 4: SAVE MEDIA
  507. reports::save_media($post, $incident);
  508. // STEP 5: SAVE PERSONAL INFORMATION
  509. reports::save_personal_info($post, $incident);
  510. // STEP 6a: SAVE LINK TO REPORTER MESSAGE
  511. // We're creating a report from a message with this option
  512. if (isset($message_id) AND intval($message_id) > 0)
  513. {
  514. $savemessage = ORM::factory('message', $message_id);
  515. if ($savemessage->loaded)
  516. {
  517. $savemessage->incident_id = $incident->id;
  518. $savemessage->save();
  519. // Does Message Have Attachments?
  520. // Add Attachments
  521. $attachments = ORM::factory("media")
  522. ->where("message_id", $savemessage->id)
  523. ->find_all();
  524. foreach ($attachments AS $attachment)
  525. {
  526. $attachment->incident_id = $incident->id;
  527. $attachment->save();
  528. }
  529. }
  530. }
  531. // STEP 6b: SAVE LINK TO NEWS FEED
  532. // We're creating a report from a newsfeed with this option
  533. if (isset($feed_item_id) AND intval($feed_item_id) > 0)
  534. {
  535. $savefeed = ORM::factory('feed_item', $feed_item_id);
  536. if ($savefeed->loaded)
  537. {
  538. $savefeed->incident_id = $incident->id;
  539. $savefeed->location_id = $location->id;
  540. $savefeed->save();
  541. }
  542. }
  543. // STEP 7: SAVE CUSTOM FORM FIELDS
  544. reports::save_custom_fields($post, $incident);
  545. // Action::report_edit - Edited a Report
  546. Event::run('ushahidi_action.report_edit', $incident);
  547. // SAVE AND CLOSE?
  548. if ($post->save == 1)
  549. {
  550. // Save but don't close
  551. url::redirect('admin/reports/edit/'. $incident->id .'/saved');
  552. }
  553. else
  554. {
  555. // Save and close
  556. url::redirect('admin/reports/');
  557. }
  558. }
  559. // No! We have validation errors, we need to show the form again, with the errors
  560. else
  561. {
  562. // Repopulate the form fields
  563. $form = arr::overwrite($form, $post->as_array());
  564. // Populate the error fields, if any
  565. $errors = arr::overwrite($errors, $post->errors('report'));
  566. $form_error = TRUE;
  567. }
  568. }
  569. else
  570. {
  571. if (Incident_Model::is_valid_incident($id))
  572. {
  573. // Retrieve Current Incident
  574. $incident = ORM::factory('incident', $id);
  575. if ($incident->loaded == true)
  576. {
  577. // Retrieve Categories
  578. $incident_category = array();
  579. foreach($incident->incident_category as $category)
  580. {
  581. $incident_category[] = $category->category_id;
  582. }
  583. // Retrieve Media
  584. $incident_news = array();
  585. $incident_video = array();
  586. $incident_photo = array();
  587. foreach($incident->media as $media)
  588. {
  589. if ($media->media_type == 4)
  590. {
  591. $incident_news[] = $media->media_link;
  592. }
  593. elseif ($media->media_type == 2)
  594. {
  595. $incident_video[] = $media->media_link;
  596. }
  597. elseif ($media->media_type == 1)
  598. {
  599. $incident_photo[] = $media->media_link;
  600. }
  601. }
  602. // Get Geometries via SQL query as ORM can't handle Spatial Data
  603. $sql = "SELECT AsText(geometry) as geometry, geometry_label,
  604. geometry_comment, geometry_color, geometry_strokewidth
  605. FROM ".Kohana::config('database.default.table_prefix')."geometry
  606. WHERE incident_id=".$id;
  607. $query = $db->query($sql);
  608. foreach ( $query as $item )
  609. {
  610. $geometry = array(
  611. "geometry" => $item->geometry,
  612. "label" => $item->geometry_label,
  613. "comment" => $item->geometry_comment,
  614. "color" => $item->geometry_color,
  615. "strokewidth" => $item->geometry_strokewidth
  616. );
  617. $form['geometry'][] = json_encode($geometry);
  618. }
  619. // Combine Everything
  620. $incident_arr = array(
  621. 'location_id' => $incident->location->id,
  622. 'form_id' => $incident->form_id,
  623. 'locale' => $incident->locale,
  624. 'incident_title' => $incident->incident_title,
  625. 'incident_description' => $incident->incident_description,
  626. 'incident_date' => date('m/d/Y', strtotime($incident->incident_date)),
  627. 'incident_hour' => date('h', strtotime($incident->incident_date)),
  628. 'incident_minute' => date('i', strtotime($incident->incident_date)),
  629. 'incident_ampm' => date('a', strtotime($incident->incident_date)),
  630. 'incident_status' => $incident->incident_status,
  631. 'phone_number' => $incident->get_message_from(),
  632. 'latitude' => $incident->location->latitude,
  633. 'longitude' => $incident->location->longitude,
  634. 'location_name' => $incident->location->location_name,
  635. 'country_id' => $incident->location->country_id,
  636. 'incident_category' => $incident_category,
  637. 'incident_news' => $incident_news,
  638. 'incident_video' => $incident_video,
  639. 'incident_photo' => $incident_photo,
  640. 'person_first' => $incident->incident_person->person_first,
  641. 'person_last' => $incident->incident_person->person_last,
  642. 'person_email' => $incident->incident_person->person_email,
  643. 'custom_field' => customforms::get_custom_form_fields($id,$incident->form_id,true),
  644. 'incident_active' => $incident->incident_active,
  645. 'incident_verified' => $incident->incident_verified,
  646. 'incident_zoom' => $incident->incident_zoom
  647. );
  648. // Merge To Form Array For Display
  649. $form = arr::overwrite($form, $incident_arr);
  650. }
  651. else
  652. {
  653. // Redirect
  654. url::redirect('admin/reports/');
  655. }
  656. }
  657. }
  658. $this->template->content->id = $id;
  659. $this->template->content->form = $form;
  660. $this->template->content->errors = $errors;
  661. $this->template->content->form_error = $form_error;
  662. $this->template->content->form_saved = $form_saved;
  663. // Retrieve Custom Form Fields Structure
  664. $this->template->content->custom_forms = new View('reports_submit_custom_forms');
  665. $disp_custom_fields = customforms::get_custom_form_fields($id, $form['form_id'], FALSE, "view");
  666. $custom_field_mismatch = customforms::get_edit_mismatch($form['form_id']);
  667. $this->template->content->custom_forms->disp_custom_fields = $disp_custom_fields;
  668. $this->template->content->custom_forms->custom_field_mismatch = $custom_field_mismatch;
  669. $this->template->content->custom_forms->form = $form;
  670. // Retrieve Previous & Next Records
  671. $previous = ORM::factory('incident')->where('id < ', $id)->orderby('id','desc')->find();
  672. $previous_url = ($previous->loaded ?
  673. url::base().'admin/reports/edit/'.$previous->id :
  674. url::base().'admin/reports/');
  675. $next = ORM::factory('incident')->where('id > ', $id)->orderby('id','desc')->find();
  676. $next_url = ($next->loaded ?
  677. url::base().'admin/reports/edit/'.$next->id :
  678. url::base().'admin/reports/');
  679. $this->template->content->previous_url = $previous_url;
  680. $this->template->content->next_url = $next_url;
  681. // Javascript Header
  682. $this->template->map_enabled = TRUE;
  683. $this->template->colorpicker_enabled = TRUE;
  684. $this->template->treeview_enabled = TRUE;
  685. $this->template->json2_enabled = TRUE;
  686. $this->template->js = new View('reports_submit_edit_js');
  687. $this->template->js->edit_mode = TRUE;
  688. $this->template->js->default_map = Kohana::config('settings.default_map');
  689. $this->template->js->default_zoom = Kohana::config('settings.default_zoom');
  690. if ( ! $form['latitude'] OR !$form['latitude'])
  691. {
  692. $this->template->js->latitude = Kohana::config('settings.default_lat');
  693. $this->template->js->longitude = Kohana::config('settings.default_lon');
  694. }
  695. else
  696. {
  697. $this->template->js->latitude = $form['latitude'];
  698. $this->template->js->longitude = $form['longitude'];
  699. }
  700. $this->template->js->incident_zoom = $form['incident_zoom'];
  701. $this->template->js->geometries = $form['geometry'];
  702. // Inline Javascript
  703. $this->template->content->date_picker_js = $this->_date_picker_js();
  704. $this->template->content->color_picker_js = $this->_color_picker_js();
  705. $this->template->content->new_category_toggle_js = $this->_new_category_toggle_js();
  706. // Pack Javascript
  707. $myPacker = new javascriptpacker($this->template->js , 'Normal', false, false);
  708. $this->template->js = $myPacker->pack();
  709. }
  710. /**
  711. * Download Reports in CSV format
  712. */
  713. public function download()
  714. {
  715. // If user doesn't have access, redirect to dashboard
  716. if ( ! admin::permissions($this->user, "reports_download"))
  717. {
  718. url::redirect(url::site().'admin/dashboard');
  719. }
  720. $this->template->content = new View('admin/reports_download');
  721. $this->template->content->title = Kohana::lang('ui_admin.download_reports');
  722. $form = array(
  723. 'data_point' => '',
  724. 'data_include' => '',
  725. 'from_date' => '',
  726. 'to_date' => ''
  727. );
  728. $errors = $form;
  729. $form_error = FALSE;
  730. // Check, has the form been submitted, if so, setup validation
  731. if ($_POST)
  732. {
  733. // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things
  734. $post = Validation::factory($_POST);
  735. // Add some filters
  736. $post->pre_filter('trim', TRUE);
  737. // Add some rules, the input field, followed by a list of checks, carried out in order
  738. $post->add_rules('data_point.*','required','numeric','between[1,4]');
  739. //$post->add_rules('data_include.*','numeric','between[1,5]');
  740. $post->add_rules('data_include.*','numeric','between[1,6]');
  741. $post->add_rules('from_date','date_mmddyyyy');
  742. $post->add_rules('to_date','date_mmddyyyy');
  743. // Validate the report dates, if included in report filter
  744. if (!empty($_POST['from_date']) OR !empty($_POST['to_date']))
  745. {
  746. // Valid FROM Date?
  747. if (empty($_POST['from_date']) OR (strtotime($_POST['from_date']) > strtotime("today")))
  748. {
  749. $post->add_error('from_date','range');
  750. }
  751. // Valid TO date?
  752. if (empty($_POST['to_date']) OR (strtotime($_POST['to_date']) > strtotime("today")))
  753. {
  754. $post->add_error('to_date','range');
  755. }
  756. // TO Date not greater than FROM Date?
  757. if (strtotime($_POST['from_date']) > strtotime($_POST['to_date']))
  758. {
  759. $post->add_error('to_date','range_greater');
  760. }
  761. }
  762. // Test to see if things passed the rule checks
  763. if ($post->validate())
  764. {
  765. // Add Filters
  766. $filter = " ( ";
  767. // Report Type Filter
  768. foreach($post->data_point as $item)
  769. {
  770. if ($item == 1)
  771. {
  772. $filter .= " OR incident_active = 1 ";
  773. }
  774. if ($item == 2)
  775. {
  776. $filter .= " OR incident_verified = 1 ";
  777. }
  778. if ($item == 3)
  779. {
  780. $filter .= " OR incident_active = 0 ";
  781. }
  782. if ($item == 4)
  783. {
  784. $filter .= " OR incident_verified = 0 ";
  785. }
  786. }
  787. $filter .= ") ";
  788. // Report Date Filter
  789. if ( ! empty($post->from_date) AND !empty($post->to_date))
  790. {
  791. $filter .= " AND ( incident_date >= '" . date("Y-m-d H:i:s",strtotime($post->from_date))
  792. . "' AND incident_date <= '" . date("Y-m-d H:i:s",strtotime($post->to_date)) . "' ) ";
  793. }
  794. // Retrieve reports
  795. $incidents = ORM::factory('incident')->where($filter)->orderby('incident_dateadd', 'desc')->find_all();
  796. // Column Titles
  797. $report_csv = "#,INCIDENT TITLE,INCIDENT DATE";
  798. foreach($post->data_include as $item)
  799. {
  800. if ($item == 1) {
  801. $report_csv .= ",LOCATION";
  802. }
  803. if ($item == 2) {
  804. $report_csv .= ",DESCRIPTION";
  805. }
  806. if ($item == 3) {
  807. $report_csv .= ",CATEGORY";
  808. }
  809. if ($item == 4) {
  810. $report_csv .= ",LATITUDE";
  811. }
  812. if($item == 5) {
  813. $report_csv .= ",LONGITUDE";
  814. }
  815. if($item == 6)
  816. {
  817. $custom_titles = ORM::factory('form_field')->orderby('field_position','desc')->find_all();
  818. foreach($custom_titles as $field_name)
  819. {
  820. $report_csv .= ",".$field_name->field_name;
  821. }
  822. }
  823. }
  824. $report_csv .= ",APPROVED,VERIFIED";
  825. $report_csv .= "\n";
  826. foreach ($incidents as $incident)
  827. {
  828. $report_csv .= '"'.$incident->id.'",';
  829. $report_csv .= '"'.$this->_csv_text($incident->incident_title).'",';
  830. $report_csv .= '"'.$incident->incident_date.'"';
  831. foreach($post->data_include as $item)
  832. {
  833. switch ($item)
  834. {
  835. case 1:
  836. $report_csv .= ',"'.$this->_csv_text($incident->location->location_name).'"';
  837. break;
  838. case 2:
  839. $report_csv .= ',"'.$this->_csv_text($incident->incident_description).'"';
  840. break;
  841. case 3:
  842. $report_csv .= ',"';
  843. foreach($incident->incident_category as $category)
  844. {
  845. if ($category->category->category_title)
  846. {
  847. $report_csv .= $this->_csv_text($category->category->category_title) . ", ";
  848. }
  849. }
  850. $report_csv .= '"';
  851. break;
  852. case 4:
  853. $report_csv .= ',"'.$this->_csv_text($incident->location->latitude).'"';
  854. break;
  855. case 5:
  856. $report_csv .= ',"'.$this->_csv_text($incident->location->longitude).'"';
  857. break;
  858. case 6:
  859. $incident_id = $incident->id;
  860. $custom_fields = ORM::factory('form_response')->where('incident_id',$incident_id)->orderby('form_field_id','desc')->find_all();
  861. foreach($custom_fields as $custom_field)
  862. {
  863. $report_csv .=',"'.$this->_csv_text($custom_field->form_response).'"';
  864. }
  865. break;
  866. }
  867. }
  868. if ($incident->incident_active)
  869. {
  870. $report_csv .= ",YES";
  871. }
  872. else
  873. {
  874. $report_csv .= ",NO";
  875. }
  876. if ($incident->incident_verified)
  877. {
  878. $report_csv .= ",YES";
  879. }
  880. else
  881. {
  882. $report_csv .= ",NO";
  883. }
  884. $report_csv .= "\n";
  885. }
  886. // Output to browser
  887. header("Content-type: text/x-csv");
  888. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  889. header("Content-Disposition: attachment; filename=" . time() . ".csv");
  890. header("Content-Length: " . strlen($report_csv));
  891. echo $report_csv;
  892. exit;
  893. }
  894. // No! We have validation errors, we need to show the form again, with the errors
  895. else
  896. {
  897. // Repopulate the form fields
  898. $form = arr::overwrite($form, $post->as_array());
  899. // Populate the error fields, if any
  900. $errors = arr::overwrite($errors, $post->errors('report'));
  901. $form_error = TRUE;
  902. }
  903. }
  904. $this->template->content->form = $form;
  905. $this->template->content->errors = $errors;
  906. $this->template->content->form_error = $form_error;
  907. // Javascript Header
  908. $this->template->js = new View('admin/reports_download_js');
  909. $this->template->js->calendar_img = url::base() . "media/img/icon-calendar.gif";
  910. }
  911. public function upload()
  912. {
  913. // If user doesn't have access, redirect to dashboard
  914. if ( ! admin::permissions($this->user, "reports_upload"))
  915. {
  916. url::redirect(url::site().'admin/dashboard');
  917. }
  918. if ($_SERVER['REQUEST_METHOD'] == 'GET') {
  919. $this->template->content = new View('admin/reports_upload');
  920. $this->template->content->title = 'Upload Reports';
  921. $this->template->content->form_error = false;
  922. }
  923. if ($_SERVER['REQUEST_METHOD']=='POST')
  924. {
  925. $errors = array();
  926. $notices = array();
  927. if (!$_FILES['csvfile']['error'])
  928. {
  929. if (file_exists($_FILES['csvfile']['tmp_name']))
  930. {
  931. if($filehandle = fopen($_FILES['csvfile']['tmp_name'], 'r'))
  932. {
  933. $importer = new ReportsImporter;
  934. if ($importer->import($filehandle))
  935. {
  936. $this->template->content = new View('admin/reports_upload_success');
  937. $this->template->content->title = 'Upload Reports';
  938. $this->template->content->rowcount = $importer->totalrows;
  939. $this->template->content->imported = $importer->importedrows;
  940. $this->template->content->notices = $importer->notices;
  941. }
  942. else
  943. {
  944. $errors = $importer->errors;
  945. }
  946. }
  947. else
  948. {
  949. $errors[] = Kohana::lang('ui_admin.file_open_error');
  950. }
  951. }
  952. // File exists?
  953. else
  954. {
  955. $errors[] = Kohana::lang('ui_admin.file_not_found_upload');
  956. }
  957. }
  958. // Upload errors?
  959. else
  960. {
  961. $errors[] = $_FILES['csvfile']['error'];
  962. }
  963. if(count($errors))
  964. {
  965. $this->template->content = new View('admin/reports_upload');
  966. $this->template->content->title = Kohana::lang('ui_admin.upload_reports');
  967. $this->template->content->errors = $errors;
  968. $this->template->content->form_error = 1;
  969. }
  970. }
  971. }
  972. /**
  973. * Translate a report
  974. * @param bool|int $id The id no. of the report
  975. * @param bool|string $saved
  976. */
  977. public function translate( $id = false, $saved = FALSE)
  978. {
  979. $this->template->content = new View('admin/reports_translate');
  980. $this->template->content->title = Kohana::lang('ui_admin.translate_reports');
  981. // Which incident are we adding this translation for?
  982. if (isset($_GET['iid']) && !empty($_GET['iid']))
  983. {
  984. $incident_id = (int) $_GET['iid'];
  985. $incident = ORM::factory('incident', $incident_id);
  986. if ($incident->loaded == true)
  987. {
  988. $orig_locale = $incident->locale;
  989. $this->template->content->orig_title = $incident->incident_title;
  990. $this->template->content->orig_description = $incident->incident_description;
  991. }
  992. else
  993. {
  994. // Redirect
  995. url::redirect('admin/reports/');
  996. }
  997. }
  998. else
  999. {
  1000. // Redirect
  1001. url::redirect('admin/reports/');
  1002. }
  1003. // Setup and initialize form field names
  1004. $form = array(
  1005. 'locale' => '',
  1006. 'incident_title' => '',
  1007. 'incident_description' => ''
  1008. );
  1009. // Copy the form as errors, so the errors will be stored with keys corresponding to the form field names
  1010. $errors = $form;
  1011. $form_error = FALSE;
  1012. $form_saved = ($saved == 'saved')? TRUE : FALSE;
  1013. // Locale (Language) Array
  1014. $this->template->content->locale_array = Kohana::config('locale.all_languages');
  1015. // Check, has the form been submitted, if so, setup validation
  1016. if ($_POST)
  1017. {
  1018. // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things
  1019. $post = Validation::factory($_POST);
  1020. // Add some filters
  1021. $post->pre_filter('trim', TRUE);
  1022. // Add some rules, the input field, followed by a list of checks, carried out in order
  1023. $post->add_rules('locale','required','alpha_dash','length[5]');
  1024. $post->add_rules('incident_title','required', 'length[3,200]');
  1025. $post->add_rules('incident_description','required');
  1026. $post->add_callbacks('locale', array($this,'translate_exists_chk'));
  1027. if ($orig_locale == $_POST['locale'])
  1028. {
  1029. // The original report and the translation are the same language!
  1030. $post->add_error('locale','locale');
  1031. }
  1032. // Test to see if things passed the rule checks
  1033. if ($post->validate())
  1034. {
  1035. // SAVE INCIDENT TRANSLATION
  1036. $incident_l = new Incident_Lang_Model($id);
  1037. $incident_l->incident_id = $incident_id;
  1038. $incident_l->locale = $post->locale;
  1039. $incident_l->incident_title = $post->incident_title;
  1040. $incident_l->incident_description = $post->incident_description;
  1041. $incident_l->save();
  1042. // SAVE AND CLOSE?
  1043. // Save but don't close
  1044. if ($post->save == 1)
  1045. {
  1046. url::redirect('admin/reports/translate/'. $incident_l->id .'/saved/?iid=' . $incident_id);
  1047. }
  1048. // Save and close
  1049. else
  1050. {
  1051. url::redirect('admin/reports/');
  1052. }
  1053. }
  1054. // No! We have validation errors, we need to show the form again, with the errors
  1055. else
  1056. {
  1057. // Repopulate the form fields
  1058. $form = arr::overwrite($form, $post->as_array());
  1059. // Populate the error fields, if any
  1060. $errors = arr::overwrite($errors, $post->errors('report'));
  1061. $form_error = TRUE;
  1062. }
  1063. }
  1064. else
  1065. {
  1066. if ($id)
  1067. {
  1068. // Retrieve Current Incident
  1069. $incident_l = ORM::factory('incident_lang', $id)->where('incident_id', $incident_id)->find();
  1070. if ($incident_l->loaded == true)
  1071. {
  1072. $form['locale'] = $incident_l->locale;
  1073. $form['incident_title'] = $incident_l->incident_title;
  1074. $form['incident_description'] = $incident_l->incident_description;
  1075. }
  1076. else
  1077. {
  1078. // Redirect
  1079. url::redirect('admin/reports/');
  1080. }
  1081. }
  1082. }
  1083. $this->template->content->form = $form;
  1084. $this->template->content->errors = $errors;
  1085. $this->template->content->form_error = $form_error;
  1086. $this->template->content->form_saved = $form_saved;
  1087. // Javascript Header
  1088. $this->template->js = new View('admin/reports_translate_js');
  1089. }
  1090. /*
  1091. * Should be in simple groups but it isn't.
  1092. */
  1093. public function remove_group() {
  1094. $this->auto_render = FALSE;
  1095. $this->template = '';
  1096. json_encode('moo');
  1097. if($_POST) {
  1098. // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things
  1099. $post = Validation::factory($_POST);
  1100. $post->pre_filter('trim', TRUE);
  1101. // Add rules
  1102. $post->add_rules('incident_id', 'required');
  1103. $post->add_rules('group_id', 'required');
  1104. if($post->validate()) {
  1105. $incident = ORM::factory('simplegroups_groups_incident')
  1106. ->where(array('incident_id' => $post['incident_id'], 'simplegroups_groups_id' => $post['group_id']))
  1107. ->delete_all();
  1108. }
  1109. }
  1110. }
  1111. /*
  1112. * Change report status, based on drop-down list
  1113. * Currently only works for post
  1114. */
  1115. public function change_status($form_id = 0, $incident_id = 0, $status = 0) {
  1116. $this->auto_render = FALSE;
  1117. $this->template = "";
  1118. if($_POST) {
  1119. // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things
  1120. $post = Validation::factory($_POST);
  1121. $post->pre_filter('trim', TRUE);
  1122. // Add rules
  1123. $post->add_rules('incident_id', 'required');
  1124. $post->add_rules('status', 'required');
  1125. if($post->validate()) {
  1126. $incident = ORM::factory('incident', $post['incident_id']);
  1127. // Only if the incident exists
  1128. if($incident->id) {
  1129. $incident->incident_status = $post['status'];
  1130. $incident->incident_verified = ($post['status'] > 1);
  1131. $incident->incident_active = !($post['status'] == 5);
  1132. $incident->save();
  1133. }
  1134. }
  1135. }
  1136. }
  1137. /**
  1138. * Save newly added dynamic categories
  1139. */
  1140. public function save_category()
  1141. {
  1142. $this->auto_render = FALSE;
  1143. $this->template = "";
  1144. // Check, has the form been submitted, if so, setup validation
  1145. if ($_POST)
  1146. {
  1147. // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things
  1148. $post = Validation::factory($_POST);
  1149. // Add some filters
  1150. $post->pre_filter('trim', TRUE);
  1151. // Add some rules, the input field, followed by a list of checks, carried out in order
  1152. $post->add_rules('category_title','required', 'length[3,200]');
  1153. $post->add_rules('category_description','required');
  1154. $post->add_rules('category_color','required', 'length[6,6]');
  1155. // Test to see if things passed the rule checks
  1156. if ($post->validate())
  1157. {
  1158. // SAVE Category
  1159. $category = new Category_Model();
  1160. $category->category_title = $post->category_title;
  1161. $category->category_description = $post->category_description;
  1162. $category->category_color = $post->category_color;
  1163. $category->save();
  1164. $form_saved = TRUE;
  1165. echo json_encode(array("status"=>"saved", "id"=>$category->id));
  1166. }
  1167. else
  1168. {
  1169. echo json_encode(array("status"=>"error"));
  1170. }
  1171. }
  1172. else
  1173. {
  1174. echo json_encode(array("status"=>"error"));
  1175. }
  1176. }
  1177. /**
  1178. * Delete Photo
  1179. * @param int $id The unique id of the photo to be deleted
  1180. */
  1181. public function deletePhoto ($id)
  1182. {
  1183. $this->auto_render = FALSE;
  1184. $this->template = "";
  1185. if ($id)
  1186. {
  1187. $photo = ORM::factory('media', $id);
  1188. $photo_large = $photo->media_link;
  1189. $photo_medium = $photo->media_medium;
  1190. $photo_thumb = $photo->media_thumb;
  1191. if (file_exists(Kohana::config('upload.directory', TRUE).$photo_large))
  1192. {
  1193. unlink(Kohana::config('upload.directory', TRUE).$photo_large);
  1194. }
  1195. elseif (Kohana::config("cdn.cdn_store_dynamic_content") AND valid::url($photo_large))
  1196. {
  1197. cdn::delete($photo_large);
  1198. }
  1199. if (file_exists(Kohana::config('upload.directory', TRUE).$photo_medium))
  1200. {
  1201. unlink(Kohana::config('upload.directory', TRUE).$photo_medium);
  1202. }
  1203. elseif (Kohana::config("cdn.cdn_store_dynamic_content") AND valid::url($photo_medium))
  1204. {
  1205. cdn::delete($photo_medium);
  1206. }
  1207. if (file_exists(Kohana::config('upload.directory', TRUE).$photo_thumb))
  1208. {
  1209. unlink(Kohana::config('upload.directory', TRUE).$photo_thumb);
  1210. }
  1211. elseif (Kohana::config("cdn.cdn_store_dynamic_content") AND valid::url($photo_thumb))
  1212. {
  1213. cdn::delete($photo_thumb);
  1214. }
  1215. // Finally Remove from DB
  1216. $photo->delete();
  1217. }
  1218. }
  1219. /* private functions */
  1220. // Dynamic categories form fields
  1221. private function _new_categories_form_arr()
  1222. {
  1223. return array(
  1224. 'category_name' => '',
  1225. 'category_description' => '',
  1226. 'category_color' => '',
  1227. );
  1228. }
  1229. // Time functions
  1230. private function _hour_array()
  1231. {
  1232. for ($i=1; $i <= 12 ; $i++)
  1233. {
  1234. // Add Leading Zero
  1235. $hour_array[sprintf("%02d", $i)] = sprintf("%02d", $i);
  1236. }
  1237. return $hour_array;
  1238. }
  1239. private function _minute_array()
  1240. {
  1241. for ($j=0; $j <= 59 ; $j++)
  1242. {
  1243. // Add Leading Zero
  1244. $minute_array[sprintf("%02d", $j)] = sprintf("%02d", $j);
  1245. }
  1246. return $minute_array;
  1247. }
  1248. private function _ampm_array()
  1249. {
  1250. return $ampm_array = array('pm'=>Kohana::lang('ui_admin.pm'),'am'=>Kohana::lang('ui_admin.am'));
  1251. }
  1252. private function _stroke_width_array()
  1253. {
  1254. for ($i = 0.5; $i <= 8 ; $i += 0.5)
  1255. {
  1256. $stroke_width_array["$i"] = $i;
  1257. }
  1258. return $stroke_width_array;
  1259. }
  1260. // Javascript functions
  1261. private function _color_picker_js()
  1262. {
  1263. return "<script type=\"text/javascript\">
  1264. $(document).ready(function() {
  1265. $('#category_color').ColorPicker({
  1266. onSubmit: function(hsb, hex, rgb) {
  1267. $('#category_color').val(hex);
  1268. },
  1269. onChange: function(hsb, hex, rgb) {
  1270. $('#category_color').val(hex);
  1271. },
  1272. onBeforeShow: function () {
  1273. $(this).ColorPickerSetColor(this.value);
  1274. }
  1275. })
  1276. .bind('keyup', function(){
  1277. $(this).ColorPickerSetColor(this.value);
  1278. });
  1279. });
  1280. </script>";
  1281. }
  1282. private function _date_picker_js()
  1283. {
  1284. return "<script type=\"text/javascript\">
  1285. $(document).ready(function() {
  1286. $(\"#incident_date\").datepicker({
  1287. showOn: \"both\",
  1288. buttonImage: \"" . url::base() . "media/img/icon-calendar.gif\",
  1289. buttonImageOnly: true
  1290. });
  1291. });
  1292. </script>";
  1293. }
  1294. private function _new_category_toggle_js()
  1295. {
  1296. return "<script type=\"text/javascript\">
  1297. $(document).ready(function() {
  1298. $('a#category_toggle').click(function() {
  1299. $('#category_add').toggle(400);
  1300. return false;
  1301. });
  1302. });
  1303. </script>";
  1304. }
  1305. /**
  1306. * Checks if translation for this report & locale exists
  1307. * @param Validation $post $_POST variable with validation rules
  1308. * @param int $iid The unique incident_id of the original report
  1309. */
  1310. public function translate_exists_chk(Validation $post)
  1311. {
  1312. // If add->rules validation found any errors, get me out of here!
  1313. if (array_key_exists('locale', $post->errors()))
  1314. return;
  1315. $iid = (isset($_GET['iid']) AND intval($_GTE['iid'] > 0))? intval($_GET['iid']) : 0;
  1316. // Load translation
  1317. $translate = ORM::factory('incident_lang')
  1318. ->where('incident_id',$iid)
  1319. ->where('locale',$post->locale)
  1320. ->find();
  1321. if ($translate->loaded)
  1322. {
  1323. $post->add_error( 'locale', 'exists');
  1324. }
  1325. else
  1326. {
  1327. // Not found
  1328. return;
  1329. }
  1330. }
  1331. /**
  1332. * Creates a SQL string from search keywords
  1333. */
  1334. private function _get_searchstring($keyword_raw)
  1335. {
  1336. $or = '';
  1337. $where_string = '';
  1338. // Stop words that we won't search for
  1339. // Add words as needed!!
  1340. $stop_words = array('the', 'and', 'a', 'to', 'of', 'in', 'i', 'is', 'that', 'it',
  1341. 'on', 'you', 'this', 'for', 'but', 'with', 'are', 'have', 'be',
  1342. 'at', 'or', 'as', 'was', 'so', 'if', 'out', 'not');
  1343. $keywords = explode(' ', $keyword_raw);
  1344. if (is_array($keywords) AND !empty($keywords))
  1345. {
  1346. array_change_key_case($keywords, CASE_LOWER);
  1347. $i = 0;
  1348. foreach ($keywords as $value)
  1349. {
  1350. if (!in_array($value,$stop_words) AND !empty($value))
  1351. {
  1352. $chunk = $this->db->escape_str($value);
  1353. if ($i > 0)
  1354. {
  1355. $or = ' OR ';
  1356. }
  1357. $where_string = $where_string
  1358. .$or
  1359. ."incident_title LIKE '%$chunk%' OR incident_description LIKE '%$chunk%' OR location_name LIKE '%$chunk%'";
  1360. $i++;
  1361. }
  1362. }
  1363. }
  1364. // Return
  1365. return $where_string;
  1366. }
  1367. private function _csv_text($text)
  1368. {
  1369. $text = stripslashes(htmlspecialchars($text));
  1370. return $text;
  1371. }
  1372. }