diff --git a/Sources/ManageMail.php b/Sources/ManageMail.php index d7c58994f6..361b8f7a28 100644 --- a/Sources/ManageMail.php +++ b/Sources/ManageMail.php @@ -249,6 +249,8 @@ function list_getMailQueue($start, $items_per_page, $sort) // Private PM/email subjects and similar shouldn't be shown in the mailbox area. if (!empty($row['private'])) $row['subject'] = $txt['personal_message']; + else + $row['subject'] = mb_decode_mimeheader($row['subject']); $mails[] = $row; } diff --git a/Sources/ScheduledTasks.php b/Sources/ScheduledTasks.php index 62e17c6508..5c5eea4e5e 100644 --- a/Sources/ScheduledTasks.php +++ b/Sources/ScheduledTasks.php @@ -712,7 +712,7 @@ function ReduceMailQueue($number = false, $override_limit = false, $force_send = // Now we know how many we're sending, let's send them. $request = $smcFunc['db_query']('', ' - SELECT id_mail, recipient, body, subject, headers, send_html, time_sent, private + SELECT id_mail, recipient, body, subject, headers, send_html, time_sent, private, priority FROM {db_prefix}mail_queue ORDER BY priority ASC, id_mail ASC LIMIT {int:limit}', @@ -734,6 +734,7 @@ function ReduceMailQueue($number = false, $override_limit = false, $force_send = 'send_html' => $row['send_html'], 'time_sent' => $row['time_sent'], 'private' => $row['private'], + 'priority' => $row['priority'], ); } $smcFunc['db_free_result']($request); @@ -772,8 +773,18 @@ function ReduceMailQueue($number = false, $override_limit = false, $force_send = // Send each email, yea! $failed_emails = array(); + $max_priority = 127; + $smtp_expire = 259200; + $priority_offset = 4; foreach ($emails as $email) { + // This seems odd, but check the priority if we should try again so soon. Do this so we don't DOS some poor mail server. + if ($email['priority'] > $priority_offset && (time() - $email['time_sent']) % $priority_offset != rand(0, $priority_offset)) + { + $failed_emails[] = array($email['to'], $email['body'], $email['subject'], $email['headers'], $email['send_html'], $email['time_sent'], $email['private'], $email['priority']); + continue; + } + if (empty($modSettings['mail_type']) || $modSettings['smtp_host'] == '') { $email['subject'] = strtr($email['subject'], array("\r" => '', "\n" => '')); @@ -794,11 +805,21 @@ function ReduceMailQueue($number = false, $override_limit = false, $force_send = else $result = smtp_mail(array($email['to']), $email['subject'], $email['body'], $email['headers']); + // Old emails should expire + if (!$result && $email['priority'] >= $max_priority) + $result = true; + // Hopefully it sent? if (!$result) - $failed_emails[] = array($email['to'], $email['body'], $email['subject'], $email['headers'], $email['send_html'], $email['time_sent'], $email['private']); + { + // Determine the "priority" as a way to keep track of SMTP failures. + $email['priority'] = max($priority_offset, $email['priority'], min(ceil((time() - $email['time_sent']) / $smtp_expire * ($max_priority - $priority_offset)) + $priority_offset, $max_priority)); + + $failed_emails[] = array($email['to'], $email['body'], $email['subject'], $email['headers'], $email['send_html'], $email['time_sent'], $email['private'], $email['priority']); + } } + // Any emails that didn't send? if (!empty($failed_emails)) { @@ -826,7 +847,7 @@ function ReduceMailQueue($number = false, $override_limit = false, $force_send = // Add our email back to the queue, manually. $smcFunc['db_insert']('insert', '{db_prefix}mail_queue', - array('recipient' => 'string', 'body' => 'string', 'subject' => 'string', 'headers' => 'string', 'send_html' => 'string', 'time_sent' => 'string', 'private' => 'int'), + array('recipient' => 'string', 'body' => 'string', 'subject' => 'string', 'headers' => 'string', 'send_html' => 'string', 'time_sent' => 'string', 'private' => 'int', 'priority' => 'int'), $failed_emails, array('id_mail') ); diff --git a/Sources/Subs-Post.php b/Sources/Subs-Post.php index d744fae1e0..496c32ebb2 100644 --- a/Sources/Subs-Post.php +++ b/Sources/Subs-Post.php @@ -1592,9 +1592,17 @@ function server_parse($message, $socket, $code, &$response = null) if ($code === null) return substr($server_response, 0, 3); - if (substr($server_response, 0, 3) != $code) + $response_code = (int) substr($server_response, 0, 3); + if ($response_code != $code) { - log_error($txt['smtp_error'] . $server_response); + // Ignoreable errors that we can't fix should not be logged. + /* + * 550 - cPanel rejected sending due to DNS issues + * 450 - DNS Routing issues + */ + if ($response_code < 500 && $response_code != 450) + log_error($txt['smtp_error'] . $server_response); + return false; }