? form_controller.api.php
? form_controller.css
? form_controller.js
Index: form.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/form/form.module,v
retrieving revision 1.5
diff -u -p -r1.5 form.module
--- form.module	8 Dec 2009 04:38:01 -0000	1.5
+++ form.module	13 Dec 2009 18:54:47 -0000
@@ -91,15 +91,15 @@ function form_form(&$form_state, $form_b
   )));
 
   $form = array();
-  $alterations = module_invoke_all('form_info');
-  foreach ($alterations as $name => $info) {
+  $form_info = form_get_info();
+  foreach ($form_info as $key => $info) {
     // Fetch configuration form.
     // @todo Take over configuration storage for most/simple implementations.
-    if (isset($info['form callback']) && function_exists($info['form callback'])) {
-      $function = $info['form callback'];
+    $function = $info['form callback'];
+    if ($function && function_exists($function)) {
       $settings = $function($form, $form_id, $context);
       if (isset($settings) && is_array($settings)) {
-        $form[$name] = array(
+        $form[$key] = array(
           '#type' => 'fieldset',
           '#title' => check_plain($info['title']),
           '#description' => check_plain($info['description']),
@@ -107,7 +107,7 @@ function form_form(&$form_state, $form_b
           //'#collapsed' => TRUE,
           '#tree' => TRUE,
         );
-        $form[$name] += $settings;
+        $form[$key] += $settings;
       }
     }
   }
@@ -174,9 +174,10 @@ function form_process_form(&$element, $e
   $form_state['form'] = $context;
 
   // @todo Cache this.
-  foreach (module_invoke_all('form_info') as $name => $info) {
-    if (!empty($info['process callback']) && function_exists($info['process callback'])) {
-      $function = $info['process callback'];
+  $form_info = form_get_info();
+  foreach ($form_info as $info) {
+    $function = $info['process callback'];
+    if ($function && function_exists($function)) {
       $function($element, $form_state, $form_id, $form_elements);
     }
   }
@@ -184,6 +185,42 @@ function form_process_form(&$element, $e
   // return $element;
 }
 
+/**
+ * Returns information about forms registered via hook_form_info().
+ *
+ * @param $reset
+ *   (optional) Boolean whether to reset the static cache and do nothing. Only
+ *   used for tests.
+ *
+ * @todo Actually cache this info using cache_set()?
+ */
+function form_get_info($reset = FALSE) {
+  static $form_info;
+
+  if ($reset) {
+    $form_info = NULL;
+    return;
+  }
+
+  if (!isset($form_info)) {
+    $form_info = module_invoke_all('form_info');
+
+    // Merge default values into each info.
+    foreach ($form_info as $key => $info) {
+      $form_info[$key] += array(
+        'process callback' => FALSE,
+        'form callback' => FALSE,
+      );
+    }
+
+    // Allow modules to alter the default form information.
+    drupal_alter('form_info', $form_info);
+  }
+
+  return $form_info;
+}
+
+
 function form_get_value($form_state, $parents) {
   $values = $form_state['values'];
   foreach ($parents as $parent) {
