Index: workflow.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/workflow/workflow.module,v
retrieving revision 1.83.2.18
diff -u -p -r1.83.2.18 workflow.module
--- workflow.module	25 Oct 2010 02:13:48 -0000	1.83.2.18
+++ workflow.module	9 Feb 2011 12:31:17 -0000
@@ -790,36 +790,48 @@ function workflow_workflow($op, $old_sta
         break;
       }
       $tid = workflow_get_transition_id($old_state, $new_state);
+      // Run specific type actions.
       $op = 'workflow-'. $node->type .'-'. $tid;
-      $aids = _trigger_get_hook_aids('workflow', $op);
-      if ($aids) {
-        $context = array(
-          'hook' => 'workflow',
-          'op' => $op,
-        );
-
-        // We need to get the expected object if the action's type is not 'node'.
-        // We keep the object in $objects so we can reuse it if we have multiple actions
-        // that make changes to an object.
-        foreach ($aids as $aid => $action_info) {
-          if ($action_info['type'] != 'node') {
-            if (!isset($objects[$action_info['type']])) {
-              $objects[$action_info['type']] = _trigger_normalize_node_context($action_info['type'], $node);
-            }
-            // Pass the node as the object for actions of type 'system'.
-            if (!isset($objects[$action_info['type']]) && $action_info['type'] == 'system') {
-              $objects[$action_info['type']] = $node;
-            }
-            // Since we know about the node, we pass that info along to the action.
-            $context['node'] = $node;
-            $result = actions_do($aid, $objects[$action_info['type']], $context);
-          }
-          else {
-            actions_do($aid, $node, $context);
-          }
+      _workflow_trigger_actions_do($op, $node);
+      // Run global actions.
+      $op = 'workflow-'. $tid;
+      _workflow_trigger_actions_do($op, $node);
+      break;
+  }
+}
+
+/**
+ * Auxiliar function to call the associated action using the actions_do()
+ * function.
+ */
+function _workflow_trigger_actions_do($op, $node) {
+  $aids = _trigger_get_hook_aids('workflow', $op);
+  if ($aids) {
+    $context = array(
+      'hook' => 'workflow',
+      'op' => $op,
+    );
+
+    // We need to get the expected object if the action's type is not 'node'.
+    // We keep the object in $objects so we can reuse it if we have multiple actions
+    // that make changes to an object.
+    foreach ($aids as $aid => $action_info) {
+      if ($action_info['type'] != 'node') {
+        if (!isset($objects[$action_info['type']])) {
+          $objects[$action_info['type']] = _trigger_normalize_node_context($action_info['type'], $node);
         }
+        // Pass the node as the object for actions of type 'system'.
+        if (!isset($objects[$action_info['type']]) && $action_info['type'] == 'system') {
+          $objects[$action_info['type']] = $node;
+        }
+        // Since we know about the node, we pass that info along to the action.
+        $context['node'] = $node;
+        $result = actions_do($aid, $objects[$action_info['type']], $context);
       }
-      break;
+      else {
+        actions_do($aid, $node, $context);
+      }
+    }
   }
 }
 
@@ -1487,12 +1499,20 @@ function workflow_hook_info() {
   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");
   }
+  $pseudohooks = array();
+  $pseudohooks_global = array();
   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])));
+    if (!isset($pseudohooks_global['workflow-'. $data->tid])) {
+      $pseudohooks_global['workflow-'. $data->tid] = array('runs when' => t('When any node moves from %state to %target_state', array('%state' => $states[$data->sid], '%target_state' => $states[$data->target_sid])));
+    }
   }
+  // Merge specific type actions with global actions
+  $pseudohooks = array_merge($pseudohooks, $pseudohooks_global);
+
   // $pseudohooks will not be set if no workflows have been assigned
   // to node types.
-  if (isset($pseudohooks)) {
+  if (count($pseudohooks)) {
     return array(
       'workflow' => array(
         'workflow' => $pseudohooks,
