Index: uc_signup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_signup/uc_signup.module,v
retrieving revision 1.36
diff -u -p -r1.36 uc_signup.module
--- uc_signup.module	7 Sep 2009 15:57:32 -0000	1.36
+++ uc_signup.module	7 Sep 2009 18:41:30 -0000
@@ -332,8 +332,9 @@ function uc_signup_form_alter(&$form, &$
       if ($add_cart_text != '') {
         $form['submit']['#value'] = t($add_cart_text);
         $node = $form['#parameters'][2];
-        if (($node->signup_close_signup_limit && $node->signup_total >= $node->signup_close_signup_limit) || !$node->signup_status) {
-          $form['submit']['#value'] = t(variable_get('uc_signup_signups_closed_text', "Signups are closed for this event."));
+        _uc_signup_node_available($node, 0 , $message);
+        if ($message) {
+          $form['submit']['#value'] = $message;
           $form['submit']['#disabled'] = TRUE;
           if (isset($form['qty'])) {
             $form['qty']['#disabled'] = TRUE;
@@ -368,9 +369,10 @@ function uc_signup_cart_view_form_submit
 }
 
 function uc_signup_product_add_to_cart_form_validate($form, &$form_state) {
-  $spots_remaining = uc_signup_spots_remaining($form_state['values']);
-  if ($form_state['values']['qty'] > $spots_remaining) {
-    form_set_error('qty', _uc_signup_limit_reached_message($spots_remaining, $form_state['values']));
+  $node = node_load($form_state['values']['nid']);
+  _uc_signup_node_available($node, $form_state['values']['qty'], $message);
+  if ($message) {
+    form_set_error('qty', $message);
   }
 }
 
@@ -378,35 +380,17 @@ function uc_signup_cart_view_form_valida
   if (!empty($form_state['values']['items'])) {
     foreach ($form_state['values']['items'] as $key => $item) {
       $data = unserialize($item['data']);
-      if (empty($form_state['values']['items'][$key]['remove']) && isset($data['uc_signup_enabled']) && $data['uc_signup_enabled'] == 1) {
-        $spots_remaining = uc_signup_spots_remaining($item);
-        if ($item['qty'] > $spots_remaining) {
-            form_set_error("items][$key][qty", _uc_signup_limit_reached_message($spots_remaining, $item));
+      if (!($form_state['values']['items'][$key]['remove'] == 1 || $form_state['values']['items'][$key]['qty'] == 0) && isset($data['uc_signup_enabled']) && $data['uc_signup_enabled'] == 1) {
+        $node = node_load($item['nid']);
+        _uc_signup_node_available($node, $item['qty'], $message);
+        if ($message) {
+          form_set_error("items][$key][qty", $message);
         }
       }
     }
   }
 }
 
-function _uc_signup_limit_reached_message($spots_remaining, $node) {
-  if (is_array($node)) {
-    $nid = $node['nid'];
-  }
-  else {
-    $nid = $node->nid;
-  }
-  if ($spots_remaining > 0) {
-    $only= 'only ';
-  }
-  $node = db_fetch_object(db_query("SELECT title, type from {node} WHERE nid = %d", $nid));
-  return t("We're sorry, but there @is $only@available @spot left for the @type %title.", array(
-           '@is' => format_plural($spots_remaining, "is", "are"),
-           '@spot' => format_plural($spots_remaining, "spot", "spots"),
-           '@available' => $spots_remaining,
-           '@type' => $node->type,
-           '%title' => $node->title
-         ));
-}
 
 /*
  * Implementation of hook_ca_predicate().
@@ -590,6 +574,7 @@ function uc_signup_order($op, &$arg1, $a
         }
       }
       if (!empty($events_to_signup)) {
+        //Clear any existing placeholder signups before proceeding.
         uc_signup_cancel_temporary_signups($order);
         foreach ($_SESSION['uc_signup']['nids'] as $nid => $attendees) {
           foreach ($attendees as $key => $mail) {
@@ -617,26 +602,16 @@ function uc_signup_order($op, &$arg1, $a
             $to_signup[$nid][] = $account->uid;
           }
         }
-        // First, create accounts for emails that don't have accounts.
-        $placeholders = '';
-        global $user;
-        // TODO: check if there are any signups to create.
-        //Make sure that there are enough spots before continuing. If there are not enough spots, the order should fail.
-
-        foreach ($to_signup as $nid => $value) {
-          $spots_remaining = uc_signup_spots_remaining(array('nid' => $nid)); 
-          if (count($to_signup[$nid]) > $spots_remaining) {
-            $insufficient_space[] = $nid;
-            $message .= _uc_signup_limit_reached_message($spots_remaining, array('nid' => $nid));
-          }
-          if (!empty($insufficient_space)) {
-            $message .= t("Events can fill up rapidly, and people may have signed up since you added these events to your cart. Please adjust the quantity before checking out.");
+        unset($nid);
+        foreach ($to_signup as $nid => $uids) {
+          //Perform the final verification that the node is available for signups in the desired quantity.
+          //Note that we do not pass the quantity in order to avoid our own placeholder signups from counting against the number of available spots.
+          $node = node_load($nid);
+          _uc_signup_node_available($node, 0, $message);
+          if ($message) {
             uc_signup_cancel_temporary_signups($order);
             return array(array('pass' => FALSE, 'message' => t($message)));
           }
-        }
-        unset($nid);
-        foreach ($to_signup as $nid => $uids) {
           foreach ($uids as $key => $uid) {
             $signup_form = array(
               'nid' => $nid,
@@ -653,30 +628,33 @@ function uc_signup_order($op, &$arg1, $a
   }
 }
 
-function uc_signup_spots_remaining($node) {
-  if (is_array($node)) {
-    $result = db_fetch_array(db_query("SELECT s.close_signup_limit, COUNT(sl.sid) AS signup_total FROM {signup} s LEFT JOIN {signup_log} sl ON s.nid=sl.nid WHERE s.nid = %d GROUP BY s.nid DESC", $node['nid']));
-
-    if ($result['close_signup_limit'] != 0) {
-      $spots_remaining = $result['close_signup_limit'] - $result['signup_total'];
-      return $spots_remaining;
-    }
-    else {
-      //I lie awake at night awaiting the bug report that this value is not sufficiently large.
-      return 9999999999;
-    }
-  }
 
-  else {
-    if ($node->close_signup_limit != 0) {
-      $spots_remaining = $node->close_signup_limit - $node->$signup_total;
-      return $spots_remaining;
+function _uc_signup_node_available($node, $qty, &$message) {
+  $type_name = db_result(db_query("SELECT name from {node_type} WHERE type = '%s'", $node->type));
+
+  if (!$node->signup_status) {
+    $message = t(variable_get('uc_signup_signups_closed_text', "Signups are closed for this event."));
+  }
+  if (_signup_node_completed($node)) {
+    $message = t("We're sorry, but the @type %title has already passed.", array('@type' => $type_name, '%title' => $node->title));
+  }
+  if ($node->signup_close_signup_limit !=0) {
+    $spots_remaining = $node->signup_close_signup_limit - $node->signup_total;
+    if ($spots_remaining > 0) {
+      $only = 'only ';
     }
-    else {
-      return 9999999999;
+    if ($spots_remaining < $qty) {
+      $message = t("We're sorry, but there @is $only@available @spot left for the @type %title.", array(
+        '@is' => format_plural($spots_remaining, "is", "are"),
+        '@spot' => format_plural($spots_remaining, "spot", "spots"),
+        '@available' => $spots_remaining,
+        '@type' => $type_name,
+        '%title' => $node->title
+      ));
     }
   }
 }
+
 function uc_signup_settings_form() {
   $form['uc_signup_add_cart_text'] = array(
     '#type' => 'textfield',
