Completed
Push — master ( a3cce1...d6fbcc )
by Marcel
09:39
created

UserController::edit()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
c 3
b 0
f 0
nc 5
nop 4
dl 0
loc 29
ccs 0
cts 18
cp 0
crap 56
rs 8.8333
1
<?php
2
3
namespace App\Controller;
4
5
use App\Entity\ActiveDirectoryUser;
6
use App\Entity\User;
7
use App\Form\AttributeDataTrait;
8
use App\Form\UserType;
9
use App\Entity\UserType as UserTypeEntity;
10
use App\Repository\UserRepositoryInterface;
11
use App\Repository\UserTypeRepositoryInterface;
12
use App\Saml\AttributeValueProvider;
13
use App\Service\AttributePersister;
14
use App\Service\AttributeResolver;
15
use App\Utils\ArrayUtils;
16
use App\View\Filter\UserRoleFilter;
17
use App\View\Filter\UserTypeFilter;
18
use SchulIT\CommonBundle\Form\ConfirmType;
19
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
22
use Symfony\Component\Routing\Annotation\Route;
23
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
24
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
25
use Symfony\Contracts\Translation\TranslatorInterface;
26
27
class UserController extends AbstractController {
28
29
    use AttributeDataTrait;
30
31
    const USERS_PER_PAGE = 25;
32
33
    const CsrfTokenId = 'remove_user';
34
    const CsrfTokenKey = '_csrf_token';
35
36
    private $repository;
37
    private $typeRepository;
38
39
    public function __construct(UserRepositoryInterface $repository, UserTypeRepositoryInterface $typeRepository) {
40
        $this->repository = $repository;
41
        $this->typeRepository = $typeRepository;
42
    }
43
44
    private function internalDisplay(Request $request, UserTypeFilter $typeFilter, UserRoleFilter $roleFilter, bool $deleted) {
45
        $q = $request->query->get('q', null);
46
        $page = $request->query->getInt('page', 1);
47
48
        $typeFilterView = $typeFilter->handle($request->query->get('type'));
49
        $roleFilterView = $roleFilter->handle($request->query->get('role'));
50
51
        $paginator = $this->repository->getPaginatedUsers(static::USERS_PER_PAGE, $page, $typeFilterView->getCurrentType(), $roleFilterView->getCurrentRole(), $q, $deleted);
52
53
        $pages = 1;
54
55
        if($paginator->count() > 0) {
56
            $pages = ceil((float)$paginator->count() / static::USERS_PER_PAGE);
57
        }
58
59
        $template = $deleted ? 'users/trash.html.twig' : 'users/index.html.twig';
60
61
        $statistics = [ ];
62
63
        if($deleted === false) {
64
            foreach ($typeFilterView->getTypes() as $type) {
65
                $statistics[] = [
66
                    'type' => $type,
67
                    'count' => $this->repository->countUsers($type)
68
                ];
69
            }
70
        }
71
72
        return $this->render($template, [
73
            'users' => $paginator->getIterator(),
74
            'page' => $page,
75
            'pages' => $pages,
76
            'q' => $q,
77
            'statistics' => $statistics,
78
            'count' => $this->repository->countUsers(),
79
            'roleFilter' => $roleFilterView,
80
            'typeFilter' => $typeFilterView,
81
            'csrf_id' => static::CsrfTokenId,
82
            'csrf_key' => static::CsrfTokenKey
83
        ]);
84
    }
85
86
    /**
87
     * @Route("/users", name="users")
88
     */
89
    public function index(Request $request, UserTypeFilter $typeFilter, UserRoleFilter $roleFilter) {
90
        return $this->internalDisplay($request, $typeFilter, $roleFilter, false);
91
    }
92
93
    /**
94
     * @Route("/users/trash", name="users_trash")
95
     */
96
    public function trash(Request $request, UserTypeFilter $typeFilter, UserRoleFilter $roleFilter) {
97
        return $this->internalDisplay($request, $typeFilter, $roleFilter, true);
98
    }
99
100
    /**
101
     * @Route("/users/{uuid}/attributes", name="show_attributes")
102
     */
103
    public function showAttributes(User $user, AttributeResolver $resolver, AttributeValueProvider $provider) {
104
        $attributes = $resolver->getDetailedResultingAttributeValuesForUser($user);
105
        $defaultAttributes = $provider->getCommonAttributesForUser($user);
106
107
        return $this->render('users/attributes.html.twig', [
108
            'selectedUser' => $user,
109
            'attributes' => $attributes,
110
            'defaultAttributes' => $defaultAttributes
111
        ]);
112
    }
113
114
    /**
115
     * @Route("/users/add", name="add_user")
116
     */
117
    public function add(Request $request, AttributePersister $attributePersister, UserPasswordEncoderInterface $passwordEncoder) {
118
        $user = new User();
119
120
        $form = $this->createForm(UserType::class, $user);
121
        $form->handleRequest($request);
122
123
        if($form->isSubmitted() && $form->isValid()) {
124
            $user->setPassword($passwordEncoder->encodePassword($user, $form->get('group_password')->get('password')->getData()));
125
126
            $this->repository->persist($user);
127
128
            $attributeData = $this->getAttributeData($form);
129
            $attributePersister->persistUserAttributes($attributeData, $user);
130
131
            $this->addFlash('success', 'users.add.success');
132
            return $this->redirectToRoute('users');
133
        }
134
135
        return $this->render('users/add.html.twig', [
136
            'form' => $form->createView()
137
        ]);
138
    }
139
140
    /**
141
     * @Route("/users/{uuid}/edit", name="edit_user")
142
     */
143
    public function edit(Request $request, User $user, AttributePersister $attributePersister, UserPasswordEncoderInterface $passwordEncoder) {
144
        if($user->isDeleted()) {
145
            throw new NotFoundHttpException();
146
        }
147
148
        $form = $this->createForm(UserType::class, $user);
149
        $form->handleRequest($request);
150
151
        if($form->isSubmitted() && $form->isValid()) {
152
            if($form->has('group_password')) {
153
                $password = $form->get('group_password')->get('password')->getData();
154
155
                if (!empty($password) && !$user instanceof ActiveDirectoryUser) {
156
                    $user->setPassword($passwordEncoder->encodePassword($user, $password));
157
                }
158
            }
159
160
            $this->repository->persist($user);
161
162
            $attributeData = $this->getAttributeData($form);
163
            $attributePersister->persistUserAttributes($attributeData, $user);
164
165
            $this->addFlash('success', 'users.edit.success');
166
            return $this->redirectToRoute('users');
167
        }
168
169
        return $this->render('users/edit.html.twig', [
170
            'form' => $form->createView(),
171
            'requestedUser' => $user
172
        ]);
173
    }
174
175
    /**
176
     * @Route("/users/{uuid}/remove", name="remove_user")
177
     */
178
    public function remove(User $user, Request $request, TranslatorInterface $translator) {
179
        if($this->getUser() instanceof User && $this->getUser()->getId() === $user->getId()) {
180
            $this->addFlash('error', 'users.remove.error.self');
181
            return $this->redirectToRoute('users');
182
        }
183
184
        if($user->isDeleted() === false) {
185
            if($request->isMethod('POST') && $this->isCsrfTokenValid(static::CsrfTokenId, $request->request->get(static::CsrfTokenKey))) {
186
                $this->addFlash('success', 'users.remove.trash.success');
187
                $this->repository->remove($user);
188
                return $this->redirectToRoute('users');
189
            } else {
190
                $this->addFlash('error', 'users.remove.trash.error');
191
                return $this->redirectToRoute('users');
192
            }
193
        }
194
195
        $form = $this->createForm(ConfirmType::class, [], [
196
            'message' => $translator->trans('users.remove.confirm', [
197
                '%username%' => $user->getUsername(),
198
                '%firstname%' => $user->getFirstname(),
199
                '%lastname%' => $user->getLastname()
200
            ]),
201
            'label' => 'users.remove.label'
202
        ]);
203
        $form->handleRequest($request);
204
205
        if($form->isSubmitted() && $form->isValid()) {
206
            $this->repository->remove($user);
207
208
            $this->addFlash('success', 'users.remove.success');
209
            return $this->redirectToRoute('users');
210
        }
211
212
        return $this->render('users/remove.html.twig', [
213
            'form' => $form->createView(),
214
            'requestedUser' => $user
215
        ]);
216
    }
217
218
    /**
219
     * @Route("/users/{uuid}/restore", name="restore_user", methods={"POST"})
220
     */
221
    public function restore(User $user, Request $request) {
222
        if($this->getUser() instanceof User && $this->getUser()->getId() === $user->getId()) {
223
            $this->addFlash('error', 'users.restore.error.self');
224
            return $this->redirectToRoute('users');
225
        }
226
227
        if($request->isMethod('POST') && $this->isCsrfTokenValid(static::CsrfTokenId, $request->request->get(static::CsrfTokenKey))) {
228
            $this->addFlash('success', 'users.trash.restore.success');
229
            $user->setDeletedAt(null);
230
            $this->repository->persist($user);
231
            return $this->redirectToRoute('users_trash');
232
        }
233
234
        $this->addFlash('error', 'users.trash.restore.error');
235
        return $this->redirectToRoute('users_trash');
236
    }
237
}