[Mailer] added tag/metadata support
This commit is contained in:
parent
8b337fc94a
commit
f2cdafcae0
@ -14,6 +14,8 @@ namespace Symfony\Component\Mailer\Bridge\Mailchimp\Tests\Transport;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillApiTransport;
|
use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillApiTransport;
|
||||||
use Symfony\Component\Mailer\Envelope;
|
use Symfony\Component\Mailer\Envelope;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
use Symfony\Component\Mime\Address;
|
use Symfony\Component\Mime\Address;
|
||||||
use Symfony\Component\Mime\Email;
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
@ -61,4 +63,42 @@ class MandrillApiTransportTest extends TestCase
|
|||||||
$this->assertCount(1, $payload['message']['headers']);
|
$this->assertCount(1, $payload['message']['headers']);
|
||||||
$this->assertEquals('foo: bar', $payload['message']['headers'][0]);
|
$this->assertEquals('foo: bar', $payload['message']['headers'][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
$envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]);
|
||||||
|
|
||||||
|
$transport = new MandrillApiTransport('ACCESS_KEY');
|
||||||
|
$method = new \ReflectionMethod(MandrillApiTransport::class, 'getPayload');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$payload = $method->invoke($transport, $email, $envelope);
|
||||||
|
|
||||||
|
$this->assertArrayHasKey('message', $payload);
|
||||||
|
$this->assertArrayNotHasKey('headers', $payload['message']);
|
||||||
|
$this->assertArrayHasKey('tags', $payload['message']);
|
||||||
|
$this->assertSame(['password-reset'], $payload['message']['tags']);
|
||||||
|
$this->assertArrayHasKey('metadata', $payload['message']);
|
||||||
|
$this->assertSame(['Color' => 'blue', 'Client-ID' => '12345'], $payload['message']['metadata']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCanHaveMultipleTags()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset,user'));
|
||||||
|
$envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]);
|
||||||
|
|
||||||
|
$transport = new MandrillApiTransport('ACCESS_KEY');
|
||||||
|
$method = new \ReflectionMethod(MandrillApiTransport::class, 'getPayload');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$payload = $method->invoke($transport, $email, $envelope);
|
||||||
|
|
||||||
|
$this->assertArrayHasKey('message', $payload);
|
||||||
|
$this->assertArrayNotHasKey('headers', $payload['message']);
|
||||||
|
$this->assertArrayHasKey('tags', $payload['message']);
|
||||||
|
$this->assertSame(['password-reset', 'user'], $payload['message']['tags']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@ namespace Symfony\Component\Mailer\Bridge\Mailchimp\Tests\Transport;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillHttpTransport;
|
use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillHttpTransport;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
class MandrillHttpTransportTest extends TestCase
|
class MandrillHttpTransportTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -41,4 +44,23 @@ class MandrillHttpTransportTest extends TestCase
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->addTextHeader('foo', 'bar');
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset,user'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
|
||||||
|
$transport = new MandrillHttpTransport('key');
|
||||||
|
$method = new \ReflectionMethod(MandrillHttpTransport::class, 'addMandrillHeaders');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$method->invoke($transport, $email);
|
||||||
|
|
||||||
|
$this->assertCount(3, $email->getHeaders()->toArray());
|
||||||
|
$this->assertSame('foo: bar', $email->getHeaders()->get('FOO')->toString());
|
||||||
|
$this->assertSame('X-MC-Tags: password-reset,user', $email->getHeaders()->get('X-MC-Tags')->toString());
|
||||||
|
$this->assertSame('X-MC-Metadata: '.json_encode(['Color' => 'blue', 'Client-ID' => '12345']), $email->getHeaders()->get('X-MC-Metadata')->toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Mailer\Bridge\Mailchimp\Tests\Transport;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillSmtpTransport;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
|
class MandrillSmtpTransportTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->addTextHeader('foo', 'bar');
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset,user'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
|
||||||
|
$transport = new MandrillSmtpTransport('user', 'password');
|
||||||
|
$method = new \ReflectionMethod(MandrillSmtpTransport::class, 'addMandrillHeaders');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$method->invoke($transport, $email);
|
||||||
|
|
||||||
|
$this->assertCount(3, $email->getHeaders()->toArray());
|
||||||
|
$this->assertSame('foo: bar', $email->getHeaders()->get('FOO')->toString());
|
||||||
|
$this->assertSame('X-MC-Tags: password-reset,user', $email->getHeaders()->get('X-MC-Tags')->toString());
|
||||||
|
$this->assertSame('X-MC-Metadata: '.json_encode(['Color' => 'blue', 'Client-ID' => '12345']), $email->getHeaders()->get('X-MC-Metadata')->toString());
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Mailer\Bridge\Mailchimp\Transport;
|
|||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Mailer\Envelope;
|
use Symfony\Component\Mailer\Envelope;
|
||||||
use Symfony\Component\Mailer\Exception\HttpTransportException;
|
use Symfony\Component\Mailer\Exception\HttpTransportException;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
use Symfony\Component\Mailer\SentMessage;
|
use Symfony\Component\Mailer\SentMessage;
|
||||||
use Symfony\Component\Mailer\Transport\AbstractApiTransport;
|
use Symfony\Component\Mailer\Transport\AbstractApiTransport;
|
||||||
use Symfony\Component\Mime\Email;
|
use Symfony\Component\Mime\Email;
|
||||||
@ -111,6 +113,18 @@ class MandrillApiTransport extends AbstractApiTransport
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($header instanceof TagHeader) {
|
||||||
|
$payload['message']['tags'] = explode(',', $header->getValue());
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($header instanceof MetadataHeader) {
|
||||||
|
$payload['message']['metadata'][$header->getKey()] = $header->getValue();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$payload['message']['headers'][] = $name.': '.$header->getBodyAsString();
|
$payload['message']['headers'][] = $name.': '.$header->getBodyAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Mailer\Bridge\Mailchimp\Transport;
|
||||||
|
|
||||||
|
use Symfony\Component\Mailer\Envelope;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
|
use Symfony\Component\Mailer\SentMessage;
|
||||||
|
use Symfony\Component\Mime\Message;
|
||||||
|
use Symfony\Component\Mime\RawMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kevin Bond <kevinbond@gmail.com>
|
||||||
|
*/
|
||||||
|
trait MandrillHeadersTrait
|
||||||
|
{
|
||||||
|
public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage
|
||||||
|
{
|
||||||
|
if ($message instanceof Message) {
|
||||||
|
$this->addMandrillHeaders($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::send($message, $envelope);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addMandrillHeaders(Message $message): void
|
||||||
|
{
|
||||||
|
$headers = $message->getHeaders();
|
||||||
|
$metadata = [];
|
||||||
|
|
||||||
|
foreach ($headers->all() as $name => $header) {
|
||||||
|
if ($header instanceof TagHeader) {
|
||||||
|
$headers->addTextHeader('X-MC-Tags', $header->getValue());
|
||||||
|
$headers->remove($name);
|
||||||
|
} elseif ($header instanceof MetadataHeader) {
|
||||||
|
$metadata[$header->getKey()] = $header->getValue();
|
||||||
|
$headers->remove($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($metadata) {
|
||||||
|
$headers->addTextHeader('X-MC-Metadata', json_encode($metadata));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,8 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
|
|||||||
*/
|
*/
|
||||||
class MandrillHttpTransport extends AbstractHttpTransport
|
class MandrillHttpTransport extends AbstractHttpTransport
|
||||||
{
|
{
|
||||||
|
use MandrillHeadersTrait;
|
||||||
|
|
||||||
private const HOST = 'mandrillapp.com';
|
private const HOST = 'mandrillapp.com';
|
||||||
private $key;
|
private $key;
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
|||||||
*/
|
*/
|
||||||
class MandrillSmtpTransport extends EsmtpTransport
|
class MandrillSmtpTransport extends EsmtpTransport
|
||||||
{
|
{
|
||||||
|
use MandrillHeadersTrait;
|
||||||
|
|
||||||
public function __construct(string $username, string $password, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
|
public function __construct(string $username, string $password, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
|
||||||
{
|
{
|
||||||
parent::__construct('smtp.mandrillapp.com', 587, true, $dispatcher, $logger);
|
parent::__construct('smtp.mandrillapp.com', 587, true, $dispatcher, $logger);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.5",
|
"php": "^7.2.5",
|
||||||
"symfony/mailer": "^4.4|^5.0"
|
"symfony/mailer": "^5.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/http-client": "^4.4|^5.0"
|
"symfony/http-client": "^4.4|^5.0"
|
||||||
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Mailer\Bridge\Mailgun\Tests\Transport;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunApiTransport;
|
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunApiTransport;
|
||||||
use Symfony\Component\Mailer\Envelope;
|
use Symfony\Component\Mailer\Envelope;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
use Symfony\Component\Mime\Address;
|
use Symfony\Component\Mime\Address;
|
||||||
use Symfony\Component\Mime\Email;
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
@ -64,4 +66,29 @@ class MailgunApiTransportTest extends TestCase
|
|||||||
$this->assertArrayHasKey('h:x-mailgun-variables', $payload);
|
$this->assertArrayHasKey('h:x-mailgun-variables', $payload);
|
||||||
$this->assertEquals($json, $payload['h:x-mailgun-variables']);
|
$this->assertEquals($json, $payload['h:x-mailgun-variables']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$json = json_encode(['foo' => 'bar']);
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->addTextHeader('X-Mailgun-Variables', $json);
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
$envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]);
|
||||||
|
|
||||||
|
$transport = new MailgunApiTransport('ACCESS_KEY', 'DOMAIN');
|
||||||
|
$method = new \ReflectionMethod(MailgunApiTransport::class, 'getPayload');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$payload = $method->invoke($transport, $email, $envelope);
|
||||||
|
|
||||||
|
$this->assertArrayHasKey('h:x-mailgun-variables', $payload);
|
||||||
|
$this->assertEquals($json, $payload['h:x-mailgun-variables']);
|
||||||
|
$this->assertArrayHasKey('o:tag', $payload);
|
||||||
|
$this->assertSame('password-reset', $payload['o:tag']);
|
||||||
|
$this->assertArrayHasKey('v:Color', $payload);
|
||||||
|
$this->assertSame('blue', $payload['v:Color']);
|
||||||
|
$this->assertArrayHasKey('v:Client-ID', $payload);
|
||||||
|
$this->assertSame('12345', $payload['v:Client-ID']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@ namespace Symfony\Component\Mailer\Bridge\Mailgun\Tests\Transport;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunHttpTransport;
|
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunHttpTransport;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
class MailgunHttpTransportTest extends TestCase
|
class MailgunHttpTransportTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -45,4 +48,23 @@ class MailgunHttpTransportTest extends TestCase
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->addTextHeader('foo', 'bar');
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
|
||||||
|
$transport = new MailgunHttpTransport('key', 'domain');
|
||||||
|
$method = new \ReflectionMethod(MailgunHttpTransport::class, 'addMailgunHeaders');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$method->invoke($transport, $email);
|
||||||
|
|
||||||
|
$this->assertCount(3, $email->getHeaders()->toArray());
|
||||||
|
$this->assertSame('foo: bar', $email->getHeaders()->get('foo')->toString());
|
||||||
|
$this->assertSame('X-Mailgun-Tag: password-reset', $email->getHeaders()->get('X-Mailgun-Tag')->toString());
|
||||||
|
$this->assertSame('X-Mailgun-Variables: '.json_encode(['Color' => 'blue', 'Client-ID' => '12345']), $email->getHeaders()->get('X-Mailgun-Variables')->toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Mailer\Bridge\Mailgun\Tests\Transport;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunSmtpTransport;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kevin Bond <kevinbond@gmail.com>
|
||||||
|
*/
|
||||||
|
class MailgunSmtpTransportTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->addTextHeader('foo', 'bar');
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
|
||||||
|
$transport = new MailgunSmtpTransport('user', 'password');
|
||||||
|
$method = new \ReflectionMethod(MailgunSmtpTransport::class, 'addMailgunHeaders');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$method->invoke($transport, $email);
|
||||||
|
|
||||||
|
$this->assertCount(3, $email->getHeaders()->toArray());
|
||||||
|
$this->assertSame('foo: bar', $email->getHeaders()->get('foo')->toString());
|
||||||
|
$this->assertSame('X-Mailgun-Tag: password-reset', $email->getHeaders()->get('X-Mailgun-Tag')->toString());
|
||||||
|
$this->assertSame('X-Mailgun-Variables: '.json_encode(['Color' => 'blue', 'Client-ID' => '12345']), $email->getHeaders()->get('X-Mailgun-Variables')->toString());
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Mailer\Bridge\Mailgun\Transport;
|
|||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Mailer\Envelope;
|
use Symfony\Component\Mailer\Envelope;
|
||||||
use Symfony\Component\Mailer\Exception\HttpTransportException;
|
use Symfony\Component\Mailer\Exception\HttpTransportException;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
use Symfony\Component\Mailer\SentMessage;
|
use Symfony\Component\Mailer\SentMessage;
|
||||||
use Symfony\Component\Mailer\Transport\AbstractApiTransport;
|
use Symfony\Component\Mailer\Transport\AbstractApiTransport;
|
||||||
use Symfony\Component\Mime\Email;
|
use Symfony\Component\Mime\Email;
|
||||||
@ -114,6 +116,18 @@ class MailgunApiTransport extends AbstractApiTransport
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($header instanceof TagHeader) {
|
||||||
|
$payload['o:tag'] = $header->getValue();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($header instanceof MetadataHeader) {
|
||||||
|
$payload['v:'.$header->getKey()] = $header->getValue();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$payload['h:'.$name] = $header->getBodyAsString();
|
$payload['h:'.$name] = $header->getBodyAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Mailer\Bridge\Mailgun\Transport;
|
||||||
|
|
||||||
|
use Symfony\Component\Mailer\Envelope;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
|
use Symfony\Component\Mailer\SentMessage;
|
||||||
|
use Symfony\Component\Mime\Message;
|
||||||
|
use Symfony\Component\Mime\RawMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kevin Bond <kevinbond@gmail.com>
|
||||||
|
*/
|
||||||
|
trait MailgunHeadersTrait
|
||||||
|
{
|
||||||
|
public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage
|
||||||
|
{
|
||||||
|
if ($message instanceof Message) {
|
||||||
|
$this->addMailgunHeaders($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::send($message, $envelope);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addMailgunHeaders(Message $message): void
|
||||||
|
{
|
||||||
|
$headers = $message->getHeaders();
|
||||||
|
$metadata = [];
|
||||||
|
|
||||||
|
foreach ($headers->all() as $name => $header) {
|
||||||
|
if ($header instanceof TagHeader) {
|
||||||
|
$headers->addTextHeader('X-Mailgun-Tag', $header->getValue());
|
||||||
|
$headers->remove($name);
|
||||||
|
} elseif ($header instanceof MetadataHeader) {
|
||||||
|
$metadata[$header->getKey()] = $header->getValue();
|
||||||
|
$headers->remove($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($metadata) {
|
||||||
|
$headers->addTextHeader('X-Mailgun-Variables', json_encode($metadata));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,8 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
|
|||||||
*/
|
*/
|
||||||
class MailgunHttpTransport extends AbstractHttpTransport
|
class MailgunHttpTransport extends AbstractHttpTransport
|
||||||
{
|
{
|
||||||
|
use MailgunHeadersTrait;
|
||||||
|
|
||||||
private const HOST = 'api.%region_dot%mailgun.net';
|
private const HOST = 'api.%region_dot%mailgun.net';
|
||||||
|
|
||||||
private $key;
|
private $key;
|
||||||
|
@ -20,6 +20,8 @@ use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
|||||||
*/
|
*/
|
||||||
class MailgunSmtpTransport extends EsmtpTransport
|
class MailgunSmtpTransport extends EsmtpTransport
|
||||||
{
|
{
|
||||||
|
use MailgunHeadersTrait;
|
||||||
|
|
||||||
public function __construct(string $username, string $password, string $region = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
|
public function __construct(string $username, string $password, string $region = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
|
||||||
{
|
{
|
||||||
parent::__construct('us' !== ($region ?: 'us') ? sprintf('smtp.%s.mailgun.org', $region) : 'smtp.mailgun.org', 465, true, $dispatcher, $logger);
|
parent::__construct('us' !== ($region ?: 'us') ? sprintf('smtp.%s.mailgun.org', $region) : 'smtp.mailgun.org', 465, true, $dispatcher, $logger);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.5",
|
"php": "^7.2.5",
|
||||||
"symfony/mailer": "^4.4|^5.0"
|
"symfony/mailer": "^5.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/http-client": "^4.4|^5.0"
|
"symfony/http-client": "^4.4|^5.0"
|
||||||
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Mailer\Bridge\Postmark\Tests\Transport;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkApiTransport;
|
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkApiTransport;
|
||||||
use Symfony\Component\Mailer\Envelope;
|
use Symfony\Component\Mailer\Envelope;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
use Symfony\Component\Mime\Address;
|
use Symfony\Component\Mime\Address;
|
||||||
use Symfony\Component\Mime\Email;
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
@ -61,4 +63,25 @@ class PostmarkApiTransportTest extends TestCase
|
|||||||
|
|
||||||
$this->assertEquals(['Name' => 'foo', 'Value' => 'bar'], $payload['Headers'][0]);
|
$this->assertEquals(['Name' => 'foo', 'Value' => 'bar'], $payload['Headers'][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
$envelope = new Envelope(new Address('alice@system.com'), [new Address('bob@system.com')]);
|
||||||
|
|
||||||
|
$transport = new PostmarkApiTransport('ACCESS_KEY');
|
||||||
|
$method = new \ReflectionMethod(PostmarkApiTransport::class, 'getPayload');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$payload = $method->invoke($transport, $email, $envelope);
|
||||||
|
|
||||||
|
$this->assertArrayNotHasKey('Headers', $payload);
|
||||||
|
$this->assertArrayHasKey('Tag', $payload);
|
||||||
|
$this->assertArrayHasKey('Metadata', $payload);
|
||||||
|
|
||||||
|
$this->assertSame('password-reset', $payload['Tag']);
|
||||||
|
$this->assertSame(['Color' => 'blue', 'Client-ID' => '12345'], $payload['Metadata']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Mailer\Bridge\Postmark\Tests\Transport;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkSmtpTransport;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
|
||||||
|
class PostmarkSmtpTransportTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testCustomHeader()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->addTextHeader('foo', 'bar');
|
||||||
|
|
||||||
|
$transport = new PostmarkSmtpTransport('ACCESS_KEY');
|
||||||
|
$method = new \ReflectionMethod(PostmarkSmtpTransport::class, 'addPostmarkHeaders');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$method->invoke($transport, $email);
|
||||||
|
|
||||||
|
$this->assertCount(2, $email->getHeaders()->toArray());
|
||||||
|
$this->assertSame('X-PM-KeepID: true', $email->getHeaders()->get('X-PM-KeepID')->toString());
|
||||||
|
$this->assertSame('foo: bar', $email->getHeaders()->get('FOO')->toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTagAndMetadataHeaders()
|
||||||
|
{
|
||||||
|
$email = new Email();
|
||||||
|
$email->getHeaders()->addTextHeader('foo', 'bar');
|
||||||
|
$email->getHeaders()->add(new TagHeader('password-reset'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Color', 'blue'));
|
||||||
|
$email->getHeaders()->add(new MetadataHeader('Client-ID', '12345'));
|
||||||
|
|
||||||
|
$transport = new PostmarkSmtpTransport('ACCESS_KEY');
|
||||||
|
$method = new \ReflectionMethod(PostmarkSmtpTransport::class, 'addPostmarkHeaders');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
$method->invoke($transport, $email);
|
||||||
|
|
||||||
|
$this->assertCount(5, $email->getHeaders()->toArray());
|
||||||
|
$this->assertSame('foo: bar', $email->getHeaders()->get('FOO')->toString());
|
||||||
|
$this->assertSame('X-PM-KeepID: true', $email->getHeaders()->get('X-PM-KeepID')->toString());
|
||||||
|
$this->assertSame('X-PM-Tag: password-reset', $email->getHeaders()->get('X-PM-Tag')->toString());
|
||||||
|
$this->assertSame('X-PM-Metadata-Color: blue', $email->getHeaders()->get('X-PM-Metadata-Color')->toString());
|
||||||
|
$this->assertSame('X-PM-Metadata-Client-ID: 12345', $email->getHeaders()->get('X-PM-Metadata-Client-ID')->toString());
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Mailer\Bridge\Postmark\Transport;
|
|||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Mailer\Envelope;
|
use Symfony\Component\Mailer\Envelope;
|
||||||
use Symfony\Component\Mailer\Exception\HttpTransportException;
|
use Symfony\Component\Mailer\Exception\HttpTransportException;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
use Symfony\Component\Mailer\SentMessage;
|
use Symfony\Component\Mailer\SentMessage;
|
||||||
use Symfony\Component\Mailer\Transport\AbstractApiTransport;
|
use Symfony\Component\Mailer\Transport\AbstractApiTransport;
|
||||||
use Symfony\Component\Mime\Email;
|
use Symfony\Component\Mime\Email;
|
||||||
@ -82,6 +84,18 @@ class PostmarkApiTransport extends AbstractApiTransport
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($header instanceof TagHeader) {
|
||||||
|
$payload['Tag'] = $header->getValue();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($header instanceof MetadataHeader) {
|
||||||
|
$payload['Metadata'][$header->getKey()] = $header->getValue();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$payload['Headers'][] = [
|
$payload['Headers'][] = [
|
||||||
'Name' => $name,
|
'Name' => $name,
|
||||||
'Value' => $header->getBodyAsString(),
|
'Value' => $header->getBodyAsString(),
|
||||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Mailer\Bridge\Postmark\Transport;
|
|||||||
|
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\Mailer\Envelope;
|
use Symfony\Component\Mailer\Envelope;
|
||||||
|
use Symfony\Component\Mailer\Header\MetadataHeader;
|
||||||
|
use Symfony\Component\Mailer\Header\TagHeader;
|
||||||
use Symfony\Component\Mailer\SentMessage;
|
use Symfony\Component\Mailer\SentMessage;
|
||||||
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;
|
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;
|
||||||
use Symfony\Component\Mime\Message;
|
use Symfony\Component\Mime\Message;
|
||||||
@ -35,9 +37,28 @@ class PostmarkSmtpTransport extends EsmtpTransport
|
|||||||
public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage
|
public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage
|
||||||
{
|
{
|
||||||
if ($message instanceof Message) {
|
if ($message instanceof Message) {
|
||||||
$message->getHeaders()->addTextHeader('X-PM-KeepID', 'true');
|
$this->addPostmarkHeaders($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::send($message, $envelope);
|
return parent::send($message, $envelope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function addPostmarkHeaders(Message $message): void
|
||||||
|
{
|
||||||
|
$message->getHeaders()->addTextHeader('X-PM-KeepID', 'true');
|
||||||
|
|
||||||
|
$headers = $message->getHeaders();
|
||||||
|
|
||||||
|
foreach ($headers->all() as $name => $header) {
|
||||||
|
if ($header instanceof TagHeader) {
|
||||||
|
$headers->addTextHeader('X-PM-Tag', $header->getValue());
|
||||||
|
$headers->remove($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($header instanceof MetadataHeader) {
|
||||||
|
$headers->addTextHeader('X-PM-Metadata-'.$header->getKey(), $header->getValue());
|
||||||
|
$headers->remove($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2.5",
|
"php": "^7.2.5",
|
||||||
"symfony/mailer": "^4.4|^5.0"
|
"symfony/mailer": "^5.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/http-client": "^4.4|^5.0"
|
"symfony/http-client": "^4.4|^5.0"
|
||||||
|
34
src/Symfony/Component/Mailer/Header/MetadataHeader.php
Normal file
34
src/Symfony/Component/Mailer/Header/MetadataHeader.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Mailer\Header;
|
||||||
|
|
||||||
|
use Symfony\Component\Mime\Header\UnstructuredHeader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kevin Bond <kevinbond@gmail.com>
|
||||||
|
*/
|
||||||
|
final class MetadataHeader extends UnstructuredHeader
|
||||||
|
{
|
||||||
|
private $key;
|
||||||
|
|
||||||
|
public function __construct(string $key, string $value)
|
||||||
|
{
|
||||||
|
$this->key = $key;
|
||||||
|
|
||||||
|
parent::__construct('X-Metadata-'.$key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKey(): string
|
||||||
|
{
|
||||||
|
return $this->key;
|
||||||
|
}
|
||||||
|
}
|
25
src/Symfony/Component/Mailer/Header/TagHeader.php
Normal file
25
src/Symfony/Component/Mailer/Header/TagHeader.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Mailer\Header;
|
||||||
|
|
||||||
|
use Symfony\Component\Mime\Header\UnstructuredHeader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kevin Bond <kevinbond@gmail.com>
|
||||||
|
*/
|
||||||
|
final class TagHeader extends UnstructuredHeader
|
||||||
|
{
|
||||||
|
public function __construct(string $value)
|
||||||
|
{
|
||||||
|
parent::__construct('X-Tag', $value);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user