Problem/Motivation
Is it possible to freely define the allowed transitions on a given state?
This is not intended as a guard condition. On the contrary, it is meant to open up new transitions, based on conditions that the core workflow module cannot verify since it restricts itself to roles-based transitions.
This patch opens up the possibility for 3rd party modules to create their own data-driven transitions based on other criteria. For example, one such module would alter allowed state transition per user. Custom modules can freely define the reasoning behind such rules.
API changes
A new hook 'hook_workflow_permitted_state_transitions_alter()' is created, allowing to add or remove allowed transitions from/to the proposed list. The list is used to generate the options in the Workflow widget. See file workflow.api.php for more info.
Original report by [username]
In my current usage of the workflow, I need to let a *specific user* execute a transition, based on a user reference field in the node instead of a user role. I also ran into other scenarios that are more indirect. I thus came up with a generic mechanism to allow modules to specific dynamic transitions, given a state, a user account, and a node. This patch is attached.
The way it works is by calling 2 new hooks at the relevant places. hook_workflow_transitions_alter
alters the current allowable transitions to include new ones or stop existing ones. hook_workflow_transitions_info
lists the modules that will intercept the transitions to display them on the admin transition grid.
A typical usage of these hooks would be thus:
<?php
// Define the sids we care about.
define('WF_STATE_1', 1);
define('WF_STATE_2', 2);
define('WF_STATE_3', 3);
function mymodule_workflow_transitions_info() {
return array(
WF_STATE_3 => array(
WF_STATE_2 => t('Let the admin go back to state 2'),
WF_STATE_1 => t('Let the referenced user go back to state 1'),
),
);
}
function mymodule_workflow_transitions_alter(&$transitions, $sid, $account, $node) {
if ($sid == WF_STATE_3) {
if ($account->uid == 1) {
$transitions[WF_STATE_2] = workflow_get_state_name(WF_STATE_2);
}
if ($node->field_user[0]['uid'] == $account->uid) {
$transitions[WF_STATE_1] = workflow_get_state_name(WF_STATE_1);
}
}
}
?>
Thanks for your consideration. I'll be glad to enhance and polish this patch if needed.
Comment | File | Size | Author |
---|---|---|---|
workflow-dynamic-transitions.patch | 4.53 KB | infojunkie | |
Comments
Comment #1
maijs CreditAttribution: maijs commentedSubscribing.
Comment #2
infojunkie@maijs: why exportables?
Comment #3
maijs CreditAttribution: maijs commentedSorry, nevermind.
Comment #4
k4ml CreditAttribution: k4ml commentedMixing transitions info in db and code doesn't look right to me. Isn't this more like a guard condition on the transition, which should only been executed if the condition pass ?
Comment #5
infojunkie@k4ml: no, this is not intended as a guard condition. On the contrary, it is meant to open up new transitions, based on conditions that the core workflow module cannot verify since it restricts itself to roles-based transitions.
This patch opens up the possibility for 3rd party modules to create their own data-driven transitions based on other criteria. For example, one such module would alter the workflow state transition grid to show CCK user reference fields for each state. Only users referenced in the selected field would be able to make the transition. This information would be stored in a separate database table, and the new module would open up this transition through the hooks introduced in the current patch.
Comment #6
kepford CreditAttribution: kepford commentedSubscribing.
Comment #7
aquaphenixSubscribing
Comment #8
infojunkieFixing title.
Comment #9
Bastlynn CreditAttribution: Bastlynn commentedInteresting idea, can you roll me a patch against Drupal 7?
Comment #10
infojunkieI'm afraid I'm not working with D7 at the moment.
Comment #11
johnvI've added this to a meta issue:
#2144747: [META] Flexible transitions
Comment #12
colanThis will have to go into D7 first.
Comment #13
colanComment #14
johnvComment #16
johnvAbove commit adds a new hook, as described in the summary.
You can now create your own state machine with any custom logic you need.
Comment #17
infojunkieThanks for taking this to completion!
Comment #19
johnvThanks, nice to have some feedback from the crowd.