/**
  * Responds to requests activated from the main emergency alert button.
  *
  * @link https://developer.wordpress.org/reference/hooks/wp_ajax__requestaction/
  *
  * @global $_POST
  *
  * @uses WP_Buoy_Plugin::$prefix
  * @uses check_ajax_referer()
  * @uses get_current_user_id()
  * @uses WP_Buoy_User_Settings::get()
  * @uses sanitize_text_field()
  * @uses stripslashes_deep()
  * @uses WP_Buoy_Alert::set()
  * @uses WP_Buoy_Alert::save()
  * @uses WP_Buoy_Alert::get_hash()
  * @uses wp_send_json_error()
  * @uses wp_send_json_success()
  * @uses wp_safe_redirect()
  *
  * @return void
  */
 public static function handleNewAlert()
 {
     check_ajax_referer(self::$prefix . '_new_alert', self::$prefix . '_nonce');
     $postarr = array();
     $meta_input = array();
     // Collect info from the browser via Ajax request
     $alert_position = empty($_POST['pos']) ? false : $_POST['pos'];
     // TODO: array_map and sanitize this?
     if ($alert_position) {
         $meta_input['geo_latitude'] = $alert_position['latitude'];
         $meta_input['geo_longitude'] = $alert_position['longitude'];
     }
     if (isset($_POST[self::$prefix . '_teams']) && is_array($_POST[self::$prefix . '_teams'])) {
         $my_teams = array_map('absint', $_POST[self::$prefix . '_teams']);
         $valid_teams = array();
         foreach ($my_teams as $team_id) {
             $team = new WP_Buoy_Team($team_id);
             if (get_current_user_id() == $team->wp_post->post_author) {
                 $valid_teams[] = $team_id;
             }
         }
         $meta_input[self::$prefix . '_teams'] = $valid_teams;
     }
     // Create and publish the new alert.
     $buoy_user = new WP_Buoy_User(get_current_user_id());
     $postarr['post_title'] = empty($_POST['msg']) ? $buoy_user->get_crisis_message() : sanitize_text_field(stripslashes_deep($_POST['msg']));
     if (!empty($meta_input)) {
         $postarr['meta_input'] = $meta_input;
     }
     $err = new WP_Error();
     if (isset($_POST['scheduled-datetime-utc'])) {
         // TODO: Scheduled alerts should be their own function?
         $old_timezone = date_default_timezone_get();
         date_default_timezone_set('UTC');
         $when_utc = strtotime(stripslashes_deep($_POST['scheduled-datetime-utc']));
         if (!$when_utc) {
             $err->add('scheduled-datetime-utc', __('Buoy could not understand the date and time you entered.', 'buoy'));
         } else {
             $dt = new DateTime("@{$when_utc}");
             // TODO: This fails to offset the UTC time back to server-local time
             //       correctly if the WP site is manually offset by a 30 minute
             //       offset instead of an hourly offset.
             $dt->setTimeZone(new DateTimeZone(wp_get_timezone_string()));
             $postarr['post_date'] = $dt->format('Y-m-d H:i:s');
             $postarr['post_date_gmt'] = gmdate('Y-m-d H:i:s', $when_utc);
             $postarr['post_status'] = 'future';
         }
         date_default_timezone_set($old_timezone);
     }
     $buoy_alert = new self();
     $post_id = $buoy_alert->set($postarr)->save();
     if (is_wp_error($post_id)) {
         wp_send_json_error($post_id);
     } else {
         if (!empty($err->errors)) {
             wp_send_json_error($err);
         } else {
             if (isset($_POST['scheduled-datetime-utc']) && empty($err->errors)) {
                 wp_send_json_success(array('id' => $post_id, 'message' => __('Your timed alert has been scheduled. Schedule another?', 'buoy')));
             } else {
                 // Construct the redirect URL to the alerter's chat room
                 $next_url = wp_nonce_url(admin_url('?page=' . self::$prefix . '_chat' . '&' . self::$prefix . '_hash=' . $buoy_alert->get_hash()), self::$prefix . '_chat', self::$prefix . '_nonce');
                 if (isset($_SERVER['HTTP_ACCEPT'])) {
                     $accepts = explode(',', $_SERVER['HTTP_ACCEPT']);
                 }
                 if ($accepts && 'application/json' === array_shift($accepts)) {
                     wp_send_json_success($next_url);
                 } else {
                     wp_safe_redirect(html_entity_decode($next_url));
                     exit;
                 }
             }
         }
     }
 }
 /**
  * Checks to ensure a user doesn't leave themselves without any
  * responders.
  *
  * Teams are only "active" is they are in the "publish" status.
  * This checks a team transition and if the action leaves a user
  * without any responders, it will re-set the team's status.
  *
  * @link https://developer.wordpress.org/reference/hooks/post_updated/
  *
  * @uses WP_Buoy_User::has_responder()
  * @uses WP_Buoy_Team::is_default()
  * @uses WP_Buoy_Team::make_default()
  *
  * @param int $post_id
  * @param WP_Post $post_after
  * @param WP_Post $post_before
  *
  * @return void
  */
 public static function postUpdated($post_id, $post_after, $post_before)
 {
     if (self::$prefix . '_team' !== $post_after->post_type) {
         return;
     }
     $buoy_user = new WP_Buoy_User($post_before->post_author);
     // Prevent the user from trashing their last responder team.
     if ('publish' === $post_before->post_status && 'publish' !== $post_after->post_status) {
         if (!$buoy_user->has_responder()) {
             wp_update_post(array('ID' => $post_id, 'post_status' => 'publish'));
         }
     }
     // Re-set the default team if the default team is trashed.
     $team = new WP_Buoy_Team($post_id);
     if ('trash' === $post_after->post_status && $team->is_default()) {
         $teams = $buoy_user->get_teams();
         $next_team = new WP_Buoy_Team(array_pop($teams));
         $next_team->make_default();
     }
 }
Exemple #3
0
 /**
  * Loads plugin componentry and calls that component's register()
  * method. Called at the WordPress `init` hook.
  *
  * @uses WP_Buoy_Settings::register()
  * @uses WP_Buoy_Team::register()
  * @uses WP_Buoy_Notification::register()
  * @uses WP_Buoy_User::register()
  * @uses WP_Buoy_Alert::register()
  *
  * @return void
  */
 public static function initialize()
 {
     require_once 'class-buoy-settings.php';
     require_once 'class-buoy-user-settings.php';
     require_once 'class-buoy-team.php';
     require_once 'class-buoy-notification.php';
     require_once 'class-buoy-user.php';
     require_once 'class-buoy-alert.php';
     require_once 'includes/class-wp-screen-help-loader.php';
     WP_Buoy_Settings::register();
     WP_Buoy_Team::register();
     WP_Buoy_Notification::register();
     WP_Buoy_User::register();
     WP_Buoy_Alert::register();
 }
 /**
  * Runs whenever an alert is published. Sends notifications to an
  * alerter's response team informing them of the alert.
  *
  * @param int $post_id
  * @param WP_Post $post
  *
  * @return void
  */
 public static function publishAlert($post_id, $post)
 {
     $alert = new WP_Buoy_Alert($post_id);
     $responder_link = admin_url('?page=' . self::$prefix . '_review_alert' . '&' . self::$prefix . '_hash=' . $alert->get_hash());
     $responder_short_link = home_url('?' . self::$prefix . '_alert=' . substr($alert->get_hash(), 0, 8));
     $subject = $post->post_title;
     $alerter = get_userdata($post->post_author);
     $headers = array("From: \"{$alerter->display_name}\" <{$alerter->user_email}>");
     foreach ($alert->get_teams() as $team_id) {
         $team = new WP_Buoy_Team($team_id);
         foreach ($team->get_confirmed_members() as $user_id) {
             $responder = new WP_Buoy_User($user_id);
             // TODO: Write a more descriptive message.
             wp_mail($responder->wp_user->user_email, $subject, $responder_link, $headers);
             $smsemail = $responder->get_sms_email();
             if (!empty($smsemail)) {
                 $sms_max_length = 160;
                 // We need to ensure that SMS notifications fit within the 160 character
                 // limit of SMS transmissions. Since we're using email-to-SMS gateways,
                 // a subject will be wrapped inside of parentheses, making it two chars
                 // longer than whatever its original contents are. Then a space is
                 // inserted between the subject and the message body. The total length
                 // of strlen($subject) + 2 + 1 + strlen($message) must be less than 160.
                 $extra_length = 3;
                 // two parenthesis and a space
                 // but in practice, there seems to be another 7 chars eaten up somewhere?
                 $extra_length += 7;
                 $url_length = strlen($responder_short_link);
                 $full_length = strlen($subject) + $extra_length + $url_length;
                 if ($full_length > $sms_max_length) {
                     // truncate the $subject since the link must be fully included
                     $subject = substr($subject, 0, $sms_max_length - $url_length - $extra_length);
                 }
                 wp_mail($smsemail, $subject, $responder_short_link, $headers);
             }
         }
     }
 }
Exemple #5
0
 /**
  * Loads plugin componentry and calls that component's register()
  * method. Called at the WordPress `init` hook.
  *
  * @uses WP_Buoy_Settings::register()
  * @uses WP_Buoy_Team::register()
  * @uses WP_Buoy_Notification::register()
  * @uses WP_Buoy_User::register()
  * @uses WP_Buoy_Alert::register()
  *
  * @return void
  */
 public static function initialize()
 {
     require_once 'class-buoy-settings.php';
     require_once 'class-buoy-user-settings.php';
     require_once 'class-buoy-team.php';
     require_once 'class-buoy-notification.php';
     require_once 'class-buoy-user.php';
     require_once 'class-buoy-alert.php';
     if (!class_exists('WP_Screen_Help_Loader')) {
         require_once 'includes/vendor/wp-screen-help-loader/class-wp-screen-help-loader.php';
     }
     WP_Buoy_Settings::register();
     WP_Buoy_Team::register();
     WP_Buoy_Notification::register();
     WP_Buoy_User::register();
     WP_Buoy_Alert::register();
 }