workflow_rules.rules-callback.inc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. /**
  3. * @file
  4. * Callback implementations for Rules integration for the Workflow module.
  5. *
  6. * These callbacks must be included in the module file.
  7. * It is not sufficient to have them in the rules_info file.
  8. */
  9. /**
  10. * Helper function to parse a token "node:<field_name>".
  11. *
  12. * @param string $token
  13. *
  14. * @return string $field_name
  15. *
  16. * This is a poorman's effort to convert a token into a field name.
  17. */
  18. function _workflow_rules_token_replace($field_name) {
  19. // Get the part after the first domain indicator.
  20. $list_parts = explode(':', $field_name, 2);
  21. $field_name = end($list_parts);
  22. $field_name = str_replace('-', '_', $field_name);
  23. return $field_name;
  24. }
  25. /**
  26. * Condition callback: gather all workflow states, to show in list_options.
  27. */
  28. function _workflow_rules_workflow_get_options($data) {
  29. // This is a poorman's effort to convert a token into a field name.
  30. $field_name = isset($data->settings['field:select']) ? _workflow_rules_token_replace($data->settings['field:select']) : '';
  31. $field = _workflow_info_field($field_name, NULL);
  32. $options['ANY'] = 'ANY state';
  33. $options += workflow_get_workflow_state_names($field['settings']['wid'], $grouped = TRUE);
  34. return $options;
  35. }
  36. /**
  37. * Condition implementation helper function: check given state.
  38. *
  39. * @param mixed $sid
  40. * A State ID, to compare with the given list of allowed State ID's.
  41. * @param array $sids
  42. * A list of allowed State ID's.
  43. *
  44. * @return bool
  45. * TRUE or FALSE.
  46. */
  47. function _workflow_rules_workflow_check_given_state($sid, array $sids) {
  48. return in_array('ANY', $sids) || in_array($sid, $sids);
  49. }
  50. /**
  51. * Condition implementation: check state transition..
  52. *
  53. * Only for Workflow Node! Workflow Field can use default Rules condition.
  54. *
  55. * @param object $node
  56. * The node with the new values. Other entity types are not supported.
  57. * @param array $old_sids
  58. * An array of old sids to meet the condition.
  59. * @param array $new_sids
  60. * An array of new sids to meet the condition.
  61. * @param array $condition
  62. * A RulesCondition->settings array.
  63. *
  64. * @return bool
  65. */
  66. function _workflow_rules_node_check_transition($node, array $old_sids, array $new_sids, array $condition) {
  67. if (!$last_transition = workflow_transition_load_single('node', $node->nid, '')) {
  68. return FALSE;
  69. }
  70. $old_sid = $last_transition->old_sid;
  71. $new_sid = $last_transition->new_sid;
  72. return
  73. _workflow_rules_workflow_check_given_state($old_sid, $old_sids) &&
  74. _workflow_rules_workflow_check_given_state($new_sid, $new_sids);
  75. }
  76. /**
  77. * Condition implementation: check current state for Workflow Node API.
  78. *
  79. * Only for Workflow Node! Workflow Field can use default Rules condition.
  80. *
  81. * @param object $node
  82. * The node with the new values. Other entity types are not supported.
  83. * @param array $sids
  84. * An array of State IDs to meet the condition.
  85. *
  86. * @return bool
  87. */
  88. function _workflow_rules_node_check_state($node, array $sids) {
  89. // Provide a fast exit if this is a node type without Workflow.
  90. // workflow_node_current_state() will return CreationState otherwise.
  91. if (!isset($node->workflow)) {
  92. return FALSE;
  93. }
  94. $field_name = ''; // An explicit var is needed.
  95. $sid = workflow_node_current_state($node, 'node', $field_name);
  96. return _workflow_rules_workflow_check_given_state($sid, $sids);
  97. }
  98. /**
  99. * Condition implementation: check previous state.
  100. *
  101. * Only for Workflow Node! Workflow Field can use default Rules condition.
  102. */
  103. function _workflow_rules_node_check_previous_state($node, $sids) {
  104. if (!$last_transition = workflow_transition_load_single('node', $node->nid, '')) {
  105. return FALSE;
  106. }
  107. $sid = $last_transition->old_sid;
  108. return _workflow_rules_workflow_check_given_state($sid, $sids);
  109. }
  110. /**
  111. * Action implementation: set current state, ignoring current user permission.
  112. *
  113. * For both Workflow Node and Workflow Field.
  114. */
  115. function _workflow_rules_set_state(array $parameters, RulesAction $action) {
  116. global $user;
  117. // Warning: keep this action in line between Workflow Field and Workflow Node.
  118. // "$parameters['node']" is for backwards compatibility: can be any entity_type.
  119. $entity = $parameters['node']->value(); // $parameters['entity'] is an EntityDrupalWrapper.
  120. $entity_type = $parameters['node']->type();
  121. // This is a poorman's effort to convert a token into a field name.
  122. $field_name = isset($parameters['settings']['field:select']) ? _workflow_rules_token_replace($parameters['settings']['field:select']) : '';
  123. $old_sid = workflow_node_current_state($entity, $entity_type, $field_name);
  124. // Select the last state on the list.
  125. $new_sid = array_pop($parameters['workflow_state']);
  126. if ($new_sid == 'ANY') {
  127. $new_sid = $old_sid;
  128. }
  129. $comment = $parameters['workflow_comment'];
  130. $transition = new WorkflowTransition();
  131. $transition->setValues($entity_type, $entity, $field_name, $old_sid, $new_sid, $user->uid, REQUEST_TIME, $comment);
  132. // Force this transition, to ignore the limitations on the current user's permissions.
  133. $transition->force(TRUE);
  134. // Execute the transition. It may bounce, due to extra checks.
  135. // @todo: use $new_sid = $transition->execute() without generating infinite loops.
  136. // Below method does not recalc tokens on automatic_entity_label.
  137. $new_sid = workflow_execute_transition($entity_type, $entity, $field_name, $transition);
  138. }