2026-03-27 11:54:51 +00:00

406 lines
10 KiB
PHP

<?php
/**
* Simply Schedule Appointments Block Booking.
*
* @since 2.4.0
* @package Simply_Schedule_Appointments
*/
/**
* Simply Schedule Appointments Block Booking.
*
* @since 2.4.0
*/
class SSA_Block_Booking {
/**
* Parent plugin class.
*
* @since 2.4.0
*
* @var Simply_Schedule_Appointments
*/
protected $plugin = null;
/**
* Constructor.
*
* @since 2.4.0
*
* @param Simply_Schedule_Appointments $plugin Main plugin object.
*/
public function __construct( $plugin ) {
$this->plugin = $plugin;
$this->hooks();
}
/**
* Initiate our hooks.
*
* @since 2.4.0
*/
public function hooks() {
add_action( 'init', array( $this, 'maybe_register_booking_block' ) );
}
public function maybe_register_booking_block() {
if( ssa_doing_async() ) {
return;
}
if ( wp_doing_cron() ) {
return;
}
if( ssa_is_json_request() ) {
return;
}
if( ssa_is_file_request() ) {
return;
}
if ( ! function_exists( 'register_block_type' ) ) {
return;
}
return $this->register_booking_block();
}
public function register_booking_block() {
wp_register_script(
'ssa-booking-block-js',
$this->plugin->url( 'assets/js/block-booking.js' ),
array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-editor' )
);
wp_register_style(
'ssa-booking-block-css',
$this->plugin->url( 'assets/css/block-booking.css' )
);
$appointment_types = $this->plugin->appointment_type_model->query( array(
'status' => 'publish',
) );
$ssa_appointment_key_values = wp_list_pluck( $appointment_types, 'title', 'slug' );
asort( $ssa_appointment_key_values );
wp_localize_script( 'ssa-booking-block-js', 'ssaAppointmentTypes', $ssa_appointment_key_values );
$appointment_type_labels = $this->plugin->appointment_type_label_model->query();
$ssa_appointment_label_key_values = wp_list_pluck( $appointment_type_labels, 'name', 'id' );
asort( $ssa_appointment_label_key_values );
wp_localize_script( 'ssa-booking-block-js', 'ssaAppointmentTypeLabels', $ssa_appointment_label_key_values );
/* Booking flow */
if ( ssa_should_render_booking_flow() ) {
$booking_flow_options = array(
'main_booking_flow' => array(
array(
'value' => 'appt_type_settings',
'label' => __('Use default settings from appointment type', 'simply-schedule-appointments'),
),
array(
'value' => 'expanded',
'label' => __('Expanded', 'simply-schedule-appointments'),
),
array(
'value' => 'express',
'label' => __('Express', 'simply-schedule-appointments'),
),
array(
'value' => 'first_available',
'label' => __('First available', 'simply-schedule-appointments'),
),
),
'suggest_first_available' => array(
'duration' => array(
'value' => 0,
'label' => __('Duration', 'simply-schedule-appointments'),
),
'duration_unit' => array(
array(
'value' => 'minutes',
'label' => __('Minutes', 'simply-schedule-appointments'),
),
array(
'value' => 'hours',
'label' => __('Hours', 'simply-schedule-appointments'),
),
array(
'value' => 'days',
'label' => __('Days', 'simply-schedule-appointments'),
),
array(
'value' => 'weeks',
'label' => __('Weeks', 'simply-schedule-appointments'),
),
),
),
'fallback_flow' => array(
array(
'value' => 'expanded',
'label' => __('Expanded', 'simply-schedule-appointments'),
),
array(
'value' => 'express',
'label' => __('Express', 'simply-schedule-appointments'),
),
),
'date_view' => array(
array(
'value' => 'week',
'label' => __('Weekly', 'simply-schedule-appointments'),
),
array(
'value' => 'month',
'label' => __('Monthly', 'simply-schedule-appointments'),
),
array(
'value' => 'only_available',
'label' => __('Only available dates', 'simply-schedule-appointments'),
),
),
'time_view' => array(
array(
'value' => 'time_of_day_columns',
'label' => __('Time of day columns', 'simply-schedule-appointments'),
),
array(
'value' => 'single_column',
'label' => __('Single column', 'simply-schedule-appointments'),
),
)
);
wp_localize_script( 'ssa-booking-block-js', 'ssaBookingFlowOptions', $booking_flow_options );
}
/* End booking flow */
/* Appointment types view */
$appointment_types_views_options = array(
array(
'value' => 'cardList',
'label' => __('List', 'simply-schedule-appointments'),
),
array(
'value' => 'cardGrid',
'label' => __('Grid', 'simply-schedule-appointments'),
),
array(
'value' => 'cardColumns',
'label' => __('Two Columns', 'simply-schedule-appointments'),
),
);
wp_localize_script( 'ssa-booking-block-js', 'ssaAppointmentTypesViewOptions', $appointment_types_views_options );
/* End appointment types view */
register_block_type( 'ssa/booking', array(
'editor_script' => 'ssa-booking-block-js',
'editor_style' => 'ssa-booking-block-css',
'd4Shortcode' => 'ssa_divi_booking_module',
'keywords' => array( 'ssa', 'appointments', 'simply', 'booking' ),
'attributes' => array (
'filter' => array (
'type' => 'string',
'default' => '',
),
'type' => array (
'type' => 'string',
'default' => '' ,
),
'types' => array (
'type' => 'array',
'default' => [] ,
),
'label' => array (
'type' => 'string',
'default' => '',
),
/* Appointment type config */
'appointment_types_view' => array(
'type' => 'string',
'default' => 'cardList',
),
/* End appointment type config */
/* Booking flow config */
'suggest_first_available' => array (
'type' => 'string',
'default' => '',
),
'suggest_first_available_duration' => array (
'type' => 'number',
'default' => 1,
),
'suggest_first_available_duration_unit' => array(
'type' => 'string',
'default' => 'week',
),
'flow' => array (
'type' => 'string',
'default' => 'appt_type_settings',
),
'fallback_flow' => array (
'type' => 'string',
'default' => 'expanded',
),
'time_view' => array (
'type' => 'string',
'default' => 'time_of_day_columns',
),
'date_view' => array (
'type' => 'string',
'default' => 'week',
),
/* End booking flow config */
'accent_color' => array (
'type' => 'string',
'default' => '',
),
'background' => array (
'type' => 'string',
'default' => '',
),
'padding' => array (
'type' => 'number',
'default' => 0,
),
'padding_unit' => array (
'type' => 'string',
'default' => '',
),
),
'render_callback' => array( $this, 'render' ),
) );
}
function convertDurationToMinutes($duration, $unit) {
// Validate if the duration is an integer
$duration = filter_var($duration, FILTER_VALIDATE_INT);
// If duration is not a valid integer, null, zero, or a negative integer return an error or null
if ($duration === false || $duration <= 0) {
return null;
}
switch ($unit) {
case 'minutes':
return $duration;
case 'hours':
return $duration * 60;
case 'days':
return $duration * 60 * 24;
case 'weeks':
return $duration * 60 * 24 * 7;
default:
return null;
}
}
public function render( $settings ) {
$attrs = array();
if ( $settings['filter'] === 'types' ) {
$settings['label'] = '';
}
elseif ( $settings['filter'] === 'label' ) {
$settings['types'] = [];
}
if ( ! empty( $settings['types'] ) ) {
if( in_array( 'All', $settings['types'] ) ) {
$settings['types'] = [];
$attrs['types'] = '';
} else {
$attrs['types'] = implode( ",", $settings['types'] );
}
}
if ( ! empty( $settings['label'] ) ) {
$attrs['types'] = '';
if( $settings['label'] !== 'All' ) {
$attrs['label'] = $settings['label'];
}
}
// After introducing the new checkboxes for appointmnent types
// We still wanna check for the old settings['type'] if set; not to break the existing/old shortcodes
// If found convert type to types and clear out type
if( $settings['type'] && $settings['type'] !== '' ) {
$attrs['types'] = $settings['type'];
$settings['type'] = '';
}
if( $settings['accent_color'] && $settings['accent_color'] !== '' ) {
$attrs['accent_color'] = ltrim( $settings['accent_color'], '#');
}
if( $settings['background'] && $settings['background'] !== '' ) {
$attrs['background'] = ltrim( $settings['background'], '#' );
}
if( $settings['padding'] && $settings['padding'] !== '' ) {
// using '%' on the dropdown value causes a "malformed URI" issue on Gutenberg renderer, so this is
// necessary
$settings['padding_unit'] = $settings['padding_unit'] === 'percent' ? '%' : $settings['padding_unit'];
$attrs['padding'] = $settings['padding'] . $settings['padding_unit'];
}
/* Appointment types view */
if ( $settings['appointment_types_view'] && $settings['appointment_types_view'] !== '' ) {
$attrs['appointment_types_view'] = $settings['appointment_types_view'];
}
/* Booking Flow */
if ( ssa_should_render_booking_flow() ) {
if ( $settings['flow'] !== 'appt_type_settings' && ! empty( $settings['flow'] ) ) {
if ( $settings['flow'] === 'expanded' ) {
$attrs['flow'] = $settings['flow'];
$attrs['date_view'] = $settings['date_view'];
$attrs['time_view'] = $settings['time_view'];
}
else if ( $settings['flow'] === 'express' ) {
$attrs['flow'] = $settings['flow'];
$attrs['time_view'] = $settings['time_view'];
}
else if ( $settings['flow'] === 'first_available' ) {
$attrs['flow'] = $settings['flow'];
$attrs['suggest_first_available'] = true;
// Only available within
$attrs['suggest_first_available_within_minutes'] = $this->convertDurationToMinutes( $settings['suggest_first_available_duration'], $settings['suggest_first_available_duration_unit'] );
// Fallback flow
if ( $settings['fallback_flow'] === 'expanded' ) {
$attrs['fallback_flow'] = $settings['fallback_flow'];
$attrs['date_view'] = $settings['date_view'];
$attrs['time_view'] = $settings['time_view'];
}
else if ( $settings['fallback_flow'] === 'express' ) {
$attrs['fallback_flow'] = $settings['fallback_flow'];
$attrs['time_view'] = $settings['time_view'];
}
}
}
}
return $this->plugin->shortcodes->ssa_booking( $attrs );
}
}