Only in sites/all/modules/workflow/: .svn
Common subdirectories: workflow/includes and sites/all/modules/workflow/includes
Common subdirectories: workflow/translations and sites/all/modules/workflow/translations
diff -up workflow/workflow.info sites/all/modules/workflow/workflow.info
--- workflow/workflow.info	2010-03-03 13:40:18.000000000 -0500
+++ sites/all/modules/workflow/workflow.info	2010-09-07 18:11:32.000000000 -0400
@@ -5,7 +5,7 @@ package = "Workflow"
 core = 6.x
 
 ; Information added by drupal.org packaging script on 2010-03-03
-version = "6.x-1.4"
+version = "6.x-1.4p2"
 core = "6.x"
 project = "workflow"
 datestamp = "1267641618"
diff -up workflow/workflow.install sites/all/modules/workflow/workflow.install
--- workflow/workflow.install	2009-06-05 17:33:23.000000000 -0400
+++ sites/all/modules/workflow/workflow.install	2010-08-16 10:42:17.000000000 -0400
@@ -39,6 +39,14 @@ function workflow_schema() {
     'indexes' => array(
       'type' => array('type', 'wid')),
   );
+  $schema['workflow_node_map'] = array(
+    'description' => t('workflow per-node associations.'),
+    'fields' => array(
+      'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+      'wid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)),
+    'indexes' => array(
+  		'nid_wid' => array('nid', 'wid')),
+  );
   $schema['workflow_transitions'] = array(
     'fields' => array(
       'tid'        => array('type' => 'serial', 'not null' => TRUE),
diff -up workflow/workflow.module sites/all/modules/workflow/workflow.module
--- workflow/workflow.module	2010-03-03 13:17:02.000000000 -0500
+++ sites/all/modules/workflow/workflow.module	2010-09-07 18:32:11.000000000 -0400
@@ -112,7 +112,7 @@ function workflow_menu() {
  */
 function workflow_node_tab_access($node = NULL) {
   global $user;
-  $wid = workflow_get_workflow_for_type($node->type);
+  $wid = workflow_get_workflow_for_node($node);
   if ($wid === FALSE) {
     // No workflow associated with this node type.
     return FALSE;
@@ -223,7 +223,7 @@ function workflow_nodeapi(&$node, $op, $
       // Note no break; fall through to 'update' case.
     case 'update':
       // Do nothing if there is no workflow for this node type.
-      $wid = workflow_get_workflow_for_type($node->type);
+      $wid = workflow_get_workflow_for_node($node);
       if (!$wid) {
         break;
       }
@@ -428,7 +428,7 @@ function workflow_form_alter(&$form, $fo
       $node = node_load($form['nid']['#value']);
     }
     $choices = workflow_field_choices($node);
-    $wid = workflow_get_workflow_for_type($node->type);
+    $wid = workflow_get_workflow_for_node($node);
     $states = workflow_get_states($wid);
     // If this is a preview, the current state should come from
     // the form values, not the node, as the user may have changed
@@ -695,7 +695,7 @@ function workflow_select_given_state_act
  */
 function workflow_field_choices($node) {
   global $user;
-  $wid = workflow_get_workflow_for_type($node->type);
+  $wid = workflow_get_workflow_for_node($node);
   if (!$wid) {
     // No workflow for this type.
     return array();
@@ -739,7 +739,7 @@ function workflow_node_current_state($no
 
   if (!$sid && !empty($node->type)) {
     // No current state. Use creation state.
-    $wid = workflow_get_workflow_for_type($node->type);
+    $wid = workflow_get_workflow_for_node($node);
     $sid = _workflow_creation_state($wid);
   }
   return $sid;
@@ -972,6 +972,33 @@ function workflow_get_name($wid) {
 }
 
 /**
+ * Get ID of a workflow for a node.
+ *
+ * @param $node
+ *   A node object.
+ * @return int
+ *   The ID of the workflow or FALSE if no workflow is mapped to this node.
+ */
+function workflow_get_workflow_for_node($node, $refresh=FALSE) {
+  static $cache;
+  if(isset($cache[$node->nid]) && !$refresh) {
+    $wid = $cache[$node->nid];
+  } elseif ($refresh) {
+    $cache[$node->nid] = $refresh;
+    $wid = $refresh;
+  } else {
+    $hook_returns = module_invoke_all('workflow_node_map', $node);
+    if ($wid = array_pop($hook_returns)) {
+      $cache[$node->nid] = $wid;
+    }
+  }
+  if (!isset($wid)) {
+    $wid = workflow_get_workflow_for_type($node->type);
+  }
+  return $wid;
+}
+
+/**
  * Get ID of a workflow for a node type.
  *
  * @param $type
@@ -1479,17 +1506,12 @@ function workflow_hook_info() {
     return;
   }
   $trigger_page = substr($_GET['q'], 0, 28) == 'admin/build/trigger/workflow';
-  if ($trigger_page && $wid = arg(4)) {
-    $result = db_query("SELECT tm.type, w.wid, w.name, ws.state, wt.tid, wt.sid, wt.target_sid FROM {workflow_type_map} tm LEFT JOIN {workflows} w ON tm.wid = w.wid LEFT JOIN {workflow_states} ws ON w.wid = ws.wid LEFT JOIN {workflow_transitions} wt ON ws.sid = wt.sid WHERE w.wid = %d AND wt.target_sid IS NOT NULL ORDER BY tm.type, ws.weight", $wid);
-  }
-  else {
-    $result = db_query("SELECT tm.type, w.wid, w.name, ws.state, wt.tid, wt.sid, wt.target_sid FROM {workflow_type_map} tm LEFT JOIN {workflows} w ON tm.wid = w.wid LEFT JOIN {workflow_states} ws ON w.wid = ws.wid LEFT JOIN {workflow_transitions} wt ON ws.sid = wt.sid WHERE wt.target_sid IS NOT NULL ORDER BY tm.type, ws.weight");
-  }
+  $result = db_query("SELECT nt.type, ws.wid, wt.tid, wt.sid, wt.target_sid FROM node_type nt, workflow_transitions wt INNER JOIN workflow_states ws ON wt.sid = ws.sid");
   while ($data = db_fetch_object($result)) {
     $pseudohooks['workflow-'. $data->type .'-'. $data->tid] = array('runs when' => t('When %type moves from %state to %target_state', array('%type' => $data->type, '%state' => $states[$data->sid], '%target_state' => $states[$data->target_sid])));
   }
   // $pseudohooks will not be set if no workflows have been assigned
-  // to node types.
+  // to node types. UPDATE: this is NOT true anymore after per-node basis patch. NYSETECH-677
   if (isset($pseudohooks)) {
     return array(
       'workflow' => array(
@@ -1523,7 +1545,7 @@ function workflow_token_values($type, $o
     case 'workflow':
       $node = (object)$object;
 
-      if ($wid = workflow_get_workflow_for_type($node->type)) {
+      if ($wid = workflow_get_workflow_for_node($node)) {
         $values['workflow-name'] = workflow_get_name($wid);
         $states = workflow_get_states($wid);
       }
@@ -1629,4 +1651,4 @@ function workflow_content_extra_fields($
     'weight' => 10,
   );
   return $extra;
-}
\ No newline at end of file
+}
diff -up workflow/workflow.pages.inc sites/all/modules/workflow/workflow.pages.inc
--- workflow/workflow.pages.inc	2010-02-15 22:44:19.000000000 -0500
+++ sites/all/modules/workflow/workflow.pages.inc	2010-08-16 10:42:17.000000000 -0400
@@ -11,7 +11,7 @@
  */
 function workflow_tab_page($node = NULL) {
   drupal_set_title(check_plain($node->title));
-  $wid = workflow_get_workflow_for_type($node->type);
+  $wid = workflow_get_workflow_for_node($node);
   $states_per_page = variable_get('workflow_states_per_page', 20);
   $result = db_query("SELECT sid, state FROM {workflow_states} WHERE status = 1 ORDER BY sid");
   while ($data = db_fetch_object($result)) {
@@ -124,7 +124,7 @@ function workflow_tab_form($form_state, 
   $min = $states[$current] == t('(creation)') ? 1 : 2;
   // Only build form if user has possible target state(s).
   if (count($choices) >= $min) {
-    $wid = workflow_get_workflow_for_type($node->type);
+    $wid = workflow_get_workflow_for_node($node);
     $workflow = workflow_load($wid);
     $form['#wf'] = $workflow;
     $name = check_plain((t($workflow->name)));
