LoginLinkNotification.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Http\LoginLink;
  11. use Symfony\Bridge\Twig\Mime\NotificationEmail;
  12. use Symfony\Component\Notifier\Message\EmailMessage;
  13. use Symfony\Component\Notifier\Message\SmsMessage;
  14. use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
  15. use Symfony\Component\Notifier\Notification\Notification;
  16. use Symfony\Component\Notifier\Notification\SmsNotificationInterface;
  17. use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;
  18. use Symfony\Component\Notifier\Recipient\SmsRecipientInterface;
  19. /**
  20. * Use this notification to ease sending login link
  21. * emails/SMS using the Notifier component.
  22. *
  23. * @author Wouter de Jong <wouter@wouterj.nl>
  24. *
  25. * @experimental in 5.2
  26. */
  27. class LoginLinkNotification extends Notification implements EmailNotificationInterface, SmsNotificationInterface
  28. {
  29. private $loginLinkDetails;
  30. public function __construct(LoginLinkDetails $loginLinkDetails, string $subject, array $channels = [])
  31. {
  32. parent::__construct($subject, $channels);
  33. $this->loginLinkDetails = $loginLinkDetails;
  34. }
  35. public function asEmailMessage(EmailRecipientInterface $recipient, string $transport = null): ?EmailMessage
  36. {
  37. if (!class_exists(NotificationEmail::class)) {
  38. throw new \LogicException(sprintf('The "%s" method requires "symfony/twig-bridge:>4.4".', __METHOD__));
  39. }
  40. $email = NotificationEmail::asPublicEmail()
  41. ->to($recipient->getEmail())
  42. ->subject($this->getSubject())
  43. ->content($this->getContent() ?: $this->getDefaultContent('button below'))
  44. ->action('Sign in', $this->loginLinkDetails->getUrl())
  45. ;
  46. return new EmailMessage($email);
  47. }
  48. public function asSmsMessage(SmsRecipientInterface $recipient, string $transport = null): ?SmsMessage
  49. {
  50. return new SmsMessage($recipient->getPhone(), $this->getDefaultContent('link').' '.$this->loginLinkDetails->getUrl());
  51. }
  52. private function getDefaultContent(string $target): string
  53. {
  54. $duration = $this->loginLinkDetails->getExpiresAt()->getTimestamp() - time();
  55. $durationString = floor($duration / 60).' minute'.($duration > 60 ? 's' : '');
  56. if (($hours = $duration / 3600) >= 1) {
  57. $durationString = floor($hours).' hour'.($hours >= 2 ? 's' : '');
  58. }
  59. return sprintf('Click on the %s to confirm you want to sign in. This link will expire in %s.', $target, $durationString);
  60. }
  61. }