Index: workflow.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/workflow/workflow.module,v retrieving revision 1.51.2.1 diff -u -F^f -r1.51.2.1 workflow.module --- workflow.module 11 Nov 2006 20:05:24 -0000 1.51.2.1 +++ workflow.module 20 Nov 2006 02:31:14 -0000 @@ -383,7 +383,7 @@ function action_workflow_execute_transit // fire the transition watchdog('action', t('Changing workflow state of node id %id to %state', array('%id' => intval($node->nid), '%state' => check_plain($new_state_name)))); - workflow_execute_transition($node, $new_state); + workflow_execute_transition($node, $new_state, '"next state" action'); watchdog('action', t('Changed workflow state of node id %id to %state', array('%id' => intval($node->nid), '%state' => check_plain($new_state_name)))); break; @@ -410,6 +410,87 @@ function action_workflow_execute_transit } /** + * Implementation of a Drupal action. + * Changes the workflow state of a node to ANY state of the workflow. + */ +function action_workflow_transition_to($op, $edit = array(), &$node) { + switch($op) { + case 'do': + $states = workflow_field_choices($node); + $new_state = $edit['new_state']; + $new_state_name = $states[$new_state]; + if (!isset($states[$new_state])) { + watchdog('action', t('Node %id cannot transition to state %state', array('%id' => intval($node->nid), '%state' => check_plain($new_state_name)))); + return; + } + + if (isset($edit['terms']) && is_array($edit['terms']) && count($edit['terms']) > 0 && count(array_intersect(array_keys($edit['terms']), array_keys(taxonomy_node_get_terms($node->nid)))) == 0) { + // do nothing + return; + } + + if (!isset($states[$new_state])) { + watchdog('action', t('Node %id cannot transition to state %state', array('%id' => intval($node->nid), '%state' => check_plain($new_state_name)))); + } + else { + watchdog('action', t('Changing workflow state of node %id to %state', array('%id' => intval($node->nid), '%state' => check_plain($new_state_name)))); + workflow_execute_transition($node, $new_state, 'Action: '.$edit['actions_desc']); + watchdog('action', t('Changed workflow state of node %id to %state', array('%id' => intval($node->nid), '%state' => check_plain($new_state_name)))); + } + break; + + case 'metadata': + return array( + 'description' => t('Change workflow state of a node to any state'), + 'type' => t('Workflow'), + 'batchable' => TRUE, + 'configurable' => TRUE, + ); + + // return an HTML config form for the action + case 'form': + $wids = workflow_get_all(); + foreach ($wids as $wid => $wname) { + $states = workflow_get_states($wid); + $options[$wname] = $states; + } + + $form = array(); + $form['new_state'] = array( + '#type' => 'select', + '#options' => $options, + '#default_value' => $edit['new_state'], + '#description' => t('Select the workflow state to switch to No transition will occur if a node triggers this action that does not belong to the selected workflow.') + ); + + $form['filter'] = array( + '#type' => 'fieldset', + '#title' => 'Filter' + ); + + $options = taxonomy_form_all(); + $form['filter']['terms'] = array( + '#type' => 'select', + '#title' => t('Filter'), + '#options' => $options, + '#multiple' => true, + '#size' => min(9, _sched_act_count_array($options)), + '#default_value' => isset($edit['terms']) ? $edit['terms'] : 0, + '#description' => t('Only fire this action if the node has at least one of the terms selected. Leave blank to operate on any triggering node.'), + ); + return $form; + + // validate the HTML form + case 'validate': + return TRUE; + + // process the HTML form to store configuration + case 'submit': + return $edit; + } +} + +/** * Get the states one can move to for a given node. * * @param object $node @@ -1099,7 +1180,7 @@ function workflow_actions_form_build($wi $actions = actions_actions_map(actions_get_all_actions()); $options = array(t('None')); foreach ($actions as $aid => $action) { - $options[$aid] = $action['description']; + $options[$action['type']][$aid] = $action['description']; } $header = array( array('data' => t('Transition'), 'colspan' => '3'), @@ -1452,7 +1533,7 @@ function workflow_actions_remove($tid, $ * @param object $node * @param int $sid */ -function _workflow_node_to_state($node, $sid, $comment = NULL) { +function _workflow_node_to_state(&$node, $sid, $comment = NULL) { global $user; if (db_result(db_query("SELECT nid FROM {workflow_node} WHERE nid = %d", $node->nid))) { db_query("UPDATE {workflow_node} SET sid = %d, uid = %d WHERE nid = %d", $sid, $user->uid, $node->nid); @@ -1461,11 +1542,25 @@ function _workflow_node_to_state($node, db_query("INSERT INTO {workflow_node} (nid, sid, uid) VALUES (%d, %d, %d)", $node->nid, $sid, $user->uid); } _workflow_write_history($node, $sid, $comment); + + // A node's workflow may be updated programatically during a + // request. Make sure our rep invariant is maintained. + $node->workflow = $node->_workflow = $sid; } function _workflow_write_history($node, $sid, $comment) { global $user; - db_query("INSERT INTO {workflow_node_history} (nid, old_sid, sid, uid, comment, stamp) VALUES (%d, %d, %d, %d, '%s', %d)", $node->nid, $node->_workflow, $sid, $user->uid, $comment, time()); + + // A node's workflow may be updated programatically more than once + // per request. Make sure log entries are sorted correctly. + static $prev_stamp = 0; + $stamp = time(); + if ($stamp == $prev_stamp) { + ++$stamp; + } + $prev_stamp = $stamp; + + db_query("INSERT INTO {workflow_node_history} (nid, old_sid, sid, uid, comment, stamp) VALUES (%d, %d, %d, %d, '%s', %d)", $node->nid, $node->_workflow, $sid, $user->uid, $comment, $stamp); } /**