/** -----------------------------------
     /**  Bulletin Board
     /** -----------------------------------*/
 function bulletin_board($message = '')
 {
     global $LANG, $DB, $OUT, $IN, $LOC, $SESS, $PREFS;
     $DB->query("UPDATE exp_members SET last_view_bulletins = '" . $LOC->now . "' WHERE member_id = '{$this->member_id}'");
     $this->title = $LANG->line('bulletin_board');
     $this->crumb = $LANG->line('bulletin_board');
     $this->conditionals['bulletins'] = 'n';
     $this->conditionals['no_bulletins'] = 'y';
     $this->conditionals['paginate'] = 'n';
     $this->conditionals['can_post_bulletin'] = $SESS->userdata['can_send_bulletins'] == 'y' ? 'y' : 'n';
     $this->single_parts['include']['message'] = $message;
     $this->conditionals['message'] = $message != '' ? 'y' : 'n';
     $this->single_parts['path']['send_bulletin'] = $this->_create_path('send_bulletin');
     /** ---------------------------------------
        	/**  Retrieve Bulletins
        	/** ---------------------------------------*/
     $dql = "SELECT m.screen_name, b.sender_id, b.bulletin_message, b.bulletin_date, b.bulletin_id ";
     $sql = "FROM exp_member_bulletin_board b, exp_members m\n\t\t\t\t WHERE b.sender_id = m.member_id\n\t\t\t\t AND b.bulletin_group = " . $DB->escape_str($SESS->userdata['group_id']) . "\n\t\t\t\t AND bulletin_date < " . $LOC->now . "\n\t\t\t\t AND \n\t\t\t\t (\n\t\t\t\t \tb.bulletin_expires > " . $LOC->now . "\n\t\t\t\t \tOR\n\t\t\t\t \tb.bulletin_expires = 0\n\t\t\t\t )\n\t\t\t\t ORDER BY b.bulletin_date DESC";
     /** ----------------------------------------
         /**  Run "count" query for pagination
         /** ----------------------------------------*/
     $query = $DB->query("SELECT COUNT(b.bulletin_id) AS count " . $sql);
     /** ----------------------------------------
         /**  If No Messages, we say so.
         /** ----------------------------------------*/
     if ($query->row['count'] == 0) {
         $this->single_parts['include']['bulletins'] = $LANG->line('message_no_bulletins');
         $this->return_data = $this->_process_template($this->retrieve_template('bulletin_board'));
         return;
     }
     /** ----------------------------------------
         /**  Determine Current Page
         /** ----------------------------------------*/
     $row_count = 0;
     // How many rows shown this far (i.e. offset)
     if ($this->allegiance == 'user') {
         $row_count = $this->cur_id;
     } else {
         $row_count = $IN->GBL('page', 'GP') === false ? 0 : $IN->GBL('page', 'GP');
     }
     if (!is_numeric($row_count)) {
         $row_count = 0;
     }
     $this->per_page = 5;
     $current_page = $row_count / $this->per_page + 1;
     $total_pages = intval($query->row['count'] / $this->per_page);
     if ($query->row['count'] % $this->per_page) {
         $total_pages++;
     }
     $this->single_parts['include']['page_count'] = $current_page . ' ' . $LANG->line('of') . ' ' . $total_pages;
     /** -----------------------------
        	/**  Do we need pagination?
        	/** -----------------------------*/
     $pager = '';
     if ($query->row['count'] > $this->per_page) {
         if (!class_exists('Paginate')) {
             require PATH_CORE . 'core.paginate' . EXT;
         }
         $PGR = new Paginate();
         if ($this->allegiance == 'user') {
             $PGR->path = $this->base_url . 'bulletin_board/';
         } else {
             $PGR->base_url = $this->base_url . 'bulletin_board';
             $PGR->qstr_var = 'page';
         }
         $PGR->total_count = $query->row['count'];
         $PGR->per_page = $this->per_page;
         $PGR->cur_page = $row_count;
         $this->single_parts['include']['pagination_link'] = $PGR->show_links();
         $this->conditionals['paginate'] = 'y';
         $sql .= " LIMIT " . $row_count . ", " . $this->per_page;
     }
     /** ----------------------------------------
         /**  Create Bulletins
         /** ----------------------------------------*/
     $this->conditionals['bulletins'] = 'y';
     $this->conditionals['no_bulletins'] = 'n';
     $folder_rows_template = $this->retrieve_template('bulletin');
     $i = 0;
     $r = '';
     $censor = FALSE;
     if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '') {
         $censor = TRUE;
         if (!class_exists('Typography')) {
             require PATH_CORE . 'core.typography' . EXT;
         }
         $TYPE = new Typography(0);
     }
     $query = $DB->query($dql . $sql);
     if ($query->row['bulletin_date'] != $SESS->userdata['last_bulletin_date']) {
         $DB->query($DB->update_string('exp_members', array('last_bulletin_date' => $query->row['bulletin_date']), "group_id = '" . $DB->escape_str($SESS->userdata['group_id']) . "'"));
     }
     foreach ($query->result as $row) {
         ++$i;
         $data = $row;
         $this->conditionals['can_delete_bulletin'] = ($SESS->userdata['group_id'] == 1 or $row['sender_id'] == $SESS->userdata['member_id']) ? 'y' : 'n';
         if ($this->allegiance == 'cp') {
             $this->single_parts['path']['delete_bulletin'] = $this->_create_path('delete_bulletin', AMP . 'bulletin_id=' . $row['bulletin_id']);
         } else {
             $this->single_parts['path']['delete_bulletin'] = $this->_create_path('delete_bulletin') . $row['bulletin_id'] . '/';
         }
         $data['bulletin_message'] = $censor === FALSE ? $data['bulletin_message'] : $TYPE->filter_censored_words($data['bulletin_message']);
         $data['bulletin_sender'] = $row['screen_name'];
         $data['bulletin_date'] = $LOC->set_human_time($row['bulletin_date']);
         $data['style'] = $i % 2 ? 'tableCellTwo' : 'tableCellOne';
         $r .= $this->_process_template($folder_rows_template, $data);
     }
     $this->single_parts['include']['bulletins'] = $r;
     /** ----------------------------------------
     		/**  Return the Folder's Contents
     		/** ----------------------------------------*/
     $this->return_data = $this->_process_template($this->retrieve_template('bulletin_board'));
 }
 /** -----------------------------
     /**  Send email
     /** -----------------------------*/
 function send_email()
 {
     global $DSP, $DB, $IN, $FNS, $REGX, $LANG, $SESS, $LOC, $PREFS;
     $debug_msg = '';
     /** -----------------------------
         /**  Are we missing any fields?
         /** -----------------------------*/
     if (!$IN->GBL('from', 'POST') or !$IN->GBL('subject', 'POST') or !$IN->GBL('message', 'POST')) {
         return $DSP->error_message($LANG->line('empty_form_fields'));
     }
     /** -----------------------------
         /**  Fetch $_POST data
         /** -----------------------------*/
     // We'll turn the $_POST data into variables for simplicity
     $groups = array();
     $list_ids = array();
     foreach ($_POST as $key => $val) {
         if (substr($key, 0, 6) == 'group_') {
             $groups[] = $val;
         } elseif (substr($key, 0, 5) == 'list_') {
             $list_ids[] = $val;
         } else {
             ${$key} = stripslashes($val);
         }
     }
     /** -----------------------------
         /**  Verify privileges
         /** -----------------------------*/
     if (count($groups) > 0 and !$DSP->allowed_group('can_email_member_groups')) {
         return $DSP->no_access_message($LANG->line('not_allowed_to_email_member_groups'));
     }
     if (count($list_ids) > 0 and !$DSP->allowed_group('can_email_mailinglist') and $this->mailinglist_exists == TRUE) {
         return $DSP->no_access_message($LANG->line('not_allowed_to_email_mailinglist'));
     }
     if (count($groups) == 0 and count($list_ids) == 0 and !$IN->GBL('recipient', 'POST')) {
         return $DSP->error_message($LANG->line('empty_form_fields'));
     }
     /** -------------------------------
         /**  Assign data for caching
         /** -------------------------------*/
     $cache_data = array('cache_id' => '', 'cache_date' => $LOC->now, 'total_sent' => 0, 'from_name' => $name, 'from_email' => $from, 'recipient' => $recipient, 'cc' => $cc, 'bcc' => $bcc, 'recipient_array' => '', 'subject' => $subject, 'message' => $message, 'plaintext_alt' => $plaintext_alt, 'mailtype' => $mailtype, 'text_fmt' => $text_fmt, 'wordwrap' => $wordwrap, 'priority' => $priority);
     /** ---------------------------------------
     		/**  Apply text formatting if necessary
     		/** ---------------------------------------*/
     if ($text_fmt != 'none' && $text_fmt != '') {
         if (!class_exists('Typography')) {
             require PATH_CORE . 'core.typography' . EXT;
         }
         $TYPE = new Typography(0);
         $TYPE->parse_smileys = FALSE;
         $subject = $TYPE->filter_censored_words($subject);
         $message = $TYPE->parse_type($message, array('text_format' => $text_fmt, 'html_format' => 'all', 'auto_links' => 'n', 'allow_img_url' => 'y'));
     }
     /** -----------------------------
         /**  Send a single email
         /** -----------------------------*/
     if (count($groups) == 0 and count($list_ids) == 0) {
         require PATH_CORE . 'core.email' . EXT;
         $to = $recipient == '' ? $SESS->userdata['email'] : $recipient;
         $email = new EEmail();
         $email->wordwrap = $wordwrap == 'y' ? TRUE : FALSE;
         $email->mailtype = $mailtype;
         $email->priority = $priority;
         $email->from($from, $name);
         $email->to($to);
         $email->cc($cc);
         $email->bcc($bcc);
         $email->subject($subject);
         $email->message($message, $plaintext_alt);
         $error = FALSE;
         if (!$email->Send()) {
             $error = TRUE;
         }
         $debug_msg = $this->debug_message($email->debug_msg);
         if ($error == TRUE) {
             return $DSP->error_message($LANG->line('error_sending_email') . $debug_msg, 0);
         }
         /** ---------------------------------
         			/**  Save cache data
         			/** ---------------------------------*/
         $cache_data['total_sent'] = $this->fetch_total($to, $cc, $bcc);
         $this->save_cache_data($cache_data);
         /** ---------------------------------
         			/**  Show success message
         			/** ---------------------------------*/
         $DSP->set_return_data($LANG->line('email_sent'), $DSP->qdiv('defaultPad', $DSP->qdiv('success', $LANG->line('email_sent_message'))) . $debug_msg, $LANG->line('email_sent'));
         // We're done
         return;
     }
     //  Send Multi-emails
     /** ----------------------------------------
         /**  Is Batch Mode set?
         /** ----------------------------------------*/
     $batch_mode = $PREFS->ini('email_batchmode');
     $batch_size = $PREFS->ini('email_batch_size');
     if (!is_numeric($batch_size)) {
         $batch_mode = 'n';
     }
     $emails = array();
     /** ---------------------------------
         /**  Fetch member group emails
         /** ---------------------------------*/
     if (count($groups) > 0) {
         $sql = "SELECT exp_members.member_id, exp_members.email, exp_members.screen_name \n\t\t\t\t\tFROM   exp_members, exp_member_groups\n\t\t\t\t\tWHERE  exp_members.group_id = exp_member_groups.group_id \n\t\t\t\t\tAND exp_member_groups.site_id = '" . $DB->escape_str($PREFS->ini('site_id')) . "' \n\t\t\t\t\tAND include_in_mailinglists = 'y' ";
         if (isset($_POST['accept_admin_email'])) {
             $sql .= "AND exp_members.accept_admin_email = 'y' ";
         }
         $sql .= "AND exp_member_groups.group_id IN (";
         foreach ($groups as $id) {
             $sql .= "'" . $DB->escape_str($id) . "',";
         }
         $sql = substr($sql, 0, -1);
         $sql .= ")";
         // Run the query
         $query = $DB->query($sql);
         if ($query->num_rows > 0) {
             foreach ($query->result as $row) {
                 $emails['m' . $row['member_id']] = array($row['email'], $row['screen_name']);
             }
         }
     }
     /** ---------------------------------
         /**  Fetch mailing list emails
         /** ---------------------------------*/
     $list_templates = array();
     if ($this->mailinglist_exists == TRUE) {
         if (count($list_ids) > 0) {
             $sql = "SELECT authcode, email, list_id FROM exp_mailing_list WHERE list_id IN (";
             foreach ($list_ids as $id) {
                 $sql .= "'" . $DB->escape_str($id) . "',";
                 // Fetch the template for each list
                 $query = $DB->query("SELECT list_template, list_title FROM exp_mailing_lists WHERE list_id = '" . $DB->escape_str($id) . "'");
                 $list_templates[$id] = array('list_template' => $query->row['list_template'], 'list_title' => $query->row['list_title']);
             }
             $sql = substr($sql, 0, -1);
             $sql .= ")";
             $sql .= " ORDER BY user_id";
             $query = $DB->query($sql);
             // No result?  Show error message
             if ($query->num_rows == 0 && sizeof($emails) == 0) {
                 return $DSP->set_return_data($LANG->line('send_an_email'), $DSP->qdiv('defaultPad', $DSP->qdiv('alert', $LANG->line('no_email_matching_criteria'))), $LANG->line('send_an_email'));
             }
             if ($query->num_rows > 0) {
                 foreach ($query->result as $row) {
                     $emails['l' . $row['authcode']] = array($row['email'], $row['list_id']);
                 }
             }
         }
     }
     /** ----------------------------------------
         /**  Kill duplicates
         /** ----------------------------------------*/
     $cleaned_emails = array();
     foreach ($emails as $key => $value) {
         if (is_array($value)) {
             $val = $value['0'];
         } else {
             $val = $value;
         }
         if (!isset($cleaned_emails[$key])) {
             $cleaned_emails[$key] = $value;
         }
     }
     $emails = $cleaned_emails;
     /** ----------------------------------------
         /**  After all that, do we have any emails?
         /** ----------------------------------------*/
     if (count($emails) == 0 and $recipient == '') {
         return $DSP->set_return_data($LANG->line('send_an_email'), $DSP->qdiv('defaultPad', $DSP->qdiv('alert', $LANG->line('no_email_matching_criteria'))), $LANG->line('send_an_email'));
     }
     /** ----------------------------------------
     		/**  Do we have any CCs or BCCs?
     		/** ----------------------------------------*/
     //  If so, we'll send those separately first
     $total_sent = 0;
     $recips = array();
     if ($cc != '' || $bcc != '') {
         if (!class_exists('EEmail')) {
             require PATH_CORE . 'core.email' . EXT;
         }
         $to = $recipient == '' ? $SESS->userdata['email'] : $recipient;
         $email = new EEmail();
         $email->wordwrap = $wordwrap == 'y' ? TRUE : FALSE;
         $email->mailtype = $mailtype;
         $email->priority = $priority;
         $email->from($from, $name);
         $email->to($to);
         $email->cc($cc);
         $email->bcc($bcc);
         $email->subject($subject);
         $email->message($message, $plaintext_alt);
         $error = FALSE;
         if (!$email->Send()) {
             $error = TRUE;
         }
         $debug_msg = $this->debug_message($email->debug_msg);
         if ($error == TRUE) {
             return $DSP->error_message($LANG->line('error_sending_email') . $debug_msg, 0);
         }
         $total_sent = $this->fetch_total($to, $cc, $bcc);
     } else {
         // No CC/BCCs? Convert recipients to an array so we can include them in the email sending cycle
         if ($recipient != '') {
             $recips = $this->convert_recipients($recipient);
         }
     }
     if (count($recips) > 0) {
         $emails = array_merge($emails, $recips);
     }
     //  Store email cache
     $cache_data['recipient_array'] = addslashes(serialize($emails));
     $cache_data['total_sent'] = 0;
     $id = $this->save_cache_data($cache_data, $groups, $list_ids);
     /** ----------------------------------------
         /**  If batch-mode is not set, send emails
         /** ----------------------------------------*/
     if (count($emails) <= $batch_size) {
         $batch_mode = 'n';
     }
     if ($batch_mode == 'n') {
         $action_id = $FNS->fetch_action_id('Mailinglist', 'unsubscribe');
         if (!class_exists('EEmail')) {
             require PATH_CORE . 'core.email' . EXT;
         }
         $email = new EEmail();
         $email->wordwrap = $wordwrap == 'y' ? TRUE : FALSE;
         $email->mailtype = $mailtype;
         $email->priority = $priority;
         foreach ($emails as $key => $val) {
             $screen_name = '';
             $list_id = FALSE;
             if (is_array($val) and substr($key, 0, 1) == 'm') {
                 $screen_name = $val['1'];
                 $val = $val['0'];
             } elseif (is_array($val) and substr($key, 0, 1) == 'l') {
                 $list_id = $val['1'];
                 $val = $val['0'];
             }
             $email->initialize();
             $email->to($val);
             $email->from($from, $name);
             $email->subject($subject);
             // We need to add the unsubscribe link to emails - but only ones
             // from the mailing list.  When we gathered the email addresses
             // above, we added one of three prefixes to the array key:
             //
             // m = member id
             // l = mailing list
             // r = general recipient
             // Make a copy so we don't mess up the original
             $msg = $message;
             $msg_alt = $plaintext_alt;
             if (substr($key, 0, 1) == 'l') {
                 $msg = $this->parse_template($list_templates[$list_id], $msg, $action_id, substr($key, 1), $mailtype);
                 $msg_alt = $this->parse_template($list_templates[$list_id], $msg_alt, $action_id, substr($key, 1), 'plain');
             }
             $msg = str_replace('{name}', $screen_name, $msg);
             $msg_alt = str_replace('{name}', $screen_name, $msg_alt);
             $email->message($msg, $msg_alt);
             $error = FALSE;
             if (!$email->Send()) {
                 $error = TRUE;
             }
             $debug_msg = $this->debug_message($email->debug_msg);
             if ($error == TRUE) {
                 // Let's adjust the recipient array up to this point
                 reset($recipient_array);
                 $recipient_array = addslashes(serialize(array_slice($recipient_array, $i)));
                 $DB->query("UPDATE exp_email_cache SET total_sent = '{$total_sent}', recipient_array = '{$recipient_array}' WHERE cache_id = '" . $DB->escape_str($id) . "'");
                 return $DSP->error_message($LANG->line('error_sending_email') . $debug_msg, 0);
             }
             $total_sent++;
         }
         /** ----------------------------------------
         			/**  Update email cache
         			/** ----------------------------------------*/
         $DB->query("UPDATE exp_email_cache SET total_sent = '{$total_sent}', recipient_array = '' WHERE cache_id = '" . $DB->escape_str($id) . "'");
         /** ----------------------------------------
         			/**  Success Mesage
         			/** ----------------------------------------*/
         $DSP->set_return_data($LANG->line('email_sent'), $DSP->qdiv('defaultPad', $DSP->qdiv('success', $LANG->line('email_sent_message'))) . $DSP->qdiv('defaultPad', $DSP->qdiv('', $LANG->line('total_emails_sent') . NBS . NBS . $total_sent)) . $debug_msg, $LANG->line('email_sent'));
         // We're done
         return;
     }
     /** ----------------------------------------
         /**  Start Batch-Mode
         /** ----------------------------------------*/
     // Turn on "refresh"
     // By putting the URL in the $DSP->refresh variable we'll tell the
     // system to write a <meta> refresh header, starting the batch process
     $DSP->refresh = BASE . AMP . 'C=communicate' . AMP . 'M=batch_send' . AMP . 'id=' . $id;
     $DSP->ref_rate = 6;
     // Kill the bread-crumb links, just to keep it away from the user
     $DSP->show_crumb = FALSE;
     // Write the initial message, telling the user the batch processor is about to start
     $r = $DSP->heading(BR . $LANG->line('sending_email'));
     $r .= $DSP->qdiv('itemWrapper', $LANG->line('batchmode_ready_to_begin'));
     $r .= $DSP->qdiv('', $DSP->qdiv('alert', $LANG->line('batchmode_warning')));
     $DSP->body = $r;
 }
 /** -----------------------------------
     /**  Send Message
     /** -----------------------------------*/
 function send_message()
 {
     global $LANG, $DB, $IN, $LOC, $FNS, $SESS, $REGX, $PREFS;
     $submission_error = array();
     /** ----------------------------------------
         /**  Is the user banned?
         /** ----------------------------------------*/
     if ($SESS->userdata['is_banned'] === TRUE) {
         return $this->_error_page();
     }
     /** ----------------------------------------
         /**  Is the IP or User Agent unavalable?
         /** ----------------------------------------*/
     if ($IN->IP == '0.0.0.0' || $SESS->userdata['user_agent'] == '') {
         return $this->_error_page();
     }
     /** -------------------------------------
     		/**  Status Setting
     		/** -------------------------------------*/
     if ($IN->GBL('preview') or $IN->GBL('remove')) {
         $status = 'preview';
     } elseif ($IN->GBL('draft')) {
         $status = 'draft';
     } else {
         $status = 'sent';
     }
     /** -------------------------------------
     		/**  Already Sent?
     		/** -------------------------------------*/
     if ($IN->GBL('message_id') !== FALSE && is_numeric($IN->GBL('message_id'))) {
         $query = $DB->query("SELECT message_status FROM exp_message_data WHERE message_id = '" . $DB->escape_str($IN->GBL('message_id')) . "'");
         if ($query->num_rows > 0 && $query->row['message_status'] == 'sent') {
             return $this->_error_page($LANG->line('messsage_already_sent'));
         }
     }
     /* -------------------------------------------
     		/*	Hidden Configuration Variables
     		/*	- prv_msg_waiting_period => How many hours after becoming a member until they can PM?
             /* -------------------------------------------*/
     $waiting_period = $PREFS->ini('prv_msg_waiting_period') !== FALSE ? (int) $PREFS->ini('prv_msg_waiting_period') : 1;
     if ($SESS->userdata['join_date'] > $LOC->now - $waiting_period * 60 * 60) {
         return $this->_error_page(str_replace(array('%time%', '%email%', '%site%'), array($waiting_period, $FNS->encode_email($PREFS->ini('webmaster_email')), $PREFS->ini('site_name')), $LANG->line('waiting_period_not_reached')));
     }
     /* -------------------------------------------
     		/*	Hidden Configuration Variables
     		/*	- prv_msg_throttling_period => How many seconds between PMs?
             /* -------------------------------------------*/
     if ($status == 'sent' && $SESS->userdata['group_id'] != 1) {
         $period = $PREFS->ini('prv_msg_throttling_period') !== FALSE ? (int) $PREFS->ini('prv_msg_throttling_period') : 30;
         $query = $DB->query("SELECT COUNT(*) AS count FROM exp_message_data d\n        \t\t\t\t\t\t WHERE d.sender_id = '" . $DB->escape_str($this->member_id) . "'\n\t\t\t\t\t\t\t\t AND d.message_status = 'sent'\n\t\t\t\t\t\t\t\t AND d.message_date > " . $DB->escape_str($LOC->now - $period));
         if ($query->row['count'] > 0) {
             return $this->_error_page(str_replace('%x', $period, $LANG->line('send_throttle')));
         }
     }
     /** ------------------------------------------
     		/**  Is there a recipient, subject, and body?
     		/** ------------------------------------------*/
     if ($IN->GBL('recipients') == '' && $status == 'sent') {
         $submission_error[] = $LANG->line('empty_recipients_field');
     } elseif ($IN->GBL('subject') == '') {
         $submission_error[] = $LANG->line('empty_subject_field');
     } elseif ($IN->GBL('body') == '') {
         $submission_error[] = $LANG->line('empty_body_field');
     }
     /** -------------------------------------------
     		/**  Deny Duplicate Data
     		/** -------------------------------------------*/
     if ($PREFS->ini('deny_duplicate_data') == 'y') {
         $query = $DB->query("SELECT COUNT(*) AS count FROM exp_message_data d\n        \t\t\t\t\t\t WHERE d.sender_id = '" . $DB->escape_str($this->member_id) . "'\n\t\t\t\t\t\t\t\t AND d.message_status = 'sent'\n\t\t\t\t\t\t\t\t AND d.message_body = '" . $DB->escape_str($REGX->xss_clean($IN->GBL('body'))) . "'");
         if ($query->row['count'] > 0) {
             return $this->_error_page($LANG->line('duplicate_message_sent'));
         }
     }
     /** ------------------------------------------
     		/**  Valid Recipients? - Only Checked on Sent
     		/** ------------------------------------------*/
     $recipients = $this->convert_recipients($IN->GBL('recipients'), 'array', 'member_id');
     $cc = trim($IN->GBL('cc')) == '' ? array() : $this->convert_recipients($IN->GBL('cc'), 'array', 'member_id');
     $recip_orig = sizeof($recipients);
     $cc_orig = sizeof($cc);
     // Make sure CC does not contain members in Recipients
     $cc = array_diff($cc, $recipients);
     if (sizeof($recipients) == 0 && $status == 'sent') {
         $submission_error[] = $LANG->line('empty_recipients_field');
     }
     if ($this->invalid_name === TRUE) {
         $submission_error[] = $LANG->line('invalid_username');
     }
     /** ------------------------------------------
     		/**  Too Big for Its Britches?
     		/** ------------------------------------------*/
     if ($this->max_chars != 0 && strlen($IN->GBL('body')) > $this->max_chars) {
         $submission_error[] = str_replace('%max%', $this->max_chars, $LANG->line('message_too_large'));
     }
     /** -------------------------------------
     		/**  Super Admins get a free pass
     		/** -------------------------------------*/
     if ($SESS->userdata('group_id') != 1) {
         /** ------------------------------------------
         			/**  Sender Allowed to Send More Messages?
         			/** ------------------------------------------*/
         $query = $DB->query("SELECT COUNT(c.copy_id) AS count \n\t\t\t\t\t\t\t\t FROM exp_message_copies c, exp_message_data d\n\t\t\t\t\t\t\t\t WHERE c.message_id = d.message_id\n\t\t\t\t\t\t\t\t AND c.sender_id = '" . $DB->escape_str($this->member_id) . "'\n\t\t\t\t\t\t\t\t AND d.message_status = 'sent'\n\t\t\t\t\t\t\t\t AND d.message_date > " . ($LOC->now - 24 * 60 * 60));
         if ($query->row['count'] + sizeof($recipients) + sizeof($cc) > $this->send_limit) {
             $submission_error[] = $LANG->line('sending_limit_warning');
         }
         /** ------------------------------------------
         			/**  Sender Allowed to Store More Messages?
         			/** ------------------------------------------*/
         if ($this->storage_limit != '0' && ($IN->GBL('sent_copy') !== FALSE && $IN->GBL('sent_copy') == 'y')) {
             if ($this->total_messages == '') {
                 $this->storage_usage();
             }
             if ($this->total_messages + 1 > $this->storage_limit) {
                 $submission_error[] = $LANG->line('storage_limit_warning');
             }
         }
     }
     /** -------------------------------------
     		/**  Upload Path Set?
     		/** -------------------------------------*/
     if ($this->upload_path == '' && (isset($_POST['remove']) || isset($_FILES['userfile']['name']) && $_FILES['userfile']['name'] != '')) {
         $submission_error[] = $LANG->line('unable_to_recieve_attach');
     }
     /** -------------------------------------
     		/**  Attachments?
     		/** -------------------------------------*/
     if ($IN->GBL('attach') !== FALSE && $IN->GBL('attach') != '') {
         $this->attachments = explode('|', $_POST['attach']);
     }
     /* -------------------------------------
     		/*  Create Forward Attachments
     		/*
     		/*  We have to copy the attachments for
     		/*  forwarded messages.  We only do this
     		/*  when the compose messaage page is first
     		/*  submitted.  We have a special variable
     		/*  called 'create_attach' to tell us when
     		/*  that is.
     		/* -------------------------------------*/
     if ($this->attach_allowed == 'y' && $this->upload_path != '' && sizeof($this->attachments) > 0 && $IN->GBL('create_attach')) {
         if (($message = $this->_duplicate_files()) !== TRUE) {
             $submission_error[] = $message . BR;
         }
     }
     /** -------------------------------------
     		/**  Is this a remove attachment request?
     		/** -------------------------------------*/
     if (isset($_POST['remove']) && $this->upload_path != '') {
         $id = key($_POST['remove']);
         if (is_numeric($id)) {
             $this->_remove_attachment($id);
             // Treat an attachment removal like a draft, where we do not
             // see the preview only the message.
             $this->hide_preview = TRUE;
         }
     }
     /** -------------------------------------
     		/**  Do we have an attachment to deal with?
     		/** -------------------------------------*/
     if ($this->attach_allowed == 'y') {
         if ($this->upload_path != '' and isset($_FILES['userfile']['name']) and $_FILES['userfile']['name'] != '') {
             $preview = $IN->GBL('preview', 'POST') !== FALSE ? TRUE : FALSE;
             if (($message = $this->_attach_file()) !== TRUE) {
                 $submission_error[] = $message . BR;
             }
         }
     }
     /** -----------------------------------
     		/**  Check Overflow
     		/** -----------------------------------*/
     $details = array();
     $details['overflow_recipients'] = array();
     $details['overflow_cc'] = array();
     for ($i = 0, $size = sizeof($recipients); $i < $size; $i++) {
         if ($this->_check_overflow($recipients[$i]) === FALSE) {
             $details['overflow_recipients'][] = $recipients[$i];
             unset($recipients[$i]);
         }
     }
     for ($i = 0, $size = sizeof($cc); $i < $size; $i++) {
         if ($this->_check_overflow($cc[$i]) === FALSE) {
             $details['overflow_cc'][] = $cc[$i];
             unset($cc[$i]);
         }
     }
     /* -------------------------------------------------
     		/*  If we have people unable to receive a message
     		/*  because of an overflow we make the message a 
     		/*  preview and will send a message to the sender.
     		/* -------------------------------------*/
     if (sizeof($details['overflow_recipients']) > 0 or sizeof($details['overflow_cc']) > 0) {
         sort($recipients);
         sort($cc);
         $overflow_names = array();
         /* -------------------------------------
         			/*  Send email alert regarding a full
         			/*  inbox to these users, load names
         			/*  for error message
         			/* -------------------------------------*/
         global $PREFS;
         $query = $DB->query("SELECT exp_members.screen_name, exp_members.email, exp_members.accept_messages, exp_member_groups.prv_msg_storage_limit\n\t\t\t\t\t\t\t\t FROM exp_members\n\t\t\t\t\t\t\t\t LEFT JOIN exp_member_groups ON exp_member_groups.group_id = exp_members.group_id\n\t\t\t\t\t\t\t\t WHERE exp_members.member_id IN ('" . implode("','", array_merge($details['overflow_recipients'], $details['overflow_cc'])) . "')\n\t\t\t\t\t\t\t\t AND exp_member_groups.site_id = '" . $DB->escape_str($PREFS->ini('site_id')) . "'");
         if ($query->num_rows > 0) {
             if (!class_exists('EEmail')) {
                 require PATH_CORE . 'core.email' . EXT;
             }
             $email = new EEmail();
             $email->wordwrap = true;
             $swap = array('sender_name' => $SESS->userdata('screen_name'), 'site_name' => stripslashes($PREFS->ini('site_name')), 'site_url' => $PREFS->ini('site_url'));
             $template = $FNS->fetch_email_template('pm_inbox_full');
             $email_tit = $FNS->var_swap($template['title'], $swap);
             $email_msg = $FNS->var_swap($template['data'], $swap);
             foreach ($query->result as $row) {
                 $overflow_names[] = $row['screen_name'];
                 if ($row['accept_messages'] != 'y') {
                     continue;
                 }
                 $email->initialize();
                 $email->from($PREFS->ini('webmaster_email'), $PREFS->ini('webmaster_name'));
                 $email->to($row['email']);
                 $email->subject($email_tit);
                 $email->message($FNS->var_swap($email_msg, array('recipient_name' => $row['screen_name'], 'pm_storage_limit' => $row['prv_msg_storage_limit'])));
                 $email->Send();
             }
         }
         $submission_error[] = str_replace('%overflow_names%', implode(', ', $overflow_names), $LANG->line('overflow_recipients'));
     }
     /** ----------------------------------------
     		/**  Submission Errors Force a Preview
     		/** ----------------------------------------*/
     if (sizeof($submission_error) > 0) {
         $status = 'preview';
         $this->hide_preview = TRUE;
         $this->invalid_name = FALSE;
     }
     /* -------------------------------------
     		/*  Check Blocked on Sent
     		/*  
     		/*  If a message is blocked, we will not notify
     		/*  the sender of this and simply proceed.
     		/* -------------------------------------*/
     if ($status == 'sent') {
         $sql = "SELECT member_id FROM exp_message_listed\n\t\t\t\t\tWHERE listed_type = 'blocked'\n\t\t\t\t\tAND listed_member = '{$this->member_id}'\n\t\t\t\t\tAND \n\t\t\t\t\t(\n\t\t\t\t\tmember_id IN ('" . implode("','", $recipients) . "')";
         if (sizeof($cc) > 0) {
             $sql .= "OR\n\t\t\t\t\t\t member_id IN ('" . implode("','", $cc) . "')";
         }
         $sql .= ")";
         $blocked = $DB->query($sql);
         if ($blocked->num_rows > 0) {
             foreach ($blocked->result as $row) {
                 $details['blocked'][] = $row['member_id'];
             }
             $recipients = array_diff($recipients, $details['blocked']);
             $cc = sizeof($cc) > 0 ? array_diff($cc, $details['blocked']) : array();
             sort($recipients);
             sort($cc);
         }
     }
     /** -------------------------------------
     		/**  Store Data
     		/** -------------------------------------*/
     $data = array('message_id' => '', 'sender_id' => $this->member_id, 'message_date' => $LOC->now, 'message_subject' => $REGX->xss_clean($IN->GBL('subject')), 'message_body' => $REGX->xss_clean($IN->GBL('body')), 'message_tracking' => !$IN->GBL('tracking') ? 'n' : 'y', 'message_attachments' => sizeof($this->attachments) > 0 ? 'y' : 'n', 'message_recipients' => implode('|', $recipients), 'message_cc' => implode('|', $cc), 'message_hide_cc' => !$IN->GBL('hide_cc') ? 'n' : 'y', 'message_sent_copy' => !$IN->GBL('sent_copy') ? 'n' : 'y', 'total_recipients' => sizeof($recipients) + sizeof($cc), 'message_status' => $status);
     if ($IN->GBL('message_id') && is_numeric($IN->GBL('message_id'))) {
         /* -------------------------------------
         			/*  Preview or Draft previously submitted.
         			/*  So, we're updating an already existing message
         			/* -------------------------------------*/
         $message_id = $IN->GBL('message_id');
         unset($data['message_id']);
         $DB->query($DB->update_string('exp_message_data', $data, "message_id = '" . $DB->escape_str($message_id) . "'"));
     } else {
         $DB->query($DB->insert_string('exp_message_data', $data));
         $message_id = $DB->insert_id;
     }
     /** -----------------------------------------
     		/**  Send out Messages to Recipients and CC
     		/** -----------------------------------------*/
     if ($status == 'sent') {
         $copy_data = array('copy_id' => '', 'message_id' => $message_id, 'sender_id' => $this->member_id);
         /** -----------------------------------------
         			/**  Send out Messages to Recipients and CC
         			/** -----------------------------------------*/
         for ($i = 0, $size = sizeof($recipients); $i < $size; $i++) {
             $copy_data['recipient_id'] = $recipients[$i];
             $copy_data['message_authcode'] = $FNS->random('alpha', 10);
             $DB->query($DB->insert_string('exp_message_copies', $copy_data));
         }
         for ($i = 0, $size = sizeof($cc); $i < $size; $i++) {
             $copy_data['recipient_id'] = $cc[$i];
             $copy_data['message_authcode'] = $FNS->random('alpha', 10);
             $DB->query($DB->insert_string('exp_message_copies', $copy_data));
         }
         /** ----------------------------------
         			/**  Increment exp_members.private_messages
         			/** ----------------------------------*/
         $DB->query("UPDATE exp_members SET private_messages = private_messages + 1\n\t\t\t\t\t\tWHERE member_id IN ('" . implode("','", array_merge($recipients, $cc)) . "')");
         /** ----------------------------------
         			/**  Send Any and All Email Notifications
         			/** ----------------------------------*/
         $query = $DB->query("SELECT screen_name, email FROM exp_members\n\t\t\t\t\t\t\t\t WHERE member_id IN ('" . implode("','", array_merge($recipients, $cc)) . "')\n\t\t\t\t\t\t\t\t AND notify_of_pm = 'y'\n\t\t\t\t\t\t\t\t AND member_id != {$this->member_id}");
         if ($query->num_rows > 0) {
             global $PREFS;
             if (!class_exists('Typography')) {
                 require PATH_CORE . 'core.typography' . EXT;
             }
             $TYPE = new Typography(0);
             $TYPE->smileys = FALSE;
             $TYPE->highlight_code = TRUE;
             if ($PREFS->ini('enable_censoring') == 'y' && $PREFS->ini('censored_words') != '') {
                 $subject = $TYPE->filter_censored_words($REGX->xss_clean($IN->GBL('subject')));
             } else {
                 $subject = $REGX->xss_clean($IN->GBL('subject'));
             }
             $body = $TYPE->parse_type(stripslashes($REGX->xss_clean($IN->GBL('body'))), array('text_format' => 'none', 'html_format' => 'none', 'auto_links' => 'n', 'allow_img_url' => 'n'));
             if (!class_exists('EEmail')) {
                 require PATH_CORE . 'core.email' . EXT;
             }
             $email = new EEmail();
             $email->wordwrap = true;
             $swap = array('sender_name' => $SESS->userdata('screen_name'), 'message_subject' => $subject, 'message_content' => $body, 'site_name' => stripslashes($PREFS->ini('site_name')), 'site_url' => $PREFS->ini('site_url'));
             $template = $FNS->fetch_email_template('private_message_notification');
             $email_tit = $FNS->var_swap($template['title'], $swap);
             $email_msg = $FNS->var_swap($template['data'], $swap);
             foreach ($query->result as $row) {
                 $email->initialize();
                 $email->from($PREFS->ini('webmaster_email'), $PREFS->ini('webmaster_name'));
                 $email->to($row['email']);
                 $email->subject($email_tit);
                 $email->message($REGX->entities_to_ascii($FNS->var_swap($email_msg, array('recipient_name' => $row['screen_name']))));
                 $email->Send();
             }
         }
     }
     /** -------------------------------------
     		/**  Sent Copy?
     		/** -------------------------------------*/
     if ($status == 'sent' && $data['message_sent_copy'] == 'y') {
         $copy_data['recipient_id'] = $this->member_id;
         $copy_data['message_authcode'] = $FNS->random('alpha', 10);
         $copy_data['message_folder'] = '2';
         // Sent Message Folder
         $copy_data['message_read'] = 'y';
         // Already read automatically
         $DB->query($DB->insert_string('exp_message_copies', $copy_data));
     }
     /** -------------------------------------
     		/**  Replying or Forwarding?
     		/** -------------------------------------*/
     if ($status == 'sent' && ($IN->GBL('replying') !== FALSE or $IN->GBL('forwarding') !== FALSE)) {
         $copy_id = $IN->GBL('replying') !== FALSE ? $IN->GBL('replying') : $IN->GBL('forwarding');
         $status = $IN->GBL('replying') !== FALSE ? 'replied' : 'forwarded';
         $DB->query("UPDATE exp_message_copies SET message_status = '{$status}' WHERE copy_id = '{$copy_id}'");
     }
     /** -------------------------------------
     		/**  Correct Member ID for Attachments
     		/** -------------------------------------*/
     if (sizeof($this->attachments) > 0) {
         $DB->query("UPDATE exp_message_attachments SET message_id = '{$message_id}' \n\t\t\t\t\t\tWHERE attachment_id IN ('" . implode("','", $this->attachments) . "')");
     }
     /** -------------------------------------
     		/**  Remove Temp Status for Attachments
     		/** -------------------------------------*/
     if ($status == 'sent') {
         $DB->query("UPDATE exp_message_attachments SET is_temp = 'n' WHERE message_id = '{$message_id}'");
     }
     /** -------------------------------------
     		/**  Redirect Them
     		/** -------------------------------------*/
     if ($status == 'preview') {
         return $this->compose($message_id, $submission_error);
     } elseif ($status == 'draft') {
         $this->drafts();
     } else {
         $FNS->redirect($this->_create_path('inbox'));
     }
 }