Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
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\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\Entity\QueuedNodeTranslationAction;
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\Helper\PageCloningHelper;
36
use Kunstmaan\NodeBundle\Repository\NodeVersionRepository;
37
use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
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\Routing\Annotation\Route;
44
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
45
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
46
use Symfony\Component\Translation\TranslatorInterface;
47
48
/**
49
 * NodeAdminController
50
 */
51
class NodeAdminController extends Controller
52
{
53
    /**
54
     * @var EntityManager
55
     */
56
    protected $em;
57
58
    /**
59
     * @var string
60
     */
61
    protected $locale;
62
63
    /**
64
     * @var AuthorizationCheckerInterface
65
     */
66
    protected $authorizationChecker;
67
68
    /**
69
     * @var BaseUser
70
     */
71
    protected $user;
72
73
    /**
74
     * @var AclHelper
75
     */
76
    protected $aclHelper;
77
78
    /**
79
     * @var AclManager
80
     */
81
    protected $aclManager;
82
83
    /**
84
     * @var NodeAdminPublisher
85
     */
86
    protected $nodePublisher;
87
88
    /**
89
     * @var TranslatorInterface
90
     */
91
    protected $translator;
92
93
    /** @var PageCloningHelper */
94
    private $pageCloningHelper;
95
96
    /**
97
     * init
98
     */
99
    protected function init(Request $request)
100
    {
101
        $this->em = $this->getDoctrine()->getManager();
102
        $this->locale = $request->getLocale();
103
        $this->authorizationChecker = $this->container->get('security.authorization_checker');
104
        $this->user = $this->getUser();
105
        $this->aclHelper = $this->container->get('kunstmaan_admin.acl.helper');
106
        $this->aclManager = $this->container->get('kunstmaan_admin.acl.manager');
107
        $this->nodePublisher = $this->container->get('kunstmaan_node.admin_node.publisher');
108
        $this->translator = $this->container->get('translator');
109
        $this->pageCloningHelper = $this->container->get(PageCloningHelper::class);
110
    }
111
112
    /**
113
     * @Route("/", name="KunstmaanNodeBundle_nodes")
114
     * @Template("@KunstmaanNode/Admin/list.html.twig")
115
     *
116
     * @return array
117
     */
118
    public function indexAction(Request $request)
119
    {
120
        $this->init($request);
121
122
        $nodeAdminListConfigurator = new NodeAdminListConfigurator(
123
            $this->em,
124
            $this->aclHelper,
125
            $this->locale,
126
            PermissionMap::PERMISSION_VIEW,
127
            $this->authorizationChecker
128
        );
129
130
        $locale = $this->locale;
131
        $acl = $this->authorizationChecker;
132
        $itemRoute = function (EntityInterface $item) use ($locale, $acl) {
133
            if ($acl->isGranted(PermissionMap::PERMISSION_VIEW, $item->getNode())) {
134
                return [
135
                    'path' => '_slug_preview',
136
                    'params' => ['_locale' => $locale, 'url' => $item->getUrl()],
137
                ];
138
            }
139
        };
140
        $nodeAdminListConfigurator->addSimpleItemAction('action.preview', $itemRoute, 'eye');
141
        $nodeAdminListConfigurator->setDomainConfiguration($this->get('kunstmaan_admin.domain_configuration'));
142
        $nodeAdminListConfigurator->setShowAddHomepage($this->getParameter('kunstmaan_node.show_add_homepage') && $this->isGranted('ROLE_SUPER_ADMIN'));
143
144
        /** @var AdminList $adminlist */
145
        $adminlist = $this->get('kunstmaan_adminlist.factory')->createList($nodeAdminListConfigurator);
146
        $adminlist->bindRequest($request);
147
148
        return [
149
            'adminlist' => $adminlist,
150
        ];
151
    }
152
153
    /**
154
     * @Route(
155
     *      "/{id}/copyfromotherlanguage",
156
     *      requirements={"id" = "\d+"},
157
     *      name="KunstmaanNodeBundle_nodes_copyfromotherlanguage",
158
     *      methods={"GET"}
159
     * )
160
     *
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(Node::class)->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(NodeTranslation::class)
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', ['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 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(Node::class)->find($id);
223
224
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
225
226
        $otherLanguageNodeTranslation = $this->em->getRepository(NodeTranslation::class)->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(NodeTranslation::class)
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', ['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 int $id
263
     *
264
     * @return RedirectResponse
265
     *
266
     * @throws AccessDeniedException
267
     */
268
    public function createEmptyPageAction(Request $request, $id)
269
    {
270
        $this->init($request);
271
        /* @var Node $node */
272
        $node = $this->em->getRepository(Node::class)->find($id);
273
274
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
275
276
        $entityName = $node->getRefEntityName();
277
        /* @var HasNodeInterface $myLanguagePage */
278
        $myLanguagePage = new $entityName();
279
        $myLanguagePage->setTitle('New page');
280
281
        $this->em->persist($myLanguagePage);
282
        $this->em->flush();
283
        /* @var NodeTranslation $nodeTranslation */
284
        $nodeTranslation = $this->em->getRepository(NodeTranslation::class)
285
            ->createNodeTranslationFor($myLanguagePage, $this->locale, $node, $this->user);
286
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
287
288
        $this->get('event_dispatcher')->dispatch(
289
            Events::ADD_EMPTY_PAGE_TRANSLATION,
290
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $myLanguagePage)
291
        );
292
293
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', ['id' => $id]));
294
    }
295
296
    /**
297
     * @Route("/{id}/publish", requirements={"id" =
298
     *                         "\d+"},
299
     *                         name="KunstmaanNodeBundle_nodes_publish", methods={"GET", "POST"})
300
     *
301
     * @param int $id
302
     *
303
     * @return RedirectResponse
304
     *
305
     * @throws AccessDeniedException
306
     */
307 View Code Duplication
    public function publishAction(Request $request, $id)
308
    {
309
        $this->init($request);
310
        /* @var Node $node */
311
        $node = $this->em->getRepository(Node::class)->find($id);
312
313
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
314
        $request = $this->get('request_stack')->getCurrentRequest();
315
        $this->nodePublisher->chooseHowToPublish($request, $nodeTranslation, $this->translator);
316
317
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', ['id' => $node->getId()]));
318
    }
319
320
    /**
321
     * @Route(
322
     *      "/{id}/unpublish",
323
     *      requirements={"id" = "\d+"},
324
     *      name="KunstmaanNodeBundle_nodes_unpublish",
325
     *      methods={"GET", "POST"}
326
     * )
327
     *
328
     * @param int $id
329
     *
330
     * @return RedirectResponse
331
     *
332
     * @throws AccessDeniedException
333
     */
334 View Code Duplication
    public function unPublishAction(Request $request, $id)
335
    {
336
        $this->init($request);
337
        /* @var Node $node */
338
        $node = $this->em->getRepository(Node::class)->find($id);
339
340
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
341
        $request = $this->get('request_stack')->getCurrentRequest();
342
        $this->nodePublisher->chooseHowToUnpublish($request, $nodeTranslation, $this->translator);
343
344
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', ['id' => $node->getId()]));
345
    }
346
347
    /**
348
     * @Route(
349
     *      "/{id}/unschedulepublish",
350
     *      requirements={"id" = "\d+"},
351
     *      name="KunstmaanNodeBundle_nodes_unschedule_publish",
352
     *      methods={"GET", "POST"}
353
     * )
354
     *
355
     * @param int $id
356
     *
357
     * @return RedirectResponse
358
     *
359
     * @throws AccessDeniedException
360
     */
361 View Code Duplication
    public function unSchedulePublishAction(Request $request, $id)
362
    {
363
        $this->init($request);
364
365
        /* @var Node $node */
366
        $node = $this->em->getRepository(Node::class)->find($id);
367
368
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
369
        $this->nodePublisher->unSchedulePublish($nodeTranslation);
370
371
        $this->addFlash(
372
            FlashTypes::SUCCESS,
373
            $this->get('translator')->trans('kuma_node.admin.unschedule.flash.success')
374
        );
375
376
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', ['id' => $id]));
377
    }
378
379
    /**
380
     * @Route(
381
     *      "/{id}/delete",
382
     *      requirements={"id" = "\d+"},
383
     *      name="KunstmaanNodeBundle_nodes_delete",
384
     *      methods={"POST"}
385
     * )
386
     *
387
     * @param int $id
388
     *
389
     * @return RedirectResponse
390
     *
391
     * @throws AccessDeniedException
392
     */
393
    public function deleteAction(Request $request, $id)
394
    {
395
        $this->init($request);
396
        /* @var Node $node */
397
        $node = $this->em->getRepository(Node::class)->find($id);
398
399
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_DELETE, $node);
400
401
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
402
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
403
        $page = $nodeVersion->getRef($this->em);
404
405
        $this->get('event_dispatcher')->dispatch(
406
            Events::PRE_DELETE,
407
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
408
        );
409
410
        $node->setDeleted(true);
411
        $this->em->persist($node);
412
413
        $children = $node->getChildren();
414
        $this->deleteNodeChildren($this->em, $this->user, $this->locale, $children);
415
        $this->em->flush();
416
417
        $event = new NodeEvent($node, $nodeTranslation, $nodeVersion, $page);
418
        $this->get('event_dispatcher')->dispatch(Events::POST_DELETE, $event);
419
        if (null === $response = $event->getResponse()) {
420
            $nodeParent = $node->getParent();
421
            // Check if we have a parent. Otherwise redirect to pages overview.
422
            if ($nodeParent) {
423
                $url = $this->get('router')->generate(
424
                    'KunstmaanNodeBundle_nodes_edit',
425
                    ['id' => $nodeParent->getId()]
426
                );
427
            } else {
428
                $url = $this->get('router')->generate(
429
                    'KunstmaanNodeBundle_nodes'
430
                );
431
            }
432
            $response = new RedirectResponse($url);
433
        }
434
435
        $this->addFlash(
436
            FlashTypes::SUCCESS,
437
            $this->get('translator')->trans('kuma_node.admin.delete.flash.success')
438
        );
439
440
        return $response;
441
    }
442
443
    /**
444
     * @Route(
445
     *      "/{id}/duplicate",
446
     *      requirements={"id" = "\d+"},
447
     *      name="KunstmaanNodeBundle_nodes_duplicate",
448
     *      methods={"POST"}
449
     * )
450
     *
451
     * @param int $id
452
     *
453
     * @return RedirectResponse
454
     *
455
     * @throws AccessDeniedException
456
     */
457
    public function duplicateAction(Request $request, $id)
458
    {
459
        $this->init($request);
460
        /* @var Node $parentNode */
461
        $originalNode = $this->em->getRepository(Node::class)
462
            ->find($id);
463
464
        // Check with Acl
465
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $originalNode);
466
467
        $request = $this->get('request_stack')->getCurrentRequest();
468
469
        $originalNodeTranslations = $originalNode->getNodeTranslation($this->locale, true);
470
        $originalRef = $originalNodeTranslations->getPublicNodeVersion()->getRef($this->em);
471
        $newPage = $this->get('kunstmaan_admin.clone.helper')
472
            ->deepCloneAndSave($originalRef);
473
474
        //set the title
475
        $title = $request->get('title');
476
        if (\is_string($title) && !empty($title)) {
477
            $newPage->setTitle($title);
478
        } else {
479
            $newPage->setTitle('New page');
480
        }
481
482
        //set the parent
483
        $parentNodeTranslation = $originalNode->getParent()->getNodeTranslation($this->locale, true);
484
        $parent = $parentNodeTranslation->getPublicNodeVersion()->getRef($this->em);
485
        $newPage->setParent($parent);
486
        $this->em->persist($newPage);
487
        $this->em->flush();
488
489
        /* @var Node $nodeNewPage */
490
        $nodeNewPage = $this->em->getRepository(Node::class)->createNodeFor(
491
            $newPage,
492
            $this->locale,
493
            $this->user
494
        );
495
496
        $nodeTranslation = $nodeNewPage->getNodeTranslation($this->locale, true);
497
        if ($newPage->isStructureNode()) {
498
            $nodeTranslation->setSlug('');
499
            $this->em->persist($nodeTranslation);
500
        }
501
        $this->em->flush();
502
503
        $this->aclManager->updateNodeAcl($originalNode, $nodeNewPage);
504
505
        $this->addFlash(
506
            FlashTypes::SUCCESS,
507
            $this->get('translator')->trans('kuma_node.admin.duplicate.flash.success')
508
        );
509
510
        return $this->redirect(
511
            $this->generateUrl('KunstmaanNodeBundle_nodes_edit', ['id' => $nodeNewPage->getId()])
512
        );
513
    }
514
515
    /**
516
     * @Route(
517
     *      "/{id}/duplicate-with-children",
518
     *      requirements={"id" = "\d+"},
519
     *      name="KunstmaanNodeBundle_nodes_duplicate_with_children",
520
     *      methods={"POST"}
521
     * )
522
     *
523
     * @throws AccessDeniedException
524
     */
525
    public function duplicateWithChildrenAction(Request $request, $id)
526
    {
527
        if (!$this->getParameter('kunstmaan_node.show_duplicate_with_children')) {
528
            return $this->redirectToRoute('KunstmaanNodeBundle_nodes_edit', ['id' => $id]);
529
        }
530
531
        $this->init($request);
532
        $title = $request->get('title', null);
533
534
        $nodeNewPage = $this->pageCloningHelper->duplicateWithChildren($id, $this->locale, $this->user, $title);
535
536
        $this->addFlash(FlashTypes::SUCCESS, $this->get('translator')->trans('kuma_node.admin.duplicate.flash.success'));
537
538
        return $this->redirectToRoute('KunstmaanNodeBundle_nodes_edit', ['id' => $nodeNewPage->getId()]);
539
    }
540
541
    /**
542
     * @Route(
543
     *      "/{id}/revert",
544
     *      requirements={"id" = "\d+"},
545
     *      defaults={"subaction" = "public"},
546
     *      name="KunstmaanNodeBundle_nodes_revert",
547
     *      methods={"GET"}
548
     * )
549
     *
550
     * @param int $id The node id
551
     *
552
     * @return RedirectResponse
553
     *
554
     * @throws AccessDeniedException
555
     * @throws InvalidArgumentException
556
     */
557
    public function revertAction(Request $request, $id)
558
    {
559
        $this->init($request);
560
        /* @var Node $node */
561
        $node = $this->em->getRepository(Node::class)->find($id);
562
563
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
564
565
        $version = $request->get('version');
566
567
        if (empty($version) || !is_numeric($version)) {
568
            throw new InvalidArgumentException('No version was specified');
569
        }
570
571
        /* @var NodeVersionRepository $nodeVersionRepo */
572
        $nodeVersionRepo = $this->em->getRepository(NodeVersion::class);
573
        /* @var NodeVersion $nodeVersion */
574
        $nodeVersion = $nodeVersionRepo->find($version);
575
576
        if (\is_null($nodeVersion)) {
577
            throw new InvalidArgumentException('Version does not exist');
578
        }
579
580
        /* @var NodeTranslation $nodeTranslation */
581
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
582
        $page = $nodeVersion->getRef($this->em);
583
        /* @var HasNodeInterface $clonedPage */
584
        $clonedPage = $this->get('kunstmaan_admin.clone.helper')
585
            ->deepCloneAndSave($page);
586
        $newNodeVersion = $nodeVersionRepo->createNodeVersionFor(
587
            $clonedPage,
588
            $nodeTranslation,
589
            $this->user,
590
            $nodeVersion,
591
            'draft'
592
        );
593
594
        $nodeTranslation->setTitle($clonedPage->getTitle());
595
        $this->em->persist($nodeTranslation);
596
        $this->em->flush();
597
598
        $this->get('event_dispatcher')->dispatch(
599
            Events::REVERT,
600
            new RevertNodeAction(
601
                $node,
602
                $nodeTranslation,
603
                $newNodeVersion,
604
                $clonedPage,
605
                $nodeVersion,
606
                $page
607
            )
608
        );
609
610
        $this->addFlash(
611
            FlashTypes::SUCCESS,
612
            $this->get('translator')->trans('kuma_node.admin.revert.flash.success')
613
        );
614
615
        return $this->redirect(
616
            $this->generateUrl(
617
                'KunstmaanNodeBundle_nodes_edit',
618
                [
619
                    'id' => $id,
620
                    'subaction' => 'draft',
621
                ]
622
            )
623
        );
624
    }
625
626
    /**
627
     * @Route(
628
     *      "/{id}/add",
629
     *      requirements={"id" = "\d+"},
630
     *      name="KunstmaanNodeBundle_nodes_add",
631
     *      methods={"POST"}
632
     * )
633
     *
634
     * @param int $id
635
     *
636
     * @return RedirectResponse
637
     *
638
     * @throws AccessDeniedException
639
     * @throws InvalidArgumentException
640
     */
641
    public function addAction(Request $request, $id)
642
    {
643
        $this->init($request);
644
        /* @var Node $parentNode */
645
        $parentNode = $this->em->getRepository(Node::class)->find($id);
646
647
        // Check with Acl
648
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parentNode);
649
650
        $parentNodeTranslation = $parentNode->getNodeTranslation($this->locale, true);
651
        $parentNodeVersion = $parentNodeTranslation->getPublicNodeVersion();
652
        $parentPage = $parentNodeVersion->getRef($this->em);
653
654
        $type = $this->validatePageType($request);
655
        $newPage = $this->createNewPage($request, $type);
656
        $newPage->setParent($parentPage);
657
658
        /* @var Node $nodeNewPage */
659
        $nodeNewPage = $this->em->getRepository(Node::class)
660
            ->createNodeFor($newPage, $this->locale, $this->user);
661
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
662
            $this->locale,
663
            true
664
        );
665
        $weight = $this->em->getRepository(NodeTranslation::class)
666
                ->getMaxChildrenWeight($parentNode, $this->locale) + 1;
667
        $nodeTranslation->setWeight($weight);
668
669
        if ($newPage->isStructureNode()) {
670
            $nodeTranslation->setSlug('');
671
        }
672
673
        $this->em->persist($nodeTranslation);
674
        $this->em->flush();
675
676
        $this->aclManager->updateNodeAcl($parentNode, $nodeNewPage);
677
678
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
679
680
        $this->get('event_dispatcher')->dispatch(
681
            Events::ADD_NODE,
682
            new NodeEvent(
683
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
684
            )
685
        );
686
687
        return $this->redirect(
688
            $this->generateUrl(
689
                'KunstmaanNodeBundle_nodes_edit',
690
                ['id' => $nodeNewPage->getId()]
691
            )
692
        );
693
    }
694
695
    /**
696
     * @Route("/add-homepage", name="KunstmaanNodeBundle_nodes_add_homepage", methods={"POST"})
697
     *
698
     * @return RedirectResponse
699
     *
700
     * @throws AccessDeniedException
701
     * @throws InvalidArgumentException
702
     */
703
    public function addHomepageAction(Request $request)
704
    {
705
        $this->init($request);
706
707
        // Check with Acl
708
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
709
710
        $type = $this->validatePageType($request);
711
712
        $newPage = $this->createNewPage($request, $type);
713
714
        /* @var Node $nodeNewPage */
715
        $nodeNewPage = $this->em->getRepository(Node::class)
716
            ->createNodeFor($newPage, $this->locale, $this->user);
717
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
718
            $this->locale,
719
            true
720
        );
721
        $this->em->flush();
722
723
        // Set default permissions
724
        $this->container->get('kunstmaan_node.acl_permission_creator_service')
725
            ->createPermission($nodeNewPage);
726
727
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
728
729
        $this->get('event_dispatcher')->dispatch(
730
            Events::ADD_NODE,
731
            new NodeEvent(
732
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
733
            )
734
        );
735
736
        return $this->redirect(
737
            $this->generateUrl(
738
                'KunstmaanNodeBundle_nodes_edit',
739
                ['id' => $nodeNewPage->getId()]
740
            )
741
        );
742
    }
743
744
    /**
745
     * @Route("/reorder", name="KunstmaanNodeBundle_nodes_reorder", methods={"POST"})
746
     *
747
     * @return string
748
     *
749
     * @throws AccessDeniedException
750
     */
751
    public function reorderAction(Request $request)
752
    {
753
        $this->init($request);
754
        $nodes = [];
755
        $nodeIds = $request->get('nodes');
756
        $changeParents = $request->get('parent');
757
758
        foreach ($nodeIds as $id) {
759
            /* @var Node $node */
760
            $node = $this->em->getRepository(Node::class)->find($id);
761
            $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
762
            $nodes[] = $node;
763
        }
764
765
        $weight = 1;
766
        foreach ($nodes as $node) {
767
            $newParentId = isset($changeParents[$node->getId()]) ? $changeParents[$node->getId()] : null;
768
            if ($newParentId) {
769
                $parent = $this->em->getRepository(Node::class)->find($newParentId);
770
                $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parent);
771
                $node->setParent($parent);
772
                $this->em->persist($node);
773
                $this->em->flush($node);
774
            }
775
776
            /* @var NodeTranslation $nodeTranslation */
777
            $nodeTranslation = $node->getNodeTranslation($this->locale, true);
778
779
            if ($nodeTranslation) {
780
                $nodeVersion = $nodeTranslation->getPublicNodeVersion();
781
                $page = $nodeVersion->getRef($this->em);
782
783
                $this->get('event_dispatcher')->dispatch(
784
                    Events::PRE_PERSIST,
785
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
786
                );
787
788
                $nodeTranslation->setWeight($weight);
789
                $this->em->persist($nodeTranslation);
790
                $this->em->flush($nodeTranslation);
791
792
                $this->get('event_dispatcher')->dispatch(
793
                    Events::POST_PERSIST,
794
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
It seems like $page defined by $nodeVersion->getRef($this->em) on line 781 can be null; however, Kunstmaan\NodeBundle\Eve...odeEvent::__construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

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