Skip to content

Commit b3b5699

Browse files
committed
override user bundle notifiers
1 parent 95492cc commit b3b5699

File tree

9 files changed

+293
-2
lines changed

9 files changed

+293
-2
lines changed

src/bundle/Resources/config/ezplatform_default_settings.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ parameters:
6868
ibexa.site_access.config.admin_group.user_registration.templates.confirmation: "@@ibexadesign/account/register/register_confirmation.html.twig"
6969
ibexa.site_access.config.admin_group.user_edit.templates.update: '@@ibexadesign/user/edit.html.twig'
7070
ibexa.site_access.config.admin_group.user_edit.templates.create: '@@ibexadesign/user/create.html.twig'
71+
ibexa.site_access.config.admin_group.user_invitation.templates.mail: "@@ibexadesign/user/invitation/mail.html.twig"
72+
7173

7274
# Content Tree Module
7375
ibexa.site_access.config.admin_group.content_tree_module.load_more_limit: 30

src/bundle/Resources/config/services.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ imports:
4141
- { resource: services/icons.yaml }
4242
- { resource: services/role_form_mappers.yaml }
4343
- { resource: services/security.yaml }
44+
- { resource: services/notifier.yaml }
4445

4546
services:
4647
_defaults:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
services:
2+
_defaults:
3+
autowire: true
4+
autoconfigure: true
5+
public: true
6+
7+
Ibexa\AdminUi\Notifier\PasswordReset:
8+
decorates: Ibexa\Contracts\User\PasswordReset\Notifier
9+
arguments:
10+
$projectDir: '%kernel.project_dir%'
11+
12+
Ibexa\AdminUi\Notifier\UserInvitation:
13+
decorates: Ibexa\Contracts\User\Invitation\InvitationSender
14+
arguments:
15+
$projectDir: '%kernel.project_dir%'
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
3+
<file source-language="en" target-language="en" datatype="plaintext" original="not.available">
4+
<header>
5+
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
6+
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
7+
</header>
8+
<body>
9+
<trans-unit id="e7b58c781e23a49ce354cdb479f14d6f75ca6e4f" resname="forgot_user_password.mail.message">
10+
<source>We have received a request to reset the password for your account. Click "reset password" below to choose a new password:</source>
11+
<target state="new">We have received a request to reset the password for your account. Click "reset password" below to choose a new password:</target>
12+
<note>key: forgot_user_password.mail.message</note>
13+
</trans-unit>
14+
<trans-unit id="26ccb574b6cd1e49d40d32d9183db89065138be2" resname="forgot_user_password.mail.message_footer">
15+
<source>If you did not request a password reset, please ignore this email, and your password will remain the same.</source>
16+
<target state="new">If you did not request a password reset, please ignore this email, and your password will remain the same.</target>
17+
<note>key: forgot_user_password.mail.message_footer</note>
18+
</trans-unit>
19+
<trans-unit id="a5ba92910b3dc61efc12c4f42cc869975be98723" resname="forgot_user_password.mail.message_title">
20+
<source>Hello,</source>
21+
<target state="new">Hello,</target>
22+
<note>key: forgot_user_password.mail.message_title</note>
23+
</trans-unit>
24+
<trans-unit id="b7293d1f766a95b50cf3e076c5ef4cd623dc542c" resname="forgot_user_password.mail.reset_password">
25+
<source>Reset password</source>
26+
<target state="new">Reset password</target>
27+
<note>key: forgot_user_password.mail.reset_password</note>
28+
</trans-unit>
29+
<trans-unit id="5fd68a8b7cdaa23771e0e970466b4432642df1d3" resname="forgot_user_password.mail.reset_your_password">
30+
<source>Reset your password</source>
31+
<target state="new">Reset your password</target>
32+
<note>key: forgot_user_password.mail.reset_your_password</note>
33+
</trans-unit>
34+
</body>
35+
</file>
36+
</xliff>

src/bundle/Resources/translations/ibexa_user_invitation.en.xliff

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,26 @@
66
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
77
</header>
88
<body>
9+
<trans-unit id="07c52e99431e40b768788c64536e4dc12ade0f03" resname="ibexa.user.invitation.mail.join">
10+
<source>Join</source>
11+
<target state="new">Join</target>
12+
<note>key: ibexa.user.invitation.mail.join</note>
13+
</trans-unit>
14+
<trans-unit id="bc254dd11e21f88f3d7b2a1a9c8ab30bb6825702" resname="ibexa.user.invitation.mail.message">
15+
<source>Join us at:</source>
16+
<target state="new">Join us at:</target>
17+
<note>key: ibexa.user.invitation.mail.message</note>
18+
</trans-unit>
19+
<trans-unit id="56996e20d695f581a1344e83a8c542c7df1a04ec" resname="ibexa.user.invitation.mail.message_title">
20+
<source>Hello,</source>
21+
<target state="new">Hello,</target>
22+
<note>key: ibexa.user.invitation.mail.message_title</note>
23+
</trans-unit>
24+
<trans-unit id="54fce872265c3912727c793b582ab71318d2294e" resname="ibexa.user.invitation.mail.subject">
25+
<source>You are invited to join</source>
26+
<target state="new">You are invited to join</target>
27+
<note>key: ibexa.user.invitation.mail.subject</note>
28+
</trans-unit>
929
<trans-unit id="f38b1e5444d2424d3f1a9f86b6dc7846e771fece" resname="ibexa.user.invitations.invitation_exist">
1030
<source>Invitation for %email% already exists</source>
1131
<target state="new">Invitation for %email% already exists</target>

src/bundle/Resources/views/themes/admin/account/forgot_password/mail.html.twig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{% extends '@ibexadesign/ui/mail/base_mail_template.html.twig' %}
22

3-
{% trans_default_domain 'ibexa_admin_ui' %}
3+
{% trans_default_domain 'ibexa_forgot_password' %}
44

55
{%- block subject -%}
66
{{ 'forgot_user_password.mail.reset_your_password'|trans|desc('Reset your password') }}
@@ -24,4 +24,3 @@
2424
{%- block mail_footer_content -%}
2525
{{ 'forgot_user_password.mail.message_footer'|trans()|desc('If you did not request a password reset, please ignore this email, and your password will remain the same.') }}
2626
{%- endblock mail_footer_content -%}
27-
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{% extends '@ibexadesign/ui/mail/base_mail_template.html.twig' %}
2+
3+
{% trans_default_domain 'ibexa_user_invitation' %}
4+
5+
{%- block subject -%}
6+
{{ 'ibexa.user.invitation.mail.subject'|trans|desc('You are invited to join') }}
7+
{%- endblock subject -%}
8+
9+
{%- block mail_message_title_content -%}
10+
{{ 'ibexa.user.invitation.mail.message_title'|trans()|desc('Hello,') }}
11+
{%- endblock mail_message_title_content -%}
12+
13+
{%- block mail_message_content -%}
14+
{{ 'ibexa.user.invitation.mail.message'|trans()|desc('Join us at:') }}
15+
{%- endblock mail_message_content -%}
16+
17+
{%- block mail_actions_conten -%}
18+
{% include '@ibexadesign/ui/mail/action_btn.html.twig' with {
19+
url: url('ibexa.user.from_invite.register', {
20+
'inviteHash': invite_hash,
21+
'siteaccess': siteaccess
22+
}),
23+
label: 'ibexa.user.invitation.mail.join'|trans()|desc('Join')
24+
} %}
25+
{%- endblock mail_actions_conten -%}
26+
27+
{%- block mail_footer -%}{%- endblock mail_footer -%}

src/lib/Notifier/PasswordReset.php

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\AdminUi\Notifier;
10+
11+
use Ibexa\Contracts\Core\Repository\Values\User\User;
12+
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
13+
use Ibexa\Contracts\Notifications\Service\NotificationServiceInterface;
14+
use Ibexa\Contracts\Notifications\Value\Notification\SymfonyNotificationAdapter;
15+
use Ibexa\Contracts\Notifications\Value\Recipent\SymfonyRecipientAdapter;
16+
use Ibexa\Contracts\Notifications\Value\Recipent\UserRecipient;
17+
use Ibexa\Contracts\User\Notification\UserPasswordReset;
18+
use Ibexa\Contracts\User\PasswordReset\Notifier;
19+
use Swift_Image;
20+
use Swift_Mailer;
21+
use Swift_Message;
22+
use Twig\Environment;
23+
24+
class PasswordReset implements Notifier
25+
{
26+
private ConfigResolverInterface $configResolver;
27+
28+
private Swift_Mailer $mailer;
29+
30+
private Environment $twig;
31+
32+
private NotificationServiceInterface $notificationService;
33+
34+
private string $projectDir;
35+
36+
public function __construct(
37+
ConfigResolverInterface $configResolver,
38+
Swift_Mailer $mailer,
39+
Environment $twig,
40+
NotificationServiceInterface $notificationService,
41+
string $projectDir
42+
) {
43+
$this->configResolver = $configResolver;
44+
$this->mailer = $mailer;
45+
$this->twig = $twig;
46+
$this->notificationService = $notificationService;
47+
$this->projectDir = $projectDir;
48+
}
49+
50+
public function sendMessage(User $user, string $hashKey): void
51+
{
52+
if ($this->isNotifierConfigured()) {
53+
$this->sendNotification($user, $hashKey);
54+
55+
return;
56+
}
57+
58+
// Swiftmailer delivery has to be kept to maintain backwards compatibility
59+
$template = $this->twig->load($this->configResolver->getParameter('user_forgot_password.templates.mail'));
60+
61+
$senderAddress = $this->configResolver->hasParameter('sender_address', 'swiftmailer.mailer')
62+
? $this->configResolver->getParameter('sender_address', 'swiftmailer.mailer')
63+
: '';
64+
65+
$subject = $template->renderBlock('subject');
66+
$from = $template->renderBlock('from') ?: $senderAddress;
67+
68+
$message = (new Swift_Message())
69+
->setSubject($subject)
70+
->setTo($user->email);
71+
72+
$embeddedHeader = $message->embed(Swift_Image::fromPath(
73+
$this->projectDir . '/public/bundles/ibexaadminui/img/mail/header.png'
74+
));
75+
76+
$body = $template->renderBlock('body', [
77+
'hash_key' => $hashKey,
78+
'header_img_path' => $embeddedHeader,
79+
]);
80+
81+
$message->setBody($body, 'text/html');
82+
83+
if (empty($from) === false) {
84+
$message->setFrom($from);
85+
}
86+
87+
$this->mailer->send($message);
88+
}
89+
90+
private function sendNotification(User $user, string $token): void
91+
{
92+
$this->notificationService->send(
93+
new SymfonyNotificationAdapter(
94+
new UserPasswordReset($user, $token),
95+
),
96+
[new SymfonyRecipientAdapter(new UserRecipient($user))],
97+
);
98+
}
99+
100+
private function isNotifierConfigured(): bool
101+
{
102+
$subscriptions = $this->configResolver->getParameter('notifications.subscriptions');
103+
104+
return array_key_exists(UserPasswordReset::class, $subscriptions)
105+
&& !empty($subscriptions[UserPasswordReset::class]['channels']);
106+
}
107+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\AdminUi\Notifier;
10+
11+
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
12+
use Ibexa\Contracts\User\Invitation\Invitation;
13+
use Ibexa\Contracts\User\Invitation\InvitationSender;
14+
use Swift_Image;
15+
use Swift_Mailer;
16+
use Swift_Message;
17+
use Twig\Environment;
18+
19+
final class UserInvitation implements InvitationSender
20+
{
21+
private Environment $twig;
22+
23+
private ConfigResolverInterface $configResolver;
24+
25+
private Swift_Mailer $mailer;
26+
27+
private string $projectDir;
28+
29+
public function __construct(
30+
Environment $twig,
31+
ConfigResolverInterface $configResolver,
32+
Swift_Mailer $mailer,
33+
string $projectDir
34+
) {
35+
$this->twig = $twig;
36+
$this->configResolver = $configResolver;
37+
$this->mailer = $mailer;
38+
$this->projectDir = $projectDir;
39+
}
40+
41+
public function sendInvitation(Invitation $invitation): void
42+
{
43+
$template = $this->twig->load(
44+
$this->configResolver->getParameter(
45+
'user_invitation.templates.mail',
46+
null,
47+
$invitation->getSiteAccessIdentifier()
48+
)
49+
);
50+
51+
$senderAddress = $this->configResolver->hasParameter('sender_address', 'swiftmailer.mailer')
52+
? $this->configResolver->getParameter('sender_address', 'swiftmailer.mailer')
53+
: '';
54+
55+
$subject = $template->renderBlock('subject');
56+
$from = $template->renderBlock('from') ?: $senderAddress;
57+
58+
$message = (new Swift_Message())
59+
->setSubject($subject)
60+
->setTo($invitation->getEmail());
61+
62+
$mailImagesDir = $this->projectDir . '/public/bundles/ibexaadminui/img/mail/';
63+
$embeddedHeader = $message->embed(Swift_Image::fromPath($mailImagesDir . 'header.jpg'));
64+
$embeddedBtnPrimaryLeftSide = $message->embed(Swift_Image::fromPath($mailImagesDir . 'btn_primary_left_side.jpg'));
65+
$embeddedBtnPrimaryRightSide = $message->embed(Swift_Image::fromPath($mailImagesDir . 'btn_primary_right_side.jpg'));
66+
67+
$body = $template->renderBlock('body', [
68+
'invite_hash' => $invitation->getHash(),
69+
'siteaccess' => $invitation->getSiteAccessIdentifier(),
70+
'invitation' => $invitation,
71+
'header_path' => $embeddedHeader,
72+
'btn_primary_left_side' => $embeddedBtnPrimaryLeftSide,
73+
'btn_primary_right_side' => $embeddedBtnPrimaryRightSide,
74+
]);
75+
76+
$message->setBody($body, 'text/html');
77+
78+
if (empty($from) === false) {
79+
$message->setFrom($from);
80+
}
81+
82+
$this->mailer->send($message);
83+
}
84+
}

0 commit comments

Comments
 (0)