diff --git a/assets/js/admin/form-builder.js b/assets/js/admin/form-builder.js index 22095bcb7..1a0f285e4 100644 --- a/assets/js/admin/form-builder.js +++ b/assets/js/admin/form-builder.js @@ -542,6 +542,7 @@ EVFPanelBuilder.init_datepickers(); EVFPanelBuilder.bindBulkOptionActions(); EVFPanelBuilder.bindAkismetInit(); + EVFPanelBuilder.bindFormSubmissionMinWaitingTime(); // Fields Panel. EVFPanelBuilder.bindUIActionsFields(); @@ -3204,6 +3205,32 @@ $(document).find('.everest-forms-akismet-protection-type').hide(); } }, + + /** + * Form Submission minimum waiting time. + * + * @since 3.0.2 + */ + bindFormSubmissionMinWaitingTime:function(){ + var submissionWaitingTimeEnabler = $(document).find('#everest-forms-panel-field-settings-form_submission_min_waiting_time'); + EVFPanelBuilder.formSubmissionMinTimeToggler(submissionWaitingTimeEnabler); + $(document).on('change', '#everest-forms-panel-field-settings-form_submission_min_waiting_time', function(){ + EVFPanelBuilder.formSubmissionMinTimeToggler($(this)); + }) + }, + /** + * Form Submission waiting time Toggler. + * + * @param {object} submissionWaitingTimeEnabler + */ + formSubmissionMinTimeToggler:function(submissionWaitingTimeEnabler){ + if($(submissionWaitingTimeEnabler).is(':checked')){ + $(document).find('.everest-forms-form-submission-minimum-waiting-time').show(); + }else{ + $(document).find('.everest-forms-form-submission-minimum-waiting-time').hide(); + } + }, + bindPrivacyPolicyActions: function() { // Consent message change handler. $( document.body ).on( 'input', '.everest-forms-field-option .evf-privacy-policy-consent-message', function ( e ) { diff --git a/assets/js/frontend/everest-forms.js b/assets/js/frontend/everest-forms.js index 5065dd088..991301744 100644 --- a/assets/js/frontend/everest-forms.js +++ b/assets/js/frontend/everest-forms.js @@ -35,7 +35,7 @@ jQuery( function ( $ ) { this.loadPhoneField(); this.loadCountryFlags(); this.ratingInit(); - + this.FormSubmissionWaitingTime(); // Inline validation. this.$everest_form.on( 'input validate change', '.input-text, select, input:checkbox, input:radio', this.validate_field ); @@ -47,6 +47,8 @@ jQuery( function ( $ ) { $(this).removeClass('everest-forms-field-active'); }); + ; + $( document.body ).trigger( 'everest_forms_loaded' ); @@ -597,6 +599,7 @@ jQuery( function ( $ ) { var recaptchaID = $submit.get( 0 ).recaptchaID; var razorpayForms = $form.find( "[data-gateway='razorpay']" ); var stripeForms = $form.find( "[data-gateway*='stripe']" ); + // Process form. if ( processText ) { $submit.text( processText ).prop( 'disabled', true ); @@ -948,7 +951,50 @@ jQuery( function ( $ ) { } return $( '
' + country.text + '' ); }, - + + FormSubmissionWaitingTime: function(){ + $(document).ready(function() { + var form_settings = everest_forms_params.form_settings['settings']; + var wait_form_submission_status = form_settings['form_submission_min_waiting_time']; + + if (wait_form_submission_status === '1') { + $('#evf_submission_start_time').val(Date.now()); + + // Create a MutationObserver to observe changes in the DOM. + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.addedNodes.length > 0) { + $(mutation.addedNodes).each(function() { + var display = $('#evf_submission_duration'); + if (display.length) { + var duration = parseInt(display.data('duration'), 10); + var timer = duration; + var interval = setInterval(function() { + display.text(timer); + if (--timer < 0) { + clearInterval(interval); + $('#evf_submission_duration').parent().remove(); + } + }, 1000); + + // Once the element is found, disconnect the observer. + observer.disconnect(); + } + }); + } + }); + }); + + // Start observing the target node for configured mutations. + var targetNode = document.body; + var config = { childList: true, subtree: true }; + observer.observe(targetNode, config); + } else { + return ''; + } + }); + }, + getFirstBrowserLanguage: function() { var nav = window.navigator, browserLanguagePropertyKeys = [ 'language', 'browserLanguage', 'systemLanguage', 'userLanguage' ], diff --git a/changelog.txt b/changelog.txt index 52a166e24..0d3e8b0e3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ == Changelog == += 3.0.2 - xx-xx-2024 +* Feature - Enable minimum time for form submission. + = 3.0.1 - 03-07-2024 * Feature - Import entries in our form using csv file. * Enhancement - Global Setting Premium Sidebar. diff --git a/includes/admin/builder/class-evf-builder-settings.php b/includes/admin/builder/class-evf-builder-settings.php index bf2764a6c..8c594b54c 100644 --- a/includes/admin/builder/class-evf-builder-settings.php +++ b/includes/admin/builder/class-evf-builder-settings.php @@ -791,6 +791,44 @@ public function output_content() { echo ''; echo ''; do_action( 'everest_forms_inline_security_settings', $this ); + + /** + * Minimum time for form submission. + * + * @since 3.0.1 + */ + echo '

' . esc_html__( 'Waiting time for form submission', 'everest-forms' ) . '

'; + everest_forms_panel_field( + 'toggle', + 'settings', + 'form_submission_min_waiting_time', + $this->form_data, + esc_html__( 'Enable minimum waiting time for form submission', 'everest-forms' ), + array( + 'default' => '0', + 'tooltip' => esc_html__( 'Prevents the form submission before the specified time', 'everest-forms' ), + ) + ); + + echo '
'; + everest_forms_panel_field( + 'number', + 'settings', + 'form_submission_min_waiting_time_input', + $this->form_data, + esc_html__( 'Form submission minimum waiting time (In seconds)', 'everest-forms' ), + array( + 'default' => '5', + 'tooltip' => esc_html__( 'Enter the minimum time waiting time for form submission.', 'everest-forms' ), + 'min_value' => 0, + ) + ); + + do_action( 'everest_forms_inline_form_submission_min_waiting_time_settings', $this, 'form_submission_min_waiting_time', 'connection_1' ); + + do_action( 'everest_forms_inline_form_submission_min_waiting_time_section_settings', $this, 'form_submission_min_waiting_time_section', 'connection_1' ); + echo '
'; + echo '
'; echo '
'; do_action( 'everest_forms_settings_panel_content', $this ); diff --git a/includes/admin/evf-admin-functions.php b/includes/admin/evf-admin-functions.php index 2979d68d7..56ca623e3 100644 --- a/includes/admin/evf-admin-functions.php +++ b/includes/admin/evf-admin-functions.php @@ -126,7 +126,7 @@ function evf_create_page( $slug, $option = '', $page_title = '', $page_content = */ function everest_forms_admin_fields( $options ) { if ( ! class_exists( 'EVF_Admin_Settings', false ) ) { - include dirname( __FILE__ ) . '/class-evf-admin-settings.php'; + include __DIR__ . '/class-evf-admin-settings.php'; } EVF_Admin_Settings::output_fields( $options ); @@ -140,7 +140,7 @@ function everest_forms_admin_fields( $options ) { */ function everest_forms_update_options( $options, $data = null ) { if ( ! class_exists( 'EVF_Admin_Settings', false ) ) { - include dirname( __FILE__ ) . '/class-evf-admin-settings.php'; + include __DIR__ . '/class-evf-admin-settings.php'; } EVF_Admin_Settings::save_fields( $options, $data ); @@ -156,7 +156,7 @@ function everest_forms_update_options( $options, $data = null ) { */ function everest_forms_settings_get_option( $option_name, $default = '' ) { if ( ! class_exists( 'EVF_Admin_Settings', false ) ) { - include dirname( __FILE__ ) . '/class-evf-admin-settings.php'; + include __DIR__ . '/class-evf-admin-settings.php'; } return EVF_Admin_Settings::get_option( $option_name, $default ); @@ -192,6 +192,7 @@ function everest_forms_panel_field( $option, $panel, $field, $form_data, $label, $default = isset( $args['default'] ) ? $args['default'] : ''; $tinymce = isset( $args['tinymce'] ) ? $args['tinymce'] : ''; $placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : ''; + $min_value = ! empty( $args['min_value'] ) ? esc_attr( $args['min_value'] ) : ''; $data_attr = ''; $output = ''; @@ -239,13 +240,14 @@ function everest_forms_panel_field( $option, $panel, $field, $form_data, $label, case 'number': case 'text': $output = sprintf( - '', + '', $option, sanitize_html_class( $panel_id ), sanitize_html_class( $field ), $field_name, esc_attr( $value ), $placeholder, + $min_value, $input_class, $data_attr, $custom_attributes @@ -349,7 +351,7 @@ function everest_forms_panel_field( $option, $panel, $field, $form_data, $label, $output .= sprintf( ' ', esc_attr( $item['tooltip'] ) ); } $output .= ''; - $x ++; + $x++; } break; diff --git a/includes/class-evf-form-task.php b/includes/class-evf-form-task.php index 962029aa1..b8d696b73 100644 --- a/includes/class-evf-form-task.php +++ b/includes/class-evf-form-task.php @@ -93,7 +93,7 @@ public function listen_task() { $settings = $this->form_data['settings']; $success_message = isset( $settings['successful_form_submission_message'] ) ? $settings['successful_form_submission_message'] : __( 'Thanks for contacting us! We will be in touch with you shortly.', 'everest-forms' ); - // Send 400 Bad Request when there are errors. + // Send 400 Bad Request when there are errors. if ( empty( $this->errors[ $form_id ] ) ) { wp_send_json( array( @@ -357,6 +357,18 @@ public function do_task( $entry ) { } // Initial error check. $errors = apply_filters( 'everest_forms_process_initial_errors', $this->errors, $this->form_data ); + + // Minimum time to submit check. + $min_submit_time = $this->form_submission_waiting_time( $this->errors, $this->form_data ); + if ( isset( $min_submit_time[ $form_id ]['header'] ) && ! empty( $min_submit_time ) ) { + $this->errors[ $form_id ]['header'] = $min_submit_time[ $form_id ]['header']; + $logger->error( + $min_submit_time[ $form_id ]['header'], + array( 'source' => 'Minimum time to submit' ) + ); + return $this->errors; + } + if ( isset( $_POST['__amp_form_verify'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing if ( empty( $errors[ $form_id ] ) ) { wp_send_json( array(), 200 ); @@ -649,7 +661,7 @@ public function do_task( $entry ) { $response_data = apply_filters( 'everest_forms_after_success_ajax_message', $response_data, $this->form_data, $entry ); return $response_data; } elseif ( ( 'same' === $this->form_data['settings']['redirect_to'] && empty( $submission_redirection_process ) ) || ( ! empty( $submission_redirection_process ) && 'same_page' == $submission_redirection_process['redirect_to'] ) ) { - evf_add_notice( $message, 'success' ); + evf_add_notice( $message, 'success' ); } $logger->info( 'Everest Forms After success Message.', @@ -974,7 +986,7 @@ public function entry_email( $fields, $entry, $form_data, $entry_id, $context = $emails->send( trim( $address ), $email['subject'], $email['message'], '', $connection_id ); } - endforeach; + endforeach; if ( isset( $attachment ) ) { do_action( 'everest_forms_remove_attachments_after_send_email', $attachment, $fields, $form_data, 'entry-email', $connection_id, $entry_id ); } @@ -1207,7 +1219,7 @@ public function load_previous_field_value( $properties, $field, $form_data ) { } } } elseif ( ! is_array( $data ) ) { - $properties['inputs']['primary']['attr']['value'] = esc_attr( $data ); + $properties['inputs']['primary']['attr']['value'] = esc_attr( $data ); } return $properties; } @@ -1432,4 +1444,43 @@ public function evf_set_approval_status( $entry_id, $form_data ) { update_option( 'everest_forms_admin_entry_approval_token', $evf_new_token ); } } + + /** + * Prevents form submission before the specified duration. + * + * @param array $errors Form submit errors. + * @param object $form_data An object containing settings for the form. + */ + public function form_submission_waiting_time( $errors, $form_data ) { + $form_submission_waiting_time_enable = isset( $form_data['settings']['form_submission_min_waiting_time'] ) ? $form_data['settings']['form_submission_min_waiting_time'] : ''; + $submission_duration = $form_data['settings']['form_submission_min_waiting_time_input']; + + if ( '1' === $form_submission_waiting_time_enable && 0 <= absint( $submission_duration ) ) { + $evf_submission_start_time = isset( $_POST['evf_submission_start_time'] ) ? sanitize_text_field( wp_unslash( $_POST['evf_submission_start_time'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification + $atts = $form_data['id']; + $submission_time = time() * 1000; + + $waiting_time = absint( $submission_time ) - absint( $evf_submission_start_time ); + $form_id = ! empty( $form_data['id'] ) ? $form_data['id'] : 0; + + if ( absint( $submission_time ) - absint( $evf_submission_start_time ) <= absint( $submission_duration ) * 1000 ) { + $form_submission_err_msg = apply_filters( + 'everest_forms_minimum_waiting_time_form_submission', + sprintf( + "%s %s %s", + esc_html__( 'Please wait', 'everest-forms' ), + $submission_duration, + $submission_duration, + esc_html__( 'seconds, security checkup is being executed.', 'everest-forms' ) + ) + ); + + $errors[ $form_id ]['header'] = $form_submission_err_msg; + } + + return $errors; + } + } + + } diff --git a/includes/class-evf-frontend-scripts.php b/includes/class-evf-frontend-scripts.php index 5717b5083..8395974cc 100644 --- a/includes/class-evf-frontend-scripts.php +++ b/includes/class-evf-frontend-scripts.php @@ -327,6 +327,7 @@ private static function get_script_data( $handle ) { 'plugin_url' => plugin_dir_url( EVF_PLUGIN_FILE ), 'i18n_messages_phone' => get_option( 'everest_forms_phone_validation', __( 'Please enter a valid phone number.', 'everest-forms' ) ), 'i18n_field_rating_greater_than_max_value_error' => esc_html__( 'Please enter in a value less than 100.', 'everest-forms' ), + 'form_settings' => isset( $_GET['form_id'] ) ? evf()->form->get( absint( $_GET['form_id'] ), array( 'content_only' => true ) ) : 0, ); break; case 'everest-forms-text-limit': diff --git a/includes/shortcodes/class-evf-shortcode-form.php b/includes/shortcodes/class-evf-shortcode-form.php index aa454e199..a47e89d3d 100644 --- a/includes/shortcodes/class-evf-shortcode-form.php +++ b/includes/shortcodes/class-evf-shortcode-form.php @@ -51,6 +51,9 @@ public static function hooks() { // reCaptcha Language. add_filter( 'everest_forms_frontend_recaptcha_url', array( __CLASS__, 'evf_recaptcha_language' ), 10, 1 ); + + // Enable for submission waiting time. + add_filter( 'everest_forms_display_fields_before', array( 'EVF_Shortcode_Form', 'evf_form_submission_waiting_time' ) ); } /** @@ -1157,9 +1160,7 @@ private static function view( $atts ) { * @return $url */ public static function evf_recaptcha_language( $url ) { - return esc_url_raw( add_query_arg( array( 'hl' => get_option( 'everest_forms_recaptcha_recaptcha_language', 'en-GB' ) ), $url ) ); - } /** @@ -1245,4 +1246,22 @@ function () use ( $custom_css, $form_id ) { } } } + + /** + * Function to enable the minimum form submission waiting time. + * + * @since 3.0.2 + * + * @param array $form_data Form Data. + */ + public static function evf_form_submission_waiting_time( $form_data ) { + $form_submission_waiting_time_enable = isset( $form_data['settings']['form_submission_min_waiting_time'] ) ? $form_data['settings']['form_submission_min_waiting_time'] : ''; + $submission_duration = isset( $form_data['settings']['form_submission_min_waiting_time_input'] ) ? $form_data['settings']['form_submission_min_waiting_time_input'] : ''; + + if ( '1' === $form_submission_waiting_time_enable ) { + echo ""; + } else { + return ''; + } + } } diff --git a/readme.txt b/readme.txt index cc9d307c2..bcc4f11d9 100644 --- a/readme.txt +++ b/readme.txt @@ -2,9 +2,9 @@ Contributors: WPEverest Tags: contact form, custom form, form builder, forms, survey Requires at least: 5.2 -Tested up to: 6.5.5 +Tested up to: 6.6.1 Requires PHP: 7.2 -Stable tag: 3.0.1 +Stable tag: 3.0.2 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -308,6 +308,9 @@ Yes you can! Join in on our [GitHub repository](https://github.com/wpeverest/eve == Changelog == += 3.0.2 - xx-xx-2024 +* Feature - Enable minimum time for form submission. + = 3.0.1 - 03-07-2024 * Feature - Import entries in our form using csv file. * Enhancement - Global Setting Premium Sidebar.