'. t('Drupal assigns each module a weight. For most operations involving any module that defines a particular hook, the modules are invoked in order first by weight, then by name.') .'

'; $output .= '

'. t('This module adds a weight column to the modules table at !modules, allowing weights to be viewed and edited. Once activated, a weight column appears on the modules table. To change a module weight, edit its value and press "Save configuration". Any user who can submit the !modules form will be able to change module weights.', array('!modules' => l('admin/build/modules', 'admin/build/modules'))) .'

'; break; } return $output; } function module_weights_menu() { $menu['admin/settings/util/module_weights'] = array( 'title' => 'Module Weights', 'description' => 'Module weight information.', 'page callback' => 'drupal_get_form', 'page arguments' => array('module_weights_settings'), 'access arguments' => array('administer site configuration'), 'type' => MENU_LOCAL_TASK, ); return $menu; } /** * Add weight header. */ function module_weights_system_module_headers_alter(&$header) { array_unshift($header, 'Weight'); } function module_weights_system_module_weights_alter(&$row, $module, &$form) { array_unshift($row, drupal_render($form['weights'][$module])); // CLEANUP what we added in hook_form_alter(). unset($form['weights'][$module]); } /** * Helper function to fetch and cache module weights. */ function fetch_module_weights($name = NULL) { static $module_weights = array(); if (empty($module_weights)) { $query = "SELECT filename, name, type, owner, status, throttle, bootstrap, schema_version, weight FROM {system} WHERE type = 'module' ORDER BY name"; $result = db_query($query); while ($row = db_fetch_object($result)) { // When a module is deleted, it remains in the system table. // If module has been deleted, omit it from the list. if (file_exists($row->filename)) { $module_weights[$row->name] = $row->weight; } else { // Do we want a warning? if (variable_get('module_weights_warning', 0)) { if ($row->status) { drupal_set_message(t('@name module file (@file) could not be found, but is still marked as "enabled!"', array('@name' => $row->name, '@file' => $row->filename)), 'warning'); } else { drupal_set_message(t('@name module file (@file) could not be found.', array('@name' => $row->name, '@file' => $row->filename))); } } } } } if ($name === NULL) { return $module_weights; } elseif (isset($module_weights[$name])) { return $module_weights[$name]; } else { return NULL; } } function module_weights_form_alter(&$form, $form_state, $form_id) { switch ($form_id) { // The admin modules page. case 'system_modules': if (!empty($form['description']['system_module'])) { $weights = fetch_module_weights(); $form['weights'] = array('#tree' => TRUE); foreach ($weights as $name => $weight) { // We add "w_" to the name so as not to upset system module. $form['description'][$name]['weights']["w_$name"] = array( '#type' => 'textfield', '#default_value' => $weight, '#title' => t('Module weight'), '#size' => 4, '#prefix' => '
', '#suffix' => '
', ); } // Do my #submit before system.module's so all the rebuilding // operations in system_module_submit use the new weights. array_unshift($form['#submit'], 'module_weights_system_module_submit'); $form['#validate'][] = 'module_weights_system_module_validate'; } break; } } function module_weights_system_module_validate($form, &$form_state) { $weights = fetch_module_weights(); foreach ($weights as $name => $weight) { // Submitted weights must be numeric. $found = $form_state['values']["w_$name"]; if (!is_numeric($found)) { form_set_error("weights][w_{$name}", t('The !module module weight must be a number (found "@found").', array('!module' => $name, '@found' => $found)) ); } } } function module_weights_system_module_submit($form, &$form_state) { foreach ($form_state['values'] as $key => $weight) { // Extra step of optimization, update only weights that changed // also skip on module names that don't match our record in fetch_module_weights(). if (drupal_substr($key, 0, 2) == 'w_') { $name = drupal_substr($key, 2); $module_weight = fetch_module_weights($name); if ($module_weight !== NULL && $module_weight != $weight) { $query = "UPDATE {system} SET weight = %d WHERE name LIKE '%s'"; db_query($query, (int) $weight, $name); } } } } function module_weights_settings() { drupal_add_css(drupal_get_path('module', 'module_weights') .'/module_weights.css'); $form = array(); $form['module_weights_warning'] = array( '#type' => 'radios', '#options' => array(0 => t('None'), 1 => t('Verbose')), '#default_value' => variable_get('module_weights_warning', 0), '#title' => t('Missing module warning'), '#description' => t('If a module file cannot be found, would you like a warning to be issued?'), ); $weighted = $missing = array(); $header = array(t('Module'), t('Weight')); $result = db_query("SELECT name, weight, filename, status FROM {system} WHERE TYPE = 'module' ORDER BY name"); while ($row = db_fetch_object($result)) { if (!file_exists($row->filename)) { $desc = $row->name; if ($row->status) { drupal_set_message(t('@name module file (@file) could not be found, but is still marked as "enabled!"', array('@name' => $row->name, '@file' => $row->filename)), 'warning'); $desc .= '*'; } $missing[] = $desc; } if ($row->weight != 0) { $weighted[] = array( $row->name, array('data' => $row->weight, 'align' => 'right'), ); } } if ($missing) { if (module_exists('system_table_cleaner')) { $desc = t('These module files could not be found and mess up the modules administration page. The system table needs to be cleaned up.', array('!url' => url('admin/settings/systems-table-cleaner'))); } else { $desc = t('These module files could not be found and mess up the modules administration page. The system table needs to be cleaned up. The System Table Cleaner module can be used for this.', array('!url' => 'http://drupal.org/project/system_table_cleaner')); } $form['missing'] = array( '#type' => 'fieldset', '#title' => t('Missing module files'), '#description' => $desc, '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['missing']['list'] = array( '#type' => 'markup', '#value' => theme('item_list', $missing), ); } $form['weights'] = array( '#type' => 'fieldset', '#title' => t('Weighted modules'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['weights']['list'] = array( '#type' => 'markup', '#value' => theme('table', $header, $weighted, array('style' => 'width: auto;')), ); return system_settings_form($form); }