|
| 1 | +<?php |
| 2 | + |
| 3 | +/* |
| 4 | + * This file is part of the Symfony package. |
| 5 | + * |
| 6 | + * (c) Fabien Potencier <[email protected]> |
| 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 <[email protected]> |
| 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