Skip to content

Commit

Permalink
Merge branch 'translatable-emails'
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusklocke committed Jan 21, 2025
2 parents 875f7a6 + d21030e commit e800d20
Show file tree
Hide file tree
Showing 33 changed files with 569 additions and 309 deletions.
1 change: 1 addition & 0 deletions config/doctrine/Domain/User.orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<field name="role" type="string" length="255" />
<field name="firstName" column="first_name" type="string" length="255" />
<field name="lastName" column="last_name" type="string" length="255" />
<field name="locale" column="locale" type="string" length="255" nullable="true" />
<many-to-many target-entity="HexagonalPlayground\Domain\Team" field="teams" index-by="id">
<join-table name="users_teams_link">
<join-columns>
Expand Down
6 changes: 3 additions & 3 deletions docker/php/fpm/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ ENV APP_VERSION=${APP_VERSION}
ENV PHP_VERSION=${PHP_VERSION}

# Install packages for PHP and extensions
RUN PHP_EXTENSIONS="apcu bcmath ctype curl dom fileinfo fpm gmp mbstring opcache pcntl pdo_mysql pdo_pgsql phar redis simplexml sockets tokenizer xml xmlreader xmlwriter" \
RUN PHP_EXTENSIONS="apcu bcmath ctype curl dom fileinfo fpm gmp intl mbstring opcache pcntl pdo_mysql pdo_pgsql phar redis simplexml sockets tokenizer xml xmlreader xmlwriter" \
&& PHP_PACKAGE="php${PHP_VERSION/./}" \
&& PHP_SUBPACKAGES="" \
&& for EXTENSION in ${PHP_EXTENSIONS}; do \
Expand All @@ -16,7 +16,7 @@ RUN PHP_EXTENSIONS="apcu bcmath ctype curl dom fileinfo fpm gmp mbstring opcache
&& set -ex \
&& apk update \
&& apk upgrade \
&& apk add --no-cache curl fcgi ${PHP_PACKAGE} ${PHP_SUBPACKAGES} \
&& apk add --no-cache curl fcgi icu-data-full ${PHP_PACKAGE} ${PHP_SUBPACKAGES} \
&& ln -s /etc/${PHP_PACKAGE} /etc/php \
&& test -e /usr/sbin/php-fpm || ln -s /usr/sbin/php-fpm${PHP_VERSION/./} /usr/sbin/php-fpm \
&& test -e /usr/bin/php || ln -s /usr/bin/${PHP_PACKAGE} /usr/bin/php \
Expand Down Expand Up @@ -49,9 +49,9 @@ COPY composer.lock composer.json ./
RUN composer install --optimize-autoloader --no-cache --no-dev --no-progress

# Install own application sources
COPY templates templates/
COPY src src/
COPY public public/
COPY locales locales/
COPY config config/
COPY bin bin/

Expand Down
6 changes: 3 additions & 3 deletions docker/php/roadrunner/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ENV APP_VERSION=${APP_VERSION}
ENV PHP_VERSION=${PHP_VERSION}

# Install packages for PHP and extensions
RUN PHP_EXTENSIONS="apcu bcmath ctype curl dom fileinfo gmp mbstring opcache pcntl pdo_mysql pdo_pgsql phar redis simplexml sockets tokenizer xml xmlreader xmlwriter" \
RUN PHP_EXTENSIONS="apcu bcmath ctype curl dom fileinfo gmp intl mbstring opcache pcntl pdo_mysql pdo_pgsql phar redis simplexml sockets tokenizer xml xmlreader xmlwriter" \
&& PHP_PACKAGE="php${PHP_VERSION/./}" \
&& PHP_SUBPACKAGES="" \
&& for EXTENSION in ${PHP_EXTENSIONS}; do \
Expand All @@ -19,7 +19,7 @@ RUN PHP_EXTENSIONS="apcu bcmath ctype curl dom fileinfo gmp mbstring opcache pcn
&& set -ex \
&& apk update \
&& apk upgrade \
&& apk add --no-cache curl ${PHP_PACKAGE} ${PHP_SUBPACKAGES} \
&& apk add --no-cache curl icu-data-full ${PHP_PACKAGE} ${PHP_SUBPACKAGES} \
&& ln -s /etc/${PHP_PACKAGE} /etc/php \
&& test -e /usr/bin/php || ln -s /usr/bin/${PHP_PACKAGE} /usr/bin/php \
&& adduser -u 82 -D -S -G www-data www-data \
Expand Down Expand Up @@ -53,8 +53,8 @@ COPY composer.lock composer.json ./
RUN composer install --optimize-autoloader --no-cache --no-dev --no-progress

# Install own application sources
COPY templates templates/
COPY src src/
COPY locales locales/
COPY config config/
COPY bin bin/

Expand Down
27 changes: 27 additions & 0 deletions locales/de.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"mail": {
"inviteUser": {
"title": "Deine Einladung",
"content": {
"text": "Hey %s, du wurdest von %s zum Liga-Manager eingeladen.",
"action": "Registrieren"
},
"hints": {
"validity": "Deine Einladung ist gültig bis: %s",
"disclosure": "Bitte leite deine Einladung nicht an eine andere Person weiter."
}
},
"resetPassword": {
"title": "Passwort zurücksetzen",
"content": {
"text": "Hey %s, nutze den folgenden Link um ein neues Passwort zu vergeben.",
"action": "Neues Passwort setzen"
},
"hints": {
"validity": "Der Link ist gültig bis: %s",
"disclosure": "Bitte leite diese E-Mail nicht an eine andere Person weiter.",
"flooding": "Wenn du diese E-Mail wiederholt bekommst ohne sie selbst angefordert zu haben, melde dich bitte beim Admin-Team."
}
}
}
}
27 changes: 27 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"mail": {
"inviteUser": {
"title": "Your invite",
"content": {
"text": "Hey %s, you have been invited from %s to join Liga-Manager.",
"action": "Register"
},
"hints": {
"validity": "Your invite is valid until: %s",
"disclosure": "Please do not forward your invite to another person."
}
},
"resetPassword": {
"title": "Password reset",
"content": {
"text": "Hey %s, use the following link for setting a new password.",
"action": "Set new password"
},
"hints": {
"validity": "The link is valid until: %s",
"disclosure": "Please do not forward this mail to another person.",
"flooding": "If you receive this mail repeatedly, but you did not request it, please contact the admin team."
}
}
}
}
16 changes: 15 additions & 1 deletion src/Application/Command/CreateUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class CreateUserCommand implements CommandInterface
/** @var string[] */
private array $teamIds;

/** @var string|null */
private ?string $locale;

/**
* @param string|null $id
* @param string $email
Expand All @@ -33,6 +36,7 @@ class CreateUserCommand implements CommandInterface
* @param string $lastName
* @param string $role
* @param string[] $teamIds
* @param string|null $locale
*/
public function __construct(
?string $id,
Expand All @@ -41,7 +45,8 @@ public function __construct(
string $firstName,
string $lastName,
string $role,
array $teamIds
array $teamIds,
?string $locale
) {
$this->setId($id);
$this->email = $email;
Expand All @@ -52,6 +57,7 @@ public function __construct(
$this->teamIds = array_map(function (string $teamId) {
return $teamId;
}, $teamIds);
$this->locale = $locale;
}

/**
Expand Down Expand Up @@ -101,4 +107,12 @@ public function getTeamIds(): array
{
return $this->teamIds;
}

/**
* @return string|null
*/
public function getLocale(): ?string
{
return $this->locale;
}
}
16 changes: 14 additions & 2 deletions src/Application/Command/UpdateUserCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,31 @@ class UpdateUserCommand implements CommandInterface
/** @var string[]|null */
private ?array $teamIds = null;

/** @var string|null */
private ?string $locale;

/**
* @param string $userId
* @param string|null $email
* @param string|null $firstName
* @param string|null $lastName
* @param string|null $role
* @param string[]|null $teamIds
* @param string|null $locale
*/
public function __construct(string $userId, ?string $email, ?string $firstName, ?string $lastName, ?string $role, ?array $teamIds)
public function __construct(string $userId, ?string $email, ?string $firstName, ?string $lastName, ?string $role, ?array $teamIds, ?string $locale)
{
$this->userId = $userId;
$this->email = $email;
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->role = $role;

if (null !== $teamIds) {
$this->teamIds = array_map(function (string $teamId) {
return $teamId;
}, $teamIds);
}
$this->locale = $locale;
}

/**
Expand Down Expand Up @@ -93,4 +97,12 @@ public function getTeamIds(): ?array
{
return $this->teamIds;
}

/**
* @return string|null
*/
public function getLocale(): ?string
{
return $this->locale;
}
}
26 changes: 0 additions & 26 deletions src/Application/Email/HtmlUtilsTrait.php

This file was deleted.

10 changes: 2 additions & 8 deletions src/Application/Email/MailerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,7 @@ interface MailerInterface
/**
* @param array $to
* @param string $subject
* @param string $html
* @return object
* @param MessageBody $body
*/
public function createMessage(array $to, string $subject, string $html): object;

/**
* @param object $message
*/
public function send(object $message);
public function send(array $to, string $subject, MessageBody $body);
}
21 changes: 21 additions & 0 deletions src/Application/Email/MessageBody.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php declare(strict_types=1);

namespace HexagonalPlayground\Application\Email;

class MessageBody
{
/**
* @param string $title Text to display as the title
* @param string $content Text to display as the main content
* @param array $actions Assotiative array with action label as key and URL as value
* @param array $hints Array of text items to serve as hints
*/
public function __construct(
public string $title,
public string $content,
public array $actions = [],
public array $hints = []
) {

}
}
13 changes: 11 additions & 2 deletions src/Application/Handler/CreateUserHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,17 @@ public function __invoke(CreateUserCommand $command, AuthContext $authContext):
$authContext->getUser()->assertIsAdmin();

$this->userRepository->assertEmailDoesNotExist($command->getEmail());
$user = new User($command->getId(), $command->getEmail(), $command->getPassword(), $command->getFirstName(), $command->getLastName());
$user->setRole($command->getRole());

$user = new User(
$command->getId(),
$command->getEmail(),
$command->getPassword(),
$command->getFirstName(),
$command->getLastName(),
$command->getRole(),
$command->getLocale()
);

foreach ($command->getTeamIds() as $teamId) {
/** @var Team $team */
$team = $this->teamRepository->find($teamId);
Expand Down
42 changes: 23 additions & 19 deletions src/Application/Handler/SendInviteMailHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,34 @@

use DateTimeImmutable;
use HexagonalPlayground\Application\Command\SendInviteMailCommand;
use HexagonalPlayground\Application\Email\HtmlUtilsTrait;
use HexagonalPlayground\Application\Email\MailerInterface;
use HexagonalPlayground\Application\Email\MessageBody;
use HexagonalPlayground\Application\Security\AccessLinkGeneratorInterface;
use HexagonalPlayground\Application\Security\AuthContext;
use HexagonalPlayground\Application\Security\UserRepositoryInterface;
use HexagonalPlayground\Application\TemplateRendererInterface;
use HexagonalPlayground\Application\Translator;
use HexagonalPlayground\Domain\Event\Event;
use HexagonalPlayground\Domain\User;

class SendInviteMailHandler implements AuthAwareHandler
{
use HtmlUtilsTrait;

private UserRepositoryInterface $userRepository;
private TemplateRendererInterface $templateRenderer;
private MailerInterface $mailer;
private AccessLinkGeneratorInterface $accessLinkGenerator;
private Translator $translator;

/**
* @param UserRepositoryInterface $userRepository
* @param TemplateRendererInterface $templateRenderer
* @param MailerInterface $mailer
* @param AccessLinkGeneratorInterface $accessLinkGenerator
* @param Translator $translator
*/
public function __construct(UserRepositoryInterface $userRepository, TemplateRendererInterface $templateRenderer, MailerInterface $mailer, AccessLinkGeneratorInterface $accessLinkGenerator)
public function __construct(UserRepositoryInterface $userRepository, MailerInterface $mailer, AccessLinkGeneratorInterface $accessLinkGenerator, Translator $translator)
{
$this->userRepository = $userRepository;
$this->templateRenderer = $templateRenderer;
$this->mailer = $mailer;
$this->accessLinkGenerator = $accessLinkGenerator;
$this->translator = $translator;
}

/**
Expand All @@ -50,19 +48,25 @@ public function __invoke(SendInviteMailCommand $command, AuthContext $authContex

$expiresAt = new DateTimeImmutable('now + 1 day');
$targetLink = $this->accessLinkGenerator->generateAccessLink($user, $expiresAt, $command->getTargetPath());
$locale = $user->getLocale() ?? 'de';

$recipient = [$user->getEmail() => $user->getFullName()];
$mailBody = $this->templateRenderer->render('InviteUser.html.php', [
'sender' => $authContext->getUser()->getFirstName(),
'receiver' => $user->getFirstName(),
'targetLink' => $targetLink,
'validUntil' => $expiresAt
]);

$subject = $this->extractTitle($mailBody);
$message = $this->mailer->createMessage($recipient, $subject, $mailBody);
$messageBody = new MessageBody(
$this->translator->get($locale, 'mail.inviteUser.title'),
$this->translator->get($locale, 'mail.inviteUser.content.text', [$user->getFirstName(), $authContext->getUser()->getFirstName()]),
[
$this->translator->get($locale, 'mail.inviteUser.content.action') => $targetLink
],
[
$this->translator->get($locale, 'mail.inviteUser.hints.validity', [$this->translator->getLocalizedDateTime($locale, $expiresAt)]),
$this->translator->get($locale, 'mail.inviteUser.hints.disclosure')
]
);

$this->mailer->send($message);
$this->mailer->send(
[$user->getEmail() => $user->getFullName()],
$messageBody->title,
$messageBody
);

return [];
}
Expand Down
Loading

0 comments on commit e800d20

Please sign in to comment.