Updated: Comment #25

Problem/Motivation

The Rules work as expected. But I can't figure out the action that would print a system message "The state has been set to [new-state]".

Proposed resolution

#17 introduces Rules support for Workflow Field using 'EntityDefaultRulesController'

User interface changes

#7, #21, #22 give examples of Rules.

Original report by [username]

Got 2 rules. One that publishes a node when state is set to 'done' and another that unpublishes a node when state is set back to 'draft'. The Rules work as expected. But I can't figure out the action that would print a system message "The state has been set to [new-state]".

For example, when the value of the system message field is set to the following

- Old state was: [node:field-event-state]. ([node-unchanged:field-event-state])

the message displayed is

- Old state was: 2. (2)

Both tokens yield the same value (id). I can't figure which token will give me the 'new updated state' for the node.

Any suggestions?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bisonbleu’s picture

Issue summary: View changes
bisonbleu’s picture

Issue summary: View changes
zengenuity’s picture

I have the same problem. If you use the "Workflow State Changed" event, both node and node_unchanged have the original (unchanged) node value.

But, I found that the workflow changed event is triggered with additional variables that aren't exposed in the Rules interface. The attached patch exposes the Previous State and New State variables. If you use those instead of reading directly from the field, you can detect specific transitions. I realize this is probably not the suggested approach with Workflow Field, but it's a workaround that works for now.

johnv’s picture

Status: Active » Needs review

The Rules code for Workflow Field was a mere 1-to-1 copy, enough to not break things.
I struggled with the $node_variables, and did not see how to extend this for any entity or workflow Field.
Happy to commit your patch if you think it's valid after this info.
OR we can have others to amend, review it.

zengenuity’s picture

Rewrote the patch so that Workflow State Changed event works with any entity type. This patch also includes state tokens from the last patch. After digging into this, I don't think there's any way to get the changed entity, because I think the transition hook must fire before the node has actually been saved. (Is that right?) With the state tokens, you don't really need it, though. You can figure out the transition from those.

The main problem with this patch is that it's going to break pretty much all existing rules people have, because the "node" argument is not available anymore. It's now called "entity" and you need to add an "entity is of type node" condition to get access to the node-related tokens. Once you do that, it works though. I have been able to rewrite my existing rules to work with change. I think this is the way to go long term, but breaking everyone's rules sucks. I don't know what you want to do about that.

johnv’s picture

@bisonbleu, please state if you are using Workflow Node or Workflow Field. In the first case, we really have a problem, In the second case, Workflow Field is not supporting Rules, yet.

johnv’s picture

@zengenuity, to make the patch backwards compatible, the following can be inserted:

if (module_exists('workflownode')) {use current node_variables}
else {use new entity_variables}

Or set $entity_variables always, and include the old '$node_variables' as well (only in case of nodes, ofcourse). It might help people who are converting, but it would confuse new user because of the duplicated choice.

Another thing is that there is a difference between Workflow Node (old way) and Workflow Field (new way):
Workflow Node does not touch/change the node, since the workflow state is saved in a custom table. So, the 'pre/post transition' events/hooks are in 1 function call.
Workflow Field saves the state in a real Field. So, the hook/event 'post transition' is called when de entity/node hasn't been save yet, and there is no difference with the 'pre transition' (unless the 'pre transition' canceled the operation.).
I was in doubt wheter to remove the 'post transition' hook or not, in case of Workflow Field. I still think we should, but didn't have the guts to do it...

This is my rule to do something after a field_workflow has changed, without using workflow_rules:

{ "rules_state_changed" : {
    "LABEL" : "state changed",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules" ],
    "ON" : [ "node_update" ],
    "IF" : [
      { "entity_is_of_bundle" : {
          "entity" : [ "node" ],
          "type" : "node",
          "bundle" : { "value" : { "workflowfield" : "workflowfield" } }
        }
      },
      { "NOT data_is" : {
          "data" : [ "node:field-workflow" ],
          "value" : [ "node-unchanged:field-workflow" ]
        }
      }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "The state value is now [node:field-workflow]  (rules messsage)" } }
    ]
  }
}

If I can replicate this with a 'before saving content' event, I think we can remove the 'workflow_state_changed' event.
And if i can add an action to a new 'after saving a new workflow executed transition',
And we might remove the 'workflow_comment_added', because you can do this with 'after saving a new workflow executed transition' combined with a 'workflow_field did NOT change'. (but that might be difficult to configure.

Anyway, now that transitions are object, and states are fields, we might remove this 'contrib' code.

zengenuity’s picture

Okay, I see how this works now. I think the "workflow state changed" event should not be available if you don't have Workflow Node enabled. It's confusing. (especially, if like me, you have used Workflow before, just not Workflow Fields) Even after my other patch, I ran into more problems with the tokens for the workflow comment, which I was trying to get into a notification email. But, I just rewrote my rules to be based on the Workflow Executed Transition event, and they seem to work fine and I can get the workflow comment into the email without any code changes.

One downside of the "workflow executed transition" event I came across: it doesn't give me a way to access the target entity in the conditions, so I can't check the bundle type or other fields of the target entity. I'm fetching the node object in the actions section to print the title in my email, but you can't do a fetch in conditions, so it'd be nice to have access to the full entity there instead of just type and id.

I'm going to have multiple workflows on the site I'm building right now, but I can make sure to use different fields for each bundle and check the field_name to make sure I'm in the right workflow.

johnv’s picture

I think you ran again into my limited entity-programming skills.
The Transitions are real entities. Perhaps a entity-reference can be defined via the (existing) hook_entity_info or (new) hook_entity_propery_info or metadata_wrappers?

rtackett’s picture

John, for the basic rules integration, implement the default rules controller in entity_info (just like views). It is set to false if not explicitly stated.
'rules controller class' => 'EntityDefaultRulesController',

If the

if (module_exists('workflownode')) {use current node_variables}
else {use new entity_variables}

is implemented for rules, can the same be applied to make the entity version exportable?

johnv’s picture

I'm going to have multiple workflows

.
I am glad you are exploring the boundaries of this module. Expect some problems on the way if you have two workflows on the same bundle. There is a separate issue for this.

bisonbleu’s picture

Confirming that I'm using Workflow field (and not workflow_node).

rtackett’s picture

@bisonbleu See @johnv 's comment #6. tldr: rules isn't supported for wf field yet.

and then see my comment #10 . Basically, the default entity api rules controller class can be implemented on each workflow entity.

johnv’s picture

Title: Tokens [node:field-state] and [node-unchanged:field-state] have the same value » Add Rules support for Workflow Field
johnv’s picture

@zenguinity , IMO your patch #5 can be replaced by the suggstion in #10. Correct?

The following issue gives a recipe how to drilldown to the entity_type or entity of the Transition.
#1372062: Can`t get data selector via reference fields
However, In our case it does not work since the Transition does not contain a proper entity_reference. It should be repaired by declared some entity_properties. I prefer completing the entities, above custom code.

ATM i think about disabling the pre/post hooks for Workflow Field.

zengenuity’s picture

Yes, my patch isn't needed. I've actually backed it out of my current project and have rewritten my rules based on workflow executed transition instead of workflow state changed.

I'm not sure the repercussions of removing the pre/post hooks, but I do think you should add a conditional to check for Workflow Node before declaring the the workflow state changed event to Rules. That will prevent people from thinking that is going to work properly with just Workflow Field enabled.

johnv’s picture

I removed the custom Rules support for Workflow Field in favor of 'EntityDefaultRulesController' using this commit.

We need entityreference support in a follow-up patch.

bisonbleu’s picture

Alright, so I changed my rules to use the 'After saving a new workflow executed transition' event
instead of 'Workflow state has changed'.

Now when a system message value is set to '~.~ Old state: [WorkflowTransition:old-sid] // News state: [WorkflowTransition:sid]' I finally get what I was looking for:

"~.~ Old state: 11 // News state: 14"

This is great!

Now, at times, I would like to display the state labels (not the SIDs). But they are not available in the Replacements pattern list.

Hints?

johnv’s picture

Hmm, state is not a true entity. If it were, you would have the data at hand.

Sylense’s picture

With how the rules work in the latest dev I am no longer able to select a content type as a condition when using transition as the execution. I previously had it set to execute on Workflow State Change with a condition to check for a content type. I have several node types that I want to execute different actions on and use the same workflow. Am I missing something?

EDIT: I'm assuming this is in relation to comment #15 about entity reference

johnv’s picture

@Sylense, Instead of 'After a new executed transition', you can choose:
- after after updating existing content
- if having bundle X (this exposes the workflow_field
- comparison of field_workflow

{ "rules_after_changing_field_workflow" : {
    "LABEL" : "After changing field_workflow",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules" ],
    "ON" : [ "node_update" ],
    "IF" : [
      { "entity_is_of_bundle" : {
          "entity" : [ "node" ],
          "type" : "node",
          "bundle" : { "value" : { "workflowfield" : "workflowfield" } }
        }
      },
      { "NOT data_is" : {
          "data" : [ "node:field-workflow-open" ],
          "value" : [ "node-unchanged:field-workflow-open" ]
        }
      }
    ],
    "DO" : [
      { "drupal_message" : { "message" : "\u0022The value of field_workflow has been changed\u0022" } }
    ]
  }
}
johnv’s picture

O, and you CAN filter on entity_type (you cannot select on bundle/node type):

{ "rules_after_saving_new_transition_fo_entity_type" : {
    "LABEL" : "After saving new transition fo ENTITY_TYPE",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "workflow" ],
    "ON" : [ "WorkflowTransition_insert" ],
    "IF" : [
      { "data_is" : {
          "data" : [ "WorkflowTransition:entity-type" ],
          "value" : "\u0027taxonomy_term\u0027"
        }
      }
    ],
    "DO" : []
  }
}
bisonbleu’s picture

Thanks for those exports @johnv. They help a lot.

Supplemental question if I may. Accessing [WorkflowTransition:old-sid] and [WorkflowTransition:sid] is relatively easy. But what object do I need to load in order to access the TID token ?

I'd like to add a switch (using rules_conditional) and switch on TIDs (the transition id which can be found in the workflow_transitions table).

johnv’s picture

Category: Bug report » Support request
Status: Needs review » Active
Related issues: +#2147673: Re-implement "Workflow states" Views field and sort using a proper Relationship.

Regarding the references , Some-one needs to step up and implement the relations in entityinfo. See also #2147673: Re-implement "Workflow states" Views field and sort using a proper Relationship.
Regarding the TID, I don't think you can access that. The TID is not copied to the Executed Transition. You might issue a feature request, but as an alternative, you might create a rule for Entity or Transition that checks if (old_sid = X and new_sid = Y).

bisonbleu’s picture

Unfortunately, I can't help code wise.
I can test & work on documentation if that's helpful?

johnv’s picture

Title: Add Rules support for Workflow Field » How to use Rules support for Workflow Field
Issue summary: View changes
SocialNicheGuru’s picture

Status: Active » Needs review
johnv’s picture

Status: Needs review » Active

Resetting the status. The patch in #5 is not needed. See #10.

johnv’s picture

Component: Code » Rules