Passed
Push — master ( e4b148...d70af7 )
by Derek Stephen
02:51
created

BoneUserController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 13
ccs 10
cts 10
cp 1
rs 9.9666
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 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
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;
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,
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
    }
88
89
    /**
90
     * @return string
91
     */
92 29
    public function getLogo(): string
93
    {
94 29
        if (!$this->logo) {
95 29
            $this->logo = $this->getSiteConfig()->getLogo();
96
        }
97
98 29
        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', [
113 1
            'logo' => $this->getLogo(),
114 1
            'canRegister' => $this->registrationEnabled
115
        ]
116
    );
117
118 1
        return new HtmlResponse($body);
119
    }
120
121
    /**
122
     * @param ServerRequestInterface $request
123
     * @return ResponseInterface
124
     * @throws UserException
125
     */
126 4
    public function registerAction(ServerRequestInterface $request): ResponseInterface
127
    {
128 4
        $form = new RegistrationForm('register', $this->getTranslator());
129 4
        $message = null;
130
131 4
        if ($request->getMethod() === 'POST') {
132
133 3
            $formData = $request->getParsedBody();
134 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

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

237
    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...
238
    {
239 1
        $form = new LoginForm('userlogin', $this->getTranslator());
240 1
        $this->initForm($form);
241 1
        $body = $this->getView()->render('boneuser::login', ['form' => $form, 'logo' => $this->getLogo()]);
242
243 1
        return new HtmlResponse($body);
244
    }
245
246
247
    /**
248
     * @param ServerRequestInterface $request
249
     * @return ResponseInterface
250
     */
251 5
    public function loginFormAction(ServerRequestInterface $request): ResponseInterface
252
    {
253 5
        $translator = $this->getTranslator();
254 5
        $form = new LoginForm('userlogin', $translator);
255 5
        $this->initForm($form);
256 5
        $post = $request->getParsedBody();
257 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

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

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

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

377
    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...
378
    {
379 1
        SessionManager::destroySession();
380 1
        \setcookie('resu', '', 1, '/');
381
382 1
        return new RedirectResponse(new Uri('/'));
383
    }
384
385
    /**
386
     * @param ServerRequestInterface $request
387
     * @return ResponseInterface
388
     */
389 4
    public function resendActivationEmailAction(ServerRequestInterface $request): ResponseInterface
390
    {
391 4
        $email = $request->getAttribute('email');
392 4
        $user = $this->userService->findUserByEmail($email);
393 4
        $message = [];
394 4
        $translator = $this->getTranslator();
395
396 4
        if (!$user) {
397 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
398
        }
399
400 3
        if ($user->getState()->getValue() == State::STATE_ACTIVATED) {
401 1
            $message = [UserException::USER_ACTIVATED, 'danger'];
402
        } else {
403
            try {
404 2
                $link = $this->userService->generateEmailLink($user);
405 1
                $mail = $this->mailService;
406
407 1
                $env = $mail->getSiteConfig()->getEnvironment();
408 1
                $email = $user->getEmail();
409 1
                $token = $link->getToken();
410
411 1
                $mail = new EmailMessage();
412 1
                $mail->setTo($user->getEmail());
413 1
                $mail->setSubject($translator->translate('email.user.register.thankswith', 'user') . ' ' . $this->mailService->getSiteConfig()->getTitle());
414 1
                $mail->setTemplate('email.user::user_registration/user_registration');
415 1
                $mail->setViewData([
416 1
                    'siteUrl' => $env->getSiteURL(),
417 1
                    'logo' => $this->getSiteConfig()->getEmailLogo(),
418 1
                    'address' => $this->getSiteConfig()->getAddress(),
419 1
                    'activationLink' => '/user/activate/' . $email . '/' . $token,
420
                ]);
421 1
                $this->mailService->sendEmail($mail);
422
423 1
            } catch (Exception $e) {
424 1
                $message = [$translator->translate('login.resendactivation.error', 'user')
425 1
                    . $this->getSiteConfig()->getContactEmail() . '', 'danger'];
426
            }
427
        }
428
429 3
        $body = $this->getView()->render('boneuser::resend-activation', [
430
            'message' => $message,
431 3
            'logo' => $this->getLogo(),
432
        ]);
433
434 3
        return new HtmlResponse($body);
435
    }
436
437
438
    /**
439
     * @param ServerRequestInterface $request
440
     * @return ResponseInterface
441
     */
442 4
    public function forgotPasswordAction(ServerRequestInterface $request): ResponseInterface
443
    {
444 4
        $email = $request->getAttribute('email');
445 4
        $user = $this->userService->findUserByEmail($email);
446
447 4
        if (!$user) {
448 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
449
        }
450
451 3
        if ($user->getState()->getValue() == State::STATE_UNACTIVATED) {
452 1
            return new RedirectResponse('/user/resend-activation-mail/' . $email);
453
        }
454
455
        try {
456 2
            $link = $this->userService->generateEmailLink($user);
457 1
            $email = $user->getEmail();
458 1
            $token = $link->getToken();
459 1
            $env = $this->getSiteConfig()->getEnvironment();
460 1
            $mail = new EmailMessage();
461 1
            $mail->setTo($email);
462 1
            $mail->setSubject($this->getTranslator()->translate('email.forgotpass.subject', 'user') . $this->mailService->getSiteConfig()->getTitle() . '.');
463 1
            $mail->setTemplate('email.user::user_registration/reset_password');
464 1
            $mail->setViewData([
465 1
                'siteUrl' => $env->getSiteURL(),
466 1
                'logo' => $this->getSiteConfig()->getEmailLogo(),
467 1
                'address' => $this->getSiteConfig()->getAddress(),
468 1
                'resetLink' => '/user/reset-password/' . $email . '/' . $token,
469
            ]);
470 1
            $this->mailService->sendEmail($mail);
471 1
        } catch (Exception $e) {
472 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...
473
        }
474
475 2
        $body = $this->getView()->render('boneuser::forgot-password', ['logo' => $this->getLogo()]);
476
477 2
        return new HtmlResponse($body);
478
    }
479
480
481
    /**
482
     * @param ServerRequestInterface $request
483
     * @return ResponseInterface
484
     */
485 5
    public function resetPasswordAction(ServerRequestInterface $request): ResponseInterface
486
    {
487 5
        $email = $request->getAttribute('email');
488 5
        $token = $request->getAttribute('token');
489 5
        $form = new ResetPasswordForm('resetpass');
490 5
        $translator = $this->getTranslator();
491 5
        $params = [];
492 5
        $success = false;
493 5
        $user = $this->userService->findUserByEmail($email);
494
495 5
        if (!$user) {
496 1
            throw new Exception(UserException::USER_NOT_FOUND, 404);
497
        }
498
499
        try {
500 4
            $link = $this->userService->findEmailLink($email, $token);
501
502 2
            if ($request->getMethod() === 'POST') {
503 2
                $data = $request->getParsedBody();
504 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 $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

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

670
            $form->populate(/** @scrutinizer ignore-type */ $post);
Loading history...
671
672 1
            if ($form->isValid()) {
673 1
                $data = $form->getValues();
674 1
                $data['image'] = $image;
675 1
                $dateFormat = $this->getSiteConfig()->getAttribute('i18n')['date_format'];
676 1
                $data['dob'] = DateTime::createFromFormat($dateFormat, $data['dob']);
677 1
                $data['country'] = CountryFactory::generate($data['country']);
678 1
                $this->userService->getPersonSvc()->populateFromArray($person, $data);
679 1
                $this->userService->saveUser($user);
680
            }
681
        }
682
683 1
        $body = $this->getView()->render('boneuser::edit-profile', [
684
            'person' => $person,
685 1
            'form' => $form->render(),
686
        ]);
687
688 1
        return new LayoutResponse($body, $this->adminLayout);
689
    }
690
691
    /**
692
     * @param ServerRequestInterface $requestApiController
693
     * @return ResponseInterface
694
     */
695 2
    public function resetEmailAction(ServerRequestInterface $request): ResponseInterface
696
    {
697 2
        $email = $request->getAttribute('email');
698 2
        $newEmail = $request->getAttribute('new-email');
699 2
        $token = $request->getAttribute('token');
700 2
        $translator = $this->getTranslator();
701
702
        try {
703 2
            $link = $this->userService->findEmailLink($email, $token);
704 1
            $user = $link->getUser();
705 1
            $user->setEmail($newEmail);
706 1
            $this->userService->saveUser($user);
707 1
            $this->userService->deleteEmailLink($link);
708 1
            $message = [$translator->translate('email.changeemail.success', 'user') . $newEmail . $translator->translate('email.changeemail.success2', 'user'), 'success'];
709 1
            SessionManager::getInstance()->set('user', $user->getId());
710 1
        } catch (EmailLinkException $e) {
711 1
            $message = [$e->getMessage(), 'danger'];
712
        }
713
714 2
        $body = $this->getView()->render('boneuser::reset-email', ['message' => $message, 'logo' => $this->getLogo()]);
715
716 2
        return new HtmlResponse($body);
717
    }
718
}
719