BoneUserController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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

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 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 DateTimeZone;
23
use Del\Entity\User;
24
use Del\Exception\EmailLinkException;
25
use Del\Exception\UserException;
26
use Del\Factory\CountryFactory;
27
use Del\Form\Field\Text\EmailAddress;
28
use Del\Icon;
29
use Del\Service\UserService;
30
use Del\SessionManager;
31
use Del\Value\User\State;
32
use Exception;
33
use Laminas\Diactoros\Response\RedirectResponse;
34
use Laminas\Diactoros\Uri;
35
use Psr\Http\Message\ResponseInterface;
36
use Psr\Http\Message\ServerRequestInterface;
37
38
class BoneUserController extends Controller implements SessionAwareInterface
39
{
40
    use HasSessionTrait;
41
    use HasSiteConfigTrait;
42
43
    private string $logo = '';
44
45 41
    public function __construct(
46
        private UserService $userService,
47
        private MailService $mailService,
48
        private string $loginRedirectRoute,
49
        private string $adminLayout,
50
        private PasetoService $pasetoService,
51
        private bool $registrationEnabled = true,
52
        private $profileRequired = false,
53
        private bool $rememberMeCookie = true
54
    ) {
55 41
    }
56
57
    /**
58
     * @return string
59
     */
60 29
    public function getLogo(): string
61
    {
62 29
        if ($this->logo === '') {
63 29
            $this->logo = $this->getSiteConfig()->getLogo();
64
        }
65
66 29
        return $this->logo;
67
    }
68
69
    /**
70
     * @param ServerRequestInterface $request
71
     * @return ResponseInterface $response
72
     * @throws \Exception
73
     */
74 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

74
    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...
75
    {
76 1
        if ($this->getSession()->get('user')) {
77 1
            return new RedirectResponse('/user/home');
78
        }
79
80 1
        $body = $this->getView()->render('boneuser::index', [
81 1
            'logo' => $this->getLogo(),
82 1
            'canRegister' => $this->registrationEnabled
83 1
        ]
84 1
    );
85
86 1
        return new HtmlResponse($body);
87
    }
88
89
    /**
90
     * @param ServerRequestInterface $request
91
     * @return ResponseInterface
92
     * @throws UserException
93
     */
94 4
    public function registerAction(ServerRequestInterface $request): ResponseInterface
95
    {
96 4
        $form = new RegistrationForm('register', $this->getTranslator());
97 4
        $message = null;
98
99 4
        if ($request->getMethod() === 'POST') {
100
101 3
            $formData = $request->getParsedBody();
102 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

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

205
    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...
206
    {
207 1
        $form = new LoginForm('userlogin', $this->getTranslator());
208 1
        $this->initForm($form);
209 1
        $body = $this->getView()->render('boneuser::login', ['form' => $form, 'logo' => $this->getLogo()]);
210
211 1
        return new HtmlResponse($body);
212
    }
213
214
215
    /**
216
     * @param ServerRequestInterface $request
217
     * @return ResponseInterface
218
     */
219 5
    public function loginFormAction(ServerRequestInterface $request): ResponseInterface
220
    {
221 5
        $translator = $this->getTranslator();
222 5
        $form = new LoginForm('userlogin', $translator);
223 5
        $this->initForm($form);
224 5
        $post = $request->getParsedBody();
225 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

225
        $form->populate(/** @scrutinizer ignore-type */ $post);
Loading history...
226 5
        $params = ['form' => $form];
227
228
        try {
229 5
            if ($form->isValid()) {
230 5
                $data = $form->getValues();
231 5
                $email = $data['email'];
232 5
                $pass = $data['password'];
233 5
                $userId = $this->userService->authenticate($email, $pass);
234 5
                $locale = $translator->getLocale();
235 5
                $session = $this->getSession();
236 5
                $session->set('user', $userId);
237 5
                $session->set('locale', $locale);
238 5
                $this->rememberMeCookie && isset($data['remember']) ? $this->setCookie((int)$data['remember'], $userId) : null;
239
240 5
                if ($route = $session->get('loginRedirectRoute')) {
241 5
                    $this->loginRedirectRoute = $route;
242 5
                    $session->unset('loginRedirectRoute');
243
                }
244
245 5
                $user = $this->userService->findUserById($userId);
246 1
                $user->setLastLogin(new DateTime());
247 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

247
                $this->userService->saveUser(/** @scrutinizer ignore-type */ $user);
Loading history...
248
249 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

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

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

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

521
            $form->populate(/** @scrutinizer ignore-type */ $data);
Loading history...
522
523 3
            if ($form->isValid()) {
524 2
                $data = $form->getValues();
525
526 2
                if ($data['password'] === $data['confirm']) {
527 1
                    $this->userService->changePassword($user, $data['password']);
528 1
                    $message = [Icon::CHECK_CIRCLE . ' ' . $translator->translate('email.resetpass.success', 'user'), 'success'];
529 1
                    $success = true;
530
                } else {
531 1
                    $message = [Icon::WARNING . ' ' . $translator->translate('email.resetpass.nomatch', 'user'), 'danger'];
532 1
                    $form = new ResetPasswordForm('resetpass');
533
                }
534
            } else {
535 1
                $message = [Icon::WARNING . ' There was a problem with your form.', 'danger'];
536
            }
537
        }
538
539 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...
540 3
        $params['form'] = $form;
541 3
        $params['logo'] = $this->getLogo();
542
543 3
        $body = $this->getView()->render('boneuser::change-pass', [
544 3
            'success' => $success,
545 3
            'form' => $form,
546 3
            'logo' => $this->getLogo(),
547 3
            'message' => $message
548 3
        ]);
549
550 3
        return new HtmlResponse($body);
551
    }
552
553
    /**
554
     * @param ServerRequestInterface $request
555
     * @return ResponseInterface
556
     */
557 4
    public function changeEmailAction(ServerRequestInterface $request): ResponseInterface
558
    {
559 4
        $user = $request->getAttribute('user');
560 4
        $form = new LoginForm('changeemail', $this->getTranslator());
561 4
        $form->getFields()->removeByName('remember');
562 4
        $form->getField('email')->setLabel('New email');
563 4
        $form->getField('submit')->setValue('Submit');
564 4
        $translator = $this->getTranslator();
565 4
        $params = [
566 4
            'form' => $form
567 4
        ];
568
569 4
        if ($request->getMethod() === 'POST') {
570 4
            $data = $request->getParsedBody();
571 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

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

639
            $form->populate(/** @scrutinizer ignore-type */ $post);
Loading history...
640
641 1
            if ($form->isValid()) {
642 1
                $data = $form->getValues();
643 1
                $data['image'] = $image;
644 1
                $data['dob'] = new DateTime($data['dob'], new DateTimeZone('UTC'));
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