Completed
Push — master ( ae5e03...0447ee )
by Jeroen
10:35 queued 04:37
created

NodeBundle/Helper/Menu/ActionsMenuBuilder.php (4 issues)

Upgrade to new PHP Analysis Engine

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

1
<?php
2
3
namespace Kunstmaan\NodeBundle\Helper\Menu;
4
5
use Doctrine\ORM\EntityManager;
6
use FOS\UserBundle\Model\UserInterface;
7
use Knp\Menu\FactoryInterface;
8
use Knp\Menu\ItemInterface;
9
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMap;
10
use Kunstmaan\NodeBundle\Entity\NodeVersion;
11
use Kunstmaan\NodeBundle\Entity\QueuedNodeTranslationAction;
12
use Kunstmaan\NodeBundle\Event\ConfigureActionMenuEvent;
13
use Kunstmaan\NodeBundle\Event\Events;
14
use Kunstmaan\NodeBundle\Helper\PagesConfiguration;
15
use Kunstmaan\PagePartBundle\Helper\HasPageTemplateInterface;
16
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17
use Symfony\Component\Routing\RouterInterface;
18
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
19
20
class ActionsMenuBuilder
21
{
22
    /**
23
     * @var FactoryInterface
24
     */
25
    private $factory;
26
27
    /**
28
     * @var NodeVersion
29
     */
30
    private $activeNodeVersion;
31
32
    /**
33
     * @var EntityManager
34
     */
35
    private $em;
36
37
    /**
38
     * @var RouterInterface
39
     */
40
    private $router;
41
42
    /**
43
     * @var EventDispatcherInterface
44
     */
45
    private $dispatcher;
46
47
    /**
48
     * @var AuthorizationCheckerInterface
49
     */
50
    private $authorizationChecker;
51
52
    /**
53
     * @var PagesConfiguration
54
     */
55
    private $pagesConfiguration;
56
57
    /**
58
     * @var bool
59
     */
60
    private $isEditableNode = true;
61
62
    /**
63
     * @var bool
64
     */
65
    private $enableExportPageTemplate;
66
67
    /** @var bool */
68
    private $showDuplicateWithChildren;
69
70
    /**
71
     * @param FactoryInterface              $factory
72
     * @param EntityManager                 $em
73
     * @param RouterInterface               $router
74
     * @param EventDispatcherInterface      $dispatcher
75
     * @param AuthorizationCheckerInterface $authorizationChecker
76
     * @param PagesConfiguration            $pagesConfiguration
77
     * @param bool                          $enableExportPageTemplate
78
     * @param bool                          $showDuplicateWithChildren
79
     */
80 8
    public function __construct(
81
        FactoryInterface $factory,
82
        EntityManager $em,
0 ignored issues
show
You have injected the EntityManager via parameter $em. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
83
        RouterInterface $router,
84
        EventDispatcherInterface $dispatcher,
85
        AuthorizationCheckerInterface $authorizationChecker,
86
        PagesConfiguration $pagesConfiguration,
87
        $enableExportPageTemplate = true,
88
        bool $showDuplicateWithChildren = false
89
    ) {
90 8
        $this->factory = $factory;
91 8
        $this->em = $em;
92 8
        $this->router = $router;
93 8
        $this->dispatcher = $dispatcher;
94 8
        $this->authorizationChecker = $authorizationChecker;
95 8
        $this->pagesConfiguration = $pagesConfiguration;
96 8
        $this->enableExportPageTemplate = $enableExportPageTemplate;
97 8
        $this->showDuplicateWithChildren = $showDuplicateWithChildren;
98 8
    }
99
100
    /**
101
     * @return ItemInterface
102
     */
103 1
    public function createSubActionsMenu()
104
    {
105 1
        $activeNodeVersion = $this->getActiveNodeVersion();
106 1
        $menu = $this->factory->createItem('root');
107 1
        $menu->setChildrenAttribute('class', 'page-sub-actions');
108
109 1
        if (null !== $activeNodeVersion && $this->isEditableNode) {
110 1
            $menu->addChild(
111 1
                'subaction.versions',
112
                [
113
                    'linkAttributes' => [
114 1
                        'data-toggle' => 'modal',
115
                        'data-keyboard' => 'true',
116
                        'data-target' => '#versions',
117
                    ],
118
                ]
119
            );
120
        }
121
122 1
        $this->dispatcher->dispatch(
123 1
            Events::CONFIGURE_SUB_ACTION_MENU,
124 1
            new ConfigureActionMenuEvent(
125 1
                $this->factory,
126
                $menu,
127
                $activeNodeVersion
128
            )
129
        );
130
131 1
        return $menu;
132
    }
133
134
    /**
135
     * @return ItemInterface
136
     */
137 6
    public function createActionsMenu()
138
    {
139 6
        $activeNodeVersion = $this->getActiveNodeVersion();
140
141 6
        $translations = $activeNodeVersion->getNodeTranslation()->getNode()->getNodeTranslations(true);
142 6
        $canRecopy = false;
143 6
        foreach ($translations as $translation) {
144 1
            if ($translation->getLang() != $activeNodeVersion->getNodeTranslation()->getLang()) {
145 1
                $canRecopy = true;
146
            }
147
        }
148
149 6
        $menu = $this->factory->createItem('root');
150 6
        $menu->setChildrenAttribute(
151 6
            'class',
152 6
            'page-main-actions js-auto-collapse-buttons'
153
        );
154 6
        $menu->setChildrenAttribute(
155 6
            'data-visible-buttons',
156 6
            '3'
157
        );
158
159 6
        if (null === $activeNodeVersion) {
160
            $this->dispatcher->dispatch(
161
                Events::CONFIGURE_ACTION_MENU,
162
                new ConfigureActionMenuEvent(
163
                    $this->factory,
164
                    $menu,
165
                    $activeNodeVersion
166
                )
167
            );
168
169
            return $menu;
170
        }
171
172 6
        $activeNodeTranslation = $activeNodeVersion->getNodeTranslation();
173 6
        $node = $activeNodeTranslation->getNode();
174 6
        $queuedNodeTranslationAction = $this->em->getRepository(QueuedNodeTranslationAction::class)->findOneBy(['nodeTranslation' => $activeNodeTranslation]);
175
176 6
        $isFirst = true;
177 6
        $canEdit = $this->authorizationChecker->isGranted(PermissionMap::PERMISSION_EDIT, $node);
178 6
        $canPublish = $this->authorizationChecker->isGranted(PermissionMap::PERMISSION_PUBLISH, $node);
179 6
        $isSuperAdmin = $this->authorizationChecker->isGranted(UserInterface::ROLE_SUPER_ADMIN);
180
181 6
        if ($activeNodeVersion->isDraft() && $this->isEditableNode) {
182 1 View Code Duplication
            if ($canEdit) {
0 ignored issues
show
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...
183 1
                $menu->addChild(
184 1
                    'action.saveasdraft',
185
                    [
186
                        'linkAttributes' => [
187 1
                            'type' => 'submit',
188
                            'class' => 'js-save-btn btn btn--raise-on-hover btn-primary',
189
                            'value' => 'save',
190
                            'name' => 'save',
191
                        ],
192
                        'extras' => ['renderType' => 'button'],
193
                    ]
194
                );
195 1
                if ($this->enableExportPageTemplate && $isSuperAdmin && is_subclass_of($node->getRefEntityName(), HasPageTemplateInterface::class)) {
196
                    $menu->addChild(
197
                        'action.exportpagetemplate',
198
                        [
199
                            'linkAttributes' => [
200
                                'class' => 'btn btn-default btn--raise-on-hover',
201
                                'data-toggle' => 'modal',
202
                                'data-keyboard' => 'true',
203
                                'data-target' => '#exportPagetemplate',
204
                            ],
205
                        ]
206
                    );
207
                }
208 1
                if ($canRecopy) {
209
                    $menu->addChild(
210
                        'action.recopyfromlanguage',
211
                        [
212
                            'linkAttributes' => [
213
                                'class' => 'btn btn-default btn--raise-on-hover',
214
                                'data-toggle' => 'modal',
215
                                'data-keyboard' => 'true',
216
                                'data-target' => '#recopy',
217
                            ],
218
                        ]
219
                    );
220
                }
221 1
                $isFirst = false;
222
            }
223
224 1
            $menu->addChild(
225 1
                'action.preview',
226
                [
227 1
                    'uri' => $this->router->generate(
228 1
                        '_slug_preview',
229
                        [
230 1
                            'url' => $activeNodeTranslation->getUrl(),
231 1
                            'version' => $activeNodeVersion->getId(),
232
                        ]
233
                    ),
234
                    'linkAttributes' => [
235
                        'target' => '_blank',
236
                        'class' => 'btn btn-default btn--raise-on-hover',
237
                    ],
238
                ]
239
            );
240
241 1 View Code Duplication
            if (empty($queuedNodeTranslationAction) && $canPublish) {
0 ignored issues
show
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...
242 1
                $menu->addChild(
243 1
                    'action.publish',
244
                    [
245
                        'linkAttributes' => [
246 1
                            'data-toggle' => 'modal',
247 1
                            'data-target' => '#pub',
248 1
                            'class' => 'btn btn--raise-on-hover'.($isFirst ? ' btn-primary btn-save' : ' btn-default'),
249
                        ],
250
                    ]
251
                );
252
            }
253
        } else {
254 5
            if ($canEdit && $canPublish) {
255 5
                $menu->addChild(
256 5
                    'action.save',
257
                    [
258
                        'linkAttributes' => [
259 5
                            'type' => 'submit',
260
                            'class' => 'js-save-btn btn btn--raise-on-hover btn-primary',
261
                            'value' => 'save',
262
                            'name' => 'save',
263
                        ],
264
                        'extras' => ['renderType' => 'button'],
265
                    ]
266
                );
267 5
                $isFirst = false;
268
            }
269
270 5
            if ($this->isEditableNode) {
271 4
                $menu->addChild(
272 4
                    'action.preview',
273
                    [
274 4
                        'uri' => $this->router->generate(
275 4
                            '_slug_preview',
276 4
                            ['url' => $activeNodeTranslation->getUrl()]
277
                        ),
278
                        'linkAttributes' => [
279
                            'target' => '_blank',
280
                            'class' => 'btn btn-default btn--raise-on-hover',
281
                        ],
282
                    ]
283
                );
284
285 4
                if (empty($queuedNodeTranslationAction)
286 4
                    && $activeNodeTranslation->isOnline()
287 1
                    && $this->authorizationChecker->isGranted(
288 4
                        PermissionMap::PERMISSION_UNPUBLISH,
289
                        $node
290
                    )
291
                ) {
292 1
                    $menu->addChild(
293 1
                        'action.unpublish',
294
                        [
295
                            'linkAttributes' => [
296 1
                                'class' => 'btn btn-default btn--raise-on-hover',
297
                                'data-toggle' => 'modal',
298
                                'data-keyboard' => 'true',
299
                                'data-target' => '#unpub',
300
                            ],
301
                        ]
302
                    );
303 4 View Code Duplication
                } elseif (empty($queuedNodeTranslationAction)
304 4
                    && !$activeNodeTranslation->isOnline()
305 4
                    && $canPublish
306
                ) {
307 4
                    $menu->addChild(
308 4
                        'action.publish',
309
                        [
310
                            'linkAttributes' => [
311 4
                                'class' => 'btn btn-default btn--raise-on-hover',
312
                                'data-toggle' => 'modal',
313
                                'data-keyboard' => 'true',
314
                                'data-target' => '#pub',
315
                            ],
316
                        ]
317
                    );
318
                }
319
320 4 View Code Duplication
                if ($canEdit) {
0 ignored issues
show
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...
321 4
                    $menu->addChild(
322 4
                        'action.saveasdraft',
323
                        [
324
                            'linkAttributes' => [
325 4
                                'type' => 'submit',
326 4
                                'class' => 'btn btn--raise-on-hover'.($isFirst ? ' btn-primary btn-save' : ' btn-default'),
327 4
                                'value' => 'saveasdraft',
328 4
                                'name' => 'saveasdraft',
329
                            ],
330
                            'extras' => ['renderType' => 'button'],
331
                        ]
332
                    );
333 4
                    if ($this->enableExportPageTemplate && $isSuperAdmin && is_subclass_of($node->getRefEntityName(), HasPageTemplateInterface::class)) {
334
                        $menu->addChild(
335
                            'action.exportpagetemplate',
336
                            [
337
                                'linkAttributes' => [
338
                                    'class' => 'btn btn-default btn--raise-on-hover',
339
                                    'data-toggle' => 'modal',
340
                                    'data-keyboard' => 'true',
341
                                    'data-target' => '#exportPagetemplate',
342
                                ],
343
                            ]
344
                        );
345
                    }
346 4
                    if ($canRecopy) {
347 1
                        $menu->addChild(
348 1
                            'action.recopyfromlanguage',
349
                            [
350
                                'linkAttributes' => [
351 1
                                    'class' => 'btn btn-default btn--raise-on-hover',
352
                                    'data-toggle' => 'modal',
353
                                    'data-keyboard' => 'true',
354
                                    'data-target' => '#recopy',
355
                                ],
356
                            ]
357
                        );
358
                    }
359
                }
360
            }
361
        }
362
363 6 View Code Duplication
        if ($this->pagesConfiguration->getPossibleChildTypes(
364 6
            $node->getRefEntityName()
365
        )
366
        ) {
367
            $menu->addChild(
368
                'action.addsubpage',
369
                [
370
                    'linkAttributes' => [
371
                        'type' => 'button',
372
                        'class' => 'btn btn-default btn--raise-on-hover',
373
                        'data-toggle' => 'modal',
374
                        'data-keyboard' => 'true',
375
                        'data-target' => '#add-subpage-modal',
376
                    ],
377
                    'extras' => ['renderType' => 'button'],
378
                ]
379
            );
380
        }
381
382 6
        if (null !== $node->getParent() && $canEdit) {
383 1
            $menu->addChild(
384 1
                'action.duplicate',
385
                [
386
                    'linkAttributes' => [
387 1
                        'type' => 'button',
388
                        'class' => 'btn btn-default btn--raise-on-hover',
389
                        'data-toggle' => 'modal',
390
                        'data-keyboard' => 'true',
391
                        'data-target' => '#duplicate-page-modal',
392
                    ],
393
                    'extras' => ['renderType' => 'button'],
394
                ]
395
            );
396
397 1 View Code Duplication
            if ($this->showDuplicateWithChildren) {
398
                $menu->addChild(
399
                    'action.duplicate_with_children',
400
                    [
401
                        'linkAttributes' => [
402
                            'type' => 'button',
403
                            'class' => 'btn btn-default btn--raise-on-hover',
404
                            'data-toggle' => 'modal',
405
                            'data-keyboard' => 'true',
406
                            'data-target' => '#duplicate-with-children-page-modal',
407
                        ],
408
                        'extras' => ['renderType' => 'button'],
409
                    ]
410
                );
411
            }
412
        }
413
414 6
        if ((null !== $node->getParent() || $node->getChildren()->isEmpty())
415 6
            && $this->authorizationChecker->isGranted(
416 6
                PermissionMap::PERMISSION_DELETE,
417
                $node
418
            )
419
        ) {
420 6
            $menu->addChild(
421 6
                'action.delete',
422
                [
423
                    'linkAttributes' => [
424 6
                        'type' => 'button',
425
                        'class' => 'btn btn-default btn--raise-on-hover',
426
                        'onClick' => 'oldEdited = isEdited; isEdited=false',
427
                        'data-toggle' => 'modal',
428
                        'data-keyboard' => 'true',
429
                        'data-target' => '#delete-page-modal',
430
                    ],
431
                    'extras' => ['renderType' => 'button'],
432
                ]
433
            );
434
        }
435
436 6
        $this->dispatcher->dispatch(
437 6
            Events::CONFIGURE_ACTION_MENU,
438 6
            new ConfigureActionMenuEvent(
439 6
                $this->factory,
440
                $menu,
441
                $activeNodeVersion
442
            )
443
        );
444
445 6
        return $menu;
446
    }
447
448
    /**
449
     * @return ItemInterface
450
     */
451 1
    public function createTopActionsMenu()
452
    {
453 1
        $menu = $this->createActionsMenu();
454 1
        $menu->setChildrenAttribute('id', 'page-main-actions-top');
455 1
        $menu->setChildrenAttribute(
456 1
            'class',
457 1
            'page-main-actions page-main-actions--top'
458
        );
459
460 1
        return $menu;
461
    }
462
463
    /**
464
     * @return ItemInterface
465
     */
466
    public function createHomeActionsMenu()
467
    {
468
        $menu = $this->factory->createItem('root');
469
        $menu->setChildrenAttribute(
470
            'class',
471
            'page-main-actions js-auto-collapse-buttons'
472
        );
473
        $menu->addChild(
474
            'action.addhomepage',
475
            [
476
                'linkAttributes' => [
477
                    'type' => 'button',
478
                    'class' => 'btn btn-default btn--raise-on-hover',
479
                    'data-toggle' => 'modal',
480
                    'data-keyboard' => 'true',
481
                    'data-target' => '#add-homepage-modal',
482
                ],
483
                'extras' => ['renderType' => 'button'],
484
            ]
485
        );
486
487
        return $menu;
488
    }
489
490
    /**
491
     * @return ItemInterface
492
     */
493
    public function createTopHomeActionsMenu()
494
    {
495
        $menu = $this->createHomeActionsMenu();
496
        $menu->setChildrenAttribute('id', 'page-main-actions-top');
497
        $menu->setChildrenAttribute(
498
            'class',
499
            'page-main-actions page-main-actions--top'
500
        );
501
502
        return $menu;
503
    }
504
505
    /**
506
     * Set activeNodeVersion
507
     *
508
     * @param NodeVersion $activeNodeVersion
509
     *
510
     * @return ActionsMenuBuilder
511
     */
512 8
    public function setActiveNodeVersion(NodeVersion $activeNodeVersion)
513
    {
514 8
        $this->activeNodeVersion = $activeNodeVersion;
515
516 8
        return $this;
517
    }
518
519
    /**
520
     * Get activeNodeVersion
521
     *
522
     * @return NodeVersion
523
     */
524 8
    public function getActiveNodeVersion()
525
    {
526 8
        return $this->activeNodeVersion;
527
    }
528
529
    /**
530
     * @param bool $value
531
     */
532 1
    public function setEditableNode($value)
533
    {
534 1
        $this->isEditableNode = $value;
535 1
    }
536
}
537