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

AdminListBundle/Controller/AdminListController.php (7 issues)

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
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
0 ignored issues
show
Consider making the type for parameter $request a bit more specific; maybe use Request.
Loading history...
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
0 ignored issues
show
Should the type for parameter $type not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
97
     * @param null|Request $request
0 ignored issues
show
Consider making the type for parameter $request a bit more specific; maybe use Request.
Loading history...
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
0 ignored issues
show
Consider making the type for parameter $request a bit more specific; maybe use Request.
Loading history...
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
0 ignored issues
show
Consider making the type for parameter $request a bit more specific; maybe use Request.
Loading history...
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)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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