View source
<?php
namespace Drupal\sparkpost\Plugin\Mail;
use Drupal\Core\Mail\MailFormatHelper;
use Drupal\Core\Mail\MailInterface;
use Drupal\sparkpost\ClientService;
class SparkpostMail implements MailInterface {
protected $config;
protected $messageWrapper;
public function __construct() {
$this->config = \Drupal::service('config.factory')
->get('sparkpost.settings');
$this->messageWrapper = \Drupal::service('sparkpost.message_wrapper');
}
public function format(array $message) {
if (is_array($message['body'])) {
$message['body'] = implode("\n\n", $message['body']);
}
$message['subject'] = preg_replace('/[\\r\\n]+/', '', $message['subject']);
return $message;
}
public function mail(array $message) {
try {
$format = $this->config
->get('format');
if (!empty($format)) {
$message['body'] = check_markup($message['body'], $format);
}
$headers = isset($message['headers']) ? $message['headers'] : [];
if (isset($message['params']['sparkpost']['header'])) {
$headers = $message['params']['sparkpost']['header'] + $headers;
}
if (!empty($message['from']) && empty($headers['Reply-To'])) {
$headers['Reply-To'] = $message['from'];
}
$to = $this
->createRecipientField($message['to']);
$cc = $bcc = [];
if (isset($headers['Cc'])) {
$cc = $this
->createCcField($headers['Cc'], $to);
}
if (isset($headers['Bcc'])) {
$bcc = $this
->createCcField($headers['Bcc'], $to);
}
$to = array_merge($to, $cc, $bcc);
$reply_to = isset($headers['Reply-To']) ? $headers['Reply-To'] : NULL;
$headers = $this
->allowedHeaders($headers);
$attachments = [];
if (isset($message['attachments']) && !empty($message['attachments'])) {
foreach ($message['attachments'] as $attachment) {
if (is_file($attachment)) {
$attachments[] = $this
->getAttachmentStruct($attachment);
}
}
}
$plain_text = empty($message['params']['plaintext']) ? MailFormatHelper::htmlToText($message['body']) : $message['params']['plaintext'];
$overrides = isset($message['params']['sparkpost']['overrides']) ? $message['params']['sparkpost']['overrides'] : [];
$sparkpost_message = $overrides + [
'content' => [
'from' => [
'name' => $this->config
->get('sender_name'),
'email' => $this->config
->get('sender'),
],
'html' => $message['body'],
'text' => $plain_text,
'subject' => $message['subject'],
'attachments' => $attachments,
'reply_to' => $reply_to,
'headers' => $headers,
],
'recipients' => $to,
'campaign_id' => substr($message['id'], 0, 64),
'options' => [
'transactional' => TRUE,
],
];
\Drupal::moduleHandler()
->alter('sparkpost_mail', $sparkpost_message, $message);
$this->messageWrapper
->setDrupalMessage($message);
$this->messageWrapper
->setSparkpostMessage($sparkpost_message);
if ($this->config
->get('async')) {
$queue = \Drupal::queue('sparkpost_send');
$queue
->createItem($this->messageWrapper);
return TRUE;
}
$this->messageWrapper
->sendMessage();
return TRUE;
} catch (\Exception $e) {
if ($this->config
->get('debug')) {
watchdog_exception('sparkpost', $e);
}
return FALSE;
}
}
protected function getAttachmentStruct($path) {
$struct = [];
if (!@is_file($path)) {
throw new \Exception($path . ' is not a valid file.');
}
$filename = basename($path);
$file_buffer = file_get_contents($path);
$file_buffer = chunk_split(base64_encode($file_buffer), 76, "\n");
$mime_type = \Drupal::service('file.mime_type.guesser')
->guess($path);
if (!$this
->isValidContentType($mime_type)) {
throw new \Exception($mime_type . ' is not a valid content type.');
}
$struct['type'] = $mime_type;
$struct['name'] = $filename;
$struct['data'] = $file_buffer;
return $struct;
}
protected function isValidContentType($file_type) {
$valid_types = [
'image/',
'text/',
'application/pdf',
'application/x-zip',
];
foreach ($valid_types as $vct) {
if (strpos($file_type, $vct) !== FALSE) {
return TRUE;
}
}
return FALSE;
}
private function allowedHeaders(array $headers) {
foreach ($headers as $header => $value) {
if (strpos($header, 'X-') === 0) {
continue;
}
elseif (in_array($header, [
'Return-Path',
'Cc',
])) {
continue;
}
unset($headers[$header]);
}
return $headers;
}
private function createRecipientField($to) {
$recipients = [];
$to_array = explode(',', $to);
foreach ($to_array as $email) {
if (preg_match(ClientService::EMAIL_REGEX, $email, $matches)) {
$recipients[] = [
'address' => [
'name' => $matches[1],
'email' => $matches[2],
],
];
}
else {
$recipients[] = [
'address' => [
'email' => $email,
],
];
}
}
return $recipients;
}
private function createCcField($cc, array $to) {
$recipients = [];
$cc_array = explode(',', $cc);
$header_to = implode(',', array_map(function ($recipient) {
return $recipient['address']['email'];
}, $to));
foreach ($cc_array as $email) {
if (preg_match(ClientService::EMAIL_REGEX, $email, $matches)) {
$email = $matches[2];
}
$recipients[] = [
'address' => [
'email' => $email,
'header_to' => $header_to,
],
];
}
return $recipients;
}
}