From 711c6732584ff3071cdff612922511d1869482c5 Mon Sep 17 00:00:00 2001 From: fritzmg Date: Wed, 15 May 2024 16:31:56 +0100 Subject: [PATCH] add support for friendly admin emails --- contao/languages/en/nc_tokens.xlf | 8 +- src/EventListener/AdminEmailTokenListener.php | 27 +++--- src/Gateway/MailerGateway.php | 4 +- .../AdminEmailTokenSubscriberTest.php | 83 ++++++++++++------- 4 files changed, 80 insertions(+), 42 deletions(-) diff --git a/contao/languages/en/nc_tokens.xlf b/contao/languages/en/nc_tokens.xlf index 64f72958..1ec489c5 100644 --- a/contao/languages/en/nc_tokens.xlf +++ b/contao/languages/en/nc_tokens.xlf @@ -2,9 +2,13 @@ + + Friendly name for the e-mail address of the administrator of the current page (system config or website root settings). + Friendly name for the e-mail address of the administrator of the current page (system config or website root settings). + - E-mail address of administrator of the current page (website root settings). - E-mail address of administrator of the current page (website root settings). + E-mail address of the administrator of the current page (system config or website root settings). + E-mail address of the administrator of the current page (system config or website root settings). All the form fields. diff --git a/src/EventListener/AdminEmailTokenListener.php b/src/EventListener/AdminEmailTokenListener.php index d05b0351..73c630ad 100644 --- a/src/EventListener/AdminEmailTokenListener.php +++ b/src/EventListener/AdminEmailTokenListener.php @@ -7,6 +7,7 @@ use Contao\Config; use Contao\CoreBundle\Framework\ContaoFramework; use Contao\PageModel; +use Contao\StringUtil; use Symfony\Component\EventDispatcher\Attribute\AsEventListener; use Symfony\Component\HttpFoundation\RequestStack; use Terminal42\NotificationCenterBundle\Event\CreateParcelEvent; @@ -14,7 +15,7 @@ use Terminal42\NotificationCenterBundle\Parcel\Stamp\TokenCollectionStamp; use Terminal42\NotificationCenterBundle\Token\Definition\EmailTokenDefinition; use Terminal42\NotificationCenterBundle\Token\Definition\Factory\TokenDefinitionFactoryInterface; -use Terminal42\NotificationCenterBundle\Token\Definition\TokenDefinitionInterface; +use Terminal42\NotificationCenterBundle\Token\Token; class AdminEmailTokenListener { @@ -28,7 +29,10 @@ public function __construct( #[AsEventListener] public function onGetTokenDefinitions(GetTokenDefinitionsForNotificationTypeEvent $event): void { - $event->addTokenDefinition($this->getTokenDefinition()); + $event + ->addTokenDefinition($this->tokenDefinitionFactory->create(EmailTokenDefinition::class, 'admin_name', 'admin_name')) + ->addTokenDefinition($this->tokenDefinitionFactory->create(EmailTokenDefinition::class, 'admin_email', 'admin_email')) + ; } #[AsEventListener] @@ -48,12 +52,13 @@ public function onCreateParcel(CreateParcelEvent $event): void return; } - $event->getParcel()->getStamp(TokenCollectionStamp::class)->tokenCollection->add( - $this->getTokenDefinition()->createToken('admin_email', $email), - ); + $event->getParcel()->getStamp(TokenCollectionStamp::class)->tokenCollection + ->addToken(new Token('admin_name', $email[0], $email[0])) + ->addToken(new Token('admin_email', $email[1], $email[1])) + ; } - private function getEmailFromPage(): string|null + private function getEmailFromPage(): array|null { if (null === ($request = $this->requestStack->getCurrentRequest())) { return null; @@ -67,18 +72,18 @@ private function getEmailFromPage(): string|null $pageModel->loadDetails(); - return $pageModel->adminEmail ?: null; + return $pageModel->adminEmail ? $this->parseFriendlyEmail($pageModel->adminEmail) : null; } - private function getEmailFromConfig(): string|null + private function getEmailFromConfig(): array|null { $email = $this->contaoFramework->getAdapter(Config::class)->get('adminEmail'); - return !\is_string($email) ? null : $email; + return $email ? $this->parseFriendlyEmail($email) : null; } - private function getTokenDefinition(): TokenDefinitionInterface + private function parseFriendlyEmail(string $email): array { - return $this->tokenDefinitionFactory->create(EmailTokenDefinition::class, 'admin_email', 'admin_email'); + return $this->contaoFramework->getAdapter(StringUtil::class)->splitFriendlyEmail($email); } } diff --git a/src/Gateway/MailerGateway.php b/src/Gateway/MailerGateway.php index 5a812753..942c7216 100644 --- a/src/Gateway/MailerGateway.php +++ b/src/Gateway/MailerGateway.php @@ -104,7 +104,9 @@ private function createEmailStamp(Parcel $parcel): EmailStamp $stamp = $stamp->withFrom($from); } - if ('' !== ($fromName = $this->replaceTokensAndInsertTags($parcel, $languageConfig->getString('email_sender_name')))) { + $fromName = '' !== $languageConfig->getString('email_sender_name') ? $languageConfig->getString('email_sender_name') : '##admin_name##'; + + if ('' !== ($fromName = $this->replaceTokensAndInsertTags($parcel, $fromName))) { $stamp = $stamp->withFromName($fromName); } diff --git a/tests/EventListener/AdminEmailTokenSubscriberTest.php b/tests/EventListener/AdminEmailTokenSubscriberTest.php index 00a31d19..ba026b76 100644 --- a/tests/EventListener/AdminEmailTokenSubscriberTest.php +++ b/tests/EventListener/AdminEmailTokenSubscriberTest.php @@ -7,7 +7,9 @@ use Contao\Config; use Contao\CoreBundle\Framework\ContaoFramework; use Contao\PageModel; +use Contao\StringUtil; use Contao\TestCase\ContaoTestCase; +use PHPUnit\Framework\Attributes\DataProvider; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Terminal42\NotificationCenterBundle\Config\MessageConfig; @@ -20,10 +22,11 @@ class AdminEmailTokenSubscriberTest extends ContaoTestCase { - public function testAddsTokenFromPageModel(): void + #[DataProvider('adminEmailProvider')] + public function testAddsAdminTokens(string $configFriendlyEmail, string $pageFriendlyEmail, string $expectedName, string $expectedEmail): void { $pageModel = $this->mockClassWithProperties(PageModel::class, [ - 'adminEmail' => 'foobar@terminal42.ch', + 'adminEmail' => $pageFriendlyEmail, ]); $stack = $this->buildRequestStack($pageModel); @@ -36,34 +39,43 @@ public function testAddsTokenFromPageModel(): void $listener = new AdminEmailTokenListener( $stack, $tokenDefinitionFactory, - $this->mockFrameworkWithAdminEmail('foobar-config@terminal42.ch'), + $this->mockFrameworkWithAdminEmail($configFriendlyEmail), ); $listener->onCreateParcel($event); - $this->assertSame('foobar@terminal42.ch', $tokenCollection->getByName('admin_email')->getValue()); + $this->assertSame($expectedName, $tokenCollection->getByName('admin_name')->getValue()); + $this->assertSame($expectedEmail, $tokenCollection->getByName('admin_email')->getValue()); } - public function testAddsTokenFromConfig(): void + public static function adminEmailProvider(): \Generator { - $pageModel = $this->mockClassWithProperties(PageModel::class, [ - 'adminEmail' => '', - ]); - - $stack = $this->buildRequestStack($pageModel); - $tokenCollection = new TokenCollection(); - - $event = $this->buildCreateParcelEvent($tokenCollection); - - $tokenDefinitionFactory = new CoreTokenDefinitionFactory(); - - $listener = new AdminEmailTokenListener( - $stack, - $tokenDefinitionFactory, - $this->mockFrameworkWithAdminEmail('foobar-config@terminal42.ch'), - ); - $listener->onCreateParcel($event); - - $this->assertSame('foobar-config@terminal42.ch', $tokenCollection->getByName('admin_email')->getValue()); + yield 'Basic admin email in config' => [ + 'foobar-config@terminal42.ch', + '', + '', + 'foobar-config@terminal42.ch', + ]; + + yield 'Friendly admin email in config' => [ + 'Lorem Ipsum [foobar-config@terminal42.ch]', + '', + 'Lorem Ipsum', + 'foobar-config@terminal42.ch', + ]; + + yield 'Basic admin email in page' => [ + 'Lorem Ipsum [foobar-config@terminal42.ch]', + 'foobar@terminal42.ch', + '', + 'foobar@terminal42.ch', + ]; + + yield 'Friendly admin email in page' => [ + 'Lorem Ipsum [foobar-config@terminal42.ch]', + 'Dolor Sitamet [foobar@terminal42.ch]', + 'Dolor Sitamet', + 'foobar@terminal42.ch', + ]; } private function buildRequestStack(PageModel|null $pageModel = null): RequestStack @@ -86,20 +98,35 @@ private function buildCreateParcelEvent(TokenCollection $tokenCollection): Creat private function mockFrameworkWithAdminEmail(string|null $adminEmail = null): ContaoFramework { - $adapter = $this->mockAdapter(['isComplete', 'get']); - $adapter + $configAdapter = $this->mockAdapter(['isComplete', 'get']); + $configAdapter ->method('isComplete') ->willReturn(true) ; - $adapter + $configAdapter ->method('get') ->with('adminEmail') ->willReturn($adminEmail) ; + $stringUtilAdapter = $this->mockAdapter(['splitFriendlyEmail']); + $stringUtilAdapter + ->method('splitFriendlyEmail') + ->willReturnCallback( + static function (string $email): array { + return match ($email) { + 'Lorem Ipsum [foobar-config@terminal42.ch]' => ['Lorem Ipsum', 'foobar-config@terminal42.ch'], + 'Dolor Sitamet [foobar@terminal42.ch]' => ['Dolor Sitamet', 'foobar@terminal42.ch'], + default => ['', $email], + }; + } + ) + ; + return $this->mockContaoFramework([ - Config::class => $adapter, + Config::class => $configAdapter, + StringUtil::class => $stringUtilAdapter ]); } }