You are here

function workflow_form_alter in Workflow 7.2

Same name and namespace in other branches
  1. 8 workflow.form.inc \workflow_form_alter()
  2. 5.2 workflow.module \workflow_form_alter()
  3. 5 workflow.module \workflow_form_alter()
  4. 6.2 workflow.module \workflow_form_alter()
  5. 6 workflow.module \workflow_form_alter()

Form builder. Move action buttons next to the 'Save'/'Delete' buttons.

This is only used if the set the 'options widget' to 'action buttons'. Do not use with multiple workflows per entity: confusing UX. ATM this works for:

  • Workflow Field: create, edit, view, workflow tab, comment;
  • Workflow Node: view, workflow tab;

(For forms with Workflow Node, the form_alter() is AFTER formElement(). )

@todo: move this to WorkflowTransitionForm::_addActionButtons();

File

./workflow.form.inc, line 44
Contains helper functions for WorkflowTransitionForm.

Code

function workflow_form_alter(&$form, &$form_state, $form_id) {

  // Use a fast, custom way to check if we need to do this.
  // @todo: Make this work with multiple workflows per entity.
  if (!_workflow_use_action_buttons()) {
    return;
  }

  // Find the first workflow.
  // (So this won't work with multiple workflows per entity.)
  $workflow_form = array();
  if (isset($form['workflow'])) {

    // Workflow Node or // Workflow History tab.
    $workflow_form =& $form['workflow'];
    $field_info = $workflow_form['workflow_field']['#value'];
    $field_name = $field_info['field_name'];
    $langcode = LANGUAGE_NONE;

    // Move non-standard 'Submit workflow' button in hook_node_view, workflow_tab_page, workflow_vbo.
    if (isset($form['workflow']['actions'])) {
      $form['actions'] = $form['workflow']['actions'];
      unset($form['workflow']['actions']);
    }
  }
  else {
    $field_name = '';
    foreach (element_children($form) as $key) {
      if (isset($form[$key]['#language'])) {
        $langcode = $form[$key]['#language'];
        if (isset($form[$key][$langcode][0]['workflow'])) {

          // Reference the Workflow Form, we'll remove the buttons later.
          $field_name = $key;
          $langcode = $form[$field_name]['#language'];
          $workflow_form =& $form[$key][$langcode][0]['workflow'];

          // Stop looping if found.
          break;
        }
      }
    }
  }

  // Quit if there is no Workflow on this page.
  if (!$workflow_form) {
    return;
  }

  // Quit if there are no Workflow Action buttons.
  // (If user has only 1 workflow option, there are no Action buttons.)
  if (count($workflow_form['workflow_sid']['#options']) <= 1) {
    return;
  }

  // Find the default submit button and replace with our own action buttons.
  if (isset($form['actions']['submit'])) {
    $default_submit_action = $form['actions']['submit'];
    unset($form['actions']['submit']);
  }
  elseif (isset($form['actions']['save'])) {
    $default_submit_action = $form['actions']['save'];
    unset($form['actions']['save']);
  }
  if (isset($default_submit_action)) {
    $current_sid = $workflow_form['workflow_sid']['#default_value'];
    $scheduled = isset($workflow_form['workflow_scheduling']['scheduled']) && $workflow_form['workflow_scheduling']['scheduled']['#default_value'];

    // Get the min weight for our buttons.
    $option_weight = isset($default_submit_action['#weight']) ? $default_submit_action['#weight'] : 0;
    $option_weight = $option_weight - count($workflow_form['workflow_sid']['#options']);
    $min_weight = $option_weight;
    foreach ($workflow_form['workflow_sid']['#options'] as $sid => $option_name) {

      // Make the workflow button act exactly like the original submit button.
      $same_state_button = $sid == $current_sid;

      // Add target State ID and Field name, to set correct value in validate_buttons callback.
      $workflow_submit_action = $default_submit_action + array(
        '#workflow_sid' => $sid,
        '#workflow_field_name' => $field_name,
      );

      // Keep option order. Put current state first.
      $workflow_submit_action['#weight'] = $same_state_button ? $min_weight : ++$option_weight;

      // Add/Overwrite some other settings.
      $workflow_submit_action['#access'] = TRUE;
      $workflow_submit_action['#value'] = $option_name;
      $workflow_submit_action['#attributes'] = $same_state_button ? array(
        'class' => array(
          'form-save-default-button',
        ),
      ) : array();

      //$workflow_submit_action['#executes_submit_callback']  = TRUE;
      $workflow_submit_action['#attributes']['class'][] = drupal_html_class('workflow_button_' . $option_name);

      // Append the form's #validate function, or it won't be called upon submit,
      // because the workflow buttons have its own #validate.
      if (isset($default_submit_action['#validate'])) {
        $workflow_submit_action['#validate'] = $default_submit_action['#validate'];
      }
      elseif (isset($form['#validate'])) {
        $workflow_submit_action['#validate'] = $form['#validate'];
      }
      $workflow_submit_action['#validate'][] = '_workflow_transition_form_validate_buttons';

      // Append the submit-buttons's #submit function, or it won't be called upon submit.
      if (isset($default_submit_action['#submit'])) {
        $workflow_submit_action['#submit'] = $default_submit_action['#submit'];
      }
      elseif (isset($form['#submit'])) {
        $workflow_submit_action['#submit'] = $form['#submit'];
      }

      // Hide the same-state button in some cases.
      // Alternative: use hide($element);
      if ($same_state_button && !$scheduled) {
        if (substr($form['#form_id'], 0, 24) == 'workflow_transition_form') {

          // Hide same-state-button on the transition-form (that is:
          // view page or workflow history tab) if there is nothing to do.
          // However, a Transition may be fieldable.
          if ($form['workflow']['workflow_comment']['#access'] == FALSE) {
            $workflow_submit_action['#access'] = FALSE;
          }
        }
        elseif ($form['#id'] == 'comment-form') {

          // On comment-form, the button must stay, since you can comment to same state.
        }
        else {

          // On a entity edit page, the button must stay.
        }
      }

      // Place the button with the other action buttons.
      $form['actions']['workflow_' . $sid] = $workflow_submit_action;
    }

    // On Edit page, remove the submit button from the workflow form.
    unset($workflow_form['actions']);
  }
}