BoneUserController::loginFormAction()   F
last analyzed

Complexity

Conditions 13
Paths 428

Size

Total Lines 61
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 45
CRAP Score 13

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 46
c 3
b 0
f 0
dl 0
loc 61
ccs 45
cts 45
cp 1
rs 3.2444
cc 13
nc 428
nop 1
crap 13

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Bone\User\Controller;
4
5
use Bone\Http\Response\HtmlResponse;
6
use Bone\Http\Response\LayoutResponse;
7
use Bone\I18n\Form;
8
use Bone\Controller\Controller;
9
use Bone\Paseto\PasetoService;
10
use Bone\Server\SiteConfigAwareInterface;
11
use Bone\Server\Traits\HasSiteConfigTrait;
12
use Bone\View\ViewEngine;
13
use Bone\Server\SessionAwareInterface;
14
use Bone\Server\Traits\HasSessionTrait;
15
use Bone\Mail\EmailMessage;
16
use Bone\Mail\Service\MailService;
17
use Bone\User\Form\LoginForm;
18
use Bone\User\Form\PersonForm;
19
use Bone\User\Form\RegistrationForm;
20
use Bone\User\Form\ResetPasswordForm;
21
use DateTime;
22
use Del\Entity\User;
23
use Del\Exception\EmailLinkException;
24
use Del\Exception\UserException;
25
use Del\Factory\CountryFactory;
26
use Del\Form\Field\Text\EmailAddress;
27
use Del\Icon;
28
use Del\Service\UserService;
29
use Del\SessionManager;
30
use Del\Value\User\State;
31
use Exception;
32
use Laminas\Diactoros\Response\RedirectResponse;
33
use Laminas\Diactoros\Uri;
34
use Psr\Http\Message\ResponseInterface;
35
use Psr\Http\Message\ServerRequestInterface;
36
37
class BoneUserController extends Controller implements SessionAwareInterface
38
{
39
    use HasSessionTrait;
40
    use HasSiteConfigTrait;
41
42
    private string $logo = '';
43
44 41
    public function __construct(
45
        private UserService $userService,
46
        private MailService $mailService,
47
        private string $loginRedirectRoute,
48
        private string $adminLayout,
49
        private PasetoService $pasetoService,
50
        private bool $registrationEnabled = true,
51
        private $profileRequired = false,
52
        private bool $rememberMeCookie = true
53
    ) {
54 41
    }
55
56
    /**
57
     * @return string
58
     */
59 29
    public function getLogo(): string
60
    {
61 29
        if ($this->logo === '') {
62 29
            $this->logo = $this->getSiteConfig()->getLogo();
63
        }
64
65 29
        return $this->logo;
66
    }
67
68
    /**
69
     * @param ServerRequestInterface $request
70
     * @return ResponseInterface $response
71
     * @throws \Exception
72
     */
73 1
    public function indexAction(ServerRequestInterface $request): ResponseInterface
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

73
    public function indexAction(/** @scrutinizer ignore-unused */ ServerRequestInterface $request): ResponseInterface

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
74
    {
75 1
        if ($this->getSession()->get('user')) {
76 1
            return new RedirectResponse('/user/home');
77
        }
78
79 1
        $body = $this->getView()->render('boneuser::index', [
80 1
            'logo' => $this->getLogo(),
81 1
            'canRegister' => $this->registrationEnabled
82 1
        ]
83 1
    );
84
85 1
        return new HtmlResponse($body);
86
    }
87
88
    /**
89
     * @param ServerRequestInterface $request
90
     * @return ResponseInterface
91
     * @throws UserException
92
     */
93 4
    public function registerAction(ServerRequestInterface $request): ResponseInterface
94
    {
95 4
        $form = new RegistrationForm('register', $this->getTranslator());
96 4
        $message = null;
97
98 4
        if ($request->getMethod() === 'POST') {
99
100 3
            $formData = $request->getParsedBody();
101 3
            $form->populate($formData);
0 ignored issues
show
Bug introduced by
It seems like $formData can also be of type null and object; however, parameter $values of Del\Form\AbstractForm::populate() does only seem to accept array, 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

101
            $form->populate(/** @scrutinizer ignore-type */ $formData);
Loading history...
102
103 3
            if ($form->isValid()) {
104 2
                $data = $form->getValues();
105
106
                try {
107 2
                    $user = $this->userService->registerUser($data);
108 1
                    $link = $this->userService->generateEmailLink($user);
109 1
                    $mail = $this->mailService;
110
111 1
                    $env = $mail->getSiteConfig()->getEnvironment();
112 1
                    $email = $user->getEmail();
113 1
                    $token = $link->getToken();
114
115 1
                    $mail = new EmailMessage();
116 1
                    $mail->setTo($user->getEmail());
117 1
                    $mail->setSubject($this->getTranslator()->translate('email.user.register.thankswith', 'user') . ' ' . $this->mailService->getSiteConfig()->getTitle());
118 1
                    $mail->setTemplate('email.user::user_registration/user_registration');
119 1
                    $mail->setViewData([
120 1
                        'siteUrl' => $env->getSiteURL(),
121 1
                        'logo' => $this->getSiteConfig()->getEmailLogo(),
122 1
                        'address' => $this->getSiteConfig()->getAddress(),
123 1
                        'activationLink' => '/user/activate/' . $email . '/' . $token,
124 1
                    ]);
125 1
                    $this->mailService->sendEmail($mail);
126 1
                    $body = $this->getView()->render('boneuser::thanks-for-registering', ['logo' => $this->getLogo()]);
127
128 1
                    return new HtmlResponse($body);
129
130 1
                } catch (UserException $e) {
131 1
                    $message = [$e->getMessage(), 'danger'];
132
                }
133
            } else {
134 1
                $message = [Icon::WARNING . ' There was a problem with your form.', 'danger'];
135
            }
136
        }
137
138 3
        $body = $this->getView()->render('boneuser::register', ['form' => $form, 'message' => $message, 'logo' => $this->getLogo()]);
139
140 3
        return new HtmlResponse($body);
141
    }
142
143
    /**
144
     * @param ServerRequestInterface $request
145
     * @return ResponseInterface
146
     * @throws \Doctrine\ORM\ORMException
147
     * @throws \Doctrine\ORM\OptimisticLockException
148
     */
149 3
    public function activateAction(ServerRequestInterface $request): ResponseInterface
150
    {
151 3
        $email = $request->getAttribute('email');
152 3
        $token = $request->getAttribute('token');
153 3
        $translator = $this->getTranslator();
154 3
        $userService = $this->userService;
155 3
        $loginRedirect = $this->loginRedirectRoute;
156 3
        $message = null;
157
158
        try {
159 3
            $link = $userService->findEmailLink($email, $token);
160 1
            $user = $link->getUser();
161 1
            $user->setState(new State(State::STATE_ACTIVATED));
162 1
            $user->setLastLogin(new DateTime());
163 1
            $userService->saveUser($user);
164 1
            $userService->deleteEmailLink($link);
165 1
            $this->getSession()->set('user', $user->getId());
166
167 1
            if ($this->profileRequired && !$this->userService->hasProfile($user)) {
168 1
                $this->loginRedirectRoute = '/user/edit-profile';
169
170 1
                return new RedirectResponse($this->loginRedirectRoute);
171
            }
172 2
        } catch (EmailLinkException $e) {
173 2
            switch ($e->getMessage()) {
174 2
                case EmailLinkException::LINK_EXPIRED:
175 1
                    $message = [$translator->translate('login.activation.expired', 'user')
176 1
                        . ' <a href="/user/resend-activation-mail/' . $email . '">'
177 1
                        . $translator->translate('login.activation.expired2', 'user') . '</a>', 'danger'];
178 1
                    break;
179
                default:
180 1
                    $message = [$e->getMessage(), 'danger'];
181 1
                    break;
182
            }
183
        }
184
185 2
        $body = $this->getView()->render('boneuser::activate-user-account', [
186 2
            'loginRedirect' => $loginRedirect,
187 2
            'message' => $message,
188 2
            'logo' => $this->getLogo(),
189 2
        ]);
190
191 2
        return new HtmlResponse($body);
192
    }
193
194 6
    private function initForm(LoginForm $form)
195
    {
196 6
        $this->rememberMeCookie === false ? $form->getFields()->removeByName('remember') : null;
197
    }
198
199
200
    /**
201
     * @param ServerRequestInterface $request
202
     * @return ResponseInterface
203
     */
204 1
    public function loginAction(ServerRequestInterface $request): ResponseInterface
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

204
    public function loginAction(/** @scrutinizer ignore-unused */ ServerRequestInterface $request): ResponseInterface

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
205
    {
206 1
        $form = new LoginForm('userlogin', $this->getTranslator());
207 1
        $this->initForm($form);
208 1
        $body = $this->getView()->render('boneuser::login', ['form' => $form, 'logo' => $this->getLogo()]);
209
210 1
        return new HtmlResponse($body);
211
    }
212
213
214
    /**
215
     * @param ServerRequestInterface $request
216
     * @return ResponseInterface
217
     */
218 5
    public function loginFormAction(ServerRequestInterface $request): ResponseInterface
219
    {
220 5
        $translator = $this->getTranslator();
221 5
        $form = new LoginForm('userlogin', $translator);
222 5
        $this->initForm($form);
223 5
        $post = $request->getParsedBody();
224 5
        $form->populate($post);
0 ignored issues
show
Bug introduced by
It seems like $post can also be of type null and object; however, parameter $values of Del\Form\AbstractForm::populate() does only seem to accept array, 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

224
        $form->populate(/** @scrutinizer ignore-type */ $post);
Loading history...
225 5
        $params = ['form' => $form];
226
227
        try {
228 5
            if ($form->isValid()) {
229 5
                $data = $form->getValues();
230 5
                $email = $data['email'];
231 5
                $pass = $data['password'];
232 5
                $userId = $this->userService->authenticate($email, $pass);
233 5
                $locale = $translator->getLocale();
234 5
                $session = $this->getSession();
235 5
                $session->set('user', $userId);
236 5
                $session->set('locale', $locale);
237 5
                $this->rememberMeCookie && isset($data['remember']) ? $this->setCookie((int)$data['remember'], $userId) : null;
238
239 5
                if ($route = $session->get('loginRedirectRoute')) {
240 5
                    $this->loginRedirectRoute = $route;
241 5
                    $session->unset('loginRedirectRoute');
242
                }
243
244 5
                $user = $this->userService->findUserById($userId);
245 1
                $user->setLastLogin(new DateTime());
246 1
                $this->userService->saveUser($user);
0 ignored issues
show
Bug introduced by
It seems like $user can also be of type null; however, parameter $user of Del\Service\UserService::saveUser() does only seem to accept Del\Entity\UserInterface, 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

246
                $this->userService->saveUser(/** @scrutinizer ignore-type */ $user);
Loading history...
247
248 1
                if ($this->profileRequired && !$this->userService->hasProfile($user)) {
0 ignored issues
show
Bug introduced by
It seems like $user can also be of type null; however, parameter $user of Del\Service\UserService::hasProfile() does only seem to accept Del\Entity\UserInterface, 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

248
                if ($this->profileRequired && !$this->userService->hasProfile(/** @scrutinizer ignore-type */ $user)) {
Loading history...
249 1
                    $this->loginRedirectRoute = '/user/edit-profile';
250
                }
251
252 1
                return new RedirectResponse('/' . $locale . $this->loginRedirectRoute);
253
            }
254 4
        } catch (UserException $e) {
255 4
            switch ($e->getMessage()) {
256 4
                case UserException::USER_NOT_FOUND:
257 4
                case UserException::WRONG_PASSWORD:
258 1
                    $message = [Icon::WARNING . ' ' . $translator->translate('login.error.password', 'user') . '<a href="/user/lost-password/' . $email . '">' . $translator->translate('login.error.password2', 'user') . '</a>', 'danger'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $email does not seem to be defined for all execution paths leading up to this point.
Loading history...
259 1
                    break;
260 3
                case UserException::USER_UNACTIVATED:
261 1
                    $message = [Icon::WARNING . ' ' . $translator->translate('login.unactivated', 'user') . '<a href="/user/resend-activation-mail/' . $email . '">' . $translator->translate('login.unactivated2', 'user') . '</a>', 'danger'];
262 1
                    break;
263 2
                case UserException::USER_DISABLED:
264 2
                case UserException::USER_BANNED:
265 1
                    $message = [Icon::REMOVE . ' ' . $translator->translate('login.activation.banned', 'user'), 'danger'];
266 1
                    break;
267
                default:
268 1
                    $message = $e->getMessage();
269 1
                    break;
270
            }
271
272 4
            $params['message'] = $message;
273
        }
274
275 4
        $params['logo'] = $this->getLogo();
276 4
        $body = $this->getView()->render('boneuser::login', $params);
277
278 4
        return new HtmlResponse($body);
279
280
    }
281
282
    /**
283
     * @param int $length
284
     * @param int $userId
285
     * @throws \ParagonIE\Paseto\Exception\InvalidKeyException
286
     * @throws \ParagonIE\Paseto\Exception\InvalidPurposeException
287
     * @throws \ParagonIE\Paseto\Exception\PasetoException
288
     */
289 1
    private function setCookie(int $length, int $userId): void
290
    {
291 1
        $times = [
292 1
            1 => 60 * 60 * 24 * 7,
293 1
            2 => 60 * 60 * 24 * 30,
294 1
            3 => 60 * 60 * 24 * 365,
295 1
        ];
296
297 1
        $intervals = [
298 1
            1 => 'P07D',
299 1
            2 => 'P30D',
300 1
            3 => 'P365D',
301 1
        ];
302
303 1
        $time = array_key_exists($length, $times) ? $times[$length] : 0;
304 1
        $time += \time();
305 1
        $expiry = \time() + $time;
306 1
        $interval = array_key_exists($length, $intervals) ? $intervals[$length] : 'P0D';
307 1
        $token = $this->pasetoService->encryptToken([
308 1
            'user' => $userId,
309 1
        ], $interval);
310 1
        \setcookie('resu', $token, $expiry, '/');
311
    }
312
313
    /**
314
     * @param ServerRequestInterface $request
315
     * @return ResponseInterface
316
     */
317 2
    public function homePageAction(ServerRequestInterface $request): ResponseInterface
318
    {
319 2
        if ($this->loginRedirectRoute !== '/user/home') {
320 1
            return new RedirectResponse($this->loginRedirectRoute);
321
        }
322
323 1
        $user = $request->getAttribute('user');
324
325 1
        if ($this->profileRequired && !$this->userService->hasProfile($user)) {
326 1
            $this->loginRedirectRoute = '/user/edit-profile';
327
328 1
            return new RedirectResponse($this->loginRedirectRoute);
329
        }
330
331
        $body = $this->getView()->render('boneuser::home', [
332
            'message' => [$this->getTranslator()->translate('home.loggedin', 'user'), 'success'],
333
            'user' => $user,
334
            'logo' => $this->getSiteConfig()->getLogo(),
335
        ]);
336
337
        return new LayoutResponse($body, $this->adminLayout);
338
    }
339
340
    /**
341
     * @param ServerRequestInterface $request
342
     * @return ResponseInterface
343
     */
344 1
    public function logoutAction(ServerRequestInterface $request): ResponseInterface
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

344
    public function logoutAction(/** @scrutinizer ignore-unused */ ServerRequestInterface $request): ResponseInterface

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
345
    {
346 1
        SessionManager::destroySession();
347 1
        \setcookie('resu', '', 1, '/');
348
349 1
        return new RedirectResponse(new Uri('/'));
350
    }
351
352
    /**
353
     * @param ServerRequestInterface $request
354
     * @return ResponseInterface
355
     */
356 4
    public function resendActivationEmailAction(ServerRequestInterface $request): ResponseInterface
357
    {
358 4
        $email = $request->getAttribute('email');
359 4
        $user = $this->userService->findUserByEmail($email);
360 4
        $message = null;
361 4
        $translator = $this->getTranslator();
362
363 4
        if (!$user) {
364 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
365
        }
366
367 3
        if ($user->getState()->getValue() == State::STATE_ACTIVATED) {
368 1
            $message = [UserException::USER_ACTIVATED, 'danger'];
369
        } else {
370
            try {
371 2
                $link = $this->userService->generateEmailLink($user);
372 1
                $mail = $this->mailService;
373
374 1
                $env = $mail->getSiteConfig()->getEnvironment();
375 1
                $email = $user->getEmail();
376 1
                $token = $link->getToken();
377
378 1
                $mail = new EmailMessage();
379 1
                $mail->setTo($user->getEmail());
380 1
                $mail->setSubject($translator->translate('email.user.register.thankswith', 'user') . ' ' . $this->mailService->getSiteConfig()->getTitle());
381 1
                $mail->setTemplate('email.user::user_registration/user_registration');
382 1
                $mail->setViewData([
383 1
                    'siteUrl' => $env->getSiteURL(),
384 1
                    'logo' => $this->getSiteConfig()->getEmailLogo(),
385 1
                    'address' => $this->getSiteConfig()->getAddress(),
386 1
                    'activationLink' => '/user/activate/' . $email . '/' . $token,
387 1
                ]);
388 1
                $this->mailService->sendEmail($mail);
389
390 1
            } catch (Exception $e) {
391 1
                $message = [$translator->translate('login.resendactivation.error', 'user')
392 1
                    . $this->getSiteConfig()->getContactEmail() . '', 'danger'];
393
            }
394
        }
395
396 3
        $body = $this->getView()->render('boneuser::resend-activation', [
397 3
            'message' => $message,
398 3
            'logo' => $this->getLogo(),
399 3
        ]);
400
401 3
        return new HtmlResponse($body);
402
    }
403
404
405
    /**
406
     * @param ServerRequestInterface $request
407
     * @return ResponseInterface
408
     */
409 4
    public function forgotPasswordAction(ServerRequestInterface $request): ResponseInterface
410
    {
411 4
        $email = $request->getAttribute('email');
412 4
        $user = $this->userService->findUserByEmail($email);
413
414 4
        if (!$user) {
415 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
416
        }
417
418 3
        if ($user->getState()->getValue() == State::STATE_UNACTIVATED) {
419 1
            return new RedirectResponse('/user/resend-activation-mail/' . $email);
420
        }
421
422
        try {
423 2
            $link = $this->userService->generateEmailLink($user);
424 1
            $email = $user->getEmail();
425 1
            $token = $link->getToken();
426 1
            $env = $this->getSiteConfig()->getEnvironment();
427 1
            $mail = new EmailMessage();
428 1
            $mail->setTo($email);
429 1
            $mail->setSubject($this->getTranslator()->translate('email.forgotpass.subject', 'user') . $this->mailService->getSiteConfig()->getTitle() . '.');
430 1
            $mail->setTemplate('email.user::user_registration/reset_password');
431 1
            $mail->setViewData([
432 1
                'siteUrl' => $env->getSiteURL(),
433 1
                'logo' => $this->getSiteConfig()->getEmailLogo(),
434 1
                'address' => $this->getSiteConfig()->getAddress(),
435 1
                'resetLink' => '/user/reset-password/' . $email . '/' . $token,
436 1
            ]);
437 1
            $this->mailService->sendEmail($mail);
438 1
        } catch (Exception $e) {
439 1
            $this->view->message = [$e->getMessage(), 'danger'];
0 ignored issues
show
Bug introduced by
Accessing message on the interface Bone\View\ViewEngineInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
440
        }
441
442 2
        $body = $this->getView()->render('boneuser::forgot-password', ['logo' => $this->getLogo()]);
443
444 2
        return new HtmlResponse($body);
445
    }
446
447
448
    /**
449
     * @param ServerRequestInterface $request
450
     * @return ResponseInterface
451
     */
452 5
    public function resetPasswordAction(ServerRequestInterface $request): ResponseInterface
453
    {
454 5
        $email = $request->getAttribute('email');
455 5
        $token = $request->getAttribute('token');
456 5
        $form = new ResetPasswordForm('resetpass');
457 5
        $translator = $this->getTranslator();
458 5
        $params = [];
459 5
        $success = false;
460 5
        $user = $this->userService->findUserByEmail($email);
461
462 5
        if (!$user) {
463 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
464
        }
465
466
        try {
467 4
            $link = $this->userService->findEmailLink($email, $token);
468
469 2
            if ($request->getMethod() === 'POST') {
470 2
                $data = $request->getParsedBody();
471 2
                $form->populate($data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null and object; however, parameter $values of Del\Form\AbstractForm::populate() does only seem to accept array, 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

471
                $form->populate(/** @scrutinizer ignore-type */ $data);
Loading history...
472
473 2
                if ($form->isValid()) {
474 2
                    $data = $form->getValues();
475
476 2
                    if ($data['password'] === $data['confirm']) {
477 1
                        $this->userService->changePassword($user, $data['password']);
478 1
                        $this->userService->deleteEmailLink($link);
479 1
                        $message = [$translator->translate('email.resetpass.success', 'user'), 'success'];
480 1
                        $success = true;
481 1
                        $this->getSession()->set('user', $user->getId());
482
                    } else {
483 1
                        $message = [$translator->translate('email.resetpass.nomatch', 'user'), 'danger'];
484 2
                        $form = new ResetPasswordForm('resetpass');
485
                    }
486
                }
487
            }
488 2
        } catch (EmailLinkException $e) {
489 1
            $message = [$e->getMessage(), 'danger'];
490 1
        } catch (Exception $e) {
491 1
            throw $e;
492
        }
493
494 3
        if (isset($message)) {
495 3
            $params['message'] = $message;
496
        }
497
498 3
        $params['success'] = $success;
499 3
        $params['form'] = $form;
500 3
        $params['logo'] = $this->getLogo();
501 3
        $body = $this->getView()->render('boneuser::reset-pass', $params);
502
503 3
        return new HtmlResponse($body);
504
    }
505
506
    /**
507
     * @param ServerRequestInterface $request
508
     * @return ResponseInterface
509
     */
510 3
    public function changePasswordAction(ServerRequestInterface $request): ResponseInterface
511
    {
512 3
        $user = $request->getAttribute('user');
513 3
        $form = new ResetPasswordForm('resetpass');
514 3
        $translator = $this->getTranslator();
515 3
        $message = null;
516 3
        $success = false;
517
518 3
        if ($request->getMethod() === 'POST') {
519 3
            $data = $request->getParsedBody();
520 3
            $form->populate($data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null and object; however, parameter $values of Del\Form\AbstractForm::populate() does only seem to accept array, 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

520
            $form->populate(/** @scrutinizer ignore-type */ $data);
Loading history...
521
522 3
            if ($form->isValid()) {
523 2
                $data = $form->getValues();
524
525 2
                if ($data['password'] === $data['confirm']) {
526 1
                    $this->userService->changePassword($user, $data['password']);
527 1
                    $message = [Icon::CHECK_CIRCLE . ' ' . $translator->translate('email.resetpass.success', 'user'), 'success'];
528 1
                    $success = true;
529
                } else {
530 1
                    $message = [Icon::WARNING . ' ' . $translator->translate('email.resetpass.nomatch', 'user'), 'danger'];
531 1
                    $form = new ResetPasswordForm('resetpass');
532
                }
533
            } else {
534 1
                $message = [Icon::WARNING . ' There was a problem with your form.', 'danger'];
535
            }
536
        }
537
538 3
        $params['success'] = $success;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$params was never initialized. Although not strictly required by PHP, it is generally a good practice to add $params = array(); before regardless.
Loading history...
539 3
        $params['form'] = $form;
540 3
        $params['logo'] = $this->getLogo();
541
542 3
        $body = $this->getView()->render('boneuser::change-pass', [
543 3
            'success' => $success,
544 3
            'form' => $form,
545 3
            'logo' => $this->getLogo(),
546 3
            'message' => $message
547 3
        ]);
548
549 3
        return new HtmlResponse($body);
550
    }
551
552
    /**
553
     * @param ServerRequestInterface $request
554
     * @return ResponseInterface
555
     */
556 4
    public function changeEmailAction(ServerRequestInterface $request): ResponseInterface
557
    {
558 4
        $user = $request->getAttribute('user');
559 4
        $form = new LoginForm('changeemail', $this->getTranslator());
560 4
        $form->getFields()->removeByName('remember');
561 4
        $form->getField('email')->setLabel('New email');
562 4
        $form->getField('submit')->setValue('Submit');
563 4
        $translator = $this->getTranslator();
564 4
        $params = [
565 4
            'form' => $form
566 4
        ];
567
568 4
        if ($request->getMethod() === 'POST') {
569 4
            $data = $request->getParsedBody();
570 4
            $form->populate($data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type null and object; however, parameter $values of Del\Form\AbstractForm::populate() does only seem to accept array, 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

570
            $form->populate(/** @scrutinizer ignore-type */ $data);
Loading history...
571 4
            $message = null;
572
573 4
            if ($form->isValid()) {
574
575 4
                $newEmail = $form->getField('email')->getValue();
576 4
                $password = $form->getField('password')->getValue();
577 4
                $existing = $this->userService->findUserByEmail($newEmail);
578
579 4
                if ($existing) {
580 1
                    $message = [$translator->translate('email.changeemail.registered', 'user') . $this->getSiteConfig()->getTitle() . '.', 'danger'];
581
                } else {
582 3
                    if ($this->userService->checkPassword($user, $password)) {
583
584
                        try {
585
586 2
                            $link = $this->userService->generateEmailLink($user);
587 1
                            $email = $user->getEmail();
588 1
                            $token = $link->getToken();
589 1
                            $env = $this->getSiteConfig()->getEnvironment();
590 1
                            $mail = new EmailMessage();
591 1
                            $mail->setTo($email);
592 1
                            $mail->setSubject($translator->translate('email.changeemail.subject', 'user') . $this->mailService->getSiteConfig()->getTitle() . '.');
593 1
                            $mail->setTemplate('email.user::user_registration/change_email');
594 1
                            $mail->setViewData([
595 1
                                'siteUrl' => $env->getSiteURL(),
596 1
                                'logo' => $this->getSiteConfig()->getEmailLogo(),
597 1
                                'address' => $this->getSiteConfig()->getAddress(),
598 1
                                'resetLink' => '/user/reset-email/' . $email . '/' . $newEmail . '/' . $token,
599 1
                            ]);
600 1
                            $this->mailService->sendEmail($mail);
601 1
                            $message = [$translator->translate('email.changeemail.sent', 'user'), 'info'];
602 1
                            unset ($params['form']);
603
604 1
                        } catch (Exception $e) {
605 1
                            $message = [$translator->translate('email.changeemail.notsent', 'user') . $this->getSiteConfig()->getContactEmail() . '.', 'danger'];
606
                        }
607
608
                    } else {
609 1
                        $message = [$translator->translate('email.changeemail.wrongpass', 'user'), 'danger'];
610
                    }
611
                }
612
            }
613
614 4
            $params['message'] = $message;
615
        }
616
617 4
        $params['logo'] = $this->getLogo();
618 4
        $body = $this->getView()->render('boneuser::change-email', $params);
619
620 4
        return new LayoutResponse($body, 'layouts::admin');
621
    }
622
623
    /**
624
     * @param ServerRequestInterface $request
625
     * @return ResponseInterface
626
     */
627 1
    public function editProfileAction(ServerRequestInterface $request): ResponseInterface
628
    {
629 1
        $user = $request->getAttribute('user');
630 1
        $person = $user->getPerson();
631 1
        $image = $person->getImage();
632 1
        $form = new PersonForm('profile', $this->getTranslator());
633 1
        $array = $this->userService->getPersonService()->toArray($person);
634 1
        $form->populate($array);
635
636 1
        if ($request->getMethod() === 'POST') {
637 1
            $post = $request->getParsedBody();
638 1
            $form->populate($post);
0 ignored issues
show
Bug introduced by
It seems like $post can also be of type null and object; however, parameter $values of Del\Form\AbstractForm::populate() does only seem to accept array, 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

638
            $form->populate(/** @scrutinizer ignore-type */ $post);
Loading history...
639
640 1
            if ($form->isValid()) {
641 1
                $data = $form->getValues();
642 1
                $data['image'] = $image;
643 1
                $dateFormat = $this->getSiteConfig()->getAttribute('i18n')['date_format'];
644 1
                $data['dob'] = DateTime::createFromFormat($dateFormat, $data['dob']);
645 1
                $data['country'] = CountryFactory::generate($data['country']);
646 1
                $this->userService->getPersonService()->populateFromArray($person, $data);
647 1
                $this->userService->saveUser($user);
648
            }
649
        }
650
651 1
        $body = $this->getView()->render('boneuser::edit-profile', [
652 1
            'person' => $person,
653 1
            'form' => $form->render(),
654 1
        ]);
655
656 1
        return new LayoutResponse($body, $this->adminLayout);
657
    }
658
659
    /**
660
     * @param ServerRequestInterface $requestApiController
661
     * @return ResponseInterface
662
     */
663 2
    public function resetEmailAction(ServerRequestInterface $request): ResponseInterface
664
    {
665 2
        $email = $request->getAttribute('email');
666 2
        $newEmail = $request->getAttribute('new-email');
667 2
        $token = $request->getAttribute('token');
668 2
        $translator = $this->getTranslator();
669
670
        try {
671 2
            $link = $this->userService->findEmailLink($email, $token);
672 1
            $user = $link->getUser();
673 1
            $user->setEmail($newEmail);
674 1
            $this->userService->saveUser($user);
675 1
            $this->userService->deleteEmailLink($link);
676 1
            $message = [$translator->translate('email.changeemail.success', 'user') . $newEmail . $translator->translate('email.changeemail.success2', 'user'), 'success'];
677 1
            SessionManager::getInstance()->set('user', $user->getId());
678 1
        } catch (EmailLinkException $e) {
679 1
            $message = [$e->getMessage(), 'danger'];
680
        }
681
682 2
        $body = $this->getView()->render('boneuser::reset-email', ['message' => $message, 'logo' => $this->getLogo()]);
683
684 2
        return new HtmlResponse($body);
685
    }
686
}
687