How to add eventListener to swiftmailer send event? Every time i send email i create a file and attach it to email, and after sending i want to unlink that file. How to do that? Thanks.
file_put_contents($path, implode(";\r\n", $result));
$message = (new \Swift_Message('VAT checking result !'))
->setFrom('[email protected]')
->setTo($vat->getEmail())
->setBody(
'Hello, ...' ,'text/')
->attach(\Swift_Attachment::fromPath($path));
// START send result email
$mailer = $this->container->get('mailer');
$listener = $this->container->get('app.service.send_email_listener');
$listener->setPathToFile($path);
$mailer->registerPlugin($listener);
$mailer->send( $message );
// END send email to admin
//unlink($path); email will not be sent
I tried to register listener like that
app.service.send_email_listener:
class: AppBundle\Listener\SendEmailListener
public: true
tags:
- { name: swiftmailer.plugin }
this is listener class :
namespace AppBundle\Listener;
use \Swift_Events_SendListener as base;
class SendEmailListener implements base
{
private $pathToFile;
public function setPathToFile($path)
{
$this->pathToFile = $path;
}
public function getPathToFile($path)
{
return $this->pathToFile;
}
/**
* Invoked immediately before the Message is sent.
*
* @param \Swift_Events_SendEvent $evt
*/
public function beforeSendPerformed(\Swift_Events_SendEvent $evt)
{
}
/**
* Invoked immediately after the Message is sent.
*
* @param \Swift_Events_SendEvent $evt
*/
public function sendPerformed(\Swift_Events_SendEvent $evt)
{
if($this->pathToFile){
unlink($this->pathToFile);
}
}
}
EDIT It executes the method, but swift is not able to stream the file , beacuse the the file is unlinked before the sending is end... This is from dev_logs:
[2018-05-24 20:40:18] php.CRITICAL: Uncaught Exception: Unable to open file for reading [C:\Users\\projects\vat\web\vatfiles\122.txt] {"exception":"[object] (Swift_IoException(code: 0): Unable to open file for reading [C:\\Users\\\projects\\vat\\web\\vatfiles\\122.txt] at C:\\Users\\projects\\vat\\vendor\\swiftmailer\\swiftmailer\\lib\\classes\\Swift\\ByteStream\\FileByteStream.php:144)"} []
As an alternative to using a Swiftmailer Plugin, I recommend using the __destruct
magic method in your service/controller that utilizes the file(s). __destruct
will be called when the object is released and will unlink any of the declared paths.
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class YourController extends Controller
{
private $paths = [];
public function someAction()
{
$this->paths[] = $path;
file_put_contents($path, implode(";\r\n", $result));
$message = (new \Swift_Message('VAT checking result !'))
->setFrom('[email protected]')
->setTo($vat->getEmail())
->setBody('Hello, ...' ,'text/')
->attach(\Swift_Attachment::fromPath($path));
$mailer = $this->container->get('mailer');
$mailer->send( $message );
return $this->redirectToRoute('some_route');
}
public function __destruct()
{
if ($this->paths) {
array_map('unlink', $this->paths);
}
}
}
NOTE: This approach may not work if you use a spool to send emails, as the email will not be sent until the thresholds have been met for the spool.
Symfony 2.3+ will automatically register the Swiftmailer plugin when you tag a service with swiftmailer.plugin
. So there is no need to call $mailer->registerPlugin($listener);
, where swiftmailer will simply ignore duplicate plugin registrations.