vendor/kunstmaan/node-bundle/Controller/NodeAdminController.php line 810

Open in your IDE?
  1. <?php
  2. namespace Kunstmaan\NodeBundle\Controller;
  3. use DateTime;
  4. use Doctrine\Common\Collections\ArrayCollection;
  5. use Doctrine\ORM\EntityManager;
  6. use InvalidArgumentException;
  7. use Kunstmaan\AdminBundle\Entity\BaseUser;
  8. use Kunstmaan\AdminBundle\Entity\EntityInterface;
  9. use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
  10. use Kunstmaan\AdminBundle\Helper\FormWidgets\FormWidget;
  11. use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\Tab;
  12. use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\TabPane;
  13. use Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper;
  14. use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMap;
  15. use Kunstmaan\AdminBundle\Service\AclManager;
  16. use Kunstmaan\AdminListBundle\AdminList\AdminList;
  17. use Kunstmaan\NodeBundle\AdminList\NodeAdminListConfigurator;
  18. use Kunstmaan\NodeBundle\Entity\HasNodeInterface;
  19. use Kunstmaan\NodeBundle\Entity\Node;
  20. use Kunstmaan\NodeBundle\Entity\NodeTranslation;
  21. use Kunstmaan\NodeBundle\Entity\NodeVersion;
  22. use Kunstmaan\NodeBundle\Event\AdaptFormEvent;
  23. use Kunstmaan\NodeBundle\Event\CopyPageTranslationNodeEvent;
  24. use Kunstmaan\NodeBundle\Event\Events;
  25. use Kunstmaan\NodeBundle\Event\NodeEvent;
  26. use Kunstmaan\NodeBundle\Event\RecopyPageTranslationNodeEvent;
  27. use Kunstmaan\NodeBundle\Event\RevertNodeAction;
  28. use Kunstmaan\NodeBundle\Form\NodeMenuTabAdminType;
  29. use Kunstmaan\NodeBundle\Form\NodeMenuTabTranslationAdminType;
  30. use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeAdminPublisher;
  31. use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeVersionLockHelper;
  32. use Kunstmaan\NodeBundle\Repository\NodeVersionRepository;
  33. use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
  34. use Symfony\Component\Routing\Annotation\Route;
  35. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  36. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  37. use Symfony\Component\HttpFoundation\JsonResponse;
  38. use Symfony\Component\HttpFoundation\RedirectResponse;
  39. use Symfony\Component\HttpFoundation\Request;
  40. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  41. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  42. use Symfony\Component\Translation\TranslatorInterface;
  43. /**
  44.  * NodeAdminController
  45.  */
  46. class NodeAdminController extends Controller
  47. {
  48.     /**
  49.      * @var EntityManager
  50.      */
  51.     protected $em;
  52.     /**
  53.      * @var string
  54.      */
  55.     protected $locale;
  56.     /**
  57.      * @var AuthorizationCheckerInterface
  58.      */
  59.     protected $authorizationChecker;
  60.     /**
  61.      * @var BaseUser
  62.      */
  63.     protected $user;
  64.     /**
  65.      * @var AclHelper
  66.      */
  67.     protected $aclHelper;
  68.     /**
  69.      * @var AclManager
  70.      */
  71.     protected $aclManager;
  72.     /**
  73.      * @var NodeAdminPublisher
  74.      */
  75.     protected $nodePublisher;
  76.     /**
  77.      * @var TranslatorInterface
  78.      */
  79.     protected $translator;
  80.     /**
  81.      * init
  82.      *
  83.      * @param Request $request
  84.      */
  85.     protected function init(Request $request)
  86.     {
  87.         $this->em $this->getDoctrine()->getManager();
  88.         $this->locale $request->getLocale();
  89.         $this->authorizationChecker $this->container->get('security.authorization_checker');
  90.         $this->user $this->getUser();
  91.         $this->aclHelper $this->container->get('kunstmaan_admin.acl.helper');
  92.         $this->aclManager $this->container->get('kunstmaan_admin.acl.manager');
  93.         $this->nodePublisher $this->container->get('kunstmaan_node.admin_node.publisher');
  94.         $this->translator $this->container->get('translator');
  95.     }
  96.     /**
  97.      * @Route("/", name="KunstmaanNodeBundle_nodes")
  98.      * @Template("@KunstmaanNode/Admin/list.html.twig")
  99.      *
  100.      * @param Request $request
  101.      *
  102.      * @return array
  103.      */
  104.     public function indexAction(Request $request)
  105.     {
  106.         $this->init($request);
  107.         $nodeAdminListConfigurator = new NodeAdminListConfigurator(
  108.             $this->em,
  109.             $this->aclHelper,
  110.             $this->locale,
  111.             PermissionMap::PERMISSION_VIEW,
  112.             $this->authorizationChecker
  113.         );
  114.         $locale $this->locale;
  115.         $acl $this->authorizationChecker;
  116.         $itemRoute = function (EntityInterface $item) use ($locale$acl) {
  117.             if ($acl->isGranted(PermissionMap::PERMISSION_VIEW$item->getNode())) {
  118.                 return array(
  119.                     'path' => '_slug_preview',
  120.                     'params' => ['_locale' => $locale'url' => $item->getUrl()],
  121.                 );
  122.             }
  123.         };
  124.         $nodeAdminListConfigurator->addSimpleItemAction('action.preview'$itemRoute'eye');
  125.         $nodeAdminListConfigurator->setDomainConfiguration($this->get('kunstmaan_admin.domain_configuration'));
  126.         $nodeAdminListConfigurator->setShowAddHomepage($this->getParameter('kunstmaan_node.show_add_homepage') && $this->isGranted('ROLE_SUPER_ADMIN'));
  127.         /** @var AdminList $adminlist */
  128.         $adminlist $this->get('kunstmaan_adminlist.factory')->createList($nodeAdminListConfigurator);
  129.         $adminlist->bindRequest($request);
  130.         return array(
  131.             'adminlist' => $adminlist,
  132.         );
  133.     }
  134.     /**
  135.      * @Route(
  136.      *      "/{id}/copyfromotherlanguage",
  137.      *      requirements={"id" = "\d+"},
  138.      *      name="KunstmaanNodeBundle_nodes_copyfromotherlanguage",
  139.      *      methods={"GET"}
  140.      * )
  141.      *
  142.      * @param Request $request
  143.      * @param int     $id      The node id
  144.      *
  145.      * @return RedirectResponse
  146.      *
  147.      * @throws AccessDeniedException
  148.      */
  149.     public function copyFromOtherLanguageAction(Request $request$id)
  150.     {
  151.         $this->init($request);
  152.         /* @var Node $node */
  153.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  154.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$node);
  155.         $originalLanguage $request->get('originallanguage');
  156.         $otherLanguageNodeTranslation $node->getNodeTranslation($originalLanguagetrue);
  157.         $otherLanguageNodeNodeVersion $otherLanguageNodeTranslation->getPublicNodeVersion();
  158.         $otherLanguagePage $otherLanguageNodeNodeVersion->getRef($this->em);
  159.         $myLanguagePage $this->get('kunstmaan_admin.clone.helper')
  160.             ->deepCloneAndSave($otherLanguagePage);
  161.         /* @var NodeTranslation $nodeTranslation */
  162.         $nodeTranslation $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
  163.             ->createNodeTranslationFor($myLanguagePage$this->locale$node$this->user);
  164.         $nodeVersion $nodeTranslation->getPublicNodeVersion();
  165.         $this->get('event_dispatcher')->dispatch(
  166.             Events::COPY_PAGE_TRANSLATION,
  167.             new CopyPageTranslationNodeEvent(
  168.                 $node,
  169.                 $nodeTranslation,
  170.                 $nodeVersion,
  171.                 $myLanguagePage,
  172.                 $otherLanguageNodeTranslation,
  173.                 $otherLanguageNodeNodeVersion,
  174.                 $otherLanguagePage,
  175.                 $originalLanguage
  176.             )
  177.         );
  178.         return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
  179.     }
  180.     /**
  181.      * @Route(
  182.      *      "/{id}/recopyfromotherlanguage",
  183.      *      requirements={"id" = "\d+"},
  184.      *      name="KunstmaanNodeBundle_nodes_recopyfromotherlanguage",
  185.      *      methods={"POST"}
  186.      * )
  187.      *
  188.      * @param Request $request
  189.      * @param int     $id      The node id
  190.      *
  191.      * @return RedirectResponse
  192.      *
  193.      * @throws AccessDeniedException
  194.      */
  195.     public function recopyFromOtherLanguageAction(Request $request$id)
  196.     {
  197.         $this->init($request);
  198.         /* @var Node $node */
  199.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  200.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$node);
  201.         $otherLanguageNodeTranslation $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')->find($request->get('source'));
  202.         $otherLanguageNodeNodeVersion $otherLanguageNodeTranslation->getPublicNodeVersion();
  203.         $otherLanguagePage $otherLanguageNodeNodeVersion->getRef($this->em);
  204.         $myLanguagePage $this->get('kunstmaan_admin.clone.helper')
  205.             ->deepCloneAndSave($otherLanguagePage);
  206.         /* @var NodeTranslation $nodeTranslation */
  207.         $nodeTranslation $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
  208.             ->addDraftNodeVersionFor($myLanguagePage$this->locale$node$this->user);
  209.         $nodeVersion $nodeTranslation->getPublicNodeVersion();
  210.         $this->get('event_dispatcher')->dispatch(
  211.             Events::RECOPY_PAGE_TRANSLATION,
  212.             new RecopyPageTranslationNodeEvent(
  213.                 $node,
  214.                 $nodeTranslation,
  215.                 $nodeVersion,
  216.                 $myLanguagePage,
  217.                 $otherLanguageNodeTranslation,
  218.                 $otherLanguageNodeNodeVersion,
  219.                 $otherLanguagePage,
  220.                 $otherLanguageNodeTranslation->getLang()
  221.             )
  222.         );
  223.         return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id'subaction' => NodeVersion::DRAFT_VERSION)));
  224.     }
  225.     /**
  226.      * @Route(
  227.      *      "/{id}/createemptypage",
  228.      *      requirements={"id" = "\d+"},
  229.      *      name="KunstmaanNodeBundle_nodes_createemptypage",
  230.      *      methods={"GET"}
  231.      * )
  232.      *
  233.      * @param Request $request
  234.      * @param int     $id
  235.      *
  236.      * @return RedirectResponse
  237.      *
  238.      * @throws AccessDeniedException
  239.      */
  240.     public function createEmptyPageAction(Request $request$id)
  241.     {
  242.         $this->init($request);
  243.         /* @var Node $node */
  244.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  245.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$node);
  246.         $entityName $node->getRefEntityName();
  247.         /* @var HasNodeInterface $myLanguagePage */
  248.         $myLanguagePage = new $entityName();
  249.         $myLanguagePage->setTitle('New page');
  250.         $this->em->persist($myLanguagePage);
  251.         $this->em->flush();
  252.         /* @var NodeTranslation $nodeTranslation */
  253.         $nodeTranslation $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
  254.             ->createNodeTranslationFor($myLanguagePage$this->locale$node$this->user);
  255.         $nodeVersion $nodeTranslation->getPublicNodeVersion();
  256.         $this->get('event_dispatcher')->dispatch(
  257.             Events::ADD_EMPTY_PAGE_TRANSLATION,
  258.             new NodeEvent($node$nodeTranslation$nodeVersion$myLanguagePage)
  259.         );
  260.         return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
  261.     }
  262.     /**
  263.      * @Route("/{id}/publish", requirements={"id" =
  264.      *                         "\d+"},
  265.      *                         name="KunstmaanNodeBundle_nodes_publish", methods={"GET", "POST"})
  266.      *
  267.      * @param Request $request
  268.      * @param int     $id
  269.      *
  270.      * @return RedirectResponse
  271.      *
  272.      * @throws AccessDeniedException
  273.      */
  274.     public function publishAction(Request $request$id)
  275.     {
  276.         $this->init($request);
  277.         /* @var Node $node */
  278.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  279.         $nodeTranslation $node->getNodeTranslation($this->localetrue);
  280.         $request $this->get('request_stack')->getCurrentRequest();
  281.         $this->nodePublisher->chooseHowToPublish($request$nodeTranslation$this->translator);
  282.         return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
  283.     }
  284.     /**
  285.      * @Route(
  286.      *      "/{id}/unpublish",
  287.      *      requirements={"id" = "\d+"},
  288.      *      name="KunstmaanNodeBundle_nodes_unpublish",
  289.      *      methods={"GET", "POST"}
  290.      * )
  291.      *
  292.      * @param Request $request
  293.      * @param int     $id
  294.      *
  295.      * @return RedirectResponse
  296.      *
  297.      * @throws AccessDeniedException
  298.      */
  299.     public function unPublishAction(Request $request$id)
  300.     {
  301.         $this->init($request);
  302.         /* @var Node $node */
  303.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  304.         $nodeTranslation $node->getNodeTranslation($this->localetrue);
  305.         $request $this->get('request_stack')->getCurrentRequest();
  306.         $this->nodePublisher->chooseHowToUnpublish($request$nodeTranslation$this->translator);
  307.         return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
  308.     }
  309.     /**
  310.      * @Route(
  311.      *      "/{id}/unschedulepublish",
  312.      *      requirements={"id" = "\d+"},
  313.      *      name="KunstmaanNodeBundle_nodes_unschedule_publish",
  314.      *      methods={"GET", "POST"}
  315.      * )
  316.      *
  317.      * @param Request $request
  318.      * @param int     $id
  319.      *
  320.      * @return RedirectResponse
  321.      *
  322.      * @throws AccessDeniedException
  323.      */
  324.     public function unSchedulePublishAction(Request $request$id)
  325.     {
  326.         $this->init($request);
  327.         /* @var Node $node */
  328.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  329.         $nodeTranslation $node->getNodeTranslation($this->localetrue);
  330.         $this->nodePublisher->unSchedulePublish($nodeTranslation);
  331.         $this->addFlash(
  332.             FlashTypes::SUCCESS,
  333.             $this->get('translator')->trans('kuma_node.admin.unschedule.flash.success')
  334.         );
  335.         return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
  336.     }
  337.     /**
  338.      * @Route(
  339.      *      "/{id}/delete",
  340.      *      requirements={"id" = "\d+"},
  341.      *      name="KunstmaanNodeBundle_nodes_delete",
  342.      *      methods={"POST"}
  343.      * )
  344.      *
  345.      * @param Request $request
  346.      * @param int     $id
  347.      *
  348.      * @return RedirectResponse
  349.      *
  350.      * @throws AccessDeniedException
  351.      */
  352.     public function deleteAction(Request $request$id)
  353.     {
  354.         $this->init($request);
  355.         /* @var Node $node */
  356.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  357.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_DELETE$node);
  358.         $nodeTranslation $node->getNodeTranslation($this->localetrue);
  359.         $nodeVersion $nodeTranslation->getPublicNodeVersion();
  360.         $page $nodeVersion->getRef($this->em);
  361.         $this->get('event_dispatcher')->dispatch(
  362.             Events::PRE_DELETE,
  363.             new NodeEvent($node$nodeTranslation$nodeVersion$page)
  364.         );
  365.         $node->setDeleted(true);
  366.         $this->em->persist($node);
  367.         $children $node->getChildren();
  368.         $this->deleteNodeChildren($this->em$this->user$this->locale$children);
  369.         $this->em->flush();
  370.         $event = new NodeEvent($node$nodeTranslation$nodeVersion$page);
  371.         $this->get('event_dispatcher')->dispatch(Events::POST_DELETE$event);
  372.         if (null === $response $event->getResponse()) {
  373.             $nodeParent $node->getParent();
  374.             // Check if we have a parent. Otherwise redirect to pages overview.
  375.             if ($nodeParent) {
  376.                 $url $this->get('router')->generate(
  377.                     'KunstmaanNodeBundle_nodes_edit',
  378.                     array('id' => $nodeParent->getId())
  379.                 );
  380.             } else {
  381.                 $url $this->get('router')->generate(
  382.                     'KunstmaanNodeBundle_nodes'
  383.                 );
  384.             }
  385.             $response = new RedirectResponse($url);
  386.         }
  387.         $this->addFlash(
  388.             FlashTypes::SUCCESS,
  389.             $this->get('translator')->trans('kuma_node.admin.delete.flash.success')
  390.         );
  391.         return $response;
  392.     }
  393.     /**
  394.      * @Route(
  395.      *      "/{id}/duplicate",
  396.      *      requirements={"id" = "\d+"},
  397.      *      name="KunstmaanNodeBundle_nodes_duplicate",
  398.      *      methods={"POST"}
  399.      * )
  400.      *
  401.      * @param Request $request
  402.      * @param int     $id
  403.      *
  404.      * @return RedirectResponse
  405.      *
  406.      * @throws AccessDeniedException
  407.      */
  408.     public function duplicateAction(Request $request$id)
  409.     {
  410.         $this->init($request);
  411.         /* @var Node $parentNode */
  412.         $originalNode $this->em->getRepository('KunstmaanNodeBundle:Node')
  413.             ->find($id);
  414.         // Check with Acl
  415.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$originalNode);
  416.         $request $this->get('request_stack')->getCurrentRequest();
  417.         $originalNodeTranslations $originalNode->getNodeTranslation($this->localetrue);
  418.         $originalRef $originalNodeTranslations->getPublicNodeVersion()->getRef($this->em);
  419.         $newPage $this->get('kunstmaan_admin.clone.helper')
  420.             ->deepCloneAndSave($originalRef);
  421.         //set the title
  422.         $title $request->get('title');
  423.         if (\is_string($title) && !empty($title)) {
  424.             $newPage->setTitle($title);
  425.         } else {
  426.             $newPage->setTitle('New page');
  427.         }
  428.         //set the parent
  429.         $parentNodeTranslation $originalNode->getParent()->getNodeTranslation($this->localetrue);
  430.         $parent $parentNodeTranslation->getPublicNodeVersion()->getRef($this->em);
  431.         $newPage->setParent($parent);
  432.         $this->em->persist($newPage);
  433.         $this->em->flush();
  434.         /* @var Node $nodeNewPage */
  435.         $nodeNewPage $this->em->getRepository('KunstmaanNodeBundle:Node')->createNodeFor(
  436.             $newPage,
  437.             $this->locale,
  438.             $this->user
  439.         );
  440.         $nodeTranslation $nodeNewPage->getNodeTranslation($this->localetrue);
  441.         if ($newPage->isStructureNode()) {
  442.             $nodeTranslation->setSlug('');
  443.             $this->em->persist($nodeTranslation);
  444.         }
  445.         $this->em->flush();
  446.         $this->aclManager->updateNodeAcl($originalNode$nodeNewPage);
  447.         $this->addFlash(
  448.             FlashTypes::SUCCESS,
  449.             $this->get('translator')->trans('kuma_node.admin.duplicate.flash.success')
  450.         );
  451.         return $this->redirect(
  452.             $this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $nodeNewPage->getId()))
  453.         );
  454.     }
  455.     /**
  456.      * @Route(
  457.      *      "/{id}/revert",
  458.      *      requirements={"id" = "\d+"},
  459.      *      defaults={"subaction" = "public"},
  460.      *      name="KunstmaanNodeBundle_nodes_revert",
  461.      *      methods={"GET"}
  462.      * )
  463.      *
  464.      * @param Request $request
  465.      * @param int     $id      The node id
  466.      *
  467.      * @return RedirectResponse
  468.      *
  469.      * @throws AccessDeniedException
  470.      * @throws InvalidArgumentException
  471.      */
  472.     public function revertAction(Request $request$id)
  473.     {
  474.         $this->init($request);
  475.         /* @var Node $node */
  476.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  477.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$node);
  478.         $version $request->get('version');
  479.         if (empty($version) || !is_numeric($version)) {
  480.             throw new InvalidArgumentException('No version was specified');
  481.         }
  482.         /* @var NodeVersionRepository $nodeVersionRepo */
  483.         $nodeVersionRepo $this->em->getRepository('KunstmaanNodeBundle:NodeVersion');
  484.         /* @var NodeVersion $nodeVersion */
  485.         $nodeVersion $nodeVersionRepo->find($version);
  486.         if (\is_null($nodeVersion)) {
  487.             throw new InvalidArgumentException('Version does not exist');
  488.         }
  489.         /* @var NodeTranslation $nodeTranslation */
  490.         $nodeTranslation $node->getNodeTranslation($this->localetrue);
  491.         $page $nodeVersion->getRef($this->em);
  492.         /* @var HasNodeInterface $clonedPage */
  493.         $clonedPage $this->get('kunstmaan_admin.clone.helper')
  494.             ->deepCloneAndSave($page);
  495.         $newNodeVersion $nodeVersionRepo->createNodeVersionFor(
  496.             $clonedPage,
  497.             $nodeTranslation,
  498.             $this->user,
  499.             $nodeVersion,
  500.             'draft'
  501.         );
  502.         $nodeTranslation->setTitle($clonedPage->getTitle());
  503.         $this->em->persist($nodeTranslation);
  504.         $this->em->flush();
  505.         $this->get('event_dispatcher')->dispatch(
  506.             Events::REVERT,
  507.             new RevertNodeAction(
  508.                 $node,
  509.                 $nodeTranslation,
  510.                 $newNodeVersion,
  511.                 $clonedPage,
  512.                 $nodeVersion,
  513.                 $page
  514.             )
  515.         );
  516.         $this->addFlash(
  517.             FlashTypes::SUCCESS,
  518.             $this->get('translator')->trans('kuma_node.admin.revert.flash.success')
  519.         );
  520.         return $this->redirect(
  521.             $this->generateUrl(
  522.                 'KunstmaanNodeBundle_nodes_edit',
  523.                 array(
  524.                     'id' => $id,
  525.                     'subaction' => 'draft',
  526.                 )
  527.             )
  528.         );
  529.     }
  530.     /**
  531.      * @Route(
  532.      *      "/{id}/add",
  533.      *      requirements={"id" = "\d+"},
  534.      *      name="KunstmaanNodeBundle_nodes_add",
  535.      *      methods={"POST"}
  536.      * )
  537.      *
  538.      * @param Request $request
  539.      * @param int     $id
  540.      *
  541.      * @return RedirectResponse
  542.      *
  543.      * @throws AccessDeniedException
  544.      * @throws InvalidArgumentException
  545.      */
  546.     public function addAction(Request $request$id)
  547.     {
  548.         $this->init($request);
  549.         /* @var Node $parentNode */
  550.         $parentNode $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  551.         // Check with Acl
  552.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$parentNode);
  553.         $parentNodeTranslation $parentNode->getNodeTranslation($this->localetrue);
  554.         $parentNodeVersion $parentNodeTranslation->getPublicNodeVersion();
  555.         $parentPage $parentNodeVersion->getRef($this->em);
  556.         $type $this->validatePageType($request);
  557.         $newPage $this->createNewPage($request$type);
  558.         $newPage->setParent($parentPage);
  559.         /* @var Node $nodeNewPage */
  560.         $nodeNewPage $this->em->getRepository('KunstmaanNodeBundle:Node')
  561.             ->createNodeFor($newPage$this->locale$this->user);
  562.         $nodeTranslation $nodeNewPage->getNodeTranslation(
  563.             $this->locale,
  564.             true
  565.         );
  566.         $weight $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
  567.                 ->getMaxChildrenWeight($parentNode$this->locale) + 1;
  568.         $nodeTranslation->setWeight($weight);
  569.         if ($newPage->isStructureNode()) {
  570.             $nodeTranslation->setSlug('');
  571.         }
  572.         $this->em->persist($nodeTranslation);
  573.         $this->em->flush();
  574.         $this->aclManager->updateNodeAcl($parentNode$nodeNewPage);
  575.         $nodeVersion $nodeTranslation->getPublicNodeVersion();
  576.         $this->get('event_dispatcher')->dispatch(
  577.             Events::ADD_NODE,
  578.             new NodeEvent(
  579.                 $nodeNewPage$nodeTranslation$nodeVersion$newPage
  580.             )
  581.         );
  582.         return $this->redirect(
  583.             $this->generateUrl(
  584.                 'KunstmaanNodeBundle_nodes_edit',
  585.                 array('id' => $nodeNewPage->getId())
  586.             )
  587.         );
  588.     }
  589.     /**
  590.      * @Route("/add-homepage", name="KunstmaanNodeBundle_nodes_add_homepage", methods={"POST"})
  591.      *
  592.      * @return RedirectResponse
  593.      *
  594.      * @throws AccessDeniedException
  595.      * @throws InvalidArgumentException
  596.      */
  597.     public function addHomepageAction(Request $request)
  598.     {
  599.         $this->init($request);
  600.         // Check with Acl
  601.         $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
  602.         $type $this->validatePageType($request);
  603.         $newPage $this->createNewPage($request$type);
  604.         /* @var Node $nodeNewPage */
  605.         $nodeNewPage $this->em->getRepository('KunstmaanNodeBundle:Node')
  606.             ->createNodeFor($newPage$this->locale$this->user);
  607.         $nodeTranslation $nodeNewPage->getNodeTranslation(
  608.             $this->locale,
  609.             true
  610.         );
  611.         $this->em->flush();
  612.         // Set default permissions
  613.         $this->container->get('kunstmaan_node.acl_permission_creator_service')
  614.             ->createPermission($nodeNewPage);
  615.         $nodeVersion $nodeTranslation->getPublicNodeVersion();
  616.         $this->get('event_dispatcher')->dispatch(
  617.             Events::ADD_NODE,
  618.             new NodeEvent(
  619.                 $nodeNewPage$nodeTranslation$nodeVersion$newPage
  620.             )
  621.         );
  622.         return $this->redirect(
  623.             $this->generateUrl(
  624.                 'KunstmaanNodeBundle_nodes_edit',
  625.                 array('id' => $nodeNewPage->getId())
  626.             )
  627.         );
  628.     }
  629.     /**
  630.      * @Route("/reorder", name="KunstmaanNodeBundle_nodes_reorder", methods={"POST"})
  631.      *
  632.      * @param Request $request
  633.      *
  634.      * @return string
  635.      *
  636.      * @throws AccessDeniedException
  637.      */
  638.     public function reorderAction(Request $request)
  639.     {
  640.         $this->init($request);
  641.         $nodes = array();
  642.         $nodeIds $request->get('nodes');
  643.         $changeParents $request->get('parent');
  644.         foreach ($nodeIds as $id) {
  645.             /* @var Node $node */
  646.             $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  647.             $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$node);
  648.             $nodes[] = $node;
  649.         }
  650.         $weight 1;
  651.         foreach ($nodes as $node) {
  652.             $newParentId = isset($changeParents[$node->getId()]) ? $changeParents[$node->getId()] : null;
  653.             if ($newParentId) {
  654.                 $parent $this->em->getRepository('KunstmaanNodeBundle:Node')->find($newParentId);
  655.                 $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$parent);
  656.                 $node->setParent($parent);
  657.                 $this->em->persist($node);
  658.                 $this->em->flush($node);
  659.             }
  660.             /* @var NodeTranslation $nodeTranslation */
  661.             $nodeTranslation $node->getNodeTranslation($this->localetrue);
  662.             if ($nodeTranslation) {
  663.                 $nodeVersion $nodeTranslation->getPublicNodeVersion();
  664.                 $page $nodeVersion->getRef($this->em);
  665.                 $this->get('event_dispatcher')->dispatch(
  666.                     Events::PRE_PERSIST,
  667.                     new NodeEvent($node$nodeTranslation$nodeVersion$page)
  668.                 );
  669.                 $nodeTranslation->setWeight($weight);
  670.                 $this->em->persist($nodeTranslation);
  671.                 $this->em->flush($nodeTranslation);
  672.                 $this->get('event_dispatcher')->dispatch(
  673.                     Events::POST_PERSIST,
  674.                     new NodeEvent($node$nodeTranslation$nodeVersion$page)
  675.                 );
  676.                 ++$weight;
  677.             }
  678.         }
  679.         return new JsonResponse(
  680.             array(
  681.                 'Success' => 'The node-translations for [' $this->locale '] have got new weight values',
  682.             )
  683.         );
  684.     }
  685.     /**
  686.      * @Route(
  687.      *      "/{id}/{subaction}",
  688.      *      requirements={"id" = "\d+"},
  689.      *      defaults={"subaction" = "public"},
  690.      *      name="KunstmaanNodeBundle_nodes_edit",
  691.      *      methods={"GET", "POST"}
  692.      * )
  693.      * @Template("@KunstmaanNode/NodeAdmin/edit.html.twig")
  694.      *
  695.      * @param Request $request
  696.      * @param int     $id        The node id
  697.      * @param string  $subaction The subaction (draft|public)
  698.      *
  699.      * @return RedirectResponse|array
  700.      *
  701.      * @throws AccessDeniedException
  702.      */
  703.     public function editAction(Request $request$id$subaction)
  704.     {
  705.         $this->init($request);
  706.         /* @var Node $node */
  707.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  708.         $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT$node);
  709.         $tabPane = new TabPane(
  710.             'todo',
  711.             $request,
  712.             $this->container->get('form.factory')
  713.         );
  714.         $nodeTranslation $node->getNodeTranslation($this->localetrue);
  715.         if (!$nodeTranslation) {
  716.             return $this->renderNodeNotTranslatedPage($node);
  717.         }
  718.         $nodeVersion $nodeTranslation->getPublicNodeVersion();
  719.         $draftNodeVersion $nodeTranslation->getDraftNodeVersion();
  720.         $nodeVersionIsLocked false;
  721.         /* @var HasNodeInterface $page */
  722.         $page null;
  723.         $draft = ($subaction == 'draft');
  724.         $saveAsDraft $request->get('saveasdraft');
  725.         if ((!$draft && !empty($saveAsDraft)) || ($draft && \is_null($draftNodeVersion))) {
  726.             // Create a new draft version
  727.             $draft true;
  728.             $subaction 'draft';
  729.             $page $nodeVersion->getRef($this->em);
  730.             $nodeVersion $this->createDraftVersion(
  731.                 $page,
  732.                 $nodeTranslation,
  733.                 $nodeVersion
  734.             );
  735.             $draftNodeVersion $nodeVersion;
  736.         } elseif ($draft) {
  737.             $nodeVersion $draftNodeVersion;
  738.             $page $nodeVersion->getRef($this->em);
  739.         } else {
  740.             if ($request->getMethod() == 'POST') {
  741.                 $nodeVersionIsLocked $this->isNodeVersionLocked($nodeTranslationtrue);
  742.                 //Check the version timeout and make a new nodeversion if the timeout is passed
  743.                 $thresholdDate date(
  744.                     'Y-m-d H:i:s',
  745.                     time() - $this->getParameter(
  746.                         'kunstmaan_node.version_timeout'
  747.                     )
  748.                 );
  749.                 $updatedDate date(
  750.                     'Y-m-d H:i:s',
  751.                     strtotime($nodeVersion->getUpdated()->format('Y-m-d H:i:s'))
  752.                 );
  753.                 if ($thresholdDate >= $updatedDate || $nodeVersionIsLocked) {
  754.                     $page $nodeVersion->getRef($this->em);
  755.                     if ($nodeVersion === $nodeTranslation->getPublicNodeVersion()) {
  756.                         $this->nodePublisher
  757.                             ->createPublicVersion(
  758.                                 $page,
  759.                                 $nodeTranslation,
  760.                                 $nodeVersion,
  761.                                 $this->user
  762.                             );
  763.                     } else {
  764.                         $this->createDraftVersion(
  765.                             $page,
  766.                             $nodeTranslation,
  767.                             $nodeVersion
  768.                         );
  769.                     }
  770.                 }
  771.             }
  772.             $page $nodeVersion->getRef($this->em);
  773.         }
  774.         $isStructureNode $page->isStructureNode();
  775.         $menubuilder $this->get('kunstmaan_node.actions_menu_builder');
  776.         $menubuilder->setActiveNodeVersion($nodeVersion);
  777.         $menubuilder->setEditableNode(!$isStructureNode);
  778.         // Building the form
  779.         $propertiesWidget = new FormWidget();
  780.         $propertiesWidget->addType('main'$page->getDefaultAdminType(), $page);
  781.         $propertiesWidget->addType('node'$node->getDefaultAdminType(), $node);
  782.         $tabPane->addTab(new Tab('kuma_node.tab.properties.title'$propertiesWidget));
  783.         // Menu tab
  784.         $menuWidget = new FormWidget();
  785.         $menuWidget->addType(
  786.             'menunodetranslation',
  787.             NodeMenuTabTranslationAdminType::class,
  788.             $nodeTranslation,
  789.             ['slugable' => !$isStructureNode]
  790.         );
  791.         $menuWidget->addType('menunode'NodeMenuTabAdminType::class, $node, ['available_in_nav' => !$isStructureNode]);
  792.         $tabPane->addTab(new Tab('kuma_node.tab.menu.title'$menuWidget));
  793.         $this->get('event_dispatcher')->dispatch(
  794.             Events::ADAPT_FORM,
  795.             new AdaptFormEvent(
  796.                 $request,
  797.                 $tabPane,
  798.                 $page,
  799.                 $node,
  800.                 $nodeTranslation,
  801.                 $nodeVersion
  802.             )
  803.         );
  804.         $tabPane->buildForm();
  805.         if ($request->getMethod() == 'POST') {
  806.             $tabPane->bindRequest($request);
  807.             // Don't redirect to listing when coming from ajax request, needed for url chooser.
  808.             if ($tabPane->isValid() && !$request->isXmlHttpRequest()) {
  809.                 $this->get('event_dispatcher')->dispatch(
  810.                     Events::PRE_PERSIST,
  811.                     new NodeEvent($node$nodeTranslation$nodeVersion$page)
  812.                 );
  813.                 $nodeTranslation->setTitle($page->getTitle());
  814.                 if ($isStructureNode) {
  815.                     $nodeTranslation->setSlug('');
  816.                 }
  817.                 $nodeVersion->setUpdated(new DateTime());
  818.                 if ($nodeVersion->getType() == 'public') {
  819.                     $nodeTranslation->setUpdated($nodeVersion->getUpdated());
  820.                 }
  821.                 $this->em->persist($nodeTranslation);
  822.                 $this->em->persist($nodeVersion);
  823.                 $tabPane->persist($this->em);
  824.                 $this->em->flush();
  825.                 $this->get('event_dispatcher')->dispatch(
  826.                     Events::POST_PERSIST,
  827.                     new NodeEvent($node$nodeTranslation$nodeVersion$page)
  828.                 );
  829.                 if ($nodeVersionIsLocked) {
  830.                     $this->addFlash(
  831.                         FlashTypes::SUCCESS,
  832.                         $this->get('translator')->trans('kuma_node.admin.edit.flash.locked_success')
  833.                     );
  834.                 } elseif ($request->request->has('publishing') || $request->request->has('publish_later')) {
  835.                     $this->nodePublisher->chooseHowToPublish($request$nodeTranslation$this->translator);
  836.                 } elseif ($request->request->has('unpublishing') || $request->request->has('unpublish_later')) {
  837.                     $this->nodePublisher->chooseHowToUnpublish($request$nodeTranslation$this->translator);
  838.                 } else {
  839.                     $this->addFlash(
  840.                         FlashTypes::SUCCESS,
  841.                         $this->get('translator')->trans('kuma_node.admin.edit.flash.success')
  842.                     );
  843.                 }
  844.                 $params = [
  845.                     'id' => $node->getId(),
  846.                     'subaction' => $subaction,
  847.                     'currenttab' => $tabPane->getActiveTab(),
  848.                 ];
  849.                 $params array_merge(
  850.                     $params,
  851.                     $tabPane->getExtraParams($request)
  852.                 );
  853.                 if ($subaction === 'draft' && ($request->request->has('publishing') || $request->request->has('publish_later'))) {
  854.                     unset($params['subaction']);
  855.                 }
  856.                 return $this->redirect(
  857.                     $this->generateUrl(
  858.                         'KunstmaanNodeBundle_nodes_edit',
  859.                         $params
  860.                     )
  861.                 );
  862.             }
  863.         }
  864.         $nodeVersions $this->em->getRepository(
  865.             'KunstmaanNodeBundle:NodeVersion'
  866.         )->findBy(
  867.             ['nodeTranslation' => $nodeTranslation],
  868.             ['updated' => 'ASC']
  869.         );
  870.         $queuedNodeTranslationAction $this->em->getRepository(
  871.             'KunstmaanNodeBundle:QueuedNodeTranslationAction'
  872.         )->findOneBy(['nodeTranslation' => $nodeTranslation]);
  873.         return [
  874.             'page' => $page,
  875.             'entityname' => ClassLookup::getClass($page),
  876.             'nodeVersions' => $nodeVersions,
  877.             'node' => $node,
  878.             'nodeTranslation' => $nodeTranslation,
  879.             'draft' => $draft,
  880.             'draftNodeVersion' => $draftNodeVersion,
  881.             'nodeVersion' => $nodeVersion,
  882.             'subaction' => $subaction,
  883.             'tabPane' => $tabPane,
  884.             'editmode' => true,
  885.             'queuedNodeTranslationAction' => $queuedNodeTranslationAction,
  886.             'nodeVersionLockCheck' => $this->container->getParameter('kunstmaan_node.lock_enabled'),
  887.             'nodeVersionLockInterval' => $this->container->getParameter('kunstmaan_node.lock_check_interval'),
  888.         ];
  889.     }
  890.     /**
  891.      * @Route(
  892.      *      "checkNodeVersionLock/{id}/{public}",
  893.      *      requirements={"id" = "\d+", "public" = "(0|1)"},
  894.      *      name="KunstmaanNodeBundle_nodes_versionlock_check"
  895.      * )
  896.      *
  897.      * @param Request $request
  898.      * @param $id
  899.      *
  900.      * @return JsonResponse
  901.      */
  902.     public function checkNodeVersionLockAction(Request $request$id$public)
  903.     {
  904.         $nodeVersionIsLocked false;
  905.         $message '';
  906.         $this->init($request);
  907.         /* @var Node $node */
  908.         $node $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
  909.         try {
  910.             $this->checkPermission($nodePermissionMap::PERMISSION_EDIT);
  911.             /** @var NodeVersionLockHelper $nodeVersionLockHelper */
  912.             $nodeVersionLockHelper $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
  913.             $nodeTranslation $node->getNodeTranslation($this->localetrue);
  914.             if ($nodeTranslation) {
  915.                 $nodeVersionIsLocked $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation$public);
  916.                 if ($nodeVersionIsLocked) {
  917.                     $users $nodeVersionLockHelper->getUsersWithNodeVersionLock($nodeTranslation$public$this->getUser());
  918.                     $message $this->get('translator')->trans('kuma_node.admin.edit.flash.locked', array('%users%' => implode(', '$users)));
  919.                 }
  920.             }
  921.         } catch (AccessDeniedException $ade) {
  922.         }
  923.         return new JsonResponse(['lock' => $nodeVersionIsLocked'message' => $message]);
  924.     }
  925.     /**
  926.      * @param NodeTranslation $nodeTranslation
  927.      * @param bool            $isPublic
  928.      *
  929.      * @return bool
  930.      */
  931.     private function isNodeVersionLocked(NodeTranslation $nodeTranslation$isPublic)
  932.     {
  933.         if ($this->container->getParameter('kunstmaan_node.lock_enabled')) {
  934.             /** @var NodeVersionLockHelper $nodeVersionLockHelper */
  935.             $nodeVersionLockHelper $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
  936.             $nodeVersionIsLocked $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation$isPublic);
  937.             return $nodeVersionIsLocked;
  938.         }
  939.         return false;
  940.     }
  941.     /**
  942.      * @param HasNodeInterface $page            The page
  943.      * @param NodeTranslation  $nodeTranslation The node translation
  944.      * @param NodeVersion      $nodeVersion     The node version
  945.      *
  946.      * @return NodeVersion
  947.      */
  948.     private function createDraftVersion(
  949.         HasNodeInterface $page,
  950.         NodeTranslation $nodeTranslation,
  951.         NodeVersion $nodeVersion
  952.     ) {
  953.         $publicPage $this->get('kunstmaan_admin.clone.helper')
  954.             ->deepCloneAndSave($page);
  955.         /* @var NodeVersion $publicNodeVersion */
  956.         $publicNodeVersion $this->em->getRepository(
  957.             'KunstmaanNodeBundle:NodeVersion'
  958.         )->createNodeVersionFor(
  959.             $publicPage,
  960.             $nodeTranslation,
  961.             $this->user,
  962.             $nodeVersion->getOrigin(),
  963.             'public',
  964.             $nodeVersion->getCreated()
  965.         );
  966.         $nodeTranslation->setPublicNodeVersion($publicNodeVersion);
  967.         $nodeVersion->setType('draft');
  968.         $nodeVersion->setOrigin($publicNodeVersion);
  969.         $nodeVersion->setCreated(new DateTime());
  970.         $this->em->persist($nodeTranslation);
  971.         $this->em->persist($nodeVersion);
  972.         $this->em->flush();
  973.         $this->get('event_dispatcher')->dispatch(
  974.             Events::CREATE_DRAFT_VERSION,
  975.             new NodeEvent(
  976.                 $nodeTranslation->getNode(),
  977.                 $nodeTranslation,
  978.                 $nodeVersion,
  979.                 $page
  980.             )
  981.         );
  982.         return $nodeVersion;
  983.     }
  984.     /**
  985.      * @param Node   $node       The node
  986.      * @param string $permission The permission to check for
  987.      *
  988.      * @throws AccessDeniedException
  989.      */
  990.     private function checkPermission(Node $node$permission)
  991.     {
  992.         if (false === $this->authorizationChecker->isGranted($permission$node)) {
  993.             throw new AccessDeniedException();
  994.         }
  995.     }
  996.     /**
  997.      * @param EntityManager   $em       The Entity Manager
  998.      * @param BaseUser        $user     The user who deletes the children
  999.      * @param string          $locale   The locale that was used
  1000.      * @param ArrayCollection $children The children array
  1001.      */
  1002.     private function deleteNodeChildren(
  1003.         EntityManager $em,
  1004.         BaseUser $user,
  1005.         $locale,
  1006.         ArrayCollection $children
  1007.     ) {
  1008.         /* @var Node $childNode */
  1009.         foreach ($children as $childNode) {
  1010.             $childNodeTranslation $childNode->getNodeTranslation(
  1011.                 $this->locale,
  1012.                 true
  1013.             );
  1014.             $childNodeVersion $childNodeTranslation->getPublicNodeVersion();
  1015.             $childNodePage $childNodeVersion->getRef($this->em);
  1016.             $this->get('event_dispatcher')->dispatch(
  1017.                 Events::PRE_DELETE,
  1018.                 new NodeEvent(
  1019.                     $childNode,
  1020.                     $childNodeTranslation,
  1021.                     $childNodeVersion,
  1022.                     $childNodePage
  1023.                 )
  1024.             );
  1025.             $childNode->setDeleted(true);
  1026.             $this->em->persist($childNode);
  1027.             $children2 $childNode->getChildren();
  1028.             $this->deleteNodeChildren($em$user$locale$children2);
  1029.             $this->get('event_dispatcher')->dispatch(
  1030.                 Events::POST_DELETE,
  1031.                 new NodeEvent(
  1032.                     $childNode,
  1033.                     $childNodeTranslation,
  1034.                     $childNodeVersion,
  1035.                     $childNodePage
  1036.                 )
  1037.             );
  1038.         }
  1039.     }
  1040.     /**
  1041.      * @param Request $request
  1042.      * @param string  $type
  1043.      *
  1044.      * @return HasNodeInterface
  1045.      */
  1046.     private function createNewPage(Request $request$type)
  1047.     {
  1048.         /* @var HasNodeInterface $newPage */
  1049.         $newPage = new $type();
  1050.         $title $request->get('title');
  1051.         if (\is_string($title) && !empty($title)) {
  1052.             $newPage->setTitle($title);
  1053.         } else {
  1054.             $newPage->setTitle($this->get('translator')->trans('kuma_node.admin.new_page.title.default'));
  1055.         }
  1056.         $this->em->persist($newPage);
  1057.         $this->em->flush();
  1058.         return $newPage;
  1059.     }
  1060.     /**
  1061.      * @param Request $request
  1062.      *
  1063.      * @return string
  1064.      * @throw InvalidArgumentException
  1065.      */
  1066.     private function validatePageType($request)
  1067.     {
  1068.         $type $request->get('type');
  1069.         if (empty($type)) {
  1070.             throw new InvalidArgumentException('Please specify a type of page you want to create');
  1071.         }
  1072.         return $type;
  1073.     }
  1074.     /**
  1075.      * @param Node $node
  1076.      *
  1077.      * @return \Symfony\Component\HttpFoundation\Response
  1078.      */
  1079.     private function renderNodeNotTranslatedPage(Node $node)
  1080.     {
  1081.         //try to find a parent node with the correct translation, if there is none allow copy.
  1082.         //if there is a parent but it doesn't have the language to copy to don't allow it
  1083.         $parentNode $node->getParent();
  1084.         if ($parentNode) {
  1085.             $parentNodeTranslation $parentNode->getNodeTranslation(
  1086.                 $this->locale,
  1087.                 true
  1088.             );
  1089.             $parentsAreOk false;
  1090.             if ($parentNodeTranslation) {
  1091.                 $parentsAreOk $this->em->getRepository(
  1092.                     'KunstmaanNodeBundle:NodeTranslation'
  1093.                 )->hasParentNodeTranslationsForLanguage(
  1094.                     $node->getParent()->getNodeTranslation(
  1095.                         $this->locale,
  1096.                         true
  1097.                     ),
  1098.                     $this->locale
  1099.                 );
  1100.             }
  1101.         } else {
  1102.             $parentsAreOk true;
  1103.         }
  1104.         return $this->render(
  1105.             '@KunstmaanNode/NodeAdmin/pagenottranslated.html.twig',
  1106.             array(
  1107.                 'node' => $node,
  1108.                 'nodeTranslations' => $node->getNodeTranslations(
  1109.                     true
  1110.                 ),
  1111.                 'copyfromotherlanguages' => $parentsAreOk,
  1112.             )
  1113.         );
  1114.     }
  1115. }