Passed
Push — master ( 331013...49242a )
by Derek Stephen
04:04
created

BoneUserController::homePageAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 8
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 10
c 2
b 1
f 0
cc 2
nc 2
nop 1
crap 2
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 Psr\Http\Message\ResponseInterface;
33
use Psr\Http\Message\ServerRequestInterface;
34
use Laminas\Diactoros\Response\RedirectResponse;
35
use Laminas\Diactoros\Uri;
36
37
class BoneUserController extends Controller implements SessionAwareInterface, SiteConfigAwareInterface
38
{
39
    use HasSessionTrait;
40
    use HasSiteConfigTrait;
41
42
    /** @var UserService $userService */
43
    private $userService;
44
45
    /** @var MailService $mailService */
46
    private $mailService;
47
48
    /** @var string $loginRedirectRoute */
49
    private $loginRedirectRoute;
50
51
    /** @var string $logo */
52
    private $logo;
53
54
    /** @var string $adminLayout */
55
    private $adminLayout;
56
57
    /** @var bool $registrationEnabled */
58
    private $registrationEnabled;
59
60
    /** @var bool $profileRequired */
61
    private $profileRequired;
62
63
    /** @var bool $rememberMeCookie */
64
    private $rememberMeCookie;
65
66
    /** @var PasetoService $pasetoService */
67
    private $pasetoService = null;
68
69
    /**
70
     * BoneUserController constructor.
71
     * @param UserService $userService
72
     * @param MailService $mailService
73
     */
74 41
    public function __construct(UserService $userService, MailService $mailService, string $loginRedirectRoute = '/user/home',
75
                                string $adminLayout, PasetoService $pasetoService, bool $registrationEnabled = true, $profileRequired = false,
76
                                bool $rememberMeCookie = true)
77
    {
78 41
        $this->userService = $userService;
79 41
        $this->mailService = $mailService;
80 41
        $this->loginRedirectRoute = $loginRedirectRoute;
81 41
        $this->adminLayout = $adminLayout;
82 41
        $this->registrationEnabled = $registrationEnabled;
83 41
        $this->profileRequired = $profileRequired;
84 41
        $this->rememberMeCookie = $rememberMeCookie;
85 41
        $this->profileRequired = $profileRequired;
86 41
        $this->pasetoService = $pasetoService;
87 41
    }
88
89
    /**
90
     * @return string
91
     */
92 30
    public function getLogo(): string
93
    {
94 30
        if (!$this->logo) {
95 30
            $this->logo = $this->getSiteConfig()->getLogo();
96
        }
97
98 30
        return $this->logo;
99
    }
100
101
    /**
102
     * @param ServerRequestInterface $request
103
     * @return ResponseInterface $response
104
     * @throws \Exception
105
     */
106 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

106
    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...
107
    {
108 1
        if ($this->getSession()->get('user')) {
109 1
            return new RedirectResponse('/user/home');
110
        }
111
112 1
        $body = $this->getView()->render('boneuser::index', ['logo' => $this->getLogo()]);
113
114 1
        return new HtmlResponse($body);
115
    }
116
117
    /**
118
     * @param ServerRequestInterface $request
119
     * @return ResponseInterface
120
     * @throws UserException
121
     */
122 4
    public function registerAction(ServerRequestInterface $request): ResponseInterface
123
    {
124 4
        $form = new RegistrationForm('register', $this->getTranslator());
125 4
        $message = null;
126
127 4
        if ($request->getMethod() == 'POST') {
128
129 3
            $formData = $request->getParsedBody();
130 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 $data 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

130
            $form->populate(/** @scrutinizer ignore-type */ $formData);
Loading history...
131
132 3
            if ($form->isValid()) {
133 2
                $data = $form->getValues();
134
                try {
135 2
                    $user = $this->userService->registerUser($data);
136 1
                    $link = $this->userService->generateEmailLink($user);
137 1
                    $mail = $this->mailService;
138
139 1
                    $env = $mail->getSiteConfig()->getEnvironment();
140 1
                    $email = $user->getEmail();
141 1
                    $token = $link->getToken();
142
143 1
                    $mail = new EmailMessage();
144 1
                    $mail->setTo($user->getEmail());
145 1
                    $mail->setSubject($this->getTranslator()->translate('email.user.register.thankswith', 'user') . ' ' . $this->mailService->getSiteConfig()->getTitle());
146 1
                    $mail->setTemplate('email.user::user_registration/user_registration');
147 1
                    $mail->setViewData([
148 1
                        'siteUrl' => $env->getSiteURL(),
149 1
                        'logo' => $this->getSiteConfig()->getEmailLogo(),
150 1
                        'address' => $this->getSiteConfig()->getAddress(),
151 1
                        'activationLink' => '/user/activate/' . $email . '/' . $token,
152
                    ]);
153 1
                    $this->mailService->sendEmail($mail);
154 1
                    $body = $this->getView()->render('boneuser::thanks-for-registering', ['logo' => $this->getLogo()]);
155
156 1
                    return new HtmlResponse($body);
157
158 1
                } catch (UserException $e) {
159 1
                    $message = [$e->getMessage(), 'danger'];
160
                }
161
            } else {
162 1
                $message = [Icon::WARNING . ' There was a problem with your form.', 'danger'];
163
            }
164
        }
165
166 3
        $body = $this->getView()->render('boneuser::register', ['form' => $form, 'message' => $message, 'logo' => $this->getLogo()]);
167
168 3
        return new HtmlResponse($body);
169
    }
170
171
    /**
172
     * @param ServerRequestInterface $request
173
     * @return ResponseInterface
174
     * @throws \Doctrine\ORM\ORMException
175
     * @throws \Doctrine\ORM\OptimisticLockException
176
     */
177 3
    public function activateAction(ServerRequestInterface $request): ResponseInterface
178
    {
179 3
        $email = $request->getAttribute('email');
180 3
        $token = $request->getAttribute('token');
181 3
        $translator = $this->getTranslator();
182 3
        $userService = $this->userService;
183 3
        $loginRedirect = $this->loginRedirectRoute;
184 3
        $message = null;
185
186
        try {
187
188 3
            $link = $userService->findEmailLink($email, $token);
189 1
            $user = $link->getUser();
190 1
            $user->setState(new State(State::STATE_ACTIVATED));
191 1
            $user->setLastLogin(new DateTime());
192 1
            $userService->saveUser($user);
193 1
            $userService->deleteEmailLink($link);
194 1
            $this->getSession()->set('user', $user->getId());
195
196 2
        } catch (EmailLinkException $e) {
197 2
            switch ($e->getMessage()) {
198 2
                case EmailLinkException::LINK_EXPIRED:
199 1
                    $message = [$translator->translate('login.activation.expired', 'user')
200 1
                        . ' <a href="/user/resend-activation-mail/' . $email . '">'
201 1
                        . $translator->translate('login.activation.expired2', 'user') . '</a>', 'danger'];
202 1
                    break;
203
                default:
204 1
                    $message = [$e->getMessage(), 'danger'];
205 1
                    break;
206
            }
207
        }
208
209 3
        $body = $this->getView()->render('boneuser::activate-user-account', [
210 3
            'loginRedirect' => $loginRedirect,
211 3
            'message' => $message,
212 3
            'logo' => $this->getLogo(),
213
        ]);
214
215 3
        return new HtmlResponse($body);
216
    }
217
218 6
    private function initForm(LoginForm $form)
219
    {
220 6
        $this->rememberMeCookie === false ? $form->getFields()->removeByName('remember') : null;
221 6
    }
222
223
224
    /**
225
     * @param ServerRequestInterface $request
226
     * @return ResponseInterface
227
     */
228 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

228
    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...
229
    {
230 1
        $form = new LoginForm('userlogin', $this->getTranslator());
231 1
        $this->initForm($form);
232 1
        $body = $this->getView()->render('boneuser::login', ['form' => $form, 'logo' => $this->getLogo()]);
233
234 1
        return new HtmlResponse($body);
235
    }
236
237
238
    /**
239
     * @param ServerRequestInterface $request
240
     * @return ResponseInterface
241
     */
242 5
    public function loginFormAction(ServerRequestInterface $request): ResponseInterface
243
    {
244 5
        $translator = $this->getTranslator();
245 5
        $form = new LoginForm('userlogin', $translator);
246 5
        $this->initForm($form);
247 5
        $post = $request->getParsedBody();
248 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 $data 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

248
        $form->populate(/** @scrutinizer ignore-type */ $post);
Loading history...
249 5
        $params = ['form' => $form];
250
251
        try {
252
253 5
            if ($form->isValid()) {
254 5
                $data = $form->getValues();
255 5
                $email = $data['email'];
256 5
                $pass = $data['password'];
257 5
                $userId = $this->userService->authenticate($email, $pass);
258 5
                $locale = $translator->getLocale();
259 5
                $session = $this->getSession();
260 5
                $session->set('user', $userId);
261 5
                $session->set('locale', $locale);
262 5
                $this->rememberMeCookie && isset($data['remember']) ? $this->setCookie((int)$data['remember'], $userId) : null;
263
264 5
                if ($route = $session->get('loginRedirectRoute')) {
265 5
                    $this->loginRedirectRoute = $route;
266 5
                    $session->unset('loginRedirectRoute');
267
                }
268
269 5
                $user = $this->userService->findUserById($userId);
270 1
                $user->setLastLogin(new DateTime());
271 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

271
                $this->userService->saveUser(/** @scrutinizer ignore-type */ $user);
Loading history...
272
273 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\User, 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

273
                if ($this->profileRequired && !$this->userService->hasProfile(/** @scrutinizer ignore-type */ $user)) {
Loading history...
274 1
                    $this->loginRedirectRoute = '/user/edit-profile';
275
                }
276
277 1
                return new RedirectResponse('/' . $locale . $this->loginRedirectRoute);
278
            }
279 4
        } catch (UserException $e) {
280 4
            switch ($e->getMessage()) {
281 4
                case UserException::USER_NOT_FOUND:
282 4
                case UserException::WRONG_PASSWORD:
283 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...
284 1
                    break;
285 3
                case UserException::USER_UNACTIVATED:
286 1
                    $message = [Icon::WARNING . ' ' . $translator->translate('login.unactivated', 'user') . '<a href="/user/resend-activation-mail/' . $email . '">' . $translator->translate('login.unactivated2', 'user') . '</a>', 'danger'];
287 1
                    break;
288 2
                case UserException::USER_DISABLED:
289 2
                case UserException::USER_BANNED:
290 1
                    $message = [Icon::REMOVE . ' ' . $translator->translate('login.activation.banned', 'user'), 'danger'];
291 1
                    break;
292
                default:
293 1
                    $message = $e->getMessage();
294 1
                    break;
295
            }
296
297 4
            $params['message'] = $message;
298
        }
299
300 4
        $params['logo'] = $this->getLogo();
301 4
        $body = $this->getView()->render('boneuser::login', $params);
302
303 4
        return new HtmlResponse($body);
304
305
    }
306
307
    /**
308
     * @param int $length
309
     * @param int $userId
310
     * @throws \ParagonIE\Paseto\Exception\InvalidKeyException
311
     * @throws \ParagonIE\Paseto\Exception\InvalidPurposeException
312
     * @throws \ParagonIE\Paseto\Exception\PasetoException
313
     */
314 1
    private function setCookie(int $length, int $userId): void
315
    {
316
        $times = [
317 1
            1 => 60 * 60 * 24 * 7,
318
            2 => 60 * 60 * 24 * 30,
319
            3 => 60 * 60 * 24 * 365,
320
        ];
321
322 1
        $time = array_key_exists($length, $times) ? $times[$length] : 0;
323 1
        $time += \time();
324 1
        $token = $this->pasetoService->encryptToken([
325 1
            'user' => $userId,
326
        ]);
327 1
        \setcookie('resu', $token, \time() * 2, '/');
328 1
    }
329
330
    /**
331
     * @param ServerRequestInterface $request
332
     * @return ResponseInterface
333
     */
334 2
    public function homePageAction(ServerRequestInterface $request): ResponseInterface
335
    {
336 2
        if ($this->loginRedirectRoute !== '/user/home') {
337 1
            return new RedirectResponse($this->loginRedirectRoute);
338
        }
339
340 1
        $user = $request->getAttribute('user');
341 1
        $body = $this->getView()->render('boneuser::home', [
342 1
            'message' => [$this->getTranslator()->translate('home.loggedin', 'user'), 'success'],
343 1
            'user' => $user,
344 1
            'logo' => $this->getSiteConfig()->getLogo(),
345
        ]);
346
347 1
        return new LayoutResponse($body, $this->adminLayout);
348
    }
349
350
    /**
351
     * @param ServerRequestInterface $request
352
     * @return ResponseInterface
353
     */
354 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

354
    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...
355
    {
356 1
        SessionManager::destroySession();
357 1
        \setcookie('resu', '', 1, '/');
358
359 1
        return new RedirectResponse(new Uri('/'));
360
    }
361
362
    /**
363
     * @param ServerRequestInterface $request
364
     * @return ResponseInterface
365
     */
366 4
    public function resendActivationEmailAction(ServerRequestInterface $request): ResponseInterface
367
    {
368 4
        $success = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $success is dead and can be removed.
Loading history...
369 4
        $email = $request->getAttribute('email');
370 4
        $user = $this->userService->findUserByEmail($email);
371 4
        $message = [];
372 4
        $translator = $this->getTranslator();
373
374 4
        if (!$user) {
375 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
376
        }
377
378 3
        if ($user->getState()->getValue() == State::STATE_ACTIVATED) {
379 1
            $message = [UserException::USER_ACTIVATED, 'danger'];
0 ignored issues
show
Unused Code introduced by
The assignment to $message is dead and can be removed.
Loading history...
380
        } else {
381
            try {
382 2
                $link = $this->userService->generateEmailLink($user);
383 1
                $mail = $this->mailService;
384
385 1
                $env = $mail->getSiteConfig()->getEnvironment();
386 1
                $email = $user->getEmail();
387 1
                $token = $link->getToken();
388
389 1
                $mail = new EmailMessage();
390 1
                $mail->setTo($user->getEmail());
391 1
                $mail->setSubject($translator->translate('email.user.register.thankswith', 'user') . ' ' . $this->mailService->getSiteConfig()->getTitle());
392 1
                $mail->setTemplate('email.user::user_registration/user_registration');
393 1
                $mail->setViewData([
394 1
                    'siteUrl' => $env->getSiteURL(),
395 1
                    'logo' => $this->getSiteConfig()->getEmailLogo(),
396 1
                    'address' => $this->getSiteConfig()->getAddress(),
397 1
                    'activationLink' => '/user/activate/' . $email . '/' . $token,
398
                ]);
399 1
                $this->mailService->sendEmail($mail);
400
401 1
            } catch (Exception $e) {
402 1
                $message = [$translator->translate('login.resendactivation.error', 'user')
403 1
                    . $this->getSiteConfig()->getContactEmail() . '', 'danger'];
404
            }
405
        }
406
407 3
        $body = $this->getView()->render('boneuser::resend-activation', [
408 3
            'message' => null,
409 3
            'logo' => $this->getLogo(),
410
        ]);
411
412 3
        return new HtmlResponse($body);
413
    }
414
415
416
    /**
417
     * @param ServerRequestInterface $request
418
     * @return ResponseInterface
419
     */
420 4
    public function forgotPasswordAction(ServerRequestInterface $request): ResponseInterface
421
    {
422 4
        $email = $request->getAttribute('email');
423 4
        $user = $this->userService->findUserByEmail($email);
424
425 4
        if (!$user) {
426 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
427
        }
428
429 3
        if ($user->getState()->getValue() == State::STATE_UNACTIVATED) {
430 1
            return new RedirectResponse('/user/resend-activation-mail/' . $email);
431
        }
432
433
        try {
434
435 2
            $link = $this->userService->generateEmailLink($user);
436 1
            $email = $user->getEmail();
437 1
            $token = $link->getToken();
438 1
            $env = $this->getSiteConfig()->getEnvironment();
439 1
            $mail = new EmailMessage();
440 1
            $mail->setTo($email);
441 1
            $mail->setSubject($this->getTranslator()->translate('email.forgotpass.subject', 'user') . $this->mailService->getSiteConfig()->getTitle() . '.');
442 1
            $mail->setTemplate('email.user::user_registration/reset_password');
443 1
            $mail->setViewData([
444 1
                'siteUrl' => $env->getSiteURL(),
445 1
                'logo' => $this->getSiteConfig()->getEmailLogo(),
446 1
                'address' => $this->getSiteConfig()->getAddress(),
447 1
                'resetLink' => '/user/reset-password/' . $email . '/' . $token,
448
            ]);
449 1
            $this->mailService->sendEmail($mail);
450
451
452 1
        } catch (Exception $e) {
453 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...
454
        }
455
456 2
        $body = $this->getView()->render('boneuser::forgot-password', ['logo' => $this->getLogo()]);
457
458 2
        return new HtmlResponse($body);
459
    }
460
461
462
    /**
463
     * @param ServerRequestInterface $request
464
     * @return ResponseInterface
465
     */
466 5
    public function resetPasswordAction(ServerRequestInterface $request): ResponseInterface
467
    {
468 5
        $email = $request->getAttribute('email');
469 5
        $token = $request->getAttribute('token');
470 5
        $form = new ResetPasswordForm('resetpass');
471 5
        $translator = $this->getTranslator();
472 5
        $params = [];
473 5
        $success = false;
474 5
        $user = $this->userService->findUserByEmail($email);
475
476 5
        if (!$user) {
477 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
478
        }
479
480
        try {
481 4
            $link = $this->userService->findEmailLink($email, $token);
482
483 2
            if ($request->getMethod() === 'POST') {
484
485 2
                $data = $request->getParsedBody();
486 2
                $form->populate($data);
487
488 2
                if ($form->isValid()) {
489 2
                    $data = $form->getValues();
490
491 2
                    if ($data['password'] === $data['confirm']) {
492 1
                        $this->userService->changePassword($user, $data['password']);
493 1
                        $this->userService->deleteEmailLink($link);
494 1
                        $message = [$translator->translate('email.resetpass.success', 'user'), 'success'];
495 1
                        $success = true;
496 1
                        $this->getSession()->set('user', $user->getId());
497
                    } else {
498 1
                        $message = [$translator->translate('email.resetpass.nomatch', 'user'), 'danger'];
499 2
                        $form = new ResetPasswordForm('resetpass');
500
                    }
501
                }
502
            }
503 2
        } catch (EmailLinkException $e) {
504 1
            $message = [$e->getMessage(), 'danger'];
505 1
        } catch (Exception $e) {
506 1
            throw $e;
507
        }
508
509 3
        if (isset($message)) {
510 3
            $params['message'] = $message;
511
        }
512
513 3
        $params['success'] = $success;
514 3
        $params['form'] = $form;
515 3
        $params['logo'] = $this->getLogo();
516 3
        $body = $this->getView()->render('boneuser::reset-pass', $params);
517
518 3
        return new HtmlResponse($body);
519
    }
520
521
    /**
522
     * @param ServerRequestInterface $request
523
     * @return ResponseInterface
524
     */
525 3
    public function changePasswordAction(ServerRequestInterface $request): ResponseInterface
526
    {
527 3
        $user = $request->getAttribute('user');
528 3
        $form = new ResetPasswordForm('resetpass');
529 3
        $translator = $this->getTranslator();
530 3
        $message = null;
531 3
        $success = false;
532
533 3
        if ($request->getMethod() === 'POST') {
534
535 3
            $data = $request->getParsedBody();
536 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 $data 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

536
            $form->populate(/** @scrutinizer ignore-type */ $data);
Loading history...
537
538 3
            if ($form->isValid()) {
539 2
                $data = $form->getValues();
540 2
                if ($data['password'] === $data['confirm']) {
541 1
                    $this->userService->changePassword($user, $data['password']);
542 1
                    $message = [Icon::CHECK_CIRCLE . ' ' . $translator->translate('email.resetpass.success', 'user'), 'success'];
543 1
                    $success = true;
544
                } else {
545 1
                    $message = [Icon::WARNING . ' ' . $translator->translate('email.resetpass.nomatch', 'user'), 'danger'];
546 2
                    $form = new ResetPasswordForm('resetpass');
547
                }
548
            } else {
549 1
                $message = [Icon::WARNING . ' There was a problem with your form.', 'danger'];
550
            }
551
        }
552
553 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...
554 3
        $params['form'] = $form;
555 3
        $params['logo'] = $this->getLogo();
556
557 3
        $body = $this->getView()->render('boneuser::change-pass', [
558 3
            'success' => $success,
559 3
            'form' => $form,
560 3
            'logo' => $this->getLogo(),
561 3
            'message' => $message
562
        ]);
563
564 3
        return new HtmlResponse($body);
565
    }
566
567
    /**
568
     * @param ServerRequestInterface $request
569
     * @return ResponseInterface
570
     */
571 4
    public function changeEmailAction(ServerRequestInterface $request): ResponseInterface
572
    {
573 4
        $user = $request->getAttribute('user');
574 4
        $form = new LoginForm('changeemail', $this->getTranslator());
575 4
        $form->getField('email')->setLabel('New email');
576 4
        $form->getField('submit')->setValue('Submit');
577 4
        $translator = $this->getTranslator();
578
        $params = [
579 4
            'form' => $form
580
        ];
581
582 4
        if ($request->getMethod() === 'POST') {
583
584 4
            $data = $request->getParsedBody();
585 4
            $form->populate($data);
586 4
            $message = null;
587
588 4
            if ($form->isValid()) {
589
590 4
                $newEmail = $form->getField('email')->getValue();
591 4
                $password = $form->getField('password')->getValue();
592
593 4
                $existing = $this->userService->findUserByEmail($newEmail);
594
595 4
                if ($existing) {
596 1
                    $message = [$translator->translate('email.changeemail.registered', 'user') . $this->getSiteConfig()->getTitle() . '.', 'danger'];
597
                } else {
598 3
                    if ($this->userService->checkPassword($user, $password)) {
599
600
                        try {
601
602 2
                            $link = $this->userService->generateEmailLink($user);
603 1
                            $email = $user->getEmail();
604 1
                            $token = $link->getToken();
605 1
                            $env = $this->getSiteConfig()->getEnvironment();
606 1
                            $mail = new EmailMessage();
607 1
                            $mail->setTo($email);
608 1
                            $mail->setSubject($translator->translate('email.changeemail.subject', 'user') . $this->mailService->getSiteConfig()->getTitle() . '.');
609 1
                            $mail->setTemplate('email.user::user_registration/change_email');
610 1
                            $mail->setViewData([
611 1
                                'siteUrl' => $env->getSiteURL(),
612 1
                                'logo' => $this->getSiteConfig()->getEmailLogo(),
613 1
                                'address' => $this->getSiteConfig()->getAddress(),
614 1
                                'resetLink' => '/user/reset-email/' . $email . '/' . $newEmail . '/' . $token,
615
                            ]);
616 1
                            $this->mailService->sendEmail($mail);
617 1
                            $message = [$translator->translate('email.changeemail.sent', 'user'), 'info'];
618 1
                            unset ($params['form']);
619
620 1
                        } catch (Exception $e) {
621 2
                            $message = [$translator->translate('email.changeemail.notsent', 'user') . $this->getSiteConfig()->getContactEmail() . '.', 'danger'];
622
                        }
623
624
                    } else {
625 1
                        $message = [$translator->translate('email.changeemail.wrongpass', 'user'), 'danger'];
626
                    }
627
                }
628
            }
629 4
            $params['message'] = $message;
630
        }
631 4
        $params['logo'] = $this->getLogo();
632
633 4
        $body = $this->getView()->render('boneuser::change-email', $params);
634
635 4
        return new LayoutResponse($body, 'layouts::admin');
636
    }
637
638
    /**
639
     * @param ServerRequestInterface $request
640
     * @return ResponseInterface
641
     */
642 1
    public function editProfileAction(ServerRequestInterface $request): ResponseInterface
643
    {
644 1
        $user = $request->getAttribute('user');
645 1
        $person = $user->getPerson();
646 1
        $image = $person->getImage();
647 1
        $form = new PersonForm('profile', $this->getTranslator());
648 1
        $array = $this->userService->getPersonSvc()->toArray($person);
649
650 1
        $form->populate($array);
651
652 1
        if ($request->getMethod() === 'POST') {
653 1
            $post = $request->getParsedBody();
654 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 $data 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

654
            $form->populate(/** @scrutinizer ignore-type */ $post);
Loading history...
655 1
            if ($form->isValid()) {
656 1
                $data = $form->getValues();
657 1
                $data['image'] = $image;
658 1
                $dateFormat = $this->getSiteConfig()->getAttribute('i18n')['date_format'];
659 1
                $data['dob'] = DateTime::createFromFormat($dateFormat, $data['dob']);
660 1
                $data['country'] = CountryFactory::generate($data['country']);
661 1
                $this->userService->getPersonSvc()->populateFromArray($person, $data);
662 1
                $this->userService->saveUser($user);
663
            }
664
        }
665
666 1
        $body = $this->getView()->render('boneuser::edit-profile', [
667 1
            'person' => $person,
668 1
            'form' => $form->render(),
669
        ]);
670
671 1
        return new LayoutResponse($body, $this->adminLayout);
672
    }
673
674
    /**
675
     * @param ServerRequestInterface $requestApiController
676
     * @return ResponseInterface
677
     */
678 2
    public function resetEmailAction(ServerRequestInterface $request): ResponseInterface
679
    {
680 2
        $email = $request->getAttribute('email');
681 2
        $newEmail = $request->getAttribute('new-email');
682 2
        $token = $request->getAttribute('token');
683 2
        $message = null;
684 2
        $translator = $this->getTranslator();
685
686
        try {
687
688 2
            $link = $this->userService->findEmailLink($email, $token);
689 1
            $user = $link->getUser();
690 1
            $user->setEmail($newEmail);
691 1
            $this->userService->saveUser($user);
692 1
            $this->userService->deleteEmailLink($link);
693 1
            $message = [$translator->translate('email.changeemail.success', 'user') . $newEmail . $translator->translate('email.changeemail.success2', 'user'), 'success'];
694 1
            SessionManager::set('user', $user->getId());
0 ignored issues
show
Bug Best Practice introduced by
The method Del\SessionManager::set() is not static, but was called statically. ( Ignorable by Annotation )

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

694
            SessionManager::/** @scrutinizer ignore-call */ 
695
                            set('user', $user->getId());
Loading history...
695
696 1
        } catch (EmailLinkException $e) {
697 1
            $message = [$e->getMessage(), 'danger'];
698
        }
699
700 2
        $body = $this->getView()->render('boneuser::reset-email', ['message' => $message, 'logo' => $this->getLogo()]);
701
702 2
        return new HtmlResponse($body);
703
    }
704
}
705