Important menu properties lost on import/export
Dave Reid - July 10, 2009 - 22:09
| Project: | Node Export |
| Version: | 6.x-2.x-dev |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Dave Reid |
| Status: | closed |
Description
I was working on importing and exporting some nodes that had disabled menu items. The export code for those nodes was created as:
'menu' => array(
'link_title' => 'Disabled Menu',
'mlid' => 0,
'plid' => '1',
'menu_name' => 'primary-links',
'weight' => '0',
'options' => array(),
'module' => 'menu',
'expanded' => 0,
'hidden' => 0,
'has_children' => 0,
'customized' => 0,
'parent_depth_limit' => 8,
),In this case, the menu link should actually have hidden = 1 since that represents a disabled link. Some other important things that don't get saved properly are expanded, has_children. Maybe customized and options?
After a little more review, it looks like if people have selected the "Import settings into node form first", this will not work since the menu settings will be lost (no fields for hidden, etc on the node edit form). However, if someone has selected the "Save as a new node then edit" it should work.

#1
Patch attached for review. Note that this is not compatible with PHP 4 or 5.0.* because of the use of array_intersect_key, but it should be easy enough to fiddle with to work on PHP 4.
#2
Hmm does this cause any problems if you only export a single node from the menu heirarchy?
I'd rather rewrite it to use foreach or something if there are going to be compatibility issues.
#3
I've updated the function like so, hope this is satisfactory.
<?php
/**
* Create a new menu entry with title, parent and weight exported from
* another nodes menu. Returns NULL if the node has no menu title.
*/
function node_export_get_menu($node) {
// This will fetch the existing menu item if the node had one.
node_invoke_nodeapi($node, 'prepare');
// Only keep the values we care about.
if (!empty($node->menu)) {
// Store a copy of the old menu
$old_menu = $node->menu;
// Now fetch the defaults for a new menu entry.
$node = NULL;
node_invoke_nodeapi($node, 'prepare');
// Make a list of values to attempt to copy.
$menu_fields = array(
'link_title', 'plid', 'menu_name', 'weight', // These should import properly always.
'hidden', 'expanded', 'has_children', // These will only import properly on 'Save as a new node then edit' imports.
);
// Copy those fields from the old menu over the new menu defaults.
foreach ($menu_fields as $menu_field) {
$node->menu[$menu_field] = $old_menu[$menu_field];
}
// Return the menu.
return $node->menu;
}
}
?>
#4
Automatically closed -- issue fixed for 2 weeks with no activity.