Completed
Push — l10n_master ( 6cb695...818918 )
by Kunstmaan
50:17 queued 35: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 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
        /* @var AdminList $adminList */
54
        $adminList = $this->container->get('kunstmaan_adminlist.factory')->createList($configurator);
55
        $adminList->bindRequest($request);
56
57
        $this->buildSortableFieldActions($configurator);
58
59
        return new Response(
60
            $this->renderView(
61
                $configurator->getListTemplate(),
62
                array('adminlist' => $adminList, 'adminlistconfigurator' => $configurator, 'addparams' => array())
63
            )
64
        );
65
    }
66
67
    /**
68
     * Export a list of Entities
69
     *
70
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
71
     * @param string                        $_format      The format to export to
72
     * @param null|Request                  $request
73
     *
74
     * @throws AccessDeniedHttpException
75
     *
76
     * @return Response
77
     */
78
    protected function doExportAction(AbstractAdminListConfigurator $configurator, $_format, Request $request = null)
79
    {
80
        if (!$configurator->canExport()) {
81
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
82
        }
83
84
        /* @var AdminList $adminList */
85
        $adminList = $this->container->get('kunstmaan_adminlist.factory')->createExportList($configurator);
86
        $adminList->bindRequest($request);
87
88
        return $this->container->get('kunstmaan_adminlist.service.export')->getDownloadableResponse($adminList, $_format);
89
    }
90
91
    /**
92
     * Creates and processes the form to add a new Entity
93
     *
94
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
95
     * @param string                        $type         The type to add
96
     * @param null|Request                  $request
97
     *
98
     * @throws AccessDeniedHttpException
99
     *
100
     * @return Response
101
     */
102
    protected function doAddAction(AbstractAdminListConfigurator $configurator, $type = null, Request $request)
103
    {
104
        if (!$configurator->canAdd()) {
105
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
106
        }
107
108
        /* @var EntityManager $em */
109
        $em = $this->getEntityManager();
110
        $entityName = isset($type) ? $type : $configurator->getRepositoryName();
111
112
        $classMetaData = $em->getClassMetadata($entityName);
113
        // Creates a new instance of the mapped class, without invoking the constructor.
114
        $classname = $classMetaData->getName();
115
        $helper = new $classname();
116
        $helper = $configurator->decorateNewEntity($helper);
117
118
        $formType = $configurator->getAdminType($helper);
119
120
        $event = new AdaptSimpleFormEvent($request, $formType, $helper, $configurator->getAdminTypeOptions());
121
        $event = $this->container->get('event_dispatcher')->dispatch(Events::ADAPT_SIMPLE_FORM, $event);
122
        $tabPane = $event->getTabPane();
123
124
        $form = $this->createForm($formType, $helper, $event->getOptions());
125
126 View Code Duplication
        if ($request->isMethod('POST')) {
127
            if ($tabPane) {
128
                $tabPane->bindRequest($request);
129
                $form = $tabPane->getForm();
130
            } else {
131
                $form->handleRequest($request);
132
            }
133
134
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
135
            if ($form->isSubmitted() && $form->isValid() && !$request->isXmlHttpRequest()) {
136
                $adminListEvent = new AdminListEvent($helper, $request, $form);
137
                $this->container->get('event_dispatcher')->dispatch(
138
                    AdminListEvents::PRE_ADD,
139
                    $adminListEvent
140
                );
141
142
                // Check if Response is given
143
                if ($adminListEvent->getResponse() instanceof Response) {
144
                    return $adminListEvent->getResponse();
145
                }
146
147
                // Set sort weight
148
                $helper = $this->setSortWeightOnNewItem($configurator, $helper);
149
150
                $em->persist($helper);
151
                $em->flush();
152
                $this->container->get('event_dispatcher')->dispatch(
153
                    AdminListEvents::POST_ADD,
154
                    $adminListEvent
155
                );
156
157
                // Check if Response is given
158
                if ($adminListEvent->getResponse() instanceof Response) {
159
                    return $adminListEvent->getResponse();
160
                }
161
162
                $indexUrl = $configurator->getIndexUrl();
163
164
                return new RedirectResponse(
165
                    $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
166
                );
167
            }
168
        }
169
170
        $params = [
171
            'form' => $form->createView(),
172
            'adminlistconfigurator' => $configurator,
173
            'entityVersionLockCheck' => false,
174
        ];
175
176
        if ($tabPane) {
177
            $params = array_merge($params, array('tabPane' => $tabPane));
178
        }
179
180
        return new Response(
181
            $this->renderView($configurator->getAddTemplate(), $params)
182
        );
183
    }
184
185
    /**
186
     * Creates and processes the edit form for an Entity using its ID
187
     *
188
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
189
     * @param string                        $entityId     The id of the entity that will be edited
190
     * @param null|Request                  $request
191
     *
192
     * @throws NotFoundHttpException
193
     * @throws AccessDeniedHttpException
194
     *
195
     * @return Response
196
     */
197
    protected function doEditAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
198
    {
199
        /* @var EntityManager $em */
200
        $em = $this->getEntityManager();
201
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
202
203
        if ($helper === null) {
204
            throw new NotFoundHttpException('Entity not found.');
205
        }
206
207
        if (!$configurator->canEdit($helper)) {
208
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
209
        }
210
211
        // This entity is locked
212
        if (($helper instanceof LockableEntityInterface) && $this->isLockableEntityLocked($helper)) {
213
            $indexUrl = $configurator->getIndexUrl();
214
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
215
            if (!$request->isXmlHttpRequest()) {
216
                /** @var EntityVersionLockService $entityVersionLockService */
217
                $entityVersionLockService = $this->container->get('kunstmaan_entity.admin_entity.entity_version_lock_service');
218
219
                $user = $entityVersionLockService->getUsersWithEntityVersionLock($helper, $this->getUser());
220
                $message = $this->container->get('translator')->trans('kuma_admin_list.edit.flash.locked', array('%user%' => implode(', ', $user)));
221
                $this->addFlash(
222
                    FlashTypes::WARNING,
223
                    $message
224
                );
225
226
                return new RedirectResponse(
227
                    $this->generateUrl(
228
                        $indexUrl['path'],
229
                        isset($indexUrl['params']) ? $indexUrl['params'] : array()
230
                    )
231
                );
232
            }
233
        }
234
235
        $formType = $configurator->getAdminType($helper);
236
237
        $event = new AdaptSimpleFormEvent($request, $formType, $helper, $configurator->getAdminTypeOptions());
238
        $event = $this->container->get('event_dispatcher')->dispatch(Events::ADAPT_SIMPLE_FORM, $event);
239
        $tabPane = $event->getTabPane();
240
241
        $form = $this->createForm($formType, $helper, $event->getOptions());
242
243 View Code Duplication
        if ($request->isMethod('POST')) {
244
            if ($tabPane) {
245
                $tabPane->bindRequest($request);
246
                $form = $tabPane->getForm();
247
            } else {
248
                $form->handleRequest($request);
249
            }
250
251
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
252
            if ($form->isSubmitted() && $form->isValid() && !$request->isXmlHttpRequest()) {
253
                $adminListEvent = new AdminListEvent($helper, $request, $form);
254
                $this->container->get('event_dispatcher')->dispatch(
255
                    AdminListEvents::PRE_EDIT,
256
                    $adminListEvent
257
                );
258
259
                // Check if Response is given
260
                if ($adminListEvent->getResponse() instanceof Response) {
261
                    return $adminListEvent->getResponse();
262
                }
263
264
                $em->persist($helper);
265
                $em->flush();
266
                $this->container->get('event_dispatcher')->dispatch(
267
                    AdminListEvents::POST_EDIT,
268
                    $adminListEvent
269
                );
270
271
                // Check if Response is given
272
                if ($adminListEvent->getResponse() instanceof Response) {
273
                    return $adminListEvent->getResponse();
274
                }
275
276
                $indexUrl = $configurator->getIndexUrl();
277
278
                // Don't redirect to listing when coming from ajax request, needed for url chooser.
279
                if (!$request->isXmlHttpRequest()) {
280
                    return new RedirectResponse(
281
                        $this->generateUrl(
282
                            $indexUrl['path'],
283
                            isset($indexUrl['params']) ? $indexUrl['params'] : array()
284
                        )
285
                    );
286
                }
287
            }
288
        }
289
290
        $configurator->buildItemActions();
291
292
        $params = [
293
            'form' => $form->createView(),
294
            'entity' => $helper, 'adminlistconfigurator' => $configurator,
295
            'entityVersionLockInterval' => $this->container->getParameter('kunstmaan_entity.lock_check_interval'),
296
            'entityVersionLockCheck' => $this->container->getParameter('kunstmaan_entity.lock_enabled') && $helper instanceof LockableEntityInterface,
297
        ];
298
299
        if ($tabPane) {
300
            $params = array_merge($params, array('tabPane' => $tabPane));
301
        }
302
303
        return new Response(
304
            $this->renderView(
305
                $configurator->getEditTemplate(),
306
                $params
307
            )
308
        );
309
    }
310
311
    protected function doViewAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
312
    {
313
        /* @var EntityManager $em */
314
        $em = $this->getEntityManager();
315
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
0 ignored issues
show
The method findOneById() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findOneBy()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
316
        if ($helper === null) {
317
            throw new NotFoundHttpException('Entity not found.');
318
        }
319
320
        if (!$configurator->canView($helper)) {
321
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
322
        }
323
324
        $MetaData = $em->getClassMetadata($configurator->getRepositoryName());
325
        $fields = array();
326
        $accessor = PropertyAccess::createPropertyAccessor();
327
        foreach ($MetaData->fieldNames as $value) {
328
            $fields[$value] = $accessor->getValue($helper, $value);
329
        }
330
331
        return new Response(
332
            $this->renderView(
333
                $configurator->getViewTemplate(),
334
                array('entity' => $helper, 'adminlistconfigurator' => $configurator, 'fields' => $fields)
335
            )
336
        );
337
    }
338
339
    /**
340
     * Delete the Entity using its ID
341
     *
342
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
343
     * @param int                           $entityId     The id to delete
344
     * @param null|Request                  $request
345
     *
346
     * @throws NotFoundHttpException
347
     * @throws AccessDeniedHttpException
348
     *
349
     * @return Response
350
     */
351
    protected function doDeleteAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
352
    {
353
        /* @var $em EntityManager */
354
        $em = $this->getEntityManager();
355
        $helper = $em->getRepository($configurator->getRepositoryName())->findOneById($entityId);
356
        if ($helper === null) {
357
            throw new NotFoundHttpException('Entity not found.');
358
        }
359
        if (!$configurator->canDelete($helper)) {
360
            throw $this->createAccessDeniedException('You do not have sufficient rights to access this page.');
361
        }
362
363
        $indexUrl = $configurator->getIndexUrl();
364
        if ($request->isMethod('POST')) {
365
            $adminListEvent = new AdminListEvent($helper, $request);
366
            $this->container->get('event_dispatcher')->dispatch(
367
                AdminListEvents::PRE_DELETE,
368
                $adminListEvent
369
            );
370
371
            // Check if Response is given
372
            if ($adminListEvent->getResponse() instanceof Response) {
373
                return $adminListEvent->getResponse();
374
            }
375
376
            $em->remove($helper);
377
            $em->flush();
378
            $this->container->get('event_dispatcher')->dispatch(
379
                AdminListEvents::POST_DELETE,
380
                $adminListEvent
381
            );
382
383
            // Check if Response is given
384
            if ($adminListEvent->getResponse() instanceof Response) {
385
                return $adminListEvent->getResponse();
386
            }
387
        }
388
389
        return new RedirectResponse(
390
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
391
        );
392
    }
393
394
    /**
395
     * Move an item up in the list.
396
     *
397
     * @return RedirectResponse
398
     */
399 View Code Duplication
    protected function doMoveUpAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
400
    {
401
        $em = $this->getEntityManager();
402
        $sortableField = $configurator->getSortableField();
403
404
        $repositoryName = $this->getAdminListRepositoryName($configurator);
405
406
        $repo = $em->getRepository($repositoryName);
407
        $item = $repo->find($entityId);
408
409
        $setter = 'set'.ucfirst($sortableField);
410
        $getter = 'get'.ucfirst($sortableField);
411
412
        $nextItem = $repo->createQueryBuilder('i')
413
            ->where('i.'.$sortableField.' < :weight')
414
            ->setParameter('weight', $item->$getter())
415
            ->orderBy('i.'.$sortableField, 'DESC')
416
            ->setMaxResults(1)
417
            ->getQuery()
418
            ->getOneOrNullResult();
419
        if ($nextItem) {
420
            $nextItem->$setter($item->$getter());
421
            $em->persist($nextItem);
422
            $item->$setter($item->$getter() - 1);
423
424
            $em->persist($item);
425
            $em->flush();
426
        }
427
428
        $indexUrl = $configurator->getIndexUrl();
429
430
        return new RedirectResponse(
431
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
432
        );
433
    }
434
435 View Code Duplication
    protected function doMoveDownAction(AbstractAdminListConfigurator $configurator, $entityId, Request $request)
436
    {
437
        $em = $this->getEntityManager();
438
        $sortableField = $configurator->getSortableField();
439
440
        $repositoryName = $this->getAdminListRepositoryName($configurator);
441
442
        $repo = $em->getRepository($repositoryName);
443
        $item = $repo->find($entityId);
444
445
        $setter = 'set'.ucfirst($sortableField);
446
        $getter = 'get'.ucfirst($sortableField);
447
448
        $nextItem = $repo->createQueryBuilder('i')
449
            ->where('i.'.$sortableField.' > :weight')
450
            ->setParameter('weight', $item->$getter())
451
            ->orderBy('i.'.$sortableField, 'ASC')
452
            ->setMaxResults(1)
453
            ->getQuery()
454
            ->getOneOrNullResult();
455
        if ($nextItem) {
456
            $nextItem->$setter($item->$getter());
457
            $em->persist($nextItem);
458
            $item->$setter($item->$getter() + 1);
459
460
            $em->persist($item);
461
            $em->flush();
462
        }
463
464
        $indexUrl = $configurator->getIndexUrl();
465
466
        return new RedirectResponse(
467
            $this->generateUrl($indexUrl['path'], isset($indexUrl['params']) ? $indexUrl['params'] : array())
468
        );
469
    }
470
471
    private function getMaxSortableField($repo, $sort)
472
    {
473
        $maxWeight = $repo->createQueryBuilder('i')
474
            ->select('max(i.'.$sort.')')
475
            ->getQuery()
476
            ->getSingleScalarResult();
477
478
        return (int) $maxWeight;
479
    }
480
481
    /**
482
     * @param LockableEntityInterface $entity
483
     *
484
     * @return bool
485
     */
486
    protected function isLockableEntityLocked(LockableEntityInterface $entity)
487
    {
488
        /** @var EntityVersionLockService $entityVersionLockService */
489
        $entityVersionLockService = $this->container->get('kunstmaan_entity.admin_entity.entity_version_lock_service');
490
491
        return $entityVersionLockService->isEntityBelowThreshold($entity) && $entityVersionLockService->isEntityLocked(
492
                $this->getUser(),
493
                $entity
494
            );
495
    }
496
497
    /**
498
     * Sets the sort weight on a new item. Can be overridden if a non-default sorting implementation is being used.
499
     *
500
     * @param AbstractAdminListConfigurator $configurator The adminlist configurator
501
     * @param $item
502
     *
503
     * @return mixed
504
     */
505
    protected function setSortWeightOnNewItem(AbstractAdminListConfigurator $configurator, $item)
506
    {
507
        if ($configurator instanceof SortableInterface) {
508
            $repo = $this->getEntityManager()->getRepository($configurator->getRepositoryName());
509
            $sort = $configurator->getSortableField();
510
            $weight = $this->getMaxSortableField($repo, $sort);
511
            $setter = 'set'.ucfirst($sort);
512
            $item->$setter($weight + 1);
513
        }
514
515
        return $item;
516
    }
517
518
    protected function buildSortableFieldActions(AbstractAdminListConfigurator $configurator)
519
    {
520
        // Check if Sortable interface is implemented
521
        if ($configurator instanceof SortableInterface) {
522 View Code Duplication
            $route = function (EntityInterface $item) use ($configurator) {
523
                return array(
524
                    'path' => $configurator->getPathByConvention().'_move_up',
525
                    'params' => array('id' => $item->getId()),
526
                );
527
            };
528
529
            $action = new SimpleItemAction($route, 'arrow-up', 'kuma_admin_list.action.move_up');
530
            $configurator->addItemAction($action);
531
532 View Code Duplication
            $route = function (EntityInterface $item) use ($configurator) {
533
                return array(
534
                    'path' => $configurator->getPathByConvention().'_move_down',
535
                    'params' => array('id' => $item->getId()),
536
                );
537
            };
538
539
            $action = new SimpleItemAction($route, 'arrow-down', 'kuma_admin_list.action.move_down');
540
            $configurator->addItemAction($action);
541
        }
542
    }
543
544
    /**
545
     * @param AbstractAdminListConfigurator $configurator
546
     *
547
     * @return string
548
     */
549
    protected function getAdminListRepositoryName(AbstractAdminListConfigurator $configurator)
550
    {
551
        $em = $this->getEntityManager();
552
        $className = $em->getClassMetadata($configurator->getRepositoryName())->getName();
553
554
        $implements = class_implements($className);
555
        if (isset($implements[HasNodeInterface::class])) {
556
            return NodeTranslation::class;
557
        }
558
559
        return $configurator->getRepositoryName();
560
    }
561
}
562