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);
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(),
0 ignored issues
show
$this->getUser() is of type null|object, but the function expects a object<FOS\UserBundle\Model\User>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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