Completed
Push — master ( 8fc13e...c19aa3 )
by Axel
06:21
created

UserAdministrationController::createAction()   F

Complexity

Conditions 18
Paths 262

Size

Total Lines 84
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 56
nc 262
nop 8
dl 0
loc 84
rs 3.2583
c 1
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\ZAuthModule\Controller;
15
16
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
17
use Symfony\Component\HttpFoundation\RedirectResponse;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\Routing\Annotation\Route;
21
use Symfony\Component\Routing\RouterInterface;
22
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
23
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
24
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
25
use Translation\Extractor\Annotation\Desc;
26
use Zikula\Bundle\CoreBundle\Controller\AbstractController;
27
use Zikula\Bundle\CoreBundle\Event\GenericEvent;
28
use Zikula\Bundle\CoreBundle\Response\PlainResponse;
29
use Zikula\Bundle\HookBundle\Dispatcher\HookDispatcherInterface;
30
use Zikula\Bundle\HookBundle\Hook\ProcessHook;
31
use Zikula\Bundle\HookBundle\Hook\ValidationHook;
32
use Zikula\Bundle\HookBundle\Hook\ValidationProviders;
33
use Zikula\Component\SortableColumns\Column;
34
use Zikula\Component\SortableColumns\SortableColumns;
35
use Zikula\ExtensionsModule\Api\ApiInterface\VariableApiInterface;
36
use Zikula\GroupsModule\Entity\GroupEntity;
37
use Zikula\PermissionsModule\Annotation\PermissionCheck;
38
use Zikula\ThemeModule\Engine\Annotation\Theme;
39
use Zikula\UsersModule\Api\ApiInterface\CurrentUserApiInterface;
40
use Zikula\UsersModule\Collector\AuthenticationMethodCollector;
41
use Zikula\UsersModule\Constant as UsersConstant;
42
use Zikula\UsersModule\Entity\RepositoryInterface\UserRepositoryInterface;
43
use Zikula\UsersModule\Entity\UserEntity;
44
use Zikula\UsersModule\Event\UserFormAwareEvent;
45
use Zikula\UsersModule\Event\UserFormDataEvent;
46
use Zikula\UsersModule\Helper\MailHelper as UsersMailHelper;
47
use Zikula\UsersModule\Helper\RegistrationHelper;
48
use Zikula\UsersModule\HookSubscriber\UserManagementUiHooksSubscriber;
49
use Zikula\UsersModule\RegistrationEvents;
50
use Zikula\UsersModule\UserEvents;
51
use Zikula\ZAuthModule\Entity\AuthenticationMappingEntity;
52
use Zikula\ZAuthModule\Entity\RepositoryInterface\AuthenticationMappingRepositoryInterface;
53
use Zikula\ZAuthModule\Form\Type\AdminCreatedUserType;
54
use Zikula\ZAuthModule\Form\Type\AdminModifyUserType;
55
use Zikula\ZAuthModule\Form\Type\BatchForcePasswordChangeType;
56
use Zikula\ZAuthModule\Form\Type\SendVerificationConfirmationType;
57
use Zikula\ZAuthModule\Form\Type\TogglePasswordConfirmationType;
58
use Zikula\ZAuthModule\Helper\AdministrationActionsHelper;
59
use Zikula\ZAuthModule\Helper\LostPasswordVerificationHelper;
60
use Zikula\ZAuthModule\Helper\MailHelper;
61
use Zikula\ZAuthModule\Helper\RegistrationVerificationHelper;
62
use Zikula\ZAuthModule\ZAuthConstant;
63
64
/**
65
 * Class UserAdministrationController
66
 *
67
 * @Route("/admin")
68
 */
69
class UserAdministrationController extends AbstractController
70
{
71
    /**
72
     * @Route("/list/{sort}/{sortdir}/{letter}/{startnum}")
73
     * @PermissionCheck("moderate")
74
     * @Theme("admin")
75
     * @Template("@ZikulaZAuthModule/UserAdministration/list.html.twig")
76
     */
77
    public function listAction(
78
        Request $request,
79
        AuthenticationMappingRepositoryInterface $authenticationMappingRepository,
80
        RouterInterface $router,
81
        AdministrationActionsHelper $actionsHelper,
82
        string $sort = 'uid',
83
        string $sortdir = 'DESC',
84
        string $letter = 'all',
85
        int $startnum = 0
86
    ): array {
87
        $startnum = $startnum > 0 ? $startnum - 1 : 0;
88
89
        $sortableColumns = new SortableColumns($router, 'zikulazauthmodule_useradministration_list', 'sort', 'sortdir');
90
        $sortableColumns->addColumns([new Column('uname'), new Column('uid')]);
91
        $sortableColumns->setOrderByFromRequest($request);
92
        $sortableColumns->setAdditionalUrlParameters([
93
            'letter' => $letter,
94
            'startnum' => $startnum
95
        ]);
96
97
        $filter = [];
98
        if (!empty($letter) && 'all' !== $letter) {
99
            $filter['uname'] = ['operator' => 'like', 'operand' => "${letter}%"];
100
        }
101
        $limit = 25;
102
103
        $mappings = $authenticationMappingRepository->query($filter, [$sort => $sortdir], $limit, $startnum);
104
105
        return [
106
            'sort' => $sortableColumns->generateSortableColumns(),
107
            'pager' => [
108
                'count' => $mappings->count(),
109
                'limit' => $limit
110
            ],
111
            'actionsHelper' => $actionsHelper,
112
            'mappings' => $mappings
113
        ];
114
    }
115
116
    /**
117
     * Called from UsersModule/Resources/public/js/Zikula.Users.Admin.View.js
118
     * to populate a username search
119
     *
120
     * @Route("/getusersbyfragmentastable", methods = {"POST"}, options={"expose"=true})
121
     */
122
    public function getUsersByFragmentAsTableAction(
123
        Request $request,
124
        AuthenticationMappingRepositoryInterface $authenticationMappingRepository,
125
        AdministrationActionsHelper $actionsHelper
126
    ): Response {
127
        if (!$this->hasPermission('ZikulaZAuthModule', '::', ACCESS_MODERATE)) {
128
            return new PlainResponse('');
129
        }
130
        $fragment = $request->request->get('fragment');
131
        $filter = [
132
            'uname' => ['operator' => 'like', 'operand' => $fragment . '%']
133
        ];
134
        $mappings = $authenticationMappingRepository->query($filter);
135
136
        return $this->render('@ZikulaZAuthModule/UserAdministration/userlist.html.twig', [
137
            'mappings' => $mappings,
138
            'actionsHelper' => $actionsHelper
139
        ], new PlainResponse());
140
    }
141
142
    /**
143
     * @Route("/user/create")
144
     * @PermissionCheck("admin")
145
     * @Theme("admin")
146
     * @Template("@ZikulaZAuthModule/UserAdministration/create.html.twig")
147
     *
148
     * @return array|RedirectResponse
149
     */
150
    public function createAction(
151
        Request $request,
152
        VariableApiInterface $variableApi,
153
        AuthenticationMethodCollector $authenticationMethodCollector,
154
        UserRepositoryInterface $userRepository,
155
        RegistrationHelper $registrationHelper,
156
        UsersMailHelper $mailHelper,
157
        EventDispatcherInterface $eventDispatcher,
158
        HookDispatcherInterface $hookDispatcher
159
    ) {
160
        $mapping = new AuthenticationMappingEntity();
161
        $form = $this->createForm(AdminCreatedUserType::class, $mapping, [
162
            'minimumPasswordLength' => $variableApi->get('ZikulaZAuthModule', ZAuthConstant::MODVAR_PASSWORD_MINIMUM_LENGTH, ZAuthConstant::PASSWORD_MINIMUM_LENGTH)
163
        ]);
164
        $formEvent = new UserFormAwareEvent($form);
165
        $eventDispatcher->dispatch($formEvent, UserEvents::EDIT_FORM);
166
        $form->handleRequest($request);
167
168
        $hook = new ValidationHook(new ValidationProviders());
169
        $hookDispatcher->dispatch(UserManagementUiHooksSubscriber::EDIT_VALIDATE, $hook);
170
        $validators = $hook->getValidators();
171
172
        if ($form->isSubmitted() && $form->isValid() && !$validators->hasErrors()) {
173
            if ($form->get('submit')->isClicked()) {
0 ignored issues
show
Bug introduced by
The method isClicked() does not exist on Symfony\Component\Form\FormInterface. It seems like you code against a sub-type of Symfony\Component\Form\FormInterface such as Symfony\Component\Form\SubmitButton. ( Ignorable by Annotation )

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

173
            if ($form->get('submit')->/** @scrutinizer ignore-call */ isClicked()) {
Loading history...
174
                $mapping = $form->getData();
175
                $passToSend = $form['sendpass']->getData() ? $mapping->getPass() : '';
176
                $authMethodName = (ZAuthConstant::AUTHENTICATION_METHOD_EITHER === $mapping->getMethod()) ? ZAuthConstant::AUTHENTICATION_METHOD_UNAME : $mapping->getMethod();
177
                $authMethod = $authenticationMethodCollector->get($authMethodName);
178
179
                if ($request->hasSession() && ($session = $request->getSession())) {
180
                    $session->set(ZAuthConstant::MODVAR_EMAIL_VERIFICATION_REQUIRED, ($form['usermustverify']->getData() ? 'Y' : 'N'));
181
                }
182
183
                $userData = $mapping->getUserEntityData();
184
                if (null === $userData['uid']) {
185
                    unset($userData['uid']);
186
                }
187
                $user = new UserEntity();
188
                $user->merge($userData);
189
                $user->setAttribute(UsersConstant::AUTHENTICATION_METHOD_ATTRIBUTE_KEY, $mapping->getMethod());
190
                $registrationHelper->registerNewUser($user);
191
                if (UsersConstant::ACTIVATED_PENDING_REG === $user->getActivated()) {
192
                    $notificationErrors = $mailHelper->createAndSendRegistrationMail($user, $form['usernotification']->getData(), $form['adminnotification']->getData(), $passToSend);
193
                } else {
194
                    $notificationErrors = $mailHelper->createAndSendUserMail($user, $form['usernotification']->getData(), $form['adminnotification']->getData(), $passToSend);
195
                }
196
                if (!empty($notificationErrors)) {
197
                    $this->addFlash('error', 'Errors creating user!');
198
                    $this->addFlash('error', implode('<br />', $notificationErrors));
199
                }
200
                $userId = $user->getUid();
201
                $mapping->setUid($user->getUid());
202
                $mapping->setVerifiedEmail(!$form['usermustverify']->getData());
203
                if (!$authMethod->register($mapping->toArray())) {
204
                    $this->addFlash('error', 'The create process failed for an unknown reason.');
205
                    $userRepository->removeAndFlush($user);
206
                    $eventDispatcher->dispatch(new GenericEvent($userId), RegistrationEvents::DELETE_REGISTRATION);
207
208
                    return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
209
                }
210
                $formDataEvent = new UserFormDataEvent($user, $form);
211
                $eventDispatcher->dispatch($formDataEvent, UserEvents::EDIT_FORM_HANDLE);
212
                $hook = new ProcessHook($userId);
213
                $hookDispatcher->dispatch(UserManagementUiHooksSubscriber::EDIT_PROCESS, $hook);
214
                $eventDispatcher->dispatch(new GenericEvent($user), RegistrationEvents::REGISTRATION_SUCCEEDED);
215
216
                if (UsersConstant::ACTIVATED_PENDING_REG === $user->getActivated()) {
217
                    $this->addFlash('status', 'Done! Created new registration application.');
218
                } elseif (null !== $user->getActivated()) {
0 ignored issues
show
introduced by
The condition null !== $user->getActivated() is always true.
Loading history...
219
                    $this->addFlash('status', 'Done! Created new user account.');
220
                } else {
221
                    $this->addFlash('error', 'Warning! New user information has been saved, however there may have been an issue saving it properly.');
222
                }
223
224
                return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
225
            }
226
            if ($form->get('cancel')->isClicked()) {
227
                $this->addFlash('status', 'Operation cancelled.');
228
            }
229
        }
230
231
        return [
232
            'form' => $form->createView(),
233
            'additional_templates' => isset($formEvent) ? $formEvent->getTemplates() : []
234
        ];
235
    }
236
237
    /**
238
     * @Route("/user/modify/{mapping}", requirements={"mapping" = "^[1-9]\d*$"})
239
     * @Theme("admin")
240
     * @Template("@ZikulaZAuthModule/UserAdministration/modify.html.twig")
241
     *
242
     * @return array|RedirectResponse
243
     * @throws AccessDeniedException Thrown if the user hasn't edit permissions for the mapping record
244
     */
245
    public function modifyAction(
246
        Request $request,
247
        AuthenticationMappingEntity $mapping,
248
        VariableApiInterface $variableApi,
249
        EncoderFactoryInterface $encoderFactory,
250
        UserRepositoryInterface $userRepository,
251
        AuthenticationMappingRepositoryInterface $authenticationMappingRepository,
252
        EventDispatcherInterface $eventDispatcher,
253
        HookDispatcherInterface $hookDispatcher
254
    ) {
255
        if (!$this->hasPermission('ZikulaZAuthModule::', $mapping->getUname() . '::' . $mapping->getUid(), ACCESS_EDIT)) {
256
            throw new AccessDeniedException();
257
        }
258
        if (1 === $mapping->getUid()) {
259
            throw new AccessDeniedException($this->trans("Error! You can't edit the guest account."));
260
        }
261
262
        $form = $this->createForm(AdminModifyUserType::class, $mapping, [
263
            'minimumPasswordLength' => $variableApi->get('ZikulaZAuthModule', ZAuthConstant::MODVAR_PASSWORD_MINIMUM_LENGTH, ZAuthConstant::PASSWORD_MINIMUM_LENGTH)
264
        ]);
265
        $originalMapping = clone $mapping;
266
        $formEvent = new UserFormAwareEvent($form);
267
        $eventDispatcher->dispatch($formEvent, UserEvents::EDIT_FORM);
268
        $form->handleRequest($request);
269
270
        $hook = new ValidationHook(new ValidationProviders());
271
        $hookDispatcher->dispatch(UserManagementUiHooksSubscriber::EDIT_VALIDATE, $hook);
272
        $validators = $hook->getValidators();
273
274
        if ($form->isSubmitted() && $form->isValid() && !$validators->hasErrors()) {
275
            if ($form->get('submit')->isClicked()) {
276
                /** @var AuthenticationMappingEntity $mapping */
277
                $mapping = $form->getData();
278
                if ($form->get('setpass')->getData()) {
279
                    $mapping->setPass($encoderFactory->getEncoder($mapping)->encodePassword($mapping->getPass(), null));
280
                } else {
281
                    $mapping->setPass($originalMapping->getPass());
282
                }
283
                $authenticationMappingRepository->persistAndFlush($mapping);
284
                /** @var UserEntity $user */
285
                $user = $userRepository->find($mapping->getUid());
286
                $user->merge($mapping->getUserEntityData());
287
                $userRepository->persistAndFlush($user);
288
                $eventArgs = [
289
                    'action'    => 'setVar',
290
                    'field'     => 'uname',
291
                    'attribute' => null,
292
                ];
293
                $eventData = ['old_value' => $originalMapping->getUname()];
294
                $updateEvent = new GenericEvent($user, $eventArgs, $eventData);
295
                $eventDispatcher->dispatch($updateEvent, UserEvents::UPDATE_ACCOUNT);
296
297
                $formDataEvent = new UserFormDataEvent($user, $form);
298
                $eventDispatcher->dispatch($formDataEvent, UserEvents::EDIT_FORM_HANDLE);
299
                $hookDispatcher->dispatch(UserManagementUiHooksSubscriber::EDIT_PROCESS, new ProcessHook($mapping->getUid()));
300
301
                $this->addFlash('status', "Done! Saved user's account information.");
302
            } elseif ($form->get('cancel')->isClicked()) {
303
                $this->addFlash('status', 'Operation cancelled.');
304
            }
305
306
            return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
307
        }
308
309
        return [
310
            'form' => $form->createView(),
311
            'additional_templates' => isset($formEvent) ? $formEvent->getTemplates() : []
312
        ];
313
    }
314
315
    /**
316
     * @Route("/verify/{mapping}", requirements={"mapping" = "^[1-9]\d*$"})
317
     * @PermissionCheck("moderate")
318
     * @Theme("admin")
319
     * @Template("@ZikulaZAuthModule/UserAdministration/verify.html.twig")
320
     *
321
     * @return array|RedirectResponse
322
     */
323
    public function verifyAction(
324
        Request $request,
325
        AuthenticationMappingEntity $mapping,
326
        AuthenticationMappingRepositoryInterface $authenticationMappingRepository,
327
        RegistrationVerificationHelper $registrationVerificationHelper
328
    ) {
329
        $form = $this->createForm(SendVerificationConfirmationType::class, [
330
            'mapping' => $mapping->getId()
331
        ]);
332
333
        $form->handleRequest($request);
334
        if ($form->isSubmitted() && $form->isValid()) {
335
            if ($form->get('confirm')->isClicked()) {
336
                /** @var AuthenticationMappingEntity $modifiedMapping */
337
                $modifiedMapping = $authenticationMappingRepository->find($form->get('mapping')->getData());
338
                $verificationSent = $registrationVerificationHelper->sendVerificationCode($modifiedMapping);
339
                if (!$verificationSent) {
340
                    $this->addFlash('error', $this->trans('Sorry! There was a problem sending a verification code to %sub%.', ['%sub%' => $modifiedMapping->getUname()]));
341
                } else {
342
                    $this->addFlash('status', $this->trans('Done! Verification code sent to %sub%.', ['%sub%' => $modifiedMapping->getUname()]));
343
                }
344
            }
345
            if ($form->get('cancel')->isClicked()) {
346
                $this->addFlash('status', 'Operation cancelled.');
347
            }
348
349
            return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
350
        }
351
352
        return [
353
            'form' => $form->createView(),
354
            'mapping' => $mapping
355
        ];
356
    }
357
358
    /**
359
     * @Route("/send-confirmation/{mapping}", requirements={"mapping" = "^[1-9]\d*$"})
360
     *
361
     * @throws AccessDeniedException Thrown if the user hasn't moderate permissions for the mapping record
362
     */
363
    public function sendConfirmationAction(
364
        AuthenticationMappingEntity $mapping,
365
        LostPasswordVerificationHelper $lostPasswordVerificationHelper,
366
        MailHelper $mailHelper
367
    ): RedirectResponse {
368
        if (!$this->hasPermission('ZikulaZAuthModule', $mapping->getUname() . '::' . $mapping->getUid(), ACCESS_MODERATE)) {
369
            throw new AccessDeniedException();
370
        }
371
        $changePasswordExpireDays = $this->getVar(ZAuthConstant::MODVAR_EXPIRE_DAYS_CHANGE_PASSWORD, ZAuthConstant::DEFAULT_EXPIRE_DAYS_CHANGE_PASSWORD);
372
        $lostPasswordId = $lostPasswordVerificationHelper->createLostPasswordId($mapping);
373
        $mailSent = $mailHelper->sendNotification($mapping->getEmail(), 'lostpassword', [
374
            'uname' => $mapping->getUname(),
375
            'validDays' => $changePasswordExpireDays,
376
            'lostPasswordId' => $lostPasswordId,
377
            'requestedByAdmin' => true
378
        ]);
379
        if ($mailSent) {
380
            $this->addFlash('status', $this->trans('Done! The password recovery verification link for %userName% has been sent via e-mail.', ['%userName%' => $mapping->getUname()]));
381
        }
382
383
        return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
384
    }
385
386
    /**
387
     * @Route("/send-username/{mapping}", requirements={"mapping" = "^[1-9]\d*$"})
388
     *
389
     * @throws AccessDeniedException Thrown if the user hasn't moderate permissions for the mapping record
390
     */
391
    public function sendUserNameAction(
392
        AuthenticationMappingEntity $mapping,
393
        MailHelper $mailHelper
394
    ): RedirectResponse {
395
        if (!$this->hasPermission('ZikulaZAuthModule', $mapping->getUname() . '::' . $mapping->getUid(), ACCESS_MODERATE)) {
396
            throw new AccessDeniedException();
397
        }
398
        $mailSent = $mailHelper->sendNotification($mapping->getEmail(), 'lostuname', [
399
            'uname' => $mapping->getUname(),
400
            'requestedByAdmin' => true,
401
        ]);
402
403
        if ($mailSent) {
404
            $this->addFlash('status', $this->trans('Done! The user name for %userName% has been sent via e-mail.', ['%userName%' => $mapping->getUname()]));
405
        }
406
407
        return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
408
    }
409
410
    /**
411
     * @Route("/toggle-password-change/{user}", requirements={"user" = "^[1-9]\d*$"})
412
     * @Theme("admin")
413
     * @Template("@ZikulaZAuthModule/UserAdministration/togglePasswordChange.html.twig")
414
     *
415
     * @param Request $request
416
     * @param UserEntity $user // note: this is intentionally left as UserEntity instead of mapping because of need to access attributes
417
     *
418
     * @return array|RedirectResponse
419
     * @throws AccessDeniedException Thrown if the user hasn't moderate permissions for the user record
420
     */
421
    public function togglePasswordChangeAction(Request $request, UserEntity $user)
422
    {
423
        if (!$this->hasPermission('ZikulaZAuthModule', $user->getUname() . '::' . $user->getUid(), ACCESS_MODERATE)) {
424
            throw new AccessDeniedException();
425
        }
426
        if ($user->getAttributes()->containsKey(ZAuthConstant::REQUIRE_PASSWORD_CHANGE_KEY)) {
427
            $mustChangePass = $user->getAttributes()->get(ZAuthConstant::REQUIRE_PASSWORD_CHANGE_KEY);
428
        } else {
429
            $mustChangePass = false;
430
        }
431
        $form = $this->createForm(TogglePasswordConfirmationType::class, [
432
            'uid' => $user->getUid()
433
        ], [
434
            'mustChangePass' => $mustChangePass
435
        ]);
436
        $form->handleRequest($request);
437
        if ($form->isSubmitted() && $form->isValid()) {
438
            if ($form->get('toggle')->isClicked()) {
439
                if ($user->getAttributes()->containsKey(ZAuthConstant::REQUIRE_PASSWORD_CHANGE_KEY) && (bool)$user->getAttributes()->get(ZAuthConstant::REQUIRE_PASSWORD_CHANGE_KEY)) {
440
                    $user->getAttributes()->remove(ZAuthConstant::REQUIRE_PASSWORD_CHANGE_KEY);
441
                    $this->addFlash('success', $this->trans('Done! A password change will no longer be required for %userName%.', ['%userName%' => $user->getUname()]));
442
                } else {
443
                    $user->setAttribute(ZAuthConstant::REQUIRE_PASSWORD_CHANGE_KEY, true);
444
                    $this->addFlash('success', $this->trans('Done! A password change will be required the next time %userName% logs in.', ['%userName%' => $user->getUname()]));
445
                }
446
                $this->getDoctrine()->getManager()->flush();
447
            } elseif ($form->get('cancel')->isClicked()) {
448
                $this->addFlash('info', 'Operation cancelled.');
449
            }
450
451
            return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
452
        }
453
454
        return [
455
            'form' => $form->createView(),
456
            'mustChangePass' => $mustChangePass,
457
            'user' => $user
458
        ];
459
    }
460
461
    /**
462
     * @Route("/batch-force-password-change")
463
     * @PermissionCheck("admin")
464
     * @Theme("admin")
465
     * @Template("@ZikulaZAuthModule/UserAdministration/batchForcePasswordChange.html.twig")
466
     *
467
     * @return array|RedirectResponse
468
     */
469
    public function batchForcePasswordChangeAction(
470
        CurrentUserApiInterface $currentUserApi,
471
        Request $request
472
    ) {
473
        $form = $this->createForm(BatchForcePasswordChangeType::class);
474
        $form->handleRequest($request);
475
        if ($form->isSubmitted() && $form->isValid()) {
476
            if ($form->get('submit')->isClicked()) {
477
                $users = $this->getUsers($form->get('group')->getData(), $currentUserApi->get('uid'));
478
                $count = 0;
479
                foreach ($users as $user) {
480
                    $user->setAttribute(ZAuthConstant::REQUIRE_PASSWORD_CHANGE_KEY, true);
481
                    $count++;
482
                    if (0 === $count % 20) {
483
                        $this->getDoctrine()->getManager()->flush(); // flush manager every 20 reps
484
                    }
485
                }
486
                $this->getDoctrine()->getManager()->flush(); // flush remaining
487
                /** @Desc("{count, plural,\n  one   {# user was processed!}\n  other {# users were processed!}\n}") */
488
                $this->addFlash('info', $this->trans('plural_n.users.processed.', ['%count%' => $count]));
489
            } elseif ($form->get('cancel')->isClicked()) {
490
                $this->addFlash('info', 'Operation cancelled.');
491
            }
492
493
            return $this->redirectToRoute('zikulazauthmodule_useradministration_list');
494
        }
495
496
        return [
497
            'form' => $form->createView(),
498
        ];
499
    }
500
501
    private function getUsers($selector, int $currentUser)
502
    {
503
        if (!in_array($selector, ['all', 'old']) && !is_int($selector)) {
504
            return [];
505
        }
506
        $authenticationMappingRepository = $this->getDoctrine()->getRepository(AuthenticationMappingEntity::class);
507
        $toUsersArray = function($mappings) {
508
            $uids = [];
509
            foreach ($mappings as $mapping) {
510
                $uids[] = $mapping->getUid();
511
            }
512
            $userRepository = $this->getDoctrine()->getRepository(UserEntity::class);
513
514
            return $userRepository->findByUids($uids);
515
        };
516
        switch ($selector) {
517
            case 'old':
518
                $mappings = $authenticationMappingRepository->getByExpiredPasswords();
519
                $users = $toUsersArray($mappings);
520
                break;
521
            case 'all':
522
                $mappings = $authenticationMappingRepository->findAll();
523
                $users = $toUsersArray($mappings);
524
                break;
525
            default: //group id
526
                $groupRepository = $this->getDoctrine()->getRepository(GroupEntity::class);
527
                $group = $groupRepository->find($selector);
528
                if ($group && $group instanceof GroupEntity) {
529
                    $users = $group->getUsers();
530
                    foreach ($users as $user) {
531
                        if (!$authenticationMappingRepository->getByZikulaId($user->getUid())) {
532
                            $users->removeElement($user);
533
                        }
534
                    }
535
                    $users = $users->toArray();
536
                }
537
        }
538
539
        if (is_array($users) && isset($users[$currentUser])) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $users does not seem to be defined for all execution paths leading up to this point.
Loading history...
540
            // remove the current user (admin) and guest user if included
541
            unset($users[$currentUser], $users[1]);
542
        }
543
544
        return $users;
545
    }
546
}
547