Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement - Date time slot booking #1117

Merged
merged 10 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion assets/css/admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2288,7 +2288,8 @@ p.search-box {

.everest-forms-current-date-format,
.everest-forms-past-date-disable-format,
.everest-forms-min-max-date-format {
.everest-forms-min-max-date-format,
.everest-forms-slot-booking {
margin-bottom: 14px;
}

Expand Down
19 changes: 19 additions & 0 deletions assets/js/admin/form-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,13 @@
var id = $( this ).attr( 'data-field-id' );
EVFPanelBuilder.dateSettingToggler( id, $('#everest-forms-field-option-' + id + '-datetime_style' ).val() );
} );

if($('.everest-forms-slot-booking input').is(":checked")) {
//checked and hide past dates.
disable_past_date = $(document).find('.everest-forms-past-date-disable-format input');
disable_past_date.attr("checked", true);
disable_past_date.parent().hide();
}
},

/**
Expand Down Expand Up @@ -988,6 +995,18 @@
$( '#everest-forms-field-option-' + id ).removeClass( 'everest-forms-confirm-enabled' ).addClass( 'everest-forms-confirm-disabled' );
}
});
// Real-time updates for slot booking
$builder.on('change', '.everest-forms-slot-booking input', function(event) {
if($(this).is(":checked")) {
disable_past_date = $(document).find('.everest-forms-past-date-disable-format input');
if(disable_past_date.is(":not(:checked)")) {
disable_past_date.prop("checked", true);
}
disable_past_date.parent().hide();
} else {
disable_past_date.parent().show();
}
});

// Real-time updates for "Placeholder" field option.
$builder.on( 'input', '.everest-forms-field-option-row-placeholder input', function(e) {
Expand Down
39 changes: 39 additions & 0 deletions assets/js/frontend/everest-forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,45 @@ jQuery( function ( $ ) {
}
} );
}
$(document).find(".evf-field-date-time input").on('change', function (event) {
var slotBooking = $(this).data('slot-booking'),
targetLabel = $(this).parent(),
errorLabel = $(this).parent().find('.evf-error');
if(slotBooking === 1) {
var dataTimeValue = $(this).val(),
dateFormat = $(this).data('date-format'),
dateTimeFormat = $(this).data('date-time'),
mode = $(this).data('mode'),
form_id = $(this).data('form-id'),
time_interval = $(this).data('time-interval'),
data = {'action':'everest_forms_slot_booking', 'data-time-value':dataTimeValue, 'data-format': dateFormat, 'data-time-format': dateTimeFormat, 'mode': mode, 'form-id': form_id, 'time-interval':time_interval, 'security': everest_forms_params.everest_forms_slot_booking};

$.ajax({
url:everest_forms_params.ajax_url,
data: data,
type: 'POST',
beforeSend: function () {
var submitButton = $(document).find('.evf-submit-container button');
$(submitButton).prop('disabled', true);
},
success: function (res) {
if($(errorLabel).length) {
$(errorLabel).remove();
}
if(res.success === true) {
var message = res.data.message;
$(targetLabel).append('<label class="evf-error">'+message+'</label>');
var submitButton = $(document).find('.evf-submit-container button');
$(submitButton).prop('disabled', true);
} else {
var submitButton = $(document).find('.evf-submit-container button');
$(submitButton).prop('disabled', false);
}
}
});
}
})

},
init_datedropdown: function () {
//Dropdown logic here
Expand Down
3 changes: 2 additions & 1 deletion changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
- 2.0.2 - xx-xx-2023
* Feature - Regex validation for field.
* Feature - Custom CSS and JS for form.
* Enhancement - Upgrade to the pro improve for dragging a field
* Enhancement - Upgrade to the pro improve for dragging a field.
* Enhancement - Date time slot booking.
* Fix - Word count issue with Cyrillic text.

- 2.0.1 - 14-06-2023
Expand Down
30 changes: 30 additions & 0 deletions includes/abstracts/class-evf-form-fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -2555,6 +2555,36 @@ public function validate( $field_id, $field_submit, $form_data ) {
}
}

break;
case 'date-time':
$slot_booking = isset( $form_data['form_fields'][ $field_id ]['slot_booking_advanced'] ) ? $form_data['form_fields'][ $field_id ]['slot_booking_advanced'] : '';
if ( $slot_booking ) {
$datetime_format = isset( $form_data['form_fields'][ $field_id ]['datetime_format'] ) ? $form_data['form_fields'][ $field_id ]['datetime_format'] : '';
$date_format = isset( $form_data['form_fields'][ $field_id ]['date_format'] ) ? $form_data['form_fields'][ $field_id ]['date_format'] : '';
$mode = isset( $form_data['form_fields'][ $field_id ]['date_mode'] ) ? $form_data['form_fields'][ $field_id ]['date_mode'] : '';
$time_interval = isset( $form_data['form_fields'][ $field_id ]['time_interval'] ) ? $form_data['form_fields'][ $field_id ]['time_interval'] : '';
$datetime_arr = parse_datetime_values( $field_submit, $datetime_format, $date_format, $mode, $time_interval );
$booked_slot = maybe_unserialize( get_option( 'evf_booked_slot', '' ) );
$form_id = $form_data['id'];
$is_booked = false;
if ( ! empty( $booked_slot ) && array_key_exists( $form_id, $booked_slot ) ) {
foreach ( $datetime_arr as $arr ) {

foreach ( $booked_slot[ $form_id ] as $slot ) {
if ( $arr[0] >= $slot[0] && $arr[1] <= $slot[1] ) {
$is_booked = true;
break;
} elseif ( $arr[0] >= $slot[0] && $arr[0] < $slot[1] && $arr[1] >= $slot[1] ) {
$is_booked = true;
break;
}
}
}
}
if ( $is_booked ) {
$validation_text = get_option( 'evf_' . $field_type . '_validation', esc_html__( 'This slot is already booked. Please choose other slot.', 'everest-forms' ) );
}
}
break;
}

Expand Down
54 changes: 54 additions & 0 deletions includes/class-evf-ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public static function add_ajax_events() {
'ajax_form_submission' => true,
'send_test_email' => false,
'locate_form_action' => false,
'slot_booking' => true,
'active_addons' => false,
);

Expand Down Expand Up @@ -864,6 +865,59 @@ public static function locate_form_action() {
);
}
}
/**
* Slot booking.
*/
public static function slot_booking() {
try {
check_ajax_referer( 'everest_forms_slot_booking_nonce', 'security' );
$datetime_value = isset( $_POST['data-time-value'] ) ? sanitize_text_field( wp_unslash( $_POST['data-time-value'] ) ) : '';
$datetime_format = isset( $_POST['data-time-format'] ) ? sanitize_text_field( wp_unslash( $_POST['data-time-format'] ) ) : '';
$date_format = isset( $_POST['data-format'] ) ? sanitize_text_field( wp_unslash( $_POST['data-format'] ) ) : '';
$mode = isset( $_POST['mode'] ) ? sanitize_text_field( wp_unslash( $_POST['mode'] ) ) : '';
$form_id = isset( $_POST['form-id'] ) ? sanitize_text_field( wp_unslash( $_POST['form-id'] ) ) : '';
$time_interval = isset( $_POST['time-interval'] ) ? sanitize_text_field( wp_unslash( $_POST['time-interval'] ) ) : '';
$datetime_arr = parse_datetime_values( $datetime_value, $datetime_format, $date_format, $mode, $time_interval );

if ( empty( $datetime_arr ) ) {
wp_send_json_error(
array(
'message' => __( 'Please select at least one date time.', 'everest-forms' ),
)
);
}
$booked_slot = maybe_unserialize( get_option( 'evf_booked_slot', '' ) );
$is_booked = false;
if ( ! empty( $booked_slot ) && array_key_exists( $form_id, $booked_slot ) ) {
foreach ( $datetime_arr as $arr ) {

foreach ( $booked_slot[ $form_id ] as $slot ) {
if ( $arr[0] >= $slot[0] && $arr[1] <= $slot[1] ) {
$is_booked = true;
break;
} elseif ( $arr[0] >= $slot[0] && $arr[0] < $slot[1] && $arr[1] >= $slot[1] ) {
$is_booked = true;
break;
}
}
}
}
if ( $is_booked ) {
wp_send_json_success(
array(
'message' => __( 'This slot is already booked. Please choose other slot', 'everest-forms' ),
)
);
}
wp_send_json_error(
array(
'message' => __( 'This slot is not booked.', 'everest-forms' ),
)
);

}
}

/**
* Activate addons from builder.
*/
Expand Down
57 changes: 57 additions & 0 deletions includes/class-evf-form-task.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class EVF_Form_Task {
public function __construct() {
add_action( 'wp', array( $this, 'listen_task' ) );
add_filter( 'everest_forms_field_properties', array( $this, 'load_previous_field_value' ), 99, 3 );
add_action( 'everest_forms_complete_entry_save', array( $this, 'update_slot_booking_value' ), 10, 5 );
}

/**
Expand Down Expand Up @@ -1039,6 +1040,62 @@ public function entry_save( $fields, $entry, $form_id, $form_data = array() ) {
return $this->entry_id;
}

/**
* Insert or update the slot booking data.
*
* @param int $entry_id Entry id.
* @param array $fields List of form fields.
* @param array $entry User submitted data.
* @param int $form_id Form ID.
* @param array $form_data Prepared form settings.
*/
public function update_slot_booking_value( $entry_id, $fields, $entry, $form_id, $form_data ) {
$new_slot_booking_field_meta_key_list = array();
$time_interval = 0;
foreach ( $form_data['form_fields'] as $field ) {
if ( ( 'date-time' === $field['type'] ) && isset( $field['slot_booking_advanced'] ) && evf_string_to_bool( $field['slot_booking_advanced'] ) ) {
$new_slot_booking_field_meta_key_list[ $field['meta-key'] ] = array(
$field['datetime_format'],
$field['date_format'],
$field['date_mode'],
);
$time_interval = $field['time_interval'];
}
}

foreach ( $fields as $key => $value ) {
if ( array_key_exists( $value['meta_key'], $new_slot_booking_field_meta_key_list ) ) {
$new_value = $value['value'];
$datetime_format = $new_slot_booking_field_meta_key_list[ $value['meta_key'] ][0];
$date_format = $new_slot_booking_field_meta_key_list[ $value['meta_key'] ][1];
$mode = $new_slot_booking_field_meta_key_list[ $value['meta_key'] ][2];
$datetime_arr = parse_datetime_values( $new_value, $datetime_format, $date_format, $mode, $time_interval );
}
}

if ( ! empty( $datetime_arr ) ) {
$get_booked_slot = get_option( 'evf_booked_slot', array() );
$new_booked_slot = array( $form_id => $datetime_arr );

if ( empty( $get_booked_slot ) ) {
$all_booked_slot = maybe_serialize( $new_booked_slot );
} else {
$unserialized_booked_slot = maybe_unserialize( $get_booked_slot );

if ( array_key_exists( $form_id, $unserialized_booked_slot ) ) {
$booked_slot = $unserialized_booked_slot[ $form_id ];
$booked_slot = array_merge( (array) $booked_slot, $datetime_arr );
$new_booked_slot = array( $form_id => $booked_slot );
}

$all_booked_slot = maybe_serialize( array_replace( $unserialized_booked_slot, $new_booked_slot ) );
}

update_option( 'evf_booked_slot', $all_booked_slot );
}

}

/**
* Load Previous Field Value.
*
Expand Down
1 change: 1 addition & 0 deletions includes/class-evf-frontend-scripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ private static function get_script_data( $handle ) {
'submit' => esc_html__( 'Submit', 'everest-forms' ),
'disable_user_details' => get_option( 'everest_forms_disable_user_details' ),
'everest_forms_data_save' => wp_create_nonce( 'everest_forms_data_save_nonce' ),
'everest_forms_slot_booking' => wp_create_nonce( 'everest_forms_slot_booking_nonce' ),
'i18n_messages_required' => get_option( 'everest_forms_required_validation' ),
'i18n_messages_url' => get_option( 'everest_forms_url_validation' ),
'i18n_messages_email' => get_option( 'everest_forms_email_validation' ),
Expand Down
78 changes: 76 additions & 2 deletions includes/evf-core-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,7 @@ function evf_get_random_string( $length = 10 ) {
* Get all forms.
*
* @param bool $skip_disabled_entries True to skip disabled entries.
* @param bool $check_disable_storing_entry_info Check disable storing entry.
* @return array of form data.
*/
function evf_get_all_forms( $skip_disabled_entries = false, $check_disable_storing_entry_info = true ) {
Expand Down Expand Up @@ -4620,7 +4621,7 @@ function evf_file_get_contents( $file ) {
if ( $file ) {
$local_file = preg_replace( '/\\\\|\/\//', '/', plugin_dir_path( EVF_PLUGIN_FILE ) . $file );
$response = file_get_contents($local_file);
if( $response ){
if ( $response ) {
return $response;
}
global $wp_filesystem;
Expand All @@ -4636,7 +4637,80 @@ function evf_file_get_contents( $file ) {
}

/**
* EVF word Count
* Parses datetime values based on the provided format and mode.
*
* @param string $datetime_value The datetime value to parse.
* @param string $datetime_format The format of the datetime value.
* @param string $date_format The format of the date.
* @param string $mode The mode of the datetime field,
* @param int $time_interval The time interval in minutes.
* @return array
*/
function parse_datetime_values( $datetime_value, $datetime_format, $date_format, $mode, $time_interval ) {
$datetime_arr = array();

switch ($datetime_format) {
case 'time':
$current_date = gmdate('Y-m-d');
$datetime_value = gmdate('H:i', strtotime($datetime_value));
$datetime_start = "$current_date $datetime_value";
$date_time = new DateTime($datetime_start);
$date_time->modify("+$time_interval minute");
$datetime_end = $date_time->format('Y-m-d H:i');
$datetime_arr[] = array($datetime_start, $datetime_end);
break;
case 'date':
if ('range' === $mode) {
$selected_dates = explode(' to ', $datetime_value);
if (count($selected_dates) >= 2) {
$datetime_start = "$selected_dates[0] 00:00";
$datetime_start = gmdate('Y-m-d H:i', strtotime($datetime_start));
$date_time = new DateTime($selected_dates[1]);
$date_time->modify('+23 hour');
$datetime_end = $date_time->format('Y-m-d H:i');
$datetime_arr[] = array($datetime_start, $datetime_end);
}
} else {
$selected_dates = explode(', ', $datetime_value);

foreach ($selected_dates as $selected_date) {
$datetime_start = "$selected_date 00:00";
$datetime_start = gmdate('Y-m-d H:i', strtotime($datetime_start));
$date_time = new DateTime($datetime_start);
$date_time->modify('+23 hour');

$datetime_end = $date_time->format('Y-m-d H:i');
$datetime_arr[] = array($datetime_start, $datetime_end);
}
}
break;
case 'date-time':
if ('range' === $mode) {
$selected_dates = explode(' to ', $datetime_value);
if (count($selected_dates) >= 2) {
$datetime_start = gmdate('Y-m-d H:i', strtotime($selected_dates[0]));
$datetime_end = gmdate('Y-m-d H:i', strtotime($selected_dates[1]));
$datetime_arr[] = array($datetime_start, $datetime_end);
}
} else {
$selected_dates = explode(', ', $datetime_value);

foreach ($selected_dates as $selected_date) {
$datetime_start = gmdate('Y-m-d H:i', strtotime($selected_date));
$date_time = new DateTime($datetime_start);
$date_time->modify("+$time_interval minute");
$datetime_end = $date_time->format('Y-m-d H:i');
$datetime_arr[] = array($datetime_start, $datetime_end);
}
}
break;
}

return $datetime_arr;
}

/*
* EVF word Count
* @since 2.0.2
*/
function _evf_word_count( $text, $type = 'words', $settings = array() ) {
Expand Down
Loading