8000 Added LoginLinkNotification to integrate with Notifier · symfony/symfony@8bb7bac · GitHub
[go: up one dir, main page]

Skip to content

Commit 8bb7bac

Browse files
committed
Added LoginLinkNotification to integrate with Notifier
1 parent bfa520e commit 8bb7bac

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed

src/Symfony/Bridge/Twig/Mime/NotificationEmail.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class NotificationEmail extends TemplatedEmail
3737
'action_url' => null,
3838
'markdown' => false,
3939
'raw' => false,
40-
'show_footer' => true,
40+
'footer_text' => 'Notification e-mail sent by Symfony',
4141
];
4242

4343
public function __construct(Headers $headers = null, AbstractPart $body = null)
@@ -59,14 +59,13 @@ public function __construct(Headers $headers = null, AbstractPart $body = null)
5959
}
6060

6161
/**
62-
* Creates a NotificationEmail instance that can be used to sent
63-
* normal emails to users.
62+
* Creates a NotificationEmail instance that is appropriate to send to normal (non-admin) users.
6463
*/
6564
public static function asPublicEmail(Headers $headers = null, AbstractPart $body = null): self
6665
{
6766
$email = new static($headers, $body);
6867
$email->context['importance'] = null;
69-
$email->context['show_footer'] = false;
68+
$email->context['footer_text'] = null;
7069

7170
return $email;
7271
}

src/Symfony/Bridge/Twig/Resources/views/Email/zurb_2/notification/body.html.twig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<row>
1717
<columns large="12" small="12">
1818
{% block lead %}
19-
{% if importance %}<small><strong>{{ importance|upper }}</strong></small>{% endif %}
19+
{% if importance is not null %}<small><strong>{{ importance|upper }}</strong></small>{% endif %}
2020
<p class="lead">
2121
{{ email.subject }}
2222
</p>
@@ -49,11 +49,11 @@
4949
<wrapper class="secondary">
5050
<spacer size="16"></spacer>
5151
{% block footer %}
52-
{% if show_footer is not defined or show_footer %}
52+
{% if footer_text is defined and footer_text is not null %}
5353
<row>
5454
<columns small="12" large="6">
5555
{% block footer_content %}
56-
<p><small>Notification e-mail sent by Symfony</small></p>
56+
<p><small>{{ footer_text }}</small></p>
5757
{% endblock %}
5858
</columns>
5959
</row>

src/Symfony/Bridge/Twig/Tests/Mime/NotificationEmailTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public function test()
2626
'markdown' => true,
2727
'raw' => false,
2828
'a' => 'b',
29+
'footer_text' => 'Notification e-mail sent by Symfony',
2930
], $email->getContext());
3031
}
3132

@@ -47,6 +48,7 @@ public function testSerialize()
4748
'markdown' => false,
4849
'raw' => true,
4950
'a' => 'b',
51+
'footer_text' => 'Notification e-mail sent by Symfony',
5052
], $email->getContext());
5153
}
5254

@@ -63,4 +65,32 @@ public function testSubject()
6365
$headers = $email->getPreparedHeaders();
6466
$this->assertSame('[LOW] Foo', $headers->get('Subject')->getValue());
6567
}
68+
69+
public function testPublicMail()
70+
{
71+
$email = NotificationEmail::asPublicEmail()
72+
->markdown('Foo')
73+
->action('Bar', 'http://example.com/')
74+
->context(['a' => 'b'])
75+
;
76+
77+
$this->assertEquals([
78+
'importance' => null,
79+
'content' => 'Foo',
80+
'exception' => false,
81+
'action_text' => 'Bar',
82+
'action_url' => 'http://example.com/',
83+
'markdown' => true,
84+
'raw' => false,
85+
'a' => 'b',
86+
'footer_text' => null,
87+
], $email->getContext());
88+
}
89+
90+
public function testPublicMailSubject()
91+
{
92+
$email = NotificationEmail::asPublicEmail()->from('me@example.com')->subject('Foo');
93+
$headers = $email->getPreparedHeaders();
94+
$this->assertSame('Foo', $headers->get('Subject')->getValue());
95+
}
6696
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Http\LoginLink;
13+
14+
use Symfony\Bridge\Twig\Mime\NotificationEmail;
15+
use Symfony\Component\Notifier\Message\EmailMessage;
16+
use Symfony\Component\Notifier\Message\SmsMessage;
17+
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
18+
use Symfony\Component\Notifier\Notification\Notification;
19+
use Symfony\Component\Notifier\Notification\SmsNotificationInterface;
20+
use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;
21+
use Symfony\Component\Notifier\Recipient\SmsRecipientInterface;
22+
23+
/**
24+
* Use this notification to ease sending login link
25+
* emails/SMS using the Notifier component.
26+
*
27+
* @author Wouter de Jong <wouter@wouterj.nl>
28+
*
29+
* @experimental in 5.2
30+
*/
31+
class LoginLinkNotification extends Notification implements EmailNotificationInterface, SmsNotificationInterface
32+
{
33+
private $loginLinkDetails;
34+
35+
public function __construct(LoginLinkDetails $loginLinkDetails, string $subject, array $channels = [])
36+
{
37+
parent::__construct($subject, $channels);
38+
39+
$this->loginLinkDetails = $loginLinkDetails;
40+
}
41+
42+
public function asEmailMessage(EmailRecipientInterface $recipient, string $transport = null): ?EmailMessage
43+
{
44+
if (!class_exists(NotificationEmail::class)) {
45+
throw new \LogicException(sprintf('The "%s" method requires "symfony/twig-bridge:>4.4".', __METHOD__));
46+
}
47+
48+
$email = NotificationEmail::asPublicEmail()
49+
->to($recipient->getEmail())
50+
->subject($this->getSubject())
51+
->content($this->getContent() ?: $this->getDefaultContent('button below'))
52+
->action('Sign in', $this->loginLinkDetails->getUrl())
53+
;
54+
55+
return new EmailMessage($email);
56+
}
57+
58+
public function asSmsMessage(SmsRecipientInterface $recipient, string $transport = null): ?SmsMessage
59+
{
60+
return new SmsMessage($recipient->getPhone(), $this->getDefaultContent('link').' '.$this->loginLinkDetails->getUrl());
61+
}
62+
63+
private function getDefaultContent(string $target): string
64+
{
65+
$duration = $this->loginLinkDetails->getExpiresAt()->getTimestamp() - time();
66+
$durationString = floor($duration / 60).' minute'.($duration > 60 ? 's' : '');
67+
if (($hours = $duration / 3600) >= 1) {
68+
$durationString = floor($hours).' hour'.($hours >= 2 ? 's' : '');
69+
}
70+
71+
return sprintf('Click on the %s to confirm you want to sign in. This link will expire in %s.', $target, $durationString);
72+
}
73+
}

0 commit comments

Comments
 (0)
0