workflow_cleanup.module 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. /**
  3. * @file
  4. * Cleans up Workflow cruft that may build up over time.
  5. */
  6. /**
  7. * Implements hook_menu().
  8. */
  9. function workflow_cleanup_menu() {
  10. $items = array();
  11. $items['admin/config/workflow/workflow/cleanup'] = array(
  12. 'title' => 'Workflow Clean Up',
  13. 'access arguments' => array('administer workflow'),
  14. 'page callback' => 'drupal_get_form',
  15. 'page arguments' => array('workflow_cleanup_form'),
  16. 'type' => MENU_CALLBACK,
  17. );
  18. return $items;
  19. }
  20. /**
  21. * Implements hook_theme().
  22. */
  23. function workflow_cleanup_theme() {
  24. return array(
  25. 'workflow_cleanup_form' => array('render element' => 'form'),
  26. );
  27. }
  28. /**
  29. * Implements hook_workflow_operations().
  30. * Might as well eat our own cooking.
  31. */
  32. function workflow_cleanup_workflow_operations($op, $workflow = NULL, $state = NULL) {
  33. switch ($op) {
  34. case 'top_actions':
  35. $workflows = workflow_get_workflows();
  36. $alt = t('Clean up workflow cruft');
  37. $actions = array(
  38. 'workflow-cleanup' => array(
  39. 'title' => t('Clean up'),
  40. 'href' => 'admin/config/workflow/workflow/cleanup',
  41. 'attributes' => array('alt' => $alt, 'title' => $alt),
  42. ),
  43. );
  44. return $actions;
  45. }
  46. }
  47. /**
  48. * The main cleanup page.
  49. */
  50. function workflow_cleanup_form($form, $form_state) {
  51. $bc = array(l(t('Home'), '<front>'));
  52. $bc[] = l(t('Configuration'), 'admin/config');
  53. $bc[] = l(t('Workflow'), 'admin/config/workflow');
  54. $bc[] = l(t('Workflow'), 'admin/config/workflow/workflow');
  55. drupal_set_breadcrumb($bc);
  56. $form = array();
  57. // Get all of the states, indexed by sid.
  58. $states = $orphans = $inactive = array();
  59. foreach (workflow_get_workflow_states() as $state) {
  60. $states[$state->sid] = $state;
  61. // Is it associated with a workflow?
  62. if (empty($state->name)) {
  63. $orphans[$state->sid] = $state->state;
  64. }
  65. else {
  66. // Is it associated with a workflow?
  67. if (!$state->status) {
  68. $inactive[$state->sid] = $state->state;
  69. }
  70. }
  71. }
  72. // Deal with no orphan states.
  73. if (!$orphans) {
  74. $orphans[0] = t('None');
  75. }
  76. // Deal with no inactive states.
  77. if (!$inactive) {
  78. $inactive[0] = $states[0] = t('None');
  79. }
  80. $form['#workflow_states'] = $states;
  81. $form['no_workflow'] = array(
  82. '#type' => 'container',
  83. '#title' => t('Orphaned States'),
  84. '#description' => t('These states no longer belong to an existing workflow.'),
  85. '#tree' => TRUE,
  86. );
  87. foreach ($orphans as $sid => $state) {
  88. $form['no_workflow'][$sid]['check'] = array(
  89. '#type' => 'checkbox',
  90. '#return_value' => $sid,
  91. );
  92. $form['no_workflow'][$sid]['name'] = array(
  93. '#type' => 'markup',
  94. '#markup' => check_plain($state),
  95. );
  96. }
  97. $form['inactive'] = array(
  98. '#type' => 'container',
  99. '#title' => t('Inactive (Deleted) States'),
  100. '#description' => t('These states belong to a workflow, but have been marked inactive (deleted).'),
  101. '#tree' => TRUE,
  102. );
  103. foreach ($inactive as $sid => $state) {
  104. $form['inactive'][$sid]['check'] = array(
  105. '#type' => 'checkbox',
  106. '#return_value' => $sid,
  107. );
  108. $form['inactive'][$sid]['name'] = array(
  109. '#type' => 'markup',
  110. '#markup' => check_plain($state),
  111. );
  112. $form['inactive'][$sid]['wf'] = array(
  113. '#type' => 'markup',
  114. '#markup' => check_plain($states[$sid]->name),
  115. );
  116. }
  117. $form['submit'] = array('#type' => 'submit', '#value' => t('Delete selected states'));
  118. return $form;
  119. }
  120. /**
  121. * Theme the main form.
  122. */
  123. function theme_workflow_cleanup_form($variables) {
  124. $form = $variables['form'];
  125. $output = '';
  126. $header = array(t('select'), t('State'));
  127. $rows = array();
  128. foreach (element_children($form['no_workflow']) as $sid) {
  129. $rows[] = array(
  130. drupal_render($form['no_workflow'][$sid]['check']),
  131. drupal_render($form['no_workflow'][$sid]['name']),
  132. );
  133. }
  134. $output .= '<h3>' . $form['no_workflow']['#title'] . '</h3>';
  135. $output .= '<div class="description">' . $form['no_workflow']['#description'] . '</div>';
  136. $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('style' => 'width: auto;')));
  137. $header[] = t('Workflow');
  138. $rows = array();
  139. foreach (element_children($form['inactive']) as $sid) {
  140. $rows[] = array(
  141. drupal_render($form['inactive'][$sid]['check']),
  142. drupal_render($form['inactive'][$sid]['name']),
  143. drupal_render($form['inactive'][$sid]['wf']),
  144. );
  145. }
  146. $output .= '<h3>' . $form['inactive']['#title'] . '</h3>';
  147. $output .= '<div class="description">' . $form['inactive']['#description'] . '</div>';
  148. $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('style' => 'width: auto;')));
  149. $output .= drupal_render_children($form);
  150. return $output;
  151. }
  152. /**
  153. * Submission handler for main cleanup form.
  154. */
  155. function workflow_cleanup_form_submit($form, $form_state) {
  156. $states = $form['#workflow_states'];
  157. foreach (array('no_workflow', 'inactive') as $section) {
  158. foreach ($form_state['values'][$section] as $sid => $data) {
  159. // FAPI returns either a 0 or the sid.
  160. if ($data['check']) {
  161. // Delete any transitions this state is involved in.
  162. $trans_del = db_delete('workflow_transitions')->condition('target_sid', $sid)->execute();
  163. $trans_del += db_delete('workflow_transitions')->condition('sid', $sid)->execute();
  164. if ($trans_del) {
  165. drupal_set_message(t('@count transitions for the "@state" state have been deleted.',
  166. array('@state' => $states[$sid]->state, '@count' => $trans_del)));
  167. }
  168. // Remove history records too.
  169. $hist_del = db_delete('workflow_node_history')->condition('sid', $sid)->execute();
  170. if ($hist_del) {
  171. drupal_set_message(t('@count history records for the "@state" state have been deleted.',
  172. array('@state' => $states[$sid]->state, '@count' => $hist_del)));
  173. }
  174. // Go ahead and delete the state.
  175. db_delete('workflow_states')->condition('sid', $sid)->execute();
  176. drupal_set_message(t('The "@state" state has been deleted.', array('@state' => $states[$sid]->state)));
  177. }
  178. }
  179. }
  180. }