/** * Traverses an array containing category data and returns a tree view * * @param array $category_data * @return string */ private static function _generate_treeview_html($category_data) { // To hold the treeview HTMl $tree_html = ""; foreach ($category_data as $id => $category) { // Determine the category class $category_class = $category['parent_id'] > 0 ? " class=\"report-listing-category-child\"" : ""; $category_image = $category['category_image_thumb'] ? html::image(array('src' => url::convert_uploaded_to_abs($category['category_image_thumb']), 'style' => 'float:left;padding-right:5px;')) : NULL; $tree_html .= "<li" . $category_class . ">" . "<a href=\"#\" class=\"cat_selected\" id=\"filter_link_cat_" . $id . "\" title=\"{$category['category_description']}\">" . "<span class=\"item-swatch\" style=\"background-color: #" . $category['category_color'] . "\">{$category_image}</span>" . "<span class=\"item-title\">" . html::strip_tags($category['category_title']) . "</span>" . "<span class=\"item-count\">" . $category['report_count'] . "</span>" . "</a></li>"; $tree_html .= self::_generate_treeview_html($category['children']); } // Return return $tree_html; }
if ($total_items == 0) { ?> <tr> <td colspan="4" class="col"> <h3><?php echo Kohana::lang('ui_main.no_results'); ?> </h3> </td> </tr> <?php } foreach ($incidents as $incident) { $incident_id = $incident->id; $incident_title = html::escape($incident->incident_title); $incident_description = text::limit_chars(html::strip_tags($incident->incident_description), 150, "...", true); $incident_date = $incident->incident_date; $incident_date = date('Y-m-d', strtotime($incident->incident_date)); $incident_mode = $incident->incident_mode; // Mode of submission... WEB/SMS/EMAIL? //XXX incident_Mode will be discontinued in favour of $service_id if ($incident_mode == 1) { $submit_mode = "WEB"; // Who submitted the report? if ($incident->incident_person->id) { // Report was submitted by a visitor $submit_by = $incident->incident_person->person_first . " " . $incident->incident_person->person_last; } else { if ($incident->user_id) { $submit_by = $incident->user->name; } else {
<td colspan="4" class="col"> <h3><?php echo Kohana::lang('ui_main.no_results'); ?> </h3> </td> </tr> <?php } foreach ($messages as $message) { $message_id = $message->id; $message_from = html::strip_tags($message->reporter->service_account); $message_to = html::strip_tags($message->message_to); $incident_id = $message->incident_id; $message_description = text::auto_link(html::strip_tags($message->message)); $message_detail = nl2br(text::auto_link(html::strip_tags($message->message_detail))); $message_date = date('Y-m-d H:i', strtotime($message->message_date)); $message_type = $message->message_type; $message_level = $message->message_level; $latitude = $message->latitude; $longitude = $message->longitude; $level_id = $message->reporter->level_id; ?> <tr <?php if ($message_level == "99") { echo " class=\"spam_tr\""; } ?> > <td class="col-1"><input name="message_id[]" id="message" value="<?php echo $message_id;
/** * Read in new layer JSON from shared connection * @param int $sharing_id - ID of the new Share Layer */ public function index($sharing_id = FALSE) { $json = ''; $json_item = array(); $json_features = array(); $sharing_data = ""; $clustering = Kohana::config('settings.allow_clustering'); if ($sharing_id) { // Get This Sharing ID Color $sharing = ORM::factory('sharing')->find($sharing_id); if (!$sharing->loaded) { throw new Kohana_404_Exception(); } $sharing_url = sharing_helper::clean_url($sharing->sharing_url); $sharing_color = $sharing->sharing_color; if ($clustering) { // Database $db = new Database(); // Start Date $start_date = (isset($_GET['s']) and !empty($_GET['s'])) ? (int) $_GET['s'] : "0"; // End Date $end_date = (isset($_GET['e']) and !empty($_GET['e'])) ? (int) $_GET['e'] : "0"; // SouthWest Bound $southwest = (isset($_GET['sw']) and !empty($_GET['sw'])) ? $_GET['sw'] : "0"; $northeast = (isset($_GET['ne']) and !empty($_GET['ne'])) ? $_GET['ne'] : "0"; // Get Zoom Level $zoomLevel = (isset($_GET['z']) and !empty($_GET['z'])) ? (int) $_GET['z'] : 8; //$distance = 60; $distance = (10000000 >> $zoomLevel) / 100000; $filter = ""; $filter .= $start_date ? " AND incident_date >= '" . date("Y-m-d H:i:s", $start_date) . "'" : ""; $filter .= $end_date ? " AND incident_date <= '" . date("Y-m-d H:i:s", $end_date) . "'" : ""; if ($southwest and $northeast) { list($latitude_min, $longitude_min) = explode(',', $southwest); list($latitude_max, $longitude_max) = explode(',', $northeast); $filter .= " AND latitude >=" . (double) $latitude_min . " AND latitude <=" . (double) $latitude_max; $filter .= " AND longitude >=" . (double) $longitude_min . " AND longitude <=" . (double) $longitude_max; } $filter .= " AND sharing_id = " . (int) $sharing_id; $query = $db->query("SELECT * FROM `" . $this->table_prefix . "sharing_incident` WHERE 1=1 {$filter} ORDER BY incident_id ASC "); $markers = $query->result_array(FALSE); $clusters = array(); // Clustered $singles = array(); // Non Clustered // Loop until all markers have been compared while (count($markers)) { $marker = array_pop($markers); $cluster = array(); // Compare marker against all remaining markers. foreach ($markers as $key => $target) { // This function returns the distance between two markers, at a defined zoom level. // $pixels = $this->_pixelDistance($marker['latitude'], $marker['longitude'], // $target['latitude'], $target['longitude'], $zoomLevel); $pixels = abs($marker['longitude'] - $target['longitude']) + abs($marker['latitude'] - $target['latitude']); // echo $pixels."<BR>"; // If two markers are closer than defined distance, remove compareMarker from array and add to cluster. if ($pixels < $distance) { unset($markers[$key]); $target['distance'] = $pixels; $cluster[] = $target; } } // If a marker was added to cluster, also add the marker we were comparing to. if (count($cluster) > 0) { $cluster[] = $marker; $clusters[] = $cluster; } else { $singles[] = $marker; } } // Create Json foreach ($clusters as $cluster) { // Calculate cluster center $bounds = $this->calculate_center($cluster); $cluster_center = array_values($bounds['center']); $southwest = $bounds['sw']['longitude'] . ',' . $bounds['sw']['latitude']; $northeast = $bounds['ne']['longitude'] . ',' . $bounds['ne']['latitude']; // Number of Items in Cluster $cluster_count = count($cluster); $link = $sharing_url . "/reports/index/?c=0&sw=" . $southwest . "&ne=" . $northeast; $item_name = $this->get_title(Kohana::lang('ui_main.reports_count', $cluster_count), $link); $json_item = array(); $json_item['type'] = 'Feature'; $json_item['properties'] = array('name' => $item_name, 'link' => $link, 'category' => array(0), 'color' => $sharing_color, 'icon' => '', 'thumb' => '', 'timestamp' => 0, 'count' => $cluster_count); $json_item['geometry'] = array('type' => 'Point', 'coordinates' => $cluster_center); array_push($json_features, $json_item); } foreach ($singles as $single) { $link = $sharing_url . "/reports/view/" . $single['id']; $item_name = $this->get_title(html::strip_tags($single['incident_title']), $link); $json_item = array(); $json_item['type'] = 'Feature'; $json_item['properties'] = array('name' => $item_name, 'link' => $link, 'category' => array(0), 'color' => $sharing_color, 'icon' => '', 'timestamp' => 0, 'count' => 1); $json_item['geometry'] = array('type' => 'Point', 'coordinates' => array($single['longitude'], $single['latitude'])); array_push($json_features, $json_item); } } else { // Retrieve all markers $markers = ORM::factory('sharing_incident')->where('sharing_id', $sharing_id)->find_all(); foreach ($markers as $marker) { $link = $sharing_url . "/reports/view/" . $marker->incident_id; $item_name = $this->get_title($marker->incident_title, $link); $json_item = array(); $json_item['type'] = 'Feature'; $json_item['properties'] = array('id' => $marker->incident_id, 'name' => $item_name, 'link' => $link, 'color' => $sharing_color, 'icon' => '', 'timestamp' => strtotime($marker->incident_date)); $json_item['geometry'] = array('type' => 'Point', 'coordinates' => array($marker->longitude, $marker->latitude)); array_push($json_features, $json_item); } } Event::run('ushahidi_filter.json_share_features', $json_features); $json = json_encode(array("type" => "FeatureCollection", "features" => $json_features)); } header('Content-type: application/json; charset=utf-8'); echo $json; }
/** * Create a report and assign it to one or more categories and set verification */ public function __response_create_report($vars) { $categories = array(); if (isset($vars['add_category'])) { $categories = $vars['add_category']; } $verify = 0; if (isset($vars['verify'])) { $verify = (int) $vars['verify']; } $approve = 0; if (isset($vars['approve'])) { $approve = (int) $vars['approve']; } // Grab the location_id or create one if we can $location_id = 0; if (isset($this->data->location_id)) { $location_id = $this->data->location_id; } elseif (isset($this->data->latitude) and isset($this->data->longitude)) { $location_name = map::reverse_geocode($this->data->latitude, $this->data->longitude); // In case our location name is too long, chop off the end $location_name = substr_replace($location_name, '', 250); $location_data = (object) array('location_name' => $location_name, 'latitude' => $this->data->latitude, 'longitude' => $this->data->longitude); $location = new Location_Model(); reports::save_location($location_data, $location); $location_id = $location->id; } // We can only create reports if we have location. if ($location_id == FALSE or $location_id == 0) { return false; } // Build title // Build title & description // If this is a message if (isset($this->data->message)) { $incident_title = $this->data->message; $incident_description = $this->data->message; $incident_date = $this->data->message_date; // If we're got more message detail, make that the description if (!empty($message->message_detail)) { $incident_description = $this->data->message_detail; } } elseif (isset($this->data->item_title)) { $incident_title = html::strip_tags(html_entity_decode(html_entity_decode($this->data->item_title, ENT_QUOTES))); $incident_description = html::clean(html_entity_decode($this->data->item_description, ENT_QUOTES)); $incident_date = $this->data->item_date; } // Override title from action options if (!empty($vars['report_title'])) { $incident_title = $vars['report_title']; } // Save Incident $incident = new Incident_Model(); $incident->location_id = $location_id; $incident->incident_title = $incident_title; $incident->incident_description = $incident_description; $incident->incident_date = $incident_date; $incident->incident_active = $approve; $incident->incident_verified = $verify; $incident->incident_dateadd = date("Y-m-d H:i:s", time()); $incident->save(); // Conflicted.. do I run report add here? Potential to create a mess with action triggers? //Event::run('ushahidi_action.report_add', $incident); // Save media if (isset($this->data->item_title)) { $news = new Media_Model(); $news->location_id = $incident->location_id; $news->incident_id = $incident->id; $news->media_type = 4; // News $news->media_link = $this->data->item_link; $news->media_date = $this->data->item_date; $news->save(); } $incident_id = $incident->id; foreach ($categories as $category_id) { // Assign Category Incident_Category_Model::assign_category_to_incident($incident_id, $category_id); } // Link message with incident? if (isset($this->data->message) and isset($this->data->id)) { $message = new Message_Model($this->data->id); $message->incident_id = $incident_id; $message->save(); } elseif (isset($this->data->item_title) and isset($this->data->id)) { $item = new Feed_Item_Model($this->data->id); $item->incident_id = $incident_id; $item->save(); } return TRUE; }
</th> </tr> </thead> <tbody> <?php if ($incidents->count() == 0) { ?> <tr><td colspan="3"><?php echo Kohana::lang('ui_main.no_reports'); ?> </td></tr> <?php } foreach ($incidents as $incident) { $incident_id = $incident->id; $incident_title = text::limit_chars(html::strip_tags($incident->incident_title), 40, '...', True); $incident_date = $incident->incident_date; $incident_date = date('M j Y', strtotime($incident->incident_date)); $incident_location = $incident->location->location_name; ?> <tr> <td><a href="<?php echo url::site() . 'reports/view/' . $incident_id; ?> "> <?php echo $incident_title; ?> </a></td> <td><?php echo html::escape($incident_location); ?>
/** * Submit comments * * @return int */ private function _add_comment() { $api_akismet = Kohana::config('settings.api_akismet'); // Comment Post? // Setup and initialize form field names $form = array('incident_id' => '', 'comment_author' => '', 'comment_description' => '', 'comment_email' => ''); $captcha = Captcha::factory(); $errors = $form; $form_error = FALSE; $ret_value = 0; // Check, has the form been submitted, if so, setup validation if ($_POST and Kohana::config('settings.allow_comments')) { // Instantiate Validation, use $post, so we don't overwrite $_POST fields with our own things $post = Validation::factory($_POST); // Add some filters $post->pre_filter('trim', TRUE); // Add some rules, the input field, followed by a list of checks, carried out in order // We can have either a checkin id or an incident id if (isset($post->checkin_id)) { $post->add_rules('checkin_id', 'required'); } else { $post->add_rules('incident_id', 'required'); } // If the user isn't posting an email and author name, then they need to log in if (empty($post->comment_author) or empty($post->comment_email)) { if (!$this->api_service->_login()) { $this->set_error_message($this->response(2)); return; } } // Grab variables for a logged in user $auth = Auth::instance(); // Is user previously authenticated? if ($auth->logged_in()) { $user_id = $auth->get_user()->id; } else { $user_id = NULL; $post->add_rules('comment_author', 'required', 'length[3,100]'); $post->add_rules('comment_email', 'required', 'email', 'length[4,100]'); } $post->add_rules('comment_description', 'required'); // Test to see if things passed the rule checks if ($post->validate(FALSE)) { // Yes! everything is valid $incident_id = NULL; $checkin_id = NULL; if (isset($post->checkin_id)) { $checkin = ORM::factory('checkin')->where('id', $post->checkin_id)->find(); if ($checkin->id == 0) { return $this->response(1, "No checkins with that ID"); } $checkin_id = $post->checkin_id; $comment_url = ''; $comment_title = $checkin->checkin_description; } else { $incident = ORM::factory('incident')->where('id', $post->incident_id)->where('incident_active', 1)->find(); if ($incident->id == 0) { return $this->response(1, "No incidents with that ID"); } $incident_id = $post->incident_id; $comment_url = url::base() . 'reports/view/' . $post->incident_id; $comment_title = $incident->incident_title; } if ($user_id == NULL) { $comment_author = $post->comment_author; $comment_email = $post->comment_email; } else { $comment_author = $auth->get_user()->name; $comment_email = $auth->get_user()->email; } if ($api_akismet != "") { // Run Akismet Spam Checker $akismet = new Akismet(); // Comment data $comment = array('author' => $comment_author, 'email' => $comment_email, 'website' => "", 'body' => $post->comment_description, 'user_ip' => $_SERVER['REMOTE_ADDR']); $config = array('blog_url' => url::site(), 'api_key' => $api_akismet, 'comment' => $comment); $akismet->init($config); if ($akismet->errors_exist()) { if ($akismet->is_error('AKISMET_INVALID_KEY')) { // throw new Kohana_Exception('akismet.api_key'); } elseif ($akismet->is_error('AKISMET_RESPONSE_FAILED')) { // throw new Kohana_Exception('akismet.server_failed'); } elseif ($akismet->is_error('AKISMET_SERVER_NOT_FOUND')) { // throw new Kohana_Exception('akismet.server_not_found'); } // If the server is down, we have to post // the comment :( // $this->_post_comment($comment); $comment_spam = 0; } else { $comment_span = $akismet->is_spam() ? 1 : 0; } } else { // No API Key!! $comment_spam = 0; } $comment = new Comment_Model(); $comment->incident_id = intval($incident_id); $comment->checkin_id = intval($checkin_id); $comment->comment_author = html::strip_tags($comment_author, FALSE); $comment->comment_description = html::strip_tags($post->comment_description, FALSE); $comment->comment_email = html::strip_tags($comment_email, FALSE); $comment->comment_ip = $_SERVER['REMOTE_ADDR']; $comment->comment_date = date("Y-m-d H:i:s", time()); // Activate comment for now if ($comment_spam == 1) { $comment->comment_spam = 1; $comment->comment_active = 0; } else { $comment->comment_spam = 0; // 1 - Auto-approve, 0 - Manually approve $comment->comment_active = Kohana::config('settings.allow_comments') == 1 ? 1 : 0; } $comment->save(); // Notify Admin Of New Comment $send = notifications::notify_admins("[" . Kohana::config('settings.site_name') . "] " . Kohana::lang('notifications.admin_new_comment.subject'), Kohana::lang('notifications.admin_new_comment.message') . "\n\n'" . $comment_title . "'" . "\n" . $comment_url . "\n\n" . strip_tags($post->comment_description)); } else { // No! We have validation errors, we need to show the form again, with the errors // Repopulate the form fields $form = arr::overwrite($form, $post->as_array()); // Populate the error fields, if any $errors = arr::overwrite($errors, $post->errors('comments')); foreach ($errors as $error_item => $error_description) { if (!is_array($error_description)) { $this->error_messages .= $error_description; if ($error_description != end($errors)) { $this->error_messages .= " - "; } } } $ret_value = 1; // Validation error } } else { $ret_value = 3; } return $this->response($ret_value, $this->error_messages); }
?> </h3> </td> </tr> <?php } ?> <?php foreach ($checkins as $checkin) { $checkin_id = $checkin->id; $incident_id = $checkin->incident_id; $location = $checkin->location->location_name; $latitude = $checkin->location->latitude; $longitude = $checkin->location->longitude; $description = $checkin->checkin_description; $preview = text::limit_chars(html::strip_tags($description), 150, "...", true); $checkin_date = date('Y-m-d h:i', strtotime($checkin->checkin_date)); $auto_checkin = $checkin->checkin_auto ? "YES" : "NO"; ?> <tr> <td class="col-1"><input name="checkin_id[]" id="checkin" value="<?php echo $checkin_id; ?> " type="checkbox" class="check-box"/></td> <td class="col-2"> <div class="post"> <p><?php echo $preview; ?> </p> <p><a href="javascript:showCheckin('checkin_preview_<?php
<div class="report-comments"> <h5><?php echo Kohana::lang('ui_main.comments'); ?> </h5> <?php foreach ($incident_comments as $comment) { ?> <div class="report-comment-box"> <div> <strong><?php echo html::strip_tags($comment->comment_author); ?> </strong> (<?php echo date('M j Y', strtotime($comment->comment_date)); ?> ) </div> <div><?php echo html::escape($comment->comment_description); ?> </div> </div> <?php }
foreach ($messages as $priv_message) { $message_id = $priv_message->id; $parent_id = $priv_message->parent_id ? $priv_message->parent_id : $message_id; if ($priv_message->user_id == $user_id) { $message_from_user = ORM::factory("user", $priv_message->from_user_id); } else { $message_from_user = ORM::factory("user", $priv_message->user_id); } if ($message_from_user->loaded) { $message_from = $message_from_user->name; } else { $message_from = Kohana::lang('ui_admin.unknown'); } $subject = $priv_message->private_subject; $message = text::auto_link($priv_message->private_message); $message_preview = text::limit_chars(html::strip_tags($message), 150, "...", true); $message_date = date('Y-m-d', strtotime($priv_message->private_message_date)); $message_new = $priv_message->private_message_new; ?> <tr> <td class="col-1"><input name="message_id[]" id="message" value="<?php echo $message_id; ?> " type="checkbox" class="check-box"/></td> <td class="col-2"> <div class="post"> <p><?php echo $subject; ?> </p> <p><a href="javascript:preview('message_preview_<?php
// How the person feels is a concat of categories on the report $how_feel = ''; foreach ($incident->category as $category) { $how_feel .= $category->category_title . ', '; } $how_feel = trim($how_feel, ', '); // Why they feel this way and how they would change it are custom form fields $why_feel = ''; $change_place = ''; $custom_data = customforms::get_custom_form_fields($incident_id); foreach ($custom_data as $custom) { switch ($custom['field_id']) { case '1': $why_feel = text::limit_chars(html::strip_tags($custom['field_response']), 100, '...', True); case '2': $change_place = text::limit_chars(html::strip_tags($custom['field_response']), 100, '...', True); } } $incident_image = false; foreach ($incident->media as $media) { if ($media->media_type == 1) { $incident_image = url::convert_uploaded_to_abs($media->media_thumb); } } ?> <tr> <td><a href="<?php echo url::site() . 'reports/view/' . $incident_id; ?> "> <?php echo $incident_title;
$page_id = $page->id; $page_title = $page->page_title; $page_tab = $page->page_tab; $page_description = $page->page_description; $page_active = $page->page_active; ?> <tr> <td class="col-1"> </td> <td class="col-2"> <div class="post"> <h4><?php echo html::escape($page_title); ?> </h4> <p><?php echo text::limit_chars(html::strip_tags($page_description), "100", "..."); ?> </p> </div> </td> <td class="col-4"> <ul> <li class="none-separator"><a href="#add" onClick="fillFields( '<?php echo rawurlencode($page_id); ?> ', '<?php echo base64_encode($page_title); ?>
/** * Get messages according to a search criteria * * @param string search criteria (RFC2060, sec. 6.4.4). Set to "UNSEEN" by default * NB: Search criteria only affects IMAP mailboxes. * @param string date format. Set to "Y-m-d H:i:s" by default * @return mixed array containing messages */ public function get_messages($search_criteria = "UNSEEN", $date_format = "Y-m-d H:i:s") { global $htmlmsg, $plainmsg, $attachments; // If our imap connection failed earlier, return no messages if ($this->imap_stream == false) { return array(); } // Use imap_search() to find the 'UNSEEN' messages. // This is more efficient than previous code using imap_num_msg() $new_msgs = imap_search($this->imap_stream, 'UNSEEN'); $max_imap_messages = Kohana::config('email.max_imap_messages'); if ($new_msgs == null) { return array(); } // Check to see if the number of messages we want to sort through is greater than // the number of messages we want to allow. If there are too many messages, it // can fail and that's no good. $msg_to_pull = sizeof($new_msgs); // This check has had problems in the past if ($msg_to_pull > $max_imap_messages) { $msg_to_pull = $max_imap_messages; } $messages = array(); for ($msgidx = 0; $msgidx < $msg_to_pull; $msgidx++) { $msgno = $new_msgs[$msgidx]; $header = imap_headerinfo($this->imap_stream, $msgno); if (!isset($header->message_id) or !isset($header->udate)) { continue; } // Skip messages that aren't new/unseen // not sure we need this check now we use imap_search to pull only UNSEEN if ($header->Unseen != 'U' and $header->Recent != 'N') { continue; } $message_id = $header->message_id; $date = date($date_format, $header->udate); if (isset($header->from)) { $from = $header->from; } else { $from = FALSE; } $fromname = ""; $fromaddress = ""; $subject = ""; $body = ""; $attachments = ""; if ($from != FALSE) { foreach ($from as $id => $object) { if (isset($object->personal)) { $fromname = $object->personal; } if (isset($object->mailbox) and isset($object->host)) { $fromaddress = $object->mailbox . "@" . $object->host; } if ($fromname == "") { // In case from object doesn't have Name $fromname = $fromaddress; } } } if (isset($header->subject)) { $subject = $this->_mime_decode($header->subject); } // Fetch Body $this->_getmsg($this->imap_stream, $msgno); if ($htmlmsg) { // Convert HTML to Text $html2text = new Html2Text($htmlmsg); $htmlmsg = $html2text->get_text(); } $body = $plainmsg ? $plainmsg : $htmlmsg; // Fetch Attachments $attachments = $this->_extract_attachments($this->imap_stream, $msgno); // This isn't the perfect solution but windows-1256 encoding doesn't work with mb_detect_encoding() // so if it doesn't return an encoding, lets assume it's arabic. (sucks) if (mb_detect_encoding($body, 'auto', TRUE) == '') { $body = iconv("windows-1256", "UTF-8", $body); } // Convert to valid UTF8 $detected_encoding = mb_detect_encoding($body, "auto"); if ($detected_encoding == 'ASCII') { $detected_encoding = 'iso-8859-1'; } $body = mb_convert_encoding($body, $detected_encoding, 'UTF-8'); $body = html::escape($body); $subject = html::strip_tags($subject); array_push($messages, array('message_id' => $message_id, 'date' => $date, 'from' => $fromname, 'email' => $fromaddress, 'subject' => $subject, 'body' => $body, 'attachments' => $attachments)); // Mark Message As Read imap_setflag_full($this->imap_stream, $msgno, "\\Seen"); } return $messages; }