function ctools_wizard_wrapper

Provide a wrapper around another form for adding multi-step information.

1 string reference to 'ctools_wizard_wrapper'
ctools_wizard_multistep_form in includes/wizard.inc
Display a multi-step form.

File

includes/wizard.inc, line 229

Code

function ctools_wizard_wrapper($form, &$form_state) {
    $form_info =& $form_state['form_info'];
    $info = $form_info['forms'][$form_state['step']];
    // Determine the next form from this step.
    // Create a form trail if we're supposed to have one.
    $trail = array();
    $previous = TRUE;
    foreach ($form_info['order'] as $id => $title) {
        if ($id == $form_state['step']) {
            $previous = FALSE;
            $class = 'wizard-trail-current';
        }
        elseif ($previous) {
            $not_first = TRUE;
            $class = 'wizard-trail-previous';
            $form_state['previous'] = $id;
        }
        else {
            $class = 'wizard-trail-next';
            if (!isset($form_state['next'])) {
                $form_state['next'] = $id;
            }
            if (empty($form_info['show trail'])) {
                break;
            }
        }
        if (!empty($form_info['show trail'])) {
            if (!empty($form_info['free trail'])) {
                // ctools_wizard_get_path() returns results suitable for
                // $form_state['redirect] which can only be directly used in
                // drupal_goto. We have to futz a bit with it.
                $path = ctools_wizard_get_path($form_info, $id);
                $options = array();
                if (!empty($path[1])) {
                    $options = $path[1];
                }
                $title = l($title, $path[0], $options);
            }
            $trail[] = '<span class="' . $class . '">' . $title . '</span>';
        }
    }
    // Display the trail if instructed to do so.
    if (!empty($form_info['show trail'])) {
        ctools_add_css('wizard');
        $form['ctools_trail'] = array(
            '#markup' => theme(array(
                'ctools_wizard_trail__' . $form_info['id'],
                'ctools_wizard_trail',
            ), array(
                'trail' => $trail,
                'form_info' => $form_info,
            )),
            '#weight' => -1000,
        );
    }
    if (empty($form_info['no buttons'])) {
        // Ensure buttons stay on the bottom.
        $form['buttons'] = array(
            '#type' => 'actions',
            '#weight' => 1000,
        );
        $button_attributes = array();
        if (!empty($form_state['ajax']) && empty($form_state['modal'])) {
            $button_attributes = array(
                'class' => array(
                    'ctools-use-ajax',
                ),
            );
        }
        if (!empty($form_info['show back']) && isset($form_state['previous'])) {
            $form['buttons']['previous'] = array(
                '#type' => 'submit',
                '#value' => $form_info['back text'],
                '#next' => $form_state['previous'],
                '#wizard type' => 'next',
                '#weight' => -2000,
                '#limit_validation_errors' => array(),
                // Hardcode the submit so that it doesn't try to save data.
'#submit' => array(
                    'ctools_wizard_submit',
                ),
                '#attributes' => $button_attributes,
            );
            if (isset($form_info['no back validate']) || isset($info['no back validate'])) {
                $form['buttons']['previous']['#validate'] = array();
            }
        }
        // If there is a next form, place the next button.
        if (isset($form_state['next']) || !empty($form_info['free trail'])) {
            $form['buttons']['next'] = array(
                '#type' => 'submit',
                '#value' => $form_info['next text'],
                '#next' => !empty($form_info['free trail']) ? $form_state['step'] : $form_state['next'],
                '#wizard type' => 'next',
                '#weight' => -1000,
                '#attributes' => $button_attributes,
            );
        }
        // There are two ways the return button can appear. If this is not the
        // end of the form list (i.e, there is a next) then it's "update and return"
        // to be clear. If this is the end of the path and there is no next, we
        // call it 'Finish'.
        // Even if there is no direct return path (some forms may not want you
        // leaving in the middle) the final button is always a Finish and it does
        // whatever the return action is.
        if (!empty($form_info['show return']) && !empty($form_state['next'])) {
            $form['buttons']['return'] = array(
                '#type' => 'submit',
                '#value' => $form_info['return text'],
                '#wizard type' => 'return',
                '#attributes' => $button_attributes,
            );
        }
        elseif (empty($form_state['next']) || !empty($form_info['free trail'])) {
            $form['buttons']['return'] = array(
                '#type' => 'submit',
                '#value' => $form_info['finish text'],
                '#wizard type' => 'finish',
                '#attributes' => $button_attributes,
            );
        }
        // If we are allowed to cancel, place a cancel button.
        if (isset($form_info['cancel path']) && !isset($form_info['show cancel']) || !empty($form_info['show cancel'])) {
            $form['buttons']['cancel'] = array(
                '#type' => 'submit',
                '#value' => $form_info['cancel text'],
                '#wizard type' => 'cancel',
                // Hardcode the submit so that it doesn't try to save data.
'#limit_validation_errors' => array(),
                '#submit' => array(
                    'ctools_wizard_submit',
                ),
                '#attributes' => $button_attributes,
            );
        }
        // Set up optional validate handlers.
        $form['#validate'] = array();
        if (function_exists($info['form id'] . '_validate')) {
            $form['#validate'][] = $info['form id'] . '_validate';
        }
        if (isset($info['validate']) && function_exists($info['validate'])) {
            $form['#validate'][] = $info['validate'];
        }
        // Set up our submit handler after theirs. Since putting something here will
        // skip Drupal's autodetect, we autodetect for it.
        // We make sure ours is after theirs so that they get to change #next if
        // the want to.
        $form['#submit'] = array();
        if (function_exists($info['form id'] . '_submit')) {
            $form['#submit'][] = $info['form id'] . '_submit';
        }
        if (isset($info['submit']) && function_exists($info['submit'])) {
            $form['#submit'][] = $info['submit'];
        }
        $form['#submit'][] = 'ctools_wizard_submit';
    }
    if (!empty($form_state['ajax'])) {
        $params = ctools_wizard_get_path($form_state['form_info'], $form_state['step']);
        if (count($params) > 1) {
            $url = array_shift($params);
            $options = array();
            $keys = array(
                0 => 'query',
                1 => 'fragment',
            );
            foreach ($params as $key => $value) {
                if (isset($keys[$key]) && isset($value)) {
                    $options[$keys[$key]] = $value;
                }
            }
            $params = array(
                $url,
                $options,
            );
        }
        $form['#action'] = call_user_func_array('url', $params);
    }
    if (isset($info['wrapper']) && function_exists($info['wrapper'])) {
        $form = $info['wrapper']($form, $form_state);
    }
    if (isset($form_info['wrapper']) && function_exists($form_info['wrapper'])) {
        $form = $form_info['wrapper']($form, $form_state);
    }
    return $form;
}