Completed
Push — master ( df0c76...851a92 )
by Arnaud
12s
created

CRUDController::deleteAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 23
ccs 0
cts 13
cp 0
rs 9.0856
cc 2
eloc 13
nc 2
nop 1
crap 6
1
<?php
2
3
namespace LAG\AdminBundle\Controller;
4
5
use LAG\AdminBundle\Admin\AdminInterface;
6
use LAG\AdminBundle\Form\Handler\ListFormHandler;
7
use LAG\AdminBundle\Form\Type\AdminListType;
8
use LAG\AdminBundle\Form\Type\BatchActionType;
9
use Exception;
10
use LAG\AdminBundle\Form\Type\DeleteType;
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
12
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
13
use Symfony\Component\HttpFoundation\RedirectResponse;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
16
use Symfony\Component\PropertyAccess\PropertyAccess;
17
use Symfony\Component\Security\Core\Role\Role;
18
19
/**
20
 * Class CRUDController
21
 *
22
 * Generic CRUD controller
23
 */
24
class CRUDController extends Controller
25
{
26
    /**
27
     * Generic list action.
28
     *
29
     * @Template("LAGAdminBundle:CRUD:list.html.twig")
30
     * @param Request $request
31
     * @return array
32
     */
33
    public function listAction(Request $request)
34
    {
35
        // retrieve admin from request route parameters
36
        $admin = $this->getAdminFromRequest($request);
37
        $admin->handleRequest($request, $this->getUser());
38
39
        // retrieve batch actions from configuration
40
        $batchActions = $admin
41
            ->getCurrentAction()
42
            ->getConfiguration()
43
            ->getParameter('batch');
44
45
        // pass admin and current action to the view
46
        $viewParameters = [
47
            'admin' => $admin,
48
            'action' => $admin->getCurrentAction(),
49
        ];
50
51
        // if batch are configured, we handle a list of checkboxes
52
        if ($batchActions) {
53
            // creating list form
54
            $form = $this->createForm(AdminListType::class, [
55
                'entities' => $admin->getEntities()
56
            ], [
57
                'batch_actions' => $batchActions['items'],
58
                'admin' => $admin
59
            ]);
60
            $form->handleRequest($request);
61
62
            if ($form->isValid()) {
63
                // get ids and batch action from list form data
64
                $formHandler = new ListFormHandler();
65
                $data = $formHandler->handle($form);
66
67
                if (count($data['ids'])) {
68
                    $batchForm = $this->createForm(BatchActionType::class, [
69
                        'batch_action' => $data['batch_action'],
70
                        'entity_ids' => $data['ids']
71
                    ], [
72
                        'labels' => $data['labels']
73
                    ]);
74
75
                    // render batch view
76
                    return $this->render('LAGAdminBundle:CRUD:batch.html.twig', [
77
                        'admin' => $admin,
78
                        'form' => $batchForm->createView()
79
                    ]);
80
                } else {
81
                    $this
82
                        ->addFlash('info', 'lag.admin.batch_no_entities');
83
                }
84
85
            }
86
            $viewParameters['form'] = $form->createView();
87
        }
88
89
        return $viewParameters;
90
    }
91
92
    /**
93
     * @param Request $request
94
     * @return RedirectResponse
95
     */
96
    public function batchAction(Request $request)
97
    {
98
        $admin = $this->getAdminFromRequest($request);
99
        $admin->handleRequest($request, $this->getUser());
100
        // create batch action form
101
        $form = $this->createForm(BatchActionType::class, [
102
            'batch_action' => [],
103
            'entity_ids' => []
104
        ]);
105
        $form->handleRequest($request);
106
107
        if ($form->isValid()) {
108
            $data = $form->getData();
109
            $admin->load([
110
                'id' => $data['entity_ids']
111
            ]);
112
113
            if ($data['batch_action'] == 'delete') {
114
                $admin->remove();
115
            }
116
        } else {
117
            throw new NotFoundHttpException('Invalid batch parameters : '.$form->getErrors(true, false));
118
        }
119
        // redirect to list view
120
        return $this->redirectToRoute($admin->generateRouteName('list'));
121
    }
122
123
    /**
124
     * Generic create action.
125
     *
126
     * @Template("LAGAdminBundle:CRUD:edit.html.twig")
127
     * @param Request $request
128
     * @return array|RedirectResponse
129
     */
130 View Code Duplication
    public function createAction(Request $request)
131
    {
132
        $admin = $this->getAdminFromRequest($request);
133
        $admin->handleRequest($request, $this->getUser());
134
        
135
        // check permissions
136
        $this->forward404IfNotAllowed($admin);
137
        
138
        // create form
139
        $form = $this->createForm($admin->getConfiguration()->getParameter('form'), $admin->create());
140
        $form->handleRequest($request);
141
142
        if ($form->isValid()) {
143
            // save entity
144
            $success = $admin->save();
145
146
            if ($success) {
147
                // if save is pressed, user stay on the edit view
148
                if ($request->request->get('submit') == 'save') {
149
                    $editRoute = $admin->generateRouteName('edit');
150
151
                    return $this->redirectToRoute($editRoute, [
152
                        'id' => $admin->getUniqueEntity()->getId(),
153
                    ]);
154
                } else {
155
                    // otherwise user is redirected to list view
156
                    $listRoute = $admin->generateRouteName('list');
157
158
                    return $this->redirectToRoute($listRoute);
159
                }
160
            }
161
        }
162
        return [
163
            'admin' => $admin,
164
            'form' => $form->createView(),
165
        ];
166
    }
167
168
    /**
169
     * Generic edit action.
170
     *
171
     * @Template("LAGAdminBundle:CRUD:edit.html.twig")
172
     *
173
     * @param Request $request
174
     *
175
     * @return array|RedirectResponse
176
     */
177 View Code Duplication
    public function editAction(Request $request)
178
    {
179
        $admin = $this->getAdminFromRequest($request);
180
        $admin->handleRequest($request, $this->getUser());
181
        // check permissions
182
        $this->forward404IfNotAllowed($admin);
183
        // create form
184
        $form = $this->createForm($admin->getConfiguration()->getParameter('form'), $admin->getUniqueEntity());
185
        $form->handleRequest($request);
186
        $accessor = PropertyAccess::createPropertyAccessor();
187
188
        if ($form->isValid()) {
189
            $admin->save();
190
191
            if ($request->request->get('submit') == 'save') {
192
                $saveRoute = $admin->generateRouteName('edit');
193
194
                return $this->redirectToRoute($saveRoute, [
195
                    'id' => $accessor->getValue($admin->getUniqueEntity(), 'id'),
196
                ]);
197
            } else {
198
                $listRoute = $admin->generateRouteName('list');
199
                // redirect to list
200
                return $this->redirectToRoute($listRoute);
201
            }
202
        }
203
204
        return [
205
            'admin' => $admin,
206
            'form' => $form->createView(),
207
        ];
208
    }
209
210
    /**
211
     * Generic delete action.
212
     *
213
     * @Template("LAGAdminBundle:CRUD:delete.html.twig")
214
     * @param Request $request
215
     * @return RedirectResponse|array
216
     */
217
    public function deleteAction(Request $request)
218
    {
219
        $admin = $this->getAdminFromRequest($request);
220
        $admin->handleRequest($request, $this->getUser());
221
        // check permissions
222
        $this->forward404IfNotAllowed($admin);
223
        // create form to avoid deletion by url
224
        $form = $this->createForm(DeleteType::class, $admin->getUniqueEntity());
225
        $form->handleRequest($request);
226
227
        if ($form->isValid()) {
228
            $admin->remove();
229
            // redirect to list
230
            $listRoute = $admin->generateRouteName('list');
231
232
            return $this->redirectToRoute($listRoute);
233
        }
234
235
        return [
236
            'admin' => $admin,
237
            'form' => $form->createView(),
238
        ];
239
    }
240
241
    /**
242
     * Throw a 404 Exception if $boolean is false or null
243
     *
244
     * @param $boolean
245
     * @param string $message
246
     */
247
    protected function forward404Unless($boolean, $message = '404 Not Found')
248
    {
249
        if (!$boolean) {
250
            throw $this->createNotFoundException($message);
251
        }
252
    }
253
254
    /**
255
     * Forward to 404 if user is not allowed by configuration for an action.
256
     *
257
     * @param AdminInterface $admin
258
     */
259
    protected function forward404IfNotAllowed(AdminInterface $admin)
260
    {
261
        $this->forward404Unless($this->getUser(), 'You must be logged to access to this url');
262
        $roles = $this
263
            ->getUser()
264
            ->getRoles();
265
        // check permissions and actions
266
        $this->forward404Unless(
267
            $admin->isActionGranted($admin->getCurrentAction()->getName(), $roles),
268
            sprintf('User with roles %s not allowed for action "%s"',
269
                implode(', ', array_map(function(Role $role) {
270
                    return $role->getRole();
271
                }, $roles)),
272
                $admin->getCurrentAction()->getName()
273
            )
274
        );
275
    }
276
277
    /**
278
     * Return an Admin object according to the request route parameters.
279
     *
280
     * @param Request $request
281
     * @return AdminInterface
282
     * @throws Exception
283
     */
284
    protected function getAdminFromRequest(Request $request)
285
    {
286
        return $this
287
            ->get('lag.admin.request_handler')
288
            ->handle($request);
289
    }
290
}
291