Index: signup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.module,v
retrieving revision 1.205.2.32
diff -u -p -r1.205.2.32 signup.module
--- signup.module	16 Sep 2009 00:42:57 -0000	1.205.2.32
+++ signup.module	18 Sep 2009 23:30:08 -0000
@@ -975,11 +975,41 @@ function signup_load_signup($sid) {
  *
  * @param $signup
  *   Fully-loaded signup object to save.
+ * @param $is_new
+ *   Boolean to indicate that the record is a new signup.
+ *
+ * @return
+ *   The return value from drupal_write_record().
  *
  * @see signup_load_signup()
+ * @see drupal_write_record()
  */
-function signup_save_signup($signup) {
-  drupal_write_record('signup_log', $signup, array('sid'));
+function signup_save_signup(&$signup, $is_new = FALSE) {
+  $rval = FALSE;
+  if (is_array($signup->form_data)) {
+    $form_data_array = $signup->form_data;
+    $signup->form_data = serialize($form_data_array);
+  }
+  if ($is_new) {
+    $rval = drupal_write_record('signup_log', $signup);
+  }
+  else {
+    $rval = drupal_write_record('signup_log', $signup, 'sid');
+  }
+  if (isset($form_data_array)) {
+    $signup->form_data = $form_data_array;
+  }
+  if (!empty($rval)) {
+    if ($is_new) {
+      // Invoke hook_signup_create() to inform modules of the new signup.
+      module_invoke_all('signup_create', $signup);
+    }
+    else {
+      // Invoke hook_signup_update() to inform modules of the updated signup.
+      module_invoke_all('signup_update', $signup);
+    }
+  }
+  return $rval;
 }
 
 /**
@@ -1196,28 +1226,33 @@ function signup_sign_up_user($signup_for
     if (!empty($extra)) {
       $signup_info = array_merge($signup_info, $extra);
     }
-    $signup_form_data = serialize($signup_info);
 
     // Figure out if confirmation or reminder emails will be sent and
     // inform the user.
     $confirmation_email = $node->signup_send_confirmation ? '  '. t('A confirmation email will be sent shortly containing further information about this %node_type.', array('%node_type' => node_get_types('name', $node->type))) : '';
     $reminder_email = $node->signup_send_reminder ? '  '. t('A reminder email will be sent !number !days before the %node_type.', array('!number' => $node->signup_reminder_days_before, '!days' => format_plural($node->signup_reminder_days_before, 'day', 'days'), '%node_type' => node_get_types('name', $node->type))) : '';
 
-    // Insert the user into the signup_log.
-    db_query("INSERT INTO {signup_log} (uid, nid, anon_mail, signup_time, form_data) VALUES (%d, %d, '%s', %d, '%s')", $signup_form['uid'], $signup_form['nid'], $signup_anon_mail, $current_time, $signup_form_data);
-    $sid = db_last_insert_id('signup_log', 'sid');
-
-    // Get the hard-coded tokens provided by the signup module to use
-    // for the confirmation and/or forwarding emails.  We need to create
-    // an object representing the user's signup to get the right values.
-    $signup = $user;
+    // Construct the appropriate $signup object representing this signup.
+    $signup = new stdClass;
+    $signup->nid = $node->nid;
+    // Grab the values from the $user object we care about
+    foreach (array('uid', 'name', 'mail') as $field) {
+      $signup->$field = $user->$field;
+    }
+    // Other special signup values.
     $signup->form_data = $signup_info;
-    $signup->sid = $sid;
     $signup->signup_time = $current_time;
-    if (!empty($signup_anon_mail)) {
-      $signup->anon_mail = $signup_anon_mail;
+    if (!empty($signup_form['anon_mail'])) {
+      $signup->anon_mail = $signup_form['anon_mail'];
     }
 
+    // Invoke hook_signup_data_alter() to let other modules change this.
+    drupal_alter('signup_data', $signup, $signup_form);
+
+    // Insert the signup into the {signup_log} table. Since this is a new
+    // signup, we need to pass TRUE for the second argument.
+    signup_save_signup($signup, TRUE);
+
     // See if we should generate any notifications from this signup.
     if ($notify_user) {
       // Confirmation e-mail to the user who signed up.
@@ -1236,7 +1271,7 @@ function signup_sign_up_user($signup_for
     if ($node->signup_close_signup_limit) {
       _signup_check_limit($node, 'total');
     }
-    return $sid;
+    return $signup->sid;
   }
   else {
     drupal_access_denied();
Index: signup.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.api.php,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 signup.api.php
--- signup.api.php	25 Jul 2009 21:28:40 -0000	1.1.2.2
+++ signup.api.php	18 Sep 2009 23:30:09 -0000
@@ -8,6 +8,18 @@
  */
 
 /**
+ * Hook to alter signup data before a signup is created or updated.
+ *
+ * @param $signup
+ *   Reference to the fully-loaded signup object representing the signup.
+ * @param $form_values
+ *   Array of form values (if any) from the signup being created or updated.
+ */
+function hook_signup_data_alter(&$signup, $form_values) {
+  // TODO
+}
+
+/**
  * Hook invoked when a signup is being canceled.
  *
  * At the time this hook is invoked the record about the signup in the
@@ -41,6 +53,25 @@ function hook_signup_cancel($signup, $no
   drupal_set_message(theme('item_list', $info, t('Signup canceled for %node_title', array('%node_title' => $node->title))));
 }
 
+/**
+ * Hook invoked after a signup has been created.
+ *
+ * @param $signup
+ *   The fully-loaded signup object representing the new signup.
+ */
+function hook_signup_create($signup) {
+  // TODO
+}
+
+/**
+ * Hook invoked after a signup has been updated.
+ *
+ * @param $signup
+ *   The fully-loaded signup object representing the updated signup.
+ */
+function hook_signup_update($signup) {
+  // TODO
+}
 
 /**
  * Hook invoked when a signup is being created to gather other signup data.
Index: includes/signup_edit_form.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/signup_edit_form.inc,v
retrieving revision 1.1.2.5
diff -u -p -r1.1.2.5 signup_edit_form.inc
--- includes/signup_edit_form.inc	2 Mar 2009 17:25:51 -0000	1.1.2.5
+++ includes/signup_edit_form.inc	18 Sep 2009 23:30:09 -0000
@@ -143,35 +143,39 @@ function signup_validate_anon_mail($form
  * Submit callback when saving changes to an existing signup.
  */
 function signup_edit_form_save_submit($form, $form_state) {
-  $signup_info = array();
+  $signup = $form['#signup'];
   if (!empty($form_state['values']['signup_form_data'])) {
-    $signup_info = $form_state['values']['signup_form_data'];
+    $signup->form_data = $form_state['values']['signup_form_data'];
   }
-  $values[] = "form_data = '%s'";
-  $args[] = serialize($signup_info);
 
   // If the form contains an e-mail address for an anonymous signup, save it.
   if (!empty($form_state['values']['signup_anon_mail'])) {
-    $values[] = "anon_mail = '%s'";
-    $args[] = $form_state['values']['signup_anon_mail'];
+    $signup->anon_mail = $form_state['values']['signup_anon_mail'];
   }
 
   // If the form contains attendance info, save it.
   if (isset($form_state['values']['attended'])) {
     if ($form_state['values']['attended'] == -1) {
-      $values[] = "attended = NULL";
+      unset($signup->attended);
     }
     else {
-      $values[] = "attended = %d";
-      $args[] = $form_state['values']['attended'];
+      $signup->attended = $form_state['values']['attended'];
     }
   }
 
-  /// @TODO invoke a hook?
-  /// @TODO should we have a "signup_update_time" field and update that, too?
-  $updates = implode(', ', $values);
-  $args[] = $form['#signup']->sid;
-  db_query("UPDATE {signup_log} SET $updates WHERE sid = %d", $args);
+  // Invoke hook_signup_data_alter() to let other modules change this.
+  drupal_alter('signup_data', $signup, $form_state['values']);
+
+  // Update the signup in the {signup_log} table.
+  signup_save_signup($signup);
+
+  // Because drupal_write_record() doesn't gracefully handle columns that can
+  // be NULL, if the attendence was cleared out by this edit, we need to
+  // manually set the DB record to NULL here.
+  if (!isset($signup->attended)) {
+    db_query("UPDATE {signup_log} SET attended = NULL WHERE sid = %d", $signup->sid);
+  }
+
   drupal_set_message(t('Signup information updated.'));
 }
 
