/protected/email.php
PHP | 601 lines | 348 code | 103 blank | 150 comment | 75 complexity | 9c1421678fd9d5d358a95adfb5e1a4c3 MD5 | raw file
Possible License(s): GPL-2.0
- <?php
- /**
- * Based on code of FluxBB's include/email.php
- *
- * @copyright Copyright (C) 2011-2012 Yoory Nagumanov
- * @copyright Copyright (C) 2008-2012 FluxBB
- * @copyright based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
- * @license http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
- */
- require_once Pe::get('root').'include/utf8/utils/ascii.php';
- /**
- * Wrapper for email functions.
- */
- class Email extends PeComponent
- {
- // Set by constructor
- protected
- /**
- * Boards configuration.
- * @var array
- * @access protected
- */
- $pun_config,
- /**
- * Common language strings.
- * @var array
- * @access protected
- */
- $lang_common;
- // Set by methods that serve subscriptions
- protected
- /**
- * Database adapter object.
- * @var \pe\dblayer\DBLayer
- * @access protected
- */
- $db,
- /**
- * Current user.
- * @var array
- * @access protected
- */
- $pun_user;
- /**
- * Validate an email address
- *
- * @param string $email
- * @return boolean
- * @access public
- * @static
- */
- public static function isValidEmail($email)
- {
- if (strlen($email) > 80)
- return false;
- return preg_match('/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|("[^"]+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email);
- }
- /**
- * Check if $email is banned
- *
- * @param string $email
- * @return boolean
- * @access public
- */
- public function isBannedEmail($email)
- {
- $pun_bans = Pe::get('pun_bans');
- foreach ($pun_bans as $cur_ban)
- {
- if ($cur_ban['email'] != '' &&
- ($email == $cur_ban['email'] ||
- (strpos($cur_ban['email'], '@') === false && stristr($email, '@'.$cur_ban['email']))))
- return true;
- }
- return false;
- }
- /**
- * Encode mail text with base64.
- *
- * Only encode with base64, if there is at least one unicode character in the string
- *
- * @param string $str
- * @return string
- * @access private
- */
- private function _encodeMailText($str)
- {
- if (utf8_is_ascii($str))
- return $str;
- return '=?UTF-8?B?'.base64_encode($str).'?=';
- }
- /**
- * Wrapper for PHP's mail()
- *
- * @param string $to
- * @param string $subject
- * @param string $message
- * @param string $reply_to_email [optional]
- * @param string $reply_to_name [optional]
- * @access public
- */
- public function punMail($to, $subject, $message, $reply_to_email = '', $reply_to_name = '')
- {
- // Default sender/return address
- $from_name = str_replace('"', '', $this->pun_config['o_board_title']);
- $from_email = $this->pun_config['o_webmaster_email'];
- // Do a little spring cleaning
- $to = pun_trim(preg_replace('#[\n\r]+#s', '', $to));
- $subject = pun_trim(preg_replace('#[\n\r]+#s', '', $subject));
- $from_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $from_email));
- $from_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $from_name)));
- $reply_to_email = pun_trim(preg_replace('#[\n\r:]+#s', '', $reply_to_email));
- $reply_to_name = pun_trim(preg_replace('#[\n\r:]+#s', '', str_replace('"', '', $reply_to_name)));
- // Set up some headers to take advantage of UTF-8
- $from = $this->_encodeMailText($from_name).' <'.$from_email.'>';
- $subject = $this->_encodeMailText($subject);
- $headers = 'From: '.$from."\r\n".'Date: '.gmdate('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset=utf-8'."\r\n".'X-Mailer: FluxBB Mailer';
- // If we specified a reply-to email, we deal with it here
- if (!empty($reply_to_email))
- {
- $reply_to = $this->_encodeMailText($reply_to_name).' <'.$reply_to_email.'>';
- $headers .= "\r\n".'Reply-To: '.$reply_to;
- }
- // Make sure all linebreaks are CRLF in message (and strip out any NULL bytes)
- $message = str_replace(array("\n", "\0"), array("\r\n", ''), pun_linebreaks($message));
- if ($this->pun_config['o_smtp_host'] != '')
- $this->_smtpMail($to, $subject, $message, $headers);
- else
- {
- // Change the linebreaks used in the headers according to OS
- if (strtoupper(substr(PHP_OS, 0, 3)) == 'MAC')
- $headers = str_replace("\r\n", "\r", $headers);
- else if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN')
- $headers = str_replace("\r\n", "\n", $headers);
- mail($to, $subject, $message, $headers);
- }
- }
- /**
- * Parse server responce.
- *
- * If the socket returns unexpected responce throw an exception.
- *
- * This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com).
- * They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards.
- *
- * @param resource $socket
- * @param string $expected_response
- * @throws PeException
- * @access private
- */
- private function _serverParse($socket, $expected_response)
- {
- $server_response = '';
- while (substr($server_response, 3, 1) != ' ')
- {
- if (!($server_response = fgets($socket, 256)))
- throw new PeException('Couldn\'t get mail server response codes. Please contact the forum administrator.');
- }
- if (!(substr($server_response, 0, 3) == $expected_response))
- throw new PeException('Unable to send email. Please contact the forum administrator with the following error message reported by the SMTP server: "'.$server_response.'"');
- }
- /**
- * Send email via SMTP protocol.
- *
- * This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com).
- * They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards.
- *
- * @param string $to
- * @param string $subject
- * @param string $message
- * @param string $headers [optional]
- * @throws PeException
- * @access private
- */
- private function _smtpMail($to, $subject, $message, $headers = '')
- {
- $recipients = explode(',', $to);
- // Sanitize the message
- $message = str_replace("\r\n.", "\r\n..", $message);
- $message = (substr($message, 0, 1) == '.' ? '.'.$message : $message);
- // Are we using port 25 or a custom port?
- if (strpos($this->pun_config['o_smtp_host'], ':') !== false)
- list($smtp_host, $smtp_port) = explode(':', $this->pun_config['o_smtp_host']);
- else
- {
- $smtp_host = $this->pun_config['o_smtp_host'];
- $smtp_port = 25;
- }
- if ($this->pun_config['o_smtp_ssl'] == '1')
- $smtp_host = 'ssl://'.$smtp_host;
- if (!($socket = fsockopen($smtp_host, $smtp_port, $errno, $errstr, 15)))
- throw new PeException('Could not connect to smtp host "'.$this->pun_config['o_smtp_host'].'" ('.$errno.') ('.$errstr.')');
- $this->_serverParse($socket, '220');
- if ($this->pun_config['o_smtp_user'] != '' && $this->pun_config['o_smtp_pass'] != '')
- {
- fwrite($socket, 'EHLO '.$smtp_host."\r\n");
- $this->_serverParse($socket, '250');
- fwrite($socket, 'AUTH LOGIN'."\r\n");
- $this->_serverParse($socket, '334');
- fwrite($socket, base64_encode($this->pun_config['o_smtp_user'])."\r\n");
- $this->_serverParse($socket, '334');
- fwrite($socket, base64_encode($this->pun_config['o_smtp_pass'])."\r\n");
- $this->_serverParse($socket, '235');
- }
- else
- {
- fwrite($socket, 'HELO '.$smtp_host."\r\n");
- $this->_serverParse($socket, '250');
- }
- fwrite($socket, 'MAIL FROM: <'.$this->pun_config['o_webmaster_email'].'>'."\r\n");
- $this->_serverParse($socket, '250');
- foreach ($recipients as $email)
- {
- fwrite($socket, 'RCPT TO: <'.$email.'>'."\r\n");
- $this->_serverParse($socket, '250');
- }
- fwrite($socket, 'DATA'."\r\n");
- $this->_serverParse($socket, '354');
- fwrite($socket, 'Subject: '.$subject."\r\n".'To: <'.implode('>, <', $recipients).'>'."\r\n".$headers."\r\n\r\n".$message."\r\n");
- fwrite($socket, '.'."\r\n");
- $this->_serverParse($socket, '250');
- fwrite($socket, 'QUIT'."\r\n");
- fclose($socket);
- }
- /**
- * Send email messages about a new post to subscribers.
- *
- * @param int $tid
- * @param array $cur_posting
- * @param string $message
- * @param int $new_pid
- * @param string $username
- * @access public
- */
- public function mailNewPostSubscribers($tid, $cur_posting, $message, $new_pid, $username)
- {
- $this->db = Pe::get('db');
- $this->pun_user = Pe::get('pun_user');
- // Get the post time for the previous post in this topic
- $result = $this->db->query('SELECT posted FROM '.$this->db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1, 1');
- $previous_post_time = $this->db->result($result);
- $user_ids_sql[] = 'SELECT user_id FROM '.$this->db->prefix.'topic_subscriptions WHERE topic_id='.$tid.' AND send_email=1 AND user_id!='.$this->pun_user['id'];
- // Select IDs of board subscribers
- if ($this->pun_config['o_forum_subscriptions'] == '1')
- $user_ids_sql[] = 'SELECT user_id FROM '.$this->db->prefix.'forum_subscriptions WHERE forum_id='.$cur_posting['id'].' AND send_email=1 AND follow_replies=1 AND user_id!='.$this->pun_user['id'];
- // Select IDs of category subscribers
- if ($this->pun_config['o_category_subscriptions'] == '1')
- $user_ids_sql[] = 'SELECT user_id FROM '.$this->db->prefix.'category_subscriptions WHERE cat_id='.$cur_posting['cat_id'].' AND send_email=1 AND follow_replies=1 AND user_id!='.$this->pun_user['id'];
- // Get any subscribed users that should be notified (banned users are excluded)
- $result = $this->db->query('SELECT u.id, u.email, u.notify_with_post, u.language FROM '.$this->db->prefix.'users AS u LEFT JOIN '.$this->db->prefix.'forum_perms AS fp ON (fp.forum_id='.$cur_posting['id'].' AND fp.group_id=u.group_id) LEFT JOIN '.$this->db->prefix.'online AS o ON u.id=o.user_id LEFT JOIN '.$this->db->prefix.'bans AS b ON u.username=b.username WHERE b.username IS NULL AND COALESCE(o.logged, u.last_visit)>'.$previous_post_time.' AND (fp.read_forum IS NULL OR fp.read_forum=1) AND u.id IN ('.implode(' UNION ', $user_ids_sql).')');
- if ($this->db->num_rows($result))
- {
- $notification_emails = array();
- $subscribers = array();
- // Loop through subscribed users and send emails
- while ($cur_subscriber = $this->db->fetch_assoc($result))
- {
- // Is the subscription email for $cur_subscriber['language'] cached or not?
- if (!isset($notification_emails[$cur_subscriber['language']]))
- {
- if (file_exists(Pe::get('root').'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl'))
- {
- // Load the "new reply" template
- $mail_tpl = trim(file_get_contents(Pe::get('root').'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl'));
- // Load the "new reply full" template (with post included)
- $mail_tpl_full = trim(file_get_contents(Pe::get('root').'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply_full.tpl'));
- // The first row contains the subject (it also starts with "Subject:")
- $first_crlf = strpos($mail_tpl, "\n");
- $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
- $mail_message = trim(substr($mail_tpl, $first_crlf));
- $first_crlf = strpos($mail_tpl_full, "\n");
- $mail_subject_full = trim(substr($mail_tpl_full, 8, $first_crlf-8));
- $mail_message_full = trim(substr($mail_tpl_full, $first_crlf));
- $mail_subject = str_replace('<topic_subject>', $cur_posting['subject'], $mail_subject);
- $mail_message = str_replace('<topic_subject>', $cur_posting['subject'], $mail_message);
- $mail_message = str_replace('<replier>', $username, $mail_message);
- $mail_message = str_replace('<post_url>', Pe::get('urlUtils')->getBaseUrl().'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message);
- $mail_message = str_replace('<unsubscribe_url>', Pe::get('urlUtils')->getBaseUrl().'/misc.php?action=unsubscribe&tid='.$tid, $mail_message);
- $mail_message = str_replace('<board_mailer>', sprintf($this->lang_common['Mailer'], $this->pun_config['o_board_title']), $mail_message);
- $mail_subject_full = str_replace('<topic_subject>', $cur_posting['subject'], $mail_subject_full);
- $mail_message_full = str_replace('<topic_subject>', $cur_posting['subject'], $mail_message_full);
- $mail_message_full = str_replace('<replier>', $username, $mail_message_full);
- $mail_message_full = str_replace('<message>', $message, $mail_message_full);
- $mail_message_full = str_replace('<post_url>', Pe::get('urlUtils')->getBaseUrl().'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message_full);
- $mail_message_full = str_replace('<unsubscribe_url>', Pe::get('urlUtils')->getBaseUrl().'/misc.php?action=unsubscribe&tid='.$tid, $mail_message_full);
- $mail_message_full = str_replace('<board_mailer>', sprintf($this->lang_common['Mailer'], $this->pun_config['o_board_title']), $mail_message_full);
- $notification_emails[$cur_subscriber['language']][0] = $mail_subject;
- $notification_emails[$cur_subscriber['language']][1] = $mail_message;
- $notification_emails[$cur_subscriber['language']][2] = $mail_subject_full;
- $notification_emails[$cur_subscriber['language']][3] = $mail_message_full;
- $mail_subject = $mail_message = $mail_subject_full = $mail_message_full = null;
- }
- }
- // We have to double check here because the templates could be missing
- if (isset($notification_emails[$cur_subscriber['language']]))
- {
- if ($this->pun_config['o_use_email_pool'] == '0')
- {
- if ($cur_subscriber['notify_with_post'] == '0')
- $this->punMail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][0], $notification_emails[$cur_subscriber['language']][1]);
- else
- $this->punMail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][2], $notification_emails[$cur_subscriber['language']][3]);
- }
- else
- {
- $subscribers[$cur_subscriber['language']][$cur_subscriber['notify_with_post']][] = $cur_subscriber;
- }
- }
- }
- if ($this->pun_config['o_use_email_pool'] == '1' && !empty($subscribers))
- {
- foreach ($subscribers as $language => $cur_subscriber_set)
- {
- if (!empty($cur_subscriber_set[0]))
- {
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_messages (mail_subject, mail_message) VALUES (\''.$this->db->escape($notification_emails[$language][0]).'\', \''.$this->db->escape($notification_emails[$language][1]).'\')');
- $msg_id = $this->db->insert_id();
- $values = array();
- foreach ($cur_subscriber_set[0] as $cur_subscriber)
- $values[] = '('.$cur_subscriber['id'].', '.$msg_id.', \''.$this->db->escape($cur_subscriber['email']).'\')';
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_recipients (user_id, pool_msg_id, email) VALUES '.implode(', ', $values));
- }
- if (!empty($cur_subscriber_set[1]))
- {
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_messages (mail_subject, mail_message) VALUES (\''.$this->db->escape($notification_emails[$language][2]).'\', \''.$this->db->escape($notification_emails[$language][3]).'\')');
- $msg_id = $this->db->insert_id();
- $values = array();
- foreach ($cur_subscriber_set[1] as $cur_subscriber)
- $values[] = '('.$cur_subscriber['id'].', '.$msg_id.', \''.$this->db->escape($cur_subscriber['email']).'\')';
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_recipients (user_id, pool_msg_id, email) VALUES '.implode(', ', $values));
- }
- }
- }
- }
- }
- /**
- * Send email messages about a new topic to subscribers.
- *
- * @param array $cur_posting
- * @param string $subject
- * @param string $message
- * @param int $new_tid
- * @param string $username
- * @access public
- */
- public function mailNewTopicSubscribers($cur_posting, $subject, $message, $new_tid, $username)
- {
- $this->db = Pe::get('db');
- $this->pun_user = Pe::get('pun_user');
- $user_ids_sql = array();
- // Select IDs of board subscribers
- if ($this->pun_config['o_forum_subscriptions'] == '1')
- $user_ids_sql[] = 'SELECT user_id FROM '.$this->db->prefix.'forum_subscriptions WHERE forum_id='.$cur_posting['id'].' AND send_email=1 AND user_id!='.$this->pun_user['id'];
- // Select IDs of category subscribers
- if ($this->pun_config['o_category_subscriptions'] == '1')
- $user_ids_sql[] = 'SELECT user_id FROM '.$this->db->prefix.'category_subscriptions WHERE cat_id='.$cur_posting['cat_id'].' AND send_email=1 AND user_id!='.$this->pun_user['id'];
- if (empty($user_ids_sql))
- return;
- // Get any subscribed users that should be notified (banned users are excluded)
- $result = $this->db->query('SELECT u.id, u.email, u.notify_with_post, u.language FROM '.$this->db->prefix.'users AS u LEFT JOIN '.$this->db->prefix.'forum_perms AS fp ON (fp.forum_id='.$cur_posting['id'].' AND fp.group_id=u.group_id) LEFT JOIN '.$this->db->prefix.'bans AS b ON u.username=b.username WHERE b.username IS NULL AND (fp.read_forum IS NULL OR fp.read_forum=1) AND u.id IN ('.implode(' UNION ', $user_ids_sql).')');
- if ($this->db->num_rows($result))
- {
- $notification_emails = array();
- $subscribers = array();
- // Loop through subscribed users and send emails
- while ($cur_subscriber = $this->db->fetch_assoc($result))
- {
- // Is the subscription email for $cur_subscriber['language'] cached or not?
- if (!isset($notification_emails[$cur_subscriber['language']]))
- {
- if (file_exists(Pe::get('root').'lang/'.$cur_subscriber['language'].'/mail_templates/new_topic.tpl'))
- {
- // Load the "new topic" template
- $mail_tpl = trim(file_get_contents(Pe::get('root').'lang/'.$cur_subscriber['language'].'/mail_templates/new_topic.tpl'));
- // Load the "new topic full" template (with post included)
- $mail_tpl_full = trim(file_get_contents(Pe::get('root').'lang/'.$cur_subscriber['language'].'/mail_templates/new_topic_full.tpl'));
- // The first row contains the subject (it also starts with "Subject:")
- $first_crlf = strpos($mail_tpl, "\n");
- $mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
- $mail_message = trim(substr($mail_tpl, $first_crlf));
- $first_crlf = strpos($mail_tpl_full, "\n");
- $mail_subject_full = trim(substr($mail_tpl_full, 8, $first_crlf-8));
- $mail_message_full = trim(substr($mail_tpl_full, $first_crlf));
- $mail_subject = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_subject);
- $mail_message = str_replace('<topic_subject>', $subject, $mail_message);
- $mail_message = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_message);
- $mail_message = str_replace('<poster>', $username, $mail_message);
- $mail_message = str_replace('<topic_url>', Pe::get('urlUtils')->getBaseUrl().'/viewtopic.php?id='.$new_tid, $mail_message);
- $mail_message = str_replace('<unsubscribe_url>', Pe::get('urlUtils')->getBaseUrl().'/misc.php?action=unsubscribe&fid='.$cur_posting['id'], $mail_message);
- $mail_message = str_replace('<board_mailer>', sprintf($this->lang_common['Mailer'], $this->pun_config['o_board_title']), $mail_message);
- $mail_subject_full = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_subject_full);
- $mail_message_full = str_replace('<topic_subject>', $subject, $mail_message_full);
- $mail_message_full = str_replace('<forum_name>', $cur_posting['forum_name'], $mail_message_full);
- $mail_message_full = str_replace('<poster>', $username, $mail_message_full);
- $mail_message_full = str_replace('<message>', $message, $mail_message_full);
- $mail_message_full = str_replace('<topic_url>', Pe::get('urlUtils')->getBaseUrl().'/viewtopic.php?id='.$new_tid, $mail_message_full);
- $mail_message_full = str_replace('<unsubscribe_url>', Pe::get('urlUtils')->getBaseUrl().'/misc.php?action=unsubscribe&fid='.$cur_posting['id'], $mail_message_full);
- $mail_message_full = str_replace('<board_mailer>', sprintf($this->lang_common['Mailer'], $this->pun_config['o_board_title']), $mail_message_full);
- $notification_emails[$cur_subscriber['language']][0] = $mail_subject;
- $notification_emails[$cur_subscriber['language']][1] = $mail_message;
- $notification_emails[$cur_subscriber['language']][2] = $mail_subject_full;
- $notification_emails[$cur_subscriber['language']][3] = $mail_message_full;
- $mail_subject = $mail_message = $mail_subject_full = $mail_message_full = null;
- }
- }
- // We have to double check here because the templates could be missing
- if (isset($notification_emails[$cur_subscriber['language']]))
- {
- if ($this->pun_config['o_use_email_pool'] == '0')
- {
- if ($cur_subscriber['notify_with_post'] == '0')
- $this->punMail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][0], $notification_emails[$cur_subscriber['language']][1]);
- else
- $this->punMail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][2], $notification_emails[$cur_subscriber['language']][3]);
- }
- else
- {
- $subscribers[$cur_subscriber['language']][$cur_subscriber['notify_with_post']][] = $cur_subscriber;
- }
- }
- }
- if ($this->pun_config['o_use_email_pool'] == '1' && !empty($subscribers))
- {
- foreach ($subscribers as $language => $cur_subscriber_set)
- {
- if (!empty($cur_subscriber_set[0]))
- {
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_messages (mail_subject, mail_message) VALUES (\''.$this->db->escape($notification_emails[$language][0]).'\', \''.$this->db->escape($notification_emails[$language][1]).'\')');
- $msg_id = $this->db->insert_id();
- $values = array();
- foreach ($cur_subscriber_set[0] as $cur_subscriber)
- $values[] = '('.$cur_subscriber['id'].', '.$msg_id.', \''.$this->db->escape($cur_subscriber['email']).'\')';
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_recipients (user_id, pool_msg_id, email) VALUES '.implode(', ', $values));
- }
- if (!empty($cur_subscriber_set[1]))
- {
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_messages (mail_subject, mail_message) VALUES (\''.$this->db->escape($notification_emails[$language][2]).'\', \''.$this->db->escape($notification_emails[$language][3]).'\')');
- $msg_id = $this->db->insert_id();
- $values = array();
- foreach ($cur_subscriber_set[1] as $cur_subscriber)
- $values[] = '('.$cur_subscriber['id'].', '.$msg_id.', \''.$this->db->escape($cur_subscriber['email']).'\')';
- $this->db->query('INSERT INTO '.$this->db->prefix.'email_pool_recipients (user_id, pool_msg_id, email) VALUES '.implode(', ', $values));
- }
- }
- }
- }
- }
- /**
- * Send a batch of emails from the email pool.
- *
- * @throws PeDbException
- */
- public function cronMail()
- {
- if ($this->pun_config['o_use_email_pool'] == '0')
- return;
- $this->db = Pe::get('db');
- $result = $this->db->query('SELECT user_id, pool_msg_id, email FROM '.$this->db->prefix.'email_pool_recipients ORDER BY pool_msg_id ASC LIMIT '.$this->pun_config['o_email_batch_size']);
- // Do we have anything to send?
- if (!$this->db->num_rows($result))
- return;
- $recipients = array();
- $msg_ids = array();
- while ($cur_recipient = $this->db->fetch_assoc($result))
- {
- $recipients[] = $cur_recipient;
- $msg_ids[] = $cur_recipient['pool_msg_id'];
- }
- $msg_ids = array_unique($msg_ids);
- $result = $this->db->query('SELECT id, mail_subject, mail_message FROM '.$this->db->prefix.'email_pool_messages WHERE id IN ('.implode(', ', $msg_ids).')');
- if (!$this->db->num_rows($result))
- throw new PeDbException('Database tables seem to be out of sync.');
- $messages = array();
- while ($cur_message = $this->db->fetch_assoc($result))
- $messages[$cur_message['id']] = $cur_message;
- $cur_msg_id = 0;
- $user_ids = array();
- foreach ($recipients as $cur_recipient)
- {
- if ($cur_msg_id != $cur_recipient['pool_msg_id'])
- {
- // Delete recipients from the database
- if (!empty($user_ids))
- $this->db->query('DELETE FROM '.$this->db->prefix.'email_pool_recipients WHERE pool_msg_id='.$cur_msg_id.' AND user_id IN ('.implode(', ', $user_ids).')');
- $cur_msg_id = $cur_recipient['pool_msg_id'];
- $user_ids = array();
- }
- $user_ids[] = $cur_recipient['user_id'];
- // Send message
- $this->punMail($cur_recipient['email'], $messages[$cur_recipient['pool_msg_id']]['mail_subject'], $messages[$cur_recipient['pool_msg_id']]['mail_message']);
- }
- // Delete recipients from the database
- if (!empty($user_ids))
- $this->db->query('DELETE FROM '.$this->db->prefix.'email_pool_recipients WHERE pool_msg_id='.$cur_msg_id.' AND user_id IN ('.implode(', ', $user_ids).')');
- // Delete messages from database
- $this->db->query('DELETE FROM '.$this->db->prefix.'email_pool_messages WHERE id NOT IN (SELECT DISTINCT pool_msg_id FROM '.$this->db->prefix.'email_pool_recipients)');
- }
- }