Completed
Push — master ( 91fdab...75a7b9 )
by
unknown
13:37
created

AdminListBundle/Controller/AdminListController.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\AdminListBundle\Controller;
4
5
use Doctrine\ORM\EntityManager;
6
use Kunstmaan\AdminBundle\Entity\EntityInterface;
7
use Kunstmaan\AdminBundle\Event\AdaptSimpleFormEvent;
8
use Kunstmaan\AdminBundle\Event\Events;
9
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
10
use Kunstmaan\AdminListBundle\AdminList\AdminList;
11
use Kunstmaan\AdminListBundle\AdminList\Configurator\AbstractAdminListConfigurator;
12
use Kunstmaan\AdminListBundle\AdminList\ItemAction\SimpleItemAction;
13
use Kunstmaan\AdminListBundle\AdminList\SortableInterface;
14
use Kunstmaan\AdminListBundle\Entity\LockableEntityInterface;
15
use Kunstmaan\AdminListBundle\Event\AdminListEvent;
16
use Kunstmaan\AdminListBundle\Event\AdminListEvents;
17
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
18
use Symfony\Component\HttpFoundation\RedirectResponse;
19
use Kunstmaan\AdminListBundle\Service\EntityVersionLockService;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpFoundation\Response;
22
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
23
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
24
use Symfony\Component\PropertyAccess\PropertyAccess;
25
26
/**
27
 * AdminListController
28
 */
29
abstract class AdminListController extends Controller
30
{
31
    /**
32
     * You can override this method to return the correct entity manager when using multiple databases ...
33
     *
34
     * @return \Doctrine\Common\Persistence\ObjectManager|object
0 ignored issues
show
Consider making the return type a bit more specific; maybe use \Doctrine\Common\Persistence\ObjectManager.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
35
     */
36
    protected function getEntityManager()
37
    {
38
        return $this->getDoctrine()->getManager();
39
    }
40
41
    /**
42
     * Shows the list of entities
43
     *
44
     * @param AbstractAdminListConfigurator $configurator
45
     * @param null|Request $request
46
     *
47
     * @return Response
48
     */
49
    protected function doIndexAction(AbstractAdminListConfigurator $configurator, Request $request)
50
    {
51
        $em = $this->getEntityManager();
52
        /* @var AdminList $adminList */
53
        $adminList = $this->container->get("kunstmaan_adminlist.factory")->createList($configurator, $em);
54
        $adminList->bindRequest($request);
55
56
        $this->buildSortableFieldActions($configurator);
57
58
        return new Response(
59
            $this->renderView(
60
                $configurator->getListTemplate(),
61
                array('adminlist' => $adminList, 'adminlistconfigurator' => $configurator, 'addparams' => array())
62
            )
63
        );
64
    }
65
66
    /**
67
     * Export a list of Entities
68
     *
69
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
70
     * @param string $_format The format to export to
71
     * @param null|Request $request
72
     *
73
     * @throws AccessDeniedHttpException
74
     *
75
     * @return Response
76
     */
77
    protected function doExportAction(AbstractAdminListConfigurator $configurator, $_format, Request $request = null)
78
    {
79
        if (!$configurator->canExport()) {
80
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
81
        }
82
83
        $em = $this->getEntityManager();
84
85
        /* @var AdminList $adminList */
86
        $adminList = $this->container->get("kunstmaan_adminlist.factory")->createExportList($configurator, $em);
87
        $adminList->bindRequest($request);
88
89
        return $this->container->get("kunstmaan_adminlist.service.export")->getDownloadableResponse($adminList, $_format);
90
    }
91
92
    /**
93
     * Creates and processes the form to add a new Entity
94
     *
95
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
96
     * @param string $type The type to add
97
     * @param null|Request $request
98
     *
99
     * @throws AccessDeniedHttpException
100
     *
101
     * @return Response
102
     */
103
    protected function doAddAction(AbstractAdminListConfigurator $configurator, $type = null, Request $request)
104
    {
105
        if (!$configurator->canAdd()) {
106
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
107
        }
108
109
        /* @var EntityManager $em */
110
        $em = $this->getEntityManager();
111
        $entityName = null;
112
        $entityName = (isset($type)) ? $type : $configurator->getRepositoryName();
113
114
        $classMetaData = $em->getClassMetadata($entityName);
115
        // Creates a new instance of the mapped class, without invoking the constructor.
116
        $classname = $classMetaData->getName();
117
        $helper = new $classname();
118
        $helper = $configurator->decorateNewEntity($helper);
119
120
        $formType = $configurator->getAdminType($helper);
121
122
        $event = new AdaptSimpleFormEvent($request, $formType, $helper, $configurator->getAdminTypeOptions());
123
        $event = $this->container->get('event_dispatcher')->dispatch(Events::ADAPT_SIMPLE_FORM, $event);
124
        $tabPane = $event->getTabPane();
125
126
        $form = $this->createForm($formType, $helper, $event->getOptions());
127
128 View Code Duplication
        if ($request->isMethod('POST')) {
129
            if ($tabPane) {
130
                $tabPane->bindRequest($request);
131
                $form = $tabPane->getForm();
132
            } else {
133
                $form->handleRequest($request);
134
            }
135
136
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
137
            if ($form->isSubmitted() && $form->isValid() && !$request->isXmlHttpRequest()) {
138
                $adminListEvent = new AdminListEvent($helper, $request, $form);
139
                $this->container->get('event_dispatcher')->dispatch(
140
                    AdminListEvents::PRE_ADD,
141
                    $adminListEvent
142
                );
143
144
                // Check if Response is given
145
                if ($adminListEvent->getResponse() instanceof Response) {
146
                    return $adminListEvent->getResponse();
147
                }
148
149
                // Set sort weight
150
                $helper = $this->setSortWeightOnNewItem($configurator, $helper);
151
152
                $em->persist($helper);
153
                $em->flush();
154
                $this->container->get('event_dispatcher')->dispatch(
155
                    AdminListEvents::POST_ADD,
156
                    $adminListEvent
157
                );
158
159
                // Check if Response is given
160
                if ($adminListEvent->getResponse() instanceof Response) {
161
                    return $adminListEvent->getResponse();
162
                }
163
164
                $indexUrl = $configurator->getIndexUrl();
165
166
                return new RedirectResponse(
167
                    $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
168
                );
169
            }
170
        }
171
172
        $params = [
173
            'form' => $form->createView(),
174
            'adminlistconfigurator' => $configurator,
175
            'entityVersionLockCheck' => false
176
        ];
177
178
        if ($tabPane) {
179
            $params = array_merge($params, array('tabPane' => $tabPane));
180
        }
181
182
        return new Response(
183
            $this->renderView($configurator->getAddTemplate(), $params)
184
        );
185
    }
186
187
    /**
188
     * Creates and processes the edit form for an Entity using its ID
189
     *
190
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
191
     * @param string $entityId The id of the entity that will be edited
192
     * @param null|Request $request
193
     *
194
     * @throws NotFoundHttpException
195
     * @throws AccessDeniedHttpException
196
     *
197
     * @return Response
198
     */
199
    protected function doEditAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
200
    {
201
        /* @var EntityManager $em */
202
        $em = $this->getEntityManager();
203
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
204
205
        if ($helper === null) {
206
            throw new NotFoundHttpException("Entity not found.");
207
        }
208
209
        if (!$configurator->canEdit($helper)) {
210
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
211
        }
212
213
        if ($helper instanceof LockableEntityInterface) {
214
            // This entity is locked
215
            if ($this->isLockableEntityLocked($helper)) {
216
                $indexUrl = $configurator->getIndexUrl();
217
                // Don't redirect to listing when coming from ajax request, needed for url chooser.
218
                if (!$request->isXmlHttpRequest()) {
219
                    /** @var EntityVersionLockService $entityVersionLockService*/
220
                    $entityVersionLockService = $this->container->get('kunstmaan_entity.admin_entity.entity_version_lock_service');
221
222
                    $user = $entityVersionLockService->getUsersWithEntityVersionLock($helper, $this->getUser());
223
                    $message = $this->container->get('translator')->trans('kuma_admin_list.edit.flash.locked', array('%user%' => implode(', ', $user)));
224
                    $this->addFlash(
225
                        FlashTypes::WARNING,
226
                        $message
227
                    );
228
                    return new RedirectResponse(
229
                        $this->generateUrl(
230
                            $indexUrl['path'],
231
                            isset($indexUrl['params']) ? $indexUrl['params'] : array()
232
                        )
233
                    );
234
                }
235
            }
236
        }
237
238
        $formType = $configurator->getAdminType($helper);
239
240
        $event = new AdaptSimpleFormEvent($request, $formType, $helper, $configurator->getAdminTypeOptions());
241
        $event = $this->container->get('event_dispatcher')->dispatch(Events::ADAPT_SIMPLE_FORM, $event);
242
        $tabPane = $event->getTabPane();
243
244
        $form = $this->createForm($formType, $helper, $event->getOptions());
245
246 View Code Duplication
        if ($request->isMethod('POST')) {
247
248
            if ($tabPane) {
249
                $tabPane->bindRequest($request);
250
                $form = $tabPane->getForm();
251
            } else {
252
                $form->handleRequest($request);
253
            }
254
255
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
256
            if ($form->isSubmitted() && $form->isValid() && !$request->isXmlHttpRequest()) {
257
                $adminListEvent = new AdminListEvent($helper, $request, $form);
258
                $this->container->get('event_dispatcher')->dispatch(
259
                    AdminListEvents::PRE_EDIT,
260
                    $adminListEvent
261
                );
262
263
                // Check if Response is given
264
                if ($adminListEvent->getResponse() instanceof Response) {
265
                    return $adminListEvent->getResponse();
266
                }
267
268
                $em->persist($helper);
269
                $em->flush();
270
                $this->container->get('event_dispatcher')->dispatch(
271
                    AdminListEvents::POST_EDIT,
272
                    $adminListEvent
273
                );
274
275
                // Check if Response is given
276
                if ($adminListEvent->getResponse() instanceof Response) {
277
                    return $adminListEvent->getResponse();
278
                }
279
280
                $indexUrl = $configurator->getIndexUrl();
281
282
                // Don't redirect to listing when coming from ajax request, needed for url chooser.
283
                if (!$request->isXmlHttpRequest()) {
284
                    return new RedirectResponse(
285
                        $this->generateUrl(
286
                            $indexUrl['path'],
287
                            isset($indexUrl['params']) ? $indexUrl['params'] : array()
288
                        )
289
                    );
290
                }
291
            }
292
        }
293
294
        $configurator->buildItemActions();
295
296
        $params = [
297
            'form' => $form->createView(),
298
            'entity' => $helper, 'adminlistconfigurator' => $configurator,
299
            'entityVersionLockInterval' => $this->container->getParameter('kunstmaan_entity.lock_check_interval'),
300
            'entityVersionLockCheck' => $this->container->getParameter('kunstmaan_entity.lock_enabled') && $helper instanceof LockableEntityInterface,
301
        ];
302
303
        if ($tabPane) {
304
            $params = array_merge($params, array('tabPane' => $tabPane));
305
        }
306
307
        return new Response(
308
            $this->renderView(
309
                $configurator->getEditTemplate(),
310
                $params
311
            )
312
        );
313
    }
314
315
    protected function doViewAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
316
    {
317
        /* @var EntityManager $em */
318
        $em = $this->getEntityManager();
319
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
320
        if ($helper === null) {
321
            throw new NotFoundHttpException("Entity not found.");
322
        }
323
324
        if (!$configurator->canView($helper)) {
325
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
326
        }
327
328
        $MetaData = $em->getClassMetadata($configurator->getRepositoryName());
329
        $fields = array();
330
        $accessor = PropertyAccess::createPropertyAccessor();
331
        foreach ($MetaData->fieldNames as $value) {
332
            $fields[$value] = $accessor->getValue($helper, $value);
333
        }
334
335
336
        return new Response(
337
            $this->renderView(
338
                $configurator->getViewTemplate(),
339
                array('entity' => $helper, 'adminlistconfigurator' => $configurator, 'fields' => $fields)
340
            )
341
        );
342
    }
343
344
    /**
345
     * Delete the Entity using its ID
346
     *
347
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
348
     * @param integer $entityId The id to delete
349
     * @param null|Request $request
350
     *
351
     * @throws NotFoundHttpException
352
     * @throws AccessDeniedHttpException
353
     *
354
     * @return Response
355
     */
356
    protected function doDeleteAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
357
    {
358
        /* @var $em EntityManager */
359
        $em = $this->getEntityManager();
360
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
361
        if ($helper === null) {
362
            throw new NotFoundHttpException("Entity not found.");
363
        }
364
        if (!$configurator->canDelete($helper)) {
365
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
366
        }
367
368
        $indexUrl = $configurator->getIndexUrl();
369
        if ($request->isMethod('POST')) {
370
            $adminListEvent = new AdminListEvent($helper, $request);
371
            $this->container->get('event_dispatcher')->dispatch(
372
                AdminListEvents::PRE_DELETE,
373
                $adminListEvent
374
            );
375
376
            // Check if Response is given
377
            if ($adminListEvent->getResponse() instanceof Response) {
378
                return $adminListEvent->getResponse();
379
            }
380
381
            $em->remove($helper);
382
            $em->flush();
383
            $this->container->get('event_dispatcher')->dispatch(
384
                AdminListEvents::POST_DELETE,
385
                $adminListEvent
386
            );
387
388
            // Check if Response is given
389
            if ($adminListEvent->getResponse() instanceof Response) {
390
                return $adminListEvent->getResponse();
391
            }
392
        }
393
394
        return new RedirectResponse(
395
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
396
        );
397
    }
398
399
    /**
400
     * Move an item up in the list.
401
     *
402
     * @return RedirectResponse
403
     */
404 View Code Duplication
    protected function doMoveUpAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
405
    {
406
        $em = $this->getEntityManager();
407
        $sortableField = $configurator->getSortableField();
408
        $repo = $em->getRepository($configurator->getRepositoryName());
409
        $item = $repo->find($entityId);
410
411
        $setter = "set".ucfirst($sortableField);
412
        $getter = "get".ucfirst($sortableField);
413
414
        $nextItem = $repo->createQueryBuilder('i')
415
            ->where('i.'.$sortableField.' < :weight')
416
            ->setParameter('weight', $item->$getter())
417
            ->orderBy('i.'.$sortableField, 'DESC')
418
            ->setMaxResults(1)
419
            ->getQuery()
420
            ->getOneOrNullResult();
421
        if ($nextItem) {
422
            $nextItem->$setter($item->$getter());
423
            $em->persist($nextItem);
424
            $item->$setter($item->$getter() - 1);
425
426
            $em->persist($item);
427
            $em->flush();
428
        }
429
430
        $indexUrl = $configurator->getIndexUrl();
431
432
        return new RedirectResponse(
433
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
434
        );
435
    }
436
437 View Code Duplication
    protected function doMoveDownAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
438
    {
439
        $em = $this->getEntityManager();
440
        $sortableField = $configurator->getSortableField();
441
        $repo = $em->getRepository($configurator->getRepositoryName());
442
        $item = $repo->find($entityId);
443
444
        $setter = "set".ucfirst($sortableField);
445
        $getter = "get".ucfirst($sortableField);
446
447
        $nextItem = $repo->createQueryBuilder('i')
448
            ->where('i.'.$sortableField.' > :weight')
449
            ->setParameter('weight', $item->$getter())
450
            ->orderBy('i.'.$sortableField, 'ASC')
451
            ->setMaxResults(1)
452
            ->getQuery()
453
            ->getOneOrNullResult();
454
        if ($nextItem) {
455
            $nextItem->$setter($item->$getter());
456
            $em->persist($nextItem);
457
            $item->$setter($item->$getter() + 1);
458
459
            $em->persist($item);
460
            $em->flush();
461
        }
462
463
        $indexUrl = $configurator->getIndexUrl();
464
465
        return new RedirectResponse(
466
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
467
        );
468
    }
469
470
    private function getMaxSortableField($repo, $sort)
471
    {
472
        $maxWeight = $repo->createQueryBuilder('i')
473
            ->select('max(i.'.$sort.')')
474
            ->getQuery()
475
            ->getSingleScalarResult();
476
477
        return (int)$maxWeight;
478
    }
479
480
    /**
481
     * @param LockableEntityInterface $entity
482
     * @return bool
483
     */
484
    protected function isLockableEntityLocked(LockableEntityInterface $entity)
485
    {
486
        /** @var EntityVersionLockService $entityVersionLockService */
487
        $entityVersionLockService = $this->container->get('kunstmaan_entity.admin_entity.entity_version_lock_service');
488
489
        return $entityVersionLockService->isEntityBelowThreshold($entity) && $entityVersionLockService->isEntityLocked(
490
                $this->getUser(),
491
                $entity
492
            );
493
    }
494
495
    /**
496
     * Sets the sort weight on a new item. Can be overridden if a non-default sorting implementation is being used.
497
     *
498
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
499
     * @param $item
500
     *
501
     * @return mixed
502
     */
503
    protected function setSortWeightOnNewItem(AbstractAdminListConfigurator $configurator, $item) {
504
        if ($configurator instanceof SortableInterface) {
505
            $repo = $this->getEntityManager()->getRepository($configurator->getRepositoryName());
506
            $sort = $configurator->getSortableField();
507
            $weight = $this->getMaxSortableField($repo, $sort);
508
            $setter = "set".ucfirst($sort);
509
            $item->$setter($weight + 1);
510
        }
511
512
        return $item;
513
    }
514
515
    protected function buildSortableFieldActions(AbstractAdminListConfigurator $configurator)
516
    {
517
        // Check if Sortable interface is implemented
518
        if ($configurator instanceof SortableInterface) {
519 View Code Duplication
            $route = function (EntityInterface $item) use ($configurator) {
520
                return array(
521
                    'path' => $configurator->getPathByConvention().'_move_up',
522
                    'params' => array('id' => $item->getId()),
523
                );
524
            };
525
526
            $action = new SimpleItemAction($route, 'arrow-up', 'kuma_admin_list.action.move_up');
527
            $configurator->addItemAction($action);
528
529 View Code Duplication
            $route = function (EntityInterface $item) use ($configurator) {
530
                return array(
531
                    'path' => $configurator->getPathByConvention().'_move_down',
532
                    'params' => array('id' => $item->getId()),
533
                );
534
            };
535
536
            $action = new SimpleItemAction($route, 'arrow-down', 'kuma_admin_list.action.move_down');
537
            $configurator->addItemAction($action);
538
        }
539
    }
540
}
541