Passed
Push — v2 ( 227daa...82a867 )
by Daniel
05:48
created

UserMailer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 20
ccs 0
cts 10
cp 0
rs 9.9666
cc 1
nc 1
nop 9
crap 2

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/*
4
 * This file is part of the Silverback API Component Bundle Project
5
 *
6
 * (c) Daniel West <[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
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentBundle\Mailer;
15
16
use Silverback\ApiComponentBundle\Entity\User\AbstractUser;
17
use Silverback\ApiComponentBundle\Exception\InvalidParameterException;
18
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
19
use Symfony\Component\HttpFoundation\RequestStack;
20
use Symfony\Component\Mailer\MailerInterface;
21
use Symfony\Component\Mime\Address;
22
23
/**
24
 * @author Daniel West <[email protected]>
25
 */
26
class UserMailer
27
{
28
    private MailerInterface $mailer;
29
    private RequestStack $requestStack;
30
    private string $websiteName;
31
    private string $defaultPasswordResetPath;
32
    private string $defaultChangeEmailVerifyPath;
33
    private bool $sendUserWelcomeEmailEnabled;
34
    private bool $sendUserEnabledEmailEnabled;
35
    private bool $sendUserUsernameChangedEmailEnabled;
36
    private bool $sendUserPasswordChangedEmailEnabled;
37
38
    public function __construct(
39
        MailerInterface $mailer,
40
        RequestStack $requestStack,
41
        string $websiteName,
42
        string $defaultPasswordResetPath,
43
        string $defaultChangeEmailVerifyPath,
44
        bool $sendUserWelcomeEmailEnabled = true,
45
        bool $sendUserEnabledEmailEnabled = true,
46
        bool $sendUserUsernameChangedEmailEnabled = true,
47
        bool $sendUserPasswordChangedEmailEnabled = true)
48
    {
49
        $this->mailer = $mailer;
50
        $this->requestStack = $requestStack;
51
        $this->defaultPasswordResetPath = $defaultPasswordResetPath;
52
        $this->defaultChangeEmailVerifyPath = $defaultChangeEmailVerifyPath;
53
        $this->websiteName = $websiteName;
54
        $this->sendUserWelcomeEmailEnabled = $sendUserWelcomeEmailEnabled;
55
        $this->sendUserEnabledEmailEnabled = $sendUserEnabledEmailEnabled;
56
        $this->sendUserUsernameChangedEmailEnabled = $sendUserUsernameChangedEmailEnabled;
57
        $this->sendUserPasswordChangedEmailEnabled = $sendUserPasswordChangedEmailEnabled;
58
    }
59
60
    public function sendPasswordResetEmail(AbstractUser $user): void
61
    {
62
        $userEmail = $this->getUserEmail($user);
63
        $resetUrl = $this->pathToReferrerUrl(
64
            $user->getNewPasswordConfirmationToken(),
0 ignored issues
show
Bug introduced by
It seems like $user->getNewPasswordConfirmationToken() can also be of type null; however, parameter $token of Silverback\ApiComponentB...er::pathToReferrerUrl() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
            /** @scrutinizer ignore-type */ $user->getNewPasswordConfirmationToken(),
Loading history...
65
            $user->getUsername(),
0 ignored issues
show
Bug introduced by
It seems like $user->getUsername() can also be of type null; however, parameter $email of Silverback\ApiComponentB...er::pathToReferrerUrl() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

65
            /** @scrutinizer ignore-type */ $user->getUsername(),
Loading history...
66
            'resetPath',
67
            $this->defaultPasswordResetPath
68
        );
69
        $email = (new TemplatedEmail())
70
            ->to(Address::fromString($userEmail))
71
            ->subject('Your password reset request')
72
            ->htmlTemplate('@SilverbackApiComponent/emails/user_forgot_password.html.twig')
73
            ->context([
74
                'user' => $user,
75
                'reset_url' => $resetUrl,
76
                'website_name' => $this->websiteName,
77
            ]);
78
        $this->mailer->send($email);
79
    }
80
81
    public function sendChangeEmailConfirmationEmail(AbstractUser $user): void
82
    {
83
        $userEmail = $this->getUserEmail($user);
84
        $verifyUrl = $this->pathToReferrerUrl(
85
            $user->getNewEmailConfirmationToken(),
0 ignored issues
show
Bug introduced by
It seems like $user->getNewEmailConfirmationToken() can also be of type null; however, parameter $token of Silverback\ApiComponentB...er::pathToReferrerUrl() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

85
            /** @scrutinizer ignore-type */ $user->getNewEmailConfirmationToken(),
Loading history...
86
            $user->getUsername(),
0 ignored issues
show
Bug introduced by
It seems like $user->getUsername() can also be of type null; however, parameter $email of Silverback\ApiComponentB...er::pathToReferrerUrl() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
            /** @scrutinizer ignore-type */ $user->getUsername(),
Loading history...
87
            'verifyPath',
88
            $this->defaultChangeEmailVerifyPath
89
        );
90
        $email = (new TemplatedEmail())
91
            ->to(Address::fromString($userEmail))
92
            ->subject('Your password reset request')
93
            ->htmlTemplate('@SilverbackApiComponent/emails/user_verify_email.html.twig')
94
            ->context([
95
                'user' => $user,
96
                'verify_url' => $verifyUrl,
97
                'website_name' => $this->websiteName,
98
            ]);
99
        $this->mailer->send($email);
100
    }
101
102
    public function sendUserWelcomeEmail(AbstractUser $user): void
103
    {
104
        if (!$this->sendUserWelcomeEmailEnabled) {
105
            return;
106
        }
107
        $userEmail = $this->getUserEmail($user);
108
        $email = (new TemplatedEmail())
109
            ->to(Address::fromString($userEmail))
110
            ->subject(sprintf('Welcome to %s', $this->websiteName))
111
            ->htmlTemplate('@SilverbackApiComponent/emails/user_welcome.html.twig')
112
            ->context([
113
                'user' => $user,
114
                'website_name' => $this->websiteName,
115
            ]);
116
        $this->mailer->send($email);
117
    }
118
119
    public function sendUserEnabledEmail(AbstractUser $user): void
120
    {
121
        if (!$this->sendUserEnabledEmailEnabled) {
122
            return;
123
        }
124
        $userEmail = $this->getUserEmail($user);
125
        $email = (new TemplatedEmail())
126
            ->to(Address::fromString($userEmail))
127
            ->subject('Your account has been enabled')
128
            ->htmlTemplate('@SilverbackApiComponent/emails/user_enabled.html.twig')
129
            ->context([
130
                'user' => $user,
131
                'website_name' => $this->websiteName,
132
            ]);
133
        $this->mailer->send($email);
134
    }
135
136
    public function sendUsernameChangedEmail(AbstractUser $user): void
137
    {
138
        if (!$this->sendUserUsernameChangedEmailEnabled) {
139
            return;
140
        }
141
        $userEmail = $this->getUserEmail($user);
142
        $email = (new TemplatedEmail())
143
            ->to(Address::fromString($userEmail))
144
            ->subject('Your username has been changed')
145
            ->htmlTemplate('@SilverbackApiComponent/emails/username_changed.html.twig')
146
            ->context([
147
                'user' => $user,
148
                'website_name' => $this->websiteName,
149
            ]);
150
        $this->mailer->send($email);
151
    }
152
153
    public function sendPasswordChangedEmail(AbstractUser $user): void
154
    {
155
        if (!$this->sendUserPasswordChangedEmailEnabled) {
156
            return;
157
        }
158
        $userEmail = $this->getUserEmail($user);
159
        $email = (new TemplatedEmail())
160
            ->to(Address::fromString($userEmail))
161
            ->subject('Your password has been changed')
162
            ->htmlTemplate('@SilverbackApiComponent/emails/user_password_changed.html.twig')
163
            ->context([
164
                'user' => $user,
165
                'website_name' => $this->websiteName,
166
            ]);
167
        $this->mailer->send($email);
168
    }
169
170
    private function getUserEmail(AbstractUser $user): string
171
    {
172
        if (!($userEmail = $user->getEmailAddress())) {
173
            throw new InvalidParameterException('The user must have an email address to send a password reset email');
174
        }
175
176
        return $userEmail;
177
    }
178
179
    private function pathToReferrerUrl(string $token, string $email, string $queryKey, string $defaultPath): string
180
    {
181
        $request = $this->requestStack->getCurrentRequest();
182
        $path = $request ? $request->query->get($queryKey, $defaultPath) : $defaultPath;
183
        $urlParts = $request ? parse_url($request->headers->get('referer')) : ['scheme' => 'https', 'host' => 'no-referrer'];
184
        $path = str_replace(['{{ token }}', '{{ email }}'], [$token, $email], $path);
185
186
        return sprintf(
187
            '%s://%s/%s',
188
            $urlParts['scheme'],
189
            $urlParts['host'],
190
            ltrim($path, '/')
191
        );
192
    }
193
}
194