/**
  * Attaches the "Active Alerts" menu to WordPress's admin toolbar.
  *
  * @global $wp_admin_bar
  *
  * @return void
  */
 public static function addAlertsMenu()
 {
     global $wp_admin_bar;
     $alerts = array('my_alerts' => array(), 'my_responses' => array(), 'my_scheduled_alerts' => array());
     foreach (self::getActiveAlerts() as $post) {
         $alert = new WP_Buoy_Alert($post->ID);
         if (get_current_user_id() == $post->post_author) {
             $alerts['my_alerts'][] = $post;
         } else {
             if (in_array(get_current_user_id(), $alert->get_responders())) {
                 $alerts['my_responses'][] = $post;
             }
         }
     }
     foreach (self::getScheduledAlerts(get_current_user_id()) as $post) {
         if (get_current_user_id() == $post->post_author) {
             $alerts['my_scheduled_alerts'][] = $post;
         }
     }
     if (!empty($alerts['my_alerts']) || !empty($alerts['my_responses']) || !empty($alerts['my_scheduled_alerts'])) {
         $wp_admin_bar->add_menu(array('id' => self::$prefix . '-alerts-menu', 'title' => __('Active alerts', 'buoy')));
     }
     // TODO: Each of these nodes have similar HTML, reuse some code between these?
     // Add group nodes to WP Toolbar
     foreach ($alerts as $group_name => $posts) {
         $wp_admin_bar->add_group(array('id' => self::$prefix . '_' . $group_name, 'parent' => self::$prefix . '-alerts-menu'));
     }
     $dtfmt = get_option('date_format') . ' ' . get_option('time_format');
     foreach ($alerts['my_alerts'] as $post) {
         $alert = new WP_Buoy_Alert($post->ID);
         $author = get_userdata($post->post_author);
         $url = wp_nonce_url(admin_url('?page=' . self::$prefix . '_chat&' . self::$prefix . '_hash=' . $alert->get_hash()), self::$prefix . '_chat', self::$prefix . '_nonce');
         $wp_admin_bar->add_node(array('id' => self::$prefix . '-alert-' . $alert->get_hash(), 'title' => sprintf(__('My alert on %2$s', 'buoy'), $author->display_name, date($dtfmt, strtotime($post->post_date))), 'parent' => self::$prefix . '_my_alerts', 'href' => $url));
     }
     foreach ($alerts['my_responses'] as $post) {
         $alert = new WP_Buoy_Alert($post->ID);
         $author = get_userdata($post->post_author);
         $url = wp_nonce_url(admin_url('?page=' . self::$prefix . '_chat&' . self::$prefix . '_hash=' . $alert->get_hash()), self::$prefix . '_chat', self::$prefix . '_nonce');
         $wp_admin_bar->add_node(array('id' => self::$prefix . '-alert-' . $alert->get_hash(), 'title' => sprintf(__('Alert issued by %1$s on %2$s', 'buoy'), $author->display_name, date($dtfmt, strtotime($post->post_date))), 'parent' => self::$prefix . '_my_responses', 'href' => $url));
     }
     foreach ($alerts['my_scheduled_alerts'] as $post) {
         $alert = new WP_Buoy_Alert($post->ID);
         $url = wp_nonce_url(admin_url('admin-ajax.php?action=' . self::$prefix . '_unschedule_alert&' . self::$prefix . '_hash=' . $alert->get_hash() . '&r=' . esc_url($_SERVER['REQUEST_URI'])), self::$prefix . '_unschedule_alert', self::$prefix . '_nonce');
         $wp_admin_bar->add_node(array('id' => self::$prefix . '-alert-' . $alert->get_hash(), 'title' => sprintf(__('Cancel scheduled alert for %1$s', 'buoy'), date($dtfmt, strtotime($post->post_date))), 'meta' => array('title' => __('Cancel this alert', 'buoy')), 'parent' => self::$prefix . '_my_scheduled_alerts', 'href' => $url));
     }
 }
 /**
  * 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);
             }
         }
     }
 }