Completed
Pull Request — dev (#9)
by Arnaud
02:46
created

CRUDController::getAdminFromRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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