Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

NodeBundle/Helper/Menu/PageMenuAdaptor.php (1 issue)

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\EntityManagerInterface;
6
use Kunstmaan\AdminBundle\Helper\DomainConfigurationInterface;
7
use Kunstmaan\AdminBundle\Helper\Menu\MenuAdaptorInterface;
8
use Kunstmaan\AdminBundle\Helper\Menu\MenuBuilder;
9
use Kunstmaan\AdminBundle\Helper\Menu\MenuItem;
10
use Kunstmaan\AdminBundle\Helper\Menu\TopMenuItem;
11
use Kunstmaan\AdminBundle\Helper\Security\Acl\AclNativeHelper;
12
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMap;
13
use Kunstmaan\NodeBundle\Entity\Node;
14
use Kunstmaan\NodeBundle\Helper\NodeMenuItem;
15
use Kunstmaan\NodeBundle\Helper\PagesConfiguration;
16
use Symfony\Component\HttpFoundation\Request;
17
18
/**
19
 * The Page Menu Adaptor
20
 */
21
class PageMenuAdaptor implements MenuAdaptorInterface
22
{
23
    /**
24
     * @var EntityManagerInterface
25
     */
26
    private $em;
27
28
    /**
29
     * @var AclNativeHelper
30
     */
31
    private $aclNativeHelper;
32
33
    /**
34
     * @var array
35
     */
36
    private $treeNodes;
37
38
    /**
39
     * @var array
40
     */
41
    private $activeNodeIds;
42
43
    /**
44
     * @var PagesConfiguration
45
     */
46
    private $pagesConfiguration;
47
48
    /**
49
     * @var DomainConfigurationInterface
50
     */
51
    private $domainConfiguration;
52
53
    /**
54
     * @param EntityManagerInterface $em              The entity manager
55
     * @param AclNativeHelper        $aclNativeHelper The acl helper
56
     */
57
    public function __construct(
58
        EntityManagerInterface $em,
59
        AclNativeHelper $aclNativeHelper,
60
        PagesConfiguration $pagesConfiguration,
61
        DomainConfigurationInterface $domainConfiguration
62
    ) {
63
        $this->em = $em;
64
        $this->aclNativeHelper = $aclNativeHelper;
65
        $this->pagesConfiguration = $pagesConfiguration;
66
        $this->domainConfiguration = $domainConfiguration;
67
    }
68
69
    /**
70
     * In this method you can add children for a specific parent, but also
71
     * remove and change the already created children
72
     *
73
     * @param MenuBuilder $menu      The menu builder
74
     * @param MenuItem[]  &$children The children array that may be adapted
75
     * @param MenuItem    $parent    The parent menu item
76
     * @param Request     $request   The request
0 ignored issues
show
Should the type for parameter $request not be null|Request?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
77
     */
78
    public function adaptChildren(
79
        MenuBuilder $menu,
80
        array &$children,
81
        MenuItem $parent = null,
82
        Request $request = null
83
    ) {
84
        if (null === $parent) {
85
            $menuItem = new TopMenuItem($menu);
86
            $menuItem
87
                ->setRoute('KunstmaanNodeBundle_nodes')
88
                ->setUniqueId('pages')
89
                ->setLabel('pages.title')
90
                ->setParent($parent);
91
            if (stripos($request->attributes->get('_route'), $menuItem->getRoute()) === 0) {
92
                $menuItem->setActive(true);
93
            }
94
            $children[] = $menuItem;
95
        } elseif (strncasecmp($request->attributes->get('_route'), 'KunstmaanNodeBundle_nodes', 25) === 0) {
96
            $treeNodes = $this->getTreeNodes(
97
                $request->getLocale(),
98
                PermissionMap::PERMISSION_VIEW,
99
                $this->aclNativeHelper,
100
                true
101
            );
102
            $activeNodeIds = $this->getActiveNodeIds($request);
103
104
            if (isset($treeNodes[0]) && 'KunstmaanNodeBundle_nodes' === $parent->getRoute()) {
105
                $this->processNodes(
106
                    $menu,
107
                    $children,
108
                    $treeNodes[0],
109
                    $parent,
110
                    $activeNodeIds
111
                );
112
            } elseif ('KunstmaanNodeBundle_nodes_edit' === $parent->getRoute()) {
113
                $parentRouteParams = $parent->getRouteParams();
114
                $parent_id = $parentRouteParams['id'];
115
                if (\array_key_exists($parent_id, $treeNodes)) {
116
                    $this->processNodes(
117
                        $menu,
118
                        $children,
119
                        $treeNodes[$parent_id],
120
                        $parent,
121
                        $activeNodeIds
122
                    );
123
                }
124
            }
125
        }
126
    }
127
128
    /**
129
     * Get the list of nodes that is used in the admin menu.
130
     *
131
     * @param string $lang
132
     * @param string $permission
133
     * @param bool   $includeHiddenFromNav
134
     *
135
     * @return array
136
     */
137
    private function getTreeNodes(
138
        $lang,
139
        $permission,
140
        AclNativeHelper $aclNativeHelper,
141
        $includeHiddenFromNav
142
    ) {
143
        if (null === $this->treeNodes) {
144
            $repo = $this->em->getRepository(Node::class);
145
            $this->treeNodes = [];
146
147
            $rootNode = $this->domainConfiguration->getRootNode();
148
149
            // Get all nodes that should be shown in the menu
150
            $allNodes = $repo->getAllMenuNodes(
151
                $lang,
152
                $permission,
153
                $aclNativeHelper,
154
                $includeHiddenFromNav,
155
                $rootNode
156
            );
157
            foreach ($allNodes as $nodeInfo) {
158
                $refEntityName = $nodeInfo['ref_entity_name'];
159
                if ($this->pagesConfiguration->isHiddenFromTree($refEntityName)) {
160
                    continue;
161
                }
162
                $parent_id = \is_null($nodeInfo['parent']) ? 0 : $nodeInfo['parent'];
163
                unset($nodeInfo['parent']);
164
                $this->treeNodes[$parent_id][] = $nodeInfo;
165
            }
166
            unset($allNodes);
167
        }
168
169
        return $this->treeNodes;
170
    }
171
172
    /**
173
     * Get an array with the id's off all nodes in the tree that should be
174
     * expanded.
175
     *
176
     * @param $request
177
     *
178
     * @return array
179
     */
180
    private function getActiveNodeIds($request)
181
    {
182
        if ((null === $this->activeNodeIds) && strncasecmp($request->attributes->get('_route'), 'KunstmaanNodeBundle_nodes_edit', 30) === 0) {
183
            $repo = $this->em->getRepository(Node::class);
184
185
            $currentNode = $repo->findOneById($request->attributes->get('id'));
186
            $parentNodes = $repo->getAllParents($currentNode);
187
            $this->activeNodeIds = [];
188
            foreach ($parentNodes as $parentNode) {
189
                $this->activeNodeIds[] = $parentNode->getId();
190
            }
191
        }
192
193
        return \is_null($this->activeNodeIds) ? [] : $this->activeNodeIds;
194
    }
195
196
    /**
197
     * @param MenuBuilder    $menu          The menu builder
198
     * @param MenuItem[]     &$children     The children array that may be
199
     *                                      adapted
200
     * @param NodeMenuItem[] $nodes         The nodes
201
     * @param MenuItem       $parent        The parent menu item
202
     * @param array          $activeNodeIds List with id's of all nodes that
203
     *                                      should be expanded in the tree
204
     */
205
    private function processNodes(
206
        MenuBuilder $menu,
207
        array &$children,
208
        array $nodes,
209
        MenuItem $parent = null,
210
        array $activeNodeIds
211
    ) {
212
        foreach ($nodes as $child) {
213
            $menuItem = new MenuItem($menu);
214
            $refName = $child['ref_entity_name'];
215
216
            $menuItem
217
                ->setRoute('KunstmaanNodeBundle_nodes_edit')
218
                ->setRouteParams(['id' => $child['id']])
219
                ->setUniqueId('node-' . $child['id'])
220
                ->setLabel($child['title'])
221
                ->setParent($parent)
222
                ->setOffline(!$child['online'] && !$this->pagesConfiguration->isStructureNode($refName))
223
                ->setHiddenFromNav($child['hidden'])
224
                ->setFolder($this->pagesConfiguration->isStructureNode($refName))
225
                ->setRole('page')
226
                ->setWeight($child['weight'])
227
                ->addAttributes(
228
                    [
229
                        'page' => [
230
                            'class' => $refName,
231
                            'children' => $this->pagesConfiguration->getPossibleChildTypes($refName),
232
                            'icon' => $this->pagesConfiguration->getIcon($refName) ?? ($this->pagesConfiguration->isHomePage($refName) ? 'fa fa-home' : null),
233
                        ],
234
                    ]
235
                );
236
237
            if (\in_array($child['id'], $activeNodeIds, false)) {
238
                $menuItem->setActive(true);
239
            }
240
            $children[] = $menuItem;
241
        }
242
    }
243
}
244