ResetRequestController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 18
rs 10

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
2
3
/**
4
 * (c) FSi sp. z o.o. <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace FSi\Bundle\AdminSecurityBundle\Controller\PasswordReset;
13
14
use FSi\Bundle\AdminBundle\Message\FlashMessages;
15
use FSi\Bundle\AdminSecurityBundle\Event\AdminSecurityEvents;
16
use FSi\Bundle\AdminSecurityBundle\Event\ResetPasswordRequestEvent;
17
use FSi\Bundle\AdminSecurityBundle\Security\User\ResettablePasswordInterface;
18
use FSi\Bundle\AdminSecurityBundle\Security\User\UserRepositoryInterface;
19
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
20
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
21
use Symfony\Component\Form\FormFactoryInterface;
22
use Symfony\Component\Form\FormInterface;
23
use Symfony\Component\HttpFoundation\RedirectResponse;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpFoundation\Response;
26
use Symfony\Component\Routing\RouterInterface;
27
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
28
use Symfony\Component\Security\Core\User\UserInterface;
29
30
class ResetRequestController
31
{
32
    /**
33
     * @var EngineInterface
34
     */
35
    private $templating;
36
37
    /**
38
     * @var string
39
     */
40
    private $requestActionTemplate;
41
42
    /**
43
     * @var FormFactoryInterface
44
     */
45
    private $formFactory;
46
47
    /**
48
     * @var RouterInterface
49
     */
50
    private $router;
51
52
    /**
53
     * @var UserRepositoryInterface
54
     */
55
    private $userRepository;
56
57
    /**
58
     * @var EventDispatcherInterface
59
     */
60
    private $eventDispatcher;
61
62
    /**
63
     * @var FlashMessages
64
     */
65
    private $flashMessages;
66
67
    /**
68
     * @var string
69
     */
70
    private $formType;
71
72
    public function __construct(
73
        EngineInterface $templating,
74
        $requestActionTemplate,
75
        FormFactoryInterface $formFactory,
76
        RouterInterface $router,
77
        UserRepositoryInterface $userRepository,
78
        EventDispatcherInterface $eventDispatcher,
79
        FlashMessages $flashMessages,
80
        $formType
81
    ) {
82
        $this->templating = $templating;
83
        $this->requestActionTemplate = $requestActionTemplate;
84
        $this->formFactory = $formFactory;
85
        $this->router = $router;
86
        $this->userRepository = $userRepository;
87
        $this->eventDispatcher = $eventDispatcher;
88
        $this->flashMessages = $flashMessages;
89
        $this->formType = $formType;
90
    }
91
92
    public function requestAction(Request $request): Response
93
    {
94
        $form = $this->formFactory->create($this->formType);
95
96
        $form->handleRequest($request);
97
        if (!$form->isSubmitted() || !$form->isValid()) {
98
            return $this->templating->renderResponse($this->requestActionTemplate, ['form' => $form->createView()]);
99
        }
100
101
        $user = $this->getUser($form);
102
        $redirectResponse = $this->addFlashAndRedirect(
103
            'info',
104
            'admin.password_reset.request.mail_sent_if_correct'
105
        );
106
107
        if (!$this->isUserEligibleForResettingPassword($user)) {
108
            return $redirectResponse;
109
        }
110
111
        $this->eventDispatcher->dispatch(
112
            AdminSecurityEvents::RESET_PASSWORD_REQUEST,
0 ignored issues
show
Bug introduced by
FSi\Bundle\AdminSecurity...:RESET_PASSWORD_REQUEST of type string is incompatible with the type object expected by parameter $event of Symfony\Contracts\EventD...erInterface::dispatch(). ( Ignorable by Annotation )

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

112
            /** @scrutinizer ignore-type */ AdminSecurityEvents::RESET_PASSWORD_REQUEST,
Loading history...
113
            new ResetPasswordRequestEvent($user)
0 ignored issues
show
Bug introduced by
$user of type Symfony\Component\Securi...User\UserInterface|null is incompatible with the type FSi\Bundle\AdminSecurity...ttablePasswordInterface expected by parameter $user of FSi\Bundle\AdminSecurity...estEvent::__construct(). ( Ignorable by Annotation )

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

113
            new ResetPasswordRequestEvent(/** @scrutinizer ignore-type */ $user)
Loading history...
Unused Code introduced by
The call to Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with new FSi\Bundle\AdminSecu...wordRequestEvent($user). ( Ignorable by Annotation )

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

113
        $this->eventDispatcher->/** @scrutinizer ignore-call */ 
114
                                dispatch(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
114
        );
115
116
        return $redirectResponse;
117
    }
118
119
    private function addFlashAndRedirect(string $type, string $message): RedirectResponse
120
    {
121
        $this->flashMessages->{$type}($message, [], 'FSiAdminSecurity');
122
123
        return new RedirectResponse($this->router->generate('fsi_admin_security_user_login'));
124
    }
125
126
    private function getUser(FormInterface $form): ?UserInterface
127
    {
128
        return $this->userRepository->findUserByEmail($form->get('email')->getData());
129
    }
130
131
    private function isUserEligibleForResettingPassword($user): bool
132
    {
133
        if (!($user instanceof ResettablePasswordInterface)) {
134
            return false;
135
        }
136
137
        if (($user instanceof AdvancedUserInterface) && !$user->isEnabled()) {
138
            return false;
139
        }
140
141
        if ($this->hasNonExpiredPasswordResetToken($user)) {
142
            return false;
143
        }
144
145
        if (($user instanceof AdvancedUserInterface) && !$user->isAccountNonLocked()) {
146
            return false;
147
        }
148
149
        return true;
150
    }
151
152
    private function hasNonExpiredPasswordResetToken(ResettablePasswordInterface $user): bool
153
    {
154
        return $user->getPasswordResetToken() && $user->getPasswordResetToken()->isNonExpired();
155
    }
156
}
157