Completed
Push — master ( 06c1ce...67d37c )
by Jeroen
06:20
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
     * @param PagesConfiguration           $pagesConfiguration
57
     * @param DomainConfigurationInterface $domainConfiguration
58
     */
59
    public function __construct(
60
        EntityManagerInterface $em,
61
        AclNativeHelper $aclNativeHelper,
62
        PagesConfiguration $pagesConfiguration,
63
        DomainConfigurationInterface $domainConfiguration
64
    ) {
65
        $this->em = $em;
66
        $this->aclNativeHelper = $aclNativeHelper;
67
        $this->pagesConfiguration = $pagesConfiguration;
68
        $this->domainConfiguration = $domainConfiguration;
69
    }
70
71
    /**
72
     * In this method you can add children for a specific parent, but also
73
     * remove and change the already created children
74
     *
75
     * @param MenuBuilder $menu      The menu builder
76
     * @param MenuItem[]  &$children The children array that may be adapted
77
     * @param MenuItem    $parent    The parent menu item
78
     * @param Request     $request   The request
79
     */
80
    public function adaptChildren(
81
        MenuBuilder $menu,
82
        array &$children,
83
        MenuItem $parent = null,
84
        Request $request = null
85
    ) {
86
        if (null === $parent) {
87
            $menuItem = new TopMenuItem($menu);
88
            $menuItem
89
                ->setRoute('KunstmaanNodeBundle_nodes')
90
                ->setUniqueId('pages')
91
                ->setLabel('pages.title')
92
                ->setParent($parent);
93
            if (stripos($request->attributes->get('_route'), $menuItem->getRoute()) === 0) {
94
                $menuItem->setActive(true);
95
            }
96
            $children[] = $menuItem;
97
        } elseif (strncasecmp($request->attributes->get('_route'), 'KunstmaanNodeBundle_nodes', 25) === 0) {
98
            $treeNodes = $this->getTreeNodes(
99
                $request->getLocale(),
100
                PermissionMap::PERMISSION_VIEW,
101
                $this->aclNativeHelper,
102
                true
103
            );
104
            $activeNodeIds = $this->getActiveNodeIds($request);
105
106
            if (isset($treeNodes[0]) && 'KunstmaanNodeBundle_nodes' === $parent->getRoute()) {
107
                $this->processNodes(
108
                    $menu,
109
                    $children,
110
                    $treeNodes[0],
111
                    $parent,
112
                    $activeNodeIds
113
                );
114
            } elseif ('KunstmaanNodeBundle_nodes_edit' === $parent->getRoute()) {
115
                $parentRouteParams = $parent->getRouteParams();
116
                $parent_id = $parentRouteParams['id'];
117
                if (\array_key_exists($parent_id, $treeNodes)) {
118
                    $this->processNodes(
119
                        $menu,
120
                        $children,
121
                        $treeNodes[$parent_id],
122
                        $parent,
123
                        $activeNodeIds
124
                    );
125
                }
126
            }
127
        }
128
    }
129
130
    /**
131
     * Get the list of nodes that is used in the admin menu.
132
     *
133
     * @param string          $lang
134
     * @param string          $permission
135
     * @param AclNativeHelper $aclNativeHelper
136
     * @param bool            $includeHiddenFromNav
137
     *
138
     * @return array
139
     */
140
    private function getTreeNodes(
141
        $lang,
142
        $permission,
143
        AclNativeHelper $aclNativeHelper,
144
        $includeHiddenFromNav
145
    ) {
146
        if (null === $this->treeNodes) {
147
            $repo = $this->em->getRepository('KunstmaanNodeBundle:Node');
148
            $this->treeNodes = [];
149
150
            $rootNode = $this->domainConfiguration->getRootNode();
151
152
            // Get all nodes that should be shown in the menu
153
            $allNodes = $repo->getAllMenuNodes(
154
                $lang,
155
                $permission,
156
                $aclNativeHelper,
157
                $includeHiddenFromNav,
158
                $rootNode
159
            );
160
            /** @var Node $nodeInfo */
161
            foreach ($allNodes as $nodeInfo) {
162
                $refEntityName = $nodeInfo['ref_entity_name'];
163
                if ($this->pagesConfiguration->isHiddenFromTree($refEntityName)) {
164
                    continue;
165
                }
166
                $parent_id = \is_null($nodeInfo['parent']) ? 0 : $nodeInfo['parent'];
167
                unset($nodeInfo['parent']);
168
                $this->treeNodes[$parent_id][] = $nodeInfo;
169
            }
170
            unset($allNodes);
171
        }
172
173
        return $this->treeNodes;
174
    }
175
176
    /**
177
     * Get an array with the id's off all nodes in the tree that should be
178
     * expanded.
179
     *
180
     * @param $request
181
     *
182
     * @return array
183
     */
184
    private function getActiveNodeIds($request)
185
    {
186
        if ((null === $this->activeNodeIds) && strncasecmp($request->attributes->get('_route'), 'KunstmaanNodeBundle_nodes_edit', 30) === 0) {
187
            $repo = $this->em->getRepository('KunstmaanNodeBundle:Node');
188
189
            $currentNode = $repo->findOneById($request->attributes->get('id'));
190
            $parentNodes = $repo->getAllParents($currentNode);
191
            $this->activeNodeIds = [];
192
            foreach ($parentNodes as $parentNode) {
193
                $this->activeNodeIds[] = $parentNode->getId();
194
            }
195
        }
196
197
        return \is_null($this->activeNodeIds) ? [] : $this->activeNodeIds;
198
    }
199
200
    /**
201
     * @param MenuBuilder    $menu          The menu builder
202
     * @param MenuItem[]     &$children     The children array that may be
203
     *                                      adapted
204
     * @param NodeMenuItem[] $nodes         The nodes
205
     * @param MenuItem       $parent        The parent menu item
0 ignored issues
show
Should the type for parameter $parent not be null|MenuItem?

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...
206
     * @param array          $activeNodeIds List with id's of all nodes that
207
     *                                      should be expanded in the tree
208
     */
209
    private function processNodes(
210
        MenuBuilder $menu,
211
        array &$children,
212
        array $nodes,
213
        MenuItem $parent = null,
214
        array $activeNodeIds
215
    ) {
216
        foreach ($nodes as $child) {
217
            $menuItem = new MenuItem($menu);
218
            $refName = $child['ref_entity_name'];
219
220
            $menuItem
221
                ->setRoute('KunstmaanNodeBundle_nodes_edit')
222
                ->setRouteParams(['id' => $child['id']])
223
                ->setUniqueId('node-'.$child['id'])
224
                ->setLabel($child['title'])
225
                ->setParent($parent)
226
                ->setOffline(!$child['online'] && !$this->pagesConfiguration->isStructureNode($refName))
227
                ->setHiddenFromNav($child['hidden'])
228
                ->setFolder($this->pagesConfiguration->isStructureNode($refName))
229
                ->setRole('page')
230
                ->setWeight($child['weight'])
231
                ->addAttributes(
232
                    [
233
                        'page' => [
234
                            'class' => $refName,
235
                            'children' => $this->pagesConfiguration->getPossibleChildTypes($refName),
236
                            'icon' => $this->pagesConfiguration->getIcon($refName) ?? ($this->pagesConfiguration->isHomePage($refName) ? 'fa fa-home' : null),
237
                        ],
238
                    ]
239
                );
240
241
            if (\in_array($child['id'], $activeNodeIds, false)) {
242
                $menuItem->setActive(true);
243
            }
244
            $children[] = $menuItem;
245
        }
246
    }
247
}
248