Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Chops up WordPress out-going emails so that number of bcc addressees stays below a configured limit
<?php
/*
Plugin Name: Ovni chop up emails
Description: Prevents number of Bcc addresees exceeding defined limit by breaking it up into multiple emails.
Author: Tony Voss
Version: 1.0 1 Mar 2019
History
Version: 1.0 1 Mar 2019 Initial version
Limitations:
(1) If an email contains mutiple cc addressees it notes it in the error log but lets the email through. Not seen any such emails from my websites.
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
function ovni_chop_email($args){
/* configuration */
$max_bcc = 10; // maximum number of Bcc addresses allowed
$debug = false; // whether want debug
if ($debug){
ob_start();
var_dump($args);
$result = ob_get_clean();
error_log("Entering ovni_chop_email\n" . $result);
}
$headers = $args['headers'];
if (empty($headers)) return($args); // if no headers, nothing to do
// pick up CC/BCC, collating them from headers
if (isset($args['headers'])) {
$cc = array();
$bcc = array();
$other = array();
if (!is_array($headers)) {
$headers = explode("\n", str_replace("\r\n", "\n", $headers));
}
foreach ($headers as $header) {
if ($header) {
switch (strtolower(substr($header, 0, 3))) {
case 'cc:':
$cc[] = $header;
error_log("Found cc:" . $header);
break;
case 'bcc':
$bcc[] = $header;
break;
default:
$others[] = $header;
break;
}
}
if (!empty($cc)){
// not yet supporting cc
error_log("Ovni_chop_mail saw addressee in cc field for email: " . $args['subject']);
return($args);
}
}
if (sizeof($bcc) == 1){ // may be a list of adressees with a single bcc header, as from Subscribe2
$bcc = explode("\n", str_replace(",", "\nBcc:", $bcc[0]));
}
if (sizeof($bcc) <= $max_bcc) return($args); // This one can go straight through - nothing to do
}
// we need to chop up this email into multiples
remove_filter('wp_mail', 'ovni_chop_email',5); // We do not want to be called back each time we send one of the parts
while (sizeof($bcc) > $max_bcc){
if($debug) error_log("Chopping up - bcc=". strval(sizeof($bcc)));
$this_batch = array_slice($bcc, 0, $max_bcc);
$bcc = array_slice($bcc, $max_bcc); // reduce to those not in this batch
$headers = array_merge($others, $this_batch);
if (!wp_mail($args["to"], $args["subject"], $args["message"], $headers, $args["attachments"])) error_log("Ovni_chop_email returned error");
}
// We are here because we have done all but the last chunk. Return and let original call do this one.
$headers = array_merge($others, $bcc);
$args['headers'] = $headers;
add_filter('wp_mail', 'ovni_chop_email',5); // restore the filter
return($args);
}
add_filter('wp_mail', 'ovni_chop_email',5);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment