Sending emails is a very common task in modern Enterprise Software Applications. If your application is built on top of PHP Symfony Framework, just follow these simple steps:
Prerequisites:
Step 1. Make sure you have the Symfony mailer component by doing:
composer require symfony/mailer
Step 2. Configure your mailer in the config/packages/mailer.yaml
file:
# config/packages/mailer.yaml
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
Notice that MAILER_DSN
is the connection string to the mailing transport. For more information on this refer to Symfony Mailer Component
Step 3. Inject the Symfony\Component\Mailer\MailerInterface
in the Controller or Service Class from where you are going to send emails and implement something like this:
use App\ApiBundle\Exceptions\SystemException;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mime\Email;
use Twig\Environment;
class MailService
{
/**
* @var MailerInterface
*/
private MailerInterface $mailer;
/**
* @var Environment
*/
private Environment $twig;
/**
* @param MailerInterface $mailer
* @param Environment $twig
*/
public function __construct(MailerInterface $mailer, Environment $twig)
{
$this->mailer = $mailer;
$this->twig = $twig;
}
/**
* @param SomeDtoClass $forThis
* @return array
*/
public function getEmailPayload(SomeDtoClass $forThis): array
{
//...Get Email Twig Template Name
$payload['twigTemplateName'] = $forThis->templateName;
//...Get Data to put in Html Text
$payload['HtmlBody'] = $this->getHtmlBody($forThis->data);
//...Get Text To put in no Html format Email
$payload['rawTextBody'] = $this->getRawTextBody($forThis->data);
//...Get Sender
$payload['sender'] = $this->getEmailSenser($forThis);
//...Get Recipient(s) email address
$payload['sendTo'] = $this->getSendTo($forThis->user);
//...Get Email Subject Text string
$payload['subject'] = $this->getEmailSubject($forThis);
//...Get Email Attachments if any
$payload['attachments'] = $this->getEmailAttachments($forThis->attachments);
return $payload;
}
/**
* @param array $payload
* @return bool
*/
public function sendEmail(array $payload): bool
{
try {
//Use this in case you prefer to have all sensitive data stored somewhere else like in a Schema table no accesible by anyone but the sys admin
$dsn = $this->getParamFromDb('MAILER_DSN');
$transport = Transport::fromDsn($dsn);
$mailer = new Mailer($transport);
$message = new Email();
$message->getHeaders()
// this non-standard header tells compliant autoresponders ("email holiday mode") to not
// reply to this message because it's an automated email
->addTextHeader('X-Auto-Response-Suppress', 'OOF, DR, RN, NRN, AutoReply');
$message->from($payload['sender'])
->to($payload['sendTo'])
->subject($payload['subject'])
->text($this->twig->render('emails/' . $payload['twigTemplateName'] . '.txt.twig', $payload['rawTextBody']))
->html($this->twig->render('emails/' . $payload['twigTemplateName'] . '.html.twig', $payload['HtmlBody']));
//Most Email services like Google and Yahoo accept up to 10 attachments and total size up to 20 MB
foreach ($payload['attachments'] as $attachment) {
$message->attach($attachment, $attachment->name, $attachment->contentType);
}
//Send Email
$mailer->send($message);
} catch (\Throwable $e) {
throw new SystemException($e->getMessage());
}
return true;
}
}
It is always a good idea to use Twig Templates for the email content. This way, you can have very nice formatted text and a template that can be reused over and over again.
Refer to Symfony Documentation for more details and more options.