Replace SwiftMailer by Symfony Mailer

This commit is contained in:
Jeremy Benoist 2022-12-15 12:02:52 +01:00
parent 9c16dd7bd1
commit 32661f380c
No known key found for this signature in database
GPG key ID: 7168D5DD29F38552
13 changed files with 148 additions and 334 deletions

View file

@ -13,7 +13,6 @@ class AppKernel extends Kernel
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new FOS\RestBundle\FOSRestBundle(),

View file

@ -34,6 +34,8 @@ framework:
fragments: ~
http_method_override: true
assets: ~
mailer:
dsn: "%mailer_dsn%"
# Twig Configuration
twig:
@ -78,18 +80,6 @@ doctrine_migrations:
table_name: migration_versions
name: Application Migrations
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"
username: "%mailer_user%"
password: "%mailer_password%"
host: "%mailer_host%"
port: "%mailer_port%"
encryption: "%mailer_encryption%"
auth_mode: "%mailer_auth_mode%"
spool:
type: memory
fos_rest:
param_fetcher_listener: true
body_listener: true
@ -183,7 +173,7 @@ fos_user:
address: "%from_email%"
sender_name: wallabag
service:
mailer: fos_user.mailer.twig_swift
mailer: Wallabag\UserBundle\Mailer\UserMailer
fos_oauth_server:
db_driver: orm

View file

@ -8,6 +8,10 @@ framework:
profiler:
only_exceptions: false
mailer:
# see https://mailcatcher.me/
dsn: smtp://127.0.0.1:1025
web_profiler:
toolbar: true
intercept_redirects: false
@ -35,12 +39,6 @@ monolog:
VERBOSITY_DEBUG: DEBUG
channels: [doctrine]
swiftmailer:
# see https://mailcatcher.me/
transport: smtp
host: 'localhost'
port: 1025
# If you want to use cache for queries used in WallabagExtension
# Uncomment the following lines
#doctrine:

View file

@ -11,16 +11,13 @@ framework:
collect: false
translator:
enabled: false
mailer:
dsn: 'null://null'
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
# to be able to read emails sent
spool:
type: file
doctrine:
dbal:
driver: "%test_database_driver%"

View file

@ -26,13 +26,7 @@ parameters:
domain_name: https://your-wallabag-url-instance.com
server_name: "Your wallabag instance"
mailer_transport: smtp
mailer_user: ~
mailer_password: ~
mailer_host: 127.0.0.1
mailer_port: false
mailer_encryption: ~
mailer_auth_mode: ~
mailer_dsn: smtp://127.0.0.1
locale: en

View file

@ -200,6 +200,16 @@ services:
wallabag_core.entry.download_images.client:
alias: 'httplug.client.wallabag_core.entry.download_images'
Wallabag\UserBundle\Mailer\UserMailer:
arguments:
$parameters:
template:
confirmation: '%fos_user.registration.confirmation.template%'
resetting: '%fos_user.resetting.email.template%'
from_email:
confirmation: '%fos_user.registration.confirmation.from_email%'
resetting: '%fos_user.resetting.email.from_email%'
Wallabag\UserBundle\EventListener\CreateConfigListener:
arguments:
$itemsOnPage: "%wallabag_core.items_on_page%"

View file

@ -65,6 +65,7 @@
"doctrine/migrations": "^1.8",
"doctrine/orm": "^2.6",
"doctrine/persistence": "^1.3",
"egulias/email-validator": "^3.2",
"enshrined/svg-sanitize": "^0.15.4",
"friendsofsymfony/jsrouting-bundle": "^2.2",
"friendsofsymfony/oauth-server-bundle": "^1.5",
@ -112,10 +113,9 @@
"sensio/framework-extra-bundle": "^6.2",
"sentry/sentry-symfony": "3.5.3",
"stof/doctrine-extensions-bundle": "^1.2",
"swiftmailer/swiftmailer": "^6.3",
"symfony/dom-crawler": "^4.0",
"symfony/mailer": "^4.0",
"symfony/monolog-bundle": "^3.1",
"symfony/swiftmailer-bundle": "^3.2",
"symfony/symfony": "^4.0",
"tecnickcom/tcpdf": "^6.3.0",
"twig/extra-bundle": "^3.4",

254
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7cd556e18e7d5c08e61d78d21acddb09",
"content-hash": "1bdf0355a12843194f046a6ac0b87338",
"packages": [
{
"name": "babdev/pagerfanta-bundle",
@ -7788,16 +7788,16 @@
},
{
"name": "phpstan/phpdoc-parser",
"version": "1.15.0",
"version": "1.15.2",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpdoc-parser.git",
"reference": "6ff970a7101acfe99b3048e4bbfbc094e55c5b04"
"reference": "5941477f100993652218928039d530b75a13a9ca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6ff970a7101acfe99b3048e4bbfbc094e55c5b04",
"reference": "6ff970a7101acfe99b3048e4bbfbc094e55c5b04",
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/5941477f100993652218928039d530b75a13a9ca",
"reference": "5941477f100993652218928039d530b75a13a9ca",
"shasum": ""
},
"require": {
@ -7827,9 +7827,9 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.15.0"
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.15.2"
},
"time": "2022-12-07T16:12:39+00:00"
"time": "2022-12-16T06:42:48+00:00"
},
{
"name": "phpzip/phpzip",
@ -9552,82 +9552,6 @@
},
"time": "2022-09-30T11:52:24+00:00"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v6.3.0",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8a5d5072dca8f48460fce2f4131fcc495eec654c",
"reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c",
"shasum": ""
},
"require": {
"egulias/email-validator": "^2.0|^3.1",
"php": ">=7.0.0",
"symfony/polyfill-iconv": "^1.0",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
"symfony/phpunit-bridge": "^4.4|^5.4"
},
"suggest": {
"ext-intl": "Needed to support internationalized email addresses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.2-dev"
}
},
"autoload": {
"files": [
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Corbyn"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "https://swiftmailer.symfony.com",
"keywords": [
"email",
"mail",
"mailer"
],
"support": {
"issues": "https://github.com/swiftmailer/swiftmailer/issues",
"source": "https://github.com/swiftmailer/swiftmailer/tree/v6.3.0"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/swiftmailer/swiftmailer",
"type": "tidelift"
}
],
"abandoned": "symfony/mailer",
"time": "2021-10-18T15:26:12+00:00"
},
{
"name": "symfony/contracts",
"version": "v1.1.13",
@ -9952,89 +9876,6 @@
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-iconv",
"version": "v1.27.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-iconv.git",
"reference": "927013f3aac555983a5059aada98e1907d842695"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/927013f3aac555983a5059aada98e1907d842695",
"reference": "927013f3aac555983a5059aada98e1907d842695",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-iconv": "*"
},
"suggest": {
"ext-iconv": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.27-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Iconv\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Iconv extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"iconv",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-iconv/tree/v1.27.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-11-03T14:55:06+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.27.0",
@ -10942,87 +10783,6 @@
],
"time": "2022-10-05T15:16:54+00:00"
},
{
"name": "symfony/swiftmailer-bundle",
"version": "v3.5.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/swiftmailer-bundle.git",
"reference": "9daab339f226ac958192bf89836cb3378cc0e652"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/swiftmailer-bundle/zipball/9daab339f226ac958192bf89836cb3378cc0e652",
"reference": "9daab339f226ac958192bf89836cb3378cc0e652",
"shasum": ""
},
"require": {
"php": ">=7.1",
"swiftmailer/swiftmailer": "^6.1.3",
"symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/http-kernel": "^4.4|^5.0"
},
"conflict": {
"twig/twig": "<1.41|>=2.0,<2.10"
},
"require-dev": {
"symfony/console": "^4.4|^5.0",
"symfony/framework-bundle": "^4.4|^5.0",
"symfony/phpunit-bridge": "^4.4|^5.0",
"symfony/yaml": "^4.4|^5.0"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-main": "3.5-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Bundle\\SwiftmailerBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony SwiftmailerBundle",
"homepage": "http://symfony.com",
"support": {
"issues": "https://github.com/symfony/swiftmailer-bundle/issues",
"source": "https://github.com/symfony/swiftmailer-bundle/tree/v3.5.4"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"abandoned": "symfony/mailer",
"time": "2022-02-06T08:03:40+00:00"
},
{
"name": "symfony/symfony",
"version": "v4.4.49",

View file

@ -140,7 +140,6 @@
<tr><td>smalot/pdfparser</td><td>GPL-3.0</td></tr>
<tr><td>sonata-project/google-authenticator</td><td>MIT</td></tr>
<tr><td>stof/doctrine-extensions-bundle</td><td>MIT</td></tr>
<tr><td>swiftmailer/swiftmailer</td><td>MIT</td></tr>
<tr><td>symfony/assetic-bundle</td><td>MIT</td></tr>
<tr><td>symfony/monolog-bundle</td><td>MIT</td></tr>
<tr><td>All of Symfony</td><td>MIT-licenced</td></tr>

View file

@ -4,6 +4,9 @@ namespace Wallabag\UserBundle\Mailer;
use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;
use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Twig\Environment;
/**
@ -13,9 +16,9 @@ use Twig\Environment;
class AuthCodeMailer implements AuthCodeMailerInterface
{
/**
* SwiftMailer.
* Mailer.
*
* @var \Swift_Mailer
* @var MailerInterface
*/
private $mailer;
@ -55,14 +58,12 @@ class AuthCodeMailer implements AuthCodeMailerInterface
private $wallabagUrl;
/**
* Initialize the auth code mailer with the SwiftMailer object.
*
* @param string $senderEmail
* @param string $senderName
* @param string $supportUrl wallabag support url
* @param string $wallabagUrl wallabag instance url
*/
public function __construct(\Swift_Mailer $mailer, Environment $twig, $senderEmail, $senderName, $supportUrl, $wallabagUrl)
public function __construct(MailerInterface $mailer, Environment $twig, $senderEmail, $senderName, $supportUrl, $wallabagUrl)
{
$this->mailer = $mailer;
$this->twig = $twig;
@ -92,15 +93,13 @@ class AuthCodeMailer implements AuthCodeMailerInterface
'support_url' => $this->supportUrl,
]);
$message = new \Swift_Message();
$message
->setTo($user->getEmailAuthRecipient())
->setFrom($this->senderEmail, $this->senderName)
->setSubject($subject)
->setBody($bodyText, 'text/plain')
->addPart($bodyHtml, 'text/html')
;
$email = (new Email())
->from(new Address($this->senderEmail, $this->senderName ?? $this->senderEmail))
->to($user->getEmailAuthRecipient())
->subject($subject)
->text($bodyText)
->html($bodyHtml);
$this->mailer->send($message);
$this->mailer->send($email);
}
}

View file

@ -0,0 +1,78 @@
<?php
namespace Wallabag\UserBundle\Mailer;
use FOS\UserBundle\Mailer\TwigSwiftMailer;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Environment;
/**
* This replace the default mailer from TwigSwiftMailer by symfony/mailer instead of swiftmailer.
*/
class UserMailer extends TwigSwiftMailer
{
/**
* @var MailerInterface
*/
protected $mailer;
/**
* @var UrlGeneratorInterface
*/
protected $router;
/**
* @var Environment
*/
protected $twig;
/**
* @var array
*/
protected $parameters;
public function __construct(MailerInterface $mailer, UrlGeneratorInterface $router, Environment $twig, array $parameters)
{
$this->mailer = $mailer;
$this->router = $router;
$this->twig = $twig;
$this->parameters = $parameters;
}
/**
* @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);
}
$email = (new Email())
->from(new Address(key($fromEmail), current($fromEmail)))
->to($toEmail)
->subject($subject);
if (!empty($htmlBody)) {
$email
->text($textBody)
->html($htmlBody);
} else {
$email->text($textBody);
}
$this->mailer->send($email);
}
}

View file

@ -3,6 +3,8 @@
namespace Tests\Wallabag\UserBundle\Mailer;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Wallabag\UserBundle\Entity\User;
@ -10,19 +12,10 @@ use Wallabag\UserBundle\Mailer\AuthCodeMailer;
class AuthCodeMailerTest extends TestCase
{
protected $mailer;
protected $spool;
protected $twig;
protected function setUp(): void
{
$this->spool = new CountableMemorySpool();
$transport = new \Swift_Transport_SpoolTransport(
new \Swift_Events_SimpleEventDispatcher(),
$this->spool
);
$this->mailer = new \Swift_Mailer($transport);
$twigTemplate = <<<'TWIG'
{% block subject %}subject{% endblock %}
{% block body_html %}html body {{ code }}{% endblock %}
@ -34,6 +27,31 @@ TWIG;
public function testSendEmail()
{
$mailer = $this->createMock(MailerInterface::class);
$mailer->expects($this->once())
->method('send')
->with($this->callback(function ($email) {
$this->assertSame('subject', $email->getSubject());
$this->assertSame('text body http://0.0.0.0/support', $email->getTextBody());
$this->assertSame('html body 666666', $email->getHtmlBody());
$this->assertCount(1, $email->getTo());
/** @var Address[] $addresses */
$addresses = $email->getTo();
$this->assertInstanceOf(Address::class, $addresses[0]);
$this->assertSame('', $addresses[0]->getName());
$this->assertSame('test@wallabag.io', $addresses[0]->getAddress());
$this->assertCount(1, $email->getFrom());
/** @var Address[] $addresses */
$addresses = $email->getFrom();
$this->assertInstanceOf(Address::class, $addresses[0]);
$this->assertSame('wallabag test', $addresses[0]->getName());
$this->assertSame('nobody@test.io', $addresses[0]->getAddress());
return true;
}));
$user = new User();
$user->setEmailTwoFactor(true);
$user->setEmailAuthCode(666666);
@ -41,7 +59,7 @@ TWIG;
$user->setName('Bob');
$authCodeMailer = new AuthCodeMailer(
$this->mailer,
$mailer,
$this->twig,
'nobody@test.io',
'wallabag test',
@ -50,14 +68,5 @@ TWIG;
);
$authCodeMailer->sendAuthCode($user);
$this->assertCount(1, $this->spool);
$msg = $this->spool->getMessages()[0];
$this->assertArrayHasKey('test@wallabag.io', $msg->getTo());
$this->assertSame(['nobody@test.io' => 'wallabag test'], $msg->getFrom());
$this->assertSame('subject', $msg->getSubject());
$this->assertStringContainsString('text body http://0.0.0.0/support', $msg->toString());
$this->assertStringContainsString('html body 666666', $msg->toString());
}
}

View file

@ -1,19 +0,0 @@
<?php
namespace Tests\Wallabag\UserBundle\Mailer;
/**
* @see https://www.pmg.com/blog/integration-testing-swift-mailer/
*/
final class CountableMemorySpool extends \Swift_MemorySpool implements \Countable
{
public function count()
{
return \count($this->messages);
}
public function getMessages()
{
return $this->messages;
}
}