danielebarchiesi@4
|
1 <?php
|
danielebarchiesi@4
|
2
|
danielebarchiesi@4
|
3 /**
|
danielebarchiesi@4
|
4 * Implements hook_features_api().
|
danielebarchiesi@4
|
5 */
|
danielebarchiesi@4
|
6 function menu_features_api() {
|
danielebarchiesi@4
|
7 return array(
|
danielebarchiesi@4
|
8 'menu_custom' => array(
|
danielebarchiesi@4
|
9 'name' => t('Menus'),
|
danielebarchiesi@4
|
10 'default_hook' => 'menu_default_menu_custom',
|
danielebarchiesi@4
|
11 'feature_source' => TRUE,
|
danielebarchiesi@4
|
12 'default_file' => FEATURES_DEFAULTS_INCLUDED,
|
danielebarchiesi@4
|
13 ),
|
danielebarchiesi@4
|
14 'menu_links' => array(
|
danielebarchiesi@4
|
15 'name' => t('Menu links'),
|
danielebarchiesi@4
|
16 'default_hook' => 'menu_default_menu_links',
|
danielebarchiesi@4
|
17 'feature_source' => TRUE,
|
danielebarchiesi@4
|
18 'default_file' => FEATURES_DEFAULTS_INCLUDED,
|
danielebarchiesi@4
|
19 ),
|
danielebarchiesi@4
|
20 // DEPRECATED
|
danielebarchiesi@4
|
21 'menu' => array(
|
danielebarchiesi@4
|
22 'name' => t('Menu items'),
|
danielebarchiesi@4
|
23 'default_hook' => 'menu_default_items',
|
danielebarchiesi@4
|
24 'default_file' => FEATURES_DEFAULTS_INCLUDED,
|
danielebarchiesi@4
|
25 'feature_source' => FALSE,
|
danielebarchiesi@4
|
26 ),
|
danielebarchiesi@4
|
27 );
|
danielebarchiesi@4
|
28 }
|
danielebarchiesi@4
|
29
|
danielebarchiesi@4
|
30 /**
|
danielebarchiesi@4
|
31 * Implements hook_features_export().
|
danielebarchiesi@4
|
32 * DEPRECATED: This implementation simply migrates deprecated `menu` items
|
danielebarchiesi@4
|
33 * to the `menu_links` type.
|
danielebarchiesi@4
|
34 */
|
danielebarchiesi@4
|
35 function menu_features_export($data, &$export, $module_name = '') {
|
danielebarchiesi@4
|
36 $pipe = array();
|
danielebarchiesi@4
|
37 foreach ($data as $path) {
|
danielebarchiesi@4
|
38 $pipe['menu_links'][] = "features:{$path}";
|
danielebarchiesi@4
|
39 }
|
danielebarchiesi@4
|
40 return $pipe;
|
danielebarchiesi@4
|
41 }
|
danielebarchiesi@4
|
42
|
danielebarchiesi@4
|
43 /**
|
danielebarchiesi@4
|
44 * Implements hook_features_export_options().
|
danielebarchiesi@4
|
45 */
|
danielebarchiesi@4
|
46 function menu_custom_features_export_options() {
|
danielebarchiesi@4
|
47 $options = array();
|
danielebarchiesi@4
|
48 $result = db_query("SELECT * FROM {menu_custom} ORDER BY title", array(), array('fetch' => PDO::FETCH_ASSOC));
|
danielebarchiesi@4
|
49 foreach ($result as $menu) {
|
danielebarchiesi@4
|
50 $options[$menu['menu_name']] = $menu['title'];
|
danielebarchiesi@4
|
51 }
|
danielebarchiesi@4
|
52 return $options;
|
danielebarchiesi@4
|
53 }
|
danielebarchiesi@4
|
54
|
danielebarchiesi@4
|
55 /**
|
danielebarchiesi@4
|
56 * Implements hook_features_export().
|
danielebarchiesi@4
|
57 */
|
danielebarchiesi@4
|
58 function menu_custom_features_export($data, &$export, $module_name = '') {
|
danielebarchiesi@4
|
59 // Default hooks are provided by the feature module so we need to add
|
danielebarchiesi@4
|
60 // it as a dependency.
|
danielebarchiesi@4
|
61 $export['dependencies']['features'] = 'features';
|
danielebarchiesi@4
|
62 $export['dependencies']['menu'] = 'menu';
|
danielebarchiesi@4
|
63
|
danielebarchiesi@4
|
64 // Collect a menu to module map
|
danielebarchiesi@4
|
65 $pipe = array();
|
danielebarchiesi@4
|
66 $map = features_get_default_map('menu_custom', 'menu_name');
|
danielebarchiesi@4
|
67 foreach ($data as $menu_name) {
|
danielebarchiesi@4
|
68 // If this menu is provided by a different module, add it as a dependency.
|
danielebarchiesi@4
|
69 if (isset($map[$menu_name]) && $map[$menu_name] != $module_name) {
|
danielebarchiesi@4
|
70 $export['dependencies'][$map[$menu_name]] = $map[$menu_name];
|
danielebarchiesi@4
|
71 }
|
danielebarchiesi@4
|
72 else {
|
danielebarchiesi@4
|
73 $export['features']['menu_custom'][$menu_name] = $menu_name;
|
danielebarchiesi@4
|
74 }
|
danielebarchiesi@4
|
75 }
|
danielebarchiesi@4
|
76 return $pipe;
|
danielebarchiesi@4
|
77 }
|
danielebarchiesi@4
|
78
|
danielebarchiesi@4
|
79 /**
|
danielebarchiesi@4
|
80 * Implements hook_features_export_render()
|
danielebarchiesi@4
|
81 */
|
danielebarchiesi@4
|
82 function menu_custom_features_export_render($module, $data) {
|
danielebarchiesi@4
|
83 $code = array();
|
danielebarchiesi@4
|
84 $code[] = ' $menus = array();';
|
danielebarchiesi@4
|
85 $code[] = '';
|
danielebarchiesi@4
|
86
|
danielebarchiesi@4
|
87 $translatables = array();
|
danielebarchiesi@4
|
88 foreach ($data as $menu_name) {
|
danielebarchiesi@4
|
89 $row = db_select('menu_custom')
|
danielebarchiesi@4
|
90 ->fields('menu_custom')
|
danielebarchiesi@4
|
91 ->condition('menu_name', $menu_name)
|
danielebarchiesi@4
|
92 ->execute()
|
danielebarchiesi@4
|
93 ->fetchAssoc();
|
danielebarchiesi@4
|
94 if ($row) {
|
danielebarchiesi@4
|
95 $export = features_var_export($row, ' ');
|
danielebarchiesi@4
|
96 $code[] = " // Exported menu: {$menu_name}.";
|
danielebarchiesi@4
|
97 $code[] = " \$menus['{$menu_name}'] = {$export};";
|
danielebarchiesi@4
|
98 $translatables[] = $row['title'];
|
danielebarchiesi@4
|
99 $translatables[] = $row['description'];
|
danielebarchiesi@4
|
100 }
|
danielebarchiesi@4
|
101 }
|
danielebarchiesi@4
|
102 if (!empty($translatables)) {
|
danielebarchiesi@4
|
103 $code[] = features_translatables_export($translatables, ' ');
|
danielebarchiesi@4
|
104 }
|
danielebarchiesi@4
|
105
|
danielebarchiesi@4
|
106 $code[] = '';
|
danielebarchiesi@4
|
107 $code[] = ' return $menus;';
|
danielebarchiesi@4
|
108 $code = implode("\n", $code);
|
danielebarchiesi@4
|
109 return array('menu_default_menu_custom' => $code);
|
danielebarchiesi@4
|
110 }
|
danielebarchiesi@4
|
111
|
danielebarchiesi@4
|
112 /**
|
danielebarchiesi@4
|
113 * Implements hook_features_revert().
|
danielebarchiesi@4
|
114 */
|
danielebarchiesi@4
|
115 function menu_custom_features_revert($module) {
|
danielebarchiesi@4
|
116 menu_custom_features_rebuild($module);
|
danielebarchiesi@4
|
117 }
|
danielebarchiesi@4
|
118
|
danielebarchiesi@4
|
119 /**
|
danielebarchiesi@4
|
120 * Implements hook_features_rebuild().
|
danielebarchiesi@4
|
121 */
|
danielebarchiesi@4
|
122 function menu_custom_features_rebuild($module) {
|
danielebarchiesi@4
|
123 if ($defaults = features_get_default('menu_custom', $module)) {
|
danielebarchiesi@4
|
124 foreach ($defaults as $menu) {
|
danielebarchiesi@4
|
125 menu_save($menu);
|
danielebarchiesi@4
|
126 }
|
danielebarchiesi@4
|
127 }
|
danielebarchiesi@4
|
128 }
|
danielebarchiesi@4
|
129
|
danielebarchiesi@4
|
130 /**
|
danielebarchiesi@4
|
131 * Implements hook_features_export_options().
|
danielebarchiesi@4
|
132 */
|
danielebarchiesi@4
|
133 function menu_links_features_export_options() {
|
danielebarchiesi@4
|
134 global $menu_admin;
|
danielebarchiesi@4
|
135 // Need to set this to TRUE in order to get menu links that the
|
danielebarchiesi@4
|
136 // current user may not have access to (i.e. user/login)
|
danielebarchiesi@4
|
137 $menu_admin = TRUE;
|
danielebarchiesi@4
|
138 $use_menus = array_intersect_key(menu_get_menus(), array_flip(array_filter(variable_get('features_admin_menu_links_menus', array_keys(menu_get_menus())))));
|
danielebarchiesi@4
|
139 $menu_links = menu_parent_options($use_menus, array('mlid' => 0));
|
danielebarchiesi@4
|
140 $options = array();
|
danielebarchiesi@4
|
141 foreach ($menu_links as $key => $name) {
|
danielebarchiesi@4
|
142 list($menu_name, $mlid) = explode(':', $key, 2);
|
danielebarchiesi@4
|
143 if ($mlid != 0) {
|
danielebarchiesi@4
|
144 $link = menu_link_load($mlid);
|
danielebarchiesi@4
|
145 $identifier = menu_links_features_identifier($link);
|
danielebarchiesi@4
|
146 $options[$identifier] = "{$menu_name}: {$name}";
|
danielebarchiesi@4
|
147 }
|
danielebarchiesi@4
|
148 }
|
danielebarchiesi@4
|
149 $menu_admin = FALSE;
|
danielebarchiesi@4
|
150 return $options;
|
danielebarchiesi@4
|
151 }
|
danielebarchiesi@4
|
152
|
danielebarchiesi@4
|
153 /**
|
danielebarchiesi@4
|
154 * Callback for generating the menu link exportable identifier.
|
danielebarchiesi@4
|
155 */
|
danielebarchiesi@4
|
156 function menu_links_features_identifier($link) {
|
danielebarchiesi@4
|
157 return isset($link['menu_name'], $link['link_path']) ? "{$link['menu_name']}:{$link['link_path']}" : FALSE;
|
danielebarchiesi@4
|
158 }
|
danielebarchiesi@4
|
159
|
danielebarchiesi@4
|
160 /**
|
danielebarchiesi@4
|
161 * Implements hook_features_export().
|
danielebarchiesi@4
|
162 */
|
danielebarchiesi@4
|
163 function menu_links_features_export($data, &$export, $module_name = '') {
|
danielebarchiesi@4
|
164 // Default hooks are provided by the feature module so we need to add
|
danielebarchiesi@4
|
165 // it as a dependency.
|
danielebarchiesi@4
|
166 $export['dependencies']['features'] = 'features';
|
danielebarchiesi@4
|
167 $export['dependencies']['menu'] = 'menu';
|
danielebarchiesi@4
|
168
|
danielebarchiesi@4
|
169 // Collect a link to module map
|
danielebarchiesi@4
|
170 $pipe = array();
|
danielebarchiesi@4
|
171 $map = features_get_default_map('menu_links', 'menu_links_features_identifier');
|
danielebarchiesi@4
|
172 foreach ($data as $identifier) {
|
danielebarchiesi@4
|
173 if ($link = features_menu_link_load($identifier)) {
|
danielebarchiesi@4
|
174 // If this link is provided by a different module, add it as a dependency.
|
danielebarchiesi@4
|
175 if (isset($map[$identifier]) && $map[$identifier] != $module_name) {
|
danielebarchiesi@4
|
176 $export['dependencies'][$map[$identifier]] = $map[$identifier];
|
danielebarchiesi@4
|
177 }
|
danielebarchiesi@4
|
178 else {
|
danielebarchiesi@4
|
179 $export['features']['menu_links'][$identifier] = $identifier;
|
danielebarchiesi@4
|
180 }
|
danielebarchiesi@4
|
181 // For now, exclude a variety of common menus from automatic export.
|
danielebarchiesi@4
|
182 // They may still be explicitly included in a Feature if the builder
|
danielebarchiesi@4
|
183 // chooses to do so.
|
danielebarchiesi@4
|
184 if (!in_array($link['menu_name'], array('features', 'primary-links', 'secondary-links', 'navigation', 'admin', 'devel'))) {
|
danielebarchiesi@4
|
185 $pipe['menu_custom'][] = $link['menu_name'];
|
danielebarchiesi@4
|
186 }
|
danielebarchiesi@4
|
187 }
|
danielebarchiesi@4
|
188 }
|
danielebarchiesi@4
|
189 return $pipe;
|
danielebarchiesi@4
|
190 }
|
danielebarchiesi@4
|
191
|
danielebarchiesi@4
|
192 /**
|
danielebarchiesi@4
|
193 * Implements hook_features_export_render()
|
danielebarchiesi@4
|
194 */
|
danielebarchiesi@4
|
195 function menu_links_features_export_render($module, $data) {
|
danielebarchiesi@4
|
196 $code = array();
|
danielebarchiesi@4
|
197 $code[] = ' $menu_links = array();';
|
danielebarchiesi@4
|
198 $code[] = '';
|
danielebarchiesi@4
|
199
|
danielebarchiesi@4
|
200 $translatables = array();
|
danielebarchiesi@4
|
201 foreach ($data as $identifier) {
|
danielebarchiesi@4
|
202 if ($link = features_menu_link_load($identifier)) {
|
danielebarchiesi@4
|
203 // Replace plid with a parent path.
|
danielebarchiesi@4
|
204 if (!empty($link['plid']) && $parent = menu_link_load($link['plid'])) {
|
danielebarchiesi@4
|
205 $link['parent_path'] = $parent['link_path'];
|
danielebarchiesi@4
|
206 }
|
danielebarchiesi@4
|
207 unset($link['plid']);
|
danielebarchiesi@4
|
208 unset($link['mlid']);
|
danielebarchiesi@4
|
209
|
danielebarchiesi@4
|
210 $code[] = " // Exported menu link: {$identifier}";
|
danielebarchiesi@4
|
211 $code[] = " \$menu_links['{$identifier}'] = ". features_var_export($link, ' ') .";";
|
danielebarchiesi@4
|
212 $translatables[] = $link['link_title'];
|
danielebarchiesi@4
|
213 }
|
danielebarchiesi@4
|
214 }
|
danielebarchiesi@4
|
215 if (!empty($translatables)) {
|
danielebarchiesi@4
|
216 $code[] = features_translatables_export($translatables, ' ');
|
danielebarchiesi@4
|
217 }
|
danielebarchiesi@4
|
218
|
danielebarchiesi@4
|
219 $code[] = '';
|
danielebarchiesi@4
|
220 $code[] = ' return $menu_links;';
|
danielebarchiesi@4
|
221 $code = implode("\n", $code);
|
danielebarchiesi@4
|
222 return array('menu_default_menu_links' => $code);
|
danielebarchiesi@4
|
223 }
|
danielebarchiesi@4
|
224
|
danielebarchiesi@4
|
225 /**
|
danielebarchiesi@4
|
226 * Implements hook_features_revert().
|
danielebarchiesi@4
|
227 */
|
danielebarchiesi@4
|
228 function menu_links_features_revert($module) {
|
danielebarchiesi@4
|
229 menu_links_features_rebuild($module);
|
danielebarchiesi@4
|
230 }
|
danielebarchiesi@4
|
231
|
danielebarchiesi@4
|
232 /**
|
danielebarchiesi@4
|
233 * Implements hook_features_rebuild().
|
danielebarchiesi@4
|
234 */
|
danielebarchiesi@4
|
235 function menu_links_features_rebuild($module) {
|
danielebarchiesi@4
|
236 if ($menu_links = features_get_default('menu_links', $module)) {
|
danielebarchiesi@4
|
237 menu_links_features_rebuild_ordered($menu_links);
|
danielebarchiesi@4
|
238 }
|
danielebarchiesi@4
|
239 }
|
danielebarchiesi@4
|
240
|
danielebarchiesi@4
|
241 /**
|
danielebarchiesi@4
|
242 * Generate a depth tree of all menu links.
|
danielebarchiesi@4
|
243 */
|
danielebarchiesi@4
|
244 function menu_links_features_rebuild_ordered($menu_links, $reset = FALSE) {
|
danielebarchiesi@4
|
245 static $ordered;
|
danielebarchiesi@4
|
246 static $all_links;
|
danielebarchiesi@4
|
247 if (!isset($ordered) || $reset) {
|
danielebarchiesi@4
|
248 $ordered = array();
|
danielebarchiesi@4
|
249 $unordered = features_get_default('menu_links');
|
danielebarchiesi@4
|
250
|
danielebarchiesi@4
|
251 // Order all links by depth.
|
danielebarchiesi@4
|
252 if ($unordered) {
|
danielebarchiesi@4
|
253 do {
|
danielebarchiesi@4
|
254 $current = count($unordered);
|
danielebarchiesi@4
|
255 foreach ($unordered as $key => $link) {
|
danielebarchiesi@4
|
256 $identifier = menu_links_features_identifier($link);
|
danielebarchiesi@4
|
257 $parent = isset($link['parent_path']) ? "{$link['menu_name']}:{$link['parent_path']}" : '';
|
danielebarchiesi@4
|
258 if (empty($parent)) {
|
danielebarchiesi@4
|
259 $ordered[$identifier] = 0;
|
danielebarchiesi@4
|
260 $all_links[$identifier] = $link;
|
danielebarchiesi@4
|
261 unset($unordered[$key]);
|
danielebarchiesi@4
|
262 }
|
danielebarchiesi@4
|
263 elseif (isset($ordered[$parent])) {
|
danielebarchiesi@4
|
264 $ordered[$identifier] = $ordered[$parent] + 1;
|
danielebarchiesi@4
|
265 $all_links[$identifier] = $link;
|
danielebarchiesi@4
|
266 unset($unordered[$key]);
|
danielebarchiesi@4
|
267 }
|
danielebarchiesi@4
|
268 }
|
danielebarchiesi@4
|
269 } while (count($unordered) < $current);
|
danielebarchiesi@4
|
270 }
|
danielebarchiesi@4
|
271 asort($ordered);
|
danielebarchiesi@4
|
272 }
|
danielebarchiesi@4
|
273
|
danielebarchiesi@4
|
274 // Ensure any default menu items that do not exist are created.
|
danielebarchiesi@4
|
275 foreach (array_keys($ordered) as $identifier) {
|
danielebarchiesi@4
|
276 $link = $all_links[$identifier];
|
danielebarchiesi@4
|
277 $existing = features_menu_link_load($identifier);
|
danielebarchiesi@4
|
278 if (!$existing || in_array($link, $menu_links)) {
|
danielebarchiesi@4
|
279 // Retrieve the mlid if this is an existing item.
|
danielebarchiesi@4
|
280 if ($existing) {
|
danielebarchiesi@4
|
281 $link['mlid'] = $existing['mlid'];
|
danielebarchiesi@4
|
282 }
|
danielebarchiesi@4
|
283 // Retrieve the plid for a parent link.
|
danielebarchiesi@4
|
284 if (!empty($link['parent_path']) && $parent = features_menu_link_load("{$link['menu_name']}:{$link['parent_path']}")) {
|
danielebarchiesi@4
|
285 $link['plid'] = $parent['mlid'];
|
danielebarchiesi@4
|
286 }
|
danielebarchiesi@4
|
287 else {
|
danielebarchiesi@4
|
288 $link['plid'] = 0;
|
danielebarchiesi@4
|
289 }
|
danielebarchiesi@4
|
290 menu_link_save($link);
|
danielebarchiesi@4
|
291 }
|
danielebarchiesi@4
|
292 }
|
danielebarchiesi@4
|
293 }
|
danielebarchiesi@4
|
294
|
danielebarchiesi@4
|
295 /**
|
danielebarchiesi@4
|
296 * Load a menu link by its menu_name:link_path identifier.
|
danielebarchiesi@4
|
297 */
|
danielebarchiesi@4
|
298 function features_menu_link_load($identifier) {
|
danielebarchiesi@4
|
299 list($menu_name, $link_path) = explode(':', $identifier, 2);
|
danielebarchiesi@4
|
300 $link = db_select('menu_links')
|
danielebarchiesi@4
|
301 ->fields('menu_links', array('menu_name', 'mlid', 'plid', 'link_path', 'router_path', 'link_title', 'options', 'module', 'hidden', 'external', 'has_children', 'expanded', 'weight'))
|
danielebarchiesi@4
|
302 ->condition('menu_name', $menu_name)
|
danielebarchiesi@4
|
303 ->condition('link_path', $link_path)
|
danielebarchiesi@4
|
304 ->addTag('features_menu_link')
|
danielebarchiesi@4
|
305 ->execute()
|
danielebarchiesi@4
|
306 ->fetchAssoc();
|
danielebarchiesi@4
|
307 if ($link) {
|
danielebarchiesi@4
|
308 $link['options'] = unserialize($link['options']);
|
danielebarchiesi@4
|
309 return $link;
|
danielebarchiesi@4
|
310 }
|
danielebarchiesi@4
|
311 return FALSE;
|
danielebarchiesi@4
|
312 }
|