[Back] <?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if ( ! class_exists( 'OsStepsController' ) ) :
class OsStepsController extends OsController {
private $booking;
function __construct() {
parent::__construct();
$this->action_access['customer'] = array_merge( $this->action_access['customer'], [ 'start_from_order_intent' ] );
$this->action_access['public'] = array_merge( $this->action_access['public'], [
'start',
'start_instant',
'load_step',
'reload_booking_form_summary_panel',
'check_order_intent_bookable',
'load_datepicker_month'
] );
$this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'steps/';
$this->vars['page_header'] = __( 'Appointments', 'latepoint' );
$this->vars['breadcrumbs'][] = array(
'label' => __( 'Appointments', 'latepoint' ),
'link' => OsRouterHelper::build_link( [
'bookings',
'pending_approval'
] )
);
}
public function start_instant() {
$atts = [];
if(!empty($this->params['selected_agent'])) $atts['selected_agent'] = sanitize_text_field($this->params['selected_agent']);
if(!empty($this->params['selected_service'])) $atts['selected_service'] = sanitize_text_field($this->params['selected_service']);
if(!empty($this->params['selected_location'])) $atts['selected_location'] = sanitize_text_field($this->params['selected_location']);
if(!empty($this->params['hide_side_panel']) && $this->params['hide_side_panel'] == 'yes') $atts['hide_side_panel'] = 'yes';
if(!empty($this->params['hide_summary']) && $this->params['hide_summary'] == 'yes') $atts['hide_summary'] = 'yes';
if(!empty($this->params['background_pattern'])) $this->vars['background_pattern'] = sanitize_text_field($this->params['background_pattern']);
$this->vars['atts'] = $atts;
$this->set_layout( 'clean' );
$this->format_render( __FUNCTION__ );
}
public function load_datepicker_month() {
OsStepsHelper::set_required_objects( $this->params );
$target_date = new OsWpDateTime( $this->params['target_date_string'] );
$calendar_settings = [
'layout' => $this->params['calendar_layout'] ?? 'classic',
'timezone_name' => $this->params['timezone_name'] ?? false,
];
$calendar_settings['earliest_possible_booking'] = OsSettingsHelper::get_earliest_possible_booking_restriction( OsStepsHelper::$booking_object->service_id ?? false );
$calendar_settings['latest_possible_booking'] = OsSettingsHelper::get_latest_possible_booking_restriction( OsStepsHelper::$booking_object->service_id ?? false );
$this->format_render( 'partials/_monthly_calendar_days', [
'target_date' => $target_date,
'calendar_settings' => $calendar_settings,
'booking_request' => \LatePoint\Misc\BookingRequest::create_from_booking_model( OsStepsHelper::$booking_object )
] );
}
public function check_order_intent_bookable() {
OsStepsHelper::set_required_objects( $this->params );
if(OsStepsHelper::$cart_object->order_id){
// already converted, so we are good
$this->send_json( [
'status' => LATEPOINT_STATUS_SUCCESS,
'message' => __( 'Cart has already been converted to order', 'latepoint' )
] );
}
$order_intent = OsOrderIntentHelper::create_or_update_order_intent( OsStepsHelper::$cart_object, OsStepsHelper::$restrictions, OsStepsHelper::$presets, '', OsStepsHelper::get_customer_object_id() );
if ( $order_intent->is_bookable() ) {
$this->send_json( [
'status' => LATEPOINT_STATUS_SUCCESS,
'message' => __( 'Order intent can be converted to order', 'latepoint' )
] );
} else {
$this->send_json( [
'status' => LATEPOINT_STATUS_ERROR,
'message' => __( 'Selected booking slot is not available anymore. Please pick a different time slot.', 'latepoint' )
] );
}
}
function generate_timeslots_for_day(){
OsStepsHelper::set_required_objects( $this->params );
wp_send_json( [ 'status' => LATEPOINT_STATUS_SUCCESS, 'message' => '' ] );
}
function reload_booking_form_summary_panel() {
OsStepsHelper::set_required_objects( $this->params );
$this->vars['cart'] = OsStepsHelper::$cart_object;
if ( OsStepsHelper::is_ready_for_summary() ) {
$this->vars['current_step_code'] = $this->params['current_step_code'] ?? '';
$this->vars['booking'] = OsStepsHelper::$booking_object;
$this->vars['customer'] = OsStepsHelper::get_customer_object();
$this->vars['active_cart_item'] = OsStepsHelper::$active_cart_item;
if ( $this->get_return_format() == 'json' ) {
$response_html = $this->render( $this->views_folder . 'partials/_booking_form_summary_panel', 'none' );
wp_send_json( [ 'status' => LATEPOINT_STATUS_SUCCESS, 'message' => $response_html ] );
exit();
} else {
echo $this->render( $this->views_folder . 'partials/_booking_form_summary_panel', $this->get_layout() );
}
} else {
wp_send_json( [ 'status' => LATEPOINT_STATUS_SUCCESS, 'message' => '' ] );
}
}
public function start_from_order_intent() {
$order_intent = OsOrderIntentHelper::get_order_intent_by_intent_key($this->params['order_intent_key']);
if ( !$order_intent->is_new_record() ) {
$step_codes_to_preload = [];
$steps = OsStepsHelper::get_steps();
OsStepsHelper::set_required_objects($this->params);
if ( $order_intent->order_id ) {
// if order is created - load it
OsStepsHelper::load_order_object( $order_intent->order_id );
$current_step_code = 'confirmation';
$current_step = $steps[ $current_step_code ];
$this->vars['price_breakdown_rows'] = OsStepsHelper::$order_object->generate_price_breakdown_rows();
$steps = [ 'confirmation' => $steps['confirmation'] ];
} else {
OsStepsHelper::set_cart_object_from_order_intent( $order_intent );
$current_step_code = 'verify';
$current_step = $steps[ $current_step_code ];
foreach ( OsStepsHelper::$step_codes_in_order as $step_code ) {
if ( $step_code == $current_step_code ) {
break;
} else {
$step_codes_to_preload[] = $step_code;
}
}
$this->vars['price_breakdown_rows'] = OsStepsHelper::$cart_object->generate_price_breakdown_rows();
// order exists - only load confirmation step
$this->vars['step_codes_to_preload'] = $step_codes_to_preload;
}
$this->vars['cart'] = OsStepsHelper::$cart_object;
$this->vars['show_next_btn'] = OsStepsHelper::can_step_show_next_btn( $current_step_code );
$this->vars['show_prev_btn'] = OsStepsHelper::can_step_show_prev_btn( $current_step_code );
$this->vars['all_steps'] = OsStepsHelper::get_steps( true );
$this->vars['steps'] = $steps;
$this->vars['current_step'] = $current_step;
$this->vars['current_step_code'] = $current_step_code;
$this->vars['booking'] = OsStepsHelper::$booking_object;
$this->vars['customer'] = OsStepsHelper::get_customer_object();
$this->vars['active_cart_item'] = OsStepsHelper::$active_cart_item;
$this->vars['restrictions'] = OsStepsHelper::$restrictions;
$this->vars['presets'] = OsStepsHelper::$presets;
$this->vars['booking_element_type'] = 'lightbox';
$this->vars['booking_element_styles'] = [];
$this->set_layout( 'none' );
$this->format_render( 'start', array(), array( 'lightbox_class' => '' ) );
} else {
$this->send_json( array(
'status' => LATEPOINT_STATUS_ERROR,
'message' => __( 'Invalid order intent key', 'latepoint' )
) );
}
}
public function start( array $custom_restrictions = [], array $custom_presets = [], array $booking_element_styles = [], bool $output = true, string $booking_element_type = 'lightbox' ) {
$merged_params = $this->params;
if ( ! empty( $custom_restrictions ) ) {
$merged_params['restrictions'] = $custom_restrictions;
}
if ( ! empty( $custom_presets ) ) {
$merged_params['presets'] = $custom_presets;
}
if( ! empty( $this->params['booking_element_type'] ) ) {
$booking_element_type = $this->params['booking_element_type'];
}
if(!empty($merged_params['booking_element_styles'])){
$booking_element_styles = array_merge( $booking_element_styles, $merged_params['booking_element_styles'] );
}
// set early to check if it's converted or should be emptied
OsStepsHelper::set_cart_object();
if(!empty(OsStepsHelper::$cart_object->order_id)){
OsCartsHelper::reset_cart();
OsStepsHelper::set_cart_object();
}
// clear cart if "shopping cart" feature is not enabled
if ( ! OsCartsHelper::can_checkout_multiple_items() ) OsStepsHelper::$cart_object->clear();
OsStepsHelper::set_required_objects( $merged_params );
$steps = OsStepsHelper::get_steps();
$current_step_code = OsStepsHelper::get_step_codes_in_order()[0];
if ( OsStepsHelper::should_step_be_skipped( $current_step_code ) ) {
$current_step_code = OsStepsHelper::get_next_step_code( $current_step_code );
}
// check if all booking steps have to be skipped, if so - it means the booking object is ready and we can add it to the cart
$ready_to_add_to_cart = true;
if(OsStepsHelper::$active_cart_item->is_booking()){
foreach($steps as $step_code => $step_object) {
$step_main_parent_code = explode('__', $step_code);
if(!empty($step_main_parent_code[0]) && $step_main_parent_code[0] == 'booking'){
$ready_to_add_to_cart = false;
break;
}
}
}
// looks like item is ready to be added to cart (because all necessary steps/presets where applied in a trigger element), add it to cart
if($ready_to_add_to_cart){
try{
OsStepsHelper::add_current_item_to_cart();
}catch(Exception $e){
$this->vars['booking'] = OsStepsHelper::$booking_object;
if ( $output ) {
$this->format_render( 'preset_slot_not_available' );
return false;
} else {
return $this->format_render_return( 'preset_slot_not_available' );
}
}
}
$current_step = $steps[ $current_step_code ];
$this->vars['cart'] = OsStepsHelper::$cart_object;
$this->vars['show_next_btn'] = OsStepsHelper::can_step_show_next_btn( $current_step->code );
$this->vars['show_prev_btn'] = OsStepsHelper::can_step_show_prev_btn( $current_step->code );
$this->vars['all_steps'] = OsStepsHelper::get_steps( true );
$this->vars['steps'] = $steps;
$this->vars['current_step'] = $current_step;
$this->vars['current_step_code'] = $current_step->code;
$this->vars['booking'] = OsStepsHelper::$booking_object;
$this->vars['customer'] = OsStepsHelper::get_customer_object();
$this->vars['active_cart_item'] = OsStepsHelper::$active_cart_item;
$this->vars['restrictions'] = OsStepsHelper::$restrictions;
$this->vars['presets'] = OsStepsHelper::$presets;
$this->vars['booking_element_type'] = $booking_element_type;
$this->vars['booking_element_styles'] = $booking_element_styles;
$this->vars['timezone_name'] = OsTimeHelper::get_timezone_name_from_session();
$this->set_layout( 'none' );
if ( $output ) {
$this->format_render( __FUNCTION__, [], [ 'step' => $current_step->code ] );
} else {
return $this->format_render_return( __FUNCTION__, [], [ 'step' => $current_step->code ] );
}
}
public function load_step() {
OsStepsHelper::set_required_objects( $this->params );
$current_step_code = OsStepsHelper::retrieve_step_code( $this->params['current_step_code'] );
if ( empty( $current_step_code ) ) {
return false;
}
$step_direction = $this->params['step_direction'] ?? 'next';
$step_code_to_load = false;
switch ( $step_direction ) {
case 'next':
/**
* Process step by code
*
* @param {string} $step_code step code that will be processed
* @param {OsBookingModel} $booking booking object
* @param {array} $params array of params
*
* @since 5.0.0
* @hook latepoint_process_step
*
*/
do_action( 'latepoint_process_step', $current_step_code, OsStepsHelper::$booking_object, $this->params );
$step_code_to_load = OsStepsHelper::get_next_step_code( $current_step_code );
break;
case 'prev':
$step_code_to_load = OsStepsHelper::get_prev_step_code( $current_step_code );
break;
case 'specific':
$step_code_to_load = OsStepsHelper::should_step_be_skipped( $current_step_code ) ? OsStepsHelper::get_next_step_code( $current_step_code ) : $current_step_code;
break;
}
if ( $step_code_to_load ) {
/**
* Load step by code
*
* @param {string} $step_code step code to load
* @param {string} $type type of return (json)
* @param {array} $params array of params
*
* @since 5.0.0
* @hook latepoint_load_step
*
*/
do_action( 'latepoint_load_step', $step_code_to_load, 'json', $this->params );
}
}
}
endif;