# booking/11.4.2/includes/page-setup/setup_ajax.php

Booking Calendar, version 11.4.2. 443 lines.

- Page: https://pluginprobe.com/plugins/booking/11.4.2/code/includes/page-setup/setup_ajax.php
- Raw: https://pluginprobe.com/plugins/booking/11.4.2/raw/includes/page-setup/setup_ajax.php
- Modified: 2026-06-23T07:56:44+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/booking/11.4.2/code/includes/page-setup/setup_ajax.php#L10-L20`.

```php
<?php /**
 * @version 1.0
 * @description Ajax and Requests Structure  for   WPBC_AJX__Setup__Ajax_Request
 * @category   Setup Class
 * @author wpdevelop
 *
 * @web-site http://oplugins.com/
 * @email info@oplugins.com
 *
 * @modified 2023-06-23
 */

if ( ! defined( 'ABSPATH' ) ) exit;                                             // Exit if accessed directly

// =====================================================================================================================
// ==  Get RULES STRUCTURE  ==
// =====================================================================================================================

/**
* Get params names for escaping and/or default value of such  params
*
* @return array        array (  'resource_id'      => array( 'validate' => 'digit_or_csd',  	'default' => array( '1' ) )
*                             , ... )
*/
function wpbc_setup_wizard_page__request_rules_structure() {

	return array(
		'do_action' => array(
			'validate' => array(
								'none',
								'save_and_continue',
								'make_reset', 'skip_wizard',

								'save_and_continue__welcome',
								'save_and_continue__general_info',
								'save_and_continue__date_time_formats',
								'save_and_continue__bookings_types',
								'redirect_to_setup_step'
						),
			'default'  => 'none'
		),
		'current_step'          => array( 'validate' => 's', 'default' => '' ),
		'resource_id'           => array( 'validate' => 'd', 'default' => wpbc_get_default_resource() ),
		'ui_clicked_element_id' => array( 'validate' => 's', 'default' => '' )
		// 'calendar__booking_start_day_weeek' => array( 'validate' => array( '0', '1', '2', '3', '4', '5', '6' ), 'default'  => get_bk_option( 'booking_start_day_weeek' ) )
	);
}


	/**
	 * Get default params
	 *
	 * @return array        array (  'ui_wh_modification_date_radio' => 0
	 *                             , ... )
	 */
	function wpbc_setup_wizard_page__get__request_values__default(){

		$request_rules_structure = wpbc_setup_wizard_page__request_rules_structure();

		$default_params_arr = array();

		$structure_type = 'default';

		foreach ( $request_rules_structure as $key => $value ) {
			$default_params_arr[ $key ] = $value[ $structure_type ];
		}

		return $default_params_arr;
	}


// =====================================================================================================================
// ==  Get sanitised Request parameters  for  Ajax  ==
// =====================================================================================================================

/**
 * Get sanitised request parameters. |  01. -> Firstly check if user saved request params in user_meta DB.
 *                                   |  02. -> Otherwise check      $_REQUEST.
 *                                   |  03. -> Otherwise Get        default.
 *
 * @return array|false
 */
function wpbc_setup_wizard_page__get_cleaned_params__saved_request_default(){

	// User Specific Experience with Setup -> saved to user meta_table.
	// E.g. next  time user  open the page with  saved own settings
	$user_request = new WPBC_AJX__REQUEST( array(
											   'db_option_name'          => 'booking_setup_wizard_page_request_params',
											   'user_id'                 => wpbc_get_current_user_id(),
											   'request_rules_structure' => wpbc_setup_wizard_page__request_rules_structure()
											)
					);

	// -----------------------------------------------------------------------------------------------------------------
	// Get saved from DB
	// -----------------------------------------------------------------------------------------------------------------
	$escaped_request_params_arr = $user_request->get_sanitized__saved__user_request_params();


	// -----------------------------------------------------------------------------------------------------------------
	// Get $_REQUEST or Default      ::       This request was not saved before, then get sanitized direct parameters   , such as: 	$_REQUEST['resource_id']
	// -----------------------------------------------------------------------------------------------------------------
	if ( false === $escaped_request_params_arr ) {
		$request_prefix = false;
		$escaped_request_params_arr = $user_request->get_sanitized__in_request__value_or_default( $request_prefix  );
	}

	// -----------------------------------------------------------------------------------------------------------------
	// ==  O V E R R I D E    - DB params  by  the params from  REQUEST!  ==
	// -----------------------------------------------------------------------------------------------------------------
	$request_key = 'current_step';
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
    if ( isset( $_REQUEST[ $request_key ] ) ) {

		 // Get SANITIZED REQUEST parameters together with default values
		$request_prefix = false;
		$url_request_params_arr = $user_request->get_sanitized__in_request__value_or_default( $request_prefix  );		 		// Direct: 	$_REQUEST['resource_id']

		// Now get only SANITIZED values that exist in REQUEST
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
		$url_request_params_only_arr = array_intersect_key( $url_request_params_arr, $_REQUEST );

		// And now override our DB  $escaped_request_params_arr  by  SANITIZED $_REQUEST values
		$escaped_request_params_arr  = wp_parse_args( $url_request_params_only_arr, $escaped_request_params_arr );
	}
	// ---------------------------------------------------------------------------------------------------------

	//	//MU
	//	if ( class_exists( 'wpdev_bk_multiuser' ) ) {
	//
	//		// Check if this MU user activated or super-admin,  otherwise show warning
	//		if ( ! wpbc_is_mu_user_can_be_here('activated_user') )
	//			return  false;
	//
	//		// Check if this MU user owner of this resource or super-admin,  otherwise show warning
	//		if ( ! wpbc_is_mu_user_can_be_here( 'resource_owner', $escaped_request_params_arr['resource_id'] ) ) {
	//			$default_values = $user_request->get_request_rules__default();
	//			$escaped_request_params_arr['resource_id'] = $default_values['resource_id'];
	//		}
	//	}

    return $escaped_request_params_arr;
}


// =====================================================================================================================
// ==  A J A X  ==
// =====================================================================================================================

class WPBC_AJX__Setup_Wizard__Ajax_Request {


	/**
	 * Define HOOKs for start  loading Ajax
	 */
	public function define_ajax_hook(){

		// Ajax Handlers.		Note. "locale_for_ajax" rechecked in wpbc-ajax.php
		add_action( 'wp_ajax_'		     . 'WPBC_AJX_SETUP_WIZARD_PAGE', array( $this, 'ajax_' . 'WPBC_AJX_SETUP_WIZARD_PAGE' ) );	    // Admin & Client (logged in usres)
		add_action( 'wp_ajax_'		     . 'WPBC_AJX_SETUP_WIZARD_MARK_STEP_SAVED', array( $this, 'ajax_' . 'WPBC_AJX_SETUP_WIZARD_MARK_STEP_SAVED' ) );

		// Ajax Handlers for actions
		// add_action( 'wp_ajax_nopriv_' . 'WPBC_AJX_BOOKING_LISTING', array( $this, 'ajax_' . 'WPBC_AJX_BOOKING_LISTING' ) );	    // Client         (not logged in)
	}

	/**
	 * Ajax - mark an external setup step as saved after an existing settings page saves successfully.
	 *
	 * @return void
	 */
	public function ajax_WPBC_AJX_SETUP_WIZARD_MARK_STEP_SAVED() {

		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
		if ( ! wp_verify_nonce( $nonce, 'wpbc_setup_wizard_mark_step_saved' ) ) {
			wp_send_json_error( array( 'message' => __( 'Security check failed.', 'booking' ) ) );
		}

		$step_name   = isset( $_POST['wpbc_setup_step'] ) ? sanitize_key( wp_unslash( $_POST['wpbc_setup_step'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
		$setup_steps = new WPBC_SETUP_WIZARD_STEPS();
		$steps_arr   = $setup_steps->get_steps_arr();

		if ( empty( $step_name ) && function_exists( 'wpbc_setup_wizard__detect_step_from_admin_url' ) ) {
			$referer_step = wpbc_setup_wizard__detect_step_from_admin_url( wp_get_referer() );
			if ( ! empty( $referer_step ) && isset( $steps_arr[ $referer_step ] ) ) {
				$step_name = $referer_step;
			}
		}

		if ( empty( $step_name ) || ! isset( $steps_arr[ $step_name ] ) ) {
			wp_send_json_error( array( 'message' => __( 'Unknown setup step.', 'booking' ) ) );
		}

		$setup_steps->db__set_step_as_saved( $step_name, true );
		$setup_steps->db__save_current_step_name( $step_name );

		wp_send_json_success( array( 'step' => $step_name ) );
	}


	/**
	 * Ajax - Get Listing Data and Response to JS script
	 */
	public function ajax_WPBC_AJX_SETUP_WIZARD_PAGE() {

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
		if ( ! isset( $_POST['all_ajx_params'] ) || empty( $_POST['all_ajx_params'] ) ) { exit; }

		// -------------------------------------------------------------------------------------------------------------
		// ==  Security  ==         ->   in Ajax Post:   'nonce': wpbc_ajx_booking_listing.get_secure_param( 'nonce' )
		// -------------------------------------------------------------------------------------------------------------
		$action_name    = 'wpbc_setup_wizard_page_ajx' . '_wpbcnonce';
		$nonce_post_key = 'nonce';
		$result_check   = check_ajax_referer( $action_name, $nonce_post_key );

		$user_id = ( isset( $_REQUEST['wpbc_ajx_user_id'] ) )  ?  intval( $_REQUEST['wpbc_ajx_user_id'] )  :  wpbc_get_current_user_id();  // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing

		// -------------------------------------------------------------------------------------------------------------
		// ==  Request  ==          ->  $_REQUEST['all_ajx_params']['page_num'],   $_REQUEST['all_ajx_params']['page_items_count'], ...
		// -------------------------------------------------------------------------------------------------------------
		$user_request = new WPBC_AJX__REQUEST( array(
												   'db_option_name'          => 'booking_setup_wizard_page_request_params',
												   'user_id'                 => $user_id,
												   'request_rules_structure' => wpbc_setup_wizard_page__request_rules_structure()
												)
						);
		//--------------------------------------------------------------------------------------------------------------
		// If in Ajax:   all_ajx_params: _wpbc_settings.get_all_..()  ->  Use prefix "all_ajx_params"       THEN        Sanitize required REQUEST params
		//--------------------------------------------------------------------------------------------------------------
		$request_prefix = 'all_ajx_params';
		$cleaned_request_params = $user_request->get_sanitized__in_request__value_or_default( $request_prefix  );		// NOT Direct: 	$_REQUEST['all_ajx_params']['resource_id']
		//--------------------------------------------------------------------------------------------------------------

		$cleaned_data = array();
		$setup_steps  = new WPBC_SETUP_WIZARD_STEPS();

		$data_arr = array();
		$data_arr['ajx_after_action_message'] = '';
		$data_arr['ajx_after_action_result']  = 1;                  // Message Type:   ? '1' => 'success' : 'error'
		//--------------------------------------------------------------------------------------------------------------
		// Steps
		//--------------------------------------------------------------------------------------------------------------
		$data_arr['current_step']  = ( ! empty( $cleaned_request_params['current_step'] )
										? $cleaned_request_params['current_step']
										: $setup_steps->get_active_step_name() );       // e.g. 'general_info' or 'date_availability'
		$data_arr['steps'] = $setup_steps->get_steps_arr();
		if ( ! isset( $data_arr['steps'][ $data_arr['current_step'] ] ) ) {
			$data_arr['current_step'] = $setup_steps->get_active_step_name();
		}

		// -------------------------------------------------------------------------------------------------------------
		// Get Wizard history
		// -------------------------------------------------------------------------------------------------------------
		$booking_wizard_data_arr = get_bk_option( 'booking_wizard_data' );
		$booking_wizard_data_arr = ( empty( $booking_wizard_data_arr ) ) ? array() : $booking_wizard_data_arr;


		// =============================================================================================================
		// ==  Do Action  ==
		// =============================================================================================================
		switch ( $cleaned_request_params['do_action'] ) {

			// ---------------------------------------------------------------------------------------------------------
			// ==  RESET  ==
			// ---------------------------------------------------------------------------------------------------------
			case 'make_reset':

				$is_reseted = $user_request->user_request_params__db_delete();											// Delete from DB

				wpbc_setup_wizard__set_full_screen_mode_for_current_user( false );

				$cleaned_request_params['do_action'] = $is_reseted ? 'reset_done' : 'reset_error';

				$cleaned_request_params = wpbc_setup_wizard_page__get__request_values__default();

				$data_arr['ajx_after_action_message'] = __( 'Start Setup from Beginning', 'booking' );

				$data_arr['current_step'] = 'welcome';

				update_bk_option( 'booking_wizard_data', array() );

				$setup_steps->db__set_all_steps_as( false );        // Clear All Steps      Mark as Undone
				break;

			case 'skip_wizard':

				$data_arr['current_step'] = 'welcome';
				// $data_arr['redirect_url'] = wpbc_get_settings_url();
				$data_arr['redirect_url'] = wpbc_get_bookings_url();

				wpbc_setup_wizard__set_full_screen_mode_for_current_user( false );
				$setup_steps->db__set_all_steps_as( true );        // Mark All Steps as Done

				break;

			case 'save_and_continue__welcome':

				$setup_steps->db__set_step_as_completed( 'welcome' );
				break;

			case 'save_and_continue__general_info':

				// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
				if ( isset( $_POST['all_ajx_params']['step_data'] ) && ( ! empty( $_POST['all_ajx_params']['step_data'] ) ) ) {
					$cleaned_data = wpbc_template__general_info__action_validate_data( $_POST['all_ajx_params']['step_data'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

					if ( 'On' === $cleaned_data['wpbc_swp_accept_send'] ) {
						//wpbc_setup_feedback__send_email( $cleaned_data );		// FixIn: 10.7.1.3.
						update_bk_option( 'booking_feedback__send_email', $cleaned_data );
					} else {
						delete_bk_option( 'booking_feedback__send_email' );
					}

					wpbc_setup__update__general_info( $cleaned_data );
				}

				$setup_steps->db__set_step_as_completed( 'general_info' );
				break;

			case 'save_and_continue__date_time_formats':

				// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
				if ( isset( $_POST['all_ajx_params']['step_data'] ) && ( ! empty( $_POST['all_ajx_params']['step_data'] ) ) ) {
					$cleaned_data = wpbc_template__date_time_formats__action_validate_data( $_POST['all_ajx_params']['step_data'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
					wpbc_setup__update__date_time_formats( $cleaned_data );
				}

				$setup_steps->db__set_step_as_completed( 'date_time_formats' );
				break;

			case 'save_and_continue__bookings_types':

				// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
				if ( isset( $_POST['all_ajx_params']['step_data'] ) && ( ! empty( $_POST['all_ajx_params']['step_data'] ) ) ) {
					$cleaned_data = wpbc_template__bookings_types__action_validate_data( $_POST['all_ajx_params']['step_data'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

					// Legacy  update booking form  and dates selection, as some other options (recurrent time)....
					wpbc_setup__update__bookings_types( $cleaned_data );
					$booking_wizard_data_arr['save_and_continue__bookings_types'] = $cleaned_data;
					update_bk_option( 'booking_wizard_data', $booking_wizard_data_arr );
					$setup_steps = new WPBC_SETUP_WIZARD_STEPS();

					// FixIn: 10.7.1.3. // FixIn: 10.15.1.1.
					$cleaned_data_booking_feedback_arr = get_bk_option( 'booking_feedback__send_email' );
					if (! empty($cleaned_data_booking_feedback_arr)){
						if ( 'On' === $cleaned_data_booking_feedback_arr['wpbc_swp_accept_send'] ) {
							$cleaned_data_booking_feedback_arr = array_merge( $cleaned_data_booking_feedback_arr , array( 'type' => 'Type: ' . $cleaned_data ['wpbc_swp_booking_types'] ) );
							if ( 'time_slots_appointments' === $cleaned_data ['wpbc_swp_booking_types'] ) {
								$cleaned_data_booking_feedback_arr = array_merge( $cleaned_data_booking_feedback_arr, array( 'appointments_type' => 'Appointment: ' . $cleaned_data ['wpbc_swp_booking_appointments_type'] ) );
							}
							wpbc_setup_feedback__send_email( $cleaned_data_booking_feedback_arr );
							update_bk_option( 'booking_feedback__after_send', $cleaned_data_booking_feedback_arr );
							delete_bk_option( 'booking_feedback__send_email' );
						}
					}

				}

				$setup_steps->db__set_step_as_completed( 'bookings_types' );
				if ( ! empty( $cleaned_data ) ) {
					wpbc_setup_wizard__set_full_screen_mode_for_current_user( true );
					$data_arr['current_step'] = wpbc_setup_wizard__get_first_profile_step();
					$current_steps_arr        = $setup_steps->get_steps_arr();
					$setup_steps->db__reset_steps_from( $data_arr['current_step'] );
					if (
						isset( $current_steps_arr[ $data_arr['current_step'] ] )
						&& 'manual_save_required' === $setup_steps->get_step_save_behavior( $data_arr['current_step'] )
					) {
						$setup_steps->db__set_step_as_saved( $data_arr['current_step'], false );
					}
					$data_arr['redirect_url'] = $setup_steps->get_step_target_url( $data_arr['current_step'] );
					$data_arr['steps']        = $current_steps_arr;
					$cleaned_request_params['do_action'] = 'redirect_to_setup_step';
				}
				break;

			default:
				// Default
		}

		//--------------------------------------------------------------------------------------------------------------
		// Other
		//--------------------------------------------------------------------------------------------------------------
		$data_arr['steps_is_done']               = $setup_steps->db__get_steps_is_done();
		$data_arr['left_navigation']             = wpbc_setup_wizard_page__get_left_navigation_menu_arr();
		$data_arr['plugin_menu__setup_progress'] = $setup_steps->get_plugin_menu_title__setup_progress( $data_arr['current_step'] );

		// External setup steps are now configured on their existing admin pages, so the setup-page AJAX response does
		// not need to embed their duplicated calendars or forms.
		$data_arr['ui'] = array();
		$data_arr['calendar_force_load'] = '';


		// -------------------------------------------------------------------------------------------------------------
		// Save Wizard history
		// -------------------------------------------------------------------------------------------------------------
		// Save to DB
		$booking_wizard_data_arr[ $cleaned_request_params['do_action'] ] = $cleaned_data;
		update_bk_option( 'booking_wizard_data', $booking_wizard_data_arr );
		// Ajax Transfer
		$data_arr['booking_wizard_data'] = $booking_wizard_data_arr;
		// -------------------------------------------------------------------------------------------------------------

		// -------------------------------------------------------------------------------------------------------------
		// Save Status of Wizard for specific user
		// -------------------------------------------------------------------------------------------------------------
		if ( 'make_reset' !== $cleaned_request_params['do_action'] ) {

			$cleaned_request_params['current_step'] = $data_arr['current_step'];
			$request_params_to_save = $cleaned_request_params;

			// Do not safe such elements
			unset( $request_params_to_save['ui_clicked_element_id'] );
			unset( $request_params_to_save['do_action'] );
			unset( $request_params_to_save['calendar_force_load'] );
			unset( $request_params_to_save['plugin_menu__setup_progress'] );

			$is_success_update = $user_request->user_request_params__db_save( $request_params_to_save );					// Save to DB		// - $cleaned_request_params - serialized here automatically
		}

		if ( ! empty( $data_arr['calendar_force_load'] ) ) {
			$data_arr['calendar_force_load'] = wpbc_clean_calendar_loading_scripts( $data_arr['calendar_force_load'] );
		}
		// -------------------------------------------------------------------------------------------------------------
		// Send JSON.   It will make "wp_json_encode" - so pass only array, and This function call wp_die( '', '', array( 'response' => null, ) )		Pass JS OBJ: response_data in "jQuery.post( " function on success.
		// -------------------------------------------------------------------------------------------------------------
		wp_send_json( array(
							'ajx_data'              => $data_arr,
							// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
							'ajx_all_ajx_params'    => $_REQUEST[ $request_prefix ],			 					    // $_REQUEST[ 'all_ajx_params' ]
							'ajx_cleaned_params'    => $cleaned_request_params
						) );
	}

}

/**
 * Just for loading CSS and  JavaScript files
 */
if ( true ) {
	$wpbc_setup_wizard_page_loading = new WPBC_AJX__Setup_Wizard__Ajax_Request;
	$wpbc_setup_wizard_page_loading->define_ajax_hook();
}

```
