Completed
Pull Request — master (#2686)
by Jeroen
06:10
created

NodeAdminController::editAction()   F

Complexity

Conditions 24
Paths 205

Size

Total Lines 213

Duplication

Lines 18
Ratio 8.45 %

Code Coverage

Tests 0
CRAP Score 600

Importance

Changes 0
Metric Value
dl 18
loc 213
ccs 0
cts 184
cp 0
rs 2.6166
c 0
b 0
f 0
cc 24
nc 205
nop 3
crap 600

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Kunstmaan\NodeBundle\Controller;
4
5
use DateTime;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use Doctrine\ORM\EntityManager;
8
use InvalidArgumentException;
9
use Kunstmaan\AdminBundle\Entity\BaseUser;
10
use Kunstmaan\AdminBundle\Entity\EntityInterface;
11
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
12
use Kunstmaan\AdminBundle\Helper\FormWidgets\FormWidget;
13
use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\Tab;
14
use Kunstmaan\AdminBundle\Helper\FormWidgets\Tabs\TabPane;
15
use Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper;
16
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMap;
17
use Kunstmaan\AdminBundle\Service\AclManager;
18
use Kunstmaan\AdminListBundle\AdminList\AdminList;
19
use Kunstmaan\NodeBundle\AdminList\NodeAdminListConfigurator;
20
use Kunstmaan\NodeBundle\Entity\HasNodeInterface;
21
use Kunstmaan\NodeBundle\Entity\Node;
22
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
23
use Kunstmaan\NodeBundle\Entity\NodeVersion;
24
use Kunstmaan\NodeBundle\Event\AdaptFormEvent;
25
use Kunstmaan\NodeBundle\Event\CopyPageTranslationNodeEvent;
26
use Kunstmaan\NodeBundle\Event\Events;
27
use Kunstmaan\NodeBundle\Event\NodeEvent;
28
use Kunstmaan\NodeBundle\Event\RecopyPageTranslationNodeEvent;
29
use Kunstmaan\NodeBundle\Event\RevertNodeAction;
30
use Kunstmaan\NodeBundle\Form\NodeMenuTabAdminType;
31
use Kunstmaan\NodeBundle\Form\NodeMenuTabTranslationAdminType;
32
use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeAdminPublisher;
33
use Kunstmaan\NodeBundle\Helper\NodeAdmin\NodeVersionLockHelper;
34
use Kunstmaan\NodeBundle\Helper\PageCloningHelper;
35
use Kunstmaan\NodeBundle\Repository\NodeVersionRepository;
36
use Kunstmaan\UtilitiesBundle\Helper\ClassLookup;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
38
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
39
use Symfony\Component\HttpFoundation\JsonResponse;
40
use Symfony\Component\HttpFoundation\RedirectResponse;
41
use Symfony\Component\HttpFoundation\Request;
42
use Symfony\Component\Routing\Annotation\Route;
43
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
44
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
45
use Symfony\Component\Translation\TranslatorInterface;
46
47
/**
48
 * NodeAdminController
49
 */
50
class NodeAdminController extends Controller
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Bundle\Framework...e\Controller\Controller has been deprecated with message: since Symfony 4.2, use "Symfony\Bundle\FrameworkBundle\Controller\AbstractController" instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
51
{
52
    /**
53
     * @var EntityManager
54
     */
55
    protected $em;
56
57
    /**
58
     * @var string
59
     */
60
    protected $locale;
61
62
    /**
63
     * @var AuthorizationCheckerInterface
64
     */
65
    protected $authorizationChecker;
66
67
    /**
68
     * @var BaseUser
69
     */
70
    protected $user;
71
72
    /**
73
     * @var AclHelper
74
     */
75
    protected $aclHelper;
76
77
    /**
78
     * @var AclManager
79
     */
80
    protected $aclManager;
81
82
    /**
83
     * @var NodeAdminPublisher
84
     */
85
    protected $nodePublisher;
86
87
    /**
88
     * @var TranslatorInterface
89
     */
90
    protected $translator;
91
92
    /** @var PageCloningHelper */
93
    private $pageCloningHelper;
94
95
    /**
96
     * init
97
     *
98
     * @param Request $request
99
     */
100
    protected function init(Request $request)
101
    {
102
        $this->em = $this->getDoctrine()->getManager();
103
        $this->locale = $request->getLocale();
104
        $this->authorizationChecker = $this->container->get('security.authorization_checker');
105
        $this->user = $this->getUser();
106
        $this->aclHelper = $this->container->get('kunstmaan_admin.acl.helper');
107
        $this->aclManager = $this->container->get('kunstmaan_admin.acl.manager');
108
        $this->nodePublisher = $this->container->get('kunstmaan_node.admin_node.publisher');
109
        $this->translator = $this->container->get('translator');
110
        $this->pageCloningHelper = $this->container->get(PageCloningHelper::class);
111
    }
112
113
    /**
114
     * @Route("/", name="KunstmaanNodeBundle_nodes")
115
     * @Template("@KunstmaanNode/Admin/list.html.twig")
116
     *
117
     * @param Request $request
118
     *
119
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,AdminList>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
120
     */
121
    public function indexAction(Request $request)
122
    {
123
        $this->init($request);
124
125
        $nodeAdminListConfigurator = new NodeAdminListConfigurator(
126
            $this->em,
127
            $this->aclHelper,
128
            $this->locale,
129
            PermissionMap::PERMISSION_VIEW,
130
            $this->authorizationChecker
131
        );
132
133
        $locale = $this->locale;
134
        $acl = $this->authorizationChecker;
135
        $itemRoute = function (EntityInterface $item) use ($locale, $acl) {
136
            if ($acl->isGranted(PermissionMap::PERMISSION_VIEW, $item->getNode())) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Kunstmaan\AdminBundle\Entity\EntityInterface as the method getNode() does only exist in the following implementations of said interface: Kunstmaan\FormBundle\Entity\FormSubmission, Kunstmaan\FormBundle\Tes...List\FakeFormSubmission, Kunstmaan\NodeBundle\Entity\NodeTranslation, Kunstmaan\NodeSearchBundle\Entity\NodeSearch.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
137
                return array(
138
                    'path' => '_slug_preview',
139
                    'params' => ['_locale' => $locale, 'url' => $item->getUrl()],
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Kunstmaan\AdminBundle\Entity\EntityInterface as the method getUrl() does only exist in the following implementations of said interface: Kunstmaan\AdminBundle\Entity\Exception, Kunstmaan\MediaBundle\Entity\Media, Kunstmaan\MenuBundle\Entity\BaseMenuItem, Kunstmaan\MenuBundle\Entity\MenuItem, Kunstmaan\NodeBundle\Entity\NodeTranslation, Kunstmaan\PagePartBundle\Entity\LinkPagePart.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
140
                );
141
            }
142
        };
143
        $nodeAdminListConfigurator->addSimpleItemAction('action.preview', $itemRoute, 'eye');
144
        $nodeAdminListConfigurator->setDomainConfiguration($this->get('kunstmaan_admin.domain_configuration'));
145
        $nodeAdminListConfigurator->setShowAddHomepage($this->getParameter('kunstmaan_node.show_add_homepage') && $this->isGranted('ROLE_SUPER_ADMIN'));
146
147
        /** @var AdminList $adminlist */
148
        $adminlist = $this->get('kunstmaan_adminlist.factory')->createList($nodeAdminListConfigurator);
149
        $adminlist->bindRequest($request);
150
151
        return array(
152
            'adminlist' => $adminlist,
153
        );
154
    }
155
156
    /**
157
     * @Route(
158
     *      "/{id}/copyfromotherlanguage",
159
     *      requirements={"id" = "\d+"},
160
     *      name="KunstmaanNodeBundle_nodes_copyfromotherlanguage",
161
     *      methods={"GET"}
162
     * )
163
     *
164
     * @param Request $request
165
     * @param int     $id      The node id
166
     *
167
     * @return RedirectResponse
168
     *
169
     * @throws AccessDeniedException
170
     */
171
    public function copyFromOtherLanguageAction(Request $request, $id)
172
    {
173
        $this->init($request);
174
        /* @var Node $node */
175
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
176
177
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
178
179
        $originalLanguage = $request->get('originallanguage');
180
        $otherLanguageNodeTranslation = $node->getNodeTranslation($originalLanguage, true);
181
        $otherLanguageNodeNodeVersion = $otherLanguageNodeTranslation->getPublicNodeVersion();
182
        $otherLanguagePage = $otherLanguageNodeNodeVersion->getRef($this->em);
183
        $myLanguagePage = $this->get('kunstmaan_admin.clone.helper')
184
            ->deepCloneAndSave($otherLanguagePage);
185
186
        /* @var NodeTranslation $nodeTranslation */
187
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
188
            ->createNodeTranslationFor($myLanguagePage, $this->locale, $node, $this->user);
189
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
190
191
        $this->get('event_dispatcher')->dispatch(
192
            Events::COPY_PAGE_TRANSLATION,
193
            new CopyPageTranslationNodeEvent(
194
                $node,
195
                $nodeTranslation,
196
                $nodeVersion,
197
                $myLanguagePage,
198
                $otherLanguageNodeTranslation,
0 ignored issues
show
Bug introduced by
It seems like $otherLanguageNodeTranslation defined by $node->getNodeTranslatio...originalLanguage, true) on line 180 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...
199
                $otherLanguageNodeNodeVersion,
200
                $otherLanguagePage,
201
                $originalLanguage
202
            )
203
        );
204
205
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
206
    }
207
208
    /**
209
     * @Route(
210
     *      "/{id}/recopyfromotherlanguage",
211
     *      requirements={"id" = "\d+"},
212
     *      name="KunstmaanNodeBundle_nodes_recopyfromotherlanguage",
213
     *      methods={"POST"}
214
     * )
215
     *
216
     * @param Request $request
217
     * @param int     $id      The node id
218
     *
219
     * @return RedirectResponse
220
     *
221
     * @throws AccessDeniedException
222
     */
223
    public function recopyFromOtherLanguageAction(Request $request, $id)
224
    {
225
        $this->init($request);
226
        /* @var Node $node */
227
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
228
229
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
230
231
        $otherLanguageNodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')->find($request->get('source'));
232
        $otherLanguageNodeNodeVersion = $otherLanguageNodeTranslation->getPublicNodeVersion();
233
        $otherLanguagePage = $otherLanguageNodeNodeVersion->getRef($this->em);
234
        $myLanguagePage = $this->get('kunstmaan_admin.clone.helper')
235
            ->deepCloneAndSave($otherLanguagePage);
236
237
        /* @var NodeTranslation $nodeTranslation */
238
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
239
            ->addDraftNodeVersionFor($myLanguagePage, $this->locale, $node, $this->user);
240
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
241
242
        $this->get('event_dispatcher')->dispatch(
243
            Events::RECOPY_PAGE_TRANSLATION,
244
            new RecopyPageTranslationNodeEvent(
245
                $node,
246
                $nodeTranslation,
247
                $nodeVersion,
248
                $myLanguagePage,
249
                $otherLanguageNodeTranslation,
0 ignored issues
show
Documentation introduced by
$otherLanguageNodeTranslation is of type object|null, but the function expects a object<Kunstmaan\NodeBun...Entity\NodeTranslation>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
250
                $otherLanguageNodeNodeVersion,
251
                $otherLanguagePage,
252
                $otherLanguageNodeTranslation->getLang()
253
            )
254
        );
255
256
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id, 'subaction' => NodeVersion::DRAFT_VERSION)));
257
    }
258
259
    /**
260
     * @Route(
261
     *      "/{id}/createemptypage",
262
     *      requirements={"id" = "\d+"},
263
     *      name="KunstmaanNodeBundle_nodes_createemptypage",
264
     *      methods={"GET"}
265
     * )
266
     *
267
     * @param Request $request
268
     * @param int     $id
269
     *
270
     * @return RedirectResponse
271
     *
272
     * @throws AccessDeniedException
273
     */
274
    public function createEmptyPageAction(Request $request, $id)
275
    {
276
        $this->init($request);
277
        /* @var Node $node */
278
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
279
280
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
281
282
        $entityName = $node->getRefEntityName();
283
        /* @var HasNodeInterface $myLanguagePage */
284
        $myLanguagePage = new $entityName();
285
        $myLanguagePage->setTitle('New page');
286
287
        $this->em->persist($myLanguagePage);
288
        $this->em->flush();
289
        /* @var NodeTranslation $nodeTranslation */
290
        $nodeTranslation = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
291
            ->createNodeTranslationFor($myLanguagePage, $this->locale, $node, $this->user);
292
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
293
294
        $this->get('event_dispatcher')->dispatch(
295
            Events::ADD_EMPTY_PAGE_TRANSLATION,
296
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $myLanguagePage)
297
        );
298
299
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
300
    }
301
302
    /**
303
     * @Route("/{id}/publish", requirements={"id" =
304
     *                         "\d+"},
305
     *                         name="KunstmaanNodeBundle_nodes_publish", methods={"GET", "POST"})
306
     *
307
     * @param Request $request
308
     * @param int     $id
309
     *
310
     * @return RedirectResponse
311
     *
312
     * @throws AccessDeniedException
313
     */
314 View Code Duplication
    public function publishAction(Request $request, $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
315
    {
316
        $this->init($request);
317
        /* @var Node $node */
318
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
319
320
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
321
        $request = $this->get('request_stack')->getCurrentRequest();
322
        $this->nodePublisher->chooseHowToPublish($request, $nodeTranslation, $this->translator);
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $node->getNodeTranslation($this->locale, true) on line 320 can be null; however, Kunstmaan\NodeBundle\Hel...r::chooseHowToPublish() 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...
323
324
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
325
    }
326
327
    /**
328
     * @Route(
329
     *      "/{id}/unpublish",
330
     *      requirements={"id" = "\d+"},
331
     *      name="KunstmaanNodeBundle_nodes_unpublish",
332
     *      methods={"GET", "POST"}
333
     * )
334
     *
335
     * @param Request $request
336
     * @param int     $id
337
     *
338
     * @return RedirectResponse
339
     *
340
     * @throws AccessDeniedException
341
     */
342 View Code Duplication
    public function unPublishAction(Request $request, $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
343
    {
344
        $this->init($request);
345
        /* @var Node $node */
346
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
347
348
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
349
        $request = $this->get('request_stack')->getCurrentRequest();
350
        $this->nodePublisher->chooseHowToUnpublish($request, $nodeTranslation, $this->translator);
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $node->getNodeTranslation($this->locale, true) on line 348 can be null; however, Kunstmaan\NodeBundle\Hel...:chooseHowToUnpublish() 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...
351
352
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $node->getId())));
353
    }
354
355
    /**
356
     * @Route(
357
     *      "/{id}/unschedulepublish",
358
     *      requirements={"id" = "\d+"},
359
     *      name="KunstmaanNodeBundle_nodes_unschedule_publish",
360
     *      methods={"GET", "POST"}
361
     * )
362
     *
363
     * @param Request $request
364
     * @param int     $id
365
     *
366
     * @return RedirectResponse
367
     *
368
     * @throws AccessDeniedException
369
     */
370 View Code Duplication
    public function unSchedulePublishAction(Request $request, $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
371
    {
372
        $this->init($request);
373
374
        /* @var Node $node */
375
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
376
377
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
378
        $this->nodePublisher->unSchedulePublish($nodeTranslation);
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $node->getNodeTranslation($this->locale, true) on line 377 can be null; however, Kunstmaan\NodeBundle\Hel...er::unSchedulePublish() 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...
379
380
        $this->addFlash(
381
            FlashTypes::SUCCESS,
382
            $this->get('translator')->trans('kuma_node.admin.unschedule.flash.success')
383
        );
384
385
        return $this->redirect($this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $id)));
386
    }
387
388
    /**
389
     * @Route(
390
     *      "/{id}/delete",
391
     *      requirements={"id" = "\d+"},
392
     *      name="KunstmaanNodeBundle_nodes_delete",
393
     *      methods={"POST"}
394
     * )
395
     *
396
     * @param Request $request
397
     * @param int     $id
398
     *
399
     * @return RedirectResponse
400
     *
401
     * @throws AccessDeniedException
402
     */
403
    public function deleteAction(Request $request, $id)
404
    {
405
        $this->init($request);
406
        /* @var Node $node */
407
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
408
409
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_DELETE, $node);
410
411
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
412
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
413
        $page = $nodeVersion->getRef($this->em);
414
415
        $this->get('event_dispatcher')->dispatch(
416
            Events::PRE_DELETE,
417
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $node->getNodeTranslation($this->locale, true) on line 411 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...
418
        );
419
420
        $node->setDeleted(true);
421
        $this->em->persist($node);
422
423
        $children = $node->getChildren();
424
        $this->deleteNodeChildren($this->em, $this->user, $this->locale, $children);
425
        $this->em->flush();
426
427
        $event = new NodeEvent($node, $nodeTranslation, $nodeVersion, $page);
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $node->getNodeTranslation($this->locale, true) on line 411 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...
428
        $this->get('event_dispatcher')->dispatch(Events::POST_DELETE, $event);
429
        if (null === $response = $event->getResponse()) {
430
            $nodeParent = $node->getParent();
431
            // Check if we have a parent. Otherwise redirect to pages overview.
432
            if ($nodeParent) {
433
                $url = $this->get('router')->generate(
434
                    'KunstmaanNodeBundle_nodes_edit',
435
                    array('id' => $nodeParent->getId())
436
                );
437
            } else {
438
                $url = $this->get('router')->generate(
439
                    'KunstmaanNodeBundle_nodes'
440
                );
441
            }
442
            $response = new RedirectResponse($url);
443
        }
444
445
        $this->addFlash(
446
            FlashTypes::SUCCESS,
447
            $this->get('translator')->trans('kuma_node.admin.delete.flash.success')
448
        );
449
450
        return $response;
451
    }
452
453
    /**
454
     * @Route(
455
     *      "/{id}/duplicate",
456
     *      requirements={"id" = "\d+"},
457
     *      name="KunstmaanNodeBundle_nodes_duplicate",
458
     *      methods={"POST"}
459
     * )
460
     *
461
     * @param Request $request
462
     * @param int     $id
463
     *
464
     * @return RedirectResponse
465
     *
466
     * @throws AccessDeniedException
467
     */
468
    public function duplicateAction(Request $request, $id)
469
    {
470
        $this->init($request);
471
        /* @var Node $parentNode */
472
        $originalNode = $this->em->getRepository('KunstmaanNodeBundle:Node')
473
            ->find($id);
474
475
        // Check with Acl
476
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $originalNode);
477
478
        $request = $this->get('request_stack')->getCurrentRequest();
479
480
        $originalNodeTranslations = $originalNode->getNodeTranslation($this->locale, true);
481
        $originalRef = $originalNodeTranslations->getPublicNodeVersion()->getRef($this->em);
482
        $newPage = $this->get('kunstmaan_admin.clone.helper')
483
            ->deepCloneAndSave($originalRef);
484
485
        //set the title
486
        $title = $request->get('title');
487
        if (\is_string($title) && !empty($title)) {
488
            $newPage->setTitle($title);
489
        } else {
490
            $newPage->setTitle('New page');
491
        }
492
493
        //set the parent
494
        $parentNodeTranslation = $originalNode->getParent()->getNodeTranslation($this->locale, true);
495
        $parent = $parentNodeTranslation->getPublicNodeVersion()->getRef($this->em);
496
        $newPage->setParent($parent);
497
        $this->em->persist($newPage);
498
        $this->em->flush();
499
500
        /* @var Node $nodeNewPage */
501
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')->createNodeFor(
502
            $newPage,
503
            $this->locale,
504
            $this->user
505
        );
506
507
        $nodeTranslation = $nodeNewPage->getNodeTranslation($this->locale, true);
508
        if ($newPage->isStructureNode()) {
509
            $nodeTranslation->setSlug('');
510
            $this->em->persist($nodeTranslation);
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $nodeNewPage->getNodeTra...on($this->locale, true) on line 507 can be null; however, Doctrine\ORM\EntityManager::persist() 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...
511
        }
512
        $this->em->flush();
513
514
        $this->aclManager->updateNodeAcl($originalNode, $nodeNewPage);
0 ignored issues
show
Documentation introduced by
$originalNode is of type object|null, but the function expects a object<Kunstmaan\NodeBundle\Entity\Node>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
515
516
        $this->addFlash(
517
            FlashTypes::SUCCESS,
518
            $this->get('translator')->trans('kuma_node.admin.duplicate.flash.success')
519
        );
520
521
        return $this->redirect(
522
            $this->generateUrl('KunstmaanNodeBundle_nodes_edit', array('id' => $nodeNewPage->getId()))
523
        );
524
    }
525
526
527
    /**
528
     * @Route(
529
     *      "/{id}/duplicate-with-children",
530
     *      requirements={"id" = "\d+"},
531
     *      name="KunstmaanNodeBundle_nodes_duplicate_with_children",
532
     *      methods={"POST"}
533
     * )
534
     *
535
     * @throws AccessDeniedException
536
     */
537
    public function duplicateWithChildrenAction(Request $request, $id)
538
    {
539
        if (!$this->getParameter('kunstmaan_node.show_duplicate_with_children')) {
540
            return $this->redirect(
541
                $this->generateUrl('KunstmaanNodeBundle_nodes_edit', ['id' => $id])
542
            );
543
        }
544
545
        $this->init($request);
546
        $title = $request->get('title', null);
547
548
        $nodeNewPage = $this->pageCloningHelper->duplicateWithChildren($id, $this->locale, $this->user, $title);
549
550
        $this->addFlash(
551
            FlashTypes::SUCCESS,
552
            $this->get('translator')->trans('kuma_node.admin.duplicate.flash.success')
553
        );
554
555
        return $this->redirect(
556
            $this->generateUrl('KunstmaanNodeBundle_nodes_edit', ['id' => $nodeNewPage->getId()])
557
        );
558
    }
559
560
    /**
561
     * @Route(
562
     *      "/{id}/revert",
563
     *      requirements={"id" = "\d+"},
564
     *      defaults={"subaction" = "public"},
565
     *      name="KunstmaanNodeBundle_nodes_revert",
566
     *      methods={"GET"}
567
     * )
568
     *
569
     * @param Request $request
570
     * @param int     $id      The node id
571
     *
572
     * @return RedirectResponse
573
     *
574
     * @throws AccessDeniedException
575
     * @throws InvalidArgumentException
576
     */
577
    public function revertAction(Request $request, $id)
578
    {
579
        $this->init($request);
580
        /* @var Node $node */
581
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
582
583
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
584
585
        $version = $request->get('version');
586
587
        if (empty($version) || !is_numeric($version)) {
588
            throw new InvalidArgumentException('No version was specified');
589
        }
590
591
        /* @var NodeVersionRepository $nodeVersionRepo */
592
        $nodeVersionRepo = $this->em->getRepository('KunstmaanNodeBundle:NodeVersion');
593
        /* @var NodeVersion $nodeVersion */
594
        $nodeVersion = $nodeVersionRepo->find($version);
595
596
        if (\is_null($nodeVersion)) {
597
            throw new InvalidArgumentException('Version does not exist');
598
        }
599
600
        /* @var NodeTranslation $nodeTranslation */
601
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
602
        $page = $nodeVersion->getRef($this->em);
603
        /* @var HasNodeInterface $clonedPage */
604
        $clonedPage = $this->get('kunstmaan_admin.clone.helper')
605
            ->deepCloneAndSave($page);
606
        $newNodeVersion = $nodeVersionRepo->createNodeVersionFor(
607
            $clonedPage,
608
            $nodeTranslation,
609
            $this->user,
610
            $nodeVersion,
611
            'draft'
612
        );
613
614
        $nodeTranslation->setTitle($clonedPage->getTitle());
615
        $this->em->persist($nodeTranslation);
616
        $this->em->flush();
617
618
        $this->get('event_dispatcher')->dispatch(
619
            Events::REVERT,
620
            new RevertNodeAction(
621
                $node,
622
                $nodeTranslation,
623
                $newNodeVersion,
624
                $clonedPage,
625
                $nodeVersion,
626
                $page
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 602 can be null; however, Kunstmaan\NodeBundle\Eve...deAction::__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...
627
            )
628
        );
629
630
        $this->addFlash(
631
            FlashTypes::SUCCESS,
632
            $this->get('translator')->trans('kuma_node.admin.revert.flash.success')
633
        );
634
635
        return $this->redirect(
636
            $this->generateUrl(
637
                'KunstmaanNodeBundle_nodes_edit',
638
                array(
639
                    'id' => $id,
640
                    'subaction' => 'draft',
641
                )
642
            )
643
        );
644
    }
645
646
    /**
647
     * @Route(
648
     *      "/{id}/add",
649
     *      requirements={"id" = "\d+"},
650
     *      name="KunstmaanNodeBundle_nodes_add",
651
     *      methods={"POST"}
652
     * )
653
     *
654
     * @param Request $request
655
     * @param int     $id
656
     *
657
     * @return RedirectResponse
658
     *
659
     * @throws AccessDeniedException
660
     * @throws InvalidArgumentException
661
     */
662
    public function addAction(Request $request, $id)
663
    {
664
        $this->init($request);
665
        /* @var Node $parentNode */
666
        $parentNode = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
667
668
        // Check with Acl
669
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parentNode);
670
671
        $parentNodeTranslation = $parentNode->getNodeTranslation($this->locale, true);
672
        $parentNodeVersion = $parentNodeTranslation->getPublicNodeVersion();
673
        $parentPage = $parentNodeVersion->getRef($this->em);
674
675
        $type = $this->validatePageType($request);
676
        $newPage = $this->createNewPage($request, $type);
677
        $newPage->setParent($parentPage);
678
679
        /* @var Node $nodeNewPage */
680
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')
681
            ->createNodeFor($newPage, $this->locale, $this->user);
682
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
683
            $this->locale,
684
            true
685
        );
686
        $weight = $this->em->getRepository('KunstmaanNodeBundle:NodeTranslation')
687
                ->getMaxChildrenWeight($parentNode, $this->locale) + 1;
688
        $nodeTranslation->setWeight($weight);
689
690
        if ($newPage->isStructureNode()) {
691
            $nodeTranslation->setSlug('');
692
        }
693
694
        $this->em->persist($nodeTranslation);
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $nodeNewPage->getNodeTra...on($this->locale, true) on line 682 can be null; however, Doctrine\ORM\EntityManager::persist() 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...
695
        $this->em->flush();
696
697
        $this->aclManager->updateNodeAcl($parentNode, $nodeNewPage);
698
699
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
700
701
        $this->get('event_dispatcher')->dispatch(
702
            Events::ADD_NODE,
703
            new NodeEvent(
704
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $nodeNewPage->getNodeTra...on($this->locale, true) on line 682 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...
705
            )
706
        );
707
708
        return $this->redirect(
709
            $this->generateUrl(
710
                'KunstmaanNodeBundle_nodes_edit',
711
                array('id' => $nodeNewPage->getId())
712
            )
713
        );
714
    }
715
716
    /**
717
     * @Route("/add-homepage", name="KunstmaanNodeBundle_nodes_add_homepage", methods={"POST"})
718
     *
719
     * @return RedirectResponse
720
     *
721
     * @throws AccessDeniedException
722
     * @throws InvalidArgumentException
723
     */
724
    public function addHomepageAction(Request $request)
725
    {
726
        $this->init($request);
727
728
        // Check with Acl
729
        $this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
730
731
        $type = $this->validatePageType($request);
732
733
        $newPage = $this->createNewPage($request, $type);
734
735
        /* @var Node $nodeNewPage */
736
        $nodeNewPage = $this->em->getRepository('KunstmaanNodeBundle:Node')
737
            ->createNodeFor($newPage, $this->locale, $this->user);
738
        $nodeTranslation = $nodeNewPage->getNodeTranslation(
739
            $this->locale,
740
            true
741
        );
742
        $this->em->flush();
743
744
        // Set default permissions
745
        $this->container->get('kunstmaan_node.acl_permission_creator_service')
746
            ->createPermission($nodeNewPage);
747
748
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
749
750
        $this->get('event_dispatcher')->dispatch(
751
            Events::ADD_NODE,
752
            new NodeEvent(
753
                $nodeNewPage, $nodeTranslation, $nodeVersion, $newPage
0 ignored issues
show
Bug introduced by
It seems like $nodeTranslation defined by $nodeNewPage->getNodeTra...on($this->locale, true) on line 738 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...
754
            )
755
        );
756
757
        return $this->redirect(
758
            $this->generateUrl(
759
                'KunstmaanNodeBundle_nodes_edit',
760
                array('id' => $nodeNewPage->getId())
761
            )
762
        );
763
    }
764
765
    /**
766
     * @Route("/reorder", name="KunstmaanNodeBundle_nodes_reorder", methods={"POST"})
767
     *
768
     * @param Request $request
769
     *
770
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be JsonResponse?

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

Loading history...
771
     *
772
     * @throws AccessDeniedException
773
     */
774
    public function reorderAction(Request $request)
775
    {
776
        $this->init($request);
777
        $nodes = array();
778
        $nodeIds = $request->get('nodes');
779
        $changeParents = $request->get('parent');
780
781
        foreach ($nodeIds as $id) {
782
            /* @var Node $node */
783
            $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
784
            $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
785
            $nodes[] = $node;
786
        }
787
788
        $weight = 1;
789
        foreach ($nodes as $node) {
790
            $newParentId = isset($changeParents[$node->getId()]) ? $changeParents[$node->getId()] : null;
791
            if ($newParentId) {
792
                $parent = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($newParentId);
793
                $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $parent);
794
                $node->setParent($parent);
795
                $this->em->persist($node);
796
                $this->em->flush($node);
797
            }
798
799
            /* @var NodeTranslation $nodeTranslation */
800
            $nodeTranslation = $node->getNodeTranslation($this->locale, true);
801
802
            if ($nodeTranslation) {
803
                $nodeVersion = $nodeTranslation->getPublicNodeVersion();
804
                $page = $nodeVersion->getRef($this->em);
805
806
                $this->get('event_dispatcher')->dispatch(
807
                    Events::PRE_PERSIST,
808
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 804 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...
809
                );
810
811
                $nodeTranslation->setWeight($weight);
812
                $this->em->persist($nodeTranslation);
813
                $this->em->flush($nodeTranslation);
814
815
                $this->get('event_dispatcher')->dispatch(
816
                    Events::POST_PERSIST,
817
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 804 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...
818
                );
819
820
                ++$weight;
821
            }
822
        }
823
824
        return new JsonResponse(
825
            array(
826
                'Success' => 'The node-translations for [' . $this->locale . '] have got new weight values',
827
            )
828
        );
829
    }
830
831
    /**
832
     * @Route(
833
     *      "/{id}/{subaction}",
834
     *      requirements={"id" = "\d+"},
835
     *      defaults={"subaction" = "public"},
836
     *      name="KunstmaanNodeBundle_nodes_edit",
837
     *      methods={"GET", "POST"}
838
     * )
839
     * @Template("@KunstmaanNode/NodeAdmin/edit.html.twig")
840
     *
841
     * @param Request $request
842
     * @param int     $id        The node id
843
     * @param string  $subaction The subaction (draft|public)
844
     *
845
     * @return RedirectResponse|array
0 ignored issues
show
Documentation introduced by
Should the return type not be \Symfony\Component\HttpFoundation\Response|array?

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

Loading history...
846
     *
847
     * @throws AccessDeniedException
848
     */
849
    public function editAction(Request $request, $id, $subaction)
850
    {
851
        $this->init($request);
852
        /* @var Node $node */
853
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
854
855
        $this->denyAccessUnlessGranted(PermissionMap::PERMISSION_EDIT, $node);
856
857
        $tabPane = new TabPane(
858
            'todo',
859
            $request,
860
            $this->container->get('form.factory')
0 ignored issues
show
Documentation introduced by
$this->container->get('form.factory') is of type object|null, but the function expects a object<Symfony\Component...m\FormFactoryInterface>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
861
        );
862
863
        $nodeTranslation = $node->getNodeTranslation($this->locale, true);
864
        if (!$nodeTranslation) {
865
            return $this->renderNodeNotTranslatedPage($node);
866
        }
867
868
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
869
        $draftNodeVersion = $nodeTranslation->getDraftNodeVersion();
870
        $nodeVersionIsLocked = false;
871
872
        /* @var HasNodeInterface $page */
873
        $page = null;
0 ignored issues
show
Unused Code introduced by
$page is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
874
        $draft = ($subaction == 'draft');
875
        $saveAsDraft = $request->get('saveasdraft');
876
        if ((!$draft && !empty($saveAsDraft)) || ($draft && \is_null($draftNodeVersion))) {
877
            // Create a new draft version
878
            $draft = true;
879
            $subaction = 'draft';
880
            $page = $nodeVersion->getRef($this->em);
881
            $nodeVersion = $this->createDraftVersion(
882
                $page,
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 880 can be null; however, Kunstmaan\NodeBundle\Con...r::createDraftVersion() 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...
883
                $nodeTranslation,
884
                $nodeVersion
885
            );
886
            $draftNodeVersion = $nodeVersion;
887
        } elseif ($draft) {
888
            $nodeVersion = $draftNodeVersion;
889
            $page = $nodeVersion->getRef($this->em);
890
        } else {
891
            if ($request->getMethod() == 'POST') {
892
                $nodeVersionIsLocked = $this->isNodeVersionLocked($nodeTranslation, true);
893
894
                //Check the version timeout and make a new nodeversion if the timeout is passed
895
                $thresholdDate = date(
896
                    'Y-m-d H:i:s',
897
                    time() - $this->getParameter(
898
                        'kunstmaan_node.version_timeout'
899
                    )
900
                );
901
                $updatedDate = date(
902
                    'Y-m-d H:i:s',
903
                    strtotime($nodeVersion->getUpdated()->format('Y-m-d H:i:s'))
904
                );
905 View Code Duplication
                if ($thresholdDate >= $updatedDate || $nodeVersionIsLocked) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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

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

Loading history...
906
                    $page = $nodeVersion->getRef($this->em);
907
                    if ($nodeVersion === $nodeTranslation->getPublicNodeVersion()) {
908
                        $this->nodePublisher
909
                            ->createPublicVersion(
910
                                $page,
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 906 can be null; however, Kunstmaan\NodeBundle\Hel...::createPublicVersion() 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...
911
                                $nodeTranslation,
912
                                $nodeVersion,
913
                                $this->user
914
                            );
915
                    } else {
916
                        $this->createDraftVersion(
917
                            $page,
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 906 can be null; however, Kunstmaan\NodeBundle\Con...r::createDraftVersion() 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...
918
                            $nodeTranslation,
919
                            $nodeVersion
920
                        );
921
                    }
922
                }
923
            }
924
            $page = $nodeVersion->getRef($this->em);
925
        }
926
        $isStructureNode = $page->isStructureNode();
927
928
        $menubuilder = $this->get('kunstmaan_node.actions_menu_builder');
929
        $menubuilder->setActiveNodeVersion($nodeVersion);
930
        $menubuilder->setEditableNode(!$isStructureNode);
931
932
        // Building the form
933
        $propertiesWidget = new FormWidget();
934
        $propertiesWidget->addType('main', $page->getDefaultAdminType(), $page);
935
        $propertiesWidget->addType('node', $node->getDefaultAdminType(), $node);
936
        $tabPane->addTab(new Tab('kuma_node.tab.properties.title', $propertiesWidget));
937
938
        // Menu tab
939
        $menuWidget = new FormWidget();
940
        $menuWidget->addType(
941
            'menunodetranslation',
942
            NodeMenuTabTranslationAdminType::class,
943
            $nodeTranslation,
944
            ['slugable' => !$isStructureNode]
945
        );
946
        $menuWidget->addType('menunode', NodeMenuTabAdminType::class, $node, ['available_in_nav' => !$isStructureNode]);
947
        $tabPane->addTab(new Tab('kuma_node.tab.menu.title', $menuWidget));
948
949
        $this->get('event_dispatcher')->dispatch(
950
            Events::ADAPT_FORM,
951
            new AdaptFormEvent(
952
                $request,
953
                $tabPane,
954
                $page,
955
                $node,
956
                $nodeTranslation,
957
                $nodeVersion
958
            )
959
        );
960
961
        $tabPane->buildForm();
962
963
        if ($request->getMethod() == 'POST') {
964
            $tabPane->bindRequest($request);
965
966
            // Don't redirect to listing when coming from ajax request, needed for url chooser.
967
            if ($tabPane->isValid() && !$request->isXmlHttpRequest()) {
968
                $this->get('event_dispatcher')->dispatch(
969
                    Events::PRE_PERSIST,
970
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $nodeVersion defined by $draftNodeVersion on line 888 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...
971
                );
972
973
                $nodeTranslation->setTitle($page->getTitle());
974
                if ($isStructureNode) {
975
                    $nodeTranslation->setSlug('');
976
                }
977
                $nodeVersion->setUpdated(new DateTime());
978
                if ($nodeVersion->getType() == 'public') {
979
                    $nodeTranslation->setUpdated($nodeVersion->getUpdated());
980
                }
981
                $this->em->persist($nodeTranslation);
982
                $this->em->persist($nodeVersion);
0 ignored issues
show
Bug introduced by
It seems like $nodeVersion defined by $draftNodeVersion on line 888 can be null; however, Doctrine\ORM\EntityManager::persist() 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...
983
                $tabPane->persist($this->em);
984
                $this->em->flush();
985
986
                $this->get('event_dispatcher')->dispatch(
987
                    Events::POST_PERSIST,
988
                    new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $nodeVersion defined by $draftNodeVersion on line 888 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...
989
                );
990
991
                if ($nodeVersionIsLocked) {
992
                    $this->addFlash(
993
                        FlashTypes::SUCCESS,
994
                        $this->get('translator')->trans('kuma_node.admin.edit.flash.locked_success')
995
                    );
996
                } elseif ($request->request->has('publishing') || $request->request->has('publish_later')) {
997
                    $this->nodePublisher->chooseHowToPublish($request, $nodeTranslation, $this->translator);
998
                } elseif ($request->request->has('unpublishing') || $request->request->has('unpublish_later')) {
999
                    $this->nodePublisher->chooseHowToUnpublish($request, $nodeTranslation, $this->translator);
1000
                } else {
1001
                    $this->addFlash(
1002
                        FlashTypes::SUCCESS,
1003
                        $this->get('translator')->trans('kuma_node.admin.edit.flash.success')
1004
                    );
1005
                }
1006
1007
                $params = [
1008
                    'id' => $node->getId(),
1009
                    'subaction' => $subaction,
1010
                    'currenttab' => $tabPane->getActiveTab(),
1011
                ];
1012
                $params = array_merge(
1013
                    $params,
1014
                    $tabPane->getExtraParams($request)
1015
                );
1016
1017
                if ($subaction === 'draft' && ($request->request->has('publishing') || $request->request->has('publish_later'))) {
1018
                    unset($params['subaction']);
1019
                }
1020
1021
                return $this->redirect(
1022
                    $this->generateUrl(
1023
                        'KunstmaanNodeBundle_nodes_edit',
1024
                        $params
1025
                    )
1026
                );
1027
            }
1028
        }
1029
1030
        $nodeVersions = $this->em->getRepository(
1031
            'KunstmaanNodeBundle:NodeVersion'
1032
        )->findBy(
1033
            ['nodeTranslation' => $nodeTranslation],
1034
            ['updated' => 'ASC']
1035
        );
1036
        $queuedNodeTranslationAction = $this->em->getRepository(
1037
            'KunstmaanNodeBundle:QueuedNodeTranslationAction'
1038
        )->findOneBy(['nodeTranslation' => $nodeTranslation]);
1039
1040
        $childCount = $this->em->getRepository('KunstmaanNodeBundle:Node')->getChildCount($node);
1041
1042
        $showDuplicateWithChildren = $this->getParameter('kunstmaan_node.show_duplicate_with_children');
1043
        return [
1044
            'page' => $page,
1045
            'entityname' => ClassLookup::getClass($page),
1046
            'nodeVersions' => $nodeVersions,
1047
            'node' => $node,
1048
            'nodeTranslation' => $nodeTranslation,
1049
            'draft' => $draft,
1050
            'draftNodeVersion' => $draftNodeVersion,
1051
            'showDuplicateWithChildren' => $showDuplicateWithChildren,
1052
            'nodeVersion' => $nodeVersion,
1053
            'subaction' => $subaction,
1054
            'tabPane' => $tabPane,
1055
            'editmode' => true,
1056
            'childCount' => $childCount,
1057
            'queuedNodeTranslationAction' => $queuedNodeTranslationAction,
1058
            'nodeVersionLockCheck' => $this->container->getParameter('kunstmaan_node.lock_enabled'),
1059
            'nodeVersionLockInterval' => $this->container->getParameter('kunstmaan_node.lock_check_interval'),
1060
        ];
1061
    }
1062
1063
    /**
1064
     * @Route(
1065
     *      "checkNodeVersionLock/{id}/{public}",
1066
     *      requirements={"id" = "\d+", "public" = "(0|1)"},
1067
     *      name="KunstmaanNodeBundle_nodes_versionlock_check"
1068
     * )
1069
     *
1070
     * @param Request $request
1071
     * @param $id
1072
     *
1073
     * @return JsonResponse
1074
     */
1075
    public function checkNodeVersionLockAction(Request $request, $id, $public)
1076
    {
1077
        $nodeVersionIsLocked = false;
1078
        $message = '';
1079
        $this->init($request);
1080
1081
        /* @var Node $node */
1082
        $node = $this->em->getRepository('KunstmaanNodeBundle:Node')->find($id);
1083
1084
        try {
1085
            $this->checkPermission($node, PermissionMap::PERMISSION_EDIT);
1086
1087
            /** @var NodeVersionLockHelper $nodeVersionLockHelper */
1088
            $nodeVersionLockHelper = $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
1089
            $nodeTranslation = $node->getNodeTranslation($this->locale, true);
1090
1091
            if ($nodeTranslation) {
1092
                $nodeVersionIsLocked = $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation, $public);
0 ignored issues
show
Documentation introduced by
$this->getUser() is of type null|object, but the function expects a object<Kunstmaan\AdminBundle\Entity\BaseUser>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1093
1094
                if ($nodeVersionIsLocked) {
1095
                    $users = $nodeVersionLockHelper->getUsersWithNodeVersionLock($nodeTranslation, $public, $this->getUser());
1096
                    $message = $this->get('translator')->trans('kuma_node.admin.edit.flash.locked', array('%users%' => implode(', ', $users)));
1097
                }
1098
            }
1099
        } catch (AccessDeniedException $ade) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
1100
        }
1101
1102
        return new JsonResponse(['lock' => $nodeVersionIsLocked, 'message' => $message]);
1103
    }
1104
1105
    /**
1106
     * @param NodeTranslation $nodeTranslation
1107
     * @param bool            $isPublic
1108
     *
1109
     * @return bool
1110
     */
1111
    private function isNodeVersionLocked(NodeTranslation $nodeTranslation, $isPublic)
1112
    {
1113
        if ($this->container->getParameter('kunstmaan_node.lock_enabled')) {
1114
            /** @var NodeVersionLockHelper $nodeVersionLockHelper */
1115
            $nodeVersionLockHelper = $this->get('kunstmaan_node.admin_node.node_version_lock_helper');
1116
            $nodeVersionIsLocked = $nodeVersionLockHelper->isNodeVersionLocked($this->getUser(), $nodeTranslation, $isPublic);
0 ignored issues
show
Documentation introduced by
$this->getUser() is of type null|object, but the function expects a object<Kunstmaan\AdminBundle\Entity\BaseUser>.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1117
1118
            return $nodeVersionIsLocked;
1119
        }
1120
1121
        return false;
1122
    }
1123
1124
    /**
1125
     * @param HasNodeInterface $page            The page
1126
     * @param NodeTranslation  $nodeTranslation The node translation
1127
     * @param NodeVersion      $nodeVersion     The node version
1128
     *
1129
     * @return NodeVersion
1130
     */
1131
    private function createDraftVersion(
1132
        HasNodeInterface $page,
1133
        NodeTranslation $nodeTranslation,
1134
        NodeVersion $nodeVersion
1135
    ) {
1136
        $publicPage = $this->get('kunstmaan_admin.clone.helper')
1137
            ->deepCloneAndSave($page);
1138
        /* @var NodeVersion $publicNodeVersion */
1139
1140
        $publicNodeVersion = $this->em->getRepository(
1141
            'KunstmaanNodeBundle:NodeVersion'
1142
        )->createNodeVersionFor(
1143
            $publicPage,
1144
            $nodeTranslation,
1145
            $this->user,
1146
            $nodeVersion->getOrigin(),
1147
            'public',
1148
            $nodeVersion->getCreated()
1149
        );
1150
1151
        $nodeTranslation->setPublicNodeVersion($publicNodeVersion);
1152
        $nodeVersion->setType('draft');
1153
        $nodeVersion->setOrigin($publicNodeVersion);
1154
        $nodeVersion->setCreated(new DateTime());
1155
1156
        $this->em->persist($nodeTranslation);
1157
        $this->em->persist($nodeVersion);
1158
        $this->em->flush();
1159
1160
        $this->get('event_dispatcher')->dispatch(
1161
            Events::CREATE_DRAFT_VERSION,
1162
            new NodeEvent(
1163
                $nodeTranslation->getNode(),
1164
                $nodeTranslation,
1165
                $nodeVersion,
1166
                $page
1167
            )
1168
        );
1169
1170
        return $nodeVersion;
1171
    }
1172
1173
    /**
1174
     * @param Node   $node       The node
1175
     * @param string $permission The permission to check for
1176
     *
1177
     * @throws AccessDeniedException
1178
     */
1179
    private function checkPermission(Node $node, $permission)
1180
    {
1181
        if (false === $this->authorizationChecker->isGranted($permission, $node)) {
1182
            throw new AccessDeniedException();
1183
        }
1184
    }
1185
1186
    /**
1187
     * @param EntityManager   $em       The Entity Manager
1188
     * @param BaseUser        $user     The user who deletes the children
1189
     * @param string          $locale   The locale that was used
1190
     * @param ArrayCollection $children The children array
1191
     */
1192
    private function deleteNodeChildren(
1193
        EntityManager $em,
1194
        BaseUser $user,
1195
        $locale,
1196
        ArrayCollection $children
1197
    ) {
1198
        /* @var Node $childNode */
1199
        foreach ($children as $childNode) {
1200
            $childNodeTranslation = $childNode->getNodeTranslation(
1201
                $this->locale,
1202
                true
1203
            );
1204
1205
            $childNodeVersion = $childNodeTranslation->getPublicNodeVersion();
1206
            $childNodePage = $childNodeVersion->getRef($this->em);
1207
1208
            $this->get('event_dispatcher')->dispatch(
1209
                Events::PRE_DELETE,
1210
                new NodeEvent(
1211
                    $childNode,
1212
                    $childNodeTranslation,
1213
                    $childNodeVersion,
1214
                    $childNodePage
1215
                )
1216
            );
1217
1218
            $childNode->setDeleted(true);
1219
            $this->em->persist($childNode);
1220
1221
            $children2 = $childNode->getChildren();
1222
            $this->deleteNodeChildren($em, $user, $locale, $children2);
1223
1224
            $this->get('event_dispatcher')->dispatch(
1225
                Events::POST_DELETE,
1226
                new NodeEvent(
1227
                    $childNode,
1228
                    $childNodeTranslation,
1229
                    $childNodeVersion,
1230
                    $childNodePage
1231
                )
1232
            );
1233
        }
1234
    }
1235
1236
    /**
1237
     * @param Request $request
1238
     * @param string  $type
1239
     *
1240
     * @return HasNodeInterface
1241
     */
1242
    private function createNewPage(Request $request, $type)
1243
    {
1244
        /* @var HasNodeInterface $newPage */
1245
        $newPage = new $type();
1246
1247
        $title = $request->get('title');
1248
        if (\is_string($title) && !empty($title)) {
1249
            $newPage->setTitle($title);
1250
        } else {
1251
            $newPage->setTitle($this->get('translator')->trans('kuma_node.admin.new_page.title.default'));
1252
        }
1253
        $this->em->persist($newPage);
1254
        $this->em->flush();
1255
1256
        return $newPage;
1257
    }
1258
1259
    /**
1260
     * @param Request $request
1261
     *
1262
     * @return string
1263
     * @throw InvalidArgumentException
1264
     */
1265
    private function validatePageType($request)
1266
    {
1267
        $type = $request->get('type');
1268
1269
        if (empty($type)) {
1270
            throw new InvalidArgumentException('Please specify a type of page you want to create');
1271
        }
1272
1273
        return $type;
1274
    }
1275
1276
    /**
1277
     * @param Node $node
1278
     *
1279
     * @return \Symfony\Component\HttpFoundation\Response
1280
     */
1281
    private function renderNodeNotTranslatedPage(Node $node)
1282
    {
1283
        //try to find a parent node with the correct translation, if there is none allow copy.
1284
        //if there is a parent but it doesn't have the language to copy to don't allow it
1285
        $parentNode = $node->getParent();
1286
        if ($parentNode) {
1287
            $parentNodeTranslation = $parentNode->getNodeTranslation(
1288
                $this->locale,
1289
                true
1290
            );
1291
            $parentsAreOk = false;
1292
1293
            if ($parentNodeTranslation) {
1294
                $parentsAreOk = $this->em->getRepository(
1295
                    'KunstmaanNodeBundle:NodeTranslation'
1296
                )->hasParentNodeTranslationsForLanguage(
1297
                    $node->getParent()->getNodeTranslation(
1298
                        $this->locale,
1299
                        true
1300
                    ),
1301
                    $this->locale
1302
                );
1303
            }
1304
        } else {
1305
            $parentsAreOk = true;
1306
        }
1307
1308
        return $this->render(
1309
            '@KunstmaanNode/NodeAdmin/pagenottranslated.html.twig',
1310
            array(
1311
                'node' => $node,
1312
                'nodeTranslations' => $node->getNodeTranslations(
1313
                    true
1314
                ),
1315
                'copyfromotherlanguages' => $parentsAreOk,
1316
            )
1317
        );
1318
    }
1319
}
1320