public function index() { $settings = ORM::factory('settings')->find(1); $site_name = $settings->site_name; $alerts_email = $settings->alerts_email; $unsubscribe_message = Kohana::lang('alerts.unsubscribe') . url::site() . 'alerts/unsubscribe/'; $sms_from = NULL; $clickatell = NULL; $miles = FALSE; // Change to True to calculate distances in Miles $max_recipients = 20; // Limit each script execution to 50 recipients if ($settings->email_smtp == 1) { Kohana::config_set('email.driver', 'smtp'); Kohana::config_set('email.options', array('hostname' => $settings->alerts_host, 'port' => $settings->alerts_port, 'username' => $settings->alerts_username, 'password' => $settings->alerts_password)); } $db = new Database(); /* Find All Alerts with the following parameters - incident_active = 1 -- An approved incident - incident_alert_status = 1 -- Incident has been tagged for sending Incident Alert Statuses - 0, Incident has not been tagged for sending. Ensures old incidents are not sent out as alerts - 1, Incident has been tagged for sending by updating it with 'approved' or 'verified' - 2, Incident has been tagged as sent. No need to resend again */ // 1 - Retrieve All the Incidents that haven't been sent (Process only 1 per script execution) $incidents = $db->query("\n\t\t\t\t\t\t\t\t SELECT incident.id, incident_title, \n\t\t\t\t\t\t\t\t incident_description, incident_verified, \n\t\t\t\t\t\t\t\t location.latitude, location.longitude\n\t\t\t\t\t\t\t\t FROM incident\n\t\t\t\t\t\t\t\t INNER JOIN location on location.id = incident.location_id\n\t\t\t\t\t\t\t\t WHERE incident.incident_active=1 AND incident.incident_alert_status = 1 LIMIT 1\n\t\t\t\t\t\t\t\t"); foreach ($incidents as $incident) { $latitude = (double) $incident->latitude; $longitude = (double) $incident->longitude; // 2 - Retrieve All Qualifying Alertees Based on Distance and Make sure they haven't received this alert, // Return Alertees if they haven't requested a Category OR Return Alertees if they specifically asked // for this incident region and specific category. $distance_type = $miles ? "" : " * 1.609344"; $alertees = $db->query(' SELECT DISTINCT alert.*, ((ACOS(SIN(' . $latitude . ' * PI() / 180) * SIN(`alert`.`alert_lat` * PI() / 180) + COS(' . $latitude . ' * PI() / 180) * COS(`alert`.`alert_lat` * PI() / 180) * COS((' . $longitude . ' - `alert`.`alert_lon`) * PI() / 180)) * 180 / PI()) * 60 * 1.1515 ' . $distance_type . ') AS distance FROM alert WHERE alert.alert_confirmed = 1 HAVING distance <= alert_radius '); $i = 0; foreach ($alertees as $alertee) { // 3 - Has this incident alert been sent to this alertee? $alert_sent = ORM::factory('alert_sent')->where('alert_id', $alertee->id)->where('incident_id', $incident->id)->find(); $requested_category = true; $alert_categories = ORM::factory('alert_category')->select("alert_category.category_id")->where('alert_id', $alertee->id)->find_all(); // The Alertee requested specific categories for the incident. // Make sure the categories are part of this incident. $requested_category = alert::requested_category($alert_categories, $incident->id); // Alert has not been sent and the alertee requested the incident with the category if ($alert_sent->loaded == FALSE && $requested_category) { // 4 - Get Alert Type. 1=SMS, 2=EMAIL $alert_type = (int) $alertee->alert_type; if ($alert_type == 1) { // Save this first $alert = ORM::factory('alert_sent'); $alert->alert_id = $alertee->id; $alert->incident_id = $incident->id; $alert->alert_date = date("Y-m-d H:i:s"); $alert->save(); // Get SMS Numbers if (!empty($settings->sms_no3)) { $sms_from = $settings->sms_no3; } elseif (!empty($settings->sms_no2)) { $sms_from = $settings->sms_no2; } elseif (!empty($settings->sms_no1)) { $sms_from = $settings->sms_no1; } else { $sms_from = "000"; } // Admin needs to set up an SMS number $clickatell = new Clickatell(); $clickatell->api_id = $settings->clickatell_api; $clickatell->user = $settings->clickatell_username; $clickatell->password = $settings->clickatell_password; $clickatell->use_ssl = false; $clickatell->sms(); $message = text::limit_chars($incident->incident_description, 150, "..."); //++ We won't verify for now if sms was sent // Leaves too much room for duplicates to be sent out $clickatell->send($alertee->alert_recipient, $sms_from, $message); } elseif ($alert_type == 2) { // Save this first $alert = ORM::factory('alert_sent'); $alert->alert_id = $alertee->id; $alert->incident_id = $incident->id; $alert->alert_date = date("Y-m-d H:i:s"); $alert->save(); //for some reason, mail function complains about bad parameters // in the function so i'm disallowing these characters in the // subject field to allow the mail function to work. $disallowed_chars = array("(", ")", "[", "]", "-"); $to = $alertee->alert_recipient; $from = $alerts_email; $subject = trim(str_replace($disallowed_chars, "", $site_name) . ": " . str_replace($disallowed_chars, "", $incident->incident_title)); $message = $incident->incident_description . "<p>" . url::base() . "reports/view/" . $incident->id . "</p>" . "<p>" . $unsubscribe_message . "?c=" . $alertee->alert_code . "</p>"; //++ We won't verify for now if email was sent // Leaves too much room for duplicates to be sent out email::send($to, $from, $subject, $message, TRUE); } sleep(1); $i++; } if ($i == $max_recipients) { exit; } } // End For Each Loop // Update Incident - All Alerts Have Been Sent! $update_incident = ORM::factory('incident', $incident->id); if ($update_incident->loaded) { $update_incident->incident_alert_status = 2; $update_incident->save(); } } }