=== modified file 'includes/module.inc' --- includes/module.inc 2007-11-30 09:16:02 +0000 +++ includes/module.inc 2007-12-08 15:52:56 +0000 @@ -147,6 +147,7 @@ function module_rebuild_cache() { db_query("INSERT INTO {system} (name, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, serialize($files[$filename]->info), 'module', $file->filename, 0, 0, $bootstrap); } } + $files = _module_build_dependencies($files); $files = _module_build_dependents($files); return $files; } @@ -174,6 +175,46 @@ function _module_build_dependents($files return $files; } +function _module_build_dependencies($files) { + do { + $new_dependency = FALSE; + foreach ($files as $filename => $file) { + $file = &$files[$filename]; + if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { + foreach ($file->info['dependencies'] as $dependency_name) { + // This is a nonexistent module. + if ($dependency_name == '-circular-') { + continue; + } + $dependency = $files[$dependency_name]; + if (isset($dependency->info['dependencies']) && is_array($dependency->info['dependencies'])) { + foreach ($dependency->info['dependencies'] as $candidate) { + if (array_search($candidate, $file->info['dependencies']) === FALSE) { + if ($candidate == $filename) { + // As a module name can not contain dashes, this makes + // impossible to switch on the module. + $candidate = '-circular-'; + // Do not display the message or add -circular- more than once. + if (array_search($candidate, $file->info['dependencies']) !== FALSE) { + continue; + } + drupal_set_message(t('%module is part of a circular dependency. This is not supported and you will not be able to switch it on.', array('%module' => $file->info['name'])), 'error'); + } + else { + $new_dependency = TRUE; + } + $file->info['dependencies'][] = $candidate; + } + } + } + } + } + unset($file); + } + } while ($new_dependency); + return $files; +} + /** * Determine whether a given module exists. * @@ -240,6 +281,23 @@ function module_load_all_includes($type, * An array of module names. */ function module_enable($module_list) { + $files = module_rebuild_cache(); + do { + $moved = FALSE; + foreach ($module_list as $key => $module) { + $done[$module] = TRUE; + $file = $files[$module]; + if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { + foreach ($file->info['dependencies'] as $dependency) { + if (!isset($done[$dependency])) { + unset($module_list[$key]); + $module_list[] = $module; + $moved = TRUE; + } + } + } + } + } while ($moved); $invoke_modules = array(); foreach ($module_list as $module) { $existing = db_fetch_object(db_query("SELECT status FROM {system} WHERE type = '%s' AND name = '%s'", 'module', $module)); === modified file 'modules/system/system.admin.inc' --- modules/system/system.admin.inc 2007-12-08 14:06:20 +0000 +++ modules/system/system.admin.inc 2007-12-08 15:23:50 +0000 @@ -535,6 +535,12 @@ function system_theme_settings_submit($f * Recursively check compatability */ function _system_is_incompatible(&$incompatible, $files, $file) { + static $seen; + // We need to protect ourselves in case of a circular dependency. + if (isset($seen[$file->name])) { + return isset($incompatible[$file->name]); + } + $seen[$file->name] = TRUE; if (isset($incompatible[$file->name])) { return TRUE; }