Im using swiftmailer for sending mails from my symfony2.2 project. Is there a way to log globally all email info and send results?
It would be great if mailer send() method have trigger somę event, but I can't see it does.
I did it this way:
# /src/Tiriana/MyBundle/Resources/config/services.yml
parameters:
swiftmailer.class: Tiriana\MyBundle\Util\MailerWrapper
It extends Swift_Mailer
, because it is passed to different classes expecting mailer to be instance of Swift_Mailer
.
And it creates Swift_Mailer
instance as a field, because... $transport
is private
in \Swith_Mailer
(link). Code would be so much better if $transport
was protected
...
// /src/Tiriana/MyBundle/Util/MailerWrapper.php
namespace Tiriana\MyBundle\Util;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
class MailerWrapper extends \Swift_Mailer
{
private $_logger;
/** @var \Swift_Mailer */
private $_mailer;
public function send(\Swift_Mime_Message $message, &$failedRecipients = null)
{
$this->_log('BEFORE SEND'); // <-- add your logic here
$ret = $this->_mailer->send($message, $failedRecipients);
$this->_log('AFTER SEND'); // <-- add your logic here
return $ret;
}
/** @return Logger */
public function getLogger()
{
return $this->_logger;
}
protected function _log($msg)
{
$this->getLogger()->debug(__CLASS__ . ": " . $msg);
}
public function __construct(\Swift_Transport $transport, Logger $logger)
{
/* we need _mailer because _transport is private
(not protected) in Swift_Mailer, unfortunately... */
$this->_mailer = parent::newInstance($transport);
$this->_logger = $logger;
}
public static function newInstance(\Swift_Transport $transport)
{
return new self($transport);
}
public function getTransport()
{
return $this->_mailer->getTransport();
}
public function registerPlugin(Swift_Events_EventListener $plugin)
{
$this->getTransport()->registerPlugin($plugin);
}
}
// /src/Tiriana/MyBundle/TirianaMyBundle.php
namespace Tiriana\MyBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Tiriana\MyBundle\DependencyInjection\Compiler\OverrideServiceSwiftMailer;
class TirianaMyBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new OverrideServiceSwiftMailer()); // <-- ADD THIS LINE
}
}
OverrideServiceSwiftMailer
class// /src/Tiriana/MyBundle/DependencyInjection/Compiler/OverrideServiceSwiftMailer.php
namespace Tiriana\MyBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class OverrideServiceSwiftMailer implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
/* @var $definition \Symfony\Component\DependencyInjection\DefinitionDecorator */
$definition = $container->findDefinition('mailer');
$definition->addArgument(new Reference('logger'));
/* add more dependencies if you need - i.e. event_dispatcher */
}
}