? signup-DRUPAL-6--1.patch
? signup.patch
? ~signup-DRUPAL-6--1.patch
Index: signup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.module,v
retrieving revision 1.205.2.36
diff -u -p -r1.205.2.36 signup.module
--- signup.module	8 Oct 2009 00:01:29 -0000	1.205.2.36
+++ signup.module	9 Oct 2009 21:48:46 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: signup.module,v 1.205.2.36 2009/10/08 00:01:29 dww Exp $
+// $Id: signup.module,v 1.205.2.34 2009/09/19 01:42:58 dww Exp $
 
 
 /**
@@ -201,6 +201,7 @@ function signup_cron() {
   module_load_include('inc', 'signup', 'includes/cron');
   _signup_initialize_scheduler_backend();
   _signup_cron_send_reminders();
+  _signup_cron_autoopen();
   _signup_cron_autoclose();
 }
 
@@ -238,6 +239,9 @@ function _signup_build_query($common_sql
   if (!empty($full_sql['group_by'])) {
     $sql .= ' GROUP BY '. implode(', ', $full_sql['group_by']);
   }
+  if (!empty($full_sql['having'])) {
+    $sql .= ' HAVING '. implode(', ', $full_sql['having']);
+  }
   return $sql;
 }
 
@@ -764,6 +768,8 @@ function signup_nodeapi(&$node, $op, $te
         $node->signup_reminder_email = $signup->reminder_email;
         $node->signup_close_signup_limit = $signup->close_signup_limit;
         $node->signup_status = $signup->status;
+		$node->signup_open_at = $signup->open_at;
+		$node->signup_close_at = $signup->close_at;
         if ($node->nid) {
           $node->signup_total = db_result(db_query("SELECT COUNT(*) FROM {signup_log} WHERE nid = %d", $node->nid));
           $node->signup_effective_total = db_result(db_query("SELECT SUM(count_towards_limit) FROM {signup_log} WHERE nid = %d", $node->nid));
@@ -1252,8 +1258,6 @@ function signup_sign_up_user($signup_for
     // Other special signup values.
     $signup->form_data = $signup_info;
     $signup->signup_time = $current_time;
-    // By default, signups should count towards the limit.
-    $signup->count_towards_total = 1;
     if (!empty($signup_anon_mail)) {
       $signup->anon_mail = $signup_anon_mail;
     }
@@ -1706,7 +1710,6 @@ function signup_token_list($type) {
       'signup-email' => t('The e-mail address for the signup (either anonymous or authenticated).'),
       'signup-anonymous-email' => t('The e-mail addressed entered for an anonymous signup, or an empty string if an authenticated user signed up.'),
       'signup-attendence' => t('If the user attended the thing they signed up for.'),
-      'signup-id' => t('Site-wide numeric identifier for the signup.'),
     );
   }
   return $tokens;
@@ -1758,7 +1761,7 @@ function signup_token_values($type = 'al
     $values['signup-anonymous-email'] = !empty($object->anon_mail) ? $object->anon_mail : '';
     $attended = isset($signup->attended) ? $signup->attended : NULL;
     $values['signup-attendence'] = check_plain(theme('signup_attended_text', $attended));
-    $values['signup-id'] = $object->sid;
+
   }
   return $values;
 }
Index: includes/admin.settings.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/admin.settings.inc,v
retrieving revision 1.2.2.5
diff -u -p -r1.2.2.5 admin.settings.inc
--- includes/admin.settings.inc	24 Jan 2009 08:52:46 -0000	1.2.2.5
+++ includes/admin.settings.inc	9 Oct 2009 21:48:46 -0000
@@ -13,10 +13,17 @@
 function signup_settings_form() {
   module_load_include('inc', 'signup', 'includes/node_settings');
   if (signup_site_has_dates()) {
-    $form['signup_close_early'] = array(
+    $form['signup_open_before'] = array(
+      '#title' => t('Open x hours before start'),
+      '#type' => 'textfield',
+      '#default_value' => variable_get('signup_open_before', 100),
+      '#size' => 5, '#maxlength' => 10,
+      '#description' => t('The number of hours before the event which signups will begin. Use negative numbers to open signups after the event start (example: -12).'),
+    );
+    $form['signup_close_before'] = array(
       '#title' => t('Close x hours before'),
       '#type' => 'textfield',
-      '#default_value' => variable_get('signup_close_early', 1),
+      '#default_value' => variable_get('signup_close_before', 1),
       '#size' => 5, '#maxlength' => 10,
       '#description' => t('The number of hours before the event which signups will no longer be allowed. Use negative numbers to close signups after the event start (example: -12).'),
     );
Index: includes/cron.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/cron.inc,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 cron.inc
--- includes/cron.inc	14 Aug 2009 23:26:10 -0000	1.1.2.2
+++ includes/cron.inc	9 Oct 2009 21:48:46 -0000
@@ -79,49 +79,77 @@ function _signup_cron_send_reminders() {
 /**
  * Helper function that handles auto-closing time-based nodes during cron.
  *
- * Loops over all the node types that are signup-enabled.  For each one, it
- * invokes the method for the installed event/date backend module to get the
- * right query fragments, and builds a query to find all nodes of that type
- * where signups should be closed (e.g. events that already started, etc).
+ * Determine current time in UTC and fetch all open signup enabled nodes with a signup close time before current UTC time.
+ * Requires Date API or PHP5.2+
  *
  * @see signup_cron()
- * @see signup_autoclose_sql()
+ * @see _signup_cron_autoopen()
  * @see _signup_build_query()
  */
 function _signup_cron_autoclose() {
-  $type_autoclose_sql = array();
-  foreach (signup_content_types() as $type) {
-    $type_sql = signup_autoclose_sql($type);
-    if (!empty($type_sql)) {
-      $type_autoclose_sql[$type] = $type_sql;
-    }
-  }
-  if (empty($type_autoclose_sql)) {
-    // No node types support auto-close, so bail out now.
-    return;
-  }
 
-  $autoclose_common_sql = array(
+  // Get current time in UTC for comparison. If Date_API is unavailable, use PHP5.2's functions.
+  $current_time = function_exists(date_make_date) ? date_format(date_make_date('now', 'UTC'),DATE_FORMAT_DATETIME) : date_format(date_create('now',timezone_open('UTC')),'Y-m-d H:i:s');
+  
+  
+  $autoclose_sql = array(
     'primary' => '{node} n',
     'fields' => array('n.nid', 'n.type'),
-    'where' => array('s.status = 1', "n.type = '%s'"),
+    'where' => array('s.status = 1', "s.close_at <= '$current_time'", "s.close_at > '0000-00-00 00:00:00'"),
     'joins' => array('INNER JOIN {signup} s ON s.nid = n.nid'),
   );
 
-  foreach ($type_autoclose_sql as $type => $autoclose_sql) {
-    $sql = _signup_build_query($autoclose_common_sql, $autoclose_sql);
-    $result = db_query($sql, $type);
-
-    // Loop through the results, calling the signup closing function.
-    while ($signup = db_fetch_object($result)) {
-      signup_close_signup($signup->nid, $cron = 'yes');
-      $node = node_load($signup->nid);
-      foreach (module_implements('signup_close') as $module) {
-        $function = $module .'_signup_close';
-        $function($node);
-      }
-      watchdog('signup', 'Signups closed for %title by cron.', array('%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
+  $sql = _signup_build_query($autoclose_sql, array());
+  $result = db_query($sql, $type);
+
+  // Loop through the results, calling the signup closing function.
+  while ($signup = db_fetch_object($result)) {
+    signup_close_signup($signup->nid, $cron = 'yes');
+	$node = node_load($nid);
+    foreach (module_implements('signup_close') as $module) {
+      $function = $module .'_signup_close';
+      $function($node);
     }
+    watchdog('signup', 'Signups closed for %title by cron.', array('%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
   }
 }
 
+/**
+ * Helper function that handles auto-opening time-based nodes during cron.
+ *
+ * Determine current time in UTC and fetch all closed signup enabled nodes with a signup open time before current UTC time.
+ * Requires Date API or PHP5.2+
+ *
+ * @see signup_cron()
+ * @see _signup_cron_autoclose()
+ * @see _signup_build_query()
+ */
+function _signup_cron_autoopen() {
+
+  // Get current time in UTC for comparison. If Date_API is unavailable, use PHP5.2's functions.
+  $current_time = function_exists(date_make_date) ? date_format(date_make_date('now', 'UTC'),DATE_FORMAT_DATETIME) : date_format(date_create('now',timezone_open('UTC')),'Y-m-d H:i:s');
+  
+  
+  $autoopen_sql = array(
+    'primary' => '{node} n',
+    'fields' => array('n.nid', 'n.type'),
+    'where' => array('s.status = 0', "s.open_at <= '$current_time'", "s.close_at > '$current_time'", "s.open_at > '0000-00-00 00:00:00'", "s.close_at > '0000-00-00 00:00:00'"),
+	'having' => array("SUM(l.count_towards_limit) < s.close_signup_limit"),
+    'joins' => array('INNER JOIN {signup} s ON s.nid = n.nid','INNER JOIN {signup_log} l ON l.nid = s.nid'),
+	'group_by' => array('s.close_signup_limit'),
+  );
+
+  $sql = _signup_build_query($autoopen_sql, array());
+  $result = db_query($sql, $type);
+
+  // Loop through the results, calling the signup closing function.
+  while ($signup = db_fetch_object($result)) {
+    signup_open_signup($signup->nid, $cron = 'yes');
+    $node = node_load($nid);
+    foreach (module_implements('signup_open') as $module) {
+      $function = $module .'_signup_open';
+      $function($node);
+    }
+    watchdog('signup', 'Signups opened for %title by cron.', array('%title' => $node->title), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
+  }
+}
Index: includes/date.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/date.inc,v
retrieving revision 1.16.2.4
diff -u -p -r1.16.2.4 date.inc
--- includes/date.inc	4 Mar 2009 19:19:34 -0000	1.16.2.4
+++ includes/date.inc	9 Oct 2009 21:48:46 -0000
@@ -549,3 +549,93 @@ function _signup_date_format_date($node,
   return $date_out;
 }
 
+/**
+ * Collect the start time of the event
+ *
+ * A similar function for event.module based nodes will be required.
+ * A parameter should be added to allow returned time for different timezones.
+ *
+ * @param $node
+ *   The node to return the start time for
+ * @return $date
+ *   The start time for the signup enabled event. Returns as UTC time.
+ */
+ 
+function _signup_node_start_at(&$node) {
+  // Get the date field information for this content type.
+  $field = signup_date_field($node->type);
+  #$start_field = $field['database']['columns']['value']['column'];
+  #var_dump($field);
+  
+  
+  // Grab whatever date value we actually have, regardless of format.
+  $date_value = $node->{$field['field_name']}[0]['value'];
+  // Figure out the timezone handling for this date.
+  if ($field['tz_handling'] == 'date') {
+    $tz = $node->{$field['field_name']}[0]['timezone'];
+  }
+  else {
+    $tz = date_default_timezone_name();
+  }
+  $db_tz = date_get_timezone_db($field['tz_handling'], $tz);
+  // Create a date object
+  $date = date_make_date($date_value, $db_tz, $field['type']);
+  // Make sure the date object is going to print UTC values.
+  date_timezone_set($date, timezone_open('UTC'));
+  
+  date_format($date,DATE_DATETIME);
+  
+  return $date;
+}
+
+/**
+ * Get the timezone to display with the time field of this node.
+ *
+ * A similar function for event.module based nodes will be required.
+ *
+ * @param $node
+ *   The node to return the timezone for
+ * @return $timezone
+ *   The string timezone for the signup enabled node.
+ */
+ 
+function _signup_node_timezone(&$node) {
+  // Get the date field information for this content type.
+  $field = signup_date_field($node->type);
+  
+  $tz = date_get_timezone($field['tz_handling']);
+  
+  return $tz;
+}
+
+/**
+ * Format a time for the database and do timezone conversion.
+ *
+ * A similar function for event.module based nodes will be required.
+ *
+ * @param $time
+ *   The datetime that is to be stored in the database. 
+ * @param $node
+ *   The node to convert and format for.
+ * @param $timezone
+ *   The timezone for the input time. Defaults to UTC.
+ * @return $time
+ *   The formatted time ready to be stored in the database.
+ */
+ 
+function _signup_time_db_format($time, &$node, $timezone = 'UTC') {
+  // Get the date field information for this content type.
+  $field = signup_date_field($node->type);
+  
+  //Create the DateTime object with correct time, timezone and format.
+  $date = date_make_date($time, $timezone, $field['type']);
+  
+  //Convert to the timezone used for the database.
+  #$timezone = $field['timezone_db']; //is this better?
+  $timezone = date_get_timezone_db($field['tz_handling']);
+  date_timezone_set($date, timezone_open($timezone));
+  
+  $date = date_format_date($date, 'custom', date_type_format($field['database']['columns']['value']['type']));
+  
+  return $date;
+}
Index: includes/node_form.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/node_form.inc,v
retrieving revision 1.4.2.2
diff -u -p -r1.4.2.2 node_form.inc
--- includes/node_form.inc	16 Sep 2009 00:42:57 -0000	1.4.2.2
+++ includes/node_form.inc	9 Oct 2009 21:48:46 -0000
@@ -63,14 +63,28 @@ function signup_save_node($node, $op) {
       $needs_defaults = empty($has_record);
     }
   }
+  //Needs the time information from the full node, so loading of the full node is now done before loading of defaults.
+  $node = node_load($node->nid); 
   
   if ($needs_defaults) {
     $values = db_fetch_array(db_query("SELECT forwarding_email, send_confirmation, confirmation_email, close_signup_limit, send_reminder, reminder_days_before, reminder_email FROM {signup} WHERE nid = 0"));
-    $values[] = $node->nid;
-    db_query("INSERT INTO {signup} (forwarding_email, send_confirmation, confirmation_email, close_signup_limit, send_reminder, reminder_days_before, reminder_email, nid) VALUES ('%s', %d, '%s', %d, %d, %d, '%s', %d)", $values);
+    
+    // Get the date field information for this content type.
+    $field = signup_date_field($node->type);
+	
+	//Calculate open and close time for signups.
+	$open_at = _signup_node_start_at($node);
+	$close_at = _signup_node_start_at($node);
+	date_modify($open_at, '-'.variable_get('signup_open_before',100).'hours');
+	date_modify($close_at, '-'.variable_get('signup_close_before', 1).'hours');
+	$values['open_at'] = _signup_time_db_format(date_format_date($open_at, 'custom', DATE_FORMAT_DATETIME), $node, date_get_timezone_db($field['tz_handling']));
+	$values['close_at'] = _signup_time_db_format(date_format_date($close_at, 'custom', DATE_FORMAT_DATETIME), $node, date_get_timezone_db($field['tz_handling']));
+	$values[] = $node->nid;
+	
+    db_query("INSERT INTO {signup} (forwarding_email, send_confirmation, confirmation_email, close_signup_limit, send_reminder, reminder_days_before, reminder_email, open_at, close_at, nid) VALUES ('%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s', %d)", $values);
   }
 
-  $node = node_load($node->nid);
+
   if (_signup_node_completed($node) && !empty($node->signup_status)) {
     // If this is an time-based node, and it's already past the close in
     // advance time (e.g. someone just changed the node start time), and
Index: includes/node_settings.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/node_settings.inc,v
retrieving revision 1.1.2.4
diff -u -p -r1.1.2.4 node_settings.inc
--- includes/node_settings.inc	21 Sep 2009 05:23:09 -0000	1.1.2.4
+++ includes/node_settings.inc	9 Oct 2009 21:48:46 -0000
@@ -29,6 +29,8 @@
  *
  */
 function signup_node_settings_form($form_state, $node = NULL, $node_type = NULL, $has_date = FALSE, $include_buttons = FALSE) {
+  
+  
   if (module_exists('token')) {
     $signup_token_description = t('Supported string substitutions: %node_title, %node_url, %node_start_time, %user_name, %user_mail, %user_signup_info (additional information from the signup form), %cancel_signup_url (access to this link is denied to users without the "%cancel_own_signups" permission), and any tokens in the %replacement_tokens list.', array('%replacement_tokens' => t('Replacement tokens'), '%cancel_own_signups' => t('cancel own signups')));
   }
@@ -47,7 +49,7 @@ function signup_node_settings_form($form
     $node->signup_reminder_email = $result->reminder_email;
     $node->signup_close_signup_limit = $result->close_signup_limit;
   }
-
+  
   $form['signup_forwarding_email'] = array(
     '#type' => 'textfield',
     '#title' => t('Send signups to'),
@@ -73,7 +75,41 @@ function signup_node_settings_form($form
   }
 
   if ($has_date) {
-    // Define a sub-tree to wrap the next 2 form elements together in an
+	if ($node->nid) {
+      // Get the date field information for this content type.
+      #$field = signup_date_field($node->type);
+      #$node_start_time = date_create($node->$field['field_name']['value']);
+	  $timezone = _signup_node_timezone($node);
+	  $open_at = date_create($node->signup_open_at,timezone_open('UTC'));
+	  $close_at = date_create($node->signup_close_at,timezone_open('UTC'));
+	  date_timezone_set($open_at, timezone_open($timezone));
+	  date_timezone_set($close_at, timezone_open($timezone));
+	  
+      $form['signup_open_at'] = array(
+        '#type' => 'date_select',
+  	    '#title' => t('Time to open signup'),
+        '#default_value' => date_format($open_at, DATE_FORMAT_DATETIME),
+        '#description' => t('Time before an event starts to auto-open the signup.'),
+		'#date_format' => DATE_FORMAT_DATETIME,
+		'#date_timezone' => $timezone,
+      );
+    
+      $form['signup_close_at'] = array(
+        '#type' => 'date_select',
+	    '#title' => t('Time to close signup'),
+        '#default_value' => date_format($close_at, DATE_FORMAT_DATETIME),
+        '#description' => t('Time before an event starts to auto-close the signup.'),
+		'#date_format' => DATE_FORMAT_DATETIME,
+		'#date_timezone' => $timezone,
+      );
+      // If the date_popup module is enabled we want to use the popup element
+      if (module_exists('date_popup')) {
+        $form['signup_open_at']['#type'] = 'date_popup';
+  	    $form['signup_close_at']['#type'] = 'date_popup';
+      }
+    }
+	
+	// Define a sub-tree to wrap the next 2 form elements together in an
     // inline div for better display.
     $form['signup_reminder'] = array(
       '#prefix' => '<div class="container-inline">',
@@ -169,13 +205,20 @@ function signup_node_settings_form_submi
     $values['send_reminder'] = isset($form_state['values']['signup_send_reminder']) ? $form_state['values']['signup_send_reminder'] : 0;
     $values['reminder_days_before'] = isset($form_state['values']['signup_reminder_days_before']) ? $form_state['values']['signup_reminder_days_before'] : 0;
     $values['reminder_email'] = isset($form_state['values']['signup_reminder_email']) ? $form_state['values']['signup_reminder_email'] : '';
+	
+	if (isset($form_state['values']['signup_open_at']) && isset($form['signup_open_at']['#date_timezone'])) {
+	  $values['signup_open_at'] = _signup_time_db_format($form_state['values']['signup_open_at'], $form['#node'], $form['signup_open_at']['#date_timezone']);
+	}
+	if (isset($form_state['values']['signup_close_at']) && isset($form['signup_close_at']['#date_timezone'])) {
+	  $values['signup_close_at'] = _signup_time_db_format($form_state['values']['signup_close_at'], $form['#node'], $form['signup_close_at']['#date_timezone']);
+	}
   }
 
   // Either way, we want to make sure we're updating the values for the
   // current node, not nid 0...
   $node = $form['#node'];
   $values[] = $node->nid;
-  db_query("UPDATE {signup} SET forwarding_email = '%s', send_confirmation = %d, confirmation_email = '%s', close_signup_limit = %d, send_reminder = %d, reminder_days_before = %d, reminder_email = '%s' WHERE nid = %d", $values);
+  db_query("UPDATE {signup} SET forwarding_email = '%s', send_confirmation = %d, confirmation_email = '%s', close_signup_limit = %d, send_reminder = %d, reminder_days_before = %d, reminder_email = '%s', open_at = '%s', close_at = '%s' WHERE nid = %d", $values);
 
   // See if the limit changed, and if so, take any necessary action.
   if ($node->signup_close_signup_limit != $form_state['values']['signup_close_signup_limit']) {
Index: includes/scheduler.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/scheduler.inc,v
retrieving revision 1.4
diff -u -p -r1.4 scheduler.inc
--- includes/scheduler.inc	6 Nov 2008 10:20:48 -0000	1.4
+++ includes/scheduler.inc	9 Oct 2009 21:48:47 -0000
@@ -124,6 +124,9 @@ function signup_reminder_sql($node_type)
   }
 }
 
+
+// Outdated by new autoclose
+/*
 function signup_autoclose_sql($node_type) {
   switch (_signup_get_node_type_scheduler($node_type)) {
     case 'event':
@@ -136,6 +139,7 @@ function signup_autoclose_sql($node_type
       return array();
   }
 }
+*/
 
 function signup_admin_sql($node_type) {
   switch (_signup_get_node_type_scheduler($node_type)) {
