ActivationController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 9
dl 0
loc 20
rs 9.9666
c 0
b 0
f 0

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\Activation;
13
14
use FSi\Bundle\AdminBundle\Message\FlashMessages;
15
use FSi\Bundle\AdminSecurityBundle\Event\ActivationEvent;
16
use FSi\Bundle\AdminSecurityBundle\Event\AdminSecurityEvents;
17
use FSi\Bundle\AdminSecurityBundle\Event\ChangePasswordEvent;
18
use FSi\Bundle\AdminSecurityBundle\Security\User\ActivableInterface;
19
use FSi\Bundle\AdminSecurityBundle\Security\User\EnforceablePasswordChangeInterface;
20
use FSi\Bundle\AdminSecurityBundle\Security\User\UserRepositoryInterface;
21
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
22
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23
use Symfony\Component\Form\FormFactoryInterface;
24
use Symfony\Component\HttpFoundation\RedirectResponse;
25
use Symfony\Component\HttpFoundation\Request;
26
use Symfony\Component\HttpFoundation\Response;
27
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
28
use Symfony\Component\Routing\RouterInterface;
29
30
class ActivationController
31
{
32
    /**
33
     * @var EngineInterface
34
     */
35
    private $templating;
36
37
    /**
38
     * @var string
39
     */
40
    private $changePasswordActionTemplate;
41
42
    /**
43
     * @var UserRepositoryInterface
44
     */
45
    private $userRepository;
46
47
    /**
48
     * @var RouterInterface
49
     */
50
    private $router;
51
52
    /**
53
     * @var FormFactoryInterface
54
     */
55
    private $formFactory;
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 $changePasswordFormType;
71
72
    /**
73
     * @var array
74
     */
75
    private $changePasswordFormValidationGroups;
76
77
    public function __construct(
78
        EngineInterface $templating,
79
        $changePasswordActionTemplate,
80
        UserRepositoryInterface $userRepository,
81
        RouterInterface $router,
82
        FormFactoryInterface $formFactory,
83
        EventDispatcherInterface $eventDispatcher,
84
        FlashMessages $flashMessages,
85
        string $changePasswordFormType,
86
        array $changePasswordFormValidationGroups
87
    ) {
88
        $this->templating = $templating;
89
        $this->changePasswordActionTemplate = $changePasswordActionTemplate;
90
        $this->userRepository = $userRepository;
91
        $this->router = $router;
92
        $this->formFactory = $formFactory;
93
        $this->eventDispatcher = $eventDispatcher;
94
        $this->flashMessages = $flashMessages;
95
        $this->changePasswordFormType = $changePasswordFormType;
96
        $this->changePasswordFormValidationGroups = $changePasswordFormValidationGroups;
97
    }
98
99
    public function activateAction(string $token): Response
100
    {
101
        $user = $this->tryFindUserByActivationToken($token);
102
103
        if ($this->isUserEnforcedToChangePassword($user)) {
104
            $this->flashMessages->info(
105
                'admin.activation.message.change_password',
106
                [],
107
                'FSiAdminSecurity'
108
            );
109
110
            return new RedirectResponse(
111
                $this->router->generate('fsi_admin_activation_change_password', ['token' => $token])
112
            );
113
        } else {
114
            $this->eventDispatcher->dispatch(
115
                AdminSecurityEvents::ACTIVATION,
0 ignored issues
show
Bug introduced by
FSi\Bundle\AdminSecurity...urityEvents::ACTIVATION 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

115
                /** @scrutinizer ignore-type */ AdminSecurityEvents::ACTIVATION,
Loading history...
116
                new ActivationEvent($user)
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with new FSi\Bundle\AdminSecu...\ActivationEvent($user). ( Ignorable by Annotation )

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

116
            $this->eventDispatcher->/** @scrutinizer ignore-call */ 
117
                                    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...
117
            );
118
119
            return $this->addFlashAndRedirect('success', 'admin.activation.message.success');
120
        }
121
    }
122
123
    public function changePasswordAction(Request $request, string $token): Response
124
    {
125
        $user = $this->tryFindUserByActivationToken($token);
126
127
        if (!$this->isUserEnforcedToChangePassword($user)) {
128
            throw new NotFoundHttpException();
129
        }
130
131
        $form = $this->formFactory->create(
132
            $this->changePasswordFormType,
133
            $user,
134
            ['validation_groups' => $this->changePasswordFormValidationGroups]
135
        );
136
137
        if ($form->handleRequest($request)->isSubmitted() && $form->isValid()) {
138
            $this->eventDispatcher->dispatch(
139
                AdminSecurityEvents::ACTIVATION,
0 ignored issues
show
Bug introduced by
FSi\Bundle\AdminSecurity...urityEvents::ACTIVATION 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

139
                /** @scrutinizer ignore-type */ AdminSecurityEvents::ACTIVATION,
Loading history...
140
                new ActivationEvent($user)
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with new FSi\Bundle\AdminSecu...\ActivationEvent($user). ( Ignorable by Annotation )

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

140
            $this->eventDispatcher->/** @scrutinizer ignore-call */ 
141
                                    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...
141
            );
142
143
            $this->eventDispatcher->dispatch(
144
                AdminSecurityEvents::CHANGE_PASSWORD,
145
                new ChangePasswordEvent($user)
146
            );
147
148
            return $this->addFlashAndRedirect('success', 'admin.activation.message.change_password_success');
149
        }
150
151
        return $this->templating->renderResponse(
152
            $this->changePasswordActionTemplate,
153
            ['form' => $form->createView()]
154
        );
155
    }
156
157
    private function tryFindUserByActivationToken(string $token): ActivableInterface
158
    {
159
        $user = $this->userRepository->findUserByActivationToken($token);
160
161
        if (null === $user) {
162
            throw new NotFoundHttpException();
163
        }
164
165
        if ($user->isEnabled()) {
166
            throw new NotFoundHttpException();
167
        }
168
169
        if (!$user->getActivationToken()->isNonExpired()) {
170
            throw new NotFoundHttpException();
171
        }
172
173
        return $user;
174
    }
175
176
    private function addFlashAndRedirect(string $type,string $message): RedirectResponse
177
    {
178
        $this->flashMessages->{$type}($message, [], 'FSiAdminSecurity');
179
180
        return new RedirectResponse($this->router->generate('fsi_admin_security_user_login'));
181
    }
182
183
    private function isUserEnforcedToChangePassword(ActivableInterface $user): bool
184
    {
185
        return ($user instanceof EnforceablePasswordChangeInterface) && $user->isForcedToChangePassword();
186
    }
187
}
188