Completed
Push — master ( 1de9b7...830752 )
by Kristof
38:46 queued 24:09
created

NodeBundle/Controller/NodeAdminController.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\NodeBundle\Controller;
4
5
use DateTime;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use Doctrine\ORM\EntityManager;
8
use InvalidArgumentException;
9
use Kunstmaan\AdminBundle\Entity\BaseUser;
10
use Kunstmaan\AdminBundle\Entity\EntityInterface;
11
use Kunstmaan\AdminBundle\Entity\User;
12
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
13
use Kunstmaan\AdminBundle\Helper\FormWidgets\FormWidget;
14
use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\Tab;
15
use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\TabPane;
16
use Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper;
17
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMap;
18
use Kunstmaan\AdminBundle\Service\AclManager;
19
use Kunstmaan\AdminListBundle\AdminList\AdminList;
20
use Kunstmaan\NodeBundle\AdminList\NodeAdminListConfigurator;
21
use Kunstmaan\NodeBundle\Entity\HasNodeInterface;
22
use Kunstmaan\NodeBundle\Entity\Node;
23
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
24
use Kunstmaan\NodeBundle\Entity\NodeVersion;
25
use Kunstmaan\NodeBundle\Event\AdaptFormEvent;
26
use Kunstmaan\NodeBundle\Event\CopyPageTranslationNodeEvent;
27
use Kunstmaan\NodeBundle\Event\Events;
28
use Kunstmaan\NodeBundle\Event\NodeEvent;
29
use Kunstmaan\NodeBundle\Event\RecopyPageTranslationNodeEvent;
30
use Kunstmaan\NodeBundle\Event\RevertNodeAction;
31
use Kunstmaan\NodeBundle\Form\NodeMenuTabAdminType;
32
use Kunstmaan\NodeBundle\Form\NodeMenuTabTranslationAdminType;
33
use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeAdminPublisher;
34
use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeVersionLockHelper;
35
use Kunstmaan\NodeBundle\Repository\NodeVersionRepository;
36
use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
37
use Symfony\Component\Routing\Annotation\Route;
38
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
39
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
40
use Symfony\Component\HttpFoundation\JsonResponse;
41
use Symfony\Component\HttpFoundation\RedirectResponse;
42
use Symfony\Component\HttpFoundation\Request;
43
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
44
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
45
use Symfony\Component\Translation\TranslatorInterface;
46
47
/**
48
 * NodeAdminController
49
 */
50
class NodeAdminController extends Controller
51
{
52
    /**
53
     * @var EntityManager
54
     */
55
    protected $em;
56
57
    /**
58
     * @var string
59
     */
60
    protected $locale;
61
62
    /**
63
     * @var AuthorizationCheckerInterface
64
     */
65
    protected $authorizationChecker;
66
67
    /**
68
     * @var BaseUser
69
     */
70
    protected $user;
71
72
    /**
73
     * @var AclHelper
74
     */
75
    protected $aclHelper;
76
77
    /**
78
     * @var AclManager
79
     */
80
    protected $aclManager;
81
82
    /**
83
     * @var NodeAdminPublisher
84
     */
85
    protected $nodePublisher;
86
87
    /**
88
     * @var TranslatorInterface
89
     */
90
    protected $translator;
91
92
    /**
93
     * init
94
     *
95
     * @param Request $request
96
     */
97
    protected function init(Request $request)
98
    {
99
        $this->em = $this->getDoctrine()->getManager();
100
        $this->locale = $request->getLocale();
101
        $this->authorizationChecker = $this->container->get('security.authorization_checker');
102
        $this->user = $this->getUser();
103
        $this->aclHelper = $this->container->get('kunstmaan_admin.acl.helper');
104
        $this->aclManager = $this->container->get('kunstmaan_admin.acl.manager');
105
        $this->nodePublisher = $this->container->get('kunstmaan_node.admin_node.publisher');
106
        $this->translator = $this->container->get('translator');
107
    }
108
109
    /**
110
     * @Route("/", name="KunstmaanNodeBundle_nodes")
111
     * @Template("KunstmaanNodeBundle:Admin:list.html.twig")
112
     *
113
     * @param Request $request
114
     *
115
     * @return array
116
     */
117
    public function indexAction(Request $request)
118
    {
119
        $this->init($request);
120
121
        $nodeAdminListConfigurator = new NodeAdminListConfigurator(
122
            $this->em,
123
            $this->aclHelper,
124
            $this->locale,
125
            PermissionMap::PERMISSION_VIEW,
126
            $this->authorizationChecker
127
        );
128
129
        $locale = $this->locale;
130
        $acl = $this->authorizationChecker;
131
        $itemRoute = function (EntityInterface $item) use ($locale, $acl) {
132
            if ($acl->isGranted(PermissionMap::PERMISSION_VIEW, $item->getNode())) {
133
                return array(
134
                    'path' => '_slug_preview',
135
                    'params' => ['_locale' => $locale, 'url' => $item->getUrl()],
136
                );
137
            }
138
        };
139
        $nodeAdminListConfigurator->addSimpleItemAction('action.preview', $itemRoute, 'eye');
140
        $nodeAdminListConfigurator->setDomainConfiguration($this->get('kunstmaan_admin.domain_configuration'));
141
        $nodeAdminListConfigurator->setShowAddHomepage($this->getParameter('kunstmaan_node.show_add_homepage') && $this->isGranted('ROLE_SUPER_ADMIN'));
142
143
        /** @var AdminList $adminlist */
144
        $adminlist = $this->get('kunstmaan_adminlist.factory')->createList($nodeAdminListConfigurator);
145
        $adminlist->bindRequest($request);
146
147
        return array(
148
            'adminlist' => $adminlist,
149
        );
150
    }
151
152
    /**
153
     * @Route(
154
     *      "/{id}/copyfromotherlanguage",
155
     *      requirements={"id" = "\d+"},
156
     *      name="KunstmaanNodeBundle_nodes_copyfromotherlanguage",
157
     *      methods={"GET"}
158
     * )
159
     *
160
     * @param Request $request
161
     * @param int     $id      The node id
162
     *
163
     * @return RedirectResponse
164
     *
165
     * @throws AccessDeniedException
166
     */
167
    public function copyFromOtherLanguageAction(Request $request, $id)
168
    {
169
        $this->init($request);
170
        /* @var Node $node */
171
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
172
173
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
174
175
        $originalLanguage = $request->get('originallanguage');
176
        $otherLanguageNodeTranslation = $node->getNodeTranslation($originalLanguage, true);
177
        $otherLanguageNodeNodeVersion = $otherLanguageNodeTranslation->getPublicNodeVersion();
178
        $otherLanguagePage = $otherLanguageNodeNodeVersion->getRef($this->em);
179
        $myLanguagePage = $this->get('kunstmaan_admin.clone.helper')
180
            ->deepCloneAndSave($otherLanguagePage);
181
182
        /* @var NodeTranslation $nodeTranslation */
183
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
184
            ->createNodeTranslationFor($myLanguagePage, $this->locale, $node, $this->user);
185
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
186
187
        $this->get('event_dispatcher')->dispatch(
188
            Events::COPY_PAGE_TRANSLATION,
189
            new CopyPageTranslationNodeEvent(
190
                $node,
191
                $nodeTranslation,
192
                $nodeVersion,
193
                $myLanguagePage,
194
                $otherLanguageNodeTranslation,
195
                $otherLanguageNodeNodeVersion,
196
                $otherLanguagePage,
197
                $originalLanguage
198
            )
199
        );
200
201
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
202
    }
203
204
    /**
205
     * @Route(
206
     *      "/{id}/recopyfromotherlanguage",
207
     *      requirements={"id" = "\d+"},
208
     *      name="KunstmaanNodeBundle_nodes_recopyfromotherlanguage",
209
     *      methods={"POST"}
210
     * )
211
     *
212
     * @param Request $request
213
     * @param int     $id      The node id
214
     *
215
     * @return RedirectResponse
216
     *
217
     * @throws AccessDeniedException
218
     */
219
    public function recopyFromOtherLanguageAction(Request $request, $id)
220
    {
221
        $this->init($request);
222
        /* @var Node $node */
223
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
224
225
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
226
227
        $otherLanguageNodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')->find($request->get('source'));
228
        $otherLanguageNodeNodeVersion = $otherLanguageNodeTranslation->getPublicNodeVersion();
229
        $otherLanguagePage = $otherLanguageNodeNodeVersion->getRef($this->em);
230
        $myLanguagePage = $this->get('kunstmaan_admin.clone.helper')
231
            ->deepCloneAndSave($otherLanguagePage);
232
233
        /* @var NodeTranslation $nodeTranslation */
234
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
235
            ->addDraftNodeVersionFor($myLanguagePage, $this->locale, $node, $this->user);
236
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
237
238
        $this->get('event_dispatcher')->dispatch(
239
            Events::RECOPY_PAGE_TRANSLATION,
240
            new RecopyPageTranslationNodeEvent(
241
                $node,
242
                $nodeTranslation,
243
                $nodeVersion,
244
                $myLanguagePage,
245
                $otherLanguageNodeTranslation,
246
                $otherLanguageNodeNodeVersion,
247
                $otherLanguagePage,
248
                $otherLanguageNodeTranslation->getLang()
249
            )
250
        );
251
252
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id, 'subaction' => NodeVersion::DRAFT_VERSION)));
253
    }
254
255
    /**
256
     * @Route(
257
     *      "/{id}/createemptypage",
258
     *      requirements={"id" = "\d+"},
259
     *      name="KunstmaanNodeBundle_nodes_createemptypage",
260
     *      methods={"GET"}
261
     * )
262
     *
263
     * @param Request $request
264
     * @param int     $id
265
     *
266
     * @return RedirectResponse
267
     *
268
     * @throws AccessDeniedException
269
     */
270
    public function createEmptyPageAction(Request $request, $id)
271
    {
272
        $this->init($request);
273
        /* @var Node $node */
274
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
275
276
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
277
278
        $entityName = $node->getRefEntityName();
279
        /* @var HasNodeInterface $myLanguagePage */
280
        $myLanguagePage = new $entityName();
281
        $myLanguagePage->setTitle('New page');
282
283
        $this->em->persist($myLanguagePage);
284
        $this->em->flush();
285
        /* @var NodeTranslation $nodeTranslation */
286
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
287
            ->createNodeTranslationFor($myLanguagePage, $this->locale, $node, $this->user);
288
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
289
290
        $this->get('event_dispatcher')->dispatch(
291
            Events::ADD_EMPTY_PAGE_TRANSLATION,
292
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $myLanguagePage)
293
        );
294
295
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
296
    }
297
298
    /**
299
     * @Route("/{id}/publish", requirements={"id" =
300
     *                         "\d+"},
301
     *                         name="KunstmaanNodeBundle_nodes_publish", methods={"GET", "POST"})
302
     *
303
     * @param Request $request
304
     * @param int     $id
305
     *
306
     * @return RedirectResponse
307
     *
308
     * @throws AccessDeniedException
309
     */
310 View Code Duplication
    public function publishAction(Request $request, $id)
311
    {
312
        $this->init($request);
313
        /* @var Node $node */
314
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
315
316
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
317
        $request = $this->get('request_stack')->getCurrentRequest();
318
        $this->nodePublisher->chooseHowToPublish($request, $nodeTranslation, $this->translator);
319
320
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
321
    }
322
323
    /**
324
     * @Route(
325
     *      "/{id}/unpublish",
326
     *      requirements={"id" = "\d+"},
327
     *      name="KunstmaanNodeBundle_nodes_unpublish",
328
     *      methods={"GET", "POST"}
329
     * )
330
     *
331
     * @param Request $request
332
     * @param int     $id
333
     *
334
     * @return RedirectResponse
335
     *
336
     * @throws AccessDeniedException
337
     */
338 View Code Duplication
    public function unPublishAction(Request $request, $id)
339
    {
340
        $this->init($request);
341
        /* @var Node $node */
342
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
343
344
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
345
        $request = $this->get('request_stack')->getCurrentRequest();
346
        $this->nodePublisher->chooseHowToUnpublish($request, $nodeTranslation, $this->translator);
347
348
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
349
    }
350
351
    /**
352
     * @Route(
353
     *      "/{id}/unschedulepublish",
354
     *      requirements={"id" = "\d+"},
355
     *      name="KunstmaanNodeBundle_nodes_unschedule_publish",
356
     *      methods={"GET", "POST"}
357
     * )
358
     *
359
     * @param Request $request
360
     * @param int     $id
361
     *
362
     * @return RedirectResponse
363
     *
364
     * @throws AccessDeniedException
365
     */
366 View Code Duplication
    public function unSchedulePublishAction(Request $request, $id)
367
    {
368
        $this->init($request);
369
370
        /* @var Node $node */
371
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
372
373
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
374
        $this->nodePublisher->unSchedulePublish($nodeTranslation);
375
376
        $this->addFlash(
377
            FlashTypes::SUCCESS,
378
            $this->get('translator')->trans('kuma_node.admin.unschedule.flash.success')
379
        );
380
381
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
382
    }
383
384
    /**
385
     * @Route(
386
     *      "/{id}/delete",
387
     *      requirements={"id" = "\d+"},
388
     *      name="KunstmaanNodeBundle_nodes_delete",
389
     *      methods={"POST"}
390
     * )
391
     *
392
     * @param Request $request
393
     * @param int     $id
394
     *
395
     * @return RedirectResponse
396
     *
397
     * @throws AccessDeniedException
398
     */
399
    public function deleteAction(Request $request, $id)
400
    {
401
        $this->init($request);
402
        /* @var Node $node */
403
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
404
405
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_DELETE, $node);
406
407
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
408
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
409
        $page = $nodeVersion->getRef($this->em);
410
411
        $this->get('event_dispatcher')->dispatch(
412
            Events::PRE_DELETE,
413
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
414
        );
415
416
        $node->setDeleted(true);
417
        $this->em->persist($node);
418
419
        $children = $node->getChildren();
420
        $this->deleteNodeChildren($this->em, $this->user, $this->locale, $children);
421
        $this->em->flush();
422
423
        $event = new NodeEvent($node, $nodeTranslation, $nodeVersion, $page);
424
        $this->get('event_dispatcher')->dispatch(Events::POST_DELETE, $event);
425
        if (null === $response = $event->getResponse()) {
426
            $nodeParent = $node->getParent();
427
            // Check if we have a parent. Otherwise redirect to pages overview.
428
            if ($nodeParent) {
429
                $url = $this->get('router')->generate(
430
                    'KunstmaanNodeBundle_nodes_edit',
431
                    array('id' => $nodeParent->getId())
432
                );
433
            } else {
434
                $url = $this->get('router')->generate(
435
                    'KunstmaanNodeBundle_nodes'
436
                );
437
            }
438
            $response = new RedirectResponse($url);
439
        }
440
441
        $this->addFlash(
442
            FlashTypes::SUCCESS,
443
            $this->get('translator')->trans('kuma_node.admin.delete.flash.success')
444
        );
445
446
        return $response;
447
    }
448
449
    /**
450
     * @Route(
451
     *      "/{id}/duplicate",
452
     *      requirements={"id" = "\d+"},
453
     *      name="KunstmaanNodeBundle_nodes_duplicate",
454
     *      methods={"POST"}
455
     * )
456
     *
457
     * @param Request $request
458
     * @param int     $id
459
     *
460
     * @return RedirectResponse
461
     *
462
     * @throws AccessDeniedException
463
     */
464
    public function duplicateAction(Request $request, $id)
465
    {
466
        $this->init($request);
467
        /* @var Node $parentNode */
468
        $originalNode = $this->em->getRepository('KunstmaanNodeBundle:Node')
469
            ->find($id);
470
471
        // Check with Acl
472
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $originalNode);
473
474
        $request = $this->get('request_stack')->getCurrentRequest();
475
476
        $originalNodeTranslations = $originalNode->getNodeTranslation($this->locale, true);
477
        $originalRef = $originalNodeTranslations->getPublicNodeVersion()->getRef($this->em);
478
        $newPage = $this->get('kunstmaan_admin.clone.helper')
479
            ->deepCloneAndSave($originalRef);
480
481
        //set the title
482
        $title = $request->get('title');
483
        if (is_string($title) && !empty($title)) {
484
            $newPage->setTitle($title);
485
        } else {
486
            $newPage->setTitle('New page');
487
        }
488
489
        //set the parent
490
        $parentNodeTranslation = $originalNode->getParent()->getNodeTranslation($this->locale, true);
491
        $parent = $parentNodeTranslation->getPublicNodeVersion()->getRef($this->em);
492
        $newPage->setParent($parent);
493
        $this->em->persist($newPage);
494
        $this->em->flush();
495
496
        /* @var Node $nodeNewPage */
497
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')->createNodeFor(
498
            $newPage,
499
            $this->locale,
500
            $this->user
501
        );
502
503
        $nodeTranslation = $nodeNewPage->getNodeTranslation($this->locale, true);
504
        if ($newPage->isStructureNode()) {
505
            $nodeTranslation->setSlug('');
506
            $this->em->persist($nodeTranslation);
507
        }
508
        $this->em->flush();
509
510
        $this->aclManager->updateNodeAcl($originalNode, $nodeNewPage);
511
512
        $this->addFlash(
513
            FlashTypes::SUCCESS,
514
            $this->get('translator')->trans('kuma_node.admin.duplicate.flash.success')
515
        );
516
517
        return $this->redirect(
518
            $this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $nodeNewPage->getId()))
519
        );
520
    }
521
522
    /**
523
     * @Route(
524
     *      "/{id}/revert",
525
     *      requirements={"id" = "\d+"},
526
     *      defaults={"subaction" = "public"},
527
     *      name="KunstmaanNodeBundle_nodes_revert",
528
     *      methods={"GET"}
529
     * )
530
     *
531
     * @param Request $request
532
     * @param int     $id      The node id
533
     *
534
     * @return RedirectResponse
535
     *
536
     * @throws AccessDeniedException
537
     * @throws InvalidArgumentException
538
     */
539
    public function revertAction(Request $request, $id)
540
    {
541
        $this->init($request);
542
        /* @var Node $node */
543
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
544
545
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
546
547
        $version = $request->get('version');
548
549
        if (empty($version) || !is_numeric($version)) {
550
            throw new InvalidArgumentException('No version was specified');
551
        }
552
553
        /* @var NodeVersionRepository $nodeVersionRepo */
554
        $nodeVersionRepo = $this->em->getRepository('KunstmaanNodeBundle:NodeVersion');
555
        /* @var NodeVersion $nodeVersion */
556
        $nodeVersion = $nodeVersionRepo->find($version);
557
558
        if (is_null($nodeVersion)) {
559
            throw new InvalidArgumentException('Version does not exist');
560
        }
561
562
        /* @var NodeTranslation $nodeTranslation */
563
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
564
        $page = $nodeVersion->getRef($this->em);
565
        /* @var HasNodeInterface $clonedPage */
566
        $clonedPage = $this->get('kunstmaan_admin.clone.helper')
567
            ->deepCloneAndSave($page);
568
        $newNodeVersion = $nodeVersionRepo->createNodeVersionFor(
569
            $clonedPage,
570
            $nodeTranslation,
571
            $this->user,
572
            $nodeVersion,
573
            'draft'
574
        );
575
576
        $nodeTranslation->setTitle($clonedPage->getTitle());
577
        $this->em->persist($nodeTranslation);
578
        $this->em->flush();
579
580
        $this->get('event_dispatcher')->dispatch(
581
            Events::REVERT,
582
            new RevertNodeAction(
583
                $node,
584
                $nodeTranslation,
585
                $newNodeVersion,
586
                $clonedPage,
587
                $nodeVersion,
588
                $page
589
            )
590
        );
591
592
        $this->addFlash(
593
            FlashTypes::SUCCESS,
594
            $this->get('translator')->trans('kuma_node.admin.revert.flash.success')
595
        );
596
597
        return $this->redirect(
598
            $this->generateUrl(
599
                'KunstmaanNodeBundle_nodes_edit',
600
                array(
601
                    'id' => $id,
602
                    'subaction' => 'draft',
603
                )
604
            )
605
        );
606
    }
607
608
    /**
609
     * @Route(
610
     *      "/{id}/add",
611
     *      requirements={"id" = "\d+"},
612
     *      name="KunstmaanNodeBundle_nodes_add",
613
     *      methods={"POST"}
614
     * )
615
     *
616
     * @param Request $request
617
     * @param int     $id
618
     *
619
     * @return RedirectResponse
620
     *
621
     * @throws AccessDeniedException
622
     * @throws InvalidArgumentException
623
     */
624
    public function addAction(Request $request, $id)
625
    {
626
        $this->init($request);
627
        /* @var Node $parentNode */
628
        $parentNode = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
629
630
        // Check with Acl
631
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parentNode);
632
633
        $parentNodeTranslation = $parentNode->getNodeTranslation($this->locale, true);
634
        $parentNodeVersion = $parentNodeTranslation->getPublicNodeVersion();
635
        $parentPage = $parentNodeVersion->getRef($this->em);
636
637
        $type = $this->validatePageType($request);
638
        $newPage = $this->createNewPage($request, $type);
639
        $newPage->setParent($parentPage);
640
641
        /* @var Node $nodeNewPage */
642
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')
643
            ->createNodeFor($newPage, $this->locale, $this->user);
644
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
645
            $this->locale,
646
            true
647
        );
648
        $weight = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
649
                ->getMaxChildrenWeight($parentNode, $this->locale) + 1;
650
        $nodeTranslation->setWeight($weight);
651
652
        if ($newPage->isStructureNode()) {
653
            $nodeTranslation->setSlug('');
654
        }
655
656
        $this->em->persist($nodeTranslation);
657
        $this->em->flush();
658
659
        $this->aclManager->updateNodeAcl($parentNode, $nodeNewPage);
660
661
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
662
663
        $this->get('event_dispatcher')->dispatch(
664
            Events::ADD_NODE,
665
            new NodeEvent(
666
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
667
            )
668
        );
669
670
        return $this->redirect(
671
            $this->generateUrl(
672
                'KunstmaanNodeBundle_nodes_edit',
673
                array('id' => $nodeNewPage->getId())
674
            )
675
        );
676
    }
677
678
    /**
679
     * @Route("/add-homepage", name="KunstmaanNodeBundle_nodes_add_homepage", methods={"POST"})
680
     *
681
     * @return RedirectResponse
682
     *
683
     * @throws AccessDeniedException
684
     * @throws InvalidArgumentException
685
     */
686
    public function addHomepageAction(Request $request)
687
    {
688
        $this->init($request);
689
690
        // Check with Acl
691
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
692
693
        $type = $this->validatePageType($request);
694
695
        $newPage = $this->createNewPage($request, $type);
696
697
        /* @var Node $nodeNewPage */
698
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')
699
            ->createNodeFor($newPage, $this->locale, $this->user);
700
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
701
            $this->locale,
702
            true
703
        );
704
        $this->em->flush();
705
706
        // Set default permissions
707
        $this->container->get('kunstmaan_node.acl_permission_creator_service')
708
            ->createPermission($nodeNewPage);
709
710
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
711
712
        $this->get('event_dispatcher')->dispatch(
713
            Events::ADD_NODE,
714
            new NodeEvent(
715
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
716
            )
717
        );
718
719
        return $this->redirect(
720
            $this->generateUrl(
721
                'KunstmaanNodeBundle_nodes_edit',
722
                array('id' => $nodeNewPage->getId())
723
            )
724
        );
725
    }
726
727
    /**
728
     * @Route("/reorder", name="KunstmaanNodeBundle_nodes_reorder", methods={"POST"})
729
     *
730
     * @param Request $request
731
     *
732
     * @return string
0 ignored issues
show
Should the return type not be JsonResponse?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
733
     *
734
     * @throws AccessDeniedException
735
     */
736
    public function reorderAction(Request $request)
737
    {
738
        $this->init($request);
739
        $nodes = array();
740
        $nodeIds = $request->get('nodes');
741
        $changeParents = $request->get('parent');
742
743
        foreach ($nodeIds as $id) {
744
            /* @var Node $node */
745
            $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
746
            $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
747
            $nodes[] = $node;
748
        }
749
750
        $weight = 0;
751
        foreach ($nodes as $node) {
752
            $newParentId = isset($changeParents[$node->getId()]) ? $changeParents[$node->getId()] : null;
753
            if ($newParentId) {
754
                $parent = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($newParentId);
755
                $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parent);
756
                $node->setParent($parent);
757
                $this->em->persist($node);
758
                $this->em->flush($node);
759
            }
760
761
            /* @var NodeTranslation $nodeTranslation */
762
            $nodeTranslation = $node->getNodeTranslation($this->locale, true);
763
764
            if ($nodeTranslation) {
765
                $nodeVersion = $nodeTranslation->getPublicNodeVersion();
766
                $page = $nodeVersion->getRef($this->em);
767
768
                $this->get('event_dispatcher')->dispatch(
769
                    Events::PRE_PERSIST,
770
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
771
                );
772
773
                $nodeTranslation->setWeight($weight);
774
                $this->em->persist($nodeTranslation);
775
                $this->em->flush($nodeTranslation);
776
777
                $this->get('event_dispatcher')->dispatch(
778
                    Events::POST_PERSIST,
779
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
780
                );
781
782
                ++$weight;
783
            }
784
        }
785
786
        return new JsonResponse(
787
            array(
788
                'Success' => 'The node-translations for [' . $this->locale . '] have got new weight values',
789
            )
790
        );
791
    }
792
793
    /**
794
     * @Route(
795
     *      "/{id}/{subaction}",
796
     *      requirements={"id" = "\d+"},
797
     *      defaults={"subaction" = "public"},
798
     *      name="KunstmaanNodeBundle_nodes_edit",
799
     *      methods={"GET", "POST"}
800
     * )
801
     * @Template("@KunstmaanNode/NodeAdmin/edit.html.twig")
802
     *
803
     * @param Request $request
804
     * @param int     $id        The node id
805
     * @param string  $subaction The subaction (draft|public)
806
     *
807
     * @return RedirectResponse|array
808
     *
809
     * @throws AccessDeniedException
810
     */
811
    public function editAction(Request $request, $id, $subaction)
812
    {
813
        $this->init($request);
814
        /* @var Node $node */
815
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
816
817
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
818
819
        $tabPane = new TabPane(
820
            'todo',
821
            $request,
822
            $this->container->get('form.factory')
823
        );
824
825
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
826
        if (!$nodeTranslation) {
827
            return $this->renderNodeNotTranslatedPage($node);
828
        }
829
830
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
831
        $draftNodeVersion = $nodeTranslation->getDraftNodeVersion();
832
        $nodeVersionIsLocked = false;
833
834
        /* @var HasNodeInterface $page */
835
        $page = null;
836
        $draft = ($subaction == 'draft');
837
        $saveAsDraft = $request->get('saveasdraft');
838
        if ((!$draft && !empty($saveAsDraft)) || ($draft && is_null($draftNodeVersion))) {
839
            // Create a new draft version
840
            $draft = true;
841
            $subaction = 'draft';
842
            $page = $nodeVersion->getRef($this->em);
843
            $nodeVersion = $this->createDraftVersion(
844
                $page,
845
                $nodeTranslation,
846
                $nodeVersion
847
            );
848
            $draftNodeVersion = $nodeVersion;
849
        } elseif ($draft) {
850
            $nodeVersion = $draftNodeVersion;
851
            $page = $nodeVersion->getRef($this->em);
852
        } else {
853
            if ($request->getMethod() == 'POST') {
854
                $nodeVersionIsLocked = $this->isNodeVersionLocked($nodeTranslation, true);
855
856
                //Check the version timeout and make a new nodeversion if the timeout is passed
857
                $thresholdDate = date(
858
                    'Y-m-d H:i:s',
859
                    time() - $this->getParameter(
860
                        'kunstmaan_node.version_timeout'
861
                    )
862
                );
863
                $updatedDate = date(
864
                    'Y-m-d H:i:s',
865
                    strtotime($nodeVersion->getUpdated()->format('Y-m-d H:i:s'))
866
                );
867 View Code Duplication
                if ($thresholdDate >= $updatedDate || $nodeVersionIsLocked) {
868
                    $page = $nodeVersion->getRef($this->em);
869
                    if ($nodeVersion == $nodeTranslation->getPublicNodeVersion()) {
870
                        $this->nodePublisher
871
                            ->createPublicVersion(
872
                                $page,
873
                                $nodeTranslation,
874
                                $nodeVersion,
875
                                $this->user
876
                            );
877
                    } else {
878
                        $this->createDraftVersion(
879
                            $page,
880
                            $nodeTranslation,
881
                            $nodeVersion
882
                        );
883
                    }
884
                }
885
            }
886
            $page = $nodeVersion->getRef($this->em);
887
        }
888
        $isStructureNode = $page->isStructureNode();
889
890
        $menubuilder = $this->get('kunstmaan_node.actions_menu_builder');
891
        $menubuilder->setActiveNodeVersion($nodeVersion);
892
        $menubuilder->setEditableNode(!$isStructureNode);
893
894
        // Building the form
895
        $propertiesWidget = new FormWidget();
896
        $propertiesWidget->addType('main', $page->getDefaultAdminType(), $page);
897
        $propertiesWidget->addType('node', $node->getDefaultAdminType(), $node);
898
        $tabPane->addTab(new Tab('kuma_node.tab.properties.title', $propertiesWidget));
899
900
        // Menu tab
901
        $menuWidget = new FormWidget();
902
        $menuWidget->addType(
903
            'menunodetranslation',
904
            NodeMenuTabTranslationAdminType::class,
905
            $nodeTranslation,
906
            ['slugable' => !$isStructureNode]
907
        );
908
        $menuWidget->addType('menunode', NodeMenuTabAdminType::class, $node, ['available_in_nav' => !$isStructureNode]);
909
        $tabPane->addTab(new Tab('kuma_node.tab.menu.title', $menuWidget));
910
911
        $this->get('event_dispatcher')->dispatch(
912
            Events::ADAPT_FORM,
913
            new AdaptFormEvent(
914
                $request,
915
                $tabPane,
916
                $page,
917
                $node,
918
                $nodeTranslation,
919
                $nodeVersion
920
            )
921
        );
922
923
        $tabPane->buildForm();
924
925
        if ($request->getMethod() == 'POST') {
926
            $tabPane->bindRequest($request);
927
928
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
929
            if ($tabPane->isValid() && !$request->isXmlHttpRequest()) {
930
                $this->get('event_dispatcher')->dispatch(
931
                    Events::PRE_PERSIST,
932
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
933
                );
934
935
                $nodeTranslation->setTitle($page->getTitle());
936
                if ($isStructureNode) {
937
                    $nodeTranslation->setSlug('');
938
                }
939
                $nodeVersion->setUpdated(new DateTime());
940
                if ($nodeVersion->getType() == 'public') {
941
                    $nodeTranslation->setUpdated($nodeVersion->getUpdated());
942
                }
943
                $this->em->persist($nodeTranslation);
944
                $this->em->persist($nodeVersion);
945
                $tabPane->persist($this->em);
946
                $this->em->flush();
947
948
                $this->get('event_dispatcher')->dispatch(
949
                    Events::POST_PERSIST,
950
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
951
                );
952
953
                if ($nodeVersionIsLocked) {
954
                    $this->addFlash(
955
                        FlashTypes::SUCCESS,
956
                        $this->get('translator')->trans('kuma_node.admin.edit.flash.locked_success')
957
                    );
958
                } else {
959
                    if ($request->request->has('publishing') || $request->request->has('publish_later')) {
960
                        $this->nodePublisher->chooseHowToPublish($request, $nodeTranslation, $this->translator);
961
                    } elseif ($request->request->has('unpublishing') || $request->request->has('unpublish_later')) {
962
                        $this->nodePublisher->chooseHowToUnpublish($request, $nodeTranslation, $this->translator);
963
                    } else {
964
                        $this->addFlash(
965
                            FlashTypes::SUCCESS,
966
                            $this->get('translator')->trans('kuma_node.admin.edit.flash.success')
967
                        );
968
                    }
969
                }
970
971
                $params = [
972
                    'id' => $node->getId(),
973
                    'subaction' => $subaction,
974
                    'currenttab' => $tabPane->getActiveTab(),
975
                ];
976
                $params = array_merge(
977
                    $params,
978
                    $tabPane->getExtraParams($request)
979
                );
980
981
                return $this->redirect(
982
                    $this->generateUrl(
983
                        'KunstmaanNodeBundle_nodes_edit',
984
                        $params
985
                    )
986
                );
987
            }
988
        }
989
990
        $nodeVersions = $this->em->getRepository(
991
            'KunstmaanNodeBundle:NodeVersion'
992
        )->findBy(
993
            ['nodeTranslation' => $nodeTranslation],
994
            ['updated' => 'ASC']
995
        );
996
        $queuedNodeTranslationAction = $this->em->getRepository(
997
            'KunstmaanNodeBundle:QueuedNodeTranslationAction'
998
        )->findOneBy(['nodeTranslation' => $nodeTranslation]);
999
1000
        return [
1001
            'page' => $page,
1002
            'entityname' => ClassLookup::getClass($page),
1003
            'nodeVersions' => $nodeVersions,
1004
            'node' => $node,
1005
            'nodeTranslation' => $nodeTranslation,
1006
            'draft' => $draft,
1007
            'draftNodeVersion' => $draftNodeVersion,
1008
            'nodeVersion' => $nodeVersion,
1009
            'subaction' => $subaction,
1010
            'tabPane' => $tabPane,
1011
            'editmode' => true,
1012
            'queuedNodeTranslationAction' => $queuedNodeTranslationAction,
1013
            'nodeVersionLockCheck' => $this->container->getParameter('kunstmaan_node.lock_enabled'),
1014
            'nodeVersionLockInterval' => $this->container->getParameter('kunstmaan_node.lock_check_interval'),
1015
        ];
1016
    }
1017
1018
    /**
1019
     * @Route(
1020
     *      "checkNodeVersionLock/{id}/{public}",
1021
     *      requirements={"id" = "\d+", "public" = "(0|1)"},
1022
     *      name="KunstmaanNodeBundle_nodes_versionlock_check"
1023
     * )
1024
     *
1025
     * @param Request $request
1026
     * @param $id
1027
     *
1028
     * @return JsonResponse
1029
     */
1030
    public function checkNodeVersionLockAction(Request $request, $id, $public)
1031
    {
1032
        $nodeVersionIsLocked = false;
1033
        $message = '';
1034
        $this->init($request);
1035
1036
        /* @var Node $node */
1037
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
1038
1039
        try {
1040
            $this->checkPermission($node, PermissionMap::PERMISSION_EDIT);
1041
1042
            /** @var NodeVersionLockHelper $nodeVersionLockHelper */
1043
            $nodeVersionLockHelper = $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
1044
            $nodeTranslation = $node->getNodeTranslation($this->locale, true);
1045
1046
            if ($nodeTranslation) {
1047
                $nodeVersionIsLocked = $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation, $public);
1048
1049
                if ($nodeVersionIsLocked) {
1050
                    $users = $nodeVersionLockHelper->getUsersWithNodeVersionLock($nodeTranslation, $public, $this->getUser());
1051
                    $message = $this->get('translator')->trans('kuma_node.admin.edit.flash.locked', array('%users%' => implode(', ', $users)));
1052
                }
1053
            }
1054
        } catch (AccessDeniedException $ade) {
1055
        }
1056
1057
        return new JsonResponse(['lock' => $nodeVersionIsLocked, 'message' => $message]);
1058
    }
1059
1060
    /**
1061
     * @param NodeTranslation $nodeTranslation
1062
     * @param bool            $isPublic
1063
     *
1064
     * @return bool
1065
     */
1066
    private function isNodeVersionLocked(NodeTranslation $nodeTranslation, $isPublic)
1067
    {
1068
        if ($this->container->getParameter('kunstmaan_node.lock_enabled')) {
1069
            /** @var NodeVersionLockHelper $nodeVersionLockHelper */
1070
            $nodeVersionLockHelper = $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
1071
            $nodeVersionIsLocked = $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation, $isPublic);
1072
1073
            return $nodeVersionIsLocked;
1074
        }
1075
1076
        return false;
1077
    }
1078
1079
    /**
1080
     * @param HasNodeInterface $page            The page
1081
     * @param NodeTranslation  $nodeTranslation The node translation
1082
     * @param NodeVersion      $nodeVersion     The node version
1083
     *
1084
     * @return NodeVersion
1085
     */
1086
    private function createDraftVersion(
1087
        HasNodeInterface $page,
1088
        NodeTranslation $nodeTranslation,
1089
        NodeVersion $nodeVersion
1090
    ) {
1091
        $publicPage = $this->get('kunstmaan_admin.clone.helper')
1092
            ->deepCloneAndSave($page);
1093
        /* @var NodeVersion $publicNodeVersion */
1094
1095
        $publicNodeVersion = $this->em->getRepository(
1096
            'KunstmaanNodeBundle:NodeVersion'
1097
        )->createNodeVersionFor(
1098
            $publicPage,
1099
            $nodeTranslation,
1100
            $this->user,
1101
            $nodeVersion->getOrigin(),
1102
            'public',
1103
            $nodeVersion->getCreated()
1104
        );
1105
1106
        $nodeTranslation->setPublicNodeVersion($publicNodeVersion);
1107
        $nodeVersion->setType('draft');
1108
        $nodeVersion->setOrigin($publicNodeVersion);
1109
        $nodeVersion->setCreated(new DateTime());
1110
1111
        $this->em->persist($nodeTranslation);
1112
        $this->em->persist($nodeVersion);
1113
        $this->em->flush();
1114
1115
        $this->get('event_dispatcher')->dispatch(
1116
            Events::CREATE_DRAFT_VERSION,
1117
            new NodeEvent(
1118
                $nodeTranslation->getNode(),
1119
                $nodeTranslation,
1120
                $nodeVersion,
1121
                $page
1122
            )
1123
        );
1124
1125
        return $nodeVersion;
1126
    }
1127
1128
    /**
1129
     * @param Node   $node       The node
1130
     * @param string $permission The permission to check for
1131
     *
1132
     * @throws AccessDeniedException
1133
     */
1134
    private function checkPermission(Node $node, $permission)
1135
    {
1136
        if (false === $this->authorizationChecker->isGranted($permission, $node)) {
1137
            throw new AccessDeniedException();
1138
        }
1139
    }
1140
1141
    /**
1142
     * @param EntityManager   $em       The Entity Manager
1143
     * @param BaseUser        $user     The user who deletes the children
1144
     * @param string          $locale   The locale that was used
1145
     * @param ArrayCollection $children The children array
1146
     */
1147
    private function deleteNodeChildren(
1148
        EntityManager $em,
1149
        BaseUser $user,
1150
        $locale,
1151
        ArrayCollection $children
1152
    ) {
1153
        /* @var Node $childNode */
1154
        foreach ($children as $childNode) {
1155
            $childNodeTranslation = $childNode->getNodeTranslation(
1156
                $this->locale,
1157
                true
1158
            );
1159
1160
            $childNodeVersion = $childNodeTranslation->getPublicNodeVersion();
1161
            $childNodePage = $childNodeVersion->getRef($this->em);
1162
1163
            $this->get('event_dispatcher')->dispatch(
1164
                Events::PRE_DELETE,
1165
                new NodeEvent(
1166
                    $childNode,
1167
                    $childNodeTranslation,
1168
                    $childNodeVersion,
1169
                    $childNodePage
1170
                )
1171
            );
1172
1173
            $childNode->setDeleted(true);
1174
            $this->em->persist($childNode);
1175
1176
            $children2 = $childNode->getChildren();
1177
            $this->deleteNodeChildren($em, $user, $locale, $children2);
1178
1179
            $this->get('event_dispatcher')->dispatch(
1180
                Events::POST_DELETE,
1181
                new NodeEvent(
1182
                    $childNode,
1183
                    $childNodeTranslation,
1184
                    $childNodeVersion,
1185
                    $childNodePage
1186
                )
1187
            );
1188
        }
1189
    }
1190
1191
    /**
1192
     * @param Request $request
1193
     * @param string  $type
1194
     *
1195
     * @return HasNodeInterface
1196
     */
1197
    private function createNewPage(Request $request, $type)
1198
    {
1199
        /* @var HasNodeInterface $newPage */
1200
        $newPage = new $type();
1201
1202
        $title = $request->get('title');
1203
        if (is_string($title) && !empty($title)) {
1204
            $newPage->setTitle($title);
1205
        } else {
1206
            $newPage->setTitle($this->get('translator')->trans('kuma_node.admin.new_page.title.default'));
1207
        }
1208
        $this->em->persist($newPage);
1209
        $this->em->flush();
1210
1211
        return $newPage;
1212
    }
1213
1214
    /**
1215
     * @param Request $request
1216
     *
1217
     * @return string
1218
     * @throw InvalidArgumentException
1219
     */
1220
    private function validatePageType($request)
1221
    {
1222
        $type = $request->get('type');
1223
1224
        if (empty($type)) {
1225
            throw new InvalidArgumentException(
1226
                'Please specify a type of page you want to create'
1227
            );
1228
        }
1229
1230
        return $type;
1231
    }
1232
1233
    /**
1234
     * @param Node $node
1235
     *
1236
     * @return \Symfony\Component\HttpFoundation\Response
1237
     */
1238
    private function renderNodeNotTranslatedPage(Node $node)
1239
    {
1240
        //try to find a parent node with the correct translation, if there is none allow copy.
1241
        //if there is a parent but it doesn't have the language to copy to don't allow it
1242
        $parentNode = $node->getParent();
1243
        if ($parentNode) {
1244
            $parentNodeTranslation = $parentNode->getNodeTranslation(
1245
                $this->locale,
1246
                true
1247
            );
1248
            $parentsAreOk = false;
1249
1250
            if ($parentNodeTranslation) {
1251
                $parentsAreOk = $this->em->getRepository(
1252
                    'KunstmaanNodeBundle:NodeTranslation'
1253
                )->hasParentNodeTranslationsForLanguage(
1254
                    $node->getParent()->getNodeTranslation(
1255
                        $this->locale,
1256
                        true
1257
                    ),
1258
                    $this->locale
1259
                );
1260
            }
1261
        } else {
1262
            $parentsAreOk = true;
1263
        }
1264
1265
        return $this->render(
1266
            'KunstmaanNodeBundle:NodeAdmin:pagenottranslated.html.twig',
1267
            array(
1268
                'node' => $node,
1269
                'nodeTranslations' => $node->getNodeTranslations(
1270
                    true
1271
                ),
1272
                'copyfromotherlanguages' => $parentsAreOk,
1273
            )
1274
        );
1275
    }
1276
}
1277