diff --git modules/system/system.admin.inc modules/system/system.admin.inc
index 82eef0a..3919810 100644
--- modules/system/system.admin.inc
+++ modules/system/system.admin.inc
@@ -570,11 +570,44 @@ function _system_is_incompatible(&$incompatible, $files, $file) {
* The form array.
*/
function system_modules($form_state = array()) {
- // Clear all caches.
- registry_rebuild();
- drupal_theme_rebuild();
- node_types_rebuild();
- cache_clear_all('schema', 'cache');
+ drupal_add_js(drupal_get_path('module', 'system') . '/system.js');
+ drupal_add_js('misc/vertical-tabs.js', array('weight' => 0));
+ drupal_add_css('misc/vertical-tabs.css');
+
+ // Clear all caches, but not when searching the modules page to save time.
+ if (!isset($form_state['storage']['search_string'])) {
+ registry_rebuild();
+ drupal_theme_rebuild();
+ node_types_rebuild();
+ cache_clear_all('schema', 'cache');
+ }
+
+ // Fieldset to search the modules form.
+ $form['search'] = array(
+ '#type' => 'fieldset',
+ '#weight' => -5,
+ '#collapsible' => FALSE,
+ '#title' => t('Search modules'),
+ );
+
+ $form['search']['search_string'] = array(
+ '#type' => 'textfield',
+ );
+
+ $form['search']['search_submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Search'),
+ '#submit' => array('system_modules_search_submit'),
+ '#ahah' => array(
+ 'callback' => 'system_modules_search_js',
+ 'wrapper' => 'edit-modules-search-pane',
+ 'method' => 'replace',
+ 'success_callback' => 'moduleFormSearch',
+ 'keypress' => TRUE,
+ 'event' => 'click',
+ ),
+ );
+
// Get current list of modules.
$files = module_rebuild_cache();
@@ -591,17 +624,129 @@ function system_modules($form_state = array()) {
// and if there are unfilled required modules, then form_state['storage'] is
// filled, triggering a rebuild. In this case we need to display a
// confirmation form.
- if (!empty($form_state['storage'])) {
+ if (!empty($form_state['storage']) && empty($form_state['storage']['search_string'])) {
return system_modules_confirm_form($files, $form_state['storage']);
}
$modules = array();
- $form['modules'] = array('#tree' => TRUE);
+ $form['modules'] = array(
+ '#tree' => TRUE,
+ '#prefix' => '
',
+ '#suffix' => '
',
+ );
+
+ // Add dependencies and additional information to the files array.
+ $files = _system_modules_build_files_for_form($files);
+
+ // If the search button was clicked, add the search fieldset with matching modules.
+ if (!empty($form_state['storage']['search_string'])) {
+ $form['modules']['search_pane'] = _system_modules_search_form($files, $form_state['storage']['search_string']);
+ }
+ // Otherwise, add all modules, with a fieldset for each category.
+ else {
+ // Iterate through each of the modules.
+ foreach ($files as $filename => $module) {
+ $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $module->extra);
+ }
+
+ // Add basic information to the fieldsets.
+ foreach (element_children($form['modules']) as $package) {
+ $form['modules'][$package] += array(
+ '#type' => 'fieldset',
+ '#title' => t($package),
+ '#theme' => 'system_modules_fieldset',
+ '#header' => array(
+ array('data' => t('Enabled'), 'class' => 'checkbox'),
+ t('Name'),
+ t('Version'),
+ t('Description'),
+ ),
+ );
+ }
+ }
+
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Save configuration'),
+ );
+ $form['#action'] = url('admin/build/modules/list/confirm');
+
+ return $form;
+}
+
+/**
+ * Submit callback for the search button on the modules form.
+ *
+ * If a search string is present, store it in $form_state['storage'].
+ */
+function system_modules_search_submit($form, &$form_state) {
+ if (!empty($form_state['values']['search_string'])) {
+ $form_state['storage']['search_string'] = $form_state['values']['search_string'];
+ }
+ else {
+ unset($form_state['storage']['search_string']);
+ }
+}
+
+/**
+ * AHAH callback for the search button on the modules form.
+ */
+function system_modules_search_js($form, &$form_state) {
+ $search_form = $form['modules']['search_pane'];
+ drupal_json(array('status' => TRUE, 'data' => drupal_render($search_form)));
+}
+
+/**
+ * Creates the search result fieldset for the modules form.
+ *
+ * This returns a fieldset similar to the normal module category fieldsets,
+ * but containing modules whose names or descriptions match $search_string.
+ */
+function _system_modules_search_form($files, $search_string) {
+ $search_form = array(
+ '#type' => 'fieldset',
+ '#weight' => 9999,
+ '#title' => t('Search results'),
+ );
+
+ // Iterate over the module files, and add rows for matching names or
+ // descriptions.
+ foreach ($files as $filename => $module) {
+ if (stripos($module->info['name'], $search_string) !== FALSE ||
+ stripos($module->info['description'], $search_string) !== FALSE ||
+ stripos($module->filename, $search_string) !== FALSE) {
+ $search_form[$filename] = _system_modules_build_row($module->info, $module->extra);
+ }
+ }
+
+ if (element_children($search_form)) {
+ $search_form += array(
+ '#theme' => 'system_modules_fieldset',
+ '#header' => array(
+ array('data' => t('Enabled'), 'class' => 'checkbox'),
+ t('Name'),
+ t('Version'),
+ t('Description'),
+ ),
+ );
+ }
+ else {
+ $search_form['info']['#markup'] = t('Your search did not return any results.');
+ }
+ return $search_form;
+}
+
+/**
+ * Add information to the module files array that is needed on the modules form.
+ *
+ * Iterates over the module files and adds dependency information to be used
+ * in the modules form.
+ */
+function _system_modules_build_files_for_form($files) {
// Used when checking if module implements a help page.
$help_arg = module_exists('help') ? drupal_help_arg() : FALSE;
- // Iterate through each of the modules.
foreach ($files as $filename => $module) {
$extra = array();
$extra['enabled'] = (bool) $module->status;
@@ -641,31 +786,9 @@ function system_modules($form_state = array()) {
}
}
}
- $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $extra);
+ $files[$filename]->extra = $extra;
}
- // Add basic information to the fieldsets.
- foreach (element_children($form['modules']) as $package) {
- $form['modules'][$package] += array(
- '#type' => 'fieldset',
- '#title' => t($package),
- '#collapsible' => TRUE,
- '#theme' => 'system_modules_fieldset',
- '#header' => array(
- array('data' => t('Enabled'), 'class' => 'checkbox'),
- t('Name'),
- t('Version'),
- t('Description'),
- ),
- );
- }
-
- $form['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Save configuration'),
- );
- $form['#action'] = url('admin/build/modules/list/confirm');
-
- return $form;
+ return $files;
}
/**
@@ -800,7 +923,7 @@ function system_modules_submit($form, &$form_state) {
include_once DRUPAL_ROOT . '/includes/install.inc';
$modules = array();
// If we're not coming from the confirmation form, build the list of modules.
- if (!isset($form_state['storage'])) {
+ if (!isset($form_state['storage']['modules'])) {
foreach ($form_state['values']['modules'] as $group_name => $group) {
foreach ($group as $module => $enabled) {
$modules[$module] = array('group' => $group_name, 'enabled' => $enabled['enable']);
@@ -812,7 +935,6 @@ function system_modules_submit($form, &$form_state) {
// the modules out of $form_state.
$modules = $form_state['storage']['modules'];
}
-
// Get a list of all modules, it will be used to find which module requires
// which.
$files = module_rebuild_cache();
diff --git modules/system/system.js modules/system/system.js
index 9ff6c08..a922708 100644
--- modules/system/system.js
+++ modules/system/system.js
@@ -134,4 +134,37 @@ Drupal.behaviors.poweredByPreview = {
}
};
+/**
+ * AHAH success callback for the search button on the modules form.
+ *
+ * If no search fieldset is present, this inserts the search fieldset into
+ * the form and adds a vertical tab for it. If there is already a search fieldset,
+ * it is replaced by the new one.
+ */
+Drupal.ahah.prototype.successCallbacks.moduleFormSearch = function(element, response, status) {
+ new_content = $(response.data);
+
+ // Check if there is already a search tab present, and if so, remove it.
+ if ($('#edit-modules-search-pane').size()) {
+ $('#edit-modules-search-pane').data('verticalTab').item.remove();
+ $('#edit-modules-search-pane').remove();
+ }
+ // Append the search fieldset to the wrapper and add a vertical tab for it.
+ $('#modules-form-wrapper').append(new_content);
+ var list = new_content.parents().find('.vertical-tabs-panes').siblings('ul.vertical-tabs-list');
+ var tab = new Drupal.verticalTab({ title: $('> legend', new_content).text(), fieldset: $(new_content) });
+ list.append(tab.item);
+ new_content
+ .data('verticalTab', tab)
+ .find('input, textarea, select')
+ .change(function() {
+ tab.updateDescription();
+ });
+
+ // Give the search tab the focus.
+ $(new_content).data('verticalTab').focus();
+
+ Drupal.attachBehaviors(new_content);
+}
+
})(jQuery);
\ No newline at end of file