workflow_admin_ui.page.transitions.inc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. /**
  3. * @file
  4. * Provides an Admin UI page for the Workflow Transitions.
  5. */
  6. /**
  7. * Menu callback. Edit a workflow's transitions.
  8. *
  9. * @param array $transitions from values.
  10. * Transitions, for example:
  11. * 18 => array(
  12. * 20 => array(
  13. * 'author' => 1,
  14. * 1 => 0,
  15. * 2 => 1,
  16. * )
  17. * )
  18. * means the transition from state 18 to state 20 can be executed by
  19. * the node author or a user in role 2. The $transitions array should
  20. * contain ALL transitions for the workflow.
  21. * @param Workflow $workflow
  22. * The Workflow object.
  23. *
  24. * @return array
  25. * HTML form and permissions table.
  26. */
  27. function workflow_admin_ui_transitions_form($form, &$form_state, $workflow, $op) {
  28. // Make sure we have a workflow.
  29. if ($workflow) {
  30. $form = array();
  31. $form['workflow'] = array(
  32. '#type' => 'value',
  33. '#value' => $workflow,
  34. );
  35. $form['transitions'] = _workflow_admin_ui_transition_grid_form($form, $form_state, $workflow);
  36. $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
  37. return $form;
  38. }
  39. }
  40. /**
  41. * Form builder. Build the grid of transitions for defining a workflow.
  42. *
  43. * Some special situations exist:
  44. * - it is not allowed to go to the '(creation)' state.
  45. * - all roles are permitted to use the 'stay on this state' transition.
  46. * So, this is hidden from the user.
  47. *
  48. * @param Workflow $workflow
  49. * The Workflow object.
  50. */
  51. function _workflow_admin_ui_transition_grid_form($form, &$form_state, $workflow) {
  52. $form = array('#tree' => TRUE);
  53. $states = $workflow->getStates($all = 'CREATION');
  54. if (!$states) {
  55. $form['error'] = array(
  56. '#type' => 'markup',
  57. '#value' => t('There are no states defined for this workflow.'),
  58. );
  59. return $form;
  60. }
  61. $roles = workflow_get_roles();
  62. foreach ($states as $state1) {
  63. $from = $state1->sid;
  64. foreach ($states as $state2) {
  65. // Don't allow transition TO '(creation)'.
  66. if (!$state2->isCreationState()) {
  67. $to = $state2->sid;
  68. $stay_on_this_state = ($to == $from);
  69. // Generate checkboxes for each transition.
  70. foreach ($roles as $rid => $role_name) {
  71. $checked = $stay_on_this_state;
  72. $config_transitions = $workflow->getTransitionsBySidTargetSid($from, $to);
  73. if ($config_transition = reset($config_transitions)) {
  74. $checked |= $config_transition->isAllowed(array($rid));
  75. }
  76. $form[$from][$to][$rid] = array(
  77. '#type' => $stay_on_this_state ? 'hidden' : 'checkbox',
  78. '#title' => check_plain($role_name),
  79. '#default_value' => $checked,
  80. '#disabled' => $stay_on_this_state,
  81. );
  82. }
  83. }
  84. }
  85. }
  86. return $form;
  87. }
  88. /**
  89. * Theme the workflow editing form.
  90. *
  91. * @see workflow_edit_form()
  92. */
  93. function theme_workflow_admin_ui_transitions_form($variables) {
  94. $output = '';
  95. $form = $variables['form'];
  96. $workflow = $form['workflow']['#value'];
  97. if ($workflow) {
  98. drupal_set_title(t('Edit workflow %name transitions', array('%name' => $workflow->getName())), PASS_THROUGH);
  99. $states = $workflow->getStates($all = 'CREATION');
  100. if ($states) {
  101. $roles = workflow_get_roles();
  102. $header = array(array('data' => t('From / To') . ' &nbsp;' . WORKFLOW_ADMIN_UI_ARROW));
  103. $rows = array();
  104. foreach ($states as $state) {
  105. $label = $state->label();
  106. // Don't allow transition TO (creation).
  107. if (!$state->isCreationState()) {
  108. $header[] = array('data' => $label);
  109. }
  110. $row = array(array('data' => $label));
  111. foreach ($states as $nested_state) {
  112. // Don't allow transition TO (creation).
  113. if ($nested_state->isCreationState()) {
  114. continue;
  115. }
  116. if (TRUE || $nested_state != $state) {
  117. // Render checkboxes for each transition.
  118. $from = $state->sid;
  119. $to = $nested_state->sid;
  120. $cell = '';
  121. foreach ($roles as $rid => $role_name) {
  122. $cell .= drupal_render($form['transitions'][$from][$to][$rid]);
  123. }
  124. $row[] = array('data' => $cell);
  125. }
  126. else {
  127. $row[] = array('data' => '');
  128. }
  129. }
  130. $rows[] = $row;
  131. }
  132. $output .= theme('table', array('header' => $header, 'rows' => $rows));
  133. }
  134. else {
  135. $output = t('There are no states defined for this workflow.');
  136. }
  137. $output .= drupal_render_children($form);
  138. return $output;
  139. }
  140. }
  141. /**
  142. * Validate the workflow editing form.
  143. *
  144. * @see workflow_edit_form()
  145. */
  146. function workflow_admin_ui_transitions_form_validate($form, $form_state) {
  147. $workflow = $form_state['values']['workflow'];
  148. $wid = $workflow->wid;
  149. // Make sure 'author' is checked for (creation) -> [something].
  150. $creation_state = $workflow->getCreationState();
  151. $creation_sid = $creation_state->sid;
  152. if (isset($form_state['values']['transitions'][$creation_sid]) && is_array($form_state['values']['transitions'][$creation_sid])) {
  153. foreach ($form_state['values']['transitions'][$creation_sid] as $roles) {
  154. if ($roles[WORKFLOW_ROLE_AUTHOR_RID]) {
  155. $author_has_permission = TRUE;
  156. break;
  157. }
  158. }
  159. }
  160. $state_count = db_query('SELECT COUNT(sid) FROM {workflow_states} WHERE wid = :wid', array(':wid' => $wid))->fetchField();
  161. if (empty($author_has_permission) && $state_count > 1) {
  162. form_set_error('transitions', t('Please give the author permission to go from %creation to at least one state!',
  163. array('%creation' => $creation_state->label())));
  164. }
  165. }
  166. /**
  167. * Submit handler for the workflow editing form.
  168. *
  169. * @see workflow_edit_form()
  170. */
  171. function workflow_admin_ui_transitions_form_submit($form, &$form_state) {
  172. $workflow = $form['workflow']['#value'];
  173. $wid = $workflow->wid;
  174. if (isset($form_state['values']['transitions'])) {
  175. $transitions = $form_state['values']['transitions'];
  176. // Empty string is sometimes passed in instead of an array.
  177. if (!$transitions) {
  178. return;
  179. }
  180. foreach ($transitions as $from => $to_data) {
  181. foreach ($to_data as $to => $role_data) {
  182. $roles = array();
  183. foreach ($role_data as $role => $can_do) {
  184. if ($can_do) {
  185. $roles += array($role => $role);
  186. }
  187. }
  188. if (count($roles)) {
  189. $config_transition = $workflow->createTransition($from, $to);
  190. $config_transition->roles = $roles;
  191. $config_transition->save();
  192. }
  193. else {
  194. foreach ($workflow->getTransitionsBySidTargetSid($from, $to, 'ALL') as $config_transition) {
  195. $config_transition->delete();
  196. }
  197. }
  198. }
  199. }
  200. }
  201. drupal_set_message(t('The workflow was updated.'));
  202. // $form_state['redirect'] = WORKFLOW_ADMIN_UI_PATH;
  203. }