From ca41ac6da78b8eec9407fd1f87825f45e242c274 Mon Sep 17 00:00:00 2001 From: "Andrey F. Mindubaev" Date: Wed, 30 May 2018 13:43:33 +0300 Subject: [PATCH 1/4] Make "mailer" service optional --- .../Compiler/CheckForMailerPass.php | 2 + FOSUserBundle.php | 2 - Mailer/Mailer.php | 7 + Mailer/TwigMailer.php | 129 ++++++++++++++++++ Mailer/TwigSwiftMailer.php | 97 +------------ Resources/config/mailer.xml | 6 +- ...SwiftMailerTest.php => TwigMailerTest.php} | 16 +-- 7 files changed, 156 insertions(+), 103 deletions(-) create mode 100644 Mailer/TwigMailer.php rename Tests/Mailer/{TwigSwiftMailerTest.php => TwigMailerTest.php} (90%) diff --git a/DependencyInjection/Compiler/CheckForMailerPass.php b/DependencyInjection/Compiler/CheckForMailerPass.php index fa2ee0414f..1381089e36 100644 --- a/DependencyInjection/Compiler/CheckForMailerPass.php +++ b/DependencyInjection/Compiler/CheckForMailerPass.php @@ -19,6 +19,8 @@ * Checks to see if the mailer service exists. * * @author Ryan Weaver + * + * @deprecated since 2.1, "mailer" service should be optional */ class CheckForMailerPass implements CompilerPassInterface { diff --git a/FOSUserBundle.php b/FOSUserBundle.php index e00208552f..4b3388e721 100644 --- a/FOSUserBundle.php +++ b/FOSUserBundle.php @@ -14,7 +14,6 @@ use Doctrine\Bundle\CouchDBBundle\DependencyInjection\Compiler\DoctrineCouchDBMappingsPass; use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass; use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass; -use FOS\UserBundle\DependencyInjection\Compiler\CheckForMailerPass; use FOS\UserBundle\DependencyInjection\Compiler\CheckForSessionPass; use FOS\UserBundle\DependencyInjection\Compiler\InjectRememberMeServicesPass; use FOS\UserBundle\DependencyInjection\Compiler\InjectUserCheckerPass; @@ -38,7 +37,6 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new InjectUserCheckerPass()); $container->addCompilerPass(new InjectRememberMeServicesPass()); $container->addCompilerPass(new CheckForSessionPass()); - $container->addCompilerPass(new CheckForMailerPass()); $this->addRegisterMappingsPass($container); } diff --git a/Mailer/Mailer.php b/Mailer/Mailer.php index 8f9e537a70..52db46b0b0 100644 --- a/Mailer/Mailer.php +++ b/Mailer/Mailer.php @@ -91,6 +91,13 @@ public function sendResettingEmailMessage(UserInterface $user) */ protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail) { + if (null === $this->mailer) { + throw new \RuntimeException( + 'Sending email requires the "mailer" service to be available. '. + 'Run "composer require symfony/swiftmailer-bundle" to install Swiftmailer.' + ); + } + // Render the email, use the first line as the subject, and the rest as the body $renderedLines = explode("\n", trim($renderedTemplate)); $subject = array_shift($renderedLines); diff --git a/Mailer/TwigMailer.php b/Mailer/TwigMailer.php new file mode 100644 index 0000000000..be02284a69 --- /dev/null +++ b/Mailer/TwigMailer.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\UserBundle\Mailer; + +use FOS\UserBundle\Model\UserInterface; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +/** + * @author Christophe Coevoet + */ +class TwigMailer implements MailerInterface +{ + /** + * @var \Swift_Mailer + */ + protected $mailer; + + /** + * @var UrlGeneratorInterface + */ + protected $router; + + /** + * @var \Twig_Environment + */ + protected $twig; + + /** + * @var array + */ + protected $parameters; + + /** + * TwigMailer constructor. + * + * @param \Swift_Mailer $mailer + * @param UrlGeneratorInterface $router + * @param \Twig_Environment $twig + * @param array $parameters + */ + public function __construct($mailer, UrlGeneratorInterface $router, \Twig_Environment $twig, array $parameters) + { + $this->mailer = $mailer; + $this->router = $router; + $this->twig = $twig; + $this->parameters = $parameters; + } + + /** + * {@inheritdoc} + */ + public function sendConfirmationEmailMessage(UserInterface $user) + { + $template = $this->parameters['template']['confirmation']; + $url = $this->router->generate('fos_user_registration_confirm', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL); + + $context = array( + 'user' => $user, + 'confirmationUrl' => $url, + ); + + $this->sendMessage($template, $context, $this->parameters['from_email']['confirmation'], (string) $user->getEmail()); + } + + /** + * {@inheritdoc} + */ + public function sendResettingEmailMessage(UserInterface $user) + { + $template = $this->parameters['template']['resetting']; + $url = $this->router->generate('fos_user_resetting_reset', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL); + + $context = array( + 'user' => $user, + 'confirmationUrl' => $url, + ); + + $this->sendMessage($template, $context, $this->parameters['from_email']['resetting'], (string) $user->getEmail()); + } + + /** + * @param string $templateName + * @param array $context + * @param array $fromEmail + * @param string $toEmail + */ + protected function sendMessage($templateName, $context, $fromEmail, $toEmail) + { + if (null === $this->mailer) { + throw new \RuntimeException( + 'Sending email requires the "mailer" service to be available. '. + 'Run "composer require symfony/swiftmailer-bundle" to install Swiftmailer.' + ); + } + + $template = $this->twig->load($templateName); + $subject = $template->renderBlock('subject', $context); + $textBody = $template->renderBlock('body_text', $context); + + $htmlBody = ''; + + if ($template->hasBlock('body_html', $context)) { + $htmlBody = $template->renderBlock('body_html', $context); + } + + $message = (new \Swift_Message()) + ->setSubject($subject) + ->setFrom($fromEmail) + ->setTo($toEmail); + + if (!empty($htmlBody)) { + $message->setBody($htmlBody, 'text/html') + ->addPart($textBody, 'text/plain'); + } else { + $message->setBody($textBody); + } + + $this->mailer->send($message); + } +} diff --git a/Mailer/TwigSwiftMailer.php b/Mailer/TwigSwiftMailer.php index cad3696828..4c412bef22 100644 --- a/Mailer/TwigSwiftMailer.php +++ b/Mailer/TwigSwiftMailer.php @@ -11,34 +11,15 @@ namespace FOS\UserBundle\Mailer; -use FOS\UserBundle\Model\UserInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; /** * @author Christophe Coevoet + * + * @deprecated TwigSwiftMailer class is deprecated since 2.1, use TwigMailer instead. */ -class TwigSwiftMailer implements MailerInterface +class TwigSwiftMailer extends TwigMailer { - /** - * @var \Swift_Mailer - */ - protected $mailer; - - /** - * @var UrlGeneratorInterface - */ - protected $router; - - /** - * @var \Twig_Environment - */ - protected $twig; - - /** - * @var array - */ - protected $parameters; - /** * TwigSwiftMailer constructor. * @@ -49,74 +30,10 @@ class TwigSwiftMailer implements MailerInterface */ public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $router, \Twig_Environment $twig, array $parameters) { - $this->mailer = $mailer; - $this->router = $router; - $this->twig = $twig; - $this->parameters = $parameters; - } - - /** - * {@inheritdoc} - */ - public function sendConfirmationEmailMessage(UserInterface $user) - { - $template = $this->parameters['template']['confirmation']; - $url = $this->router->generate('fos_user_registration_confirm', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL); - - $context = array( - 'user' => $user, - 'confirmationUrl' => $url, - ); - - $this->sendMessage($template, $context, $this->parameters['from_email']['confirmation'], (string) $user->getEmail()); - } - - /** - * {@inheritdoc} - */ - public function sendResettingEmailMessage(UserInterface $user) - { - $template = $this->parameters['template']['resetting']; - $url = $this->router->generate('fos_user_resetting_reset', array('token' => $user->getConfirmationToken()), UrlGeneratorInterface::ABSOLUTE_URL); - - $context = array( - 'user' => $user, - 'confirmationUrl' => $url, - ); - - $this->sendMessage($template, $context, $this->parameters['from_email']['resetting'], (string) $user->getEmail()); - } - - /** - * @param string $templateName - * @param array $context - * @param array $fromEmail - * @param string $toEmail - */ - protected function sendMessage($templateName, $context, $fromEmail, $toEmail) - { - $template = $this->twig->load($templateName); - $subject = $template->renderBlock('subject', $context); - $textBody = $template->renderBlock('body_text', $context); - - $htmlBody = ''; - - if ($template->hasBlock('body_html', $context)) { - $htmlBody = $template->renderBlock('body_html', $context); - } - - $message = (new \Swift_Message()) - ->setSubject($subject) - ->setFrom($fromEmail) - ->setTo($toEmail); - - if (!empty($htmlBody)) { - $message->setBody($htmlBody, 'text/html') - ->addPart($textBody, 'text/plain'); - } else { - $message->setBody($textBody); - } + @trigger_error(sprintf( + '%s is deprecated, use %s instead.', __CLASS__, TwigMailer::class + ), E_USER_DEPRECATED); - $this->mailer->send($message); + parent::__construct($mailer, $router, $twig, $parameters); } } diff --git a/Resources/config/mailer.xml b/Resources/config/mailer.xml index b3253ae119..4fc96a389c 100644 --- a/Resources/config/mailer.xml +++ b/Resources/config/mailer.xml @@ -17,7 +17,7 @@ - + @@ -31,8 +31,8 @@ - - + + diff --git a/Tests/Mailer/TwigSwiftMailerTest.php b/Tests/Mailer/TwigMailerTest.php similarity index 90% rename from Tests/Mailer/TwigSwiftMailerTest.php rename to Tests/Mailer/TwigMailerTest.php index f56e02292b..120d30ee6a 100644 --- a/Tests/Mailer/TwigSwiftMailerTest.php +++ b/Tests/Mailer/TwigMailerTest.php @@ -11,19 +11,19 @@ namespace FOS\UserBundle\Tests\Mailer; -use FOS\UserBundle\Mailer\TwigSwiftMailer; +use FOS\UserBundle\Mailer\TwigMailer; use PHPUnit\Framework\TestCase; use Swift_Mailer; use Swift_Transport_NullTransport; -class TwigSwiftMailerTest extends TestCase +class TwigMailerTest extends TestCase { /** * @dataProvider goodEmailProvider */ public function testSendConfirmationEmailMessageWithGoodEmails($emailAddress) { - $mailer = $this->getTwigSwiftMailer(); + $mailer = $this->getTwigMailer(); $mailer->sendConfirmationEmailMessage($this->getUser($emailAddress)); $this->assertTrue(true); @@ -35,7 +35,7 @@ public function testSendConfirmationEmailMessageWithGoodEmails($emailAddress) */ public function testSendConfirmationEmailMessageWithBadEmails($emailAddress) { - $mailer = $this->getTwigSwiftMailer(); + $mailer = $this->getTwigMailer(); $mailer->sendConfirmationEmailMessage($this->getUser($emailAddress)); } @@ -44,7 +44,7 @@ public function testSendConfirmationEmailMessageWithBadEmails($emailAddress) */ public function testSendResettingEmailMessageWithGoodEmails($emailAddress) { - $mailer = $this->getTwigSwiftMailer(); + $mailer = $this->getTwigMailer(); $mailer->sendResettingEmailMessage($this->getUser($emailAddress)); $this->assertTrue(true); @@ -56,7 +56,7 @@ public function testSendResettingEmailMessageWithGoodEmails($emailAddress) */ public function testSendResettingEmailMessageWithBadEmails($emailAddress) { - $mailer = $this->getTwigSwiftMailer(); + $mailer = $this->getTwigMailer(); $mailer->sendResettingEmailMessage($this->getUser($emailAddress)); } @@ -78,9 +78,9 @@ public function badEmailProvider() ); } - private function getTwigSwiftMailer() + private function getTwigMailer() { - return new TwigSwiftMailer( + return new TwigMailer( new Swift_Mailer( new Swift_Transport_NullTransport( $this->getMockBuilder('Swift_Events_EventDispatcher')->getMock() From 2d4a90acebdb623fa43f7e655bac40f939e156c8 Mon Sep 17 00:00:00 2001 From: Tristan Bessoussa Date: Tue, 4 Jun 2019 11:07:20 +0200 Subject: [PATCH 2/4] suggest one of 2 mailer Symfony has. --- composer.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/composer.json b/composer.json index 0a4bf2bd90..6a9dda470d 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,10 @@ "symfony/phpunit-bridge": "^2.8 || ^3.0 || ^4.0", "symfony/yaml": "^2.8 || ^3.0 || ^4.0" }, + "suggest": { + "symfony/swiftmailer-bundle": "*", + "symfony/mailer": "*" + }, "config": { "sort-packages": true }, From 2aee57acf1ce8faae6e4abb3f6650c2ee396af63 Mon Sep 17 00:00:00 2001 From: Tristan Bessoussa Date: Tue, 4 Jun 2019 13:48:30 +0200 Subject: [PATCH 3/4] allow to use symfony/mailer --- Mailer/Mailer.php | 39 ++++++++++++++++++++++++++++----------- composer.json | 1 + 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Mailer/Mailer.php b/Mailer/Mailer.php index 52db46b0b0..e1f2f68e8e 100644 --- a/Mailer/Mailer.php +++ b/Mailer/Mailer.php @@ -21,7 +21,7 @@ class Mailer implements MailerInterface { /** - * @var \Swift_Mailer + * @var \Swift_Mailer|Symfony\Component\Mailer\MailerInterface */ protected $mailer; @@ -43,10 +43,10 @@ class Mailer implements MailerInterface /** * Mailer constructor. * - * @param \Swift_Mailer $mailer - * @param UrlGeneratorInterface $router - * @param EngineInterface $templating - * @param array $parameters + * @param \Swift_Mailer|Symfony\Component\Mailer\MailerInterface $mailer + * @param UrlGeneratorInterface $router + * @param EngineInterface $templating + * @param array $parameters */ public function __construct($mailer, UrlGeneratorInterface $router, EngineInterface $templating, array $parameters) { @@ -94,7 +94,14 @@ protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail) if (null === $this->mailer) { throw new \RuntimeException( 'Sending email requires the "mailer" service to be available. '. - 'Run "composer require symfony/swiftmailer-bundle" to install Swiftmailer.' + 'Run "composer require symfony/mailer" or "composer require symfony/swiftmailer-bundle"' + ); + } + + if (!in_array(get_class($this->mailer), ['Symfony\Component\Mailer\MailerInterface', '\Swift_Message'], true)) { + throw new \RuntimeException( + 'Sending email requires either symfony/mailer or symfony/swiftmailer-bundle'. + 'Run "composer require symfony/mailer" or "composer require symfony/swiftmailer-bundle"' ); } @@ -103,11 +110,21 @@ protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail) $subject = array_shift($renderedLines); $body = implode("\n", $renderedLines); - $message = (new \Swift_Message()) - ->setSubject($subject) - ->setFrom($fromEmail) - ->setTo($toEmail) - ->setBody($body); + if (class_exists('Symfony\Component\Mailer\MailerInterface')) { + $message = (new Symfony\Component\Mime\Email()) + ->subject($subject) + ->from($fromEmail) + ->to($toEmail) + ->html($body); + } + + if (class_exists('\Swift_Message')) { + $message = (new \Swift_Message()) + ->setSubject($subject) + ->setFrom($fromEmail) + ->setTo($toEmail) + ->setBody($body); + } $this->mailer->send($message); } diff --git a/composer.json b/composer.json index 6a9dda470d..ddd697111c 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,7 @@ "friendsofphp/php-cs-fixer": "^2.2", "phpunit/phpunit": "^4.8.35 || ^5.7.11 || ^6.5", "swiftmailer/swiftmailer": "^4.3 || ^5.0 || ^6.0", + "symfony/mailer": "^4.3", "symfony/console": "^2.8 || ^3.0 || ^4.0", "symfony/phpunit-bridge": "^2.8 || ^3.0 || ^4.0", "symfony/yaml": "^2.8 || ^3.0 || ^4.0" From a0924d7739e3d619defa0150bb49e562ed8569ff Mon Sep 17 00:00:00 2001 From: Tristan Bessoussa Date: Tue, 4 Jun 2019 14:11:25 +0200 Subject: [PATCH 4/4] fix tests --- Mailer/Mailer.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Mailer/Mailer.php b/Mailer/Mailer.php index e1f2f68e8e..2e262a55a5 100644 --- a/Mailer/Mailer.php +++ b/Mailer/Mailer.php @@ -12,6 +12,7 @@ namespace FOS\UserBundle\Mailer; use FOS\UserBundle\Model\UserInterface; +use Swift_Mailer; use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -98,7 +99,7 @@ protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail) ); } - if (!in_array(get_class($this->mailer), ['Symfony\Component\Mailer\MailerInterface', '\Swift_Message'], true)) { + if (!in_array(get_class($this->mailer), ['Symfony\Component\Mailer\MailerInterface', 'Swift_Mailer'], true)) { throw new \RuntimeException( 'Sending email requires either symfony/mailer or symfony/swiftmailer-bundle'. 'Run "composer require symfony/mailer" or "composer require symfony/swiftmailer-bundle"' @@ -118,7 +119,7 @@ protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail) ->html($body); } - if (class_exists('\Swift_Message')) { + if (class_exists('Swift_Mailer')) { $message = (new \Swift_Message()) ->setSubject($subject) ->setFrom($fromEmail)