diff --git a/contao/languages/de/nc_tokens.xlf b/contao/languages/de/nc_tokens.xlf index fcf9f875..42a30bfb 100644 --- a/contao/languages/de/nc_tokens.xlf +++ b/contao/languages/de/nc_tokens.xlf @@ -3,8 +3,12 @@ - E-mail address of administrator of the current page (website root settings). - E-Mail-Adresse des Administrators der aktuellen Seite (Einstellungen der Rootseite). + E-mail address of the administrator of the current page (system config or website root settings). + E-Mail-Adresse des Administrators der aktuellen Seite (Systemeinstellungen oder Einstellungen der Rootseite). + + + Friendly name for the e-mail address of the administrator of the current page (system config or website root settings). + Anzeigename für die E-Mail-Adresse des Administrators der aktuellen Seite (Systemeinstellungen oder Einstellungen der Rootseite). All the form fields. diff --git a/contao/languages/en/nc_tokens.xlf b/contao/languages/en/nc_tokens.xlf index 64f72958..2fccbe5a 100644 --- a/contao/languages/en/nc_tokens.xlf +++ b/contao/languages/en/nc_tokens.xlf @@ -3,8 +3,12 @@ - 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). + + + 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). All the form fields. diff --git a/src/EventListener/AdminEmailTokenListener.php b/src/EventListener/AdminEmailTokenListener.php index d05b0351..b03671c9 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; @@ -28,7 +29,10 @@ public function __construct( #[AsEventListener] public function onGetTokenDefinitions(GetTokenDefinitionsForNotificationTypeEvent $event): void { - $event->addTokenDefinition($this->getTokenDefinition()); + $event + ->addTokenDefinition($this->getTokenDefinition('admin_email')) + ->addTokenDefinition($this->getTokenDefinition('admin_name')) + ; } #[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($this->getTokenDefinition('admin_email')->createToken('admin_email', $email[1])) + ->addToken($this->getTokenDefinition('admin_name')->createToken('admin_name', $email[0])) + ; } - private function getEmailFromPage(): string|null + private function getEmailFromPage(): array|null { if (null === ($request = $this->requestStack->getCurrentRequest())) { return null; @@ -67,18 +72,23 @@ 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 getTokenDefinition(string $token): TokenDefinitionInterface { - return $this->tokenDefinitionFactory->create(EmailTokenDefinition::class, 'admin_email', 'admin_email'); + return $this->tokenDefinitionFactory->create(EmailTokenDefinition::class, $token, $token); + } + + private function parseFriendlyEmail(string $email): array + { + 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..a7100c64 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,33 @@ 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 fn (string $email): array => 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, ]); } }