$el_id,
'name' => $el_id,
'label' => array( 'title' => __( 'Emails sending', 'booking' ), 'position' => 'right' ),
'style' => '',
'class' => '',
'disabled' => false,
'attr' => array(
'data-wpbc-add-booking-send-emails' => '1',
),
'legend' => '',
'value' => $el_value,
'selected' => ( 'On' === $el_value ),
'hint' => array( 'title' => __( 'Send email notification to customer about this operation', 'booking' ), 'position' => 'top' ),
);
?>
$el_id,
'name' => $el_id,
'label' => array( 'title' => __( 'Allow booking in the past', 'booking' ), 'position' => 'right' ),
'style' => '',
'class' => '',
'disabled' => false,
'attr' => array(
'data-wpbc-add-booking-allow-past' => '1',
),
'legend' => '',
'value' => 'On',
'selected' => false,
'hint' => array( 'title' => __( 'Allow booking in the past', 'booking' ), 'position' => 'top' ),
);
?>
'builder_booking_form',
'form_name' => 'standard',
),
wpbc_get_settings_url()
);
?>
WPBC_JS_IN_FOOTER ) );
wp_enqueue_script( 'wpbc_capacity', wpbc_plugin_url( '/includes/_capacity/_out/create_booking.js' ), array( 'wpbc-main-client' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) );
wp_enqueue_script( 'wpbc-times', wpbc_plugin_url( '/js/wpbc_times.js' ), array( 'wpbc-main-client' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) );
wp_enqueue_script( 'wpbc-time-selector', wpbc_plugin_url( '/js/wpbc_time-selector.js' ), array( 'wpbc-times' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) );
wp_enqueue_script( 'wpbc-imask', wpbc_plugin_url( '/vendors/imask/dist/imask.js' ), array( 'wpbc-main-client' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) );
wp_enqueue_script( 'wpbc-boo_listing_ajx_actions', wpbc_plugin_url( '/includes/page-bookings/_out/boo_listing__actions.js' ), array( 'wpbc_all', 'wpbc-modal' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) );
if ( 'On' === get_bk_option( 'booking_is_use_phone_validation' ) ) {
wp_enqueue_script( 'wpbc-iphone-validator', wpbc_plugin_url( '/js/wpbc_phone_validator.js' ), array( 'wpbc-imask' ), WP_BK_VERSION_NUM, array( 'in_footer' => WPBC_JS_IN_FOOTER ) );
}
}
/**
* Enqueue front-end booking-form styles required by the modal body.
*
* @param string $where_to_load Load context.
*
* @return void
*/
public static function enqueue_css_files( $where_to_load ) {
if ( ! self::is_supported_admin_page() || ! in_array( $where_to_load, array( 'admin', 'both' ), true ) ) {
return;
}
if ( function_exists( 'wpbc_enqueue_styles__front_end' ) ) {
wpbc_enqueue_styles__front_end();
}
}
/**
* AJAX: render Add Booking modal body.
*
* @return void
*/
public static function ajax_render() {
check_ajax_referer( strtolower( self::AJAX_ACTION ) . '_wpbcnonce', 'nonce' );
if ( ! wpbc_is_mu_user_can_be_here( 'activated_user' ) ) {
wp_send_json_error( array( 'message' => __( 'You do not have access to this page.', 'booking' ) ), 403 );
}
$args = self::get_clean_request_args();
if ( ( 'add' === $args['mode'] ) && ! WPBC_Add_Booking_Component::current_user_can_add_booking() ) {
wp_send_json_error( array( 'message' => __( 'You do not have access to this page.', 'booking' ) ), 403 );
}
if ( empty( $args['resource_id'] ) ) {
$args['resource_id'] = wpbc_get_default_resource();
}
if ( empty( $args['resource_id'] ) ) {
wp_send_json_error( array( 'message' => __( 'Booking resource type is not defined.', 'booking' ) ), 400 );
}
if (
class_exists( 'wpdev_bk_multiuser' )
&& ! wpbc_is_mu_user_can_be_here( 'resource_owner', $args['resource_id'] )
) {
wp_send_json_error( array( 'message' => __( 'You do not have access to this booking resource.', 'booking' ) ), 403 );
}
if ( ( 'add' === $args['mode'] ) && ( '' === (string) $args['booking_form'] ) ) {
$args['booking_form'] = WPBC_Add_Booking_Component::get_default_booking_form_for_resource( $args['resource_id'], 'standard' );
$args['custom_booking_form'] = $args['booking_form'];
}
$html = self::render_component_with_legacy_request_context( $args );
wp_send_json_success(
array(
'html' => $html,
'resource_id' => absint( $args['resource_id'] ),
'booking_hash' => (string) $args['booking_hash'],
'mode' => (string) $args['mode'],
'title' => ( 'edit' === $args['mode'] ) ? __( 'Edit booking', 'booking' ) : __( 'Add booking', 'booking' ),
'button_title' => ( 'edit' === $args['mode'] ) ? __( 'Save booking', 'booking' ) : __( 'Add booking', 'booking' ),
'booking_id' => absint( $args['booking_id'] ),
'booking_form' => (string) $args['booking_form'],
'allow_past' => absint( $args['allow_past'] ),
'selected_dates_without_calendar' => (string) $args['selected_dates_without_calendar'],
'selected_dates' => (string) $args['selected_dates'],
'selected_date' => (string) $args['selected_date'],
'selected_time' => (string) $args['selected_time'],
'time_override_enabled' => absint( $args['time_override_enabled'] ),
'time_override_source' => (string) $args['time_override_source'],
'time_override_start' => (string) $args['time_override_start'],
'time_override_end' => (string) $args['time_override_end'],
)
);
}
/**
* Get sanitized request args.
*
* @return array
*/
private static function get_clean_request_args() {
$mode = isset( $_POST['mode'] ) ? sanitize_key( wp_unslash( $_POST['mode'] ) ) : 'add'; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$mode = in_array( $mode, array( 'add', 'edit' ), true ) ? $mode : 'add';
$booking_hash = isset( $_POST['booking_hash'] ) ? sanitize_text_field( wp_unslash( $_POST['booking_hash'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$resource_id = isset( $_POST['resource_id'] ) ? absint( $_POST['resource_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$booking_id = isset( $_POST['booking_id'] ) ? absint( $_POST['booking_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$booking_form = isset( $_POST['booking_form'] ) ? sanitize_text_field( wp_unslash( $_POST['booking_form'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$allow_past = isset( $_POST['allow_past'] ) ? absint( $_POST['allow_past'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$selected_dates_without_calendar = isset( $_POST['selected_dates_without_calendar'] ) ? sanitize_text_field( wp_unslash( $_POST['selected_dates_without_calendar'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$selected_dates = isset( $_POST['selected_dates'] ) ? sanitize_text_field( wp_unslash( $_POST['selected_dates'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$selected_date = isset( $_POST['selected_date'] ) ? sanitize_text_field( wp_unslash( $_POST['selected_date'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$selected_time = isset( $_POST['selected_time'] ) ? sanitize_text_field( wp_unslash( $_POST['selected_time'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$time_override_enabled = isset( $_POST['time_override_enabled'] ) ? absint( $_POST['time_override_enabled'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$time_override_source = isset( $_POST['time_override_source'] ) ? sanitize_key( wp_unslash( $_POST['time_override_source'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$time_override_start = isset( $_POST['time_override_start'] ) ? self::sanitize_time_hm( wp_unslash( $_POST['time_override_start'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
$time_override_end = isset( $_POST['time_override_end'] ) ? self::sanitize_time_hm( wp_unslash( $_POST['time_override_end'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
if ( '' !== $booking_hash ) {
$hash_resource = wpbc_hash__get_booking_id__resource_id( $booking_hash );
if ( false === $hash_resource ) {
wp_send_json_error( array( 'message' => __( 'We could not find your booking. The link you used may be incorrect or has expired.', 'booking' ) ), 404 );
}
$booking_id = absint( $hash_resource[0] );
$resource_id = absint( $hash_resource[1] );
$mode = 'edit';
$allow_past = 1;
}
return array(
'mode' => $mode,
'resource_id' => $resource_id,
'booking_type' => $resource_id,
'booking_id' => $booking_id,
'booking_hash' => $booking_hash,
'booking_form' => $booking_form,
'custom_booking_form' => $booking_form,
'allow_past' => $allow_past ? 1 : 0,
'selected_dates_without_calendar' => $selected_dates_without_calendar,
'selected_dates' => $selected_dates,
'selected_date' => $selected_date,
'selected_time' => $selected_time,
'time_override_enabled' => ( $time_override_enabled && $time_override_start && $time_override_end ) ? 1 : 0,
'time_override_source' => $time_override_source,
'time_override_start' => $time_override_start,
'time_override_end' => $time_override_end,
'is_toolbar_visible' => false,
'is_booking_page_js' => false,
'is_booking_page_popover' => false,
'is_show_before_content_spacer'=> false,
'is_show_footer_email_toggle' => false,
'content_css_class' => 'add_booking_page_content wpbc_add_booking_component__in_modal',
'content_style' => 'width:100%;margin-bottom:20px;',
'is_echo' => 0,
);
}
/**
* Sanitize HH:MM time value.
*
* @param string $time_value Time value.
*
* @return string
*/
private static function sanitize_time_hm( $time_value ) {
$time_value = trim( sanitize_text_field( (string) $time_value ) );
if ( ! preg_match( '/^([0-9]{1,2}):([0-9]{2})$/', $time_value, $matches ) ) {
return '';
}
$hour = absint( $matches[1] );
$minute = absint( $matches[2] );
if ( $hour > 24 || $minute > 59 || ( 24 === $hour && 0 !== $minute ) ) {
return '';
}
return sprintf( '%02d:%02d', $hour, $minute );
}
/**
* Render the component with a scoped legacy request context for older renderers that still read $_GET.
*
* @param array $args Component args.
*
* @return string
*/
private static function render_component_with_legacy_request_context( $args ) {
$old_get = $_GET;
$old_request = $_REQUEST;
$old_request_uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';
$query_args = array(
'page' => 'wpbc',
'tab' => 'add-booking',
'booking_type' => absint( $args['resource_id'] ),
'is_show_payment_form' => 'Off',
);
if ( '' !== $args['booking_hash'] ) {
$query_args['booking_hash'] = $args['booking_hash'];
$query_args['parent_res'] = 1;
}
if ( ! empty( $args['allow_past'] ) || ( '' !== $args['booking_hash'] ) ) {
$query_args['allow_past'] = 1;
}
if ( '' !== $args['booking_form'] ) {
$query_args['booking_form'] = $args['booking_form'];
}
foreach ( $query_args as $key => $value ) {
$_GET[ $key ] = $value;
$_REQUEST[ $key ] = $value;
}
$_SERVER['REQUEST_URI'] = wp_parse_url( admin_url( 'admin.php' ), PHP_URL_PATH ) . '?' . http_build_query( $query_args, '', '&' );
try {
return WPBC_Add_Booking_Component::render( $args );
} finally {
$_GET = $old_get;
$_REQUEST = $old_request;
$_SERVER['REQUEST_URI'] = $old_request_uri;
}
}
/**
* Get booking resource options for the modal selector.
*
* @return array
*/
private static function get_booking_resource_options() {
$resources = array();
if ( function_exists( 'wpbc_get_all_booking_resources_list' ) ) {
$resources = wpbc_get_all_booking_resources_list();
}
if ( empty( $resources ) ) {
$default_resource = absint( wpbc_get_default_resource() );
$default_resource = $default_resource ? $default_resource : 1;
$resources = array(
$default_resource => array(
'title' => __( 'Default', 'booking' ),
'attr' => array(),
),
);
}
return $resources;
}
/**
* Get booking form options for the modal selector.
*
* @return array
*/
private static function get_booking_form_options() {
$options = array(
'standard' => __( 'Standard', 'booking' ),
);
if ( ! class_exists( 'WPBC_FE_Custom_Form_Helper' ) ) {
return $options;
}
$is_can = apply_bk_filter( 'multiuser_is_user_can_be_here', true, 'only_super_admin' );
if ( ( ! $is_can ) && ( 'On' !== get_bk_option( 'booking_is_custom_forms_for_regular_users' ) ) ) {
return $options;
}
$owner_user_id = WPBC_FE_Custom_Form_Helper::wpbc_mu__get_current__owner_user_id();
$forms = WPBC_FE_Custom_Form_Helper::get_custom_booking_forms_list(
array(
'include_standard' => false,
'owner_user_id' => $owner_user_id,
'statuses' => array( 'published' ),
'list_mode' => 'auto',
)
);
foreach ( $forms as $form ) {
if ( empty( $form['name'] ) ) {
continue;
}
$form_title = ! empty( $form['title'] ) ? $form['title'] : $form['name'];
$options[ $form['name'] ] = wpbc_lang( $form_title );
}
return $options;
}
/**
* Check if assets should be loaded for Booking Listing or Timeline view.
*
* @return bool
*/
public static function is_supported_admin_page() {
if ( ! is_admin() ) {
return false;
}
if ( function_exists( 'wpbc_is_availability_page' ) && wpbc_is_availability_page() ) {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
$requested_tab = isset( $_REQUEST['tab'] ) ? sanitize_key( wp_unslash( $_REQUEST['tab'] ) ) : '';
return ( 'time_slots_availability' === $requested_tab );
}
if ( function_exists( 'wpbc_is_bookings_page' ) ) {
if ( ! wpbc_is_bookings_page() ) {
return false;
}
} else {
$server_request_uri = ( isset( $_SERVER['REQUEST_URI'] ) ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
if ( ( false === strpos( $server_request_uri, 'page=wpbc' ) ) || ( false !== strpos( $server_request_uri, 'page=wpbc-' ) ) ) {
return false;
}
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
$requested_tab = isset( $_REQUEST['tab'] ) ? sanitize_key( wp_unslash( $_REQUEST['tab'] ) ) : '';
if ( '' !== $requested_tab ) {
return in_array( $requested_tab, array( 'vm_booking_listing', 'vm_calendar' ), true );
}
if ( function_exists( 'wpbc_get_default_saved_view_mode_for_wpbc_page' ) ) {
return in_array( wpbc_get_default_saved_view_mode_for_wpbc_page(), array( 'vm_booking_listing', 'vm_calendar' ), true );
}
return true;
}
/**
* Backward-compatible alias for existing Add Booking modal checks.
*
* @return bool
*/
public static function is_booking_listing_admin_page() {
return self::is_supported_admin_page();
}
}
/**
* Check if Booking Listing or Timeline needs the Add Booking modal client assets.
*
* @return bool
*/
if ( ! function_exists( 'wpbc_is_add_booking_modal_on_booking_listing_page' ) ) {
/**
* Check if Booking Listing or Timeline needs the Add Booking modal client assets.
*
* @return bool
*/
function wpbc_is_add_booking_modal_on_booking_listing_page() {
return WPBC_Add_Booking_Modal::is_supported_admin_page();
}
}
add_action( 'wpbc_ui_el__top_nav__content_end', array( 'WPBC_Add_Booking_Modal', 'print_top_toolbar_button' ), 19, 3 );
add_action( 'wpbc_hook_booking_template__hidden_templates', array( 'WPBC_Add_Booking_Modal', 'template_for_modal' ) );
add_action( 'wpbc_enqueue_js_files', array( 'WPBC_Add_Booking_Modal', 'enqueue_js_files' ), 52 );
add_action( 'wpbc_enqueue_css_files', array( 'WPBC_Add_Booking_Modal', 'enqueue_css_files' ), 52 );
add_action( 'wp_ajax_' . WPBC_Add_Booking_Modal::AJAX_ACTION, array( 'WPBC_Add_Booking_Modal', 'ajax_render' ) );