Completed
Push — develop ( e72854...0832ef )
by Daniel
06:46
created

Mailer   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 11
eloc 73
dl 0
loc 116
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A newUsernameConfirmation() 0 25 3
A pathToAppUrl() 0 10 2
A sendEmail() 0 15 1
A __construct() 0 20 2
A passwordResetEmail() 0 26 3
1
<?php
2
3
namespace Silverback\ApiComponentBundle\Mailer;
4
5
use Silverback\ApiComponentBundle\Entity\User\User;
6
use Silverback\ApiComponentBundle\Exception\InvalidParameterException;
7
use Symfony\Component\HttpFoundation\RequestStack;
8
use Twig\Environment;
9
10
final class Mailer
11
{
12
    private $mailer;
13
    private $twig;
14
    private $requestStack;
15
    private $fromEmailAddress;
16
    private $logoSrc;
17
    private $websiteName;
18
    private $requestTimeout;
19
20
    public function __construct(
21
        \Swift_Mailer $mailer,
22
        Environment $twig,
23
        RequestStack $requestStack,
24
        string $fromEmailAddress,
25
        ?string $logoSrc,
26
        ?string $websiteName,
27
        int $requestTimeout
28
    ) {
29
        $this->mailer = $mailer;
30
        $this->twig = $twig;
31
        $this->requestStack = $requestStack;
32
        $this->fromEmailAddress = $fromEmailAddress;
33
        $this->logoSrc = $logoSrc;
34
        $this->websiteName = $websiteName;
35
        $this->requestTimeout = gmdate('G', $requestTimeout);
36
        if ($this->requestTimeout > 1) {
37
            $this->requestTimeout .= ' hours';
38
        } else {
39
            $this->requestTimeout .= ' hour';
40
        }
41
    }
42
43
    public function sendEmail(string $toEmail, string $subject, string $htmlBody, string $textBody): int
44
    {
45
        $htmlTemplate = $this->twig->render('@SilverbackApiComponent/emails/template.html.twig', [
46
            'subject' => $subject,
47
            'body_html' => $htmlBody,
48
            'logo_src' => $this->logoSrc,
49
            'website_name' => $this->websiteName
50
        ]);
51
        $message = (new \Swift_Message($subject))
52
            ->setFrom($this->fromEmailAddress)
53
            ->setTo($toEmail)
54
            ->setBody($htmlTemplate, 'text/html')
55
            ->addPart($textBody, 'text/plain')
56
        ;
57
        return $this->mailer->send($message);
58
    }
59
60
    public function passwordResetEmail(User $user, string $resetUrl): int
61
    {
62
        $confirmationToken = $user->getPasswordResetConfirmationToken();
63
        if (!$confirmationToken) {
64
            throw new InvalidParameterException(sprintf('The entity %s should have a confirmation token set to send a password reset email.', User::class));
65
        }
66
        $username = $user->getUsername();
67
        if (!$username) {
68
            throw new InvalidParameterException(sprintf('The entity %s should have a username set to send a password reset email.', User::class));
69
        }
70
        $resetUrl = $this->pathToAppUrl(
71
            $resetUrl,
72
            $confirmationToken,
73
            $username
74
        );
75
        $subject = 'Password Reset Request';
76
        $htmlEmail = $this->twig->render(
77
            '@SilverbackApiComponent/emails/password_reset.html.twig',
78
            ['user' => $user, 'reset_url' => $resetUrl, 'website_name' => $this->websiteName, 'timeout' => $this->requestTimeout]
79
        );
80
        $textEmail = $this->twig->render(
81
            '@SilverbackApiComponent/emails/password_reset.txt.twig',
82
            ['user' => $user, 'reset_url' => $resetUrl, 'website_name' => $this->websiteName, 'timeout' => $this->requestTimeout]
83
        );
84
85
        return $this->sendEmail($user->getUsername(), $subject, $htmlEmail, $textEmail);
86
    }
87
88
    public function newUsernameConfirmation(User $user, string $confirmUrl): int
89
    {
90
        $confirmationToken = $user->getUsernameConfirmationToken();
91
        if (!$confirmationToken) {
92
            throw new InvalidParameterException(sprintf('The entity %s should have a confirmation token set to send a new user confirmation email.', User::class));
93
        }
94
        $username = $user->getNewUsername();
95
        if (!$username) {
96
            throw new InvalidParameterException(sprintf('The entity %s should have a new username set to send a new user confirmation email.', User::class));
97
        }
98
99
        $confirmUrl = $this->pathToAppUrl(
100
            $confirmUrl,
101
            $confirmationToken,
102
            $username
103
        );
104
        $htmlEmail = $this->twig->render(
105
            '@SilverbackApiComponent/emails/new_username_confirmation.html.twig',
106
            ['user' => $user, 'confirm_url' => $confirmUrl, 'website_name' => $this->websiteName]
107
        );
108
        $textEmail = $this->twig->render(
109
            '@SilverbackApiComponent/emails/new_username_confirmation.txt.twig',
110
            ['user' => $user, 'confirm_url' => $confirmUrl, 'website_name' => $this->websiteName]
111
        );
112
        return $this->sendEmail($username, 'Confirm change of username', $htmlEmail, $textEmail);
113
114
    }
115
116
    private function pathToAppUrl(string $path, string $token, string $email): string
117
    {
118
        $request = $this->requestStack->getCurrentRequest();
119
        $urlParts = $request ? parse_url($request->headers->get('referer')) : ['scheme' => 'https', 'host' => 'no-referrer'];
120
        $path = str_replace(['{{ token }}', '{{ email }}'], [$token, $email], $path);
121
        return sprintf(
122
            '%s://%s/%s',
123
            $urlParts['scheme'],
124
            $urlParts['host'],
125
            ltrim($path, '/')
126
        );
127
    }
128
}
129