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

BoneUserController::editProfileAction()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 30
ccs 21
cts 21
cp 1
rs 9.584
cc 3
nc 3
nop 1
crap 3
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