= $page_number ) ) { $is_valid = self::validate( $form, $field_values, $page_number, $failed_validation_page ); } $log_is_valid = $is_valid ? 'Yes' : 'No'; GFCommon::log_debug( "GFFormDisplay::process_form(): After validation. Is submission valid? {$log_is_valid}." ); // Upload files to temp folder when going to the next page or when submitting the form and it failed validation if ( $target_page > $page_number || $target_page == 0 ) { if ( ! empty( $_FILES ) && ! $saving_for_later ) { // When saving, ignore files with single file upload fields as they have not been validated. GFCommon::log_debug( 'GFFormDisplay::process_form(): Uploading files...' ); // Uploading files to temporary folder. $files = self::upload_files( $form, $files ); RGFormsModel::$uploaded_files[ $form_id ] = $files; } } // Load target page if it did not fail validation or if going to the previous page if ( ! $saving_for_later && $is_valid ) { $page_number = $target_page; } else { $page_number = $failed_validation_page; } $confirmation = ''; if ( ( $is_valid && $page_number == 0 ) || $saving_for_later ) { //Make sure submit button isn't hidden by conditional logic if ( GFFormsModel::is_submit_button_hidden( $form ) && ! $saving_for_later ) { // Ignore submission. return; } $ajax = isset( $_POST['gform_ajax'] ); //adds honeypot field if configured if ( rgar( $form, 'enableHoneypot' ) ) { $form['fields'][] = self::get_honeypot_field( $form ); } $failed_honeypot = rgar( $form, 'enableHoneypot' ) && ! self::validate_honeypot( $form ); if ( $failed_honeypot ) { GFCommon::log_debug( 'GFFormDisplay::process_form(): Failed Honeypot validation. Displaying confirmation and aborting.' ); //display confirmation but doesn't process the form when honeypot fails $confirmation = self::handle_confirmation( $form, $lead, $ajax ); $is_valid = false; } elseif ( ! $saving_for_later ) { GFCommon::log_debug( 'GFFormDisplay::process_form(): Submission is valid. Moving forward.' ); $form = self::update_confirmation( $form ); //pre submission action /** * Fires before form submission is handled * * Typically used to modify values before the submission is processed. * * @param array $form The Form object */ gf_do_action( array( 'gform_pre_submission', $form['id'] ), $form ); //pre submission filter $form = gf_apply_filters( array( 'gform_pre_submission_filter', $form_id ), $form ); //handle submission $confirmation = self::handle_submission( $form, $lead, $ajax ); //after submission hook if ( has_filter( 'gform_after_submission' ) || has_filter( "gform_after_submission_{$form['id']}" ) ) { GFCommon::log_debug( __METHOD__ . '(): Executing functions hooked to gform_after_submission.' ); } /** * Fires after successful form submission * * Used to perform additional actions after submission * * @param array $lead The Entry object * @param array $form The Form object */ gf_do_action( array( 'gform_after_submission', $form['id'] ), $lead, $form ); } elseif ( $saving_for_later ) { GFCommon::log_debug( 'GFFormDisplay::process_form(): Saving for later.' ); $lead = GFFormsModel::get_current_lead(); $form = self::update_confirmation( $form, $lead, 'form_saved' ); $confirmation = rgar( $form['confirmation'], 'message' ); $nl2br = rgar( $form['confirmation'], 'disableAutoformat' ) ? false : true; $confirmation = GFCommon::replace_variables( $confirmation, $form, $lead, false, true, $nl2br ); $form_unique_id = GFFormsModel::get_form_unique_id( $form_id ); $ip = rgars( $form, 'personalData/preventIP' ) ? '' : GFFormsModel::get_ip(); $source_url = GFFormsModel::get_current_page_url(); $source_url = esc_url_raw( $source_url ); $resume_token = rgpost( 'gform_resume_token' ); $resume_token = sanitize_key( $resume_token ); $resume_token = GFFormsModel::save_draft_submission( $form, $lead, $field_values, $page_number, $files, $form_unique_id, $ip, $source_url, $resume_token ); $notifications_to_send = GFCommon::get_notifications_to_send( 'form_saved', $form, $lead ); $log_notification_event = empty( $notifications_to_send ) ? 'No notifications to process' : 'Processing notifications'; GFCommon::log_debug( "GFFormDisplay::process_form(): {$log_notification_event} for form_saved event." ); foreach ( $notifications_to_send as $notification ) { if ( isset( $notification['isActive'] ) && ! $notification['isActive'] ) { GFCommon::log_debug( "GFFormDisplay::process_form(): Notification is inactive, not processing notification (#{$notification['id']} - {$notification['name']})." ); continue; } $notification['message'] = self::replace_save_variables( $notification['message'], $form, $resume_token ); GFCommon::send_notification( $notification, $form, $lead ); } self::set_submission_if_null( $form_id, 'saved_for_later', true ); self::set_submission_if_null( $form_id, 'resume_token', $resume_token ); GFCommon::log_debug( 'GFFormDisplay::process_form(): Saved incomplete submission.' ); } /** * Allows the confirmation redirect header to be suppressed. Required by GFAPI::submit_form(). * * @since 2.3 * * @param bool $suppress_redirect */ $suppress_redirect = apply_filters( 'gform_suppress_confirmation_redirect', false ); if ( is_array( $confirmation ) && isset( $confirmation['redirect'] ) && ! $suppress_redirect ) { header( "Location: {$confirmation["redirect"]}" ); /** * Fires after submission, if the confirmation page includes a redirect * * Used to perform additional actions after submission * * @param array $lead The Entry object * @param array $form The Form object */ gf_do_action( array( 'gform_post_submission', $form['id'] ), $lead, $form ); exit; } } if ( ! isset( self::$submission[ $form_id ] ) ) { self::$submission[ $form_id ] = array(); } self::set_submission_if_null( $form_id, 'is_valid', $is_valid ); self::set_submission_if_null( $form_id, 'form', $form ); self::set_submission_if_null( $form_id, 'lead', $lead ); self::set_submission_if_null( $form_id, 'confirmation_message', $confirmation ); self::set_submission_if_null( $form_id, 'page_number', $page_number ); self::set_submission_if_null( $form_id, 'source_page_number', $source_page_number ); /** * Fires after the form processing is completed. Form processing happens when submitting a page on a multi-page form (i.e. going to the "Next" or "Previous" page), or * when submitting a single page form. * * @param array $form The Form Object * @param int $page_number In a multi-page form, this variable contains the current page number. * @param int $source_page_number In a multi-page form, this parameters contains the number of the page that the submission came from. * For example, when clicking "Next" on page 1, this parameter will be set to 1. When clicking "Previous" on page 2, this parameter will be set to 2. */ gf_do_action( array( 'gform_post_process', $form['id'] ), $form, $page_number, $source_page_number ); } /** * Get form object and insert review page, if necessary. * * @since 2.1.1.25 Added $partial_entry parameter. * @since 1.9.15 * * @param array $form The current Form object. * @param array $partial_entry The partial entry from the resumed incomplete submission. Defaults to an empty array. * * @return array The form object. */ public static function maybe_add_review_page( $form, $partial_entry = array() ) { /* Setup default review page parameters. */ $review_page = array( 'content' => '', 'cssClass' => '', 'is_enabled' => false, 'nextButton' => array( 'type' => 'text', 'text' => __( 'Review Form', 'gravityforms' ), 'imageUrl' => '', 'imageAlt' => '', ), 'previousButton' => array( 'type' => 'text', 'text' => __( 'Previous', 'gravityforms' ), 'imageUrl' => '', 'imageAlt' => '', ), ); if ( has_filter( 'gform_review_page' ) || has_filter( "gform_review_page_{$form['id']}" ) ) { if ( empty( $partial_entry ) ) { // Prepare partial entry for review page. $partial_entry = GFFormsModel::get_current_lead(); } /** * GFFormsModel::create_lead() caches the field value and conditional logic visibility which can create * issues when 3rd parties use hooks later in the process to modify the form. Let's flush the cache avoid * any weirdness. */ GFCache::flush(); /** * A filter for setting up the review page * * @param array $review_page The review page parameters * @param array $form The current form object * @param array|false $partial_entry The partial entry for the form or false on initial form display. */ $review_page = gf_apply_filters( array( 'gform_review_page', $form['id'] ), $review_page, $form, $partial_entry ); if ( ! rgempty( 'button_text', $review_page ) ) { $review_page['nextButton']['text'] = $review_page['button_text']; } } if ( rgar( $review_page, 'is_enabled' ) ) { $form = self::insert_review_page( $form, $review_page ); } return $form; } private static function set_submission_if_null( $form_id, $key, $val ) { if ( ! isset( self::$submission[ $form_id ][ $key ] ) ) { self::$submission[ $form_id ][ $key ] = $val; } } private static function upload_files( $form, $files ) { $form_upload_path = GFFormsModel::get_upload_path( $form['id'] ); GFCommon::log_debug( "GFFormDisplay::upload_files(): Upload path {$form_upload_path}" ); //Creating temp folder if it does not exist $target_path = $form_upload_path . '/tmp/'; wp_mkdir_p( $target_path ); GFCommon::recursive_add_index_file( $form_upload_path ); foreach ( $form['fields'] as $field ) { $input_name = "input_{$field->id}"; //skip fields that are not file upload fields or that don't have a file to be uploaded or that have failed validation $input_type = RGFormsModel::get_input_type( $field ); if ( ! in_array( $input_type, array( 'fileupload', 'post_image' ) ) || $field->multipleFiles ) { continue; } /*if ( $field->failed_validation || empty( $_FILES[ $input_name ]['name'] ) ) { GFCommon::log_debug( "GFFormDisplay::upload_files(): Skipping field: {$field->label}({$field->id} - {$field->type})." ); continue; }*/ if ( $field->failed_validation ) { GFCommon::log_debug( "GFFormDisplay::upload_files(): Skipping field because it failed validation: {$field->label}({$field->id} - {$field->type})." ); continue; } if ( empty( $_FILES[ $input_name ]['name'] ) ) { GFCommon::log_debug( "GFFormDisplay::upload_files(): Skipping field because a file could not be found: {$field->label}({$field->id} - {$field->type})." ); continue; } $file_name = $_FILES[ $input_name ]['name']; if ( GFCommon::file_name_has_disallowed_extension( $file_name ) ) { GFCommon::log_debug( __METHOD__ . "(): Illegal file extension: {$file_name}" ); continue; } $allowed_extensions = ! empty( $field->allowedExtensions ) ? GFCommon::clean_extensions( explode( ',', strtolower( $field->allowedExtensions ) ) ) : array(); if ( ! empty( $allowed_extensions ) ) { if ( ! GFCommon::match_file_extension( $file_name, $allowed_extensions ) ) { GFCommon::log_debug( __METHOD__ . "(): The uploaded file type is not allowed: {$file_name}" ); continue; } } /** * Allows the disabling of file upload whitelisting * * @param bool false Set to 'true' to disable whitelisting. Defaults to 'false'. */ $whitelisting_disabled = apply_filters( 'gform_file_upload_whitelisting_disabled', false ); if ( empty( $allowed_extensions ) && ! $whitelisting_disabled ) { // Whitelist the file type $valid_file_name = GFCommon::check_type_and_ext( $_FILES[ $input_name ], $file_name ); if ( is_wp_error( $valid_file_name ) ) { GFCommon::log_debug( __METHOD__ . "(): The uploaded file type is not allowed: {$file_name}" ); continue; } } $file_info = RGFormsModel::get_temp_filename( $form['id'], $input_name ); GFCommon::log_debug( 'GFFormDisplay::upload_files(): Temp file info: ' . print_r( $file_info, true ) ); if ( $file_info && move_uploaded_file( $_FILES[ $input_name ]['tmp_name'], $target_path . $file_info['temp_filename'] ) ) { GFFormsModel::set_permissions( $target_path . $file_info['temp_filename'] ); $files[ $input_name ] = $file_info['uploaded_filename']; GFCommon::log_debug( "GFFormDisplay::upload_files(): File uploaded successfully: {$file_info['uploaded_filename']}" ); } else { GFCommon::log_error( "GFFormDisplay::upload_files(): File could not be uploaded: tmp_name: {$_FILES[ $input_name ]['tmp_name']} - target location: " . $target_path . $file_info['temp_filename'] ); } } return $files; } public static function get_state( $form, $field_values ) { $fields = array(); foreach ( $form['fields'] as $field ) { /* @var GF_Field $field */ if ( GFCommon::is_product_field( $field->type ) || $field->type == 'donation' || $field->type === 'consent' ) { $value = RGFormsModel::get_field_value( $field, $field_values, false ); $value = $field->get_value_default_if_empty( $value ); switch ( $field->inputType ) { case 'calculation' : case 'singleproduct' : case 'hiddenproduct' : $price = ! is_array( $value ) || empty( $value[ $field->id . '.2' ] ) ? $field->basePrice : $value[ $field->id . '.2' ]; if ( empty( $price ) ) { $price = 0; } $price = GFCommon::to_number( $price ); $product_name = ! is_array( $value ) || empty( $value[ $field->id . '.1' ] ) ? $field->label : $value[ $field->id . '.1' ]; $fields[ $field->id . '.1' ] = wp_hash( GFFormsModel::maybe_trim_input( $product_name, $form['id'], $field ) ); $fields[ $field->id . '.2' ] = wp_hash( GFFormsModel::maybe_trim_input( $price, $form['id'], $field ) ); break; case 'singleshipping' : $price = ! empty( $value ) ? $value : $field->basePrice; $price = ! empty( $price ) ? GFCommon::to_number( $price ) : 0; $fields[ $field->id ] = wp_hash( GFFormsModel::maybe_trim_input( $price, $form['id'], $field ) ); break; case 'radio' : case 'select' : $fields[ $field->id ] = array(); foreach ( $field->choices as $choice ) { $field_value = ! empty( $choice['value'] ) || $field->enableChoiceValue ? $choice['value'] : $choice['text']; if ( $field->enablePrice ) { $price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) ); $field_value .= '|' . $price; } $fields[ $field->id ][] = wp_hash( GFFormsModel::maybe_trim_input( $field_value, $form['id'], $field ) ); } break; case 'checkbox' : $index = 1; foreach ( $field->choices as $choice ) { $field_value = ! empty( $choice['value'] ) || $field->enableChoiceValue ? $choice['value'] : $choice['text']; if ( $field->enablePrice ) { $price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) ); $field_value .= '|' . $price; } if ( $index % 10 == 0 ) { //hack to skip numbers ending in 0. so that 5.1 doesn't conflict with 5.10 $index ++; } $fields[ $field->id . '.' . $index ++ ] = wp_hash( GFFormsModel::maybe_trim_input( $field_value, $form['id'], $field ) ); } break; case 'consent': $text = $field->checkboxLabel; $description = GFFormsModel::get_latest_form_revisions_id( $form['id'] ); $fields[ $field->id . '.1' ] = wp_hash( 1 ); $fields[ $field->id . '.2' ] = wp_hash( GFFormsModel::maybe_trim_input( $text, $form['id'], $field ) ); $fields[ $field->id . '.3' ] = wp_hash( GFFormsModel::maybe_trim_input( $description, $form['id'], $field ) ); break; } } } $hash = json_encode( $fields ); $checksum = wp_hash( crc32( $hash ) ); return base64_encode( json_encode( array( $hash, $checksum ) ) ); } /** * Determine if form has any pages. * * @access private * * @param array $form The form object * * @return bool If form object has any pages */ private static function has_pages( $form ) { return GFCommon::has_pages( $form ); } private static function has_character_counter( $form ) { if ( ! is_array( $form['fields'] ) ) { return false; } foreach ( $form['fields'] as $field ) { if ( $field->maxLength && ! $field->inputMask ) { return true; } } return false; } private static function has_placeholder( $form ) { if ( ! is_array( $form['fields'] ) ) { return false; } foreach ( $form['fields'] as $field ) { if ( $field->placeholder != '' ) { return true; } if ( is_array( $field->inputs ) ) { foreach ( $field->inputs as $input ) { if ( rgar( $input, 'placeholder' ) != '' ) { return true; } } } } return false; } private static function has_enhanced_dropdown( $form ) { if ( ! is_array( $form['fields'] ) ) { return false; } foreach ( $form['fields'] as $field ) { if ( in_array( RGFormsModel::get_input_type( $field ), array( 'select', 'multiselect' ) ) && $field->enableEnhancedUI ) { return true; } } return false; } private static function has_password_strength( $form ) { if ( ! is_array( $form['fields'] ) ) { return false; } foreach ( $form['fields'] as $field ) { if ( $field->type == 'password' && $field->passwordStrengthEnabled ) { return true; } } return false; } /** * Determines if form has a Password field with the Password Visibility Toggle enabled. * * @since 2.4.15 * * @param array $form Form object. * * @return bool */ private static function has_password_visibility( $form ) { if ( ! is_array( $form['fields'] ) ) { return false; } foreach ( $form['fields'] as $field ) { if ( $field->type == 'password' && $field->passwordVisibilityEnabled ) { return true; } } return false; } private static function has_other_choice( $form ) { if ( ! is_array( $form['fields'] ) ) { return false; } foreach ( $form['fields'] as $field ) { if ( $field->type == 'radio' && $field->enableOtherChoice ) { return true; } } return false; } public static function get_target_page( $form, $current_page, $field_values ) { $page_number = RGForms::post( "gform_target_page_number_{$form['id']}" ); $page_number = ! is_numeric( $page_number ) ? 1 : $page_number; $direction = $page_number >= $current_page ? 1 : - 1; //Finding next page that is not hidden by conditional logic while ( RGFormsModel::is_page_hidden( $form, $page_number, $field_values ) ) { $page_number += $direction; } //If all following pages are hidden, submit the form if ( $page_number > self::get_max_page_number( $form ) ) { $page_number = 0; } /** * Modify the target page. * * @since 2.1.2.13 * * @see https://docs.gravityforms.com/gform_target_page/ * * @param int $page_number The target page number. * @param array $form The current form object. * @param int $current_page The page that was submitted. * @param array $field_values Dynamic population values that were provided when loading the form. */ return gf_apply_filters( array( 'gform_target_page', $form['id'] ), $page_number, $form, $current_page, $field_values ); } public static function get_source_page( $form_id ) { $page_number = RGForms::post( "gform_source_page_number_{$form_id}" ); return ! is_numeric( $page_number ) ? 1 : $page_number; } public static function set_current_page( $form_id, $page_number ) { self::$submission[ $form_id ]['page_number'] = $page_number; } public static function get_current_page( $form_id ) { $page_number = isset( self::$submission[ $form_id ] ) ? intval( self::$submission[ $form_id ]['page_number'] ) : 1; return $page_number; } private static function is_page_active( $form_id, $page_number ) { return intval( self::get_current_page( $form_id ) ) == intval( $page_number ); } /** * Determine if the last page for the current form object is being submitted or rendered (depending on the provided $mode). * * @param array $form A Gravity Forms form object. * @param string $mode Mode to check for: 'submit' or 'render' * * @return boolean */ public static function is_last_page( $form, $mode = 'submit' ) { $page_number = self::get_source_page( $form['id'] ); $field_values = GFForms::post( 'gform_field_values' ); $target_page = self::get_target_page( $form, $page_number, $field_values ); if ( $mode == 'render' ) { $is_valid = rgars( self::$submission, "{$form['id']}/is_valid" ); $is_last_page = $is_valid && $target_page == self::get_max_page_number( $form ); } else { $is_last_page = (string) $target_page === '0'; } return $is_last_page; } /** * Returns the entry limit date range for the given period. * * @since unknown * @since 2.4.15 Updated the day period to use the local time. * * @param string $period The eriod for the entry limit. * * @return array */ private static function get_limit_period_dates( $period ) { if ( empty( $period ) ) { return array( 'start_date' => null, 'end_date' => null ); } switch ( $period ) { case 'day': return array( 'start_date' => current_time( 'Y-m-d' ), 'end_date' => current_time( 'Y-m-d 23:59:59' ), ); break; case 'week': return array( 'start_date' => gmdate( 'Y-m-d', strtotime( 'Monday this week' ) ), 'end_date' => gmdate( 'Y-m-d 23:59:59', strtotime( 'next Sunday' ) ), ); break; case 'month': $month_start = gmdate( 'Y-m-1'); return array( 'start_date' => $month_start, 'end_date' => gmdate( 'Y-m-d H:i:s', strtotime( "{$month_start} +1 month -1 second" ) ), ); break; case 'year': return array( 'start_date' => gmdate( 'Y-1-1' ), 'end_date' => gmdate( 'Y-12-31 23:59:59' ), ); break; } } public static function get_form( $form_id, $display_title = true, $display_description = true, $force_display = false, $field_values = null, $ajax = false, $tabindex = 0 ) { /** * 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 ); $action = remove_query_arg( 'gf_token' ); if ( rgpost( 'gform_send_resume_link' ) == $form_id ) { $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_draft_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 = $review_page_done = false; if ( isset( $_GET['gf_token'] ) ) { $incomplete_submission_info = GFFormsModel::get_draft_submission_values( $_GET['gf_token'] ); if ( rgar( $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 ); $form = self::maybe_add_review_page( $form, $partial_entry ); $review_page_done = true; $max_page_number = self::get_max_page_number( $form ); $page_number = $submission_details['page_number']; if ( $page_number > 1 && $max_page_number > 0 && $page_number > $max_page_number ) { $page_number = $max_page_number; } self::set_submission_if_null( $form_id, 'page_number', $page_number ); } } if ( ! $review_page_done && $form !== false ) { $form = self::maybe_add_review_page( $form ); } 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 ); } } 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 ) { /** * Filter the form not found message that will be displayed * * @since 2.2.6 * * @param string The default form not found message * @param int|string $form_id The ID of the form we tried to retrieve */ return apply_filters( 'gform_form_not_found_message', '
' . esc_html__( 'Oops! We could not locate your form.', 'gravityforms' ) . '
', $form_id ); } $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'] ) ? '' . esc_html__( 'Sorry. You must be logged in to view this form.', 'gravityforms' ) . '
' : '' . GFCommon::gform_do_shortcode( $form['requireLoginMessage'] ) . '
'; } } } // 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 .= "