start_controls_section( 'block_section', [ 'label' => __( 'Block Description', 'simply-schedule-appointments' ), 'tab' => \Elementor\Controls_Manager::TAB_CONTENT, ] ); $icon_url = $this->get_icon(); $this->add_control( 'title', [ 'raw' => '
Appointment Booking Form
', 'type' => \Elementor\Controls_Manager::RAW_HTML, ] ); $this->add_control( 'description', [ 'raw' => '

' .esc_html__('Displays an Appointment Booking Form. You can customize the appointment type and styles.', 'simply-schedule-appointments') . '

', 'type' => \Elementor\Controls_Manager::RAW_HTML, ] ); $this->end_controls_section(); $this->start_controls_section( 'section_ssa_booking', [ 'label' => __( 'Select Appointment Types', 'simply-schedule-appointments' ), ] ); $appointment_type_labels = ssa()->appointment_type_label_model->query(); $ssa_appointment_label_key_values = wp_list_pluck( $appointment_type_labels, 'name', 'id' ); $ssa_appointment_label_key_values[''] = 'All'; $ssa_appointment_label_key_values = array_reverse( $ssa_appointment_label_key_values, true ); $appointment_types = ssa()->appointment_type_model->query( array( 'number' => -1, 'status' => 'publish', ) ); $filter_options = [ 'types' => __( 'Appointment types', 'simply-schedule-appointments' ), 'label' => __( 'Label', 'simply-schedule-appointments' ), ]; $default_filter = key($filter_options); $map_appointment_type_ids_to_labels = wp_list_pluck( $appointment_types, 'title', 'slug' ); $map_appointment_type_ids_to_labels = array_reverse( $map_appointment_type_ids_to_labels, true ); $map_appointment_type_ids_to_labels[''] = 'All'; $map_appointment_type_ids_to_labels = array_reverse( $map_appointment_type_ids_to_labels, true ); $this->add_control( 'appointment_types_filter', [ 'label' => __( 'FILTER BY', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => $default_filter, 'options' => $filter_options, 'classes' => 'ssa-booking-block', ] ); $this->add_control( 'label', [ 'label' => __( 'Labels', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => '', 'options' => $ssa_appointment_label_key_values, 'condition' => [ 'appointment_types_filter' => 'label', ], ] ); $this->add_control( 'header', [ 'raw' => '

Select Appointment Types:

', 'type' => \Elementor\Controls_Manager::RAW_HTML, 'separator' => 'after', 'condition' => [ 'appointment_types' => 'types', ], ] ); $this->add_control( 'appointment_type', [ 'label' => esc_html__('Appointment Types', 'simply-schedule-appointments'), 'type' => \Elementor\Controls_Manager::SELECT2, 'options' => $map_appointment_type_ids_to_labels, 'label_block' => true, 'multiple' => true, 'frontend_available' => true, 'condition' => [ 'appointment_types_filter' => 'types', ], ] ); $this->end_controls_section(); /* Appointment type view */ $this->start_controls_section( 'section_ssa_booking_type_view', [ 'label' => __( 'Appointment Types View', 'simply-schedule-appointments' ), ] ); $filter_types_options = [ 'cardList' => __('List', 'simply-schedule-appointments'), 'cardGrid' => __('Grid', 'simply-schedule-appointments'), 'cardColumns' => __('Two Columns', 'simply-schedule-appointments'), ]; $default_filter_type = key($filter_types_options); $this->add_control( 'appointment_types_view', [ 'label' => __( 'Appointments types view', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::SELECT, 'default' => $default_filter_type, 'options' => $filter_types_options, 'label_block' => true, 'classes' => 'ssa-booking-block', ] ); $this->end_controls_section(); /* Booking Flow UI*/ if ( ssa_should_render_booking_flow()) { $this->start_controls_section( 'section_ssa_booking_flow', [ 'label' => __( 'Booking Flow', 'simply-schedule-appointments' ), ] ); $filter_flow_options = [ 'appt_type_settings' => __('Use default settings from appointment type', 'simply-schedule-appointments'), 'expanded' => __('Expanded', 'simply-schedule-appointments'), 'express' => __('Express', 'simply-schedule-appointments'), 'first_available' => __('First available', 'simply-schedule-appointments'), ]; $default_flow_filter = key($filter_flow_options); $this->add_control( 'booking_layout', [ 'label' => esc_html__( 'Main Booking Layout', 'simply-schedule-appointments' ), 'label_block' => true, 'frontend_available' => true, 'type' => \Elementor\Controls_Manager::SELECT, 'default' => $default_flow_filter, 'options' => $filter_flow_options, ] ); $this->add_control( 'appt_duration', [ 'label' => esc_html__( 'Duration', 'simply-schedule-appointments' ), 'label_block' => false, 'type' => \Elementor\Controls_Manager::NUMBER, 'min' => 1, 'default' => 1, 'condition' => [ 'booking_layout' => 'first_available', ] ] ); $filter_duration_units = [ 'minutes' => __('Minutes', 'simply-schedule-appointments'), 'hours' => __('Hours', 'simply-schedule-appointments'), 'days' => __('Days', 'simply-schedule-appointments'), 'weeks' => __('Weeks', 'simply-schedule-appointments'), ]; $default_duration_unit = key($filter_duration_units); $this->add_control( 'duration_unit', [ 'label' => esc_html__( 'Duration Unit', 'simply-schedule-appointments' ), 'label_block' => true, 'type' => \Elementor\Controls_Manager::SELECT, 'default' => $default_duration_unit, 'options' => $filter_duration_units, 'condition' => [ 'booking_layout' => 'first_available', ], ] ); $filter_fallback_options = [ 'expanded' => __('Expanded', 'simply-schedule-appointments'), 'express' => __('Express', 'simply-schedule-appointments'), ]; $default_fallback_filter = key($filter_fallback_options); $this->add_control( 'fallback_options', [ 'label' => esc_html__( 'Fallback Flow', 'simply-schedule-appointments' ), 'label_block' => true, 'type' => \Elementor\Controls_Manager::SELECT, 'default' => $default_fallback_filter, 'options' => $filter_fallback_options, 'condition' => [ 'booking_layout' => 'first_available', ], ] ); $this->add_control( 'view_type', [ 'label' => esc_html__( 'View Type', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::CHOOSE, 'frontend_available' => true, 'options' => [ 'left' => [ 'title' => esc_html__( 'Date View', 'simply-schedule-appointments' ), 'icon' => 'eicon-calendar', ], 'right' => [ 'title' => esc_html__( 'Time View', 'simply-schedule-appointments' ), 'icon' => 'eicon-clock-o', ], ], 'default' => 'left', 'toggle' => true, 'selectors_dictionary' => [ 'left' => is_rtl() ? 'end' : 'start', 'right' => is_rtl() ? 'start' : 'end', ], 'conditions' => [ 'relation' => 'and', 'terms' => [ [ 'name' => 'booking_layout', 'operator' => '!==', 'value' => 'express', ], [ 'name' => 'booking_layout', 'operator' => '!==', 'value' => 'appt_type_settings', ], ] ], ] ); $filter_date_options = [ 'week' => __('Weekly', 'simply-schedule-appointments'), 'month' => __('Monthly', 'simply-schedule-appointments'), 'only_available' =>__('Only available dates', 'simply-schedule-appointments'), ]; $default_date_filter = key($filter_date_options); $this->add_control( 'date_view_options', [ 'label' => esc_html__( 'Date View', 'simply-schedule-appointments' ), 'label_block' => true, 'type' => \Elementor\Controls_Manager::SELECT, 'default' => $default_date_filter, 'options' => $filter_date_options, 'conditions' => [ 'relation' => 'and', 'terms' => [ [ 'name' => 'view_type', 'operator' => '===', 'value' => 'left', ], [ 'relation' => 'and', 'terms' => [ [ 'name' => 'booking_layout', 'operator' => '!==', 'value' => 'express', ], [ 'name' => 'booking_layout', 'operator' => '!==', 'value' => 'appt_type_settings', ], ], ], ], ], ] ); $filter_time_options = [ 'time_of_day_columns' => __('Time of day columns', 'simply-schedule-appointments'), 'single_column' => __('Single column', 'simply-schedule-appointments'), ]; $default_time_filter = key($filter_time_options); $this->add_control( 'time_view_options', [ 'label' => esc_html__( 'Time View', 'simply-schedule-appointments' ), 'label_block' => true, 'type' => \Elementor\Controls_Manager::SELECT, 'default' => $default_time_filter, 'options' => $filter_time_options, 'conditions' => [ 'relation' => 'or', 'terms' => [ [ 'name' => 'booking_layout', 'operator' => '===', 'value' => 'express', ], [ 'relation' => 'and', 'terms' => [ [ 'name' => 'view_type', 'operator' => '===', 'value' => 'right', ], [ 'name' => 'booking_layout', 'operator' => '!==', 'value' => 'appt_type_settings', ], ], ] ] ], ] ); $this->end_controls_section(); } $this->start_controls_section( 'section_style', [ 'label' => __( 'Styles', 'elementor' ), 'tab' => \Elementor\Controls_Manager::TAB_STYLE, ] ); $this->add_control( 'accent_color', [ 'label' => __( 'Accent Color', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::COLOR, 'alpha' => false, ] ); $this->add_control( 'background_color', [ 'label' => __( 'Background Color', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::COLOR, 'alpha' => false, ] ); $this->add_control( 'font_family', [ 'label' => __( 'Font Family', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::FONT, ] ); $this->add_control( 'padding', [ 'label' => __( 'Padding', 'simply-schedule-appointments' ), 'type' => \Elementor\Controls_Manager::SLIDER, 'size_units' => [ 'px', 'em', 'rem', 'vw', '%' ], 'range' => [ 'px' => [ 'min' => 0, 'max' => 100, 'step' => 1 ], 'em' => [ 'min' => 0, 'max' => 100, 'step' => 1 ], 'rem' => [ 'min' => 0, 'max' => 100, 'step' => 1 ], 'vw' => [ 'min' => 0, 'max' => 100, 'step' => 1 ], '%' => [ 'min' => 0, 'max' => 100, 'step' => 1 ], ], ] ); $this->end_controls_section(); } public function get_global_color($global_colors, $new_color){ $new_color_id = substr($new_color, strpos($new_color, 'colors?id=')+10); foreach($global_colors as $global_color){ if($global_color['_id']!= $new_color_id){ continue; } $new_color = ltrim($global_color['color'], '#'); } return $new_color; } /** * Converts time units to minutes * * This function converts time units to minutes based on the duration and unit type passed to the function, returning their equivalent. * * @param int $duration - The amount of time that needs conversion. * @param string $unit - The time format (minutes, hours, days, weeks). * * @return int|null The amount after conversion, or null if the input is invalid. */ 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; } } /** * Render Upcoming Appointments widget output on the frontend. * * Written in PHP and used to generate the final HTML. * * @since 1.0.0 * @access protected */ protected function render() { $settings = $this->get_settings_for_display(); if ( $settings['appointment_type'] === 'none' || $settings['appointment_type'] === 'all' ) { $settings['appointment_type'] = ''; } $attrs = array(); $kit = Elementor\Plugin::$instance->kits_manager->get_active_kit_for_frontend(); $system_colors = $kit->get_settings_for_display( 'system_colors' ); $custom_colors = $kit->get_settings_for_display( 'custom_colors' ); $global_colors = array_merge( $system_colors, $custom_colors ); if( $settings['appointment_type'] && $settings['appointment_type'] !== '') { if( is_array($settings['appointment_type'])){ $attrs['types'] = implode(',', $settings['appointment_type']); }else { $attrs['types'] = $settings['appointment_type']; $settings['appointment_type'] = ''; } } if( $settings['label'] && $settings['label'] !== '') { $attrs['label'] = $settings['label']; } if ( $settings['appointment_types_view'] && $settings['appointment_types_view'] !== '' ) { $attrs['appointment_types_view'] = $settings['appointment_types_view']; } if ( ssa_should_render_booking_flow() ) { if ( $settings['booking_layout'] !== 'appt_type_settings' && !empty( $settings['booking_layout'] ) ) { if ( $settings['booking_layout'] === 'expanded' ) { $attrs['flow'] = $settings['booking_layout']; $attrs['date_view'] = $settings['date_view_options']; $attrs['time_view'] = $settings['time_view_options']; } else if ( $settings['booking_layout'] === 'express' ) { $attrs['flow'] = $settings['booking_layout']; $attrs['time_view'] = $settings['time_view_options']; } else if ( $settings['booking_layout'] === 'first_available' ) { $attrs['flow'] = $settings['booking_layout']; $attrs['suggest_first_available'] = true; // Only available within $attrs['suggest_first_available_within_minutes'] = $this->convertDurationToMinutes( $settings['appt_duration'], $settings['duration_unit'] ); // Fallback flow if ( $settings['fallback_options'] === 'expanded' ) { $attrs['fallback_flow'] = $settings['fallback_options']; $attrs['date_view'] = $settings['date_view_options']; $attrs['time_view'] = $settings['time_view_options']; } else if ( $settings['fallback_options'] === 'express' ) { $attrs['fallback_flow'] = $settings['fallback_options']; $attrs['time_view'] = $settings['time_view_options']; } } } } if( $settings['accent_color'] && $settings['accent_color'] !== '' ) { $attrs['accent_color'] = ltrim( $settings['accent_color'], '#'); } else if ( ! empty( $settings['__globals__']['accent_color'] ) ) { $attrs['accent_color'] = $this->get_global_color($global_colors, $settings['__globals__']['accent_color']); } if( $settings['background_color'] && $settings['background_color'] !== '' ) { $attrs['background'] = ltrim( $settings['background_color'], '#' ); } else if (!empty($settings['__globals__']['background_color'])) { $attrs['background'] = $this->get_global_color($global_colors, $settings['__globals__']['background_color']); } if( $settings['font_family'] && $settings['font_family'] !== '' ) { $attrs['font'] = $settings['font_family']; } if( $settings['padding'] && $settings['padding'] !== '' ) { $attrs['padding'] = $settings['padding']['size'] . $settings['padding']['unit']; } ?>
get_render_attribute_string( 'booking' ); ?>>
shortcodes->ssa_booking( $attrs ); ?>