? 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 @@ 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' => '
', @@ -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)) {