Completed
Push — master ( 947afa...ae5e03 )
by Jeroen
26s queued 14s
created

UsersController::deleteFormAction()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 30

Duplication

Lines 14
Ratio 46.67 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 14
loc 30
ccs 0
cts 23
cp 0
crap 12
rs 9.44
c 0
b 0
f 0
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 Wim Vandersmissen
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 Wim Vandersmissen
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 Danny van Wijk
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
     * @return array
0 ignored issues
show
Documentation introduced by Wim Vandersmissen
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...
133
     *
134
     * @throws AccessDeniedException
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 Danny van Wijk
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 Request $request
218
     * @param int     $id
219
     *
220
     * @Route("/{id}/delete", requirements={"id" = "\d+"}, name="KunstmaanUserManagementBundle_settings_users_delete", methods={"POST"})
221
     *
222
     * @return array
0 ignored issues
show
Documentation introduced by Kevin Jossart
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...
223
     *
224
     * @throws AccessDeniedException
225
     *
226
     * @deprecated this method is deprecated since KunstmaanUserManagementBundle 5.6 and will be removed in KunstmaanUserManagementBundle 6.0
227
     */
228
    public function deleteAction(Request $request, $id)
229
    {
230
        @trigger_error('Using the deleteAction method from the UsersController is deprecated since KunstmaanUserManagementBundle 5.6 and will be replaced by the method deleteFormAction in KunstmaanUserManagementBundle 6.0. Use the correct method instead.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by Kevin Jossart
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
231
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
232
233
        /* @var EntityManager $em */
234
        $em = $this->getDoctrine()->getManager();
235
        /* @var UserInterface $user */
236
        $user = $em->getRepository($this->container->getParameter('fos_user.model.user.class'))->find($id);
237 View Code Duplication
        if (!\is_null($user)) {
0 ignored issues
show
Duplication introduced by Wim Vandersmissen
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...
238
            $userEvent = new UserEvent($user, $request);
239
            $this->container->get('event_dispatcher')->dispatch(UserEvents::USER_DELETE_INITIALIZE, $userEvent);
240
241
            $em->remove($user);
242
            $em->flush();
243
244
            $this->addFlash(
245
                FlashTypes::SUCCESS,
246
                $this->container->get('translator')->trans('kuma_user.users.delete.flash.success.%username%', [
247
                    '%username%' => $user->getUsername(),
248
                ])
249
            );
250
        }
251
252
        return new RedirectResponse($this->generateUrl('KunstmaanUserManagementBundle_settings_users'));
253
    }
254
255
    /**
256
     * @Route("/form-delete/{id}", requirements={"id" = "\d+"}, name="KunstmaanUserManagementBundle_settings_users_form_delete", methods={"POST"})
257
     */
258
    public function deleteFormAction(Request $request, $id)
259
    {
260
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
261
262
        $submittedToken = $request->request->get('token');
263
        if (!$this->isCsrfTokenValid('delete-user', $submittedToken)) {
264
            return new RedirectResponse($this->generateUrl('KunstmaanUserManagementBundle_settings_users'));
265
        }
266
267
        /* @var EntityManager $em */
268
        $em = $this->getDoctrine()->getManager();
269
        /* @var UserInterface $user */
270
        $user = $em->getRepository($this->container->getParameter('fos_user.model.user.class'))->find($id);
271 View Code Duplication
        if (!\is_null($user)) {
0 ignored issues
show
Duplication introduced by Kevin Jossart
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...
272
            $userEvent = new UserEvent($user, $request);
273
            $this->container->get('event_dispatcher')->dispatch(UserEvents::USER_DELETE_INITIALIZE, $userEvent);
274
275
            $em->remove($user);
276
            $em->flush();
277
278
            $this->addFlash(
279
                FlashTypes::SUCCESS,
280
                $this->container->get('translator')->trans('kuma_user.users.delete.flash.success.%username%', [
281
                    '%username%' => $user->getUsername(),
282
                ])
283
            );
284
        }
285
286
        return new RedirectResponse($this->generateUrl('KunstmaanUserManagementBundle_settings_users'));
287
    }
288
289
    /**
290
     * @return \Symfony\Component\HttpFoundation\Response
0 ignored issues
show
Documentation introduced by Wim Vandersmissen
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...
291
     */
292
    public function changePasswordAction()
293
    {
294
        // Redirect to current user edit route...
295
        return new RedirectResponse(
296
            $this->generateUrl(
297
                'KunstmaanUserManagementBundle_settings_users_edit',
298
                [
299
                    'id' => $this->container->get('security.token_storage')->getToken()->getUser()->getId(),
300
                ]
301
            )
302
        );
303
    }
304
}
305