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