Passed
Push — master ( e29dd4...45ceca )
by nguereza
03:00 queued 57s
created

UserAction::index()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 22
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 31
rs 9.568
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Platine\App\Http\Action\User;
6
7
use Exception;
8
use Platine\App\Helper\StatusList;
9
use Platine\App\Param\UserParam;
10
use Platine\App\Validator\UserValidator;
11
use Platine\Framework\Auth\Entity\User;
12
use Platine\Framework\Auth\Repository\RoleRepository;
13
use Platine\Framework\Auth\Repository\UserRepository;
14
use Platine\Framework\Helper\Flash;
15
use Platine\Framework\Http\RequestData;
16
use Platine\Framework\Http\Response\RedirectResponse;
17
use Platine\Framework\Http\Response\TemplateResponse;
18
use Platine\Framework\Http\RouteHelper;
19
use Platine\Http\ResponseInterface;
20
use Platine\Http\ServerRequestInterface;
21
use Platine\Lang\Lang;
22
use Platine\Logger\LoggerInterface;
23
use Platine\Pagination\Pagination;
24
use Platine\Security\Hash\HashInterface;
25
use Platine\Stdlib\Helper\Arr;
26
use Platine\Stdlib\Helper\Str;
27
use Platine\Template\Template;
28
29
/**
30
* @class UserAction
31
* @package Platine\App\Http\Action\User
32
*/
33
class UserAction
34
{
35
    /**
36
    * The Lang instance
37
    * @var Lang
38
    */
39
    protected Lang $lang;
40
41
    /**
42
    * The Pagination instance
43
    * @var Pagination
44
    */
45
    protected Pagination $pagination;
46
47
    /**
48
    * The Template instance
49
    * @var Template
50
    */
51
    protected Template $template;
52
53
    /**
54
    * The Flash instance
55
    * @var Flash
56
    */
57
    protected Flash $flash;
58
59
    /**
60
    * The RouteHelper instance
61
    * @var RouteHelper
62
    */
63
    protected RouteHelper $routeHelper;
64
65
    /**
66
    * The LoggerInterface instance
67
    * @var LoggerInterface
68
    */
69
    protected LoggerInterface $logger;
70
71
    /**
72
    * The RoleRepository instance
73
    * @var RoleRepository
74
    */
75
    protected RoleRepository $roleRepository;
76
77
    /**
78
    * The StatusList instance
79
    * @var StatusList
80
    */
81
    protected StatusList $statusList;
82
83
    /**
84
    * The HashInterface instance
85
    * @var HashInterface
86
    */
87
    protected HashInterface $hash;
88
89
    /**
90
    * The UserRepository instance
91
    * @var UserRepository
92
    */
93
    protected UserRepository $userRepository;
94
95
96
97
    /**
98
    * Create new instance
99
    * @param Lang $lang
100
    * @param Pagination $pagination
101
    * @param Template $template
102
    * @param Flash $flash
103
    * @param RouteHelper $routeHelper
104
    * @param LoggerInterface $logger
105
    * @param RoleRepository $roleRepository
106
    * @param StatusList $statusList
107
    * @param HashInterface $hash
108
    * @param UserRepository $userRepository
109
    */
110
    public function __construct(
111
        Lang $lang,
112
        Pagination $pagination,
113
        Template $template,
114
        Flash $flash,
115
        RouteHelper $routeHelper,
116
        LoggerInterface $logger,
117
        RoleRepository $roleRepository,
118
        StatusList $statusList,
119
        HashInterface $hash,
120
        UserRepository $userRepository
121
    ) {
122
        $this->lang = $lang;
123
        $this->pagination = $pagination;
124
        $this->template = $template;
125
        $this->flash = $flash;
126
        $this->routeHelper = $routeHelper;
127
        $this->logger = $logger;
128
        $this->roleRepository = $roleRepository;
129
        $this->statusList = $statusList;
130
        $this->hash = $hash;
131
        $this->userRepository = $userRepository;
132
    }
133
134
    /**
135
    * List all entities
136
    * @param ServerRequestInterface $request
137
    * @return ResponseInterface
138
    */
139
    public function index(ServerRequestInterface $request): ResponseInterface
140
    {
141
        $context = [];
142
        $param = new RequestData($request);
143
        $totalItems = $this->userRepository->query()
144
                                               ->count('id');
145
146
        $currentPage = (int) $param->get('page', 1);
147
148
        $this->pagination->setTotalItems($totalItems)
149
                        ->setCurrentPage($currentPage);
150
151
        $limit = $this->pagination->getItemsPerPage();
152
        $offset = $this->pagination->getOffset();
153
154
        $results = $this->userRepository->query()
155
                                            ->offset($offset)
156
                                            ->limit($limit)
157
                                            ->orderBy('lastname', 'ASC')
158
                        ->orderBy('firstname', 'ASC')
159
                                            ->all();
160
161
        $context['list'] = $results;
162
        $context['pagination'] = $this->pagination->render();
163
        $context['user_status'] = $this->statusList->getUserStatus();
164
165
166
        return new TemplateResponse(
167
            $this->template,
168
            'user/list',
169
            $context
170
        );
171
    }
172
173
    /**
174
    * List entity detail
175
    * @param ServerRequestInterface $request
176
    * @return ResponseInterface
177
    */
178
    public function detail(ServerRequestInterface $request): ResponseInterface
179
    {
180
        $context = [];
181
        $id = (int) $request->getAttribute('id');
182
183
        /** @var User|null $user */
184
        $user = $this->userRepository->find($id);
185
186
        if ($user === null) {
187
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
188
189
            return new RedirectResponse(
190
                $this->routeHelper->generateUrl('user_list')
191
            );
192
        }
193
        $context['user'] = $user;
194
        $context['user_status'] = $this->statusList->getUserStatus();
195
196
        return new TemplateResponse(
197
            $this->template,
198
            'user/detail',
199
            $context
200
        );
201
    }
202
203
    /**
204
    * Create new entity
205
    * @param ServerRequestInterface $request
206
    * @return ResponseInterface
207
    */
208
    public function create(ServerRequestInterface $request): ResponseInterface
209
    {
210
        $context = [];
211
        $param = new RequestData($request);
212
213
        $formParam = new UserParam($param->posts());
214
        $context['param'] = $formParam;
215
        $context['roles'] = $this->roleRepository->orderBy('name')
216
                                                 ->all();
217
218
        $context['user_status'] = $this->statusList->getUserStatus();
219
220
221
        if ($request->getMethod() === 'GET') {
222
            return new TemplateResponse(
223
                $this->template,
224
                'user/create',
225
                $context
226
            );
227
        }
228
229
        $validator = new UserValidator($formParam, $this->lang);
230
        if ($validator->validate() === false) {
231
            $context['errors'] = $validator->getErrors();
232
233
            return new TemplateResponse(
234
                $this->template,
235
                'user/create',
236
                $context
237
            );
238
        }
239
240
        $usernameExist = $this->userRepository->findBy([
241
                                               'username' => $formParam->getUsername(),
242
                                           ]);
243
244
        if ($usernameExist !== null) {
245
            $this->flash->setError($this->lang->tr('This username already exist'));
246
247
            return new TemplateResponse(
248
                $this->template,
249
                'user/create',
250
                $context
251
            );
252
        }
253
254
        $emailExist = $this->userRepository->findBy([
255
                                               'email' => $formParam->getEmail(),
256
                                           ]);
257
258
        if ($emailExist !== null) {
259
            $this->flash->setError($this->lang->tr('This email already exist'));
260
261
            return new TemplateResponse(
262
                $this->template,
263
                'user/create',
264
                $context
265
            );
266
        }
267
268
        $passwordHash = $this->hash->hash($formParam->getPassword());
269
270
        /** @var User $user */
271
        $user = $this->userRepository->create([
272
           'username' => $formParam->getUsername(),
273
        'lastname' => Str::upper($formParam->getLastname()),
274
        'firstname' => Str::ucfirst($formParam->getFirstname()),
275
        'email' => $formParam->getEmail(),
276
        'status' => $formParam->getStatus(),
277
        'role' => $formParam->getRole(),
278
        'password' => $passwordHash,
279
        ]);
280
281
        $rolesId = $formParam->getRoles();
282
        if (count($rolesId) > 0) {
283
            $selectedRoles = $this->roleRepository->findAll(...$rolesId);
284
            $user->setRoles($selectedRoles);
285
        }
286
287
        try {
288
            $this->userRepository->save($user);
289
290
            $this->flash->setSuccess($this->lang->tr('Data successfully created'));
291
292
            return new RedirectResponse(
293
                $this->routeHelper->generateUrl('user_list')
294
            );
295
        } catch (Exception $ex) {
296
            $this->logger->error('Error when saved the data {error}', ['error' => $ex->getMessage()]);
297
298
            $this->flash->setError($this->lang->tr('Data processing error'));
299
300
            return new TemplateResponse(
301
                $this->template,
302
                'user/create',
303
                $context
304
            );
305
        }
306
    }
307
308
    /**
309
    * Update existing entity
310
    * @param ServerRequestInterface $request
311
    * @return ResponseInterface
312
    */
313
    public function update(ServerRequestInterface $request): ResponseInterface
314
    {
315
        $context = [];
316
        $param = new RequestData($request);
317
318
        $id = (int) $request->getAttribute('id');
319
320
        /** @var User|null $user */
321
        $user = $this->userRepository->find($id);
322
323
        if ($user === null) {
324
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
325
326
            return new RedirectResponse(
327
                $this->routeHelper->generateUrl('user_list')
328
            );
329
        }
330
        $context['user'] = $user;
331
        $context['param'] = (new UserParam())->fromEntity($user);
332
        $currentRolesId = Arr::getColumn($user->roles, 'id');
333
        $context['param']->setRoles($currentRolesId);
334
335
        $context['roles'] = $this->roleRepository->orderBy('name')
336
                                                 ->all();
337
338
        $context['user_status'] = $this->statusList->getUserStatus();
339
340
        if ($request->getMethod() === 'GET') {
341
            return new TemplateResponse(
342
                $this->template,
343
                'user/update',
344
                $context
345
            );
346
        }
347
        $formParam = new UserParam($param->posts());
348
        $context['param'] = $formParam;
349
350
        $validator = new UserValidator($formParam, $this->lang, true);
351
        if ($validator->validate() === false) {
352
            $context['errors'] = $validator->getErrors();
353
354
            return new TemplateResponse(
355
                $this->template,
356
                'user/update',
357
                $context
358
            );
359
        }
360
361
        $usernameExist = $this->userRepository->findBy([
362
                                               'username' => $formParam->getUsername(),
363
                                           ]);
364
365
        if ($usernameExist !== null && $usernameExist->id !== $id) {
366
            $this->flash->setError($this->lang->tr('This username already exist'));
367
368
            return new TemplateResponse(
369
                $this->template,
370
                'user/update',
371
                $context
372
            );
373
        }
374
375
        $emailExist = $this->userRepository->findBy([
376
                                               'email' => $formParam->getEmail(),
377
                                           ]);
378
379
        if ($emailExist !== null && $emailExist->id !== $id) {
380
            $this->flash->setError($this->lang->tr('This email already exist'));
381
382
            return new TemplateResponse(
383
                $this->template,
384
                'user/update',
385
                $context
386
            );
387
        }
388
389
        $user->username = $formParam->getUsername();
390
        $user->lastname = $formParam->getLastname();
391
        $user->firstname = $formParam->getFirstname();
392
        $user->email = $formParam->getEmail();
393
        $user->status = $formParam->getStatus();
394
        $user->role = $formParam->getRole();
395
396
        $password = $formParam->getPassword();
397
        if (!empty($password)) {
398
            $passwordHash = $this->hash->hash($password);
399
400
            $user->password = $passwordHash;
401
        }
402
403
        $rolesId = $formParam->getRoles();
404
        $rolesIdToDelete = array_diff($currentRolesId, $rolesId);
405
        if (count($rolesIdToDelete) > 0) {
406
            $deletedRoles = $this->roleRepository->findAll(...$rolesIdToDelete);
407
            $user->removeRoles($deletedRoles);
408
        }
409
410
        $newRolesId = array_diff($rolesId, $currentRolesId);
411
        if (count($newRolesId) > 0) {
412
            $newRoles = $this->roleRepository->findAll(...$newRolesId);
413
            $user->setRoles($newRoles);
414
        }
415
416
        try {
417
            $this->userRepository->save($user);
418
419
            $this->flash->setSuccess($this->lang->tr('Data successfully updated'));
420
421
            return new RedirectResponse(
422
                $this->routeHelper->generateUrl('user_detail', ['id' => $id])
423
            );
424
        } catch (Exception $ex) {
425
            $this->logger->error('Error when saved the data {error}', ['error' => $ex->getMessage()]);
426
427
            $this->flash->setError($this->lang->tr('Data processing error'));
428
429
            return new TemplateResponse(
430
                $this->template,
431
                'user/update',
432
                $context
433
            );
434
        }
435
    }
436
437
    /**
438
    * Delete the entity
439
    * @param ServerRequestInterface $request
440
    * @return ResponseInterface
441
    */
442
    public function delete(ServerRequestInterface $request): ResponseInterface
443
    {
444
        $id = (int) $request->getAttribute('id');
445
446
        /** @var User|null $user */
447
        $user = $this->userRepository->find($id);
448
449
        if ($user === null) {
450
            $this->flash->setError($this->lang->tr('This record doesn\'t exist'));
451
452
            return new RedirectResponse(
453
                $this->routeHelper->generateUrl('user_list')
454
            );
455
        }
456
457
        try {
458
            $this->userRepository->delete($user);
459
460
            $this->flash->setSuccess($this->lang->tr('Data successfully deleted'));
461
462
            return new RedirectResponse(
463
                $this->routeHelper->generateUrl('user_list')
464
            );
465
        } catch (Exception $ex) {
466
            $this->logger->error('Error when delete the data {error}', ['error' => $ex->getMessage()]);
467
468
            $this->flash->setError($this->lang->tr('Data processing error'));
469
470
            return new RedirectResponse(
471
                $this->routeHelper->generateUrl('user_list')
472
            );
473
        }
474
    }
475
}
476