Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.15
diff -r1.15 install.inc
351a352,363
>  * Calls the uninstall function and updates the system table for a given module.
>  *
>  * @param module
>  *   The module to install.
>  */
> function drupal_uninstall_module($module) {
>   module_load_install($module);
>   module_invoke($module, 'uninstall');
>   drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED);
> }
> 
> /**
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.82
diff -r1.82 module.inc
106,108c106,107
<     drupal_get_filename('module', $file->name, $file->filename);
<     drupal_load('module', $file->name);
< 
---
>     $file->metadata = module_get_meta_info($file->name, dirname($file->filename));
>     $files[$filename]->metadata = $file->metadata;
120c119
<       db_query("UPDATE {system} SET description = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", $file->description, $file->name, $file->filename, $bootstrap, $file->old_filename);
---
>       db_query("UPDATE {system} SET description = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", $file->metadata['description'], $file->name, $file->filename, $bootstrap, $file->old_filename);
124c123
<       db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $file->description, 'module', $file->filename, $file->status, $file->throttle, $bootstrap);
---
>       db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $file->metadata['description'], 'module', $file->filename, $file->status, $file->throttle, $bootstrap);
129a129,167
> /**
>  * Parse drupal meta file format.
>  *
>  * @param $filename 
>  *   The path to the filename
>  * @return 
>  *   The meta data array
>  */
> function module_parse_meta_file($filename) {
>   $handle = fopen($filename, "r");
>   $meta = fread($handle, filesize($filename));
>   fclose($handle);
>   $metadata = array();    
>   $pattern = '@^\s*((?:[^:/]|/(?!/))+?)\s*:\s*(?:("(?:[^"]|(?<=\\\\)")*")|(\'(?:[^\']|(?<=\\\\)\')*\')|([^\n]*?))\s*($|//)@ms';    
>   if (preg_match_all($pattern, $meta, $matches, PREG_SET_ORDER)) {
>     foreach ($matches as $match) {
>       list(, $key, $value1, $value2, $value3) = $match;
>       $value = stripslashes(trim($value1, '"')) . stripslashes(trim($value2, "'")) . $value3;
>       $metadata[$key] = $value;
>     }
>   } 
>   return $metadata;
> }
>   
> /**
>  * Load the metadata associated with a module.
>  *
>  * @param $module
>  *   The name of the module
>  * @param $path
>  *   The path the module lives in, not including the module name.
>  */
> function module_get_meta_info($module, $path) {
>   $filename = $path .'/'. $module .'.meta';
>   $metadata = array();
>   
>   if (file_exists($filename)) {
>     $metadata = module_parse_meta_file($filename);
>   }
130a169,205
>   // Fill in a bunch of safe defaults.
>   if (!$metadata['package']) {
>     $metadata['package'] = t('Uncategorized');
>   }
>   if (!$metadata['version']) {
>     $metadata['version'] = t('unknown');
>   }
>   if ($metadata['version'] == 'SYSTEM') {
>     $metadata['version'] = VERSION;
>   }
>   if (!$metadata['drupal']) {
>     $metadata['drupal'] = t('undefined');
>   }
>   if (!$metadata['name']) {
>     $metadata['name'] = $module;
>   }
>   if (!$metadata['links']) {
>     $metadata['links'] = array();
>   }
>   else {
>     $metadata['links'] = explode(",", $metadata['links']);
>     $links = array();
>     foreach ($metadata['links'] as $link) {
>       list($link, $destination) = explode('=', $link, 2);
>       $links[] = array('title' => trim($link), 'href' => trim($destination));
>     }
>     $metadata['links'] = $links;
>   }
>   if ($metadata['dependencies']) {
>     $metadata['dependencies'] = explode(',', $metadata['dependencies']);
>   }
>   else {
>     $metadata['dependencies'] = array();
>   }
>   return $metadata;
> }
>  
Index: modules/aggregator/aggregator.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.install,v
retrieving revision 1.5
diff -r1.5 aggregator.install
112a113,123
> 
> /**
>  * Uninstall the aggregator module and drop its tables.
>  */
> function aggregator_uninstall() {
>   db_query("DROP TABLE {aggregator_category}");
>   db_query("DROP TABLE {aggregator_category_feed}");
>   db_query("DROP TABLE {aggregator_category_item}");
>   db_query("DROP TABLE {aggregator_feed}");
>   db_query("DROP TABLE {aggregator_item}");
> }
Index: modules/book/book.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.install,v
retrieving revision 1.5
diff -r1.5 book.install
30a31,35
> 
> function book_uninstall() {
>   db_query("DROP TABLE {book}");
> }
> 
Index: modules/contact/contact.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.install,v
retrieving revision 1.4
diff -r1.4 contact.install
32a33,36
> 
> function contact_uninstall() {
>   db_query("DROP TABLE {contact}");
> }
Index: modules/drupal/drupal.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/drupal/drupal.install,v
retrieving revision 1.4
diff -r1.4 drupal.install
54a55,59
> 
> function drupal_uninstall() {
>   db_query("DROP TABLE {client}");
>   db_query("DROP TABLE {client_system}");
> }
Index: modules/forum/forum.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.install,v
retrieving revision 1.5
diff -r1.5 forum.install
28a29,32
> 
> function forum_uninstall() {
>   db_query("DROP TABLE {forum}");
> }
Index: modules/locale/locale.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.install,v
retrieving revision 1.4
diff -r1.4 locale.install
69a70,75
> 
> function locale_uninstall() {
>   db_query("DROP TABLE {locales_meta}");
>   db_query("DROP TABLE {locales_source}");
>   db_query("DROP TABLE {locales_target}");
> }
Index: modules/poll/poll.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.install,v
retrieving revision 1.6
diff -r1.6 poll.install
65a66,71
> 
> function poll_uninstall() {
>   db_query("DROP TABLE {poll}");
>   db_query("DROP TABLE {poll_votes}");
>   db_query("DROP TABLE {poll_choices}");
> }
Index: modules/profile/profile.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.install,v
retrieving revision 1.6
diff -r1.6 profile.install
65a66,70
> 
> function profile_uninstall() {
>   db_query("DROP TABLE {profile_fields}");
>   db_query("DROP TABLE {profile_values}");
> }
Index: modules/search/search.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.install,v
retrieving revision 1.5
diff -r1.5 search.install
60a61,66
> 
> function search_uninstall() {
>   db_query("DROP TABLE {search_dataset}");
>   db_query("DROP TABLE {search_index}");
>   db_query("DROP TABLE {search_total}");
> }
Index: modules/statistics/statistics.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.install,v
retrieving revision 1.5
diff -r1.5 statistics.install
38a39,42
> 
> function statistics_uninstall() {
>   db_query("DROP TABLE {accesslog}");
> }
Index: modules/system/admin.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/admin.css,v
retrieving revision 1.2
diff -r1.2 admin.css
51a52,91
> 
> /* modules administration */
> 
> .modules-button {
> 	cursor: pointer;
> 	width: 4.5em;
> 	padding: 0px 0px 0px 0px;
> 	font-size: 12px;
> 	font-weight: normal;
> }
> 
> .modules-header{
> 	font-size: 18px;
> 	border: none;
> 	font-weight: normal;
> 	background-color: white;
>   padding-top: 1em;
> }
> 
> .modules-heading {
>    font-size: 13px;
> }
> 
> .modules-operations {
>    font-size: 13px;
>    text-align: right;
> }
> 
> .modules-links, .modules-buttons {
> 	text-align: right;
> } 
> 
> .modules-links {
>   font-size: 90%;
> }
> 
> table.modules-table {
>   width: 100%;
> }
> 
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.348
diff -r1.348 system.module
46,47c46,49
<       return t('<p>Modules are plugins for Drupal that extend its core functionality. Here you can select which modules are enabled. Click on the name of the module in the navigation menu for their individual configuration pages. Once a module is enabled, new <a href="@permissions">permissions</a> might be made available. Modules can automatically be temporarily disabled to reduce server load when your site becomes extremely busy by enabling the throttle.module and checking throttle. The auto-throttle functionality must be enabled on the <a href="@throttle">throttle configuration page</a> after having enabled the throttle module.</p>
< <p>It is important that <a href="@update-php">update.php</a> is run every time a module is updated to a newer version.</p>', array('@permissions' => url('admin/user/access'), '@throttle' => url('admin/settings/throttle'), '@update-php' => $base_url .'/update.php'));
---
>       return t('<p>Modules are plugins for Drupal that extend its core functionality. Here you can see which modules are enabled. Some modules may include links to their administration pages. Once a module is enabled, new <a href="@permissions">permissions</a> might be made available. Modules can automatically be temporarily disabled to reduce server load when your site becomes extremely busy by enabling the throttle.module and visiting the throttle administration pages.</p>
> <p>It is important that <a href="@update-php">update.php</a> is run every time a module is updated to a newer version.</p>', array('@permissions' => url('admin/user/access'), '@update-php' => $base_url .'/update.php'));
>     case 'admin/settings/modules/disabled':
>       return t('<p>Modules are plugins for Drupal that extend its core functionality. Here you can install new modules or re-enable/uninstall previously disabled modules. Once a module is enabled, new <a href="@permissions">permissions</a> might be made available. Note that uninstalled a module will remove that module\'s data from your system, and that this operation is not recoverable! If you are not sure, be sure to make a backup of your database before selecting uninstall!</p>', array('@permissions' => url('admin/user/access')));
188,189c190,191
<       'callback' => 'drupal_get_form',
<       'callback arguments' => array('system_modules'),
---
>       'callback' => 'system_modules',
>       'callback arguments' => array('enabled'),
190a193,205
>     $items[] = array('path' => 'admin/settings/modules/enabled', 
>       'title' => t('enabled'),
>       'callback' => 'system_modules', 
>       'callback arguments' => array('enabled'), 
>       'access' => $access, 
>       'type' => MENU_DEFAULT_LOCAL_TASK, 
>       'weight' => -10);
>     $items[] = array('path' => 'admin/settings/modules/disabled',
>       'title' => t('disabled'),
>       'callback' => 'system_modules', 
>       'callback arguments' => array('disabled'), 
>       'access' => $access, 
>       'type' => MENU_LOCAL_TASK);    
1201a1217,1263
>  * Helper function to reduce code. Provides a form that is a button or two
>  * keyed to the module.
>  */
> function system_module_form($module, $metadata, $type, $type2 = NULL) {
>   $form['submit'] = array(
>     '#type' => 'submit',
>     '#value' => $type,
>     '#attributes' => array('class' => 'modules-button')
>   );
> 
>   $form['submit'] = array(
>     '#type' => 'submit',
>     '#value' => $type,
>     '#attributes' => array('class' => 'modules-button')
>   );
>   
>   $form['metadata'] = array(
>     '#type' => 'value',
>     '#value' => $metadata,
>     '#attributes' => array('class' => 'modules-button')
>   );
>   
>   $form['#submit']['system_module_form_submit'] = array();
> 
>   if ($type2) {
>     $form['submit2'] = array(
>       '#type' => 'submit',
>       '#value' => $type2,
>       '#attributes' => array('class' => 'modules-button')
>     );
>   }
>   return $form;
> }
> 
> function system_forms() {
>   static $forms = array();
>   if (!$forms) {
>     $files = system_listing('\.module$', 'modules', 'name', 0);
>     foreach ($files as $file) {
>       $forms["system_module_form_$file->name"]['callback'] = 'system_module_form';
>     }
>   }
>   return $forms;
> 
> }
> 
> /**
1204c1266
< function system_modules() {
---
> function system_modules($type) {
1206a1269
>   $required = array('block', 'filter', 'node', 'system', 'user', 'watchdog');
1209,1212c1272,1276
<     drupal_get_filename('module', $file->name, $file->filename);
<     drupal_load('module', $file->name);
< 
<     $file->description = module_invoke($file->name, 'help', 'admin/settings/modules#description');
---
>     $metadata = $file->metadata;
>     if (($type == 'enabled' && $file->status) || ($type == 'disabled' && !$file->status)) {
>       $packages[$metadata['package']][] = $file->name;
>       $options[$file->name] = '';
>     }
1214,1216c1278,1280
<     $form['name'][$file->name] = array('#value' => $file->name);
<     $form['description'][$file->name] = array('#value' => $file->description);
<     $options[$file->name] = '';
---
>     $file->description = $metadata['description'];
>  
>     // for later dependency checking.
1218c1282
<       $status[] = $file->name;
---
>       $metadata['enabled'] = true;
1220,1221c1284,1285
<     if ($file->throttle) {
<       $throttle[] = $file->name;
---
>     else if ($file->schema_version != -1) {
>       $metadata['uninstalled'] = true;
1222a1287,1288
>     $metadata['filename'] = $file->filename;
>     $modules[$filename] = $metadata;
1225,1257c1291,1394
<   // Handle status checkboxes, including overriding the generated
<   // checkboxes for required modules.
<   $form['status'] = array('#type' => 'checkboxes', '#default_value' => $status, '#options' => $options);
<   $required = array('block', 'filter', 'node', 'system', 'user', 'watchdog');
<   foreach ($required as $require) {
<     $form['status'][$require] = array('#type' => 'hidden', '#value' => 1, '#suffix' => t('required'));
<   }
< 
<   /**
<    * Handle throttle checkboxes, including overriding the generated checkboxes for required modules.
<    */
<   if (module_exists('throttle')) {
<     $form['throttle'] = array('#type' => 'checkboxes', '#default_value' => $throttle, '#options' => $options);
<     $throttle_required = array_merge($required, array('throttle'));
<     foreach ($throttle_required as $require) {
<       $form['throttle'][$require] = array('#type' => 'hidden', '#value' => 0, '#suffix' => t('required'));
<     }
<   }
< 
<   $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
< 
<   return $form;
< }
< 
< function theme_system_modules($form) {
<   foreach (element_children($form['name']) as $key) {
<     $row = array();
<     $row[] = drupal_render($form['name'][$key]);
<     $row[] = drupal_render($form['description'][$key]);
<     $row[] = array('data' => drupal_render($form['status'][$key]), 'align' => 'center');
< 
<     if (module_exists('throttle')) {
<       $row[] = array('data' => drupal_render($form['throttle'][$key]), 'align' => 'center');
---
>   $top_array = array();
>   // Re-order packages to force core modules to the top.
>   foreach (array(t('Required modules'), t('Drupal core modules')) as $key) {
>     if (is_array($packages[$key])) { 
>       $top_array[$key] = $packages[$key];
>       unset($packages[$key]);
>     }
>   }
>   ksort($packages);
>   $packages = array_merge($top_array, $packages);
> 
>   $header = array(
>     array('data' => t('Name')       , 'header' => TRUE, 'class' => 'modules-heading'),
>     array('data' => t('Version')    , 'header' => TRUE, 'class' => 'modules-heading'),
>     array('data' => t('Description'), 'header' => TRUE, 'class' => 'modules-heading'),
>     array('data' => t('Operations') , 'header' => TRUE, 'class' => 'modules-operations', 'colspan' => 2),
>   );
>        
>   $rows = array();
>   foreach ($packages as $group => $package) {
>     $rows[] = array(
>       array(
>         'colspan' => 4,
>         'header'  => TRUE,
>         'data' => $group,
>         'class' => 'modules-header', 
>       )
>     );
>     $rows[] = $header;
>     foreach ($package as $module) {
>       $modules[$module]['buttons'] = array();
>     
>       // Check for dependencies.
>       $depends = '';
>       $can_change = TRUE;
>       $compatible = strpos(VERSION, $modules[$module]['drupal']) === 0;
>           
>       if (!$modules[$module]['enabled']) {
>         // disabled modules and don't get their links
>         $modules[$module]['links'] = array();
>         foreach ($modules[$module]['dependencies'] as $dependency) {
>           $depends .= (!$depends ? t('Depends on: ') : ', ') ."<em>$dependency</em>";
>           if (!$modules[$dependency]['enabled']) {
>             $depends .= t(' (not present)');
>             $can_change = FALSE;
>           }
>         }
>         if ($can_change&&$compatible) {
>           if ($modules[$module]['uninstalled']) {
>             $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Enable'), t('Uninstall'));
>           } 
>           else {
>             $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Install'));  
>           }
>         }
>         else {
>           if ($modules[$module]['uninstalled']) {
>             $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Uninstall'));
>           } 
>         }
>       }
>       else {
>         // Check for modules that depend on this module.
>         foreach ($modules as $dependency => $module_data) {
>           if (in_array($module, $module_data['dependencies']) && $module_data['enabled']) {
>             $depends .= (!$depends ? t('Required by: ') : ', ') ."<em>$dependency</em>";
>             $can_change = FALSE;
>           }
>         }
>         if ($can_change && !in_array($module, $required)) {
>           $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Disable'));
>         }
>       }
>       $cells = array();
>       $cells[] = $modules[$module]['name'];
>       $cells[] = $modules[$module]['version'];
>       $cells[] = $modules[$module]['description'];
>       $cells[] = array(
>         'data' => theme('links', $modules[$module]['links'], ', '),
>         'class' => 'modules-links',
>       );
>       if ($modules[$module]['buttons']) {
>         $cells[] = array(
>           'data' => implode(' ', $modules[$module]['buttons']),
>           'nowrap' => TRUE,
>           'class' => 'modules-buttons',
>         );
>       }
>       else {
>         $cells[3]['colspan'] = 2;
>       }
>       $rows[] = $cells;
>       if ($depends) {
>         $rows[] = array('', array(
>           'data' => $depends, 
>           'colspan' => 4),
>         );
>       }
>       if (!$compatible) {
>         $rows[] = array('', array(
>           'data' => t('(This module is for Drupal version %version and not compatible with your current version)', array('%version' => $modules[$module]['drupal'])), 
>           'colspan' => 4)
>         );
>       }
1259,1264d1395
<     $rows[] = $row;
<   }
< 
<   $header = array(t('Name'), t('Description'), t('Enabled'));
<   if (module_exists('throttle')) {
<     $header[] = t('Throttle');
1267,1268c1398,1401
<   $output = theme('table', $header, $rows);
<   $output .= drupal_render($form);
---
>   if ($rows) {
>     $output .= theme('table', array(), $rows , array('class' => 'modules-table'));
>   }  
>   
1272,1273c1405,1412
< 
< function system_modules_submit($form_id, $edit) {
---
> /**
>  * Implementation of the module form hook_submit().
>  * @param $form_id
>  *  The id of the form.
>  * @param $form_values
>  *  The values passed back from the client.
>  */
> function system_module_form_submit($form_id, $form_values) {
1275,1284c1414,1423
<   $new_modules = array();
<   foreach ($edit['status'] as $key => $choice) {
<     if ($choice) {
<       if (drupal_get_installed_schema_version($key) == SCHEMA_UNINSTALLED) {
<         $new_modules[] = $key;
<       }
<       else {
<         module_enable($key);
<       }
<     }
---
>   $module = str_replace('system_module_form_', '', $form_id);
>   $metadata = $form_values['metadata'];
> 
>   $op = $_POST['op'];
>   if ($op == t('Install') || $op == t('Enable')) {
>     $status = 1;
>     if ($op == t('Install')) {
>       drupal_install_module($module);
>       drupal_set_message(t('%module installed.', array('%module' => $metadata['name'])));
>     } 
1286c1425,1426
<       module_disable($key);
---
>       module_enable($module);
>       drupal_set_message(t('%module enabled.', array('%module' => $metadata['name'])));
1289,1300c1429,1437
< 
<   module_list(TRUE, FALSE);
< 
<   foreach ($new_modules as $module) {
<     drupal_install_module($module);
<   }
< 
<   if (is_array($edit['throttle'])) {
<     foreach ($edit['throttle'] as $key => $choice) {
<       if ($choice) {
<         db_query("UPDATE {system} SET throttle = 1 WHERE type = 'module' and name = '%s'", $key);
<       }
---
>   else {
>     $status = 0;
>     if ($op == t('Uninstall')) {
>       drupal_uninstall_module($module);
>       drupal_set_message(t('%module uninstalled.', array('%module' => $metadata['name'])));
>     }
>     else {
>       module_disable($module);
>       drupal_set_message(t('%module disabled.', array('%module' => $metadata['name'])));
1305,1308c1442
<   node_types_rebuild();
< 
<   drupal_set_message(t('The configuration options have been saved.'));
<   return 'admin/settings/modules';
---
>   return $_GET['q'];
1311d1444
< 
Index: modules/throttle/throttle.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/throttle/throttle.module,v
retrieving revision 1.65
diff -r1.65 throttle.module
16a17,32
>       'access' => user_access('administer site configuration'),
>       'callback' => 'drupal_get_form',
>       'callback arguments' => array('throttle_admin_modules'),
>       'type' => MENU_NORMAL_ITEM,
>     );
>     $items[] = array(
>       'path' => 'admin/settings/throttle/modules',
>       'title' => t('modules'),
>       'callback' => 'drupal_get_form',
>       'callback arguments' => array('throttle_admin_modules'),
>       'access' => user_access('administer site configuration'),
>       'type' => MENU_DEFAULT_LOCAL_TASK,
>     );
>     $items[] = array(
>       'path' => 'admin/settings/throttle/settings',
>       'title' => t('settings'),
20c36
<       'type' => MENU_NORMAL_ITEM
---
>       'type' => MENU_LOCAL_TASK,
173a190,251
> 
> function throttle_admin_modules() {
>   // Get current list of modules
>   $result = db_query("SELECT * FROM {system} WHERE type = 'module' AND status = 1");
> 
>   $required = array('block', 'filter', 'node', 'system', 'user', 'watchdog', 'throttle');
>   while ($file = db_fetch_object($result)) {
>     if (!in_array($file->name, $required) && file_exists($file->filename)) {
>       $form['name'][$file->name] = array('#value' => $file->name);
>       $form['description'][$file->name] = array('#value' => $file->description);
>       $options[$file->name] = '';
>       $form['original'][$file->name] = array(
>         '#type' => 'value', 
>         '#value' => $file->throttle,
>       );
>       $form['original']['#tree'] = TRUE;
>       if ($file->throttle) {
>         $throttle[] = $file->name;
>       }
>     }
>   }
> 
>   // Handle status checkboxes, including overriding the generated
>   // checkboxes for required modules.
>   $form['throttle'] = array('#type' => 'checkboxes', '#default_value' => $throttle, '#options' => $options);
>   foreach ($throttle_required as $require) {
>     $form['throttle'][$require] = array('#type' => 'hidden', '#value' => 0, '#suffix' => t('required'));
>   }
> 
>   $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
> 
>   return $form;
> }
> 
> function theme_throttle_admin_modules($form) {
>   foreach (element_children($form['name']) as $key) {
>     $row = array();
>     $row[] = drupal_render($form['name'][$key]);
>     $row[] = drupal_render($form['description'][$key]);
>     $row[] = array('data' => drupal_render($form['throttle'][$key]), 'align' => 'center');
>     $rows[] = $row;
>   }
> 
>   $header = array(t('Name'), t('Description'), t('Throttle'));
> 
>   $output = theme('table', $header, $rows);
>   $output .= drupal_render($form);
>   return $output;
> }
> 
> function throttle_admin_modules_submit($form_id, $edit) {
>   foreach ($edit['throttle'] as $key => $choice) {
>     if ($choice && !$edit['original'][$key]) {
>       db_query("UPDATE {system} SET throttle = 1 WHERE type = 'module' and name = '%s'", $key);
>     }
>     else if (!$choice && $edit['original'][$key]) {
>       db_query("UPDATE {system} SET throttle = 0 WHERE type = 'module' and name = '%s'", $key);
>     }
>   }
>   
>   drupal_set_message(t('The configuration has been saved.'));
> }
