-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
MenuConfigPass.php
187 lines (155 loc) · 7.79 KB
/
MenuConfigPass.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<?php
/*
* This file is part of the EasyAdminBundle.
*
* (c) Javier Eguiluz <javier.eguiluz@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace EasyCorp\Bundle\EasyAdminBundle\Configuration;
/**
* Processes the main menu configuration defined in the "design.menu"
* option or creates the default config for the menu if none is defined.
*
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
*/
class MenuConfigPass implements ConfigPassInterface
{
public function process(array $backendConfig)
{
// process 1st level menu items
$menuConfig = $backendConfig['design']['menu'];
$menuConfig = $this->normalizeMenuConfig($menuConfig, $backendConfig);
$menuConfig = $this->processMenuConfig($menuConfig, $backendConfig);
$backendConfig['design']['menu'] = $menuConfig;
// process 2nd level menu items (i.e. submenus)
foreach ($backendConfig['design']['menu'] as $i => $itemConfig) {
if (empty($itemConfig['children'])) {
continue;
}
$submenuConfig = $itemConfig['children'];
$submenuConfig = $this->normalizeMenuConfig($submenuConfig, $backendConfig, $i);
$submenuConfig = $this->processMenuConfig($submenuConfig, $backendConfig, $i);
$backendConfig['design']['menu'][$i]['children'] = $submenuConfig;
}
return $backendConfig;
}
/**
* Normalizes the different shortcut notations of the menu config to simplify
* further processing.
*
* @param array $menuConfig
* @param array $backendConfig
* @param int $parentItemIndex The index of the parent item for this menu item (allows to treat submenus differently)
*
* @return array
*/
private function normalizeMenuConfig(array $menuConfig, array $backendConfig, $parentItemIndex = -1)
{
// if the backend doesn't define the menu configuration: create a default
// menu configuration to display all its entities
if (empty($menuConfig)) {
foreach ($backendConfig['entities'] as $entityName => $entityConfig) {
$menuConfig[] = array('entity' => $entityName, 'label' => $entityConfig['label']);
}
}
// replaces the short config syntax:
// design.menu: ['Product', 'User']
// by the expanded config syntax:
// design.menu: [{ entity: 'Product' }, { entity: 'User' }]
foreach ($menuConfig as $i => $itemConfig) {
if (is_string($itemConfig)) {
$itemConfig = array('entity' => $itemConfig);
}
$menuConfig[$i] = $itemConfig;
}
foreach ($menuConfig as $i => $itemConfig) {
// normalize icon configuration
if (!array_key_exists('icon', $itemConfig)) {
$itemConfig['icon'] = ($parentItemIndex > -1) ? 'fa-chevron-right' : 'fa-chevron-circle-right';
} elseif (empty($itemConfig['icon'])) {
$itemConfig['icon'] = null;
} else {
$itemConfig['icon'] = 'fa-'.$itemConfig['icon'];
}
// normalize css_class configuration
if (!array_key_exists('css_class', $itemConfig)) {
$itemConfig['css_class'] = '';
}
// normalize submenu configuration (only for main menu items)
if (!isset($itemConfig['children']) && -1 === $parentItemIndex) {
$itemConfig['children'] = array();
}
// normalize 'default' option, which sets the menu item used as the backend index
if (!array_key_exists('default', $itemConfig)) {
$itemConfig['default'] = false;
} else {
$itemConfig['default'] = (bool) $itemConfig['default'];
}
// normalize 'target' option, which allows to open menu items in different windows or tabs
if (!array_key_exists('target', $itemConfig)) {
$itemConfig['target'] = false;
} else {
$itemConfig['target'] = (string) $itemConfig['target'];
}
$menuConfig[$i] = $itemConfig;
}
return $menuConfig;
}
private function processMenuConfig(array $menuConfig, array $backendConfig, $parentItemIndex = -1)
{
foreach ($menuConfig as $i => $itemConfig) {
// these options are needed to find the active menu/submenu item in the template
$itemConfig['menu_index'] = (-1 === $parentItemIndex) ? $i : $parentItemIndex;
$itemConfig['submenu_index'] = (-1 === $parentItemIndex) ? -1 : $i;
// 1st level priority: if 'entity' is defined, link to the given entity
if (isset($itemConfig['entity'])) {
$itemConfig['type'] = 'entity';
$entityName = $itemConfig['entity'];
if (!array_key_exists($entityName, $backendConfig['entities'])) {
throw new \RuntimeException(sprintf('The "%s" entity included in the "menu" option is not managed by EasyAdmin. The menu can only include any of these entities: %s. NOTE: If your menu worked before, this error may be caused by a change introduced by EasyAdmin 1.12.0 version. Check out https://github.com/javiereguiluz/EasyAdminBundle/releases/tag/v1.12.0 for more details.', $entityName, implode(', ', array_keys($backendConfig['entities']))));
}
if (!isset($itemConfig['label'])) {
$itemConfig['label'] = $backendConfig['entities'][$entityName]['label'];
}
if (!isset($itemConfig['params'])) {
$itemConfig['params'] = array();
}
}
// 2nd level priority: if 'url' is defined, link to the given absolute/relative URL
elseif (isset($itemConfig['url'])) {
$itemConfig['type'] = 'link';
if (!isset($itemConfig['label'])) {
throw new \RuntimeException(sprintf('The configuration of the menu item with "url = %s" must define the "label" option.', $itemConfig['url']));
}
}
// 3rd level priority: if 'route' is defined, link to the path generated with the given route
elseif (isset($itemConfig['route'])) {
$itemConfig['type'] = 'route';
if (!isset($itemConfig['label'])) {
throw new \RuntimeException(sprintf('The configuration of the menu item with "route = %s" must define the "label" option.', $itemConfig['route']));
}
if (!isset($itemConfig['params'])) {
$itemConfig['params'] = array();
}
}
// 4th level priority: if 'label' is defined (and not the previous options),
// this is a menu divider of a submenu title
elseif (isset($itemConfig['label'])) {
if (empty($itemConfig['children'])) {
// if the item doesn't define a submenu, this is a menu divider
$itemConfig['type'] = 'divider';
} else {
// if the item defines a submenu, this is the title of that submenu
$itemConfig['type'] = 'empty';
}
} else {
throw new \RuntimeException(sprintf('The configuration of the menu item in the position %d (being 0 the first item) must define at least one of these options: entity, url, route, label.', $i));
}
$menuConfig[$i] = $itemConfig;
}
return $menuConfig;
}
}
class_alias('EasyCorp\Bundle\EasyAdminBundle\Configuration\MenuConfigPass', 'JavierEguiluz\Bundle\EasyAdminBundle\Configuration\MenuConfigPass', false);