Test Failed
Push — develop ( c753fd...f013d6 )
by nguereza
02:45
created

EditAction::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
nc 1
nop 7
dl 0
loc 16
rs 10
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file EditAction.php
34
 *
35
 *  The Edit action class
36
 *
37
 *  @package    Platine\Framework\Demo\Action\Role
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   http://www.iacademy.cf
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Demo\Action\Role;
49
50
use Platine\Framework\Auth\Entity\Role;
51
use Platine\Framework\Auth\Repository\PermissionRepository;
52
use Platine\Framework\Auth\Repository\RoleRepository;
53
use Platine\Framework\Demo\Form\Param\RoleParam;
54
use Platine\Framework\Demo\Form\Validator\RoleValidator;
55
use Platine\Framework\Http\RequestData;
56
use Platine\Framework\Http\Response\RedirectResponse;
57
use Platine\Framework\Http\Response\TemplateResponse;
58
use Platine\Framework\Http\RouteHelper;
59
use Platine\Http\Handler\RequestHandlerInterface;
60
use Platine\Http\ResponseInterface;
61
use Platine\Http\ServerRequestInterface;
62
use Platine\Logger\LoggerInterface;
63
use Platine\Security\Hash\HashInterface;
64
use Platine\Session\Session;
65
use Platine\Stdlib\Helper\Str;
66
use Platine\Template\Template;
67
68
/**
69
 * @class EditAction
70
 * @package Platine\Framework\Demo\Action\Role
71
 * @template T
72
 */
73
class EditAction implements RequestHandlerInterface
74
{
75
76
    /**
77
     * The logger instance
78
     * @var LoggerInterface
79
     */
80
    protected LoggerInterface $logger;
81
82
    /**
83
     * The session instance
84
     * @var Session
85
     */
86
    protected Session $session;
87
88
    /**
89
     * The role repository
90
     * @var RoleRepository
91
     */
92
    protected RoleRepository $roleRepository;
93
94
    /**
95
     * The permission repository
96
     * @var PermissionRepository
97
     */
98
    protected PermissionRepository $permissionRepository;
99
100
    /**
101
     * The template instance
102
     * @var Template
103
     */
104
    protected Template $template;
105
106
    /**
107
     * The route helper instance
108
     * @var RouteHelper
109
     */
110
    protected RouteHelper $routeHelper;
111
112
     /**
113
     * The password hash to be used
114
     * @var HashInterface
115
     */
116
    protected HashInterface $hash;
117
118
    /**
119
     * Create new instance
120
     * @param LoggerInterface $logger
121
     * @param Session $session
122
     * @param Template $template
123
     * @param RoleRepository $roleRepository
124
     * @param PermissionRepository $permissionRepository
125
     * @param RouteHelper $routeHelper
126
     * @param HashInterface $hash
127
     */
128
    public function __construct(
129
        LoggerInterface $logger,
130
        Session $session,
131
        Template $template,
132
        RoleRepository $roleRepository,
133
        PermissionRepository $permissionRepository,
134
        RouteHelper $routeHelper,
135
        HashInterface $hash
136
    ) {
137
        $this->logger = $logger;
138
        $this->session = $session;
139
        $this->roleRepository = $roleRepository;
140
        $this->permissionRepository = $permissionRepository;
141
        $this->template = $template;
142
        $this->routeHelper = $routeHelper;
143
        $this->hash = $hash;
144
    }
145
146
    /**
147
     * {@inheritodc}
148
     */
149
    public function handle(ServerRequestInterface $request): ResponseInterface
150
    {
151
        $id = (int) $request->getAttribute('id');
152
153
        /** @var Role $role */
154
        $role = $this->roleRepository
155
                                    ->with('permissions')
156
                                    ->find($id);
157
        if (!$role) {
0 ignored issues
show
introduced by
$role is of type Platine\Framework\Auth\Entity\Role, thus it always evaluated to true.
Loading history...
158
            $this->session->setFlash('error', 'Can not find the role');
159
            $this->logger->warning('Can not find role with id {id}', ['id' => $id]);
160
161
            return new RedirectResponse(
162
                $this->routeHelper->generateUrl('role_list')
163
            );
164
        }
165
166
        $permissions = $this->permissionRepository
167
                                                  ->orderBy('code')
168
                                                  ->all();
169
170
        $currentPermissionsId = [];
171
        foreach ($role->permissions as $entity) {
0 ignored issues
show
Bug Best Practice introduced by
The property permissions does not exist on Platine\Framework\Auth\Entity\Role. Since you implemented __get, consider adding a @property annotation.
Loading history...
172
            $currentPermissionsId[] = $entity->id;
173
        }
174
175
        $entityToFormParam = (new RoleParam())->fromEntity($role);
176
        $entityToFormParam->setPermissions($currentPermissionsId);
177
178
        if ($request->getMethod() === 'GET') {
179
            return new TemplateResponse(
180
                $this->template,
181
                'role/edit',
182
                [
183
                    'param' => $entityToFormParam,
184
                    'permissions' => $permissions
185
                ]
186
            );
187
        }
188
189
        $param = new RequestData($request);
190
        $formParam = new RoleParam($param->posts());
191
        $validator = new RoleValidator($formParam);
192
193
        if (!$validator->validate()) {
194
            return new TemplateResponse(
195
                $this->template,
196
                'role/edit',
197
                [
198
                    'errors' => $validator->getErrors(),
199
                    'param' => $formParam,
200
                    'permissions' => $permissions
201
                ]
202
            );
203
        }
204
205
        $name = $param->post('name');
206
        $roleExist = $this->roleRepository->findBy(['name' => $name]);
207
208
        if ($roleExist && $roleExist->id != $id) {
209
            $this->session->setFlash('error', 'This role already exists');
210
            $this->logger->error('Role with name {name} already exists', ['name' => $name]);
211
            return new TemplateResponse(
212
                $this->template,
213
                'role/edit',
214
                [
215
                   'param' => $formParam,
216
                   'permissions' => $permissions
217
                ]
218
            );
219
        }
220
221
        $password = $param->post('password');
0 ignored issues
show
Unused Code introduced by
The assignment to $password is dead and can be removed.
Loading history...
222
223
        $role->name = $formParam->getName();
0 ignored issues
show
Bug Best Practice introduced by
The property name does not exist on Platine\Framework\Auth\Entity\Role. Since you implemented __set, consider adding a @property annotation.
Loading history...
224
        $role->description = $formParam->getDescription();
0 ignored issues
show
Bug Best Practice introduced by
The property description does not exist on Platine\Framework\Auth\Entity\Role. Since you implemented __set, consider adding a @property annotation.
Loading history...
225
226
        //Handle permissions
227
        $permissionsId = $param->post('permissions', []);
228
        $permissionsIdToDelete = array_diff($currentPermissionsId, $permissionsId);
229
        if (!empty($permissionsIdToDelete)) {
230
            $deletedPermissions = $this->permissionRepository->findAll(...$permissionsIdToDelete);
231
            $role->removePermissions($deletedPermissions);
232
        }
233
        $newPermissionsId = array_diff($permissionsId, $currentPermissionsId);
234
        if (!empty($newPermissionsId)) {
235
            $newPermissions = $this->permissionRepository->findAll(...$newPermissionsId);
236
            $role->setPermissions($newPermissions);
237
        }
238
        /////////////////
239
240
        $result = $this->roleRepository->save($role);
241
242
        if (!$result) {
243
            $this->session->setFlash('error', 'Error when saved the role');
244
            $this->logger->error('Error when saved the role');
245
            return new TemplateResponse(
246
                $this->template,
247
                'role/edit',
248
                [
249
                   'param' => $formParam,
250
                   'permissions' => $permissions
251
                ]
252
            );
253
        }
254
255
        $this->session->setFlash('success', 'Role saved successfully');
256
257
        $returnUrl = $this->routeHelper->generateUrl('role_list');
258
        if ($param->get('from_detail')) {
259
            $returnUrl = $this->routeHelper->generateUrl('role_detail', ['id' => $id]);
260
        }
261
        return new RedirectResponse($returnUrl);
262
    }
263
}
264