I'm working with a client that needs to associate workflows with nodes based on more complex criteria than 'node type' -- news articles posted by one department need a different workflow than those posted by another, for example. While it's technically possible to create duplicate content types for each one, this could easily result in dozens of copies of *each* content type, just to allow workflow associations.

The attached patch is a first stab at a way of setting up these richer associations. It simply associates workflows based on the $node object itself rather than the $node->type, and defaults to the same behavior we have now while allowing other modules to implement a hook to take over the mapping. Because Workflow respects the current state and its workflow association, subsequent displays show the proper information even if they don't leverage the new hook.

Additional ideas and/or brainstorming welcome.

CommentFileSizeAuthor
#10 workflow-6.x-1.4p2.patch7.4 KBYe
#2 workflow-by-node.patch4.07 KBeaton

Comments

mitchell’s picture

no patch

eaton’s picture

StatusFileSize
new4.07 KB

You're quite right. Thanks!

Encarte’s picture

How about the same node type being able to use more than one workflow? Or, in other words, how about breaking the workflows into peaces that can be used on the node types?

For instances, I have a workflow like this:

1 > 2 > 3 > 4 > 5 > 6 > 7 > 8

I would get two different workflows:

1 > 2 > 3 > 4

5 > 6 > 7 > 8

and I could change from one to another on certain states, like this, on a node type:

    > 1 > 2 > 3 > 4
0 > 
    > 5 > 6 > 7 > 8

or like this on some other node type:

> 5 > 6 > 7 > 8 >
                     > 1 > 2 > 3 > 4

or even like this:

    > 1 > 2 > 3 > 4
0 > 
    > 5 > 6 > 7 > 8 >
                         > 1 > 2 > 3 > 4

... or whatever. You just would need to set up the transition permissions (by role) from one workflow to another on the desired state.

With a system like this different roles would have the choice (or not) to make different ways through the combination of workflows. And you could create flexible pieces of workflow instead of having to repeat/copy *almost* the same workflow from one node type to another.

I'm not a developer, so, I'm sory if I just suggested something impossible...

deekayen’s picture

I've been doing something like that without patching. It's a matter of finding out what flows each role is supposed to have. Our client gave us a Visio chart with where the node could flow to between the roles. It all boils down to granting the correct transition permissions for each role within the workflow.

Each department might need their own set of states within the workflow, which is why I created http://drupal.org/project/workflow_named_transitions. I created state names that were friendly for managing which department the state belonged to and then made end-user friendly names with the named transitions. With each department having their own states, you can set the accounting role to only have permission to advance through other accounting states.

The advantage is that later when you find out that vendors need to send to managers for approval and then to accounting for a PO number, and then back to manager for another approval, then to marketing for coordinating with the next ad, and back to the manager for another approval, the inter-departmental state changes can still happen.

Now that I've said it should be possible as-is, your patch doesn't appear to pass any arguments to the hook (like $node). There also seems to be a big gap in how exactly all the multiple different departmental workflows would be assigned to the content type and then how the alternate ones would disappear after creation, though I guess the later would just be solved with transition access permissions.

Seems like you're making it harder than it should be. I'm interested in talking it out anyway (IRC?) when we can manage to meet pings.

eaton’s picture

Now that I've said it should be possible as-is, your patch doesn't appear to pass any arguments to the hook (like $node). There also seems to be a big gap in how exactly all the multiple different departmental workflows would be assigned to the content type and then how the alternate ones would disappear after creation, though I guess the later would just be solved with transition access permissions.

Yyyyyeaaaah. That was actually a mistake with which version of the patch got uploaded; the $node itself was passed in on the version I was testing. That was the 'actual use case' -- assigning a given workflow based on what taxonomy term a node had assigned to it.

It's not perfect, naturally, and there are holes, but It's the start of a process, I think. I'm very curious to check out named transitions to see how it might fit in. The use case I'm working on for a client is per-department workflows, where some areas have extra red tape that needs to be cut through before a 'story' or 'news' node can be published.

Ye’s picture

Thanks Easton!!

This is exactly what we need for the moment. At least it sheds some bright light on how to associate workflow with a specific node instead of node type. Now the missing piece would be how to efficiently implement hook_workflow_node_map() to map out the association. I'd like to hear some recommendations on that the way to map out nodes to workflows of course I acknowledge that it could be a site specific topic. Right off top of my head, I am thinking of using a taxomy term but I am unsure if that would be exportable . Of course, there are other way where we alter the node entry form in core to add a new workflow field but to my requires more coding that it should. If only certain node types (aka content type) require the per-node basis workflow, then having an additional cck field called workflow would be also doable.

In any case, I am subscribing this!

Ye’s picture

Additional comments about the patch file Eaton posted above:

* You will have to implement hook_workflow_node_map() yourself in your module or have one additional function in workflow module called "workflow_workflow_node_map" to implement logic to determine which node is mapped to which workflow (some additional table storing that information may be needed so that an admin menu page can assign those association mappings.)

* Some information about the node should be passed into hook_workflow_node_map(), according to Eaton's comment. so the below line in original patch file:

+  if ($wid = module_invoke_all('workflow_node_map')) {

should really be:

+  if ($wid = module_invoke_all('workflow_node_map', $node)) {
Ye’s picture

Another gotcha about that initial patch is that module_invoke_all() returns an array of returns for all hook functions. if your hook_workflow_node_map() returns FALSE because the given node doesn't have a per-node workflow setting, it will turn OFF the workflow tab because the way workflow_get_workflow_for_node() is written, which is an undesired behavior.

I think this might be better.

function workflow_get_workflow_for_node($node) {
  $hook_returns = module_invoke_all('workflow_node_map', $node);
  if ($wid = array_pop($hook_returns)) {
    return $wid;
  }
  else {
    return workflow_get_workflow_for_type($node->type);
  }
}
Ye’s picture

Be careful of another gotcha with workflow_hook_info().

If you applied a per-node basis patch, and switched a couple nodes to a workflow other than the default workflow that is assigned to that content type (of those nodes), you will NOT get the proper triggers (the ones with switched workflow names) displayed in the trigger admin page's drop-down list of options. The only triggers you get are the state transition ones that are associated with the default workflow for that content type.

Ye’s picture

StatusFileSize
new7.4 KB

Here is the new patch for per-node basis workflow based on Eaton's patch. Use the below snippet of hook_form_alter upon node creation for switching workflows. Make sure you have this snippet of code in your own module and replace "hook" with your module name.

/**
 * Implementation of hook_form_alter(&$form, &$form_state, $form_id).
 * 
 * Tap into the node creation form to add workflow switch option.
 */
//function hook_form_workflow_tab_form_alter(&$form, &$form_state) {
function hook_form_alter(&$form, &$form_state, $form_id) {
  if (isset($form['#id']) && $form['#id'] == 'node-form' && empty($form['nid']['#value'])) {
    $content_type = $form['type']['#value'];
    $wid = workflow_get_workflow_for_type($content_type); //default to workflow assigned to the node's content type
    //Skip the workflow selector dropdown if "Display Workflow Form for:" checkboxes aren't checked.
    if (!in_array('node', variable_get('workflow_' . $content_type, array()))) {
      return;
    }
    $form['hook']['wid_for_node'] = array(
      '#type' => 'select', 
      '#title' => t('Workflow setting'), 
      '#default_value' => $wid,
      '#options' => array('<' . t('None') . '>') + workflow_get_all() ,
      '#description' => t('Default workflow assignment is based on content type. However you may override default workflow setting on a per-node basis.'),
    );
  }

}

/**
 * Save node to node to workflow mapping post-save
 * @param drupal form $form
 * @param drupal form state $form_state
 */
function hook_nodeapi(&$node, $op) {
  switch ($op) {
    case 'insert':
      if ($node->nid && property_exists($node, 'wid_for_node')) {
        $node_id = $node->nid;
        $new_wid = $node->wid_for_node;
        $workflow_node_map = new stdClass();
        $workflow_node_map->nid = $node_id;
        $workflow_node_map->wid = $new_wid;
        drupal_write_record('workflow_node_map', $workflow_node_map);
        workflow_get_workflow_for_node($node, $new_wid); //update the cache
      }
  }
}
heatherann’s picture

I've been doing something like that without patching. It's a matter of finding out what flows each role is supposed to have. Our client gave us a Visio chart with where the node could flow to between the roles. It all boils down to granting the correct transition permissions for each role within the workflow.

I'm intrigued by this idea but I can't see how it works for this use case.

If we have a content type 'articles', and Marketing and Operations can both publish them, don't both teams have the same access once they are published? If Marketing is allowed to edit a published article, then they can edit something published by any team. Or do you have more than one 'published' state, based on who should have future editing rights?

I can't see how to say "You can edit this book in ABC state, but not that book in ABC state" just by editing the transition permissions.

Bastlynn’s picture

Status: Needs work » Closed (won't fix)

This situation strikes me as making this more complicated than it ought to be, where you may need to go back to your human users and ask them to sort things out on that end of things. Otherwise, as much as you hate making a set of incredibly complex workflows - that is what you have when you look at it.

Since this request is over a year old, I'm going to assume a solution was found or you've moved on. If not, please get updated to the latest versions of all modules and make a request for it against Drupal 7 if the problem is still there and I'll be glad to take a look at it.

kenorb’s picture

socialnicheguru’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev

I would like multiple workflows associated with a node.

There are other business rules that can be applied.
It might be a business rule around content promotion to various states.

I do believe like in #12 that it would be upto the user to know which workflows should apply

Here is a use case:
http://drupal.org/node/1891460

johnv’s picture

Status: Closed (won't fix) » Postponed

I am reopening this issue, just to see how the new Workflow Field module (in D7) might resolve this issue.
See #2019345: Create a 'Workflow Field' with Widget, Formatter, Fieldtype
At least, it should be possible to add 2 workflows to a node type, and some custom code (conditional fields) to determine which one to show.

johnv’s picture

I've added this to a meta issue:
#2144747: [META] Flexible transitions

colan’s picture

Issue summary: View changes
Parent issue: » #2144747: [META] Flexible transitions
johnv’s picture

Status: Postponed » Closed (won't fix)

Back to "won't fix", since this is possible in D7 using Workflow Field and hook_workflow('transition permitted').
The issue is still mentioned in the META issue for inspiration.

johnv’s picture

Status: Closed (won't fix) » Closed (duplicate)
Related issues: +#744272: Allow dynamic/flexible/freely definable transitions per state

ITMT in the D7 version, a new hook_alter is introduced, that allows you to change the permitted transitions.
see workflow.api.php or #744272: Allow dynamic/flexible/freely definable transitions per state