Issue #1029606: don't try to forcefully remove menu links in drupal_uninstall_modules(), it breaks uninstallation and is completely useless. From: Damien Tournoud --- includes/install.inc | 42 +++++++++++------------------------------ includes/menu.inc | 5 +++++ modules/system/system.install | 32 ++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/includes/install.inc b/includes/install.inc index 14b5d7e..e145da8 100644 --- a/includes/install.inc +++ b/includes/install.inc @@ -782,45 +782,25 @@ function drupal_uninstall_modules($module_list = array(), $uninstall_dependents } foreach ($module_list as $module) { - // First, retrieve all the module's menu paths from db. - drupal_load('module', $module); - $paths = module_invoke($module, 'menu'); - // Uninstall the module. module_load_install($module); module_invoke($module, 'uninstall'); drupal_uninstall_schema($module); + drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED); watchdog('system', '%module module uninstalled.', array('%module' => $module), WATCHDOG_INFO); - // Now remove the menu links for all paths declared by this module. - if (!empty($paths)) { - $paths = array_keys($paths); - // Clean out the names of load functions. - foreach ($paths as $index => $path) { - $parts = explode('/', $path, MENU_MAX_PARTS); - foreach ($parts as $k => $part) { - if (preg_match('/^%[a-z_]*$/', $part)) { - $parts[$k] = '%'; - } - } - $paths[$index] = implode('/', $parts); - } - - $result = db_select('menu_links') - ->fields('menu_links') - ->condition('router_path', $paths, 'IN') - ->condition('external', 0) - ->orderBy('depth') - ->execute(); - // Remove all such items. Starting from those with the greatest depth will - // minimize the amount of re-parenting done by menu_link_delete(). - foreach ($result as $item) { - _menu_delete_item($item, TRUE); - } + // Now remove the remaining menu links declared by this module. + $result = db_select('menu_links') + ->fields('menu_links') + ->condition('original_module', $module) + ->orderBy('depth') + ->execute(); + // Remove all such items. Starting from those with the greatest depth will + // minimize the amount of re-parenting done by menu_link_delete(). + foreach ($result as $item) { + _menu_delete_item($item, TRUE); } - - drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED); } if (!empty($module_list)) { diff --git a/includes/menu.inc b/includes/menu.inc index f424122..8847d22 100644 --- a/includes/menu.inc +++ b/includes/menu.inc @@ -2672,6 +2672,8 @@ function _menu_link_build($item) { } // Note, we set this as 'system', so that we can be sure to distinguish all // the menu links generated automatically from entries in {menu_router}. + // We save the name of the original module separately. + $item['original_module'] = $item['module']; $item['module'] = 'system'; $item += array( 'menu_name' => 'navigation', @@ -2939,6 +2941,7 @@ function menu_link_save(&$item) { 'expanded' => 0, 'options' => array(), 'module' => 'menu', + 'original_module' => '', 'customized' => 0, 'updated' => 0, ); @@ -2973,6 +2976,7 @@ function menu_link_save(&$item) { 'expanded' => $item['expanded'], 'weight' => $item['weight'], 'module' => $item['module'], + 'original_module' => $item['original_module'], 'link_title' => $item['link_title'], 'options' => serialize($item['options']), 'customized' => $item['customized'], @@ -3047,6 +3051,7 @@ function menu_link_save(&$item) { 'p8' => $item['p8'], 'p9' => $item['p9'], 'module' => $item['module'], + 'original_module' => $item['original_module'], 'link_title' => $item['link_title'], 'options' => serialize($item['options']), 'customized' => $item['customized'], diff --git a/modules/system/system.install b/modules/system/system.install index af02edc..87d17d0 100644 --- a/modules/system/system.install +++ b/modules/system/system.install @@ -1188,12 +1188,19 @@ function system_schema() { 'translatable' => TRUE, ), 'module' => array( - 'description' => 'The name of the module that generated this link.', + 'description' => 'The name of the module that manages this link.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => 'system', ), + 'original_module' => array( + 'description' => 'The name of the module this link was generated for, in case it is different.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), 'hidden' => array( 'description' => 'A flag for whether the link should be rendered in menus. (1 = a disabled menu item that may be shown on admin screens, -1 = a menu callback, 0 = a normal, visible link)', 'type' => 'int', @@ -2973,5 +2980,28 @@ function system_update_7069() { /** * @} End of "defgroup updates-6.x-to-7.x" + */ + +/** + * @defgroup updates-7.x-extra Extra updates for 7.x + * @{ + */ + +/** + * Add a {menu_links}.original_module column to keep track of the source of menu links. + */ +function system_update_7070() { + $spec = array( + 'description' => 'The name of the module this link was generated for, in case it is different.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ); + db_add_field('menu_links', 'original_module', $spec); +} + +/** + * @} End of "defgroup updates-7.x-extra" * The next series of updates should start at 8000. */