public static function get_form($form_id, $display_title = true, $display_description = true, $force_display = false, $field_values = null, $ajax = false, $tabindex = 1) { /** * Provides the ability to modify the options used to display the form * * @param array An array of Form Arguments when adding it to a page/post (Like the ID, Title, AJAX or not, etc) */ $form_args = apply_filters('gform_form_args', compact('form_id', 'display_title', 'display_description', 'force_display', 'field_values', 'ajax', 'tabindex')); extract($form_args); //looking up form id by form name if (!is_numeric($form_id)) { $form_id = RGFormsModel::get_form_id($form_id); } //reading form metadata $form = GFAPI::get_form($form_id); $form = self::maybe_add_review_page($form); $action = remove_query_arg('gf_token'); //disable ajax if form has a reCAPTCHA field (not supported). if ($ajax && self::has_recaptcha_field($form)) { $ajax = false; } if (isset($_POST['gform_send_resume_link'])) { $save_email_confirmation = self::handle_save_email_confirmation($form, $ajax); if (is_wp_error($save_email_confirmation)) { // Failed email validation $resume_token = rgpost('gform_resume_token'); $resume_token = sanitize_key($resume_token); $incomplete_submission_info = GFFormsModel::get_incomplete_submission_values($resume_token); if ($incomplete_submission_info['form_id'] == $form_id) { $submission_details_json = $incomplete_submission_info['submission']; $submission_details = json_decode($submission_details_json, true); $partial_entry = $submission_details['partial_entry']; $form = self::update_confirmation($form, $partial_entry, 'form_saved'); $confirmation_message = rgar($form['confirmation'], 'message'); $nl2br = rgar($form['confirmation'], 'disableAutoformat') ? false : true; $confirmation_message = GFCommon::replace_variables($confirmation_message, $form, $partial_entry, false, true, $nl2br); return self::handle_save_confirmation($form, $resume_token, $confirmation_message, $ajax); } } else { return $save_email_confirmation; } } $is_postback = false; $is_valid = true; $confirmation_message = ''; //If form was submitted, read variables set during form submission procedure $submission_info = isset(self::$submission[$form_id]) ? self::$submission[$form_id] : false; if (rgar($submission_info, 'saved_for_later') == true) { $resume_token = $submission_info['resume_token']; $confirmation_message = rgar($submission_info, 'confirmation_message'); return self::handle_save_confirmation($form, $resume_token, $confirmation_message, $ajax); } $partial_entry = $submitted_values = false; if (isset($_GET['gf_token'])) { $incomplete_submission_info = GFFormsModel::get_incomplete_submission_values($_GET['gf_token']); if ($incomplete_submission_info['form_id'] == $form_id) { $submission_details_json = $incomplete_submission_info['submission']; $submission_details = json_decode($submission_details_json, true); $partial_entry = $submission_details['partial_entry']; $submitted_values = $submission_details['submitted_values']; $field_values = $submission_details['field_values']; GFFormsModel::$unique_ids[$form_id] = $submission_details['gform_unique_id']; GFFormsModel::$uploaded_files[$form_id] = $submission_details['files']; self::set_submission_if_null($form_id, 'resuming_incomplete_submission', true); self::set_submission_if_null($form_id, 'form_id', $form_id); $max_page_number = self::get_max_page_number($form); $page_number = $submission_details['page_number'] > $max_page_number ? $max_page_number : $submission_details['page_number']; self::set_submission_if_null($form_id, 'page_number', $page_number); } } if (!is_array($partial_entry)) { /** * A filter that allows disabling of the form view counter * * @param int $form_id The Form ID to filter when disabling the form view counter * @param bool Default set to false (view counter enabled), can be set to true to disable the counter */ $view_counter_disabled = gf_apply_filters(array('gform_disable_view_counter', $form_id), false); if ($submission_info) { $is_postback = true; $is_valid = rgar($submission_info, 'is_valid') || rgar($submission_info, 'is_confirmation'); $form = $submission_info['form']; $lead = $submission_info['lead']; $confirmation_message = rgget('confirmation_message', $submission_info); if ($is_valid && !RGForms::get('is_confirmation', $submission_info)) { if ($submission_info['page_number'] == 0) { /** * Fired after form submission * * @param array $lead The Entry object * @param array $form The Form object */ gf_do_action(array('gform_post_submission', $form['id']), $lead, $form); } else { /** * Fired after the page changes on a multi-page form * * @param array $form The Form object * @param int $submission_info['source_page_number'] The page that was submitted * @param int $submission_info['page_number'] The page that the user is being sent to */ gf_do_action(array('gform_post_paging', $form['id']), $form, $submission_info['source_page_number'], $submission_info['page_number']); } } } elseif (!current_user_can('administrator') && !$view_counter_disabled) { RGFormsModel::insert_form_view($form_id, $_SERVER['REMOTE_ADDR']); } } if (rgar($form, 'enableHoneypot')) { $form['fields'][] = self::get_honeypot_field($form); } //Fired right before the form rendering process. Allow users to manipulate the form object before it gets displayed in the front end $form = gf_apply_filters(array('gform_pre_render', $form_id), $form, $ajax, $field_values); if ($form == null) { return '<p class="gform_not_found">' . esc_html__('Oops! We could not locate your form.', 'gravityforms') . '</p>'; } $has_pages = self::has_pages($form); //calling tab index filter GFCommon::$tab_index = gf_apply_filters(array('gform_tabindex', $form_id), $tabindex, $form); //Don't display inactive forms if (!$force_display && !$is_postback) { $form_info = RGFormsModel::get_form($form_id); if (empty($form_info) || !$form_info->is_active) { return ''; } // If form requires login, check if user is logged in if (rgar($form, 'requireLogin')) { if (!is_user_logged_in()) { return empty($form['requireLoginMessage']) ? '<p>' . esc_html__('Sorry. You must be logged in to view this form.', 'gravityforms') . '</p>' : '<p>' . GFCommon::gform_do_shortcode($form['requireLoginMessage']) . '</p>'; } } } // show the form regardless of the following validations when force display is set to true if (!$force_display || $is_postback) { $form_schedule_validation = self::validate_form_schedule($form); // if form schedule validation fails AND this is not a postback, display the validation error // if form schedule validation fails AND this is a postback, make sure is not a valid submission (enables display of confirmation message) if ($form_schedule_validation && !$is_postback || $form_schedule_validation && $is_postback && !$is_valid) { return $form_schedule_validation; } $entry_limit_validation = self::validate_entry_limit($form); // refer to form schedule condition notes above if ($entry_limit_validation && !$is_postback || $entry_limit_validation && $is_postback && !$is_valid) { return $entry_limit_validation; } } $form_string = ''; //When called via a template, this will enqueue the proper scripts //When called via a shortcode, this will be ignored (too late to enqueue), but the scripts will be enqueued via the enqueue_scripts event self::enqueue_form_scripts($form, $ajax); $is_form_editor = GFCommon::is_form_editor(); $is_entry_detail = GFCommon::is_entry_detail(); $is_admin = $is_form_editor || $is_entry_detail; if (empty($confirmation_message)) { $wrapper_css_class = GFCommon::get_browser_class() . ' gform_wrapper'; if (!$is_valid) { $wrapper_css_class .= ' gform_validation_error'; } $form_css_class = esc_attr(rgar($form, 'cssClass')); //Hiding entire form if conditional logic is on to prevent 'hidden' fields from blinking. Form will be set to visible in the conditional_logic.php after the rules have been applied. $style = self::has_conditional_logic($form) ? "style='display:none'" : ''; // Split form CSS class by spaces and apply wrapper to each. $custom_wrapper_css_class = ''; if (!empty($form_css_class)) { // Separate the CSS classes. $form_css_classes = explode(' ', $form_css_class); // Append _wrapper to each class. foreach ($form_css_classes as &$wrapper_class) { $wrapper_class .= '_wrapper'; } // Merge back into a string. $custom_wrapper_css_class = ' ' . implode(' ', $form_css_classes); } $form_string .= "\n <div class='{$wrapper_css_class}{$custom_wrapper_css_class}' id='gform_wrapper_{$form_id}' " . $style . '>'; $default_anchor = $has_pages || $ajax ? true : false; $use_anchor = gf_apply_filters(array('gform_confirmation_anchor', $form_id), $default_anchor, $form); if ($use_anchor !== false) { $form_string .= "<a id='gf_{$form_id}' class='gform_anchor' ></a>"; $action .= "#gf_{$form_id}"; } $target = $ajax ? "target='gform_ajax_frame_{$form_id}'" : ''; $form_css_class = !empty($form['cssClass']) ? "class='{$form_css_class}'" : ''; $action = esc_url($action); $form_string .= gf_apply_filters(array('gform_form_tag', $form_id), "<form method='post' enctype='multipart/form-data' {$target} id='gform_{$form_id}' {$form_css_class} action='{$action}'>", $form); if ($display_title || $display_description) { $form_string .= "\n <div class='gform_heading'>"; if ($display_title) { $form_string .= "\n <h3 class='gform_title'>" . $form['title'] . '</h3>'; } if ($display_description) { $form_string .= "\n <span class='gform_description'>" . rgar($form, 'description') . '</span>'; } $form_string .= ' </div>'; } /* If the form was submitted, has multiple pages and is invalid, set the current page to the first page with an invalid field. */ if ($has_pages && $is_postback && !$is_valid) { self::set_current_page($form_id, GFFormDisplay::get_first_page_with_error($form)); } $current_page = self::get_current_page($form_id); if ($has_pages && !$is_admin) { if ($form['pagination']['type'] == 'percentage') { $form_string .= self::get_progress_bar($form, $current_page, $confirmation_message); } else { if ($form['pagination']['type'] == 'steps') { $form_string .= self::get_progress_steps($form, $current_page); } } } if ($is_postback && !$is_valid) { $validation_message = "<div class='validation_error'>" . esc_html__('There was a problem with your submission.', 'gravityforms') . ' ' . esc_html__('Errors have been highlighted below.', 'gravityforms') . '</div>'; $form_string .= gf_apply_filters(array('gform_validation_message', $form_id), $validation_message, $form); } $form_string .= "\n <div class='gform_body'>"; //add first page if this form has any page fields if ($has_pages) { $style = self::is_page_active($form_id, 1) ? '' : "style='display:none;'"; $class = !empty($form['firstPageCssClass']) ? " {$form['firstPageCssClass']}" : ''; $class = esc_attr($class); $form_string .= "<div id='gform_page_{$form_id}_1' class='gform_page{$class}' {$style}>\n <div class='gform_page_fields'>"; } $description_class = rgar($form, 'descriptionPlacement') == 'above' ? 'description_above' : 'description_below'; $sublabel_class = rgar($form, 'subLabelPlacement') == 'above' ? 'form_sublabel_above' : 'form_sublabel_below'; $form_string .= "<ul id='gform_fields_{$form_id}' class='" . GFCommon::get_ul_classes($form) . "'>"; if (is_array($form['fields'])) { foreach ($form['fields'] as $field) { /* @var GF_Field $field */ $field->conditionalLogicFields = self::get_conditional_logic_fields($form, $field->id); if (is_array($submitted_values)) { $field_value = rgar($submitted_values, $field->id); } else { $field_value = GFFormsModel::get_field_value($field, $field_values); } $form_string .= self::get_field($field, $field_value, false, $form, $field_values); } } $form_string .= ' </ul>'; if ($has_pages) { $previous_button_alt = rgempty('imageAlt', $form['lastPageButton']) ? __('Previous Page', 'gravityforms') : $form['lastPageButton']['imageAlt']; $previous_button = self::get_form_button($form['id'], "gform_previous_button_{$form['id']}", $form['lastPageButton'], __('Previous', 'gravityforms'), 'gform_previous_button', $previous_button_alt, self::get_current_page($form_id) - 1); /** * Filter through the form previous button when paged * * @param int $form_id The Form ID to filter through * @param string $previous_button The HTML rendered button (rendered with the form ID and the function get_form_button) * @param array $form The Form object to filter through */ $previous_button = gf_apply_filters(array('gform_previous_button', $form_id), $previous_button, $form); $form_string .= '</div>' . self::gform_footer($form, 'gform_page_footer ' . $form['labelPlacement'], $ajax, $field_values, $previous_button, $display_title, $display_description, $is_postback) . ' </div>'; //closes gform_page } $form_string .= '</div>'; //closes gform_body //suppress form footer for multi-page forms (footer will be included on the last page if (!$has_pages) { $form_string .= self::gform_footer($form, 'gform_footer ' . $form['labelPlacement'], $ajax, $field_values, '', $display_title, $display_description, $tabindex); } $form_string .= ' </form> </div>'; if ($ajax && $is_postback) { global $wp_scripts; $form_string = apply_filters('gform_ajax_iframe_content', '<!DOCTYPE html><html><head>' . "<meta charset='UTF-8' /></head><body class='GF_AJAX_POSTBACK'>" . $form_string . '</body></html>'); } if ($ajax && !$is_postback) { $spinner_url = gf_apply_filters(array('gform_ajax_spinner_url', $form_id), GFCommon::get_base_url() . '/images/spinner.gif', $form); $scroll_position = array('default' => '', 'confirmation' => ''); if ($use_anchor !== false) { $scroll_position['default'] = is_numeric($use_anchor) ? 'jQuery(document).scrollTop(' . intval($use_anchor) . ');' : "jQuery(document).scrollTop(jQuery('#gform_wrapper_{$form_id}').offset().top);"; $scroll_position['confirmation'] = is_numeric($use_anchor) ? 'jQuery(document).scrollTop(' . intval($use_anchor) . ');' : "jQuery(document).scrollTop(jQuery('#gforms_confirmation_message_{$form_id}').offset().top);"; } $iframe_style = defined('GF_DEBUG') && GF_DEBUG ? 'display:block;width:600px;height:300px;border:1px solid #eee;' : 'display:none;width:0px;height:0px;'; $is_html5 = RGFormsModel::is_html5_enabled(); $iframe_title = $is_html5 ? " title='Ajax Frame'" : ''; $form_string .= "\n <iframe style='{$iframe_style}' src='about:blank' name='gform_ajax_frame_{$form_id}' id='gform_ajax_frame_{$form_id}'" . $iframe_title . ">" . esc_html__('This iframe contains the logic required to handle AJAX powered Gravity Forms.', 'gravityforms') . "</iframe>\n <script type='text/javascript'>" . apply_filters('gform_cdata_open', '') . '' . 'jQuery(document).ready(function($){' . "gformInitSpinner( {$form_id}, '{$spinner_url}' );" . "jQuery('#gform_ajax_frame_{$form_id}').load( function(){" . "var contents = jQuery(this).contents().find('*').html();" . "var is_postback = contents.indexOf('GF_AJAX_POSTBACK') >= 0;" . 'if(!is_postback){return;}' . "var form_content = jQuery(this).contents().find('#gform_wrapper_{$form_id}');" . "var is_confirmation = jQuery(this).contents().find('#gform_confirmation_wrapper_{$form_id}').length > 0;" . "var is_redirect = contents.indexOf('gformRedirect(){') >= 0;" . 'var is_form = form_content.length > 0 && ! is_redirect && ! is_confirmation;' . 'if(is_form){' . "jQuery('#gform_wrapper_{$form_id}').html(form_content.html());" . "if(form_content.hasClass('gform_validation_error')){jQuery('#gform_wrapper_{$form_id}').addClass('gform_validation_error');} else {jQuery('#gform_wrapper_{$form_id}').removeClass('gform_validation_error');}" . "setTimeout( function() { /* delay the scroll by 50 milliseconds to fix a bug in chrome */ {$scroll_position['default']} }, 50 );" . "if(window['gformInitDatepicker']) {gformInitDatepicker();}" . "if(window['gformInitPriceFields']) {gformInitPriceFields();}" . "var current_page = jQuery('#gform_source_page_number_{$form_id}').val();" . "gformInitSpinner( {$form_id}, '{$spinner_url}' );" . "jQuery(document).trigger('gform_page_loaded', [{$form_id}, current_page]);" . "window['gf_submitting_{$form_id}'] = false;" . '}' . 'else if(!is_redirect){' . "var confirmation_content = jQuery(this).contents().find('#gforms_confirmation_message_{$form_id}').html();" . 'if(!confirmation_content){' . 'confirmation_content = contents;' . '}' . 'setTimeout(function(){' . "jQuery('#gform_wrapper_{$form_id}').replaceWith('<' + 'div id=\\'gforms_confirmation_message_{$form_id}\\' class=\\'gform_confirmation_message_{$form_id} gforms_confirmation_message\\'' + '>' + confirmation_content + '<' + '/div' + '>');" . "{$scroll_position['confirmation']}" . "jQuery(document).trigger('gform_confirmation_loaded', [{$form_id}]);" . "window['gf_submitting_{$form_id}'] = false;" . '}, 50);' . '}' . 'else{' . "jQuery('#gform_{$form_id}').append(contents);" . "if(window['gformRedirect']) {gformRedirect();}" . '}' . "jQuery(document).trigger('gform_post_render', [{$form_id}, current_page]);" . '} );' . '} );' . apply_filters('gform_cdata_close', '') . '</script>'; } $is_first_load = !$is_postback; if (!$ajax || $is_first_load) { self::register_form_init_scripts($form, $field_values, $ajax); if (apply_filters('gform_init_scripts_footer', false)) { add_action('wp_footer', create_function('', 'GFFormDisplay::footer_init_scripts(' . $form['id'] . ');'), 20); add_action('gform_preview_footer', create_function('', 'GFFormDisplay::footer_init_scripts(' . $form['id'] . ');')); } else { $form_string .= self::get_form_init_scripts($form); $form_string .= "<script type='text/javascript'>" . apply_filters('gform_cdata_open', '') . " jQuery(document).ready(function(){jQuery(document).trigger('gform_post_render', [{$form_id}, {$current_page}]) } ); " . apply_filters('gform_cdata_close', '') . '</script>'; } } return gf_apply_filters(array('gform_get_form_filter', $form_id), $form_string, $form); } else { $progress_confirmation = ''; //check admin setting for whether the progress bar should start at zero $start_at_zero = rgars($form, 'pagination/display_progressbar_on_confirmation'); $start_at_zero = apply_filters('gform_progressbar_start_at_zero', $start_at_zero, $form); //show progress bar on confirmation if ($start_at_zero && $has_pages && !$is_admin && ($form['confirmation']['type'] == 'message' && $form['pagination']['type'] == 'percentage')) { $progress_confirmation = self::get_progress_bar($form, 0, $confirmation_message); if ($ajax) { $progress_confirmation = apply_filters('gform_ajax_iframe_content', "<!DOCTYPE html><html><head><meta charset='UTF-8' /></head><body class='GF_AJAX_POSTBACK'>" . $progress_confirmation . '</body></html>'); } } else { //return regular confirmation message if ($ajax) { $progress_confirmation = apply_filters('gform_ajax_iframe_content', "<!DOCTYPE html><html><head><meta charset='UTF-8' /></head><body class='GF_AJAX_POSTBACK'>" . $confirmation_message . '</body></html>'); } else { $progress_confirmation = $confirmation_message; } } return $progress_confirmation; } }