Completed
Push — master ( 770316...74fc07 )
by Jeroen
09:08 queued 02:44
created

NodeBundle/Controller/NodeAdminController.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\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\FlashMessages\FlashTypes;
12
use Kunstmaan\AdminBundle\Helper\FormWidgets\FormWidget;
13
use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\Tab;
14
use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\TabPane;
15
use Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper;
16
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMap;
17
use Kunstmaan\AdminBundle\Service\AclManager;
18
use Kunstmaan\AdminListBundle\AdminList\AdminList;
19
use Kunstmaan\NodeBundle\AdminList\NodeAdminListConfigurator;
20
use Kunstmaan\NodeBundle\Entity\HasNodeInterface;
21
use Kunstmaan\NodeBundle\Entity\Node;
22
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
23
use Kunstmaan\NodeBundle\Entity\NodeVersion;
24
use Kunstmaan\NodeBundle\Event\AdaptFormEvent;
25
use Kunstmaan\NodeBundle\Event\CopyPageTranslationNodeEvent;
26
use Kunstmaan\NodeBundle\Event\Events;
27
use Kunstmaan\NodeBundle\Event\NodeEvent;
28
use Kunstmaan\NodeBundle\Event\RecopyPageTranslationNodeEvent;
29
use Kunstmaan\NodeBundle\Event\RevertNodeAction;
30
use Kunstmaan\NodeBundle\Form\NodeMenuTabAdminType;
31
use Kunstmaan\NodeBundle\Form\NodeMenuTabTranslationAdminType;
32
use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeAdminPublisher;
33
use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeVersionLockHelper;
34
use Kunstmaan\NodeBundle\Repository\NodeVersionRepository;
35
use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
36
use Symfony\Component\Routing\Annotation\Route;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
38
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
39
use Symfony\Component\HttpFoundation\JsonResponse;
40
use Symfony\Component\HttpFoundation\RedirectResponse;
41
use Symfony\Component\HttpFoundation\Request;
42
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
43
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
44
use Symfony\Component\Translation\TranslatorInterface;
45
46
/**
47
 * NodeAdminController
48
 */
49
class NodeAdminController extends Controller
50
{
51
    /**
52
     * @var EntityManager
53
     */
54
    protected $em;
55
56
    /**
57
     * @var string
58
     */
59
    protected $locale;
60
61
    /**
62
     * @var AuthorizationCheckerInterface
63
     */
64
    protected $authorizationChecker;
65
66
    /**
67
     * @var BaseUser
68
     */
69
    protected $user;
70
71
    /**
72
     * @var AclHelper
73
     */
74
    protected $aclHelper;
75
76
    /**
77
     * @var AclManager
78
     */
79
    protected $aclManager;
80
81
    /**
82
     * @var NodeAdminPublisher
83
     */
84
    protected $nodePublisher;
85
86
    /**
87
     * @var TranslatorInterface
88
     */
89
    protected $translator;
90
91
    /**
92
     * init
93
     *
94
     * @param Request $request
95
     */
96
    protected function init(Request $request)
97
    {
98
        $this->em = $this->getDoctrine()->getManager();
99
        $this->locale = $request->getLocale();
100
        $this->authorizationChecker = $this->container->get('security.authorization_checker');
101
        $this->user = $this->getUser();
102
        $this->aclHelper = $this->container->get('kunstmaan_admin.acl.helper');
103
        $this->aclManager = $this->container->get('kunstmaan_admin.acl.manager');
104
        $this->nodePublisher = $this->container->get('kunstmaan_node.admin_node.publisher');
105
        $this->translator = $this->container->get('translator');
106
    }
107
108
    /**
109
     * @Route("/", name="KunstmaanNodeBundle_nodes")
110
     * @Template("KunstmaanNodeBundle:Admin:list.html.twig")
111
     *
112
     * @param Request $request
113
     *
114
     * @return array
115
     */
116
    public function indexAction(Request $request)
117
    {
118
        $this->init($request);
119
120
        $nodeAdminListConfigurator = new NodeAdminListConfigurator(
121
            $this->em,
122
            $this->aclHelper,
123
            $this->locale,
124
            PermissionMap::PERMISSION_VIEW,
125
            $this->authorizationChecker
126
        );
127
128
        $locale = $this->locale;
129
        $acl = $this->authorizationChecker;
130
        $itemRoute = function (EntityInterface $item) use ($locale, $acl) {
131
            if ($acl->isGranted(PermissionMap::PERMISSION_VIEW, $item->getNode())) {
132
                return array(
133
                    'path' => '_slug_preview',
134
                    'params' => ['_locale' => $locale, 'url' => $item->getUrl()],
135
                );
136
            }
137
        };
138
        $nodeAdminListConfigurator->addSimpleItemAction('action.preview', $itemRoute, 'eye');
139
        $nodeAdminListConfigurator->setDomainConfiguration($this->get('kunstmaan_admin.domain_configuration'));
140
        $nodeAdminListConfigurator->setShowAddHomepage($this->getParameter('kunstmaan_node.show_add_homepage') && $this->isGranted('ROLE_SUPER_ADMIN'));
141
142
        /** @var AdminList $adminlist */
143
        $adminlist = $this->get('kunstmaan_adminlist.factory')->createList($nodeAdminListConfigurator);
144
        $adminlist->bindRequest($request);
145
146
        return array(
147
            'adminlist' => $adminlist,
148
        );
149
    }
150
151
    /**
152
     * @Route(
153
     *      "/{id}/copyfromotherlanguage",
154
     *      requirements={"id" = "\d+"},
155
     *      name="KunstmaanNodeBundle_nodes_copyfromotherlanguage",
156
     *      methods={"GET"}
157
     * )
158
     *
159
     * @param Request $request
160
     * @param int     $id      The node id
161
     *
162
     * @return RedirectResponse
163
     *
164
     * @throws AccessDeniedException
165
     */
166
    public function copyFromOtherLanguageAction(Request $request, $id)
167
    {
168
        $this->init($request);
169
        /* @var Node $node */
170
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
171
172
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
173
174
        $originalLanguage = $request->get('originallanguage');
175
        $otherLanguageNodeTranslation = $node->getNodeTranslation($originalLanguage, true);
176
        $otherLanguageNodeNodeVersion = $otherLanguageNodeTranslation->getPublicNodeVersion();
177
        $otherLanguagePage = $otherLanguageNodeNodeVersion->getRef($this->em);
178
        $myLanguagePage = $this->get('kunstmaan_admin.clone.helper')
179
            ->deepCloneAndSave($otherLanguagePage);
180
181
        /* @var NodeTranslation $nodeTranslation */
182
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
183
            ->createNodeTranslationFor($myLanguagePage, $this->locale, $node, $this->user);
184
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
185
186
        $this->get('event_dispatcher')->dispatch(
187
            Events::COPY_PAGE_TRANSLATION,
188
            new CopyPageTranslationNodeEvent(
189
                $node,
190
                $nodeTranslation,
191
                $nodeVersion,
192
                $myLanguagePage,
193
                $otherLanguageNodeTranslation,
194
                $otherLanguageNodeNodeVersion,
195
                $otherLanguagePage,
196
                $originalLanguage
197
            )
198
        );
199
200
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
201
    }
202
203
    /**
204
     * @Route(
205
     *      "/{id}/recopyfromotherlanguage",
206
     *      requirements={"id" = "\d+"},
207
     *      name="KunstmaanNodeBundle_nodes_recopyfromotherlanguage",
208
     *      methods={"POST"}
209
     * )
210
     *
211
     * @param Request $request
212
     * @param int     $id      The node id
213
     *
214
     * @return RedirectResponse
215
     *
216
     * @throws AccessDeniedException
217
     */
218
    public function recopyFromOtherLanguageAction(Request $request, $id)
219
    {
220
        $this->init($request);
221
        /* @var Node $node */
222
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
223
224
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
225
226
        $otherLanguageNodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')->find($request->get('source'));
227
        $otherLanguageNodeNodeVersion = $otherLanguageNodeTranslation->getPublicNodeVersion();
228
        $otherLanguagePage = $otherLanguageNodeNodeVersion->getRef($this->em);
229
        $myLanguagePage = $this->get('kunstmaan_admin.clone.helper')
230
            ->deepCloneAndSave($otherLanguagePage);
231
232
        /* @var NodeTranslation $nodeTranslation */
233
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
234
            ->addDraftNodeVersionFor($myLanguagePage, $this->locale, $node, $this->user);
235
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
236
237
        $this->get('event_dispatcher')->dispatch(
238
            Events::RECOPY_PAGE_TRANSLATION,
239
            new RecopyPageTranslationNodeEvent(
240
                $node,
241
                $nodeTranslation,
242
                $nodeVersion,
243
                $myLanguagePage,
244
                $otherLanguageNodeTranslation,
245
                $otherLanguageNodeNodeVersion,
246
                $otherLanguagePage,
247
                $otherLanguageNodeTranslation->getLang()
248
            )
249
        );
250
251
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id, 'subaction' => NodeVersion::DRAFT_VERSION)));
252
    }
253
254
    /**
255
     * @Route(
256
     *      "/{id}/createemptypage",
257
     *      requirements={"id" = "\d+"},
258
     *      name="KunstmaanNodeBundle_nodes_createemptypage",
259
     *      methods={"GET"}
260
     * )
261
     *
262
     * @param Request $request
263
     * @param int     $id
264
     *
265
     * @return RedirectResponse
266
     *
267
     * @throws AccessDeniedException
268
     */
269
    public function createEmptyPageAction(Request $request, $id)
270
    {
271
        $this->init($request);
272
        /* @var Node $node */
273
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
274
275
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
276
277
        $entityName = $node->getRefEntityName();
278
        /* @var HasNodeInterface $myLanguagePage */
279
        $myLanguagePage = new $entityName();
280
        $myLanguagePage->setTitle('New page');
281
282
        $this->em->persist($myLanguagePage);
283
        $this->em->flush();
284
        /* @var NodeTranslation $nodeTranslation */
285
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
286
            ->createNodeTranslationFor($myLanguagePage, $this->locale, $node, $this->user);
287
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
288
289
        $this->get('event_dispatcher')->dispatch(
290
            Events::ADD_EMPTY_PAGE_TRANSLATION,
291
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $myLanguagePage)
292
        );
293
294
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
295
    }
296
297
    /**
298
     * @Route("/{id}/publish", requirements={"id" =
299
     *                         "\d+"},
300
     *                         name="KunstmaanNodeBundle_nodes_publish", methods={"GET", "POST"})
301
     *
302
     * @param Request $request
303
     * @param int     $id
304
     *
305
     * @return RedirectResponse
306
     *
307
     * @throws AccessDeniedException
308
     */
309 View Code Duplication
    public function publishAction(Request $request, $id)
0 ignored issues
show
This method seems to be duplicated in your project.

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

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

Loading history...
310
    {
311
        $this->init($request);
312
        /* @var Node $node */
313
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
314
315
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
316
        $request = $this->get('request_stack')->getCurrentRequest();
317
        $this->nodePublisher->chooseHowToPublish($request, $nodeTranslation, $this->translator);
318
319
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
320
    }
321
322
    /**
323
     * @Route(
324
     *      "/{id}/unpublish",
325
     *      requirements={"id" = "\d+"},
326
     *      name="KunstmaanNodeBundle_nodes_unpublish",
327
     *      methods={"GET", "POST"}
328
     * )
329
     *
330
     * @param Request $request
331
     * @param int     $id
332
     *
333
     * @return RedirectResponse
334
     *
335
     * @throws AccessDeniedException
336
     */
337 View Code Duplication
    public function unPublishAction(Request $request, $id)
0 ignored issues
show
This method seems to be duplicated in your project.

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

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

Loading history...
338
    {
339
        $this->init($request);
340
        /* @var Node $node */
341
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
342
343
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
344
        $request = $this->get('request_stack')->getCurrentRequest();
345
        $this->nodePublisher->chooseHowToUnpublish($request, $nodeTranslation, $this->translator);
346
347
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
348
    }
349
350
    /**
351
     * @Route(
352
     *      "/{id}/unschedulepublish",
353
     *      requirements={"id" = "\d+"},
354
     *      name="KunstmaanNodeBundle_nodes_unschedule_publish",
355
     *      methods={"GET", "POST"}
356
     * )
357
     *
358
     * @param Request $request
359
     * @param int     $id
360
     *
361
     * @return RedirectResponse
362
     *
363
     * @throws AccessDeniedException
364
     */
365 View Code Duplication
    public function unSchedulePublishAction(Request $request, $id)
0 ignored issues
show
This method seems to be duplicated in your project.

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

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

Loading history...
366
    {
367
        $this->init($request);
368
369
        /* @var Node $node */
370
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
371
372
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
373
        $this->nodePublisher->unSchedulePublish($nodeTranslation);
374
375
        $this->addFlash(
376
            FlashTypes::SUCCESS,
377
            $this->get('translator')->trans('kuma_node.admin.unschedule.flash.success')
378
        );
379
380
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
381
    }
382
383
    /**
384
     * @Route(
385
     *      "/{id}/delete",
386
     *      requirements={"id" = "\d+"},
387
     *      name="KunstmaanNodeBundle_nodes_delete",
388
     *      methods={"POST"}
389
     * )
390
     *
391
     * @param Request $request
392
     * @param int     $id
393
     *
394
     * @return RedirectResponse
395
     *
396
     * @throws AccessDeniedException
397
     */
398
    public function deleteAction(Request $request, $id)
399
    {
400
        $this->init($request);
401
        /* @var Node $node */
402
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
403
404
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_DELETE, $node);
405
406
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
407
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
408
        $page = $nodeVersion->getRef($this->em);
409
410
        $this->get('event_dispatcher')->dispatch(
411
            Events::PRE_DELETE,
412
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
413
        );
414
415
        $node->setDeleted(true);
416
        $this->em->persist($node);
417
418
        $children = $node->getChildren();
419
        $this->deleteNodeChildren($this->em, $this->user, $this->locale, $children);
420
        $this->em->flush();
421
422
        $event = new NodeEvent($node, $nodeTranslation, $nodeVersion, $page);
423
        $this->get('event_dispatcher')->dispatch(Events::POST_DELETE, $event);
424
        if (null === $response = $event->getResponse()) {
425
            $nodeParent = $node->getParent();
426
            // Check if we have a parent. Otherwise redirect to pages overview.
427
            if ($nodeParent) {
428
                $url = $this->get('router')->generate(
429
                    'KunstmaanNodeBundle_nodes_edit',
430
                    array('id' => $nodeParent->getId())
431
                );
432
            } else {
433
                $url = $this->get('router')->generate(
434
                    'KunstmaanNodeBundle_nodes'
435
                );
436
            }
437
            $response = new RedirectResponse($url);
438
        }
439
440
        $this->addFlash(
441
            FlashTypes::SUCCESS,
442
            $this->get('translator')->trans('kuma_node.admin.delete.flash.success')
443
        );
444
445
        return $response;
446
    }
447
448
    /**
449
     * @Route(
450
     *      "/{id}/duplicate",
451
     *      requirements={"id" = "\d+"},
452
     *      name="KunstmaanNodeBundle_nodes_duplicate",
453
     *      methods={"POST"}
454
     * )
455
     *
456
     * @param Request $request
457
     * @param int     $id
458
     *
459
     * @return RedirectResponse
460
     *
461
     * @throws AccessDeniedException
462
     */
463
    public function duplicateAction(Request $request, $id)
464
    {
465
        $this->init($request);
466
        /* @var Node $parentNode */
467
        $originalNode = $this->em->getRepository('KunstmaanNodeBundle:Node')
468
            ->find($id);
469
470
        // Check with Acl
471
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $originalNode);
472
473
        $request = $this->get('request_stack')->getCurrentRequest();
474
475
        $originalNodeTranslations = $originalNode->getNodeTranslation($this->locale, true);
476
        $originalRef = $originalNodeTranslations->getPublicNodeVersion()->getRef($this->em);
477
        $newPage = $this->get('kunstmaan_admin.clone.helper')
478
            ->deepCloneAndSave($originalRef);
479
480
        //set the title
481
        $title = $request->get('title');
482
        if (\is_string($title) && !empty($title)) {
483
            $newPage->setTitle($title);
484
        } else {
485
            $newPage->setTitle('New page');
486
        }
487
488
        //set the parent
489
        $parentNodeTranslation = $originalNode->getParent()->getNodeTranslation($this->locale, true);
490
        $parent = $parentNodeTranslation->getPublicNodeVersion()->getRef($this->em);
491
        $newPage->setParent($parent);
492
        $this->em->persist($newPage);
493
        $this->em->flush();
494
495
        /* @var Node $nodeNewPage */
496
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')->createNodeFor(
497
            $newPage,
498
            $this->locale,
499
            $this->user
500
        );
501
502
        $nodeTranslation = $nodeNewPage->getNodeTranslation($this->locale, true);
503
        if ($newPage->isStructureNode()) {
504
            $nodeTranslation->setSlug('');
505
            $this->em->persist($nodeTranslation);
506
        }
507
        $this->em->flush();
508
509
        $this->aclManager->updateNodeAcl($originalNode, $nodeNewPage);
510
511
        $this->addFlash(
512
            FlashTypes::SUCCESS,
513
            $this->get('translator')->trans('kuma_node.admin.duplicate.flash.success')
514
        );
515
516
        return $this->redirect(
517
            $this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $nodeNewPage->getId()))
518
        );
519
    }
520
521
    /**
522
     * @Route(
523
     *      "/{id}/revert",
524
     *      requirements={"id" = "\d+"},
525
     *      defaults={"subaction" = "public"},
526
     *      name="KunstmaanNodeBundle_nodes_revert",
527
     *      methods={"GET"}
528
     * )
529
     *
530
     * @param Request $request
531
     * @param int     $id      The node id
532
     *
533
     * @return RedirectResponse
534
     *
535
     * @throws AccessDeniedException
536
     * @throws InvalidArgumentException
537
     */
538
    public function revertAction(Request $request, $id)
539
    {
540
        $this->init($request);
541
        /* @var Node $node */
542
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
543
544
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
545
546
        $version = $request->get('version');
547
548
        if (empty($version) || !is_numeric($version)) {
549
            throw new InvalidArgumentException('No version was specified');
550
        }
551
552
        /* @var NodeVersionRepository $nodeVersionRepo */
553
        $nodeVersionRepo = $this->em->getRepository('KunstmaanNodeBundle:NodeVersion');
554
        /* @var NodeVersion $nodeVersion */
555
        $nodeVersion = $nodeVersionRepo->find($version);
556
557
        if (\is_null($nodeVersion)) {
558
            throw new InvalidArgumentException('Version does not exist');
559
        }
560
561
        /* @var NodeTranslation $nodeTranslation */
562
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
563
        $page = $nodeVersion->getRef($this->em);
564
        /* @var HasNodeInterface $clonedPage */
565
        $clonedPage = $this->get('kunstmaan_admin.clone.helper')
566
            ->deepCloneAndSave($page);
567
        $newNodeVersion = $nodeVersionRepo->createNodeVersionFor(
568
            $clonedPage,
569
            $nodeTranslation,
570
            $this->user,
571
            $nodeVersion,
572
            'draft'
573
        );
574
575
        $nodeTranslation->setTitle($clonedPage->getTitle());
576
        $this->em->persist($nodeTranslation);
577
        $this->em->flush();
578
579
        $this->get('event_dispatcher')->dispatch(
580
            Events::REVERT,
581
            new RevertNodeAction(
582
                $node,
583
                $nodeTranslation,
584
                $newNodeVersion,
585
                $clonedPage,
586
                $nodeVersion,
587
                $page
588
            )
589
        );
590
591
        $this->addFlash(
592
            FlashTypes::SUCCESS,
593
            $this->get('translator')->trans('kuma_node.admin.revert.flash.success')
594
        );
595
596
        return $this->redirect(
597
            $this->generateUrl(
598
                'KunstmaanNodeBundle_nodes_edit',
599
                array(
600
                    'id' => $id,
601
                    'subaction' => 'draft',
602
                )
603
            )
604
        );
605
    }
606
607
    /**
608
     * @Route(
609
     *      "/{id}/add",
610
     *      requirements={"id" = "\d+"},
611
     *      name="KunstmaanNodeBundle_nodes_add",
612
     *      methods={"POST"}
613
     * )
614
     *
615
     * @param Request $request
616
     * @param int     $id
617
     *
618
     * @return RedirectResponse
619
     *
620
     * @throws AccessDeniedException
621
     * @throws InvalidArgumentException
622
     */
623
    public function addAction(Request $request, $id)
624
    {
625
        $this->init($request);
626
        /* @var Node $parentNode */
627
        $parentNode = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
628
629
        // Check with Acl
630
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parentNode);
631
632
        $parentNodeTranslation = $parentNode->getNodeTranslation($this->locale, true);
633
        $parentNodeVersion = $parentNodeTranslation->getPublicNodeVersion();
634
        $parentPage = $parentNodeVersion->getRef($this->em);
635
636
        $type = $this->validatePageType($request);
637
        $newPage = $this->createNewPage($request, $type);
638
        $newPage->setParent($parentPage);
639
640
        /* @var Node $nodeNewPage */
641
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')
642
            ->createNodeFor($newPage, $this->locale, $this->user);
643
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
644
            $this->locale,
645
            true
646
        );
647
        $weight = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
648
                ->getMaxChildrenWeight($parentNode, $this->locale) + 1;
649
        $nodeTranslation->setWeight($weight);
650
651
        if ($newPage->isStructureNode()) {
652
            $nodeTranslation->setSlug('');
653
        }
654
655
        $this->em->persist($nodeTranslation);
656
        $this->em->flush();
657
658
        $this->aclManager->updateNodeAcl($parentNode, $nodeNewPage);
659
660
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
661
662
        $this->get('event_dispatcher')->dispatch(
663
            Events::ADD_NODE,
664
            new NodeEvent(
665
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
666
            )
667
        );
668
669
        return $this->redirect(
670
            $this->generateUrl(
671
                'KunstmaanNodeBundle_nodes_edit',
672
                array('id' => $nodeNewPage->getId())
673
            )
674
        );
675
    }
676
677
    /**
678
     * @Route("/add-homepage", name="KunstmaanNodeBundle_nodes_add_homepage", methods={"POST"})
679
     *
680
     * @return RedirectResponse
681
     *
682
     * @throws AccessDeniedException
683
     * @throws InvalidArgumentException
684
     */
685
    public function addHomepageAction(Request $request)
686
    {
687
        $this->init($request);
688
689
        // Check with Acl
690
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
691
692
        $type = $this->validatePageType($request);
693
694
        $newPage = $this->createNewPage($request, $type);
695
696
        /* @var Node $nodeNewPage */
697
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')
698
            ->createNodeFor($newPage, $this->locale, $this->user);
699
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
700
            $this->locale,
701
            true
702
        );
703
        $this->em->flush();
704
705
        // Set default permissions
706
        $this->container->get('kunstmaan_node.acl_permission_creator_service')
707
            ->createPermission($nodeNewPage);
708
709
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
710
711
        $this->get('event_dispatcher')->dispatch(
712
            Events::ADD_NODE,
713
            new NodeEvent(
714
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
715
            )
716
        );
717
718
        return $this->redirect(
719
            $this->generateUrl(
720
                'KunstmaanNodeBundle_nodes_edit',
721
                array('id' => $nodeNewPage->getId())
722
            )
723
        );
724
    }
725
726
    /**
727
     * @Route("/reorder", name="KunstmaanNodeBundle_nodes_reorder", methods={"POST"})
728
     *
729
     * @param Request $request
730
     *
731
     * @return string
732
     *
733
     * @throws AccessDeniedException
734
     */
735
    public function reorderAction(Request $request)
736
    {
737
        $this->init($request);
738
        $nodes = array();
739
        $nodeIds = $request->get('nodes');
740
        $changeParents = $request->get('parent');
741
742
        foreach ($nodeIds as $id) {
743
            /* @var Node $node */
744
            $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
745
            $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
746
            $nodes[] = $node;
747
        }
748
749
        $weight = 1;
750
        foreach ($nodes as $node) {
751
            $newParentId = isset($changeParents[$node->getId()]) ? $changeParents[$node->getId()] : null;
752
            if ($newParentId) {
753
                $parent = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($newParentId);
754
                $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parent);
755
                $node->setParent($parent);
756
                $this->em->persist($node);
757
                $this->em->flush($node);
758
            }
759
760
            /* @var NodeTranslation $nodeTranslation */
761
            $nodeTranslation = $node->getNodeTranslation($this->locale, true);
762
763
            if ($nodeTranslation) {
764
                $nodeVersion = $nodeTranslation->getPublicNodeVersion();
765
                $page = $nodeVersion->getRef($this->em);
766
767
                $this->get('event_dispatcher')->dispatch(
768
                    Events::PRE_PERSIST,
769
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
770
                );
771
772
                $nodeTranslation->setWeight($weight);
773
                $this->em->persist($nodeTranslation);
774
                $this->em->flush($nodeTranslation);
775
776
                $this->get('event_dispatcher')->dispatch(
777
                    Events::POST_PERSIST,
778
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
779
                );
780
781
                ++$weight;
782
            }
783
        }
784
785
        return new JsonResponse(
786
            array(
787
                'Success' => 'The node-translations for [' . $this->locale . '] have got new weight values',
788
            )
789
        );
790
    }
791
792
    /**
793
     * @Route(
794
     *      "/{id}/{subaction}",
795
     *      requirements={"id" = "\d+"},
796
     *      defaults={"subaction" = "public"},
797
     *      name="KunstmaanNodeBundle_nodes_edit",
798
     *      methods={"GET", "POST"}
799
     * )
800
     * @Template("@KunstmaanNode/NodeAdmin/edit.html.twig")
801
     *
802
     * @param Request $request
803
     * @param int     $id        The node id
804
     * @param string  $subaction The subaction (draft|public)
805
     *
806
     * @return RedirectResponse|array
807
     *
808
     * @throws AccessDeniedException
809
     */
810
    public function editAction(Request $request, $id, $subaction)
811
    {
812
        $this->init($request);
813
        /* @var Node $node */
814
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
815
816
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
817
818
        $tabPane = new TabPane(
819
            'todo',
820
            $request,
821
            $this->container->get('form.factory')
822
        );
823
824
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
825
        if (!$nodeTranslation) {
826
            return $this->renderNodeNotTranslatedPage($node);
827
        }
828
829
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
830
        $draftNodeVersion = $nodeTranslation->getDraftNodeVersion();
831
        $nodeVersionIsLocked = false;
832
833
        /* @var HasNodeInterface $page */
834
        $page = null;
835
        $draft = ($subaction == 'draft');
836
        $saveAsDraft = $request->get('saveasdraft');
837
        if ((!$draft && !empty($saveAsDraft)) || ($draft && \is_null($draftNodeVersion))) {
838
            // Create a new draft version
839
            $draft = true;
840
            $subaction = 'draft';
841
            $page = $nodeVersion->getRef($this->em);
842
            $nodeVersion = $this->createDraftVersion(
843
                $page,
844
                $nodeTranslation,
845
                $nodeVersion
846
            );
847
            $draftNodeVersion = $nodeVersion;
848
        } elseif ($draft) {
849
            $nodeVersion = $draftNodeVersion;
850
            $page = $nodeVersion->getRef($this->em);
851
        } else {
852
            if ($request->getMethod() == 'POST') {
853
                $nodeVersionIsLocked = $this->isNodeVersionLocked($nodeTranslation, true);
854
855
                //Check the version timeout and make a new nodeversion if the timeout is passed
856
                $thresholdDate = date(
857
                    'Y-m-d H:i:s',
858
                    time() - $this->getParameter(
859
                        'kunstmaan_node.version_timeout'
860
                    )
861
                );
862
                $updatedDate = date(
863
                    'Y-m-d H:i:s',
864
                    strtotime($nodeVersion->getUpdated()->format('Y-m-d H:i:s'))
865
                );
866 View Code Duplication
                if ($thresholdDate >= $updatedDate || $nodeVersionIsLocked) {
867
                    $page = $nodeVersion->getRef($this->em);
868
                    if ($nodeVersion === $nodeTranslation->getPublicNodeVersion()) {
869
                        $this->nodePublisher
870
                            ->createPublicVersion(
871
                                $page,
872
                                $nodeTranslation,
873
                                $nodeVersion,
874
                                $this->user
875
                            );
876
                    } else {
877
                        $this->createDraftVersion(
878
                            $page,
879
                            $nodeTranslation,
880
                            $nodeVersion
881
                        );
882
                    }
883
                }
884
            }
885
            $page = $nodeVersion->getRef($this->em);
886
        }
887
        $isStructureNode = $page->isStructureNode();
888
889
        $menubuilder = $this->get('kunstmaan_node.actions_menu_builder');
890
        $menubuilder->setActiveNodeVersion($nodeVersion);
891
        $menubuilder->setEditableNode(!$isStructureNode);
892
893
        // Building the form
894
        $propertiesWidget = new FormWidget();
895
        $propertiesWidget->addType('main', $page->getDefaultAdminType(), $page);
896
        $propertiesWidget->addType('node', $node->getDefaultAdminType(), $node);
897
        $tabPane->addTab(new Tab('kuma_node.tab.properties.title', $propertiesWidget));
898
899
        // Menu tab
900
        $menuWidget = new FormWidget();
901
        $menuWidget->addType(
902
            'menunodetranslation',
903
            NodeMenuTabTranslationAdminType::class,
904
            $nodeTranslation,
905
            ['slugable' => !$isStructureNode]
906
        );
907
        $menuWidget->addType('menunode', NodeMenuTabAdminType::class, $node, ['available_in_nav' => !$isStructureNode]);
908
        $tabPane->addTab(new Tab('kuma_node.tab.menu.title', $menuWidget));
909
910
        $this->get('event_dispatcher')->dispatch(
911
            Events::ADAPT_FORM,
912
            new AdaptFormEvent(
913
                $request,
914
                $tabPane,
915
                $page,
916
                $node,
917
                $nodeTranslation,
918
                $nodeVersion
919
            )
920
        );
921
922
        $tabPane->buildForm();
923
924
        if ($request->getMethod() == 'POST') {
925
            $tabPane->bindRequest($request);
926
927
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
928
            if ($tabPane->isValid() && !$request->isXmlHttpRequest()) {
929
                $this->get('event_dispatcher')->dispatch(
930
                    Events::PRE_PERSIST,
931
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
932
                );
933
934
                $nodeTranslation->setTitle($page->getTitle());
935
                if ($isStructureNode) {
936
                    $nodeTranslation->setSlug('');
937
                }
938
                $nodeVersion->setUpdated(new DateTime());
939
                if ($nodeVersion->getType() == 'public') {
940
                    $nodeTranslation->setUpdated($nodeVersion->getUpdated());
941
                }
942
                $this->em->persist($nodeTranslation);
943
                $this->em->persist($nodeVersion);
944
                $tabPane->persist($this->em);
945
                $this->em->flush();
946
947
                $this->get('event_dispatcher')->dispatch(
948
                    Events::POST_PERSIST,
949
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
950
                );
951
952
                if ($nodeVersionIsLocked) {
953
                    $this->addFlash(
954
                        FlashTypes::SUCCESS,
955
                        $this->get('translator')->trans('kuma_node.admin.edit.flash.locked_success')
956
                    );
957
                } elseif ($request->request->has('publishing') || $request->request->has('publish_later')) {
958
                    $this->nodePublisher->chooseHowToPublish($request, $nodeTranslation, $this->translator);
959
                } elseif ($request->request->has('unpublishing') || $request->request->has('unpublish_later')) {
960
                    $this->nodePublisher->chooseHowToUnpublish($request, $nodeTranslation, $this->translator);
961
                } else {
962
                    $this->addFlash(
963
                        FlashTypes::SUCCESS,
964
                        $this->get('translator')->trans('kuma_node.admin.edit.flash.success')
965
                    );
966
                }
967
968
                $params = [
969
                    'id' => $node->getId(),
970
                    'subaction' => $subaction,
971
                    'currenttab' => $tabPane->getActiveTab(),
972
                ];
973
                $params = array_merge(
974
                    $params,
975
                    $tabPane->getExtraParams($request)
976
                );
977
978
                if ($subaction === 'draft' && ($request->request->has('publishing') || $request->request->has('publish_later'))) {
979
                    unset($params['subaction']);
980
                }
981
982
                return $this->redirect(
983
                    $this->generateUrl(
984
                        'KunstmaanNodeBundle_nodes_edit',
985
                        $params
986
                    )
987
                );
988
            }
989
        }
990
991
        $nodeVersions = $this->em->getRepository(
992
            'KunstmaanNodeBundle:NodeVersion'
993
        )->findBy(
994
            ['nodeTranslation' => $nodeTranslation],
995
            ['updated' => 'ASC']
996
        );
997
        $queuedNodeTranslationAction = $this->em->getRepository(
998
            'KunstmaanNodeBundle:QueuedNodeTranslationAction'
999
        )->findOneBy(['nodeTranslation' => $nodeTranslation]);
1000
1001
        return [
1002
            'page' => $page,
1003
            'entityname' => ClassLookup::getClass($page),
1004
            'nodeVersions' => $nodeVersions,
1005
            'node' => $node,
1006
            'nodeTranslation' => $nodeTranslation,
1007
            'draft' => $draft,
1008
            'draftNodeVersion' => $draftNodeVersion,
1009
            'nodeVersion' => $nodeVersion,
1010
            'subaction' => $subaction,
1011
            'tabPane' => $tabPane,
1012
            'editmode' => true,
1013
            'queuedNodeTranslationAction' => $queuedNodeTranslationAction,
1014
            'nodeVersionLockCheck' => $this->container->getParameter('kunstmaan_node.lock_enabled'),
1015
            'nodeVersionLockInterval' => $this->container->getParameter('kunstmaan_node.lock_check_interval'),
1016
        ];
1017
    }
1018
1019
    /**
1020
     * @Route(
1021
     *      "checkNodeVersionLock/{id}/{public}",
1022
     *      requirements={"id" = "\d+", "public" = "(0|1)"},
1023
     *      name="KunstmaanNodeBundle_nodes_versionlock_check"
1024
     * )
1025
     *
1026
     * @param Request $request
1027
     * @param $id
1028
     *
1029
     * @return JsonResponse
1030
     */
1031
    public function checkNodeVersionLockAction(Request $request, $id, $public)
1032
    {
1033
        $nodeVersionIsLocked = false;
1034
        $message = '';
1035
        $this->init($request);
1036
1037
        /* @var Node $node */
1038
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
1039
1040
        try {
1041
            $this->checkPermission($node, PermissionMap::PERMISSION_EDIT);
1042
1043
            /** @var NodeVersionLockHelper $nodeVersionLockHelper */
1044
            $nodeVersionLockHelper = $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
1045
            $nodeTranslation = $node->getNodeTranslation($this->locale, true);
1046
1047
            if ($nodeTranslation) {
1048
                $nodeVersionIsLocked = $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation, $public);
1049
1050
                if ($nodeVersionIsLocked) {
1051
                    $users = $nodeVersionLockHelper->getUsersWithNodeVersionLock($nodeTranslation, $public, $this->getUser());
1052
                    $message = $this->get('translator')->trans('kuma_node.admin.edit.flash.locked', array('%users%' => implode(', ', $users)));
1053
                }
1054
            }
1055
        } catch (AccessDeniedException $ade) {
1056
        }
1057
1058
        return new JsonResponse(['lock' => $nodeVersionIsLocked, 'message' => $message]);
1059
    }
1060
1061
    /**
1062
     * @param NodeTranslation $nodeTranslation
1063
     * @param bool            $isPublic
1064
     *
1065
     * @return bool
1066
     */
1067
    private function isNodeVersionLocked(NodeTranslation $nodeTranslation, $isPublic)
1068
    {
1069
        if ($this->container->getParameter('kunstmaan_node.lock_enabled')) {
1070
            /** @var NodeVersionLockHelper $nodeVersionLockHelper */
1071
            $nodeVersionLockHelper = $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
1072
            $nodeVersionIsLocked = $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation, $isPublic);
1073
1074
            return $nodeVersionIsLocked;
1075
        }
1076
1077
        return false;
1078
    }
1079
1080
    /**
1081
     * @param HasNodeInterface $page            The page
1082
     * @param NodeTranslation  $nodeTranslation The node translation
1083
     * @param NodeVersion      $nodeVersion     The node version
1084
     *
1085
     * @return NodeVersion
1086
     */
1087
    private function createDraftVersion(
1088
        HasNodeInterface $page,
1089
        NodeTranslation $nodeTranslation,
1090
        NodeVersion $nodeVersion
1091
    ) {
1092
        $publicPage = $this->get('kunstmaan_admin.clone.helper')
1093
            ->deepCloneAndSave($page);
1094
        /* @var NodeVersion $publicNodeVersion */
1095
1096
        $publicNodeVersion = $this->em->getRepository(
1097
            'KunstmaanNodeBundle:NodeVersion'
1098
        )->createNodeVersionFor(
1099
            $publicPage,
1100
            $nodeTranslation,
1101
            $this->user,
1102
            $nodeVersion->getOrigin(),
1103
            'public',
1104
            $nodeVersion->getCreated()
1105
        );
1106
1107
        $nodeTranslation->setPublicNodeVersion($publicNodeVersion);
1108
        $nodeVersion->setType('draft');
1109
        $nodeVersion->setOrigin($publicNodeVersion);
1110
        $nodeVersion->setCreated(new DateTime());
1111
1112
        $this->em->persist($nodeTranslation);
1113
        $this->em->persist($nodeVersion);
1114
        $this->em->flush();
1115
1116
        $this->get('event_dispatcher')->dispatch(
1117
            Events::CREATE_DRAFT_VERSION,
1118
            new NodeEvent(
1119
                $nodeTranslation->getNode(),
1120
                $nodeTranslation,
1121
                $nodeVersion,
1122
                $page
1123
            )
1124
        );
1125
1126
        return $nodeVersion;
1127
    }
1128
1129
    /**
1130
     * @param Node   $node       The node
1131
     * @param string $permission The permission to check for
1132
     *
1133
     * @throws AccessDeniedException
1134
     */
1135
    private function checkPermission(Node $node, $permission)
1136
    {
1137
        if (false === $this->authorizationChecker->isGranted($permission, $node)) {
1138
            throw new AccessDeniedException();
1139
        }
1140
    }
1141
1142
    /**
1143
     * @param EntityManager   $em       The Entity Manager
1144
     * @param BaseUser        $user     The user who deletes the children
1145
     * @param string          $locale   The locale that was used
1146
     * @param ArrayCollection $children The children array
1147
     */
1148
    private function deleteNodeChildren(
1149
        EntityManager $em,
1150
        BaseUser $user,
1151
        $locale,
1152
        ArrayCollection $children
1153
    ) {
1154
        /* @var Node $childNode */
1155
        foreach ($children as $childNode) {
1156
            $childNodeTranslation = $childNode->getNodeTranslation(
1157
                $this->locale,
1158
                true
1159
            );
1160
1161
            $childNodeVersion = $childNodeTranslation->getPublicNodeVersion();
1162
            $childNodePage = $childNodeVersion->getRef($this->em);
1163
1164
            $this->get('event_dispatcher')->dispatch(
1165
                Events::PRE_DELETE,
1166
                new NodeEvent(
1167
                    $childNode,
1168
                    $childNodeTranslation,
1169
                    $childNodeVersion,
1170
                    $childNodePage
1171
                )
1172
            );
1173
1174
            $childNode->setDeleted(true);
1175
            $this->em->persist($childNode);
1176
1177
            $children2 = $childNode->getChildren();
1178
            $this->deleteNodeChildren($em, $user, $locale, $children2);
1179
1180
            $this->get('event_dispatcher')->dispatch(
1181
                Events::POST_DELETE,
1182
                new NodeEvent(
1183
                    $childNode,
1184
                    $childNodeTranslation,
1185
                    $childNodeVersion,
1186
                    $childNodePage
1187
                )
1188
            );
1189
        }
1190
    }
1191
1192
    /**
1193
     * @param Request $request
1194
     * @param string  $type
1195
     *
1196
     * @return HasNodeInterface
1197
     */
1198
    private function createNewPage(Request $request, $type)
1199
    {
1200
        /* @var HasNodeInterface $newPage */
1201
        $newPage = new $type();
1202
1203
        $title = $request->get('title');
1204
        if (\is_string($title) && !empty($title)) {
1205
            $newPage->setTitle($title);
1206
        } else {
1207
            $newPage->setTitle($this->get('translator')->trans('kuma_node.admin.new_page.title.default'));
1208
        }
1209
        $this->em->persist($newPage);
1210
        $this->em->flush();
1211
1212
        return $newPage;
1213
    }
1214
1215
    /**
1216
     * @param Request $request
1217
     *
1218
     * @return string
1219
     * @throw InvalidArgumentException
1220
     */
1221
    private function validatePageType($request)
1222
    {
1223
        $type = $request->get('type');
1224
1225
        if (empty($type)) {
1226
            throw new InvalidArgumentException(
1227
                'Please specify a type of page you want to create'
1228
            );
1229
        }
1230
1231
        return $type;
1232
    }
1233
1234
    /**
1235
     * @param Node $node
1236
     *
1237
     * @return \Symfony\Component\HttpFoundation\Response
1238
     */
1239
    private function renderNodeNotTranslatedPage(Node $node)
1240
    {
1241
        //try to find a parent node with the correct translation, if there is none allow copy.
1242
        //if there is a parent but it doesn't have the language to copy to don't allow it
1243
        $parentNode = $node->getParent();
1244
        if ($parentNode) {
1245
            $parentNodeTranslation = $parentNode->getNodeTranslation(
1246
                $this->locale,
1247
                true
1248
            );
1249
            $parentsAreOk = false;
1250
1251
            if ($parentNodeTranslation) {
1252
                $parentsAreOk = $this->em->getRepository(
1253
                    'KunstmaanNodeBundle:NodeTranslation'
1254
                )->hasParentNodeTranslationsForLanguage(
1255
                    $node->getParent()->getNodeTranslation(
1256
                        $this->locale,
1257
                        true
1258
                    ),
1259
                    $this->locale
1260
                );
1261
            }
1262
        } else {
1263
            $parentsAreOk = true;
1264
        }
1265
1266
        return $this->render(
1267
            'KunstmaanNodeBundle:NodeAdmin:pagenottranslated.html.twig',
1268
            array(
1269
                'node' => $node,
1270
                'nodeTranslations' => $node->getNodeTranslations(
1271
                    true
1272
                ),
1273
                'copyfromotherlanguages' => $parentsAreOk,
1274
            )
1275
        );
1276
    }
1277
}
1278