Completed
Push — 6.0 ( eb641c...92cb73 )
by Ruud
148:12 queued 131:31
created

NodeAdminController::updateAcl()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 3
eloc 14
nc 3
nop 2

1 Method

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