If transition has comment and node is automatically published or unpublished for this transition (it's defined using "Actions" module) in workflow history are appeared two identical rows.

This bug take place because the function workflow_execute_transition calls itself through module_invoke_all (when "Actions" module publish node it calls node_save). Thus we have two calls:
1) through _workflow_node_to_state - it's normal call;
2) at the beginning of workflow_execute_transition (block if ($old_sid == $sid) {...}) - it's bug.
In order to fix this bug I suggest to add a static variable $hooks_process to control whether it's nested call of workflow_execute_transition.
The original code is:

function workflow_execute_transition($node, $sid, $comment = NULL) {
  $old_sid = workflow_node_current_state($node);
  if ($old_sid == $sid) { // stop if not going to a different state
    // Write comment into history though.
    if ($comment && !$node->_workflow_scheduled_comment) {
      $node->workflow_stamp = time();
      db_query("UPDATE {workflow_node} SET stamp = %d WHERE nid = %d", $node->workflow_stamp, $node->nid);
      _workflow_write_history($node, $sid, $comment);
    }
    return;
  }

  ...

  // 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);

  ...

}

The change should be:

function workflow_execute_transition($node, $sid, $comment = NULL) {
  static $hooks_process = false;
  $old_sid = workflow_node_current_state($node);
  if ($old_sid == $sid) { // stop if not going to a different state
    // Write comment into history though.
    if ($comment && !$node->_workflow_scheduled_comment && !$hooks_process) {
      $node->workflow_stamp = time();
      db_query("UPDATE {workflow_node} SET stamp = %d WHERE nid = %d", $node->workflow_stamp, $node->nid);
      _workflow_write_history($node, $sid, $comment);
    }
    return;
  }

  ...

  // Notify modules that transition has occurred. Actions should take place
  // in response to this callback, not the previous one.
  $hooks_process = true;
  module_invoke_all('workflow', 'transition post', $old_sid, $sid, $node);
  $hooks_process = false;

  ...

}

Comments

Bastlynn’s picture

Status: Active » Closed (won't fix)

Hi,

With the release of Drupal 7, Drupal 5 is no longer receiving security updates, reviews, or development from many contributed modules. Since 5 is now considered a depreciated version, you really should seriously look into upgrading to Drupal 6 or 7. The newer versions of Drupal work better, have more support, and will be safer (literally! security patches!) for your website. We are currently working on a new release for Workflow to Drupal 7. In light of that, further support for Drupal 5 issues is infeasible at the moment. Please consider upgrading to Drupal 6 or 7 in the near future - you'll be glad you did.

- Bastlynn