View source
<?php
namespace Drupal\mailgun;
use Drupal\Component\Utility\EmailValidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\EmailParser;
use Psr\Log\LoggerInterface;
use Mailgun\Mailgun;
use Mailgun\Exception;
class MailgunHandler implements MailgunHandlerInterface {
protected $mailgunConfig;
protected $logger;
protected $mailgun;
protected $messenger;
protected $emailValidator;
public function __construct(Mailgun $mailgun_client, ConfigFactoryInterface $config_factory, LoggerInterface $logger, MessengerInterface $messenger, EmailValidatorInterface $email_validator) {
$this->mailgunConfig = $config_factory
->get(MailgunHandlerInterface::CONFIG_NAME);
$this->logger = $logger;
$this->mailgun = $mailgun_client;
$this->messenger = $messenger;
$this->emailValidator = $email_validator;
}
public function sendMail(array $mailgunMessage) {
try {
if (!$this
->validateMailgunApiSettings()) {
$this->logger
->error('Failed to send message from %from to %to. Please check the Mailgun settings.', [
'%from' => $mailgunMessage['from'],
'%to' => $this
->getRecipients($mailgunMessage),
]);
return FALSE;
}
$domain = $this
->getDomain($mailgunMessage['from']);
if ($domain === FALSE) {
$this->logger
->error('Failed to send message from %from to %to. Could not retrieve domain from sender info.', [
'%from' => $mailgunMessage['from'],
'%to' => $this
->getRecipients($mailgunMessage),
]);
return FALSE;
}
$response = $this->mailgun
->messages()
->send($domain, $mailgunMessage);
if ($this->mailgunConfig
->get('debug_mode')) {
$this->logger
->notice('Successfully sent message from %from to %to. %id %message.', [
'%from' => $mailgunMessage['from'],
'%to' => $this
->getRecipients($mailgunMessage),
'%id' => $response
->getId(),
'%message' => $response
->getMessage(),
]);
}
return $response;
} catch (Exception $e) {
$this->logger
->error('Exception occurred while trying to send test email from %from to %to. Error code @code: @message', [
'%from' => $mailgunMessage['from'],
'%to' => $this
->getRecipients($mailgunMessage),
'@code' => $e
->getCode(),
'@message' => $e
->getMessage(),
]);
return FALSE;
}
}
public function getDomains() {
$domains = [];
try {
$result = $this->mailgun
->domains()
->index();
if ($result
->getTotalCount() > 100) {
$result = $this->mailgun
->domains()
->index($result
->getTotalCount());
}
foreach ($result
->getDomains() as $domain) {
$domains[$domain
->getName()] = $domain
->getName();
}
ksort($domains);
} catch (Exception $e) {
$this->logger
->error('Could not retrieve domains from Mailgun API. @code: @message.', [
'@code' => $e
->getCode(),
'@message' => $e
->getMessage(),
]);
}
return $domains;
}
public function getDomain($from) {
$domain = $this->mailgunConfig
->get('working_domain');
if ($domain !== '_sender') {
return $domain;
}
$emailParser = new EmailParser(new EmailLexer());
if ($this->emailValidator
->isValid($from)) {
return $emailParser
->parse($from)['domain'];
}
$tokens = preg_match('/^\\s*(.+?)\\s*<\\s*([^>]+)\\s*>$/', $from, $matches) === 1 ? explode('@', $matches[2]) : explode('@', $from);
return !empty($tokens) ? array_pop($tokens) : FALSE;
}
public function moduleStatus($showMessage = FALSE) {
return $this
->validateMailgunLibrary($showMessage) && $this
->validateMailgunApiSettings($showMessage);
}
public function validateMailgunApiKey($key) {
if (!$this
->validateMailgunLibrary()) {
return FALSE;
}
$mailgun = Mailgun::create($key);
try {
$mailgun
->domains()
->index();
} catch (Exception $e) {
return FALSE;
}
return TRUE;
}
public function validateMailgunApiSettings($showMessage = FALSE) {
$apiKey = $this->mailgunConfig
->get('api_key');
$workingDomain = $this->mailgunConfig
->get('working_domain');
if (empty($apiKey) || empty($workingDomain)) {
if ($showMessage) {
$this->messenger
->addMessage("Please check your API settings. API key and domain shouldn't be empty.", 'warning');
}
return FALSE;
}
if (!$this
->validateMailgunApiKey($apiKey)) {
if ($showMessage) {
$this->messenger
->addMessage("Couldn't connect to the Mailgun API. Please check your API settings.", 'warning');
}
return FALSE;
}
return TRUE;
}
public function validateMailgunLibrary($showMessage = FALSE) {
$libraryStatus = class_exists('\\Mailgun\\Mailgun');
if ($showMessage === FALSE) {
return $libraryStatus;
}
if ($libraryStatus === FALSE) {
$this->messenger
->addMessage('The Mailgun library has not been installed correctly.', 'warning');
}
return $libraryStatus;
}
protected function getRecipients(array $mailgunMessage) {
$recipients = is_array($mailgunMessage['to']) ? implode(', ', $mailgunMessage['to']) : $mailgunMessage['to'];
foreach ([
'cc',
'bcc',
] as $parameter) {
if (!empty($mailgunMessage[$parameter])) {
$recipients .= "; {$parameter}: {$mailgunMessage[$parameter]}";
}
}
return $recipients;
}
}