cvs diff: Diffing .
Index: signup.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.module,v
retrieving revision 1.159
diff -u -p -u -p -r1.159 signup.module
--- signup.module	29 Oct 2008 21:01:38 -0000	1.159
+++ signup.module	29 Oct 2008 22:11:37 -0000
@@ -38,10 +38,13 @@ function signup_cron() {
  * @see _signup_build_query()
  */
 function _signup_cron_send_reminders() {
+  $reminder_sql = array();
   if (function_exists('signup_reminder_sql')) {
-    $reminder_sql = signup_reminder_sql();
+    foreach (signup_content_type_fields() as $field) {
+      $reminder_sql[] = signup_reminder_sql($field);
+    }
   }
-  if (empty($reminder_sql)) {
+  if (empty($reminder_sql[0])) {
     // The backend doesn't support reminder emails, so bail out now.
     return;
   }
@@ -97,9 +100,11 @@ function _signup_cron_send_reminders() {
  */
 function _signup_cron_autoclose() {
   if (function_exists('signup_autoclose_sql')) {
-    $autoclose_sql = signup_autoclose_sql();
+    foreach (signup_content_type_fields() as $type) {
+      $autoclose_sql[] = signup_autoclose_sql($type);
+    }
   }
-  if (empty($autoclose_sql)) {
+  if (empty($autoclose_sql[0])) {
     // The backend doesn't support auto-closing events, so bail out now.
     return;
   }
@@ -145,31 +150,50 @@ function _signup_cron_autoclose() {
  *   Complete SQL statement based on the given query fragments.
  */
 function _signup_build_query($common_sql, $backend_sql) {
+  // Combine all the backend_sql values into a single array.
+  $fields = array();
+  $joins = array();
+  $where = array();
+  $group_by = array();
+  foreach ($backend_sql as $sql) {
+    $fields = array_merge($fields, (!empty($sql['fields']) ? $sql['fields'] : array()));
+    $joins = array_merge($joins, (!empty($sql['joins']) ? $sql['joins'] : array()));
+    $where = array_merge($where, (!empty($sql['where']) ? $sql['where'] : array()));
+    $group_by = array_merge($group_by, (!empty($sql['group_by']) ? $sql['group_by'] : array()));
+  }
 
+  // Combine backend sql with common_sql.
   $fields = array_merge(
     (!empty($common_sql['fields']) ? $common_sql['fields'] : array()),
-    (!empty($backend_sql['fields']) ? $backend_sql['fields'] : array())
+    (!empty($fields) ? $fields : array())
   );
   $joins = array_merge(
     (!empty($common_sql['joins']) ? $common_sql['joins'] : array()),
-    (!empty($backend_sql['joins']) ? $backend_sql['joins'] : array())
-  );
-  $where = array_merge(
-    (!empty($common_sql['where']) ? $common_sql['where'] : array()),
-    (!empty($backend_sql['where']) ? $backend_sql['where'] : array())
+    (!empty($joins) ? $joins : array())
   );
   $group_by = array_merge(
     (!empty($common_sql['group_by']) ? $common_sql['group_by'] : array()),
-    (!empty($backend_sql['group_by']) ? $backend_sql['group_by'] : array())
+    (!empty($group_by) ? $group_by : array())
   );
 
+  // Combine each of the backend_sql content type 'where' criteria with the common 'where'
+  // criteria to create the OR where clause.
+  if (!empty($where)) {
+    foreach ($where as $criteria) {
+      $where_or[] = implode(' AND ', array_merge($common_sql['where'], array($criteria)));
+    }
+  }
+  elseif (!empty($common_sql['where'])) {
+    $where_or = $common_sql['where'];
+  }
+
   $sql = 'SELECT '. implode(', ', $fields);
   $sql .= ' FROM '. $common_sql['primary'] .' ';
   if (!empty($joins)) {
     $sql .= implode(' ', $joins);
   }
-  if (!empty($where)) {
-    $sql .= ' WHERE '. implode(' AND ', $where);
+  if (!empty($where_or)) {
+    $sql .= ' WHERE ('. implode(') OR (', $where_or) .')';
   }
   if (!empty($group_by)) {
     $sql .= ' GROUP BY '. implode(', ', $group_by);
@@ -204,6 +228,17 @@ function signup_help($section) {
     $node = node_load(arg(1));
     return '<p>'. t('This page allows you to send an email message to every user who signed up for this @node_type.', array('@node_type' => $node->type)) .'</p>';
   }
+
+  // See if we need to add our extra checking and validation while configuring
+  // CCK node types for signup.  We only want to do this if the $section
+  // doesn't contain 'help#' since hook_help() is invoked twice on admin
+  // pages.
+  if (function_exists('signup_date_check_node_types')
+      && !preg_match('/.*help#.*/', $section)
+      && arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'types') {
+    $type = arg(3);
+    signup_date_check_node_types($type);
+  }
 }
 
 /**
@@ -289,6 +324,13 @@ function signup_menu($may_cache) {
   return $items;
 }
 
+/**
+ * Loads relevant backend event backend code based on which modules
+ * exists and which version is loaded.  Currently, checks for the
+ * event modules first, then the date module, and doesn't allow for
+ * either event or date to be used if both modules are present.
+ * @ingroup signup_core
+ */
 function _signup_initialize_event_backend() {
   define('SIGNUP_PATH', drupal_get_path('module', 'signup'));
   if (defined('EVENT_API') && EVENT_API == '5.2') {
@@ -297,10 +339,13 @@ function _signup_initialize_event_backen
   else if (module_exists('event')) {
     require_once(SIGNUP_PATH .'/includes/event.5x-1.inc');
   }
+  else if (variable_get('date_api_version', 0) == '5.2') {
+    require_once(SIGNUP_PATH .'/includes/date.inc');
+    require_once(SIGNUP_PATH .'/includes/date.5x-2.inc');
+  }
   else if (module_exists('date')) {
-    // require_once(SIGNUP_PATH .'/signup_date.inc');
-    // Until date.module support exists, fall back to the no event case.
-    require_once(SIGNUP_PATH .'/includes/event.none.inc');
+    require_once(SIGNUP_PATH .'/includes/date.inc');
+    require_once(SIGNUP_PATH .'/includes/date.5x-1.inc');
   }
   else {
     require_once(SIGNUP_PATH .'/includes/event.none.inc');
@@ -376,6 +421,11 @@ function signup_form_alter($form_id, &$f
     case $form['type']['#value'] .'_node_form':
       signup_alter_node_form($form_id, $form);
       break;
+    case '_content_admin_field':
+      if (function_exists('_signup_date_field_form_alter')) {
+        _signup_date_field_form_alter($form_id, $form);
+      }
+      break;
   }
 }
 
@@ -396,6 +446,10 @@ function signup_alter_node_type_form($fo
     '#default_value' => variable_get('signup_node_default_state_'. $type, 'disabled'),
     '#description' => t('If %disabled is selected, signups will not be possible for this content type. If %allowed_off is selected, signups will be off by default, but users with the %admin_all_signups permission will be able to allow signups for specific posts of this content type. If %enabled_on is selected, users will be allowed to signup for this content type unless an administrator disbles signups on specific posts.', array('%disabled' => t('Disabled'), '%allowed_off' => t('Allowed (off by default)'), '%enabled_on' => t('Enabled (on by default)'), '%admin_all_signups' => t('administer all signups'))),
   );
+
+  if (function_exists('_signup_date_alter_node_type_form')) {
+    _signup_date_alter_node_type_form($form_id, $form);
+  }
 }
 
 /**
@@ -1248,11 +1302,11 @@ function signup_admin_form_sql() {
   }
 
   // Get the right query elements from the currently installed backend
+  $admin_sql = array();
   if (function_exists('signup_admin_sql')) {
-    $admin_sql = signup_admin_sql();
-  }
-  else {
-    $admin_sql = array();
+    foreach (signup_content_type_fields() as $field) {
+      $admin_sql[] = signup_admin_sql($field);
+    }
   }
 
   // Build the main query.
@@ -1606,17 +1660,34 @@ function signup_list_user_signups($uid) 
 
   // We don't want to return anything for anon users.
   if ($uid != 0) {
-    $sql = signup_list_user_signups_sql();
-    // Pull all open signup nodes for this user.
-    $result = db_query(db_rewrite_sql($sql), $uid);
-    while ($node = db_fetch_array($result)) {
-      $titles[$node['nid']] = l($node['title'], 'node/'. $node['nid']);
+    foreach (signup_content_types() as $type) {
+      $sql = signup_list_user_signups_sql($type);
+      if ($sql) {
+        // Pull all open signup nodes for this user.
+        $result = db_query(db_rewrite_sql($sql), $uid);
+        while ($node = db_fetch_array($result)) {
+          $titles[$node['nid']] = l($node['title'], 'node/'. $node['nid']);
+        }
+      }
     }
   }
   return $titles;
 }
 
 /**
+ * Returns a list of content types that have signups enabled
+ */
+function signup_content_types() {
+  $signup_content_types = array();
+  foreach (node_get_types('names') as $content_type => $content_name) {
+    if (variable_get('signup_node_default_state_'. $content_type, 'disabled') != 'disabled') {
+      $signup_content_types[] = $content_type;
+    }
+  }
+  return $signup_content_types;
+}
+
+/**
  * Signs up a user to a node.
  *
  * NOTE: other modules can call this function. To do so, $signup_form
cvs diff: Diffing contrib
cvs diff: Diffing contrib/signup_conflicts
cvs diff: Diffing contrib/signup_ecommerce
cvs diff: Diffing includes
Index: includes/date.5x-1.inc
===================================================================
RCS file: includes/date.5x-1.inc
diff -N includes/date.5x-1.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/date.5x-1.inc	29 Oct 2008 22:11:38 -0000
@@ -0,0 +1,99 @@
+<?php
+// $Id$
+
+/**
+ * @return Array of SQL clauses for cron reminder email query builder.
+ */
+function signup_reminder_sql($content_type_field = NULL) {
+  global $db_type;
+  switch ($db_type) {
+    case 'mysql':
+    case 'mysqli':
+      $where = array("NOW() + INTERVAL s.reminder_days_before DAY > ". date_sql('DATE', $content_type_field['database']['columns']['value']['column'], 'iso'));
+      break;
+    case 'pgsql':
+      $where = array("NOW() + INTERVAL s.reminder_days_before days > ". date_sql('DATE', $content_type_field['database']['columns']['value']['column'], 'iso'));
+      break;
+  }
+  return array(
+    'fields' => array('n.type', $content_type_field['database']['columns']['value']['column']),
+    'joins' => array('LEFT JOIN {'. $content_type_field['database']['table'] .'}  ON {'. $content_type_field['database']['table'] .'}.vid = n.vid'),
+    'where' => $where,
+  );
+}
+
+/**
+ * @return Array of SQL clauses for cron auto-close query builder.
+ */
+function signup_autoclose_sql($content_type_field = NULL) {
+  return array(
+    'fields' => array($content_type_field['database']['columns']['value']['column']),
+    'joins' => array(
+      'INNER JOIN {node} n ON s.nid = n.nid',
+      'LEFT JOIN {'. $content_type_field['database']['table'] .'} ON {'. $content_type_field['database']['table'] .'}.vid = n.vid',
+    ),    
+    'where' => array( date_sql('DATE', $content_type_field['database']['columns']['value']['column'], 'iso')  ." < '". date('Y-m-d H:i:s', time() + variable_get('signup_close_early', 1) * 3600) ."'"),
+  );
+}
+
+/**
+ * @return SQL for listing signups a user has signed up for
+ */
+function signup_list_user_signups_sql($content_type = NULL) {
+  $field = signup_date_field($content_type);
+  if ($field && $field != 'none') {
+    return 'SELECT n.nid, n.title, '. $field['database']['columns']['value']['column'] .' FROM {node} n INNER JOIN {signup_log} s_l ON n.nid = s_l.nid LEFT JOIN '. $field['database']['table'] .' c ON c.nid = n.nid WHERE s_l.uid = %d AND ('. date_sql('NOW', $field['database']['columns']['value']['column'], 'iso') .' >= NOW() OR '. $field['database']['columns']['value']['column'] .' IS NULL) ORDER BY '. $field['database']['columns']['value']['column'];
+  } 
+  else {
+    return FALSE;
+  }
+}
+
+/**
+ * Returns TRUE if the given node is event-enabled, and the start time
+ * has already passed the "Close x hours before" setting.
+ */
+function _signup_event_completed($node) {
+  if (is_numeric($node)) {
+    $node = node_load($node);
+  }
+  $field = signup_date_field($node->type);
+  if ($field && $field != 'none' && isset($node->{$field['field_name']})) {
+    $closing_time = time() + (variable_get('signup_close_early', 1) * 3600);
+    if (date_iso2unix($node->{$field['field_name']}[0]['value']) < $closing_time) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+function signup_format_date($node, $include_to_date = FALSE) {
+  $field = signup_date_field($node->type);
+  if (!$field || $field == 'none') {
+    return '';
+  }
+  if (isset($node->{$field['field_name']})) {
+    $date_value = $node->{$field['field_name']}[0]['value'];
+  }
+  else if (isset($node->{$field['field_name'] . '_value'})) {
+    $date_value = $node->{$field['field_name'] . '_value'};
+  }
+  else {
+    $date_value = $node->{$field['database']['columns']['value']['column']};
+  }
+  $date = date_show_date(date_make_date($date_value), $field['output_format_date'], 'db');
+
+  if ($include_to_date) {
+    if (isset($node->{$field['field_name']})) {
+      $date_value = $node->{$field['field_name']}[0]['value2'];
+    }
+    else {
+      $date_value = $node->{$field['database']['columns']['value2']['column']};
+    }
+    if ($date_value) {
+      $date .= t(' to ') . date_show_date(date_make_date($date_value), $field['output_format_date'], 'db');
+    }
+  }
+
+  return $date;
+}
Index: includes/date.5x-2.inc
===================================================================
RCS file: includes/date.5x-2.inc
diff -N includes/date.5x-2.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/date.5x-2.inc	29 Oct 2008 22:11:38 -0000
@@ -0,0 +1,120 @@
+<?php
+// $Id$
+
+/**
+ * @return Array of SQL clauses for cron reminder email query builder.
+ */
+function signup_reminder_sql($content_type_field = NULL) {
+  global $db_type;
+  include_once('./'. drupal_get_path('module', 'date_api') .'/date_api_sql.inc');
+  $handler = new date_sql_handler();
+  switch ($db_type) {
+    case 'mysql':
+    case 'mysqli':
+      $where = array("NOW() + INTERVAL s.reminder_days_before DAY > ". $handler->sql_extract('DATE', $content_type_field['database']['columns']['value']['column']));
+      break;
+    case 'pgsql':
+      $where = array("NOW() + INTERVAL s.reminder_days_before days > ". $handler->sql_extract('DATE', $content_type_field['database']['columns']['value']['column']));
+      break;
+  }
+  return array(
+    'fields' => array('n.type', $content_type_field['database']['columns']['value']['column']),
+    'joins' => array('LEFT JOIN {'. $content_type_field['database']['table'] .'}  ON {'. $content_type_field['database']['table'] .'}.vid = n.vid'),
+    'where' => $where,
+  );
+}
+
+/**
+ * @return Array of SQL clauses for cron auto-close query builder.
+ */
+function signup_autoclose_sql($content_type_field = NULL) {
+  require_once(drupal_get_path('module', 'date_api') .'/date_api_sql.inc');
+  $handler = new date_sql_handler();
+  return array(
+    'fields' => array($content_type_field['database']['columns']['value']['column']),
+    'joins' => array(
+      'INNER JOIN {node} n ON s.nid = n.nid',
+      'LEFT JOIN {'. $content_type_field['database']['table'] .'}  ON {'. $content_type_field['database']['table'] .'}.vid = n.vid',
+    ),
+    'where' => array( $handler->sql_extract('DATE', $content_type_field['database']['columns']['value']['column'])  ." < '". date('Y-m-d\TH:i:s', time() + variable_get('signup_close_early', 1) * 3600) ."'"),
+  );
+}
+
+/**
+ * @return SQL for listing signups a user has signed up for
+ */
+function signup_list_user_signups_sql($content_type = NULL) {
+  require_once(drupal_get_path('module', 'date_api') .'/date_api_sql.inc');
+  $handler = new date_sql_handler();
+  $field = signup_date_field($content_type);
+  if ($field && $field != 'none') {
+    return 'SELECT n.nid, n.title, '. $field['database']['columns']['value']['column'] .' FROM {node} n INNER JOIN {signup_log} s_l ON n.nid = s_l.nid LEFT JOIN '. $field['database']['table'] .' c ON c.nid = n.nid WHERE s_l.uid = %d AND ('. $handler->sql_extract('NOW', $field['database']['columns']['value']['column'], 'iso') .' >= NOW() OR '. $field['database']['columns']['value']['column'] .' IS NULL) ORDER BY '. $field['database']['columns']['value']['column'];
+  } 
+  else {
+    return FALSE;
+  }
+}
+
+/**
+ * Returns TRUE if the given node is event-enabled, and the start time
+ * has already passed the "Close x hours before" setting.
+ */
+function _signup_event_completed($node) {
+  if (is_numeric($node)) {
+    $node = node_load($node);
+  }
+  $field = signup_date_field($node->type);
+  if ($field && $field != 'none' && isset($node->{$field['field_name']})) {
+    $closing_time = time() + (variable_get('signup_close_early', 1) * 3600);
+    if (strtotime($node->{$field['field_name']}[0]['value']) < $closing_time) {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+function signup_format_date($node, $include_to_date = FALSE) {
+  $field = signup_date_field($node->type);
+  if (!$field || $field == 'none') {
+    return '';
+  }
+  if ($field['tz_handling'] == 'date') {
+    $tz = $node->{$field['field_name']}[0]['timezone'];
+  }
+  else {
+    $tz = date_default_timezone_name();
+  }
+  $display_tz = date_get_timezone($field['tz_handling'], $tz);
+  $db_tz = date_get_timezone_db($field['tz_handling'], $tz);
+  
+  if (isset($node->{$field['field_name']})) {
+    $date_value = $node->{$field['field_name']}[0]['value'];
+  }
+  else {
+    $date_value = $node->{$field['database']['columns']['value']['column']};
+  }
+  $date = date_make_date($date_value, $db_tz, $field['type']);
+  if ($db_tz != $display_tz) {
+    date_timezone_set($date, timezone_open($display_tz));
+  }
+  $date_out = date_format_date($date, 'custom', $field['output_format_date']);
+  
+  if ($include_to_date) {
+    if (isset($node->{$field['field_name']})) {
+      $date_value = $node->{$field['field_name']}[0]['value2'];
+    }
+    else {
+      $date_value = $node->{$field['database']['columns']['value2']['column']};
+    }
+    $date = date_make_date($date_value, $db_tz, $field['type']);
+    if ($db_tz != $display_tz) {
+      date_timezone_set($date, timezone_open($display_tz));
+    }
+    $date = date_format_date($date, 'custom', $field['output_format_date']);
+    if ($date_value) {
+      $date_out .= t(' to ') . date_format_date(date_make_date($date_value), 'custom', $field['output_format_date']);
+    }
+  }
+
+  return $date_out;
+}
Index: includes/date.inc
===================================================================
RCS file: includes/date.inc
diff -N includes/date.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/date.inc	29 Oct 2008 22:11:38 -0000
@@ -0,0 +1,292 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Shared code required for any site using CCK date fields, regardless of the
+ * version of date in use.
+ */
+
+/**
+ * @return Array of SQL clauses for admin overview page query builder.
+ */
+function signup_admin_sql($content_type_field = NULL) {
+  return array(
+    'fields' => array('n.type', $content_type_field['database']['columns']['value']['column']),
+    'joins' => array('LEFT JOIN {'. $content_type_field['database']['table'] .'} ON {'. $content_type_field['database']['table'] .'}.vid = n.vid'),
+  );
+}
+
+function signup_admin_form_header() {
+  // TODO: Not sure if we can sort date fields, since they might be coming
+  // from different tables so for now 'field' is NULL to disable sorting on
+  // the date field
+  return array('data' => t('Start'), 'field' => NULL);
+}
+
+function signup_admin_form_extra($signup_event) {
+  return array(
+    '#type' => 'markup',
+    '#value' => signup_format_date($signup_event)
+  );
+}
+
+function signup_field_names($content_type = NULL) {
+  $fields = array();
+  $content_type_info = _content_type_info();
+  if ($content_type_info['content types'][$content_type]) {
+    foreach ($content_type_info['content types'][$content_type]['fields'] as $field) {
+      if (in_array($field['type'], array('date', 'datestamp'))) {
+        $fields[$field['field_name']] = $field['widget']['label'];
+      }
+    }
+  }
+  return $fields;
+}
+
+function signup_extra_tokens() {
+  return array('%time');
+}
+
+function signup_date_field($content_type) {
+  $field_name = variable_get('signup_date_field_'. $content_type, 0);
+  if ($field_name === 0 || $field_name == '0') {
+    // PHP is completely evil and 'none' == 0 is TRUE, hence the extra checks.
+    return FALSE;
+  }
+  if ($field_name == 'none') {
+    return 'none';
+  }
+  $field = content_fields($field_name, $content_type);
+  if (empty($field)) {
+    return array();
+  }
+  $field['database'] = content_database_info($field);
+  return $field;
+}
+
+function theme_signup_event_dates($node) {
+  return signup_format_date($node, TRUE);
+}
+
+/**
+ * Returns a list of all cck fields that have been set for use in signups
+ */
+function signup_content_type_fields() {
+  $fields = array();
+  foreach (signup_content_types() as $content_type) {
+    $field = signup_date_field($content_type);
+    if (!empty($field) && $field != 'none') {
+      $fields[] = $field;
+    }
+  }
+  return $fields;
+}
+
+/**
+ * Does this site have any date-enabled content?
+ *
+ * @return Bool: Always return TRUE in this backend
+ */
+function signup_site_has_dates() {
+  return TRUE;
+}
+
+/**
+ * @return Bool: Is this node type date-enabled?
+ */
+function signup_node_type_has_date($type) {
+  $signup_date_field = variable_get('signup_date_field_'. $type, 0);
+  return (!empty($signup_date_field) && $signup_date_field != 'none');
+}
+
+/**
+ * @return Bool: Is this specific node date-enabled?
+ */
+function signup_node_has_date($node) {
+  if (signup_node_type_has_date($node->type)) {
+    $field = signup_date_field($node->type);
+    return isset($node->{$field['field_name']});
+  }
+  return FALSE;
+}
+
+/**
+ * Alter the form for configuring CCK date fields on node types.
+ *
+ * Hooks into CCK Date fields to provide an option to use the current
+ * field as the Signup date field (for autoclose and reminder emails).
+ *
+ * @see signup_form_alter()
+ */
+function _signup_date_field_form_alter($form_id, &$form) {
+  $type = $form['type_name']['#value'];
+  if (in_array($form['field_type']['#value'], array('date', 'datestamp')) && variable_get('signup_node_default_state_'. $type, 'disabled') != 'disabled') {
+    $form['signup'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Signup settings'),
+      '#collapsible' => TRUE,
+      '#weight' => 1,
+    );
+    $form['signup']['signup_date_field'] = _signup_date_field_element($type);
+    $form['#submit']['_signup_date_field_form_submit'] = array();
+    // Make sure the submit button comes after the signup settings fieldset.
+    $form['submit']['#weight'] = 50;
+  }
+}
+
+/**
+ * Custom submit handler for the CCK date field editing form.
+ *
+ * @see _signup_date_field_form_alter()
+ */
+function _signup_date_field_form_submit($form_id, $form_values) {
+  $type = $form_values['type_name'];
+  if (empty($form_values['signup_date_field'])) {
+    variable_del('signup_date_field_'. $type);
+  }
+  else {
+    variable_set('signup_date_field_'. $type, $form_values['signup_date_field']);
+  }
+}
+
+/**
+ * Alter the node type form to add a setting to select the signup date field.
+ *
+ * @see signup_alter_node_type_form()
+ */
+function _signup_date_alter_node_type_form($form_id, &$form) {
+  drupal_add_js(drupal_get_path('module', 'signup') .'/js/admin.content_types.js');
+  drupal_add_css(drupal_get_path('module', 'signup') .'/signup.css');
+
+  $type = $form['#node_type']->type;
+  $default_signup_state = variable_get('signup_node_default_state_'. $type, 'disabled');
+
+  // Add a div to the 'Signup options' radios for signup.date.js.
+  $form['workflow']['signup_node_default_state']['#prefix'] = '<div class="signup-node-default-state-radios">';
+  $form['workflow']['signup_node_default_state']['#suffix'] = '</div>';
+
+  // Figure out if we should hide the date field selector by default.
+  $class = 'signup-date-field-setting';
+  if ($default_signup_state == 'disabled') {
+    $class .= ' js-hide';
+  }
+
+  $form['workflow']['signup_date_field'] = _signup_date_field_element($type);
+  $form['workflow']['signup_date_field']['#prefix'] = '<div class="'. $class .'">';
+  $form['workflow']['signup_date_field']['#suffix'] = '</div>';
+}
+
+/**
+ * Create the FAPI form element for the signup date field.
+ *
+ * @param $type
+ *   The node type to generate the form element for.
+ *
+ * @return
+ *   FAPI form array for the signup date field element.
+ *
+ * @see _signup_date_field_form_alter()
+ * @see _signup_date_alter_node_type_form()
+ */
+function _signup_date_field_element($type) {
+  return array(
+    '#type' => 'select',
+    '#title' => t('Date field to use with signup'),
+    '#options' => _signup_get_date_field_options($type),
+    '#default_value' => variable_get('signup_date_field_'. $type, 0),
+    '#description' => t('Select the date field of this content type to use for signup time-based functionality, such as automatically closing signups when the start time has passed and sending reminder emails. Select "%none" to not use a date field for signup functionality at all.', array('%none' => t('None'))),
+  );
+}
+
+/**
+ * Check the signup and date configuration on node types depending on the URL.
+ *
+ * This function is invoked from signup_help() so that we can check the
+ * configuration of any signup-enabled node types to ensure that the CCK date
+ * field and signup settings make sense.
+ *
+ * @param $type
+ *   The 4th element in the URL which specifies which node type is currently
+ *   being configured.  If this is empty, it means we're at the node type
+ *   overview listing and we should test all node types.
+ *
+ * @see signup_help()
+ * @see signup_date_field_check_config()
+ */
+function signup_date_check_node_types($type) {
+  $names = node_get_types('names');
+  if (!empty($type)) {
+    signup_date_field_check_config($type, $names[$type]);
+  }
+  else {
+    foreach ($names as $type => $name) {
+      signup_date_field_check_config($type, $name);
+    }
+  }
+}
+
+/**
+ * Check that the date and signup configuration for a node type makes sense.
+ *
+ * This validates that if a node type is signup enabled, that it either has a
+ * signup date field selected (for autoclose and reminder emails), or that the
+ * signup date field has been explicitly set to 'None'.  It warns the site
+ * administrator if they have signup-enabled a node type and not defined any
+ * date fields at all, or if they have date fields but haven't selected the
+ * one to use for signup functionality.
+ *
+ * @param $type
+ *   The node type to check signup and CCK date field configuration on.
+ * @param $name
+ *   Human readable name of the node type to check.
+ *
+ * @return
+ *   Nothing -- configuration errors are reported via drupal_set_message().
+ *
+ * @see signup_help()
+ */
+function signup_date_field_check_config($type, $name) {
+  $signup_default_state = variable_get('signup_node_default_state_'. $type, 'disabled');
+  if ($signup_default_state != 'disabled') {
+    // Signups aren't disabled on this node type, see if there's a date field.
+    $signup_date_field = signup_date_field($type);
+    if ($signup_date_field != 'none') {
+      // Administrator hasn't specifically turned off date support...
+      if (signup_field_names($type)) { 
+        // Node type has some date fields...
+        if ($signup_date_field == 0) {
+          drupal_set_message(t('You have enabled the %node_type content type for signups, and have added one or more date fields, but have not selected a date field for use with signup.', array('%node_type' => $name)), 'warning');
+        }
+      }
+      else {
+        // No date fields at all.
+        drupal_set_message(t('You have enabled the %node_type content type for signups but have not added a date field.', array('%node_type' => $name)), 'warning');
+      }
+    }
+  }
+}
+
+/**
+ * Helper function for the date field select to build its options.
+ *
+ * @param $type
+ *   Content type whose date fields should be listed.
+ *
+ * @return
+ *   Associative array with all date fields of the given content type plus
+ *   'None' and an optional 'Not specified' if the user never selected a
+ *   value.
+ */
+function _signup_get_date_field_options($type) {
+  $options = array();
+  // Add "Not specified" if the user never selected a field.
+  if (variable_get('signup_date_field_'. $type, 0) == 0) {
+    $options = array(0 => t('<Not specified>'));
+  }
+  // Add any date fields from this node type.
+  $options += signup_field_names($type);
+  // Always add 'None' as the final choice.
+  $options += array('none' => t('<None>'));
+  return $options;
+}
Index: includes/event.5x-1.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/event.5x-1.inc,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 event.5x-1.inc
--- includes/event.5x-1.inc	29 Oct 2008 20:58:28 -0000	1.9
+++ includes/event.5x-1.inc	29 Oct 2008 22:11:38 -0000
@@ -4,7 +4,7 @@
 /**
  * @return Array of SQL clauses for cron reminder email query builder.
  */
-function signup_reminder_sql() {
+function signup_reminder_sql($content_type = NULL) {
   // We must manually include this here as the event module doesn't
   // include timezone support on all page requests.
   include_once(drupal_get_path('module', 'event') .'/event_timezones.inc');
@@ -18,7 +18,7 @@ function signup_reminder_sql() {
 /**
  * @return Array of SQL clauses for cron auto-close query builder.
  */
-function signup_autoclose_sql() {
+function signup_autoclose_sql($content_type = NULL) {
   // We must manually include this here as the event module doesn't
   // include timezone support on all page requests.
   include_once(drupal_get_path('module', 'event') .'/event_timezones.inc');
@@ -32,7 +32,7 @@ function signup_autoclose_sql() {
 /**
  * @return Array of SQL clauses for admin overview page query builder.
  */
-function signup_admin_sql() {
+function signup_admin_sql($content_type = NULL) {
   $fields = array('e.event_start', 'e.timezone');
   return array(
     'fields' => $fields,
@@ -53,7 +53,7 @@ function signup_admin_form_extra($signup
   );
 }
 
-function signup_list_user_signups_sql() {
+function signup_list_user_signups_sql($content_type = NULL) {
   return "SELECT n.nid, n.title, e.event_start FROM {node} n INNER JOIN {signup_log} s_l ON n.nid = s_l.nid LEFT JOIN {event} e ON e.nid = n.nid WHERE s_l.uid = %d AND (e.event_start >= ". time() ." OR e.event_start IS NULL) ORDER BY e.event_start";
 }
 
@@ -142,6 +142,17 @@ function theme_signup_event_dates($node)
 }
 
 /**
+ * Return a list of fields used for signup functionality.
+ *
+ * For the event* backends, this just returns the name 'Event' so that we
+ * invoke the event backend with something, but the field names and content
+ * types are ignored since we're just using the event module, not CCK.
+ */
+function signup_content_type_fields() {
+  return array('Event');
+}
+
+/**
  * Does this site have any date-enabled content?
  *
  * @return Bool: Always return TRUE in this backend
Index: includes/event.5x-2.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/event.5x-2.inc,v
retrieving revision 1.8
diff -u -p -u -p -r1.8 event.5x-2.inc
--- includes/event.5x-2.inc	29 Oct 2008 20:58:32 -0000	1.8
+++ includes/event.5x-2.inc	29 Oct 2008 22:11:38 -0000
@@ -4,7 +4,7 @@
 /**
  * @return Array of SQL clauses for cron reminder email query builder.
  */
-function signup_reminder_sql() {
+function signup_reminder_sql($content_type = NULL) {
   global $db_type;
   event_include_files();
   switch ($db_type) {
@@ -25,7 +25,7 @@ function signup_reminder_sql() {
 /**
  * @return Array of SQL clauses for cron auto-close query builder.
  */
-function signup_autoclose_sql() {
+function signup_autoclose_sql($content_type = NULL) {
   event_include_files();
   return array(
     'fields' => array(event_select(), 'e.timezone'),
@@ -37,7 +37,7 @@ function signup_autoclose_sql() {
 /**
  * @return Array of SQL clauses for admin overview page query builder.
  */
-function signup_admin_sql() {
+function signup_admin_sql($content_type = NULL) {
   return array(
     'fields' => array(event_select(), 'e.timezone'),
     'group_by' => array('event_start', 'e.timezone'),
@@ -56,7 +56,7 @@ function signup_admin_form_extra($signup
   );
 }
 
-function signup_list_user_signups_sql() {
+function signup_list_user_signups_sql($content_type = NULL) {
   return 'SELECT n.nid, n.title, '. event_select() .' FROM {node} n INNER JOIN {signup_log} s_l ON n.nid = s_l.nid '. event_join('n', 'LEFT') .' WHERE s_l.uid = %d AND ('. event_where() ." >= '". event_implode_date(_event_user_time()) ."' OR e.event_start IS NULL) ORDER BY event_start";
 }
 
@@ -86,6 +86,17 @@ function signup_format_date($node) {
 }
 
 /**
+ * Return a list of fields used for signup functionality.
+ *
+ * For the event* backends, this just returns the name 'Event' so that we
+ * invoke the event backend with something, but the field names and content
+ * types are ignored since we're just using the event module, not CCK.
+ */
+function signup_content_type_fields() {
+  return array('Event');
+}
+
+/**
  * Does this site have any date-enabled content?
  *
  * @return Bool: Always return TRUE in this backend
Index: includes/event.none.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/event.none.inc,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 event.none.inc
--- includes/event.none.inc	29 Oct 2008 20:58:25 -0000	1.4
+++ includes/event.none.inc	29 Oct 2008 22:11:38 -0000
@@ -12,7 +12,7 @@
  *
  * The call site assumes the one and only %d in this query is the user's uid.
  */
-function signup_list_user_signups_sql() {
+function signup_list_user_signups_sql($content_type = NULL) {
   return "SELECT n.nid, n.title FROM {node} n INNER JOIN {signup_log} s_l ON n.nid = s_l.nid WHERE s_l.uid = %d ORDER BY n.nid";
 }
 
cvs diff: Diffing js
Index: js/admin.content_types.js
===================================================================
RCS file: js/admin.content_types.js
diff -N js/admin.content_types.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ js/admin.content_types.js	29 Oct 2008 22:11:38 -0000
@@ -0,0 +1,24 @@
+/* $Id$ */
+
+/**
+ * On a node type settings form, if the "Allow signups" radios are 
+ * not set to 0 ('Disabled'), then show the date field selection,
+ * otherwise, hide it.
+ */
+Drupal.signupShowDateFieldAutoAttach = function () {
+  $('div.signup-node-default-state-radios input[@type=radio]').click(function () {
+    if (this.value == 'disabled') {
+      $('div.signup-date-field-setting').hide();
+    }
+    else {
+      $('div.signup-date-field-setting').show();
+    }
+  });
+};
+
+// Global killswitch.
+if (Drupal.jsEnabled) {
+  $(function() {
+    Drupal.signupShowDateFieldAutoAttach();
+  });
+}
cvs diff: Diffing po
cvs diff: Diffing theme
cvs diff: Diffing views
