Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions CRM/Utils/Mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,29 @@ public static function setMimeParams($message, $params = NULL) {
* @return null|string
*/
public static function formatRFC822Email($name, $email, $useQuote = FALSE) {
$result = NULL;
if (empty($email)) {
return NULL;
}

// Already formatted
if (str_contains($email, '<')) {
return $email;
}

// Split multiple emails
if (str_contains($email, ',') || str_contains($email, ';')) {
$emails = preg_split('/[,;]+/', $email);
$formatted = [];
foreach ($emails as $singleEmail) {
$singleEmail = trim($singleEmail);
if ($singleEmail !== '') {
$formatted[] = self::formatRFC822Email($name, $singleEmail, $useQuote);
}
}
return implode(', ', $formatted);
}

$email = trim($email);
$name = trim($name ?? '');

// strip out double quotes if present at the beginning AND end
Expand All @@ -587,11 +608,10 @@ public static function formatRFC822Email($name, $email, $useQuote = FALSE) {
$name = '"' . $name . '"';
}

$result = "$name ";
return "$name <{$email}>";
}

$result .= "<{$email}>";
return $result;
return "<{$email}>";
}

/**
Expand Down
38 changes: 37 additions & 1 deletion tests/phpunit/CRM/Utils/MailTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,52 @@ public function testFormatRFC822(): void {
'result' => '"User, Test" <foo@bar.com>',
'useQuote' => TRUE,
],
[
'name' => '',
'email' => 'foo@bar.com',
'result' => '<foo@bar.com>',
],
[
'name' => NULL,
'email' => 'foo@bar.com',
'result' => '<foo@bar.com>',
],
[
'name' => '',
'email' => 'foo@bar.com, baz@bar.com',
'result' => '<foo@bar.com>, <baz@bar.com>',
],
[
'name' => NULL,
'email' => 'foo@bar.com, baz@bar.com',
'result' => '<foo@bar.com>, <baz@bar.com>',
],
[
'name' => '',
'email' => 'foo@bar.com; baz@bar.com',
'result' => '<foo@bar.com>, <baz@bar.com>',
],
];
foreach ($values as $value) {
$result = CRM_Utils_Mail::formatRFC822Email($value['name'],
$value['email'],
$value['useQuote'] ?? FALSE
);
$this->assertEquals($result, $value['result'], 'Expected encoding does not match');
$this->assertEquals($value['result'], $result, 'Expected encoding does not match');
}
}

public function testSetEmailHeadersMultipleRecipients(): void {
$params = [
'toEmail' => 'foo@bar.com, baz@bar.com',
'from' => 'admin@example.com',
'subject' => 'Test',
'text' => 'Hello',
];
[$headers, $message] = CRM_Utils_Mail::setEmailHeaders($params);
$this->assertEquals('<foo@bar.com>, <baz@bar.com>', $headers['To']);
}

/**
* Test exception handling in mail function.
*/
Expand Down
33 changes: 33 additions & 0 deletions tests/phpunit/api/v3/JobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2471,6 +2471,39 @@ public function testMailReportForCsv(): void {
$mut->stop();
}

/**
* Test that the mail_report job sends an email when multiple recipients are specified in email_to.
*/
public function testMailReportMultipleRecipients(): void {
$mut = new CiviMailUtils($this, TRUE);
$reportInstance = $this->createReportInstance();
$this->callAPISuccess('ReportInstance', 'create', [
'id' => $reportInstance['id'],
'email_to' => 'person1@example.com, person2@example.com',
]);

if (empty($_SERVER['QUERY_STRING'])) {
$_SERVER['QUERY_STRING'] = 'reset=1';
}

ob_start();
$this->callApiV3Success('Job', 'mail_report', [
'instanceId' => $reportInstance['id'],
'format' => 'pdf',
]);
ob_end_clean();

$message = $mut->getMostRecentEmail('ezc');

$this->assertEquals('This is the email subject', $message->subject);
$this->assertCount(2, $message->to);
$this->assertEquals('person1@example.com', $message->to[0]->email);
$this->assertEquals('person2@example.com', $message->to[1]->email);

$mut->clearMessages();
$mut->stop();
}

/**
* Helper to create a report instance of the contact summary report.
*
Expand Down