Index: webform_hooks.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform_hooks.php,v
retrieving revision 1.7
diff -u -r1.7 webform_hooks.php
--- webform_hooks.php	7 Feb 2010 01:36:23 -0000	1.7
+++ webform_hooks.php	10 Feb 2010 01:41:33 -0000
@@ -89,6 +89,62 @@
 }
 
 /**
+ * Modify a loaded Webform component.
+ *
+ * IMPORTANT: This hook does not actually exist because components are loaded
+ * in bulk as part of webform_node_load(). Use hook_nodeapi() to modify loaded
+ * components when the node is loaded. This example is provided merely to point
+ * to hook_nodeapi().
+ *
+ * @see hook_nodeapi()
+ * @see webform_node_load()
+ */
+function hook_webform_component_load() {
+  // This hook does not exist. Instead use hook_nodeapi().
+}
+
+/**
+ * Modify a Webform component before it is saved to the database.
+ *
+ * Note that most of the time this hook is not necessary, because Webform will
+ * automatically add data to the component based on the component form. Using
+ * hook_form_alter() will be sufficient in most cases.
+ *
+ * @see hook_form_alter()
+ * @see webform_component_edit_form()
+ *
+ * @param $component
+ *   The Webform component being saved.
+ */
+function hook_webform_component_presave(&$component) {
+  $component['extra']['new_option'] = 'foo';
+}
+
+/**
+ * Respond to a Webform component being inserted into the database.
+ */
+function hook_webform_component_insert($component) {
+  // Insert a record into a 3rd-party module table when a component is inserted.
+  db_query("INSERT INTO {mymodule_table} (nid, cid) VALUES (%d, %d)", $component['nid'], $component['sid']);
+}
+
+/**
+ * Respond to a Webform component being updated in the database.
+ */
+function hook_webform_component_update($component) {
+  // Update a record in a 3rd-party module table when a component is updated.
+  db_query('UPDATE {mymodule_table} SET value "%s" WHERE nid = %d AND cid = %d)', 'foo', $component['nid'], $component['sid']);
+}
+
+/**
+ * Respond to a Webform component being deleted.
+ */
+function hook_webform_component_delete($component) {
+  // Update a record in a 3rd-party module table when a component is updated.
+  db_query('DELETE FROM {mymodule_table} WHERE nid = %d AND cid = %d)', $component['nid'], $component['sid']);
+}
+
+/**
  * Define components to Webform.
  *
  * @return
Index: includes/webform.components.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.components.inc,v
retrieving revision 1.21
diff -u -r1.21 webform.components.inc
--- includes/webform.components.inc	9 Feb 2010 06:29:30 -0000	1.21
+++ includes/webform.components.inc	10 Feb 2010 01:41:33 -0000
@@ -615,12 +615,22 @@
  *   A full component containing fields from the component form.
  */
 function webform_component_insert(&$component) {
+  // Allow modules to modify the component before saving.
+  foreach (module_implements('webform_component_presave') as $module) {
+    $function = $module . '_webform_component_presave';
+    $function($component);
+  }
+
   db_lock_table('webform_component');
   $component['cid'] = isset($component['cid']) ? $component['cid'] : db_result(db_query('SELECT MAX(cid) FROM {webform_component} WHERE nid = %d', $component['nid'])) + 1;
   $component['value'] = isset($component['value']) ? $component['value'] : NULL;
   $component['mandatory'] = isset($component['mandatory']) ? $component['mandatory'] : 0;
   db_query("INSERT INTO {webform_component} (nid, cid, pid, form_key, name, type, value, extra, mandatory, weight) VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d)", $component['nid'], $component['cid'], $component['pid'], $component['form_key'], $component['name'], $component['type'], $component['value'], serialize($component['extra']), $component['mandatory'], $component['weight']);
   db_unlock_tables();
+
+  // Post-insert actions.
+  module_invoke_all('webform_component_insert', $component);
+
   return $component['cid'];
 }
 
@@ -632,9 +642,20 @@
  *   component form. Additional properties are stored in the extra array.
  */
 function webform_component_update($component) {
+  // Allow modules to modify the component before saving.
+  foreach (module_implements('webform_component_presave') as $module) {
+    $function = $module . '_webform_component_presave';
+    $function($component);
+  }
+
   $component['value'] = isset($component['value']) ? $component['value'] : NULL;
   $component['mandatory'] = isset($component['mandatory']) ? $component['mandatory'] : 0;
-  return db_query("UPDATE {webform_component} SET pid = %d, form_key = '%s', name = '%s', type = '%s', value = '%s', extra = '%s', mandatory = %d, weight = %d WHERE nid = %d AND cid = %d", $component['pid'], $component['form_key'], $component['name'], $component['type'], $component['value'], serialize($component['extra']), $component['mandatory'], $component['weight'], $component['nid'], $component['cid']);
+  $success = db_query("UPDATE {webform_component} SET pid = %d, form_key = '%s', name = '%s', type = '%s', value = '%s', extra = '%s', mandatory = %d, weight = %d WHERE nid = %d AND cid = %d", $component['pid'], $component['form_key'], $component['name'], $component['type'], $component['value'], serialize($component['extra']), $component['mandatory'], $component['weight'], $component['nid'], $component['cid']);
+
+  // Post-update actions.
+  module_invoke_all('webform_component_update', $component);
+
+  return $success;
 }
 
 function webform_component_delete($node, $component) {
@@ -663,6 +684,9 @@
     $component = $node->webform['components'][$row->cid];
     webform_component_delete($node, $component);
   }
+
+  // Post-delete actions.
+  module_invoke_all('webform_component_delete', $component);
 }
 
 /**
