Completed
Push — master ( 1db3cd...632e40 )
by Jeroen
24:52 queued 11:31
created

AdminListBundle/Controller/AdminListController.php (2 issues)

Labels
Severity

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 Kunstmaan\NodeBundle\Entity\HasNodeInterface;
18
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
19
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
20
use Symfony\Component\HttpFoundation\RedirectResponse;
21
use Kunstmaan\AdminListBundle\Service\EntityVersionLockService;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpFoundation\Response;
24
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
25
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
26
use Symfony\Component\PropertyAccess\PropertyAccess;
27
28
/**
29
 * AdminListController
30
 */
31
abstract class AdminListController extends Controller
32
{
33
    /**
34
     * You can override this method to return the correct entity manager when using multiple databases ...
35
     *
36
     * @return \Doctrine\Common\Persistence\ObjectManager|object
37
     */
38
    protected function getEntityManager()
39
    {
40
        return $this->getDoctrine()->getManager();
41
    }
42
43
    /**
44
     * Shows the list of entities
45
     *
46
     * @param AbstractAdminListConfigurator $configurator
47
     * @param null|Request                  $request
48
     *
49
     * @return Response
50
     */
51
    protected function doIndexAction(AbstractAdminListConfigurator $configurator, Request $request)
52
    {
53
        $em = $this->getEntityManager();
54
        /* @var AdminList $adminList */
55
        $adminList = $this->container->get('kunstmaan_adminlist.factory')->createList($configurator, $em);
56
        $adminList->bindRequest($request);
57
58
        $this->buildSortableFieldActions($configurator);
59
60
        return new Response(
61
            $this->renderView(
62
                $configurator->getListTemplate(),
63
                array('adminlist' => $adminList, 'adminlistconfigurator' => $configurator, 'addparams' => array())
64
            )
65
        );
66
    }
67
68
    /**
69
     * Export a list of Entities
70
     *
71
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
72
     * @param string                        $_format      The format to export to
73
     * @param null|Request                  $request
74
     *
75
     * @throws AccessDeniedHttpException
76
     *
77
     * @return Response
78
     */
79
    protected function doExportAction(AbstractAdminListConfigurator $configurator, $_format, Request $request = null)
80
    {
81
        if (!$configurator->canExport()) {
82
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
83
        }
84
85
        $em = $this->getEntityManager();
86
87
        /* @var AdminList $adminList */
88
        $adminList = $this->container->get('kunstmaan_adminlist.factory')->createExportList($configurator, $em);
89
        $adminList->bindRequest($request);
90
91
        return $this->container->get('kunstmaan_adminlist.service.export')->getDownloadableResponse($adminList, $_format);
92
    }
93
94
    /**
95
     * Creates and processes the form to add a new Entity
96
     *
97
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
98
     * @param string                        $type         The type to add
99
     * @param null|Request                  $request
100
     *
101
     * @throws AccessDeniedHttpException
102
     *
103
     * @return Response
104
     */
105
    protected function doAddAction(AbstractAdminListConfigurator $configurator, $type = null, Request $request)
106
    {
107
        if (!$configurator->canAdd()) {
108
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
109
        }
110
111
        /* @var EntityManager $em */
112
        $em = $this->getEntityManager();
113
        $entityName = null;
114
        $entityName = (isset($type)) ? $type : $configurator->getRepositoryName();
115
116
        $classMetaData = $em->getClassMetadata($entityName);
117
        // Creates a new instance of the mapped class, without invoking the constructor.
118
        $classname = $classMetaData->getName();
119
        $helper = new $classname();
120
        $helper = $configurator->decorateNewEntity($helper);
121
122
        $formType = $configurator->getAdminType($helper);
123
124
        $event = new AdaptSimpleFormEvent($request, $formType, $helper, $configurator->getAdminTypeOptions());
125
        $event = $this->container->get('event_dispatcher')->dispatch(Events::ADAPT_SIMPLE_FORM, $event);
126
        $tabPane = $event->getTabPane();
127
128
        $form = $this->createForm($formType, $helper, $event->getOptions());
129
130 View Code Duplication
        if ($request->isMethod('POST')) {
131
            if ($tabPane) {
132
                $tabPane->bindRequest($request);
133
                $form = $tabPane->getForm();
134
            } else {
135
                $form->handleRequest($request);
136
            }
137
138
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
139
            if ($form->isSubmitted() && $form->isValid() && !$request->isXmlHttpRequest()) {
140
                $adminListEvent = new AdminListEvent($helper, $request, $form);
141
                $this->container->get('event_dispatcher')->dispatch(
142
                    AdminListEvents::PRE_ADD,
143
                    $adminListEvent
144
                );
145
146
                // Check if Response is given
147
                if ($adminListEvent->getResponse() instanceof Response) {
148
                    return $adminListEvent->getResponse();
149
                }
150
151
                // Set sort weight
152
                $helper = $this->setSortWeightOnNewItem($configurator, $helper);
153
154
                $em->persist($helper);
155
                $em->flush();
156
                $this->container->get('event_dispatcher')->dispatch(
157
                    AdminListEvents::POST_ADD,
158
                    $adminListEvent
159
                );
160
161
                // Check if Response is given
162
                if ($adminListEvent->getResponse() instanceof Response) {
163
                    return $adminListEvent->getResponse();
164
                }
165
166
                $indexUrl = $configurator->getIndexUrl();
167
168
                return new RedirectResponse(
169
                    $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
170
                );
171
            }
172
        }
173
174
        $params = [
175
            'form' => $form->createView(),
176
            'adminlistconfigurator' => $configurator,
177
            'entityVersionLockCheck' => false,
178
        ];
179
180
        if ($tabPane) {
181
            $params = array_merge($params, array('tabPane' => $tabPane));
182
        }
183
184
        return new Response(
185
            $this->renderView($configurator->getAddTemplate(), $params)
186
        );
187
    }
188
189
    /**
190
     * Creates and processes the edit form for an Entity using its ID
191
     *
192
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
193
     * @param string                        $entityId     The id of the entity that will be edited
194
     * @param null|Request                  $request
195
     *
196
     * @throws NotFoundHttpException
197
     * @throws AccessDeniedHttpException
198
     *
199
     * @return Response
200
     */
201
    protected function doEditAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
202
    {
203
        /* @var EntityManager $em */
204
        $em = $this->getEntityManager();
205
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
206
207
        if ($helper === null) {
208
            throw new NotFoundHttpException('Entity not found.');
209
        }
210
211
        if (!$configurator->canEdit($helper)) {
212
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
213
        }
214
215
        if ($helper instanceof LockableEntityInterface) {
216
            // This entity is locked
217
            if ($this->isLockableEntityLocked($helper)) {
218
                $indexUrl = $configurator->getIndexUrl();
219
                // Don't redirect to listing when coming from ajax request, needed for url chooser.
220
                if (!$request->isXmlHttpRequest()) {
221
                    /** @var EntityVersionLockService $entityVersionLockService */
222
                    $entityVersionLockService = $this->container->get('kunstmaan_entity.admin_entity.entity_version_lock_service');
223
224
                    $user = $entityVersionLockService->getUsersWithEntityVersionLock($helper, $this->getUser());
225
                    $message = $this->container->get('translator')->trans('kuma_admin_list.edit.flash.locked', array('%user%' => implode(', ', $user)));
226
                    $this->addFlash(
227
                        FlashTypes::WARNING,
228
                        $message
229
                    );
230
231
                    return new RedirectResponse(
232
                        $this->generateUrl(
233
                            $indexUrl['path'],
234
                            isset($indexUrl['params']) ? $indexUrl['params'] : array()
235
                        )
236
                    );
237
                }
238
            }
239
        }
240
241
        $formType = $configurator->getAdminType($helper);
242
243
        $event = new AdaptSimpleFormEvent($request, $formType, $helper, $configurator->getAdminTypeOptions());
244
        $event = $this->container->get('event_dispatcher')->dispatch(Events::ADAPT_SIMPLE_FORM, $event);
245
        $tabPane = $event->getTabPane();
246
247
        $form = $this->createForm($formType, $helper, $event->getOptions());
248
249 View Code Duplication
        if ($request->isMethod('POST')) {
250
            if ($tabPane) {
251
                $tabPane->bindRequest($request);
252
                $form = $tabPane->getForm();
253
            } else {
254
                $form->handleRequest($request);
255
            }
256
257
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
258
            if ($form->isSubmitted() && $form->isValid() && !$request->isXmlHttpRequest()) {
259
                $adminListEvent = new AdminListEvent($helper, $request, $form);
260
                $this->container->get('event_dispatcher')->dispatch(
261
                    AdminListEvents::PRE_EDIT,
262
                    $adminListEvent
263
                );
264
265
                // Check if Response is given
266
                if ($adminListEvent->getResponse() instanceof Response) {
267
                    return $adminListEvent->getResponse();
268
                }
269
270
                $em->persist($helper);
271
                $em->flush();
272
                $this->container->get('event_dispatcher')->dispatch(
273
                    AdminListEvents::POST_EDIT,
274
                    $adminListEvent
275
                );
276
277
                // Check if Response is given
278
                if ($adminListEvent->getResponse() instanceof Response) {
279
                    return $adminListEvent->getResponse();
280
                }
281
282
                $indexUrl = $configurator->getIndexUrl();
283
284
                // Don't redirect to listing when coming from ajax request, needed for url chooser.
285
                if (!$request->isXmlHttpRequest()) {
286
                    return new RedirectResponse(
287
                        $this->generateUrl(
288
                            $indexUrl['path'],
289
                            isset($indexUrl['params']) ? $indexUrl['params'] : array()
290
                        )
291
                    );
292
                }
293
            }
294
        }
295
296
        $configurator->buildItemActions();
297
298
        $params = [
299
            'form' => $form->createView(),
300
            'entity' => $helper, 'adminlistconfigurator' => $configurator,
301
            'entityVersionLockInterval' => $this->container->getParameter('kunstmaan_entity.lock_check_interval'),
302
            'entityVersionLockCheck' => $this->container->getParameter('kunstmaan_entity.lock_enabled') && $helper instanceof LockableEntityInterface,
303
        ];
304
305
        if ($tabPane) {
306
            $params = array_merge($params, array('tabPane' => $tabPane));
307
        }
308
309
        return new Response(
310
            $this->renderView(
311
                $configurator->getEditTemplate(),
312
                $params
313
            )
314
        );
315
    }
316
317
    protected function doViewAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
318
    {
319
        /* @var EntityManager $em */
320
        $em = $this->getEntityManager();
321
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
322
        if ($helper === null) {
323
            throw new NotFoundHttpException('Entity not found.');
324
        }
325
326
        if (!$configurator->canView($helper)) {
327
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
328
        }
329
330
        $MetaData = $em->getClassMetadata($configurator->getRepositoryName());
331
        $fields = array();
332
        $accessor = PropertyAccess::createPropertyAccessor();
333
        foreach ($MetaData->fieldNames as $value) {
334
            $fields[$value] = $accessor->getValue($helper, $value);
335
        }
336
337
        return new Response(
338
            $this->renderView(
339
                $configurator->getViewTemplate(),
340
                array('entity' => $helper, 'adminlistconfigurator' => $configurator, 'fields' => $fields)
341
            )
342
        );
343
    }
344
345
    /**
346
     * Delete the Entity using its ID
347
     *
348
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
349
     * @param int                           $entityId     The id to delete
350
     * @param null|Request                  $request
351
     *
352
     * @throws NotFoundHttpException
353
     * @throws AccessDeniedHttpException
354
     *
355
     * @return Response
356
     */
357
    protected function doDeleteAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
358
    {
359
        /* @var $em EntityManager */
360
        $em = $this->getEntityManager();
361
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
362
        if ($helper === null) {
363
            throw new NotFoundHttpException('Entity not found.');
364
        }
365
        if (!$configurator->canDelete($helper)) {
366
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
367
        }
368
369
        $indexUrl = $configurator->getIndexUrl();
370
        if ($request->isMethod('POST')) {
371
            $adminListEvent = new AdminListEvent($helper, $request);
372
            $this->container->get('event_dispatcher')->dispatch(
373
                AdminListEvents::PRE_DELETE,
374
                $adminListEvent
375
            );
376
377
            // Check if Response is given
378
            if ($adminListEvent->getResponse() instanceof Response) {
379
                return $adminListEvent->getResponse();
380
            }
381
382
            $em->remove($helper);
383
            $em->flush();
384
            $this->container->get('event_dispatcher')->dispatch(
385
                AdminListEvents::POST_DELETE,
386
                $adminListEvent
387
            );
388
389
            // Check if Response is given
390
            if ($adminListEvent->getResponse() instanceof Response) {
391
                return $adminListEvent->getResponse();
392
            }
393
        }
394
395
        return new RedirectResponse(
396
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
397
        );
398
    }
399
400
    /**
401
     * Move an item up in the list.
402
     *
403
     * @return RedirectResponse
404
     */
405 View Code Duplication
    protected function doMoveUpAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
406
    {
407
        $em = $this->getEntityManager();
408
        $sortableField = $configurator->getSortableField();
0 ignored issues
show
The method getSortableField() does not seem to exist on object<Kunstmaan\AdminLi...tAdminListConfigurator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
409
410
        $repositoryName = $this->getAdminListRepositoryName($configurator);
411
412
        $repo = $em->getRepository($repositoryName);
413
        $item = $repo->find($entityId);
414
415
        $setter = 'set'.ucfirst($sortableField);
416
        $getter = 'get'.ucfirst($sortableField);
417
418
        $nextItem = $repo->createQueryBuilder('i')
419
            ->where('i.'.$sortableField.' < :weight')
420
            ->setParameter('weight', $item->$getter())
421
            ->orderBy('i.'.$sortableField, 'DESC')
422
            ->setMaxResults(1)
423
            ->getQuery()
424
            ->getOneOrNullResult();
425
        if ($nextItem) {
426
            $nextItem->$setter($item->$getter());
427
            $em->persist($nextItem);
428
            $item->$setter($item->$getter() - 1);
429
430
            $em->persist($item);
431
            $em->flush();
432
        }
433
434
        $indexUrl = $configurator->getIndexUrl();
435
436
        return new RedirectResponse(
437
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
438
        );
439
    }
440
441 View Code Duplication
    protected function doMoveDownAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
442
    {
443
        $em = $this->getEntityManager();
444
        $sortableField = $configurator->getSortableField();
0 ignored issues
show
The method getSortableField() does not seem to exist on object<Kunstmaan\AdminLi...tAdminListConfigurator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
445
446
        $repositoryName = $this->getAdminListRepositoryName($configurator);
447
448
        $repo = $em->getRepository($repositoryName);
449
        $item = $repo->find($entityId);
450
451
        $setter = 'set'.ucfirst($sortableField);
452
        $getter = 'get'.ucfirst($sortableField);
453
454
        $nextItem = $repo->createQueryBuilder('i')
455
            ->where('i.'.$sortableField.' > :weight')
456
            ->setParameter('weight', $item->$getter())
457
            ->orderBy('i.'.$sortableField, 'ASC')
458
            ->setMaxResults(1)
459
            ->getQuery()
460
            ->getOneOrNullResult();
461
        if ($nextItem) {
462
            $nextItem->$setter($item->$getter());
463
            $em->persist($nextItem);
464
            $item->$setter($item->$getter() + 1);
465
466
            $em->persist($item);
467
            $em->flush();
468
        }
469
470
        $indexUrl = $configurator->getIndexUrl();
471
472
        return new RedirectResponse(
473
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
474
        );
475
    }
476
477
    private function getMaxSortableField($repo, $sort)
478
    {
479
        $maxWeight = $repo->createQueryBuilder('i')
480
            ->select('max(i.'.$sort.')')
481
            ->getQuery()
482
            ->getSingleScalarResult();
483
484
        return (int) $maxWeight;
485
    }
486
487
    /**
488
     * @param LockableEntityInterface $entity
489
     *
490
     * @return bool
491
     */
492
    protected function isLockableEntityLocked(LockableEntityInterface $entity)
493
    {
494
        /** @var EntityVersionLockService $entityVersionLockService */
495
        $entityVersionLockService = $this->container->get('kunstmaan_entity.admin_entity.entity_version_lock_service');
496
497
        return $entityVersionLockService->isEntityBelowThreshold($entity) && $entityVersionLockService->isEntityLocked(
498
                $this->getUser(),
499
                $entity
500
            );
501
    }
502
503
    /**
504
     * Sets the sort weight on a new item. Can be overridden if a non-default sorting implementation is being used.
505
     *
506
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
507
     * @param $item
508
     *
509
     * @return mixed
510
     */
511
    protected function setSortWeightOnNewItem(AbstractAdminListConfigurator $configurator, $item)
512
    {
513
        if ($configurator instanceof SortableInterface) {
514
            $repo = $this->getEntityManager()->getRepository($configurator->getRepositoryName());
515
            $sort = $configurator->getSortableField();
516
            $weight = $this->getMaxSortableField($repo, $sort);
517
            $setter = 'set'.ucfirst($sort);
518
            $item->$setter($weight + 1);
519
        }
520
521
        return $item;
522
    }
523
524
    protected function buildSortableFieldActions(AbstractAdminListConfigurator $configurator)
525
    {
526
        // Check if Sortable interface is implemented
527
        if ($configurator instanceof SortableInterface) {
528 View Code Duplication
            $route = function (EntityInterface $item) use ($configurator) {
529
                return array(
530
                    'path' => $configurator->getPathByConvention().'_move_up',
531
                    'params' => array('id' => $item->getId()),
532
                );
533
            };
534
535
            $action = new SimpleItemAction($route, 'arrow-up', 'kuma_admin_list.action.move_up');
536
            $configurator->addItemAction($action);
537
538 View Code Duplication
            $route = function (EntityInterface $item) use ($configurator) {
539
                return array(
540
                    'path' => $configurator->getPathByConvention().'_move_down',
541
                    'params' => array('id' => $item->getId()),
542
                );
543
            };
544
545
            $action = new SimpleItemAction($route, 'arrow-down', 'kuma_admin_list.action.move_down');
546
            $configurator->addItemAction($action);
547
        }
548
    }
549
550
    /**
551
     * @param AbstractAdminListConfigurator $configurator
552
     *
553
     * @return string
554
     */
555
    protected function getAdminListRepositoryName(AbstractAdminListConfigurator $configurator)
556
    {
557
        $em = $this->getEntityManager();
558
        $className = $em->getClassMetadata($configurator->getRepositoryName())->getName();
559
560
        $implements = class_implements($className);
561
        if (isset($implements[HasNodeInterface::class])) {
562
            return NodeTranslation::class;
563
        }
564
565
        return $configurator->getRepositoryName();
566
    }
567
}
568