diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 01071a9ed6087..a80ab136ddae8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -2501,7 +2501,8 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ if (ContainerBuilder::willBeAvailable('symfony/fake-chat-notifier', FakeChatTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) { $container->getDefinition($classToServices[FakeChatTransportFactory::class]) - ->replaceArgument('$mailer', new Reference('mailer')); + ->replaceArgument('$mailer', new Reference('mailer')) + ->replaceArgument('$logger', new Reference('logger')); } if (ContainerBuilder::willBeAvailable('symfony/fake-sms-notifier', FakeSmsTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) { diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/CHANGELOG.md b/src/Symfony/Component/Notifier/Bridge/FakeChat/CHANGELOG.md index 1f2b652ac20ea..35a214aa4186f 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/CHANGELOG.md +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.4 +--- + +* Add the ``FakeChatLoggerTransport`` + 5.3 --- diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatLoggerTransport.php b/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatLoggerTransport.php new file mode 100644 index 0000000000000..e0448900d0565 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatLoggerTransport.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\FakeChat; + +use Psr\Log\LoggerInterface; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException; +use Symfony\Component\Notifier\Message\ChatMessage; +use Symfony\Component\Notifier\Message\MessageInterface; +use Symfony\Component\Notifier\Message\SentMessage; +use Symfony\Component\Notifier\Transport\AbstractTransport; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * @author Antoine Makdessi + */ +final class FakeChatLoggerTransport extends AbstractTransport +{ + protected const HOST = 'default'; + + private $logger; + + public function __construct(LoggerInterface $logger, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null) + { + $this->logger = $logger; + + parent::__construct($client, $dispatcher); + } + + public function __toString(): string + { + return sprintf('fakechat+logger://%s', $this->getEndpoint()); + } + + public function supports(MessageInterface $message): bool + { + return $message instanceof ChatMessage; + } + + /** + * @param MessageInterface|ChatMessage $message + */ + protected function doSend(MessageInterface $message): SentMessage + { + if (!$this->supports($message)) { + throw new UnsupportedMessageTypeException(__CLASS__, ChatMessage::class, $message); + } + + $subject = 'New Chat message without specified recipient!'; + if (null !== $message->getRecipientId()) { + $subject = sprintf('New Chat message for recipient: %s', $message->getRecipientId()); + } + + $this->logger->info(sprintf('%s: %s', $subject, $message->getSubject())); + + return new SentMessage($message, (string) $this); + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php b/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php index e8c2273afea67..9b55acb99a00f 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/FakeChatTransportFactory.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Notifier\Bridge\FakeChat; +use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Notifier\Exception\UnsupportedSchemeException; use Symfony\Component\Notifier\Transport\AbstractTransportFactory; @@ -19,38 +20,45 @@ /** * @author Oskar Stark + * @author Antoine Makdessi */ final class FakeChatTransportFactory extends AbstractTransportFactory { protected $mailer; + protected $logger; - public function __construct(MailerInterface $mailer) + public function __construct(MailerInterface $mailer, LoggerInterface $logger) { parent::__construct(); $this->mailer = $mailer; + $this->logger = $logger; } /** - * @return FakeChatEmailTransport + * @return FakeChatEmailTransport|FakeChatLoggerTransport */ public function create(Dsn $dsn): TransportInterface { $scheme = $dsn->getScheme(); - if ('fakechat+email' !== $scheme) { - throw new UnsupportedSchemeException($dsn, 'fakechat', $this->getSupportedSchemes()); + if ('fakechat+email' === $scheme) { + $mailerTransport = $dsn->getHost(); + $to = $dsn->getRequiredOption('to'); + $from = $dsn->getRequiredOption('from'); + + return (new FakeChatEmailTransport($this->mailer, $to, $from))->setHost($mailerTransport); } - $mailerTransport = $dsn->getHost(); - $to = $dsn->getRequiredOption('to'); - $from = $dsn->getRequiredOption('from'); + if ('fakechat+logger' === $scheme) { + return new FakeChatLoggerTransport($this->logger); + } - return (new FakeChatEmailTransport($this->mailer, $to, $from))->setHost($mailerTransport); + throw new UnsupportedSchemeException($dsn, 'fakechat', $this->getSupportedSchemes()); } protected function getSupportedSchemes(): array { - return ['fakechat+email']; + return ['fakechat+email', 'fakechat+logger']; } } diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/README.md b/src/Symfony/Component/Notifier/Bridge/FakeChat/README.md index c1dea2c796409..a79eaa5488b8b 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/README.md +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/README.md @@ -1,9 +1,9 @@ Fake Chat Notifier ================== -Provides Fake Chat (as email during development) integration for Symfony Notifier. +Provides Fake Chat (as email or log during development) integration for Symfony Notifier. -#### DSN example +#### DSN example for email ``` FAKE_CHAT_DSN=fakechat+email://default?to=TO&from=FROM @@ -18,6 +18,12 @@ To use a custom mailer transport: FAKE_CHAT_DSN=fakechat+email://mailchimp?to=TO&from=FROM ``` +#### DSN example for logger + +``` + FAKE_CHAT_DSN=fakechat+logger://default + ``` + Resources --------- diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatLoggerTransportTest.php b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatLoggerTransportTest.php new file mode 100644 index 0000000000000..ee93ec333421d --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatLoggerTransportTest.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\FakeChat\Tests; + +use Psr\Log\LoggerInterface; +use Symfony\Component\Notifier\Bridge\FakeChat\FakeChatLoggerTransport; +use Symfony\Component\Notifier\Message\ChatMessage; +use Symfony\Component\Notifier\Message\MessageInterface; +use Symfony\Component\Notifier\Message\SmsMessage; +use Symfony\Component\Notifier\Test\TransportTestCase; +use Symfony\Component\Notifier\Tests\Fixtures\TestOptions; +use Symfony\Component\Notifier\Transport\TransportInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +final class FakeChatLoggerTransportTest extends TransportTestCase +{ + public function createTransport(HttpClientInterface $client = null, LoggerInterface $logger = null): TransportInterface + { + return new FakeChatLoggerTransport($logger ?? $this->createMock(LoggerInterface::class), $client ?? $this->createMock(HttpClientInterface::class)); + } + + public function toStringProvider(): iterable + { + yield ['fakechat+logger://default', $this->createTransport()]; + } + + public function supportedMessagesProvider(): iterable + { + yield [new ChatMessage('Hello!')]; + } + + public function unsupportedMessagesProvider(): iterable + { + yield [new SmsMessage('0611223344', 'Hello!')]; + yield [$this->createMock(MessageInterface::class)]; + } + + public function testSendWithDefaultTransport() + { + $message1 = new ChatMessage($subject1 = 'Hello subject1!', new TestOptions(['recipient_id' => $recipient1 = 'Oskar'])); + $message2 = new ChatMessage($subject2 = 'Hello subject2!'); + + $logger = new TestLogger(); + + $transport = $this->createTransport(null, $logger); + + $transport->send($message1); + $transport->send($message2); + + $logs = $logger->logs; + $this->assertNotEmpty($logs); + + $log1 = $logs[0]; + $this->assertSame(sprintf('New Chat message for recipient: %s: %s', $recipient1, $subject1), $log1['message']); + $this->assertSame('info', $log1['level']); + + $log2 = $logs[1]; + $this->assertSame(sprintf('New Chat message without specified recipient!: %s', $subject2), $log2['message']); + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php index 2debe4dd482d7..a83d035cae707 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/FakeChatTransportFactoryTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Notifier\Bridge\FakeChat\Tests; +use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Notifier\Bridge\FakeChat\FakeChatTransportFactory; use Symfony\Component\Notifier\Test\TransportFactoryTestCase; @@ -23,7 +24,7 @@ final class FakeChatTransportFactoryTest extends TransportFactoryTestCase */ public function createFactory(): TransportFactoryInterface { - return new FakeChatTransportFactory($this->createMock(MailerInterface::class)); + return new FakeChatTransportFactory($this->createMock(MailerInterface::class), $this->createMock(LoggerInterface::class)); } public function createProvider(): iterable @@ -37,6 +38,11 @@ public function createProvider(): iterable 'fakechat+email://mailchimp?to=recipient@email.net&from=sender@email.net', 'fakechat+email://mailchimp?to=recipient@email.net&from=sender@email.net', ]; + + yield [ + 'fakechat+logger://default', + 'fakechat+logger://default', + ]; } public function missingRequiredOptionProvider(): iterable diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/TestLogger.php b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/TestLogger.php new file mode 100644 index 0000000000000..7f586d0ddd993 --- /dev/null +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/Tests/TestLogger.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Notifier\Bridge\FakeChat\Tests; + +use Psr\Log\AbstractLogger; + +final class TestLogger extends AbstractLogger +{ + public $logs = []; + + public function log($level, $message, array $context = []): void + { + $this->logs[] = [ + 'level' => $level, + 'message' => $message, + 'context' => $context, + ]; + } +} diff --git a/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json b/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json index a8689baf92f9b..9edda7183bde1 100644 --- a/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json +++ b/src/Symfony/Component/Notifier/Bridge/FakeChat/composer.json @@ -1,7 +1,7 @@ { "name": "symfony/fake-chat-notifier", "type": "symfony-bridge", - "description": "Fake Chat (as email during development) Notifier Bridge.", + "description": "Fake Chat (as email or log during development) Notifier Bridge.", "keywords": ["chat", "development", "email", "notifier", "symfony"], "homepage": "https://symfony.com", "license": "MIT", @@ -10,6 +10,11 @@ "name": "Oskar Stark", "homepage": "https://github.com/OskarStark" }, + { + "name": "Antoine Makdessi", + "email": "amakdessi@me.com", + "homepage": "http://antoine.makdessi.free.fr" + }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors"