function webform_client_form in Webform 7.4
Same name and namespace in other branches
- 5.2 webform.module \webform_client_form()
- 5 webform.module \webform_client_form()
- 6.3 webform.module \webform_client_form()
- 6.2 webform.module \webform_client_form()
- 7.3 webform.module \webform_client_form()
Client form generation function.
If this is displaying an existing submission, pass in the $submission variable with the contents of the submission to be displayed.
Parameters
$form: The current form array (always empty).
$form_state: The current form values of a submission, used in multipage webforms.
object $node: The current webform node.
$submission: An object containing information about the form submission if we're displaying a result.
$resume_draft: Optional. Set to TRUE when resuming a draft and skipping past previously- validated pages is desired.
$filter: Whether or not to filter the contents of descriptions and values when building the form. Values need to be unfiltered to be editable by Form Builder.
2 string references to 'webform_client_form'
- webform_client_form_validate in ./
webform.module - Form API #validate handler for the webform_client_form() form.
- webform_forms in ./
webform.module - Implements hook_forms().
File
- ./
webform.module, line 2497 - This module provides a simple way to create forms and questionnaires.
Code
function webform_client_form($form, &$form_state, $node, $submission = FALSE, $resume_draft = FALSE, $filter = TRUE) {
global $user;
// Attach necessary JavaScript and CSS.
$form['#attached'] = array(
'css' => array(
drupal_get_path('module', 'webform') . '/css/webform.css',
),
'js' => array(
drupal_get_path('module', 'webform') . '/js/webform.js',
),
);
form_load_include($form_state, 'inc', 'webform', 'includes/webform.components');
form_load_include($form_state, 'inc', 'webform', 'includes/webform.submissions');
// For ajax requests, $form_state['values']['details'] is missing. Restore
// from storage, if available, for multi-page forms.
if (empty($form_state['values']['details']) && !empty($form_state['storage']['details'])) {
$form_state['values']['details'] = $form_state['storage']['details'];
}
// If in a multi-step form, a submission ID may be specified in form state.
// Load this submission. This allows anonymous users to use auto-save.
if (empty($submission) && !empty($form_state['values']['details']['sid'])) {
$submission = webform_get_submission($node->nid, $form_state['values']['details']['sid']);
}
$finished = isset($submission->is_draft) ? !$submission->is_draft : 0;
$submit_button_text = $finished ? t('Save') : (empty($node->webform['submit_text']) ? t('Submit') : t($node->webform['submit_text']));
// Bind arguments to $form to make them available in theming and form_alter.
$form['#node'] = $node;
$form['#submission'] = $submission;
$form['#is_draft'] = $submission && $submission->is_draft;
$form['#filter'] = $filter;
// Add a theme function for this form.
$form['#theme'] = array(
'webform_form_' . $node->nid,
'webform_form',
);
// Add a CSS class for all client forms.
$form['#attributes']['class'][] = 'webform-client-form';
$form['#attributes']['class'][] = 'webform-client-form-' . $node->nid;
// Sometimes when displaying a webform as a teaser or block, a custom action
// property is set to direct the user to the node page.
if (!empty($node->webform['action'])) {
$form['#action'] = $node->webform['action'];
}
$form['#submit'] = array(
'webform_client_form_pages',
'webform_client_form_submit',
);
$form['#validate'] = array(
'webform_client_form_validate',
);
// Add includes for used component types and pre/post validation handlers.
$form['#process'] = array(
'webform_client_form_process',
);
if (is_array($node->webform['components']) && !empty($node->webform['components'])) {
// Prepare a new form array.
$form['submitted'] = array(
'#tree' => TRUE,
);
$form['details'] = array(
'#tree' => TRUE,
);
// Put the components into a tree structure.
if (!isset($form_state['storage']['component_tree'])) {
$form_state['webform']['component_tree'] = array();
$form_state['webform']['page_count'] = 1;
$form_state['webform']['page_num'] = 1;
_webform_components_tree_build($node->webform['components'], $form_state['webform']['component_tree'], 0, $form_state['webform']['page_count']);
// If preview is enabled, increase the page count by one.
if ($node->webform['preview']) {
$form_state['webform']['page_count']++;
}
$form_state['webform']['preview'] = $node->webform['preview'];
// If this is the first time this draft has been restore and presented to
// the user, let them know that they are looking at a draft, rather than
// a new form. This applies to the node view page, but not to a submission
// edit page (where they presummably know what submission they are
// editing).
if ($resume_draft && empty($form_state['input'])) {
drupal_set_message(t('A partially-completed form was found. Please complete the remaining portions.'));
}
}
else {
$form_state['webform']['component_tree'] = $form_state['storage']['component_tree'];
$form_state['webform']['page_count'] = $form_state['storage']['page_count'];
$form_state['webform']['page_num'] = $form_state['storage']['page_num'];
$form_state['webform']['preview'] = $form_state['storage']['preview'];
}
// Set the input values based on whether we're editing an existing
// submission or not.
$input_values = isset($submission->data) ? $submission->data : array();
// Form state storage override any default submission information. Convert
// the value structure to always be an array, matching $submission->data.
if (isset($form_state['storage']['submitted'])) {
foreach ($form_state['storage']['submitted'] as $cid => $data) {
$input_values[$cid] = is_array($data) ? $data : array(
$data,
);
}
}
// Form state values override any default submission information. Convert
// the value structure to always be an array, matching $submission->data.
if (isset($form_state['values']['submitted'])) {
foreach ($form_state['values']['submitted'] as $cid => $data) {
$input_values[$cid] = is_array($data) ? $data : array(
$data,
);
}
}
// Generate conditional topological order & report any errors.
$sorter = webform_get_conditional_sorter($node);
$sorter
->reportErrors();
// Excecute the condtionals on the current input values.
$input_values = $sorter
->executeConditionals($input_values);
// Allow values from other pages to be sent to browser for conditionals.
$form['#conditional_values'] = $input_values;
// Allow components access to most up-to-date values.
$form_state['#conditional_values'] = $input_values;
// For resuming a previous draft, find the next page after the last
// validated page.
if (!isset($form_state['storage']['page_num']) && $submission && $submission->is_draft && $submission->highest_valid_page) {
// Find the:
// 1. previous/next non-empty page, or
// 2. the preview page, or
// 3. the preview page, forcing its display if the form would unexpectedly
// submit, or
// 4. page 1 even if empty, if no other previous page would be shown.
$form_state['webform']['page_num'] = $submission->highest_valid_page;
do {
$form_state['webform']['page_num']++;
} while (!webform_get_conditional_sorter($node)
->pageVisibility($form_state['webform']['page_num']));
if (!$form_state['webform']['preview'] && $form_state['webform']['page_num'] == $form_state['webform']['page_count'] + (int) (!$form_state['webform']['preview'])) {
// Force a preview to avert an unintended submission via Next.
$form_state['webform']['preview'] = TRUE;
$form_state['webform']['page_count']++;
}
// The form hasn't been submitted (ever) and the preview code will expect
// $form_state['values']['submitted'] to be set from a previous
// submission, so provide these values here.
$form_state['values']['submitted'] = $input_values;
$form_state['storage']['submitted'] = $input_values;
}
// Shorten up our variable names.
$component_tree = $form_state['webform']['component_tree'];
$page_count = $form_state['webform']['page_count'];
$page_num = $form_state['webform']['page_num'];
$preview = $form_state['webform']['preview'];
if ($node->webform['progressbar_include_confirmation'] || $page_count > 1) {
$page_labels = webform_page_labels($node, $form_state);
$form['progressbar'] = array(
'#theme' => 'webform_progressbar',
'#node' => $node,
'#page_num' => $page_num,
'#page_count' => count($page_labels),
'#page_labels' => $page_labels,
'#weight' => -100,
);
}
// Check whether a previous submission was truncated. The length of the
// client form is not estimated before submission because a) the
// determination may not be accurate for some webform components and b) the
// error will be apparent upon submission.
webform_input_vars_check($form, $form_state, 'submitted');
// Recursively add components to the form. The unfiltered version of the
// form (typically used in Form Builder), includes all components.
foreach ($component_tree['children'] as $cid => $component) {
if ($component['type'] == 'pagebreak') {
$next_page_labels[$component['page_num'] - 1] = !empty($component['extra']['next_page_label']) ? t($component['extra']['next_page_label']) : t('Next Page >');
$prev_page_labels[$component['page_num']] = !empty($component['extra']['prev_page_label']) ? t($component['extra']['prev_page_label']) : t('< Previous Page');
}
if (!$filter || $sorter
->componentVisibility($cid, $page_num)) {
$component_value = isset($input_values[$cid]) ? $input_values[$cid] : NULL;
_webform_client_form_add_component($node, $component, $component_value, $form['submitted'], $form, $input_values, 'form', $page_num, $filter);
}
}
if ($preview) {
$next_page_labels[$page_count - 1] = $node->webform['preview_next_button_label'] ? t($node->webform['preview_next_button_label']) : t('Preview');
$prev_page_labels[$page_count] = $node->webform['preview_prev_button_label'] ? t($node->webform['preview_prev_button_label']) : t('< Previous');
}
// Add the preview if needed.
if ($preview && $page_num === $page_count) {
$preview_submission = webform_submission_create($node, $user, $form_state, TRUE, $submission);
$preview_message = $node->webform['preview_message'];
if (strlen(trim(strip_tags($preview_message))) === 0) {
$preview_message = t('Please review your submission. Your submission is not complete until you press the "!button" button!', array(
'!button' => $submit_button_text,
));
}
$form['preview_message'] = array(
'#type' => 'markup',
'#markup' => webform_replace_tokens($preview_message, $node, $preview_submission, NULL, $node->webform['preview_message_format']),
);
$form['preview'] = webform_submission_render($node, $preview_submission, NULL, 'html', $node->webform['preview_excluded_components']);
$form['#attributes']['class'][] = 'preview';
}
// These form details help managing data upon submission.
$form['details']['nid'] = array(
'#type' => 'value',
'#value' => $node->nid,
);
$form['details']['sid'] = array(
'#type' => 'hidden',
'#value' => isset($submission->sid) ? $submission->sid : NULL,
);
$form['details']['uid'] = array(
'#type' => 'value',
'#value' => isset($submission->uid) ? $submission->uid : $user->uid,
);
$form['details']['page_num'] = array(
'#type' => 'hidden',
'#value' => $page_num,
);
$form['details']['page_count'] = array(
'#type' => 'hidden',
'#value' => $page_count,
);
$form['details']['finished'] = array(
'#type' => 'hidden',
'#value' => $finished,
);
// Add process functions to remove the IDs forced upon buttons and wrappers.
$actions_pre_render = array_merge(element_info_property('actions', '#pre_render', array()), array(
'webform_pre_render_remove_id',
));
$buttons_pre_render = array_merge(element_info_property('submit', '#pre_render', array()), array(
'webform_pre_render_remove_id',
));
// Add buttons for pages, drafts, and submissions.
$form['actions'] = array(
'#type' => 'actions',
'#weight' => 1000,
'#pre_render' => $actions_pre_render,
);
// Add the draft button.
if ($node->webform['allow_draft'] && (empty($submission) || $submission->is_draft) && $user->uid != 0) {
$form['actions']['draft'] = array(
'#type' => 'submit',
'#value' => t('Save Draft'),
'#weight' => -2,
// Prevalidation only; no element validation for Save Draft.
'#validate' => array(
'webform_client_form_prevalidate',
),
'#attributes' => array(
'formnovalidate' => 'formnovalidate',
'class' => array(
'webform-draft',
),
),
'#pre_render' => $buttons_pre_render,
);
}
// Add the submit button(s).
if ($page_num > 1) {
$form['actions']['previous'] = array(
'#type' => 'submit',
'#value' => $prev_page_labels[$page_num],
'#weight' => 5,
'#validate' => array(),
'#attributes' => array(
'formnovalidate' => 'formnovalidate',
'class' => array(
'webform-previous',
),
),
'#pre_render' => $buttons_pre_render,
);
}
if ($page_num == $page_count) {
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $submit_button_text,
'#weight' => 10,
'#attributes' => array(
'class' => array(
'webform-submit',
'button-primary',
),
),
'#pre_render' => $buttons_pre_render,
);
}
elseif ($page_num < $page_count) {
$form['actions']['next'] = array(
'#type' => 'submit',
'#value' => $next_page_labels[$page_num],
'#weight' => 10,
'#attributes' => array(
'class' => array(
'webform-next',
'button-primary',
),
),
'#pre_render' => $buttons_pre_render,
);
}
}
return $form;
}