diff --git a/src/Mailer.php b/src/Mailer.php index a9e2b5b..2890fc7 100644 --- a/src/Mailer.php +++ b/src/Mailer.php @@ -8,6 +8,7 @@ use Symfony\Component\Mailer\Transport; use Symfony\Component\Mailer\Transport\TransportInterface; use Symfony\Component\Mime\RawMessage; +use yii1tech\mailer\transport\ArrayTransport; /** * @see https://symfony.com/doc/current/mailer.html @@ -84,7 +85,11 @@ public function getTransport(): TransportInterface throw new \LogicException('Either "' . get_class($this) . '::$dsn" or "' . get_class($this) . '::$transport" property should be set.'); } - $this->_transport = Transport::fromDsn($this->dsn); + if ($this->dsn === 'array' || stripos($this->dsn, 'array://') !== false) { + $this->_transport = new ArrayTransport(); + } else { + $this->_transport = Transport::fromDsn($this->dsn); + } return $this->_transport; } diff --git a/src/transport/ArrayTransport.php b/src/transport/ArrayTransport.php new file mode 100644 index 0000000..aca5233 --- /dev/null +++ b/src/transport/ArrayTransport.php @@ -0,0 +1,103 @@ + + * @since 1.0 + */ +class ArrayTransport extends AbstractTransport +{ + /** + * @var \Symfony\Component\Mime\RawMessage[]|\Symfony\Component\Mime\Email[]|\yii1tech\mailer\TemplatedEmail[] + */ + private $sentMessages = []; + + /** + * {@inheritDoc} + */ + protected function doSend(SentMessage $message): void + { + $this->sentMessages[] = $message->getOriginalMessage(); + } + + /** + * {@inheritDoc} + */ + public function __toString(): string + { + return 'array://'; + } + + /** + * @return \Symfony\Component\Mime\RawMessage[]|\Symfony\Component\Mime\Email[]|\yii1tech\mailer\TemplatedEmail[] sent messages. + */ + public function getSentMessages(): array + { + return $this->sentMessages; + } + + /** + * @return \Symfony\Component\Mime\RawMessage|\Symfony\Component\Mime\Email|\yii1tech\mailer\TemplatedEmail|null last sent message. + */ + public function getLastSentMessage(): ?RawMessage + { + if (empty($this->sentMessages)) { + return null; + } + + $sentMessages = $this->sentMessages; + + return array_pop($sentMessages); + } + + /** + * Clears the internal list of sent messages. + * + * @return static self reference. + */ + public function clearSentMessages(): self + { + $this->sentMessages = []; + + return $this; + } + + /** + * Filters the internal list of sent messages according to the given callback. + * + * Callback signature: + * + * ``` + * function (\Symfony\Component\Mailer\SentMessage $message): bool + * ``` + * + * The callback is applied over each sent message. + * In case the callback returns `true` the message will be returned in result set. + * + * @param callable $filterCallback filter callback. + * @return \Symfony\Component\Mime\RawMessage[]|\Symfony\Component\Mime\Email[]|\yii1tech\mailer\TemplatedEmail[] sent messages. + */ + public function filterSentMessages(callable $filterCallback): array + { + $result = []; + + foreach ($this->sentMessages as $message) { + if (call_user_func($filterCallback, $message)) { + $result[] = $message; + } + } + + return $result; + } +} \ No newline at end of file diff --git a/tests/MailerTest.php b/tests/MailerTest.php index 94be9bf..f7a3725 100644 --- a/tests/MailerTest.php +++ b/tests/MailerTest.php @@ -7,6 +7,7 @@ use Symfony\Component\Mailer\Transport\NullTransport; use Yii; use yii1tech\mailer\Mailer; +use yii1tech\mailer\transport\ArrayTransport; class MailerTest extends TestCase { @@ -45,6 +46,24 @@ public function testCreateTransportFromCallable(): void $this->assertTrue($mailer->getTransport() instanceof NullTransport); } + public function testCreateArrayTransport(): void + { + /** @var Mailer $mailer */ + $mailer = Yii::createComponent([ + 'class' => Mailer::class, + 'dsn' => 'array', + ]); + + $this->assertTrue($mailer->getTransport() instanceof ArrayTransport); + + $mailer = Yii::createComponent([ + 'class' => Mailer::class, + 'dsn' => 'array://', + ]); + + $this->assertTrue($mailer->getTransport() instanceof ArrayTransport); + } + public function testSetupSymfonyMailer(): void { $mailer = new Mailer(); diff --git a/tests/transport/ArrayTransportTest.php b/tests/transport/ArrayTransportTest.php new file mode 100644 index 0000000..1103565 --- /dev/null +++ b/tests/transport/ArrayTransportTest.php @@ -0,0 +1,46 @@ + Mailer::class, + 'transport' => $transport, + ]); + + $email = new Email(); + $email->from('noreply@example.com'); + $email->addTo('test@example.com'); + $email->subject('Test subject'); + $email->text('Test body'); + + $mailer->send($email); + + $this->assertCount(1, $transport->getSentMessages()); + + $sentMessage = $transport->getLastSentMessage(); + $this->assertSame('noreply@example.com', $sentMessage->getFrom()[0]->getAddress()); + + $messages = $transport->filterSentMessages(function (Email $message) { + return $message->getSubject() === 'Test subject'; + }); + $this->assertCount(1, $messages); + + $messages = $transport->filterSentMessages(function (Email $message) { + return $message->getSubject() === 'Fake'; + }); + $this->assertCount(0, $messages); + } +} \ No newline at end of file