From 7b14ef3678ae6184e797119cebd9917a6ed1cc24 Mon Sep 17 00:00:00 2001 From: Thibaut Cheymol Date: Mon, 24 Aug 2020 09:07:52 +0200 Subject: [PATCH] [Mailer] Mailjet Add ability to pass custom headers to API --- .../Transport/MailjetApiTransportTest.php | 82 +++++++++++++++++++ .../Transport/MailjetTransportFactoryTest.php | 16 ++++ .../Mailjet/Transport/MailjetApiTransport.php | 17 ++++ .../Mailer/Bridge/Mailjet/composer.json | 3 +- 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetApiTransportTest.php diff --git a/src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetApiTransportTest.php new file mode 100644 index 0000000000..f59c75ce96 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetApiTransportTest.php @@ -0,0 +1,82 @@ +assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new MailjetApiTransport(self::USER, self::PASSWORD), + 'mailjet+api://api.mailjet.com', + ], + [ + (new MailjetApiTransport(self::USER, self::PASSWORD))->setHost('example.com'), + 'mailjet+api://example.com', + ], + ]; + } + + public function testPayloadFormat() + { + $email = (new Email()) + ->subject('Sending email to mailjet API'); + $email->getHeaders() + ->addTextHeader('X-authorized-header', 'authorized') + ->addTextHeader('X-MJ-TemplateLanguage', 'forbidden'); // This header is forbidden + $envelope = new Envelope(new Address('foo@example.com', 'Foo'), [new Address('bar@example.com', 'Bar'), new Address('baz@example.com', 'Baz')]); + + $transport = new MailjetApiTransport(self::USER, self::PASSWORD); + $method = new \ReflectionMethod(MailjetApiTransport::class, 'getPayload'); + $method->setAccessible(true); + $payload = $method->invoke($transport, $email, $envelope); + + $this->assertArrayHasKey('Messages', $payload); + $this->assertNotEmpty($payload['Messages']); + + $message = $payload['Messages'][0]; + $this->assertArrayHasKey('Subject', $message); + $this->assertEquals('Sending email to mailjet API', $message['Subject']); + + $this->assertArrayHasKey('Headers', $message); + $headers = $message['Headers']; + $this->assertArrayHasKey('X-authorized-header', $headers); + $this->assertEquals('authorized', $headers['X-authorized-header']); + $this->assertArrayNotHasKey('x-mj-templatelanguage', $headers); + $this->assertArrayNotHasKey('X-MJ-TemplateLanguage', $headers); + + $this->assertArrayHasKey('From', $message); + $sender = $message['From']; + $this->assertArrayHasKey('Email', $sender); + $this->assertArrayHasKey('Name', $sender); + $this->assertEquals('foo@example.com', $sender['Email']); + $this->assertEquals('Foo', $sender['Name']); + + $this->assertArrayHasKey('To', $message); + $recipients = $message['To']; + $this->assertIsArray($recipients); + $this->assertCount(2, $recipients); + $this->assertEquals('bar@example.com', $recipients[0]['Email']); + $this->assertEquals('', $recipients[0]['Name']); // For Recipients, even if the name is filled, it is empty + $this->assertEquals('baz@example.com', $recipients[1]['Email']); + $this->assertEquals('', $recipients[1]['Name']); + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetTransportFactoryTest.php index 767e3aae69..5ecd964949 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailjet/Tests/Transport/MailjetTransportFactoryTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Mailer\Bridge\Mailjet\Tests\Transport; +use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetApiTransport; use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetSmtpTransport; use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory; use Symfony\Component\Mailer\Test\TransportFactoryTestCase; @@ -26,6 +27,11 @@ class MailjetTransportFactoryTest extends TransportFactoryTestCase public function supportsProvider(): iterable { + yield [ + new Dsn('mailjet+api', 'default'), + true, + ]; + yield [ new Dsn('mailjet', 'default'), true, @@ -52,6 +58,16 @@ class MailjetTransportFactoryTest extends TransportFactoryTestCase $dispatcher = $this->getDispatcher(); $logger = $this->getLogger(); + yield [ + new Dsn('mailjet+api', 'default', self::USER, self::PASSWORD), + new MailjetApiTransport(self::USER, self::PASSWORD, $this->getClient(), $dispatcher, $logger), + ]; + + yield [ + new Dsn('mailjet+api', 'example.com', self::USER, self::PASSWORD), + (new MailjetApiTransport(self::USER, self::PASSWORD, $this->getClient(), $dispatcher, $logger))->setHost('example.com'), + ]; + yield [ new Dsn('mailjet', 'default', self::USER, self::PASSWORD), new MailjetSmtpTransport(self::USER, self::PASSWORD, $dispatcher, $logger), diff --git a/src/Symfony/Component/Mailer/Bridge/Mailjet/Transport/MailjetApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailjet/Transport/MailjetApiTransport.php index 8a0b7a1a37..e790132759 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailjet/Transport/MailjetApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailjet/Transport/MailjetApiTransport.php @@ -26,6 +26,15 @@ class MailjetApiTransport extends AbstractApiTransport { private const HOST = 'api.mailjet.com'; private const API_VERSION = '3.1'; + private const FORBIDDEN_HEADERS = [ + 'Date', 'X-CSA-Complaints', 'Message-Id', 'X-Mailjet-Campaign', 'X-MJ-StatisticsContactsListID', + 'DomainKey-Status', 'Received-SPF', 'Authentication-Results', 'Received', 'X-Mailjet-Prio', + 'From', 'Sender', 'Subject', 'To', 'Cc', 'Bcc', 'Return-Path', 'Delivered-To', 'DKIM-Signature', + 'X-Feedback-Id', 'X-Mailjet-Segmentation', 'List-Id', 'X-MJ-MID', 'X-MJ-ErrorMessage', + 'X-MJ-TemplateErrorDeliver', 'X-MJ-TemplateErrorReporting', 'X-MJ-TemplateLanguage', + 'X-Mailjet-Debug', 'User-Agent', 'X-Mailer', 'X-MJ-CustomID', 'X-MJ-EventPayload', 'X-MJ-Vars', + 'X-Mailjet-TrackOpen', 'X-Mailjet-TrackClick', 'X-MJ-TemplateID', 'X-MJ-WorkflowID', + ]; private $privateKey; private $publicKey; @@ -104,6 +113,14 @@ class MailjetApiTransport extends AbstractApiTransport $message['HTMLPart'] = $html; } + foreach ($email->getHeaders()->all() as $header) { + if (\in_array($header->getName(), self::FORBIDDEN_HEADERS, true)) { + continue; + } + + $message['Headers'][$header->getName()] = $header->getBodyAsString(); + } + return [ 'Messages' => [$message], ]; diff --git a/src/Symfony/Component/Mailer/Bridge/Mailjet/composer.json b/src/Symfony/Component/Mailer/Bridge/Mailjet/composer.json index 4ab5f6a8cb..170eb32cbc 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailjet/composer.json +++ b/src/Symfony/Component/Mailer/Bridge/Mailjet/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": "^7.2.5", - "symfony/mailer": "^4.4|^5.0" + "symfony/mailer": "^4.4|^5.0", + "symfony/mime": "^5.2" }, "require-dev": { "symfony/http-client": "^4.4|^5.0"