diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e2b1cd..fe2933a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,15 @@ Yii Framework 2 Symfony mailer extension Change Log ================================================ +4.0.0 Jan 29, 2024 +------------------ +- Enh: Use DI container for creating factories (sammousa) + 4.0.0 ------ -- Enh #45: Include logger proxy as a dependency -- Enh #45: Drop support for end-of-life php versions 7.4 and 8.0 +- Enh #45: Include logger proxy as a dependency (sammousa) +- Enh #45: Drop support for end-of-life php versions 7.4 and 8.0 (sammousa) 3.1.0 under development ----------------------- @@ -15,7 +19,6 @@ Yii Framework 2 Symfony mailer extension Change Log - Enh #50: Forward transport logs to the Yii Logger (sammousa) - Enh #49: Removed dependency on SymfonyMailer class (sammousa) - 3.0.0 December 05, 2022 ----------------------- diff --git a/README.md b/README.md index 7f62ac6..2e8c94d 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,11 @@ Yii::$app->mailer->compose('contact/html') ->send(); ``` +DI Container +------------ +The `Mailer` component will automatically use the DI container when it is available. +This allows you to easily override the transport factory configurations or their dependencies. + Migrating from yiisoft/yii2-swiftmailer --------------------------------------- diff --git a/composer.json b/composer.json index d260da3..f4accc3 100644 --- a/composer.json +++ b/composer.json @@ -27,8 +27,8 @@ "require": { "php": ">=8.1", "psr/event-dispatcher": "1.0.0", - "symfony/mailer": "^6.4 || ^7.0", - "symfony/mime": "^6.4 || ^7.0", + "symfony/mailer": "^7.0", + "symfony/mime": "^7.0", "yiisoft/yii2": ">=2.0.4" }, "require-dev": { @@ -79,4 +79,4 @@ "psalm": "psalm", "test": "phpunit" } -} +} \ No newline at end of file diff --git a/src/Mailer.php b/src/Mailer.php index 04fbe52..044b15e 100644 --- a/src/Mailer.php +++ b/src/Mailer.php @@ -1,21 +1,37 @@ _transport; } + /** + * @psalm-suppress UndefinedClass + * @throws InvalidConfigException + * @throws \yii\di\NotInstantiableException + */ private function getTransportFactory(): Transport { if (isset($this->transportFactory)) { return $this->transportFactory; } - /** @var LoggerInterface|null $logger */ - $logger = class_exists(DynamicLogger::class) ? new DynamicLogger() : null; - $defaultFactories = Transport::getDefaultFactories(new EventDispatcherProxy($this), null, $logger); + // Use the Yii DI container, if available. + if (isset(\Yii::$container)) { + $factories = []; + foreach ([ + NullTransportFactory::class, + SendmailTransportFactory::class, + EsmtpTransportFactory::class, + NativeTransportFactory::class, + SesTransportFactory::class, + GmailTransportFactory::class, + InfobipTransportFactory::class, + MandrillTransportFactory::class, + MailgunTransportFactory::class, + MailjetTransportFactory::class, + OhMySmtpTransportFactory::class, + PostmarkTransportFactory::class, + SendgridTransportFactory::class, + SendinblueTransportFactory::class, + ] as $factoryClass) { + if (!class_exists($factoryClass)) { + continue; + } + $factories[] = \Yii::$container->get($factoryClass); + } + } else { + $factories = Transport::getDefaultFactories(); + } + /** @psalm-suppress InvalidArgument Symfony's type annotation is wrong */ - return new Transport($defaultFactories); + return new Transport($factories); } /** @@ -107,6 +153,10 @@ private function createTransport(array $config = []): TransportInterface return $transport; } + /** + * @param MessageWrapperInterface&MessageInterface $message + * @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface + */ protected function sendMessage($message): bool { if (!($message instanceof MessageWrapperInterface)) { diff --git a/tests/MailerTest.php b/tests/MailerTest.php index 5778f1f..c344881 100644 --- a/tests/MailerTest.php +++ b/tests/MailerTest.php @@ -4,11 +4,13 @@ namespace yiiunit\extensions\symfonymailer; +use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Mailer\Transport; use Symfony\Component\Mailer\Transport\TransportInterface; use Yii; use yii\base\InvalidArgumentException; use yii\base\InvalidConfigException; +use yii\di\Container; use yii\mail\MessageInterface; use yii\symfonymailer\Mailer; use yii\symfonymailer\Message; @@ -164,4 +166,26 @@ public function testSendMessageThrowsOnBadMessageType(): void $mailer->send($message); } + + public function testDiContainer(): void + { + \Yii::$container = new Container(); + + $dispatcherMock = $this->getMockBuilder(EventDispatcherInterface::class)->getMock(); + $dispatcherCreator = $this + ->getMockBuilder(\stdclass::class) + ->addMethods(['__invoke']) + ->getMock(); + + $dispatcherCreator + ->expects(self::atLeastOnce()) + ->method('__invoke')->willReturn($dispatcherMock); + \Yii::$container->set(EventDispatcherInterface::class, $dispatcherCreator); + + + $mailer = new Mailer(); + $mailer->setTransport([ + 'dsn' => 'null://null', + ]); + } }