Index: workflow.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/workflow/workflow.module,v
retrieving revision 1.75
diff -u -r1.75 workflow.module
--- workflow.module	29 Oct 2008 03:13:55 -0000	1.75
+++ workflow.module	2 Dec 2008 23:29:57 -0000
@@ -268,7 +268,6 @@
     else {
       // Schedule the the time to change the state.
       $comment = $node->workflow_comment;
-      $old_sid = workflow_node_current_state($node);
 
       if ($node->workflow_scheduled_date['day'] < 10) {
         $node->workflow_scheduled_date['day'] = '0' .
@@ -286,24 +285,7 @@
 
       $scheduled = $node->workflow_scheduled_date['year'] . $node->workflow_scheduled_date['month'] . $node->workflow_scheduled_date['day'] . ' ' . $node->workflow_scheduled_hour . 'Z';
       if ($scheduled = strtotime($scheduled)) {
-        // Adjust for user and site timezone settings.
-        global $user;
-        if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
-          $timezone = $user->timezone;
-        }
-        else {
-          $timezone = variable_get('date_default_timezone', 0);
-        }
-        $scheduled = $scheduled - $timezone;
-
-        // Clear previous entries and insert.
-        db_query("DELETE FROM {workflow_scheduled_transition} WHERE nid = %d", $node->nid);
-        db_query("INSERT INTO {workflow_scheduled_transition} VALUES (%d, %d, %d, %d, '%s')", $node->nid, $old_sid, $sid, $scheduled, $comment);
-
-        // Get name of state.
-        $state_name = db_result(db_query('SELECT state FROM {workflow_states} WHERE sid = %d', $sid));
-        watchdog('workflow', '@node_title scheduled for state change to %state_name on !scheduled_date', array('@node_title' => $node->title, '%state_name' => $state_name, '!scheduled_date' => format_date($scheduled)), WATCHDOG_NOTICE, l('view', "node/$node->nid/workflow"));
-        drupal_set_message(t('@node_title is scheduled for state change to %state_name on !scheduled_date', array('@node_title' => $node->title, '%state_name' => $state_name, '!scheduled_date' => format_date($scheduled))));
+        workflow_schedule_transition($node, $sid, $scheduled, isset($node->workflow_comment) ? $node->workflow_comment : NULL);
       }
     }
   }
@@ -465,6 +447,36 @@
 }
 
 /**
+ * Schedule a transition (change state of node)
+ *
+ * @param object $node
+ * @param int $sid
+ * @param int $scheduled
+ * @param string $comment
+ */
+function workflow_schedule_transition($node, $sid, $scheduled, $comment= '') {
+  // Adjust for user and site timezone settings.
+  global $user;
+  if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
+    $timezone = $user->timezone;
+  }
+  else {
+    $timezone = variable_get('date_default_timezone', 0);
+  }
+  $scheduled = $scheduled - $timezone;
+  $old_sid = workflow_node_current_state($node);
+
+  // Clear previous entries and insert.
+  db_query("DELETE FROM {workflow_scheduled_transition} WHERE nid = %d", $node->nid);
+  db_query("INSERT INTO {workflow_scheduled_transition} VALUES (%d, %d, %d, %d, '%s')", $node->nid, $old_sid, $sid, $scheduled, $comment);
+
+  // Get name of state.
+  $state_name = db_result(db_query('SELECT state FROM {workflow_states} WHERE sid = %d', $sid));
+  watchdog('workflow', '@node_title scheduled for state change to %state_name on !scheduled_date', array('@node_title' => $node->title, '%state_name' => $state_name, '!scheduled_date' => format_date($scheduled)), WATCHDOG_NOTICE, l('view', "node/$node->nid/workflow"));
+  drupal_set_message(t('@node_title is scheduled for state change to %state_name on !scheduled_date', array('@node_title' => $node->title, '%state_name' => $state_name, '!scheduled_date' => format_date($scheduled))));  
+}
+
+/**
  * Execute a transition (change state of a node).
  *
  * @param object $node
@@ -524,12 +536,13 @@
   $type = node_get_types('name', $node->type);
   watchdog('workflow', 'State of @type %node_title set to @state_name', array('@type' => $type, '%node_title' => $node->title, '@state_name' => $state_name), WATCHDOG_NOTICE, l('view', 'node/' . $node->nid));
 
+  // Clear any references in the scheduled listing.
+  db_query('DELETE FROM {workflow_scheduled_transition} WHERE nid = %d', $node->nid);
+  
   // Notify modules that transition has occurred. Actions should take place
   // in response to this callback, not the previous one.
   module_invoke_all('workflow', 'transition post', $old_sid, $sid, $node);
-
-  // Clear any references in the scheduled listing.
-  db_query('DELETE FROM {workflow_scheduled_transition} WHERE nid = %d', $node->nid);
+  
 }
 
 /**
@@ -596,7 +609,14 @@
  */
 function workflow_select_given_state_action($node, $context) {
   $comment = t($context['workflow_comment'], array('%title' => check_plain($node->title), '%state' => check_plain($context['state_name'])));
-  workflow_execute_transition($node, $context['target_sid'], $comment, $context['force']);
+  if($context['scheduled']) {
+    // schedule transition
+    workflow_schedule_transition($node, $context['target_sid'], strtotime($context['scheduled']), $comment);
+  }
+  else {
+    // transition occurs immediately
+    workflow_execute_transition($node, $context['target_sid'], $comment, $context['force']);
+  }
 }
 
 /**
@@ -624,6 +644,15 @@
     '#description' => t('If this box is checked, the new state will be assigned even if workflow permissions disallow it.'),
     '#default_value' => isset($context['force']) ? $context['force'] : '',
   );
+  $form['scheduled'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Schedule transition'),
+    '#description' => t('Schedule the transition for a later date, e.g. +1day, +1month. Leave blank to make transition immediate.'),
+    '#default_value' => isset($context['scheduled']) ? $context['scheduled'] : NULL,
+    '#element_validate' => array('workflow_scheduled_validate'),
+    '#size' => 60,
+    '#maxlength' => 60,
+  );
   $form['workflow_comment'] = array(
     '#type' => 'textfield',
     '#title' => t('Message'),
@@ -634,6 +663,20 @@
 }
 
 /**
+ * Validate scheduled field
+ *
+ * @param array $element
+ * @param array $form_state
+ */
+function workflow_scheduled_validate($element, &$form_state) {
+  $today = getdate();
+  $scheduled = strtotime($element['#value']);
+  if($scheduled < $today[0]) {
+    form_error($element, t('The transition time must occur in the future.'));
+  }
+}
+
+/**
  * Submit handler for "Change workflow state of post to new state" action
  * configuration form.
  *
@@ -646,6 +689,7 @@
     'state_name' => $state_name,
     'force' => $form_state['values']['force'],
     'workflow_comment' => $form_state['values']['workflow_comment'],
+    'scheduled' => $form_state['values']['scheduled'],
   );
 }
 
