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