? .DS_Store ? signup_374086_multiple_reminders_1.patch Index: signup.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/signup/signup.install,v retrieving revision 1.24.2.3 diff -u -p -r1.24.2.3 signup.install --- signup.install 27 Dec 2008 00:40:30 -0000 1.24.2.3 +++ signup.install 3 Apr 2009 20:13:08 -0000 @@ -35,25 +35,6 @@ function signup_schema() { 'size' => 'big', 'not null' => TRUE, ), - 'send_reminder' => array( - 'description' => t('Boolean indicating whether reminder emails should be sent. This is set to 0 once the reminders are sent.'), - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'reminder_days_before' => array( - 'description' => t('Number of days before the start of a time-based node when the reminder emails should be sent.'), - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'reminder_email' => array( - 'description' => t('Email template to send to users to remind them about a signup.'), - 'type' => 'text', - 'size' => 'big', - 'not null' => TRUE, - ), 'close_in_advance_time' => array( 'description' => t('Number of hours before the start of a time-based node when signups should automatically be closed. This column is not currently used and the behavior is controlled by a site-wide setting. See http://drupal.org/node/290249 for more information.'), 'type' => 'int', @@ -135,6 +116,40 @@ function signup_schema() { ), ); + $schema['signup_scheduled_messages'] = array( + 'description' => t('Records information about multiple default and per-node scheduled messages.'), + 'fields' => array( + 'nid' => array( + 'description' => t('Primary key: node ID. Relates to signup.nid, which relates to node.nid.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'send_message' => array( + 'description' => t('Boolean indicating whether scheduled messages should be sent. This is set to 0 once the messages are sent.'), + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'message_days_before' => array( + 'description' => t('Number of days before the start of a time-based node when the scheduled messages should be sent.'), + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'message_email' => array( + 'description' => t('Email template to send scheduled messages to users about a signup.'), + 'type' => 'text', + 'size' => 'big', + 'not null' => TRUE, + ), + ), + 'indexes' => array( + 'nid' => array('nid'), + ), + ); + return $schema; } @@ -169,17 +184,18 @@ function signup_uninstall() { /** * Helper method to insert the default signup information into the - * {signup} table (stored in a row for nid 0). These are the default - * settings for new signup-enabled nodes. + * {signup} and {signup_scheduled_messages) tables (stored in a row for nid 0). + * These are the default settings for new signup-enabled nodes. */ function signup_insert_default_signup_info() { - return db_query("INSERT INTO {signup} (nid, forwarding_email, + db_query("INSERT INTO {signup} (nid, forwarding_email, send_confirmation, confirmation_email, - send_reminder, reminder_days_before, reminder_email, close_in_advance_time, close_signup_limit, status) VALUES (0, '', 1, 'Enter your default confirmation email message here', - 1, 1, 'Enter your default reminder email message here', 0, 0, 1)"); + return db_query("INSERT INTO {signup_scheduled_messages} (nid, + send_message, message_days_before, message_email) VALUES (0, + 1, 1, 'Enter your default scheduled email message here')"); } function signup_update_3() { @@ -375,7 +391,8 @@ function signup_update_5204() { // Find the next N records to update, or do the final batch. $next = min($_SESSION['signup_update_5204'] + 2000, $_SESSION['signup_update_5204_max']); // Perform the UPDATE in our specified range of nid values. - db_query("UPDATE {signup} SET reminder_email = $reminder_replace, confirmation_email = $confirmation_replace WHERE nid > %d AND nid <= %d", $_SESSION['signup_update_5204'], $next); + db_query("UPDATE {signup} SET confirmation_email = $confirmation_replace WHERE nid > %d AND nid <= %d", $_SESSION['signup_update_5204'], $next); + db_query("UPDATE {signup_scheduled_messages} SET message_email = $reminder_replace WHERE nid > %d AND nid <= %d", $_SESSION['signup_update_5204'], $next); // Remember where we left off. $_SESSION['signup_update_5204'] = $next; 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 3 Apr 2009 20:13:09 -0000 @@ -21,6 +21,14 @@ function signup_settings_form() { '#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).'), ); }; + // Set number of messages. (For multiple messages patch.) + $form['signup_message_number'] = array( + '#title' => t('Number of allowed messages'), + '#type' => 'textfield', + '#default_value' => variable_get('signup_message_number', 1), + '#size' => 5, '#maxlength' => 10, + '#description' => t('The number of allowed email messages, which will appear below (for filling defaults) and on the signup-enabled node edit form. Use 0 to disable this feature.'), + ); $form['node_defaults'] = array( '#type' => 'fieldset', '#title' => t('Default signup information'), @@ -197,48 +205,92 @@ function signup_settings_form() { * @param $form_values The constructed form values array of the submitted form. */ function signup_settings_form_submit($form, &$form_state) { - $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : ''; - if ($op == t('Save configuration') && db_result(db_query('SELECT COUNT(*) FROM {signup} WHERE nid = 0'))) { - $values = array( - $form_state['values']['signup_forwarding_email'], - $form_state['values']['signup_send_confirmation'], - $form_state['values']['signup_confirmation_email'], - $form_state['values']['signup_close_signup_limit'], - ); - $values[] = isset($form_state['values']['signup_send_reminder']) ? $form_state['values']['signup_send_reminder'] : 0; - $values[] = isset($form_state['values']['signup_reminder_days_before']) ? $form_state['values']['signup_reminder_days_before'] : 0; - $values[] = isset($form_state['values']['signup_reminder_email']) ? $form_state['values']['signup_reminder_email'] : ''; + // Modifications to support multiple messages. + // See logic below for looping through the values for the columns with the word "message" in the column name. + // See newly added table signup_scheduled_messages, with columns pulled from the signup table. JDB, 2009-03-10 + $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : ''; + if ($op == t('Save configuration') && db_result(db_query('SELECT COUNT(*) FROM {signup} WHERE nid = 0'))) { + + $values = array( + $form_state['values']['signup_forwarding_email'], + $form_state['values']['signup_send_confirmation'], + $form_state['values']['signup_confirmation_email'], + $form_state['values']['signup_close_signup_limit'], + ); + + // Add number of messages from the configs above. (For multiple messages patch.) + $message_number = variable_get('signup_message_number', 1); + $values[] = 0; // "nid" of the row in {signup} for the global settings. - 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); - } - else { - module_load_include('install', 'signup', 'signup'); - db_query("DELETE FROM {signup} WHERE nid = 0"); - signup_insert_default_signup_info(); - } - - // Now, remove all the settings we just processed from our copy of - // $form_state['values'], so system_settings_form_submit() doesn't see them. - $settings = array( - 'signup_forwarding_email', - 'signup_send_confirmation', - 'signup_confirmation_email', - 'signup_send_reminder', - 'signup_reminder_days_before', - 'signup_reminder_email', - 'signup_close_signup_limit', - ); - foreach ($settings as $setting) { - unset($form_state['values'][$setting]); - } - // Remove the hidden element from signup_node_settings_form(), too. - unset($form_state['values']['signup']); - // Since the advanced settings can mess with the menu, rebuild that. - menu_rebuild(); + db_query("UPDATE {signup} SET forwarding_email = '%s', send_confirmation = %d, confirmation_email = '%s', close_signup_limit = %d WHERE nid = %d", $values); + + // Loop through X number of messages for the node, where X has been defined for the particular signup, within limit set in signup settings. + // Add number of messages from the configs above. (For multiple messages patch.) + // Could fetch actual number of sets of message fields in the form, but using the max, as here, works fine, because + // the "isset" code below will make the unused slots look like non-activated messages. In other words, there might + // be some extra rows of data in the signup_scheduled_messages table, whereever there are signups with less than the maximum + // number of messages, but those rows will not trigger and outgoing e-mail or other actions. + $message_number = variable_get('signup_message_number', 1); + + // Initialize variables for iterating through X messages for the current node (most likely and Event node). + $next_signup_send_message_value = 0; + $next_signup_message_days_before_value = 0; + $next_signup_message_email_value = ''; + $next_signup_message_before_or_after = ''; // 'before' or 'after'. + $next_values[] = array(); + // For multiple messages patch. + // Loop through X number of messages for the node, where X has been defined for the particular signup, within limit set in signup settings. + db_query("DELETE FROM {signup_scheduled_messages} WHERE nid = 0"); + for ($r = 0; $r < $message_number; $r++) { + $this_index = $r+1; + $default_message_email = ''; + $default_message_before_or_after = 'before'; + + $next_signup_send_message_value = isset($form_state['values']['signup_send_message'. $this_index]) ? $form_state['values']['signup_send_message'. $this_index] : 0 ; + $next_signup_message_days_before_value = isset($form_state['values']['signup_message_days_before'. $this_index]) ? $form_state['values']['signup_message_days_before'. $this_index] : 0 ; + $next_signup_message_email_value = isset($form_state['values']['signup_message_email'. $this_index]) ? $form_state['values']['signup_message_email'. $this_index] : $default_message_email ; + + $next_signup_message_before_or_after = isset($form_state['values']['signup_message_before_or_after'. $this_index]) ? $form_state['values']['signup_message_before_or_after'. $this_index] : $default_message_before_or_after ; + if ($next_signup_message_before_or_after == 'after') { + $next_signup_message_days_before_value = (-$next_signup_message_days_before_value); // make the integer negative + } + + $next_values[0] = $next_signup_send_message_value; + $next_values[1] = $next_signup_message_days_before_value; + $next_values[2] = $next_signup_message_email_value; + $next_values[3] = $node->nid; + db_query("INSERT INTO {signup_scheduled_messages} (send_message, message_days_before, message_email, nid) VALUES (%d, %d, '%s', %d)", $next_values); + } + } + else { + module_load_include('install', 'signup', 'signup'); + db_query("DELETE FROM {signup} WHERE nid = 0"); + signup_insert_default_signup_info(); + } + + // Now, remove all the settings we just processed from our copy of + // $form_state['values'], so system_settings_form_submit() doesn't see them. + $settings = array( + 'signup_forwarding_email', + 'signup_send_confirmation', + 'signup_confirmation_email', + 'signup_send_message', + 'signup_message_days_before', + 'signup_message_email', + 'signup_close_signup_limit', + ); + foreach ($settings as $setting) { + unset($form_state['values'][$setting]); + } + // Remove the hidden element from signup_node_settings_form(), too. + unset($form_state['values']['signup']); + + // Since the advanced settings can mess with the menu, rebuild that. + menu_rebuild(); - // Let system_settings_form_submit() do its magic with everything else. - system_settings_form_submit($form, $form_state); + // Let system_settings_form_submit() do its magic with everything else. + system_settings_form_submit($form, $form_state); } /** Index: includes/node_form.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/node_form.inc,v retrieving revision 1.4.2.1 diff -u -p -r1.4.2.1 node_form.inc --- includes/node_form.inc 8 Jan 2009 19:36:27 -0000 1.4.2.1 +++ includes/node_form.inc 3 Apr 2009 20:13:11 -0000 @@ -42,12 +42,6 @@ function signup_save_node($node, $op) { $node->signup_confirmation_email, $node->signup_close_signup_limit, ); - // If we're dealing with a node that doesn't have a start time, these - // fields are missing from the signup settings form, so we can't assume - // they're defined. - $values[] = isset($node->signup_send_reminder) ? $node->signup_send_reminder : 0; - $values[] = isset($node->signup_reminder_days_before) ? $node->signup_reminder_days_before : 0; - $values[] = isset($node->signup_reminder_email) ? $node->signup_reminder_email : ''; } } elseif ($op == 'insert' && variable_get('signup_node_default_state_'. $node->type, 'disabled') == 'enabled_on') { @@ -62,9 +56,9 @@ function signup_save_node($node, $op) { $defaults->send_confirmation, $defaults->confirmation_email, $defaults->close_signup_limit, - $defaults->send_reminder, - $defaults->reminder_days_before, - $defaults->reminder_email, + $defaults->send_message, + $defaults->message_days_before, + $defaults->message_email, ); } @@ -94,18 +88,62 @@ function signup_save_node($node, $op) { // be used as the last column in the INSERT, or the argument to the WHERE // clause for the UPDATE. $values[] = $node->nid; + + // For multiple messages patch: Note... for the "message" columns, there is no need to distinguish + // between INSERT and UPDATE mode, because the logic will always use the DELETE/INSERT + // technique for these columns, which are in the table signup_scheduled_messages, which is + // related to the signup table, based on the nid column. if ($has_signup_record) { - 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); + // For multiple messages patch. + // Support multiple messages per node (event). + db_query("UPDATE {signup} SET forwarding_email = '%s', send_confirmation = %d, confirmation_email = '%s', close_signup_limit = %d WHERE nid = " . $node->nid, $values); } else { - 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); - } + // For multiple messages patch. + // Support multiple messages per node (event). + db_query("INSERT INTO {signup} (forwarding_email, send_confirmation, confirmation_email, close_signup_limit, nid) VALUES ('%s', %d, '%s', %d, " . $node->nid . ")", $values); + } + + // Add number of messages from the configs above. (For multiple messages patch.) + // Could fetch actual number of sets of message fields in the form, but using the max, as here, works fine, because + // the "isset" code below will make the unused slots look like non-activated messages. In other words, there might + // be some extra rows of data in the signup_scheduled_messages table, whereever there are signups with less than the maximum + // number of messages, but those rows will not trigger and outgoing e-mail or other actions. + $message_number = variable_get('signup_message_number', 1); + + // Initialize variables for iterating through X messages for the current node (most likely and Event node). + $next_signup_send_message_value = 0; + $next_signup_message_days_before_value = 0; + $next_signup_message_email_value = ''; + $next_signup_message_before_or_after = ''; // 'before' or 'after' + $next_values[] = array(); + // For multiple messages patch. + // Loop through X number of messages for the node, where X has been defined for the particular signup, within limit set in signup settings. + db_query("DELETE FROM {signup_scheduled_messages} WHERE nid = %d", $node->nid); + for ($r = 0; $r < $message_number; $r++) { + $this_index = $r+1; + $default_message_email = ''; + $default_message_before_or_after = 'before'; + eval('$next_signup_send_message_value = isset($node->signup_send_message' . $this_index . ') ? $node->signup_send_message' . $this_index . ' : 0 ;'); + eval('$next_signup_message_days_before_value = isset($node->signup_message_days_before' . $this_index . ') ? $node->signup_message_days_before' . $this_index . ' : 0 ;'); + eval('$next_signup_message_email_value = isset($node->signup_message_email' . $this_index . ') ? $node->signup_message_email' . $this_index . ' : $default_message_email ;'); + eval('$next_signup_message_before_or_after = isset($node->signup_message_before_or_after' . $this_index . ') ? $node->signup_message_before_or_after' . $this_index . ' : $default_message_before_or_after ;'); + if ($next_signup_message_before_or_after == 'after') { + $next_signup_message_days_before_value = (-$next_signup_message_days_before_value); // make the integer negative + } + + $next_values[0] = $next_signup_send_message_value; + $next_values[1] = $next_signup_message_days_before_value; + $next_values[2] = $next_signup_message_email_value; + $next_values[3] = $node->nid; + db_query("INSERT INTO {signup_scheduled_messages} (send_message, message_days_before, message_email, nid) VALUES (%d, %d, '%s', %d)", $next_values); + } + 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, and signups are still open, close them now (and don't // consider the limit for changing the status). signup_close_signup($node->nid); - drupal_set_message(t('%node_type start time is already past the signup close-in-advance time, signups now closed.', array('%node_type' => node_get_types('name', $node->type)))); } elseif ($limit_changed) { $node->signup_total = db_result(db_query("SELECT COUNT(*) FROM {signup_log} WHERE nid = %d", $node->nid)); @@ -120,6 +158,7 @@ function signup_save_node($node, $op) { // No break, fall through and remove from {signup} too. case 0: // Disabled, but leave {signup_log} alone db_query("DELETE FROM {signup} WHERE nid = %d", $node->nid); + db_query("DELETE FROM {signup_scheduled_messages} WHERE nid = %d", $node->nid); // For multiple messages patch. break; } } Index: includes/node_settings.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/signup/includes/node_settings.inc,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 node_settings.inc --- includes/node_settings.inc 20 Dec 2008 04:28:56 -0000 1.1.2.1 +++ includes/node_settings.inc 3 Apr 2009 20:13:15 -0000 @@ -19,7 +19,7 @@ * node type, even if $node is NULL. * @param $has_date * Boolean flag indicating if this node (or site) has signup-aware - * date functionality, which is required for reminder emails to be in + * date functionality, which is required for message emails to be in * the form. * * @return @@ -27,25 +27,56 @@ * */ function signup_node_settings_form($form_state, $node = NULL, $node_type = NULL, $has_date = 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'))); - } - else { - $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), and %cancel_signup_url (access to this link is denied to users without the "%cancel_own_signups" permission).', array('%cancel_own_signups' => t('cancel own signups'))); - } - - // Load the default admin form data for new nodes. - if (!$node || !$node->signup) { - $result = db_fetch_object(db_query("SELECT * FROM {signup} WHERE nid = 0")); - $node->signup_forwarding_email = $result->forwarding_email; - $node->signup_send_confirmation = $result->send_confirmation; - $node->signup_confirmation_email = $result->confirmation_email; - $node->signup_send_reminder = $result->send_reminder; - $node->signup_reminder_days_before = $result->reminder_days_before; - $node->signup_reminder_email = $result->reminder_email; - $node->signup_close_signup_limit = $result->close_signup_limit; - } - + 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'))); + } + else { + $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), and %cancel_signup_url (access to this link is denied to users without the "%cancel_own_signups" permission).', array('%cancel_own_signups' => t('cancel own signups'))); + } + + // Load the default admin form data for new nodes. + if (!$node || !$node->signup) { + + // For multiple scheduled messages patch.: get values from JOIN with new table + $dbrows = db_query("SELECT * FROM {signup} su INNER JOIN {signup_scheduled_messages} sr ON su.nid=sr.nid WHERE su.nid = 0 ORDER BY message_days_before DESC"); + $dbrowcount = 1; + while ($result = db_fetch_object($dbrows)) { + + $node->signup_forwarding_email = $result->forwarding_email; // will be the same in each row, so this is OK + $node->signup_send_confirmation = $result->send_confirmation; // will be the same in each row, so this is OK + $node->signup_confirmation_email = $result->confirmation_email; // will be the same in each row, so this is OK + $node->signup_close_signup_limit = $result->close_signup_limit; // will be the same in each row, so this is OK + + // For multiple scheduled messages patch. + eval('$node->signup_send_message' . $dbrowcount . ' = $result->send_message;'); // could be multiple instances + eval('$node->signup_message_days_before' . $dbrowcount . ' = $result->message_days_before;'); // could be multiple instances + eval('$node->signup_message_email' . $dbrowcount . ' = $result->message_email;'); // could be multiple instances + ++$dbrowcount; + } + + } + + // For multiple scheduled messages patch: get values from JOIN with new table + $nid = $node->nid; + if ($nid == null) { + $nid = 0; + } + $dbrows = db_query("SELECT * FROM {signup} su INNER JOIN {signup_scheduled_messages} sr ON su.nid=sr.nid WHERE su.nid = " . $nid . " ORDER BY message_days_before DESC "); // cannot use $node->nid here + $dbrowcount = 1; + while ($result = db_fetch_object($dbrows)) { + + $node->signup_forwarding_email = $result->forwarding_email; // will be the same in each row, so this is OK + $node->signup_send_confirmation = $result->send_confirmation; // will be the same in each row, so this is OK + $node->signup_confirmation_email = $result->confirmation_email; // will be the same in each row, so this is OK + $node->signup_close_signup_limit = $result->close_signup_limit; // will be the same in each row, so this is OK + + // For multiple scheduled messages patch. + eval('$node->signup_send_message' . $dbrowcount . ' = $result->send_message;'); // could be multiple instances + eval('$node->signup_message_days_before' . $dbrowcount . ' = $result->message_days_before;'); // could be multiple instances + eval('$node->signup_message_email' . $dbrowcount . ' = $result->message_email;'); // could be multiple instances + ++$dbrowcount; + } + $form['signup_forwarding_email'] = array( '#type' => 'textfield', '#title' => t('Send signups to'), @@ -71,38 +102,79 @@ function signup_node_settings_form($form } if ($has_date) { - // Define a sub-tree to wrap the next 2 form elements together in an - // inline div for better display. - $form['signup_reminder'] = array( - '#prefix' => '