Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

UsersController   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 241
Duplicated Lines 14.11 %

Coupling/Cohesion

Components 1
Dependencies 14

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 14
dl 34
loc 241
ccs 0
cts 144
cp 0
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A changePasswordAction() 0 12 1
A listAction() 0 22 2
A getUserClassInstance() 0 6 1
B addAction() 15 44 5
C editAction() 19 77 9
A deleteAction() 0 25 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Kunstmaan\UserManagementBundle\Controller;
4
5
use Doctrine\ORM\EntityManager;
6
use FOS\UserBundle\Event\UserEvent;
7
use FOS\UserBundle\Model\UserInterface;
8
use Kunstmaan\AdminBundle\Controller\BaseSettingsController;
9
use Kunstmaan\AdminBundle\Entity\BaseUser;
10
use Kunstmaan\AdminBundle\Event\AdaptSimpleFormEvent;
11
use Kunstmaan\AdminBundle\Event\Events;
12
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
13
use Kunstmaan\AdminBundle\Form\RoleDependentUserFormInterface;
14
use Kunstmaan\AdminListBundle\AdminList\AdminList;
15
use Kunstmaan\UserManagementBundle\Event\UserEvents;
16
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
17
use Symfony\Component\HttpFoundation\RedirectResponse;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
20
use Symfony\Component\Routing\Annotation\Route;
21
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
22
23
/**
24
 * Settings controller handling everything related to creating, editing, deleting and listing users in an admin list
25
 */
26
class UsersController extends BaseSettingsController
27
{
28
    /**
29
     * List users
30
     *
31
     * @Route("/", name="KunstmaanUserManagementBundle_settings_users")
32
     * @Template("@KunstmaanAdminList/Default/list.html.twig")
33
     *
34
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,AdminList>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
35
     */
36
    public function listAction(Request $request)
37
    {
38
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
39
40
        $em = $this->getDoctrine()->getManager();
41
        $configuratorClassName = '';
42
        if ($this->container->hasParameter('kunstmaan_user_management.user_admin_list_configurator.class')) {
43
            $configuratorClassName = $this->container->getParameter(
44
                'kunstmaan_user_management.user_admin_list_configurator.class'
45
            );
46
        }
47
48
        $configurator = new $configuratorClassName($em);
49
50
        /* @var AdminList $adminList */
51
        $adminList = $this->container->get('kunstmaan_adminlist.factory')->createList($configurator);
52
        $adminList->bindRequest($request);
53
54
        return [
55
            'adminlist' => $adminList,
56
        ];
57
    }
58
59
    /**
60
     * Get an instance of the admin user class.
61
     *
62
     * @return BaseUser
63
     */
64
    private function getUserClassInstance()
65
    {
66
        $userClassName = $this->container->getParameter('fos_user.model.user.class');
67
68
        return new $userClassName();
69
    }
70
71
    /**
72
     * Add a user
73
     *
74
     * @Route("/add", name="KunstmaanUserManagementBundle_settings_users_add", methods={"GET", "POST"})
75
     * @Template("@KunstmaanUserManagement/Users/add.html.twig")
76
     *
77
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be RedirectResponse|array<s...omponent\Form\FormView>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
78
     */
79
    public function addAction(Request $request)
80
    {
81
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
82
83
        $user = $this->getUserClassInstance();
84
85
        $options = ['password_required' => true, 'langs' => $this->container->getParameter('kunstmaan_admin.admin_locales'), 'validation_groups' => ['Registration'], 'data_class' => \get_class($user)];
86
        $formTypeClassName = $user->getFormTypeClass();
87
        $formType = new $formTypeClassName();
88
89
        if ($formType instanceof RoleDependentUserFormInterface) {
90
            // to edit groups and enabled the current user should have ROLE_SUPER_ADMIN
91
            $options['can_edit_all_fields'] = $this->isGranted('ROLE_SUPER_ADMIN');
92
        }
93
94
        $form = $this->createForm(
95
            $formTypeClassName,
96
            $user,
97
            $options
98
        );
99
100
        if ($request->isMethod('POST')) {
101
            $form->handleRequest($request);
102 View Code Duplication
            if ($form->isSubmitted() && $form->isValid()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
                $user->setPasswordChanged(true);
104
                /* @var UserManager $userManager */
105
                $userManager = $this->container->get('fos_user.user_manager');
106
                $userManager->updateUser($user, true);
107
108
                $this->addFlash(
109
                    FlashTypes::SUCCESS,
110
                    $this->container->get('translator')->trans('kuma_user.users.add.flash.success.%username%', [
111
                        '%username%' => $user->getUsername(),
112
                    ])
113
                );
114
115
                return new RedirectResponse($this->generateUrl('KunstmaanUserManagementBundle_settings_users'));
116
            }
117
        }
118
119
        return [
120
            'form' => $form->createView(),
121
        ];
122
    }
123
124
    /**
125
     * Edit a user
126
     *
127
     * @param int $id
128
     *
129
     * @Route("/{id}/edit", requirements={"id" = "\d+"}, name="KunstmaanUserManagementBundle_settings_users_edit", methods={"GET", "POST"})
130
     * @Template("@KunstmaanUserManagement/Users/edit.html.twig")
131
     *
132
     * @throws AccessDeniedException
133
     *
134
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be RedirectResponse|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
135
     */
136
    public function editAction(Request $request, $id)
137
    {
138
        // The logged in user should be able to change his own password/username/email and not for other users
139
        if ($id == $this->container->get('security.token_storage')->getToken()->getUser()->getId()) {
140
            $requiredRole = 'ROLE_ADMIN';
141
        } else {
142
            $requiredRole = 'ROLE_SUPER_ADMIN';
143
        }
144
        $this->denyAccessUnlessGranted($requiredRole);
145
146
        /* @var EntityManager $em */
147
        $em = $this->getDoctrine()->getManager();
148
149
        /** @var UserInterface $user */
150
        $user = $em->getRepository($this->container->getParameter('fos_user.model.user.class'))->find($id);
151
        if ($user === null) {
152
            throw new NotFoundHttpException(sprintf('User with ID %s not found', $id));
153
        }
154
155
        $userEvent = new UserEvent($user, $request);
156
        $this->container->get('event_dispatcher')->dispatch(UserEvents::USER_EDIT_INITIALIZE, $userEvent);
157
158
        $options = ['password_required' => false, 'langs' => $this->container->getParameter('kunstmaan_admin.admin_locales'), 'data_class' => \get_class($user)];
159
        $formFqn = $user->getFormTypeClass();
160
        $formType = new $formFqn();
161
162
        if ($formType instanceof RoleDependentUserFormInterface) {
163
            // to edit groups and enabled the current user should have ROLE_SUPER_ADMIN
164
            $options['can_edit_all_fields'] = $this->isGranted('ROLE_SUPER_ADMIN');
165
        }
166
167
        $event = new AdaptSimpleFormEvent($request, $formFqn, $user, $options);
168
        $event = $this->container->get('event_dispatcher')->dispatch(Events::ADAPT_SIMPLE_FORM, $event);
169
        $tabPane = $event->getTabPane();
170
171
        $form = $this->createForm($formFqn, $user, $options);
172
173
        if ($request->isMethod('POST')) {
174
            if ($tabPane) {
175
                $tabPane->bindRequest($request);
176
                $form = $tabPane->getForm();
177
            } else {
178
                $form->handleRequest($request);
179
            }
180
181 View Code Duplication
            if ($form->isSubmitted() && $form->isValid()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
182
                /* @var UserManager $userManager */
183
                $userManager = $this->container->get('fos_user.user_manager');
184
                $userManager->updateUser($user, true);
185
186
                $this->addFlash(
187
                    FlashTypes::SUCCESS,
188
                    $this->container->get('translator')->trans('kuma_user.users.edit.flash.success.%username%', [
189
                        '%username%' => $user->getUsername(),
190
                    ])
191
                );
192
193
                return new RedirectResponse(
194
                    $this->generateUrl(
195
                        'KunstmaanUserManagementBundle_settings_users_edit',
196
                        ['id' => $id]
197
                    )
198
                );
199
            }
200
        }
201
202
        $params = [
203
            'form' => $form->createView(),
204
            'user' => $user,
205
        ];
206
207
        if ($tabPane) {
208
            $params = array_merge($params, ['tabPane' => $tabPane]);
209
        }
210
211
        return $params;
212
    }
213
214
    /**
215
     * Delete a user
216
     *
217
     * @param int $id
218
     *
219
     * @Route("/{id}/delete", requirements={"id" = "\d+"}, name="KunstmaanUserManagementBundle_settings_users_delete", methods={"POST"})
220
     *
221
     * @throws AccessDeniedException
222
     *
223
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be RedirectResponse?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
224
     */
225
    public function deleteAction(Request $request, $id)
226
    {
227
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
228
229
        /* @var EntityManager $em */
230
        $em = $this->getDoctrine()->getManager();
231
        /* @var UserInterface $user */
232
        $user = $em->getRepository($this->container->getParameter('fos_user.model.user.class'))->find($id);
233
        if (!\is_null($user)) {
234
            $userEvent = new UserEvent($user, $request);
235
            $this->container->get('event_dispatcher')->dispatch(UserEvents::USER_DELETE_INITIALIZE, $userEvent);
236
237
            $em->remove($user);
238
            $em->flush();
239
240
            $this->addFlash(
241
                FlashTypes::SUCCESS,
242
                $this->container->get('translator')->trans('kuma_user.users.delete.flash.success.%username%', [
243
                    '%username%' => $user->getUsername(),
244
                ])
245
            );
246
        }
247
248
        return new RedirectResponse($this->generateUrl('KunstmaanUserManagementBundle_settings_users'));
249
    }
250
251
    /**
252
     * @return \Symfony\Component\HttpFoundation\Response
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use RedirectResponse.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
253
     */
254
    public function changePasswordAction()
255
    {
256
        // Redirect to current user edit route...
257
        return new RedirectResponse(
258
            $this->generateUrl(
259
                'KunstmaanUserManagementBundle_settings_users_edit',
260
                [
261
                    'id' => $this->container->get('security.token_storage')->getToken()->getUser()->getId(),
262
                ]
263
            )
264
        );
265
    }
266
}
267