| 1 |
<?php
|
| 2 |
// $Id: workflow.admin.inc,v 1.6 2008/12/31 21:38:07 jvandyk Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Administrative pages for configuring workflows.
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Form builder. Create the form for adding/editing a workflow.
|
| 11 |
*
|
| 12 |
* @param $name
|
| 13 |
* Name of the workflow if editing.
|
| 14 |
* @param $add
|
| 15 |
* Boolean, if true edit workflow name.
|
| 16 |
*
|
| 17 |
* @return
|
| 18 |
* HTML form.
|
| 19 |
*/
|
| 20 |
function workflow_add_form(&$form_state, $name = NULL) {
|
| 21 |
$form = array();
|
| 22 |
$form['wf_name'] = array(
|
| 23 |
'#type' => 'textfield',
|
| 24 |
'#title' => t('Workflow Name'),
|
| 25 |
'#maxlength' => '254',
|
| 26 |
'#default_value' => $name
|
| 27 |
);
|
| 28 |
$form['submit'] = array(
|
| 29 |
'#type' => 'submit',
|
| 30 |
'#value' => t('Add Workflow')
|
| 31 |
);
|
| 32 |
return $form;
|
| 33 |
}
|
| 34 |
|
| 35 |
/**
|
| 36 |
* Validate the workflow add form.
|
| 37 |
*
|
| 38 |
* @see workflow_add_form()
|
| 39 |
*/
|
| 40 |
function workflow_add_form_validate($form, &$form_state) {
|
| 41 |
$workflow_name = $form_state['values']['wf_name'];
|
| 42 |
$workflows = array_flip(workflow_get_all());
|
| 43 |
// Make sure a nonblank workflow name is provided.
|
| 44 |
if ($workflow_name == '') {
|
| 45 |
form_set_error('wf_name', t('Please provide a nonblank name for the new workflow.'));
|
| 46 |
}
|
| 47 |
// Make sure workflow name is not a duplicate.
|
| 48 |
if (array_key_exists($workflow_name, $workflows)) {
|
| 49 |
form_set_error('wf_name', t('A workflow with the name %name already exists. Please enter another name for your new workflow.',
|
| 50 |
array('%name' => $workflow_name)));
|
| 51 |
}
|
| 52 |
}
|
| 53 |
|
| 54 |
/**
|
| 55 |
* Submit handler for the workflow add form.
|
| 56 |
*
|
| 57 |
* @see workflow_add_form()
|
| 58 |
*/
|
| 59 |
function workflow_add_form_submit($form, &$form_state) {
|
| 60 |
$workflow_name = $form_state['values']['wf_name'];
|
| 61 |
$wid = workflow_create($workflow_name);
|
| 62 |
watchdog('workflow', 'Created workflow %name', array('%name' => $workflow_name));
|
| 63 |
drupal_set_message(t('The workflow %name was created. You should now add states to your workflow.',
|
| 64 |
array('%name' => $workflow_name)), 'status');
|
| 65 |
$form_state['wid'] = $wid;
|
| 66 |
$form_state['redirect'] = 'admin/build/workflow/state/'. $wid;
|
| 67 |
}
|
| 68 |
|
| 69 |
/**
|
| 70 |
* Form builder. Create form for confirmation of workflow deletion.
|
| 71 |
*
|
| 72 |
* @param $wid
|
| 73 |
* The ID of the workflow to delete.
|
| 74 |
* @return
|
| 75 |
* Form definition array.
|
| 76 |
*
|
| 77 |
*/
|
| 78 |
function workflow_delete_form(&$form_state, $wid, $sid = NULL) {
|
| 79 |
if (isset($sid)) {
|
| 80 |
return workflow_state_delete_form($wid, $sid);
|
| 81 |
}
|
| 82 |
$form['wid'] = array(
|
| 83 |
'#type' => 'value',
|
| 84 |
'#value' => $wid
|
| 85 |
);
|
| 86 |
return confirm_form(
|
| 87 |
$form,
|
| 88 |
t('Are you sure you want to delete %title? All nodes that have a workflow state associated with this workflow will have those workflow states removed.', array('%title' => workflow_get_name($wid))),
|
| 89 |
!empty($_GET['destination']) ? $_GET['destination'] : 'admin/build/workflow',
|
| 90 |
t('This action cannot be undone.'),
|
| 91 |
t('Delete'),
|
| 92 |
t('Cancel')
|
| 93 |
);
|
| 94 |
}
|
| 95 |
|
| 96 |
/**
|
| 97 |
* Submit handler for workflow deletion form.
|
| 98 |
*
|
| 99 |
* @see workflow_delete_form()
|
| 100 |
*/
|
| 101 |
function workflow_delete_form_submit($form, &$form_state) {
|
| 102 |
if ($form_state['values']['confirm'] == 1) {
|
| 103 |
$workflow_name = workflow_get_name($form_state['values']['wid']);
|
| 104 |
workflow_deletewf($form_state['values']['wid']);
|
| 105 |
watchdog('workflow', 'Deleted workflow %name with all its states', array('%name' => $workflow_name));
|
| 106 |
drupal_set_message(t('The workflow %name with all its states was deleted.', array('%name' => $workflow_name)));
|
| 107 |
$form_state['redirect'] = 'admin/build/workflow';
|
| 108 |
}
|
| 109 |
}
|
| 110 |
|
| 111 |
/**
|
| 112 |
* View workflow permissions by role
|
| 113 |
*
|
| 114 |
* @param $wid
|
| 115 |
* The ID of the workflow.
|
| 116 |
*/
|
| 117 |
function workflow_permissions($wid) {
|
| 118 |
$name = workflow_get_name($wid);
|
| 119 |
$all = array();
|
| 120 |
$roles = array('author' => t('author')) + user_roles();
|
| 121 |
foreach ($roles as $role => $value) {
|
| 122 |
$all[$role]['name'] = $value;
|
| 123 |
}
|
| 124 |
$result = db_query(
|
| 125 |
'SELECT t.roles, s1.state AS state_name, s2.state AS target_state_name ' .
|
| 126 |
'FROM {workflow_transitions} t ' .
|
| 127 |
'INNER JOIN {workflow_states} s1 ON s1.sid = t.sid '.
|
| 128 |
'INNER JOIN {workflow_states} s2 ON s2.sid = t.target_sid '.
|
| 129 |
'WHERE s1.wid = %d ' .
|
| 130 |
'ORDER BY s1.weight ASC , s1.state ASC , s2.weight ASC , s2.state ASC',
|
| 131 |
$wid);
|
| 132 |
|
| 133 |
while ($data = db_fetch_object($result)) {
|
| 134 |
foreach (explode(',', $data->roles) as $role) {
|
| 135 |
$all[$role]['transitions'][] = array($data->state_name, WORKFLOW_ARROW, $data->target_state_name);
|
| 136 |
}
|
| 137 |
}
|
| 138 |
|
| 139 |
$header = array(t('From'), '', t('To'));
|
| 140 |
return theme('workflow_permissions', $header, $all);
|
| 141 |
}
|
| 142 |
|
| 143 |
/**
|
| 144 |
* Theme the workflow permissions view.
|
| 145 |
*/
|
| 146 |
function theme_workflow_permissions($header, $all) {
|
| 147 |
$output = '';
|
| 148 |
foreach ($all as $role => $value) {
|
| 149 |
$output .= '<h3>'. t("%role may do these transitions:", array('%role' => $value['name'])) .'</h3>';
|
| 150 |
if (!empty($value['transitions'])) {
|
| 151 |
$output .= theme('table', $header, $value['transitions']) . '<p></p>';
|
| 152 |
}
|
| 153 |
else {
|
| 154 |
$output .= '<table><tbody><tr class="odd"><td>' . t('None') . '</td><td></tr></tbody></table><p></p>';
|
| 155 |
}
|
| 156 |
}
|
| 157 |
|
| 158 |
return $output;
|
| 159 |
}
|
| 160 |
|
| 161 |
/**
|
| 162 |
* Menu callback. Edit a workflow's properties.
|
| 163 |
*
|
| 164 |
* @param $wid
|
| 165 |
* The ID of the workflow.
|
| 166 |
* @return
|
| 167 |
* HTML form and permissions table.
|
| 168 |
*/
|
| 169 |
function workflow_edit_form($form_state, $workflow) {
|
| 170 |
$form['wid'] = array(
|
| 171 |
'#type' => 'value',
|
| 172 |
'#value' => $workflow->wid,
|
| 173 |
);
|
| 174 |
$form['basic'] = array(
|
| 175 |
'#type' => 'fieldset',
|
| 176 |
'#title' => t('Workflow information')
|
| 177 |
);
|
| 178 |
$form['basic']['wf_name'] = array(
|
| 179 |
'#type' => 'textfield',
|
| 180 |
'#default_value' => $workflow->name,
|
| 181 |
'#title' => t('Workflow Name'),
|
| 182 |
'#size' => '16',
|
| 183 |
'#maxlength' => '254',
|
| 184 |
);
|
| 185 |
$form['comment'] = array(
|
| 186 |
'#type' => 'fieldset',
|
| 187 |
'#title' => t('Comment for Workflow Log'),
|
| 188 |
);
|
| 189 |
$form['comment']['comment_log_node'] = array(
|
| 190 |
'#type' => 'checkbox',
|
| 191 |
'#title' => t('Show a comment field in the workflow section of the editing form.'),
|
| 192 |
'#default_value' => $workflow->options['comment_log_node'],
|
| 193 |
'#description' => t("On the node editing form, a Comment form can be shown so that the person making the state change can record reasons for doing so. The comment is then included in the node's workflow history."),
|
| 194 |
);
|
| 195 |
$form['comment']['comment_log_tab'] = array(
|
| 196 |
'#type' => 'checkbox',
|
| 197 |
'#title' => t('Show a comment field in the workflow section of the workflow tab form.'),
|
| 198 |
'#default_value' => $workflow->options['comment_log_tab'],
|
| 199 |
'#description' => t("On the workflow tab, a Comment form can be shown so that the person making the state change can record reasons for doing so. The comment is then included in the node's workflow history."),
|
| 200 |
);
|
| 201 |
$form['tab'] = array(
|
| 202 |
'#type' => 'fieldset',
|
| 203 |
'#title' => t('Workflow tab permissions'),
|
| 204 |
'#collapsible' => TRUE,
|
| 205 |
'#collapsed' => FALSE,
|
| 206 |
);
|
| 207 |
$form['tab']['tab_roles'] = array(
|
| 208 |
'#type' => 'checkboxes',
|
| 209 |
'#options' => workflow_get_roles(),
|
| 210 |
'#default_value' => explode(',', $workflow->tab_roles),
|
| 211 |
'#description' => t('Select any roles that should have access to the workflow tab on nodes that have a workflow.'),
|
| 212 |
);
|
| 213 |
|
| 214 |
$form['transitions'] = workflow_transition_grid_form($workflow->wid);
|
| 215 |
$form['transitions']['#tree'] = TRUE;
|
| 216 |
|
| 217 |
$form['submit'] = array(
|
| 218 |
'#type' => 'submit',
|
| 219 |
'#value' => t('Save')
|
| 220 |
);
|
| 221 |
|
| 222 |
$form['permissions'] = array(
|
| 223 |
'#type' => 'fieldset',
|
| 224 |
'#title' => t('Permissions Summary'),
|
| 225 |
'#collapsible' => TRUE,
|
| 226 |
);
|
| 227 |
$form['permissions']['summary'] = array(
|
| 228 |
'#value' => workflow_permissions($workflow->wid),
|
| 229 |
);
|
| 230 |
|
| 231 |
return $form;
|
| 232 |
}
|
| 233 |
|
| 234 |
/**
|
| 235 |
* Theme the workflow editing form.
|
| 236 |
*
|
| 237 |
* @see workflow_edit_form()
|
| 238 |
*/
|
| 239 |
function theme_workflow_edit_form($form) {
|
| 240 |
$output = drupal_render($form['wf_name']);
|
| 241 |
$wid = $form['wid']['#value'];
|
| 242 |
$states = workflow_get_states($wid);
|
| 243 |
drupal_set_title(t('Edit workflow %name', array('%name' => workflow_get_name($wid))));
|
| 244 |
if ($states) {
|
| 245 |
$roles = workflow_get_roles();
|
| 246 |
$header = array(array('data' => t('From / To ') . ' ' . WORKFLOW_ARROW));
|
| 247 |
$rows = array();
|
| 248 |
foreach ($states as $state_id => $name) {
|
| 249 |
// Don't allow transition TO (creation).
|
| 250 |
if ($name != t('(creation)')) {
|
| 251 |
$header[] = array('data' => t($name));
|
| 252 |
}
|
| 253 |
$row = array(array('data' => $name));
|
| 254 |
foreach ($states as $nested_state_id => $nested_name) {
|
| 255 |
if ($nested_name == t('(creation)')) {
|
| 256 |
// Don't allow transition TO (creation).
|
| 257 |
continue;
|
| 258 |
}
|
| 259 |
if ($nested_state_id != $state_id) {
|
| 260 |
// Need to render checkboxes for transition from $state to $nested_state.
|
| 261 |
$from = $state_id;
|
| 262 |
$to = $nested_state_id;
|
| 263 |
$cell = '';
|
| 264 |
foreach ($roles as $rid => $role_name) {
|
| 265 |
$cell .= drupal_render($form['transitions'][$from][$to][$rid]);
|
| 266 |
}
|
| 267 |
$row[] = array('data' => $cell);
|
| 268 |
}
|
| 269 |
else {
|
| 270 |
$row[] = array('data' => '');
|
| 271 |
}
|
| 272 |
}
|
| 273 |
$rows[] = $row;
|
| 274 |
}
|
| 275 |
$output .= theme('table', $header, $rows);
|
| 276 |
|
| 277 |
}
|
| 278 |
else {
|
| 279 |
$output = t('There are no states defined for this workflow.');
|
| 280 |
}
|
| 281 |
|
| 282 |
$output .= drupal_render($form);
|
| 283 |
return $output;
|
| 284 |
}
|
| 285 |
|
| 286 |
/**
|
| 287 |
* Validate the workflow editing form.
|
| 288 |
*
|
| 289 |
* @see workflow_edit_form()
|
| 290 |
*/
|
| 291 |
function workflow_edit_form_validate($form_id, $form_state) {
|
| 292 |
$wid = $form_state['values']['wid'];
|
| 293 |
// Make sure workflow name is not a duplicate.
|
| 294 |
if (array_key_exists('wf_name', $form_state['values']) && $form_state['values']['wf_name'] != '') {
|
| 295 |
$workflow_name = $form_state['values']['wf_name'];
|
| 296 |
$workflows = array_flip(workflow_get_all());
|
| 297 |
if (array_key_exists($workflow_name, $workflows) && $wid != $workflows[$workflow_name]) {
|
| 298 |
form_set_error('wf_name', t('A workflow with the name %name already exists. Please enter another name for this workflow.',
|
| 299 |
array('%name' => $workflow_name)));
|
| 300 |
}
|
| 301 |
}
|
| 302 |
else {
|
| 303 |
// No workflow name was provided.
|
| 304 |
form_set_error('wf_name', t('Please provide a nonblank name for this workflow.'));
|
| 305 |
}
|
| 306 |
|
| 307 |
// Make sure 'author' is checked for (creation) -> [something].
|
| 308 |
$creation_id = _workflow_creation_state($wid);
|
| 309 |
if (isset($form_state['values']['transitions'][$creation_id]) && is_array($form_state['values']['transitions'][$creation_id])) {
|
| 310 |
foreach ($form_state['values']['transitions'][$creation_id] as $to => $roles) {
|
| 311 |
if ($roles['author']) {
|
| 312 |
$author_has_permission = TRUE;
|
| 313 |
break;
|
| 314 |
}
|
| 315 |
}
|
| 316 |
}
|
| 317 |
$state_count = db_result(db_query("SELECT COUNT(sid) FROM {workflow_states} WHERE wid = %d", $wid));
|
| 318 |
if (empty($author_has_permission) && $state_count > 1) {
|
| 319 |
form_set_error('transitions', t('Please give the author permission to go from %creation to at least one state!',
|
| 320 |
array('%creation' => '(creation)')));
|
| 321 |
}
|
| 322 |
}
|
| 323 |
|
| 324 |
/**
|
| 325 |
* Submit handler for the workflow editing form.
|
| 326 |
*
|
| 327 |
* @see workflow_edit_form()
|
| 328 |
*/
|
| 329 |
function workflow_edit_form_submit($form, &$form_state) {
|
| 330 |
if (isset($form_state['values']['transitions'])) {
|
| 331 |
workflow_update_transitions($form_state['values']['transitions']);
|
| 332 |
}
|
| 333 |
workflow_update($form_state['values']['wid'], $form_state['values']['wf_name'], array_filter($form_state['values']['tab_roles']), array('comment_log_node' => $form_state['values']['comment_log_node'], 'comment_log_tab' => $form_state['values']['comment_log_tab']));
|
| 334 |
drupal_set_message(t('The workflow was updated.'));
|
| 335 |
$form_state['redirect'] = 'admin/build/workflow';
|
| 336 |
}
|
| 337 |
|
| 338 |
/**
|
| 339 |
* Menu callback and form builder. Create form to add a workflow state.
|
| 340 |
*
|
| 341 |
* @param $wid
|
| 342 |
* The ID of the workflow.
|
| 343 |
* @return
|
| 344 |
* HTML form.
|
| 345 |
*/
|
| 346 |
function workflow_state_add_form(&$form_state, $wid, $sid = NULL) {
|
| 347 |
$form['wid'] = array('#type' => 'value', '#value' => $wid);
|
| 348 |
|
| 349 |
if (isset($sid)) {
|
| 350 |
$state = workflow_get_state($sid);
|
| 351 |
if (isset($state) && $state['status']) {
|
| 352 |
drupal_set_title(t('Edit workflow state %state', array('%state' => $state['state'])));
|
| 353 |
$form['sid'] = array(
|
| 354 |
'#type' => 'value',
|
| 355 |
'#value' => $sid
|
| 356 |
);
|
| 357 |
}
|
| 358 |
}
|
| 359 |
|
| 360 |
// If we don't have a state or db_fetch_array() returned FALSE, load defaults.
|
| 361 |
if (!isset($state) || $state === FALSE) {
|
| 362 |
$state = array('state' => '', 'weight' => 0);
|
| 363 |
drupal_set_title(t('Add a new state to workflow %workflow', array('%workflow' => workflow_get_name($wid))));
|
| 364 |
}
|
| 365 |
|
| 366 |
$form['state'] = array(
|
| 367 |
'#type' => 'textfield',
|
| 368 |
'#title' => t('State name'),
|
| 369 |
'#default_value' => $state['state'],
|
| 370 |
'#size' => '16',
|
| 371 |
'#maxlength' => '254',
|
| 372 |
'#required' => TRUE,
|
| 373 |
'#description' => t('Enter the name for a state in your workflow. For example, if you were doing a meal workflow it may include states like <em>shop</em>, <em>prepare</em>, <em>eat</em>, and <em>clean up</em>.'),
|
| 374 |
);
|
| 375 |
$form['weight'] = array(
|
| 376 |
'#type' => 'weight',
|
| 377 |
'#title' => t('Weight'),
|
| 378 |
'#default_value' => $state['weight'],
|
| 379 |
'#description' => t('In listings, the heavier states will sink and the lighter states will be positioned nearer the top.'),
|
| 380 |
);
|
| 381 |
$form['submit'] = array(
|
| 382 |
'#type' => 'submit',
|
| 383 |
'#value' => t('Save')
|
| 384 |
);
|
| 385 |
return $form;
|
| 386 |
}
|
| 387 |
|
| 388 |
/**
|
| 389 |
* Validate the state addition form.
|
| 390 |
*
|
| 391 |
* @see workflow_state_add_form()
|
| 392 |
*/
|
| 393 |
function workflow_state_add_form_validate($form, &$form_state) {
|
| 394 |
$state_name = $form_state['values']['state'];
|
| 395 |
$wf_states = array_flip(workflow_get_states($form_state['values']['wid']));
|
| 396 |
if (array_key_exists('sid', $form_state['values'])) {
|
| 397 |
// Validate changes to existing state:
|
| 398 |
// Make sure a nonblank state name is provided.
|
| 399 |
if ($state_name == '') {
|
| 400 |
form_set_error('state', t('Please provide a nonblank name for this state.'));
|
| 401 |
}
|
| 402 |
// Make sure changed state name is not a duplicate
|
| 403 |
if (array_key_exists($state_name, $wf_states) && $form_state['values']['sid'] != $wf_states[$state_name]) {
|
| 404 |
form_set_error('state', t('A state with the name %state already exists in this workflow. Please enter another name for this state.', array('%state' => $state_name)));
|
| 405 |
}
|
| 406 |
}
|
| 407 |
else {
|
| 408 |
// Validate new state:
|
| 409 |
// Make sure a nonblank state name is provided
|
| 410 |
if ($state_name == '') {
|
| 411 |
form_set_error('state', t('Please provide a nonblank name for the new state.'));
|
| 412 |
}
|
| 413 |
// Make sure state name is not a duplicate
|
| 414 |
if (array_key_exists($state_name, $wf_states)) {
|
| 415 |
form_set_error('state', t('A state with the name %state already exists in this workflow. Please enter another name for your new state.', array('%state' => $state_name)));
|
| 416 |
}
|
| 417 |
}
|
| 418 |
}
|
| 419 |
|
| 420 |
/**
|
| 421 |
* Submit handler for state addition form.
|
| 422 |
*
|
| 423 |
* @see workflow_state_add_form()
|
| 424 |
*/
|
| 425 |
function workflow_state_add_form_submit($form, &$form_state) {
|
| 426 |
$form_state['sid'] = workflow_state_save($form_state['values']);
|
| 427 |
if (array_key_exists('sid', $form_state['values'])) {
|
| 428 |
drupal_set_message(t('The workflow state was updated.'));
|
| 429 |
}
|
| 430 |
else {
|
| 431 |
watchdog('workflow', 'Created workflow state %name', array('%name' => $form_state['values']['state']));
|
| 432 |
drupal_set_message(t('The workflow state %name was created.', array('%name' => $form_state['values']['state'])));
|
| 433 |
}
|
| 434 |
$form_state['redirect'] = 'admin/build/workflow';
|
| 435 |
}
|
| 436 |
|
| 437 |
/**
|
| 438 |
* Form builder. Build the grid of transitions for defining a workflow.
|
| 439 |
*
|
| 440 |
* @param int $wid
|
| 441 |
* The ID of the workflow.
|
| 442 |
*/
|
| 443 |
function workflow_transition_grid_form($wid) {
|
| 444 |
$form = array();
|
| 445 |
|
| 446 |
$roles = workflow_get_roles();
|
| 447 |
$states = workflow_get_states($wid);
|
| 448 |
if (!$states) {
|
| 449 |
$form = array(
|
| 450 |
'#type' => 'markup',
|
| 451 |
'#value' => t('There are no states defined for this workflow.')
|
| 452 |
);
|
| 453 |
return $form;
|
| 454 |
}
|
| 455 |
foreach ($states as $state_id => $name) {
|
| 456 |
foreach ($states as $nested_state_id => $nested_name) {
|
| 457 |
if ($nested_name == t('(creation)')) {
|
| 458 |
// Don't allow transition TO (creation).
|
| 459 |
continue;
|
| 460 |
}
|
| 461 |
if ($nested_state_id != $state_id) {
|
| 462 |
// Need to generate checkboxes for transition from $state to $nested_state.
|
| 463 |
$from = $state_id;
|
| 464 |
$to = $nested_state_id;
|
| 465 |
foreach ($roles as $rid => $role_name) {
|
| 466 |
$tid = workflow_get_transition_id($from, $to);
|
| 467 |
$form[$from][$to][$rid] = array(
|
| 468 |
'#type' => 'checkbox',
|
| 469 |
'#title' => $role_name,
|
| 470 |
'#default_value' => $tid ? workflow_transition_allowed($tid, $rid) : FALSE);
|
| 471 |
}
|
| 472 |
}
|
| 473 |
}
|
| 474 |
}
|
| 475 |
return $form;
|
| 476 |
}
|
| 477 |
|
| 478 |
/**
|
| 479 |
* Menu callback. Create the main workflow page, which gives an overview
|
| 480 |
* of workflows and workflow states.
|
| 481 |
*/
|
| 482 |
function workflow_overview() {
|
| 483 |
$workflows = workflow_get_all();
|
| 484 |
$row = array();
|
| 485 |
|
| 486 |
foreach ($workflows as $wid => $name) {
|
| 487 |
$links = array(
|
| 488 |
'workflow_overview_add_state' => array(
|
| 489 |
'title' => t('Add state'),
|
| 490 |
'href' => "admin/build/workflow/state/$wid"),
|
| 491 |
'workflow_overview_actions' => array(
|
| 492 |
'title' => t('Actions'),
|
| 493 |
'href' => "admin/build/trigger/workflow/$wid"),
|
| 494 |
'workflow_overview_edit' => array(
|
| 495 |
'title' => t('Edit'),
|
| 496 |
'href' => "admin/build/workflow/edit/$wid"),
|
| 497 |
'workflow_overview_delete' => array(
|
| 498 |
'title' => t('Delete'),
|
| 499 |
'href' => "admin/build/workflow/delete/$wid"),
|
| 500 |
);
|
| 501 |
|
| 502 |
// Allow modules to insert their own workflow operations.
|
| 503 |
$links = array_merge($links, module_invoke_all('workflow_operations', 'workflow', $wid));
|
| 504 |
|
| 505 |
$states = workflow_get_states($wid);
|
| 506 |
if (!module_exists('trigger') || count($states) < 2) {
|
| 507 |
unset($links['workflow_overview_actions']);
|
| 508 |
}
|
| 509 |
|
| 510 |
$row[] = array($name, theme('links', $links));
|
| 511 |
$subrows = array();
|
| 512 |
|
| 513 |
foreach ($states as $sid => $state_name) {
|
| 514 |
$state_links = array();
|
| 515 |
if (!workflow_is_system_state(t($state_name))) {
|
| 516 |
$state_links = array(
|
| 517 |
'workflow_overview_edit_state' => array(
|
| 518 |
'title' => t('Edit'),
|
| 519 |
'href' => "admin/build/workflow/state/$wid/$sid",
|
| 520 |
),
|
| 521 |
'workflow_overview_delete_state' => array(
|
| 522 |
'title' => t('Delete'),
|
| 523 |
'href' => "admin/build/workflow/state/delete/$wid/$sid"
|
| 524 |
),
|
| 525 |
);
|
| 526 |
}
|
| 527 |
// Allow modules to insert state operations.
|
| 528 |
$state_links = array_merge($state_links, module_invoke_all('workflow_operations', 'state', $wid, $sid));
|
| 529 |
$subrows[] = array(t($state_name), theme('links', $state_links));
|
| 530 |
unset($state_links);
|
| 531 |
}
|
| 532 |
|
| 533 |
$subheader_state = array('data' => t('State'), 'style' => 'width: 30%');
|
| 534 |
$subheader_operations = array('data' => t('Operations'), 'style' => 'width: 70%');
|
| 535 |
$subheader_style = array('style' => 'width: 100%; margin: 3px 20px 20px;');
|
| 536 |
$subtable = theme('table', array($subheader_state, $subheader_operations), $subrows, $subheader_style);
|
| 537 |
|
| 538 |
$row[] = array(array('data' => $subtable, 'colspan' => '2'));
|
| 539 |
}
|
| 540 |
|
| 541 |
if ($row) {
|
| 542 |
$output = theme('table', array(t('Workflow'), t('Operations')), $row);
|
| 543 |
$output .= drupal_get_form('workflow_types_form');
|
| 544 |
}
|
| 545 |
else {
|
| 546 |
$output = '<p>' . t('No workflows have been added. Would you like to <a href="@link">add a workflow</a>?', array('@link' => url('admin/build/workflow/add'))) . '</p>';
|
| 547 |
}
|
| 548 |
|
| 549 |
return $output;
|
| 550 |
}
|
| 551 |
|
| 552 |
/**
|
| 553 |
* Form builder. Create form for confirmation of deleting a workflow state.
|
| 554 |
*
|
| 555 |
* @param $wid
|
| 556 |
* integer The ID of the workflow.
|
| 557 |
* @param $sid
|
| 558 |
* The ID of the workflow state.
|
| 559 |
* @return
|
| 560 |
* HTML form.
|
| 561 |
*/
|
| 562 |
function workflow_state_delete_form($form_state, $wid, $sid) {
|
| 563 |
$states = workflow_get_states($wid);
|
| 564 |
$state_name = $states[$sid];
|
| 565 |
|
| 566 |
// Will any nodes have no state if this state is deleted?
|
| 567 |
if ($count = db_result(db_query("SELECT COUNT(nid) FROM {workflow_node} WHERE sid = %d", $sid))) {
|
| 568 |
// Cannot assign a node to (creation) because that implies
|
| 569 |
// that the node does not exist.
|
| 570 |
$key = array_search(t('(creation)'), $states);
|
| 571 |
unset($states[$key]);
|
| 572 |
|
| 573 |
// Don't include the state to be deleted in our list of possible
|
| 574 |
// states that can be assigned.
|
| 575 |
unset($states[$sid]);
|
| 576 |
$form['new_sid'] = array(
|
| 577 |
'#type' => 'select',
|
| 578 |
'#title' => t('State to be assigned to orphaned nodes'),
|
| 579 |
'#description' => format_plural($count, 'Since you are deleting a workflow state, a node which is in that state will be orphaned, and must be reassigned to a new state. Please choose the new state.', 'Since you are deleting a workflow state, @count nodes which are in that state will be orphaned, and must be reassigned to a new state. Please choose the new state.'),
|
| 580 |
'#options' => $states,
|
| 581 |
);
|
| 582 |
}
|
| 583 |
|
| 584 |
$form['wid'] = array(
|
| 585 |
'#type' => 'value',
|
| 586 |
'#value' => $wid
|
| 587 |
);
|
| 588 |
$form['sid'] = array(
|
| 589 |
'#type' => 'value',
|
| 590 |
'#value' => $sid
|
| 591 |
);
|
| 592 |
|
| 593 |
return confirm_form(
|
| 594 |
$form,
|
| 595 |
t('Are you sure you want to delete %title (and all its transitions)?', array('%title' => $states[$sid])),
|
| 596 |
!empty($_GET['destination']) ? $_GET['destination'] : 'admin/build/workflow',
|
| 597 |
t('This action cannot be undone.'),
|
| 598 |
t('Delete'),
|
| 599 |
t('Cancel')
|
| 600 |
);
|
| 601 |
}
|
| 602 |
|
| 603 |
/**
|
| 604 |
* Submit handler for workflow state deletion form.
|
| 605 |
*
|
| 606 |
* @see workflow_state_delete_form()
|
| 607 |
*/
|
| 608 |
function workflow_state_delete_form_submit($form, &$form_state) {
|
| 609 |
$states = workflow_get_states($form_state['values']['wid']);
|
| 610 |
$state_name = $states[$form_state['values']['sid']];
|
| 611 |
if ($form_state['values']['confirm'] == 1) {
|
| 612 |
workflow_state_delete($form_state['values']['sid'], $form_state['values']['new_sid']);
|
| 613 |
watchdog('workflow', 'Deleted workflow state %name', array('%name' => $state_name));
|
| 614 |
drupal_set_message(t('The workflow state %name was deleted.', array('%name' => $state_name)));
|
| 615 |
}
|
| 616 |
$form_state['redirect'] = 'admin/build/workflow';
|
| 617 |
}
|
| 618 |
|
| 619 |
/**
|
| 620 |
* Form builder. Allow administrator to map workflows to content types
|
| 621 |
* and determine placement.
|
| 622 |
*/
|
| 623 |
function workflow_types_form() {
|
| 624 |
$form = array();
|
| 625 |
$workflows = array('<' . t('None') . '>') + workflow_get_all();
|
| 626 |
if (count($workflows) == 0) {
|
| 627 |
return $form;
|
| 628 |
}
|
| 629 |
|
| 630 |
$type_map = array();
|
| 631 |
$result = db_query("SELECT wid, type FROM {workflow_type_map}");
|
| 632 |
while ($data = db_fetch_object($result)) {
|
| 633 |
$type_map[$data->type] = $data->wid;
|
| 634 |
}
|
| 635 |
|
| 636 |
$form['#theme'] = 'workflow_types_form';
|
| 637 |
$form['#tree'] = TRUE;
|
| 638 |
$form['help'] = array(
|
| 639 |
'#type' => 'item',
|
| 640 |
'#value' => t('Each content type may have a separate workflow. The form for changing workflow state can be displayed when editing a node, editing a comment for a node, or both.'),
|
| 641 |
);
|
| 642 |
|
| 643 |
foreach (node_get_types('names') as $type => $name) {
|
| 644 |
$form[$type]['workflow'] = array(
|
| 645 |
'#type' => 'select',
|
| 646 |
'#title' => $name,
|
| 647 |
'#options' => $workflows,
|
| 648 |
'#default_value' => isset($type_map[$type]) ? $type_map[$type] : 0
|
| 649 |
);
|
| 650 |
$form[$type]['placement'] = array(
|
| 651 |
'#type' => 'checkboxes',
|
| 652 |
'#options' => array(
|
| 653 |
'node' => t('Post'),
|
| 654 |
'comment' => t('Comment'),
|
| 655 |
),
|
| 656 |
'#default_value' => variable_get('workflow_' . $type, array('node')),
|
| 657 |
);
|
| 658 |
}
|
| 659 |
$form['submit'] = array(
|
| 660 |
'#type' => 'submit',
|
| 661 |
'#value' => t('Save workflow mapping')
|
| 662 |
);
|
| 663 |
return $form;
|
| 664 |
}
|
| 665 |
|
| 666 |
/**
|
| 667 |
* Theme the workflow type mapping form.
|
| 668 |
*/
|
| 669 |
function theme_workflow_types_form($form) {
|
| 670 |
$header = array(t('Content Type'), t('Workflow'), t('Display Workflow Form for:'));
|
| 671 |
$rows = array();
|
| 672 |
foreach (node_get_types('names') as $type => $name) {
|
| 673 |
$name = $form[$type]['workflow']['#title'];
|
| 674 |
unset($form[$type]['workflow']['#title']);
|
| 675 |
$rows[] = array($name, drupal_render($form[$type]['workflow']), drupal_render($form[$type]['placement']));
|
| 676 |
}
|
| 677 |
$output = drupal_render($form['help']);
|
| 678 |
$output .= theme('table', $header, $rows);
|
| 679 |
return $output . drupal_render($form);
|
| 680 |
}
|
| 681 |
|
| 682 |
/**
|
| 683 |
* Submit handler for workflow type mapping form.
|
| 684 |
*
|
| 685 |
* @see workflow_types_form()
|
| 686 |
*/
|
| 687 |
function workflow_types_form_submit($form, &$form_state) {
|
| 688 |
workflow_types_save($form_state['values']);
|
| 689 |
drupal_set_message(t('The workflow mapping was saved.'));
|
| 690 |
menu_rebuild();
|
| 691 |
$form_state['redirect'] = 'admin/build/workflow';
|
| 692 |
}
|