Skip to content

Commit

Permalink
add support for friendly admin emails
Browse files Browse the repository at this point in the history
  • Loading branch information
fritzmg committed May 15, 2024
1 parent 395e44e commit 711c673
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 42 deletions.
8 changes: 6 additions & 2 deletions contao/languages/en/nc_tokens.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
<xliff version="1.2">
<file datatype="php" source-language="en" target-language="en">
<body>
<trans-unit id="nc_tokens.admin_name">
<source>Friendly name for the e-mail address of the administrator of the current page (system config or website root settings).</source>
<target>Friendly name for the e-mail address of the administrator of the current page (system config or website root settings).</source>
</trans-unit>
<trans-unit id="nc_tokens.admin_email">
<source>E-mail address of administrator of the current page (website root settings).</source>
<target>E-mail address of administrator of the current page (website root settings).</target>
<source>E-mail address of the administrator of the current page (system config or website root settings).</source>
<target>E-mail address of the administrator of the current page (system config or website root settings).</target>
</trans-unit>
<trans-unit id="nc_tokens.form.form_*">
<source>All the form fields.</source>
Expand Down
27 changes: 16 additions & 11 deletions src/EventListener/AdminEmailTokenListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
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;
use Terminal42\NotificationCenterBundle\Event\GetTokenDefinitionsForNotificationTypeEvent;
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
{
Expand All @@ -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]
Expand All @@ -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;
Expand All @@ -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);
}
}
4 changes: 3 additions & 1 deletion src/Gateway/MailerGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
83 changes: 55 additions & 28 deletions tests/EventListener/AdminEmailTokenSubscriberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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
]);
}
}

0 comments on commit 711c673

Please sign in to comment.