I have configured swiftmailer to spool emails using file type. here is my swiftmailer config
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool:
type: file
path: "%kernel.root_dir%/../var/spool"
When I send any emails it perfectly spools. I run following command to dispatch emails thereafter.
bin/console swiftmailer:spool:send --env=dev
According to Symfony documentation
the console command should be triggered by a cron job or scheduled task and run at a regular interval.
My problem is, I cannot use crontab because cron can be configured with a minimum of 1 minute interval which I cannot afford. I want to make use of the background process with immediate execution after the response is sent back to browser, hence minimizing execution of spools to bare minimum.
I attempted to solve this problem by creating an event listener class and listening to kernel.terminate
, and execute the command using shell_exec
or exec
function, here is the code for reference.
app.kernel.terminate.listener:
arguments: ["@kernel"]
class: AppBundle\EventListener\KernelTerminateListener
tags:
- { name: kernel.event_listener, event: kernel.terminate }
Here is my EventListener class
<?php
namespace AppBundle\EventListener;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Cocur\BackgroundProcess\BackgroundProcess;
class KernelTerminateListener
{
protected $kernel;
protected $console;
public function __construct($kernel)
{
$this->kernel = $kernel;
$this->console = $this->kernel->getRootDir().'/../bin/console ';
}
public function onKernelTerminate(PostResponseEvent $event)
{
$command = $this->console.'swiftmailer:spool:send --env='.$this->kernel->getEnvironment();
shell_exec($command);
}
}
What I am trying in here is to run bin/console swiftmailer:spool:send --env=dev
on kernel.terminate
event, unfortunately this does not work, any hint on how to approach this problem is appreciated.
Thank you.
Please use the memory spool type of swift mailer, it does exactly what you want
When you use spooling to store the emails to memory, they will get sent right before the kernel terminates. This means the email only gets sent if the whole request got executed without any unhandled exception or any errors. To configure swiftmailer with the memory option, use the following configuration: