Browse Source

** Booking Activities 1.7.14 **

* Tweak - Add customizable messages in settings: avail. and Selected Events
* Tweak - Add an option in permission selectboxes to permit misunderstanding errors (reminder: allow everybody = do not select any roles)
* Tweak - Display a notice when the WC product / variation price is empty to inform that the booking form won't appear
* Tweak - Display the Licenses tab in settings and instructions for new customers
* Tweak - Administrators now have the same restrictions as users while performing a booking action from the frontend
* Tweak - Improve visual feedback when duplicating an event
* Tweak - Allow to resize the activities and the groups of events areas in calendar editor
* Fix - Error when deleting a product bound to an activity in the booking form calendar actions settings
* Fix - No longer display events from all calendars, activities and group categories if none are allowed
* Fix - Add-ons activity and group category settings were not saved
develop 1.7.14
yoan_cutillas 2 years ago
parent
commit
9a9ed32817
  1. 4
      booking-activities.php
  2. 61
      controller/controller-bookings.php
  3. 62
      controller/controller-settings.php
  4. 4
      controller/controller-woocommerce-backend.php
  5. 27
      controller/controller-woocommerce-bookings.php
  6. 2
      controller/controller-woocommerce-forms.php
  7. 3
      controller/controller-woocommerce-frontend.php
  8. 3
      css/backend.css
  9. 2
      css/backend.min.css
  10. 13
      css/templates.css
  11. 2
      css/templates.min.css
  12. 3
      css/woocommerce.css
  13. 2
      css/woocommerce.min.css
  14. 43
      functions/functions-booking-system.php
  15. 342
      functions/functions-bookings.php
  16. 81
      functions/functions-global.php
  17. 23
      functions/functions-settings.php
  18. 19
      functions/functions-templates-forms-control.php
  19. 11
      functions/functions-woocommerce.php
  20. 6
      i18n-config.json
  21. 15
      js/booking-system-functions.js
  22. 2
      js/booking-system-functions.min.js
  23. 5
      js/bookings-dialogs.js
  24. 2
      js/bookings-dialogs.min.js
  25. 78
      js/templates-functions.js
  26. 2
      js/templates-functions.min.js
  27. 62
      js/templates.js
  28. 2
      js/templates.min.js
  29. 92
      js/woocommerce-backend.js
  30. 2
      js/woocommerce-backend.min.js
  31. 1560
      languages/booking-activities.pot
  32. 15
      languages/script-translation.php
  33. 10
      model/model-booking-system.php
  34. 22
      model/model-templates.php
  35. 14
      readme.txt
  36. 11
      view/view-settings.php
  37. 14
      view/view-templates-dialogs.php
  38. 4
      view/view-templates.php

4
booking-activities.php

@ -3,7 +3,7 @@
* Plugin Name: Booking Activities
* Plugin URI: https://booking-activities.fr/en/?utm_source=plugin&utm_medium=plugin&utm_content=header
* Description: Booking system specialized in activities (sports, cultural, leisure, events...). Works great with WooCommerce.
* Version: 1.7.13
* Version: 1.7.14
* Author: Booking Activities Team
* Author URI: https://booking-activities.fr/en/?utm_source=plugin&utm_medium=plugin&utm_content=header
* Text Domain: booking-activities
@ -40,7 +40,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// GLOBALS AND CONSTANTS
if( ! defined( 'BOOKACTI_VERSION' ) ) { define( 'BOOKACTI_VERSION', '1.7.13' ); }
if( ! defined( 'BOOKACTI_VERSION' ) ) { define( 'BOOKACTI_VERSION', '1.7.14' ); }
if( ! defined( 'BOOKACTI_PLUGIN_NAME' ) ) { define( 'BOOKACTI_PLUGIN_NAME', 'booking-activities' ); }

61
controller/controller-bookings.php

@ -6,7 +6,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// SINGLE BOOKING
/**
* AJAX Controller - Cancel a booking
* @version 1.7.4
* @version 1.7.14
*/
function bookacti_controller_cancel_booking() {
$booking_id = intval( $_POST[ 'booking_id' ] );
@ -23,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json( array( 'status' => 'failed', 'error' => 'booking_already_cancelled', 'message' => esc_html__( 'The booking is already cancelled.', 'booking-activities' ) ), 'cancel_booking' );
}
$can_be_cancelled = bookacti_booking_can_be_cancelled( $booking );
$can_be_cancelled = bookacti_booking_can_be_cancelled( $booking, false, 'front' );
if( ! $can_be_cancelled ) {
bookacti_send_json( array( 'status' => 'failed', 'error' => 'not_allowed_to_cancel_booking', 'message' => esc_html__( 'The booking cannot be cancelled.', 'booking-activities' ) ), 'cancel_booking' );
}
@ -36,7 +36,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
do_action( 'bookacti_booking_state_changed', $booking_id, 'cancelled', array( 'is_admin' => false ) );
$new_booking = bookacti_get_booking_by_id( $booking_id );
$allow_refund = bookacti_booking_can_be_refunded( $new_booking );
$allow_refund = bookacti_booking_can_be_refunded( $new_booking, false, 'front' );
$context = ! empty( $_POST[ 'context' ] ) ? sanitize_title_with_dashes( $_POST[ 'context' ] ) : '';
$columns = ! empty( $_POST[ 'columns' ] ) && is_array( $_POST[ 'columns' ] ) ? array_map( 'sanitize_title_with_dashes', $_POST[ 'columns' ] ) : array();
@ -51,7 +51,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Get possible actions to refund a booking
* @version 1.6.0
* @version 1.7.14
*/
function bookacti_controller_get_refund_actions_html() {
@ -66,12 +66,13 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json_not_allowed( 'get_refund_actions_html' );
}
if( ! bookacti_booking_can_be_refunded( $booking_id ) ) {
$front_or_admin = ! empty( $_POST[ 'is_admin' ] ) ? 'admin' : 'front';
if( ! bookacti_booking_can_be_refunded( $booking_id, false, $front_or_admin ) ) {
bookacti_send_json( array( 'status' => 'failed', 'error' => 'cannot_be_refunded', 'message' => esc_html__( 'This booking cannot be refunded.', 'booking-activities' ) ), 'get_refund_actions_html' );
}
$refund_actions_array = bookacti_get_refund_actions_by_booking_id( $booking_id );
$refund_actions_html = bookacti_get_refund_dialog_html_by_booking_id( $booking_id );
$refund_actions_array = bookacti_get_refund_actions_by_booking_id( $booking_id, $front_or_admin );
$refund_actions_html = bookacti_get_refund_dialog_html_by_booking_id( $booking_id, $front_or_admin );
if( ! empty( $refund_actions_html ) ) {
bookacti_send_json( array( 'status' => 'success', 'actions_html' => $refund_actions_html, 'actions_array' => $refund_actions_array ), 'get_refund_actions_html' );
@ -86,13 +87,14 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Refund a booking
* @version 1.7.4
* @version 1.7.14
*/
function bookacti_controller_refund_booking() {
$booking_id = intval( $_POST[ 'booking_id' ] );
$is_admin = intval( $_POST[ 'is_admin' ] );
$front_or_admin = ! empty( $_POST[ 'is_admin' ] ) ? 'admin' : 'front';
$sanitized_action = sanitize_title_with_dashes( stripslashes( $_POST[ 'refund_action' ] ) );
$refund_action = array_key_exists( $sanitized_action, bookacti_get_refund_actions_by_booking_id( $booking_id ) ) ? $sanitized_action : 'email';
$refund_action = array_key_exists( $sanitized_action, bookacti_get_refund_actions_by_booking_id( $booking_id, $front_or_admin ) ) ? $sanitized_action : 'email';
// Check nonce, capabilities and other params
if( ! check_ajax_referer( 'bookacti_refund_booking', 'nonce', false ) ) {
@ -103,7 +105,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json_not_allowed( 'refund_booking' );
}
if( ! bookacti_booking_can_be_refunded( $booking_id, $refund_action ) ) {
if( ! bookacti_booking_can_be_refunded( $booking_id, $refund_action, $front_or_admin ) ) {
bookacti_send_json( 'refund_booking' );
}
@ -121,7 +123,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
);
}
} else {
$refunded = apply_filters( 'bookacti_refund_booking', array( 'status' => 'failed' ), $booking_id, 'single', $refund_action, $refund_message );
$refunded = apply_filters( 'bookacti_refund_booking', array( 'status' => 'failed' ), $booking_id, 'single', $refund_action, $refund_message, $front_or_admin );
}
if( $refunded[ 'status' ] === 'success' ) {
@ -151,7 +153,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Change booking state
* @version 1.7.4
* @version 1.7.14
*/
function bookacti_controller_change_booking_state() {
$booking_id = intval( $_POST[ 'booking_id' ] );
@ -176,7 +178,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// Change booking state
if( $new_booking_state && $booking->state !== $new_booking_state ) {
$state_can_be_changed = bookacti_booking_state_can_be_changed_to( $booking, $new_booking_state );
$state_can_be_changed = bookacti_booking_state_can_be_changed_to( $booking, $new_booking_state, 'admin' );
if( ! $state_can_be_changed ) {
bookacti_send_json( array( 'status' => 'failed', 'error' => 'not_allowed_to_update_booking_status', 'message' => esc_html__( 'The booking status cannot be changed.', 'booking-activities' ) ), 'change_booking_status' );
}
@ -284,13 +286,14 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Reschedule a booking
* @version 1.7.4
* @version 1.7.14
*/
function bookacti_controller_reschedule_booking() {
$booking_id = intval( $_POST[ 'booking_id' ] );
$event_id = intval( $_POST[ 'event_id' ] );
$event_start = bookacti_sanitize_datetime( $_POST[ 'event_start' ] );
$event_end = bookacti_sanitize_datetime( $_POST[ 'event_end' ] );
$front_or_admin = ! empty( $_POST[ 'is_admin' ] ) ? 'admin' : 'front';
// Check nonce, capabilities and other params
$is_nonce_valid = check_ajax_referer( 'bookacti_reschedule_booking', 'nonce', false );
@ -303,7 +306,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$booking = bookacti_get_booking_by_id( $booking_id );
// Check if the desired event is eligible according to the current booking
$can_be_rescheduled = bookacti_booking_can_be_rescheduled_to( $booking, $event_id, $event_start, $event_end );
$can_be_rescheduled = bookacti_booking_can_be_rescheduled_to( $booking, $event_id, $event_start, $event_end, $front_or_admin );
if( $can_be_rescheduled[ 'status' ] !== 'success' ) {
bookacti_send_json( $can_be_rescheduled, 'reschedule_booking' );
}
@ -432,7 +435,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Cancel a booking group
* @since 1.1.0
* @version 1.7.4
* @version 1.7.14
*/
function bookacti_controller_cancel_booking_group() {
$booking_group_id = intval( $_POST[ 'booking_id' ] );
@ -449,7 +452,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json( array( 'status' => 'failed', 'error' => 'booking_group_already_cancelled', 'message' => esc_html__( 'The booking group is already cancelled.', 'booking-activities' ) ), 'cancel_booking_group' );
}
$can_be_cancelled = bookacti_booking_group_can_be_cancelled( $booking_group );
$can_be_cancelled = bookacti_booking_group_can_be_cancelled( $booking_group, 'front' );
if( ! $can_be_cancelled ) {
bookacti_send_json( array( 'status' => 'failed', 'error' => 'not_allowed_to_cancel_booking_group', 'message' => esc_html__( 'The booking group cannot be cancelled.', 'booking-activities' ) ), 'cancel_booking_group' );
}
@ -462,7 +465,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
do_action( 'bookacti_booking_group_state_changed', $booking_group_id, 'cancelled', array( 'is_admin' => false ) );
$new_booking_group = bookacti_get_booking_group_by_id( $booking_group_id );
$allow_refund = bookacti_booking_group_can_be_refunded( $new_booking_group );
$allow_refund = bookacti_booking_group_can_be_refunded( $new_booking_group, false, 'front' );
$context = ! empty( $_POST[ 'context' ] ) ? sanitize_title_with_dashes( $_POST[ 'context' ] ) : '';
$columns = ! empty( $_POST[ 'columns' ] ) && is_array( $_POST[ 'columns' ] ) ? array_map( 'sanitize_title_with_dashes', $_POST[ 'columns' ] ) : array();
@ -478,7 +481,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Get possible actions to refund a booking group
* @since 1.1.0
* @version 1.6.0
* @version 1.7.14
*/
function bookacti_controller_get_booking_group_refund_actions_html() {
@ -493,12 +496,13 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json_not_allowed( 'get_refund_actions_html' );
}
if( ! bookacti_booking_group_can_be_refunded( $booking_group_id ) ) {
$front_or_admin = ! empty( $_POST[ 'is_admin' ] ) ? 'admin' : 'front';
if( ! bookacti_booking_group_can_be_refunded( $booking_group_id, false, $front_or_admin ) ) {
bookacti_send_json( array( 'error' => 'cannot_be_refunded', 'message' => esc_html__( 'This booking cannot be refunded.', 'booking-activities' ) ), 'get_refund_actions_html' );
}
$refund_actions_array = bookacti_get_refund_actions_by_booking_group_id( $booking_group_id );
$refund_actions_html = bookacti_get_refund_dialog_html_by_booking_group_id( $booking_group_id );
$refund_actions_array = bookacti_get_refund_actions_by_booking_group_id( $booking_group_id, $front_or_admin );
$refund_actions_html = bookacti_get_refund_dialog_html_by_booking_group_id( $booking_group_id, $front_or_admin );
if( ! empty( $refund_actions_html ) ) {
bookacti_send_json( array( 'status' => 'success', 'actions_html' => $refund_actions_html, 'actions_array' => $refund_actions_array ), 'get_refund_actions_html' );
@ -514,13 +518,14 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Refund a booking group
* @since 1.1.0
* @version 1.7.4
* @version 1.7.14
*/
function bookacti_controller_refund_booking_group() {
$booking_group_id = intval( $_POST[ 'booking_id' ] );
$is_admin = intval( $_POST[ 'is_admin' ] );
$front_or_admin = ! empty( $_POST[ 'is_admin' ] ) ? 'admin' : 'front';
$sanitized_action = sanitize_title_with_dashes( stripslashes( $_POST[ 'refund_action' ] ) );
$refund_action = array_key_exists( $sanitized_action, bookacti_get_refund_actions_by_booking_group_id( $booking_group_id ) ) ? $sanitized_action : 'email';
$refund_action = array_key_exists( $sanitized_action, bookacti_get_refund_actions_by_booking_group_id( $booking_group_id, $front_or_admin ) ) ? $sanitized_action : 'email';
// Check nonce, capabilities and other params
if( ! check_ajax_referer( 'bookacti_refund_booking', 'nonce', false ) ) {
@ -531,7 +536,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json_not_allowed( 'refund_booking_group' );
}
if( ! bookacti_booking_group_can_be_refunded( $booking_group_id, $refund_action ) ) {
if( ! bookacti_booking_group_can_be_refunded( $booking_group_id, $refund_action, $front_or_admin ) ) {
bookacti_send_json( array( 'error' => 'cannot_be_refunded', 'message' => esc_html__( 'This booking cannot be refunded.', 'booking-activities' ) ), 'refund_booking_group' );
}
@ -545,7 +550,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$refunded = array( 'status' => 'failed', 'error' => 'cannot_send_email' );
}
} else {
$refunded = apply_filters( 'bookacti_refund_booking', array( 'status' => 'failed' ), $booking_group_id, 'group', $refund_action, $refund_message );
$refunded = apply_filters( 'bookacti_refund_booking', array( 'status' => 'failed' ), $booking_group_id, 'group', $refund_action, $refund_message, $front_or_admin );
}
if( $refunded[ 'status' ] === 'success' ) {
@ -581,7 +586,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Change booking group state
* @since 1.1.0
* @version 1.7.4
* @version 1.7.14
*/
function bookacti_controller_change_booking_group_state() {
$booking_group_id = intval( $_POST[ 'booking_id' ] );
@ -606,7 +611,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$booking_group = bookacti_get_booking_group_by_id( $booking_group_id );
if( $new_booking_state && $booking_group->state !== $new_booking_state ) {
$state_can_be_changed = bookacti_booking_group_state_can_be_changed_to( $booking_group, $new_booking_state );
$state_can_be_changed = bookacti_booking_group_state_can_be_changed_to( $booking_group, $new_booking_state, 'admin' );
if( ! $state_can_be_changed ) {
bookacti_send_json( array( 'status' => 'failed', 'error' => 'not_allowed_to_update_booking_group_status', 'message' => esc_html__( 'The booking group status cannot be changed.', 'booking-activities' ) ), 'change_booking_group_status' );
}

62
controller/controller-settings.php

@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Init Booking Activities settings
* @version 1.7.0
* @version 1.7.14
*/
function bookacti_init_settings() {
@ -221,6 +221,16 @@ function bookacti_init_settings() {
);
/* Licenses settings Section */
add_settings_section(
'bookacti_settings_section_licenses',
esc_html__( 'Licenses settings', 'booking-activities' ),
'bookacti_settings_section_licenses_callback',
'bookacti_licenses_settings'
);
do_action( 'bookacti_add_settings' );
@ -229,6 +239,7 @@ function bookacti_init_settings() {
register_setting( 'bookacti_notifications_settings', 'bookacti_notifications_settings' );
register_setting( 'bookacti_messages_settings', 'bookacti_messages_settings' );
register_setting( 'bookacti_system_settings', 'bookacti_system_settings' );
register_setting( 'bookacti_licenses_settings', 'bookacti_licenses_settings' );
}
add_action( 'admin_init', 'bookacti_init_settings' );
@ -777,6 +788,55 @@ add_action( 'wp_ajax_bookactiArchiveDeleteFile', 'bookacti_controller_archive_de
// LICENSES
/**
* Display a description in the Licenses settings tab
* @since 1.7.14
*/
function bookacti_display_licenses_settings_description() {
$active_add_ons = bookacti_get_active_add_ons();
if( ! $active_add_ons ) {
?>
<div class='bookacti-licenses-settings-description'>
<p><?php esc_html_e( 'Here you will be able to activate your add-ons license keys.', 'booking-activities' ); ?></p>
<h3>
<?php
/* translators: %s is a link to "Booking Activities add-ons" (link label) shop */
echo sprintf( esc_html__( 'Purchase %s now!', 'booking-activities' ), ' <a href="https://booking-activities.fr/en/add-ons/" target="_blank">' . esc_html__( 'Booking Activities add-ons', 'booking-activities' ) . '</a>' );
?>
</h3>
</div>
<?php
}
if( bookacti_is_plugin_active( 'ba-licenses-and-updates/ba-licenses-and-updates.php' ) ) { return; }
if( $active_add_ons ) {
$active_add_ons_titles = array();
foreach( $active_add_ons as $prefix => $add_on_data ) {
$active_add_ons_titles[] = $add_on_data[ 'title' ];
}
?>
<div class='bookacti-licenses-settings-description'>
<p>
<em><?php esc_html_e( 'The following add-ons are installed on your site:', 'booking-activities' ); ?></em>
<strong><?php echo implode( '</strong>, <strong>', $active_add_ons_titles ); ?></strong>
</p>
<h3>
<?php
/* translators: %s is a link to download "Licenses and Updates" (link label) add-on */
echo sprintf( esc_html__( 'Please install the "%s" add-on in order to activate your license keys.', 'booking-activities' ), '<a href="https://booking-activities.fr/wp-content/uploads/downloads/public/ba-licenses-and-updates.zip">Licenses and Updates</a>' ); ?>
</h3>
</div>
<?php
}
}
add_action( 'bookacti_licenses_settings', 'bookacti_display_licenses_settings_description', 10, 0 );
// USER PROFILE
/**

4
controller/controller-woocommerce-backend.php

@ -893,7 +893,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Add custom variation product type option
* @version 1.5.0
* @version 1.7.14
* @param int $loop
* @param array $variation_data
* @param WP_Post $variation
@ -904,7 +904,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
<input type='hidden' name='bookacti_variable_is_activity[<?php echo $loop; ?>]' value='no' />
<input
type='checkbox'
id='bookacti_variable_is_activity[<?php echo esc_attr( $loop ); ?>]'
id='bookacti_variable_is_activity_<?php echo esc_attr( $loop ); ?>'
class='checkbox bookacti_variable_is_activity'
name='bookacti_variable_is_activity[<?php echo esc_attr( $loop ); ?>]'
value='yes'

27
controller/controller-woocommerce-bookings.php

@ -779,31 +779,33 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Filter refund actions by booking
* @version 1.6.0
* @version 1.7.14
* @param array $possible_actions
* @param int|object $booking
* @param string $context
* @return array
*/
function bookacti_filter_refund_actions_by_booking( $possible_actions, $booking ) {
function bookacti_filter_refund_actions_by_booking( $possible_actions, $booking, $context = '' ) {
$order_id = is_numeric( $booking ) ? bookacti_get_booking_order_id( $booking ) : $booking->order_id;
return bookacti_filter_refund_actions_by_order( $possible_actions, $order_id );
}
add_filter( 'bookacti_refund_actions_by_booking', 'bookacti_filter_refund_actions_by_booking', 10, 2 );
add_filter( 'bookacti_refund_actions_by_booking', 'bookacti_filter_refund_actions_by_booking', 10, 3 );
/**
* Filter refund actions by booking group
* @since 1.1.0
* @version 1.6.0
* @version 1.7.14
* @param array $possible_actions
* @param int|object $booking_group
* @param string $context
* @return array
*/
function bookacti_filter_refund_actions_by_booking_group( $possible_actions, $booking_group ) {
function bookacti_filter_refund_actions_by_booking_group( $possible_actions, $booking_group, $context = '' ) {
$order_id = is_numeric( $booking_group ) ? bookacti_get_booking_group_order_id( $booking_group ) : $booking_group->order_id;
return bookacti_filter_refund_actions_by_order( $possible_actions, $order_id );
}
add_filter( 'bookacti_refund_actions_by_booking_group', 'bookacti_filter_refund_actions_by_booking_group', 10, 2 );
add_filter( 'bookacti_refund_actions_by_booking_group', 'bookacti_filter_refund_actions_by_booking_group', 10, 3 );
/**
@ -961,23 +963,22 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Trigger WooCommerce refund process according to the refund action
*
* @version 1.1.0
*
* @version 1.7.14
* @param array $return_array
* @param int $booking_id
* @param string $refund_action
* @param string $refund_message
* @param string $context
* @return array
*/
function bookacti_woocommerce_refund_booking( $return_array, $booking_id, $booking_type, $refund_action, $refund_message ) {
function bookacti_woocommerce_refund_booking( $return_array, $booking_id, $booking_type, $refund_action, $refund_message, $context = '' ) {
if( $booking_type === 'single' ) {
$order_id = bookacti_get_booking_order_id( $booking_id );
$possibles_actions = array_keys( bookacti_get_refund_actions_by_booking_id( $booking_id ) );
$possibles_actions = array_keys( bookacti_get_refund_actions_by_booking_id( $booking_id, $context ) );
} else if( $booking_type === 'group' ) {
$order_id = bookacti_get_booking_group_order_id( $booking_id );
$possibles_actions = array_keys( bookacti_get_refund_actions_by_booking_group_id( $booking_id ) );
$possibles_actions = array_keys( bookacti_get_refund_actions_by_booking_group_id( $booking_id, $context ) );
}
if( in_array( $refund_action, $possibles_actions, true ) ) {
@ -990,7 +991,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
return $return_array;
}
add_filter( 'bookacti_refund_booking', 'bookacti_woocommerce_refund_booking', 10 , 5 );
add_filter( 'bookacti_refund_booking', 'bookacti_woocommerce_refund_booking', 10, 6 );
/**

2
controller/controller-woocommerce-forms.php

@ -92,6 +92,7 @@ add_filter( 'bookacti_sanitized_field_data', 'bookacti_form_editor_wc_field_titl
/**
* Format WC booking system attributes
* @since 1.7.0
* @version 1.7.14
* @param array $atts
* @return array
*/
@ -121,6 +122,7 @@ function bookacti_format_wc_booking_system_attributes( $atts ) {
$products_ids = array_unique( array_merge( $product_by_activity, $product_by_group_category ) );
foreach( $products_ids as $product_id ) {
$product = wc_get_product( $product_id );
if( ! $product ) { continue; }
$atts[ 'products_page_url' ][ $product_id ] = $product->get_permalink();
}
}

3
controller/controller-woocommerce-frontend.php

@ -146,11 +146,12 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Add booking forms to single product page (front-end)
* @version 1.7.11
* @version 1.7.14
* @global WC_Product $product
*/
function bookacti_add_booking_system_in_single_product_page() {
global $product;
if( ! $product ) { return; }
$is_activity = bookacti_product_is_activity( $product );
if( ! $is_activity ) { return; }

3
css/backend.css

@ -108,6 +108,9 @@
.bookacti_checkbox { display: inline-block; margin-right: 20px; padding: 1px; min-width: 100px; max-width: 100px; box-sizing: border-box; overflow: hidden; white-space: nowrap; }
#bookacti_refund_actions .bookacti_checkbox { max-width: none; overflow: visible; }
.bookacti-licenses-settings-description + .submit { display: none; }
/** DIALOGS **/
.bookacti-input-warning { border-color: #d80 !important; }
.bookacti-input-error { border-color: #f00 !important; }

2
css/backend.min.css

File diff suppressed because one or more lines are too long

13
css/templates.css

@ -19,8 +19,13 @@
/***** Events *****/
#bookacti-template-container .fc-event.fc-draggable { cursor: move; }
.bookacti-event-over .fc-bg::after { content: ' '; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 3; background: -moz-linear-gradient(top, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0) 75%); background: -webkit-linear-gradient(top, rgba(0,0,0,0.5) 0%,rgba(0,0,0,0) 75%); background: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%,rgba(0,0,0,0) 75%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#00000000',GradientType=0 ); }
#bookacti-template-container .fc-event.fc-draggable,
#bookacti-template-container .fc-helper { cursor: move; }
#bookacti-template-container .fc-event.bookacti-duplicate-event,
#bookacti-template-container .fc-helper.bookacti-duplicate-event { cursor: copy; }
#bookacti-template-container .fc-event.bookacti-event-dragged.bookacti-duplicate-event { visibility: visible !important; }
.bookacti-event-over .fc-bg::after { content: ' '; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 3; background: -moz-linear-gradient(top, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0) 75%); background: -webkit-linear-gradient(top, rgba(0,0,0,0.5) 0%,rgba(0,0,0,0) 75%); background: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%,rgba(0,0,0,0) 75%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#00000000',GradientType=0 ); }
#bookacti-template-calendar .bookacti-picked-event { border-width: 1px; }
#bookacti-template-calendar .bookacti-picked-event .fc-bg { opacity: 0.25; }
@ -71,7 +76,7 @@
#bookacti-template-activities-container,
#bookacti-template-groups-of-events-container { padding-right: 6px; }
#bookacti-template-activity-list,
#bookacti-group-categories { max-height: 200px; overflow-y: auto; padding-right: 4px; }
#bookacti-group-categories { overflow-y: auto; resize: vertical; padding-right: 4px; }
.bookacti-group-category-title,
.bookacti-update-group-category,
.bookacti-group-of-events-title,
@ -79,7 +84,7 @@
.bookacti-group-category-title span { display: table-cell; vertical-align: middle; }
.bookacti-update-group-category { padding-left: 10px; cursor: pointer; }
.bookacti-update-group-of-events { padding-right: 8px; cursor: pointer; }
.bookacti-groups-of-events-editor-list { margin-left: 8px; padding-left: 7px; margin-top: 8px; border-left: 1px dotted rgba(0,0,0,0.3); max-height: 150px; overflow-y: auto; overflow-x: hidden; cursor: pointer; }
.bookacti-groups-of-events-editor-list { margin-left: 8px; padding-left: 7px; margin-top: 8px; border-left: 1px dotted rgba(0,0,0,0.3); overflow-y: auto; resize: vertical; overflow-x: hidden; cursor: pointer; }
.bookacti-group-category-title { width: 100%; cursor: pointer; }
.bookacti-group-category-title span { font-weight: 600; }
.bookacti-group-category-title,

2
css/templates.min.css

File diff suppressed because one or more lines are too long

3
css/woocommerce.css

@ -17,6 +17,9 @@ p.form-field._bookacti_groups_field { margin-bottom: 0; }
.woocommerce_options_panel .bookacti-multiple-select-container { white-space: nowrap; display: inline-block; }
.woocommerce_options_panel .bookacti-multiple-select-container label{ float: none; width: auto; margin: 0; display: inline-block; }
.bookacti-empty-product-price-notice { clear: both; color: #f89b2f; }
.bookacti-empty-product-price-notice:before { content: '\26A0 '; }
table.woocommerce_order_items ul.bookacti-booking-events-list { margin: 0; }
.bookacti-deprecated-hidden { display: none; }

2
css/woocommerce.min.css

@ -1 +1 @@
#woocommerce-product-data .bookacti-loading-alt{display:inline-block;margin:10px;max-width:120px}#woocommerce-product-data ul.product_data_tabs li.activity_tab a::before{font-family:dashicons;content:'\f508'}.bookacti-woo-title{padding:1em 0 .5em 0}p.form-field._bookacti_groups_field{margin-bottom:0}.bookacti-groups-options{margin-top:0}.bookacti-groups-options label,.form-row.bookacti-groups-options label{float:none;width:auto;margin:0 0 0 7px;font-size:12px}.bookacti-groups-options>span,.form-row.bookacti-groups-options>span{display:block;clear:both}.bookacti-groups-options>span>*,.form-row.bookacti-groups-options>span>*{display:table-cell;padding-right:8px}.bookacti-groups-options .woocommerce-help-tip,.form-row.bookacti-groups-options .woocommerce-help-tip{float:none}.woocommerce_options_panel .bookacti-multiple-select-container{white-space:nowrap;display:inline-block}.woocommerce_options_panel .bookacti-multiple-select-container label{float:none;width:auto;margin:0;display:inline-block}table.woocommerce_order_items ul.bookacti-booking-events-list{margin:0}.bookacti-deprecated-hidden{display:none}.woocommerce_options_panel .bookacti-wc-deprecated-note p.form-field{padding-left:12px!important}.woocommerce_order_items .display_meta .bookacti-booking-events-list{margin:0}.bookacti-order-item-action-buttons>div{display:inline-block;vertical-align:middle}.bookacti-order-item-action-buttons>div:after{content:' | ';vertical-align:middle}.bookacti-order-item-action-buttons>div:last-child:after{content:''}.bookacti-success-list.woocommerce a.button,.woocommerce div.product form.cart .bookacti-success-list.woocommerce .button{float:right}.woocommerce div.product form.cart table td.fc-axis{padding-left:4px}.bookacti-order-item-activity td.product-name .wc-item-meta .wc-item-meta-bookacti_booked_events,.bookacti-cart-item-activity td.product-name dl.variation dt{float:none;display:block}.woocommerce a.button.bookacti-booking-group-action,.woocommerce a.button.bookacti-booking-action{margin:5px}
#woocommerce-product-data .bookacti-loading-alt{display:inline-block;margin:10px;max-width:120px}#woocommerce-product-data ul.product_data_tabs li.activity_tab a::before{font-family:dashicons;content:'\f508'}.bookacti-woo-title{padding:1em 0 .5em 0}p.form-field._bookacti_groups_field{margin-bottom:0}.bookacti-groups-options{margin-top:0}.bookacti-groups-options label,.form-row.bookacti-groups-options label{float:none;width:auto;margin:0 0 0 7px;font-size:12px}.bookacti-groups-options>span,.form-row.bookacti-groups-options>span{display:block;clear:both}.bookacti-groups-options>span>*,.form-row.bookacti-groups-options>span>*{display:table-cell;padding-right:8px}.bookacti-groups-options .woocommerce-help-tip,.form-row.bookacti-groups-options .woocommerce-help-tip{float:none}.woocommerce_options_panel .bookacti-multiple-select-container{white-space:nowrap;display:inline-block}.woocommerce_options_panel .bookacti-multiple-select-container label{float:none;width:auto;margin:0;display:inline-block}.bookacti-empty-product-price-notice{clear:both;color:#f89b2f}.bookacti-empty-product-price-notice:before{content:'\26A0 '}table.woocommerce_order_items ul.bookacti-booking-events-list{margin:0}.bookacti-deprecated-hidden{display:none}.woocommerce_options_panel .bookacti-wc-deprecated-note p.form-field{padding-left:12px!important}.woocommerce_order_items .display_meta .bookacti-booking-events-list{margin:0}.bookacti-order-item-action-buttons>div{display:inline-block;vertical-align:middle}.bookacti-order-item-action-buttons>div:after{content:' | ';vertical-align:middle}.bookacti-order-item-action-buttons>div:last-child:after{content:''}.bookacti-success-list.woocommerce a.button,.woocommerce div.product form.cart .bookacti-success-list.woocommerce .button{float:right}.woocommerce div.product form.cart table td.fc-axis{padding-left:4px}.bookacti-order-item-activity td.product-name .wc-item-meta .wc-item-meta-bookacti_booked_events,.bookacti-cart-item-activity td.product-name dl.variation dt{float:none;display:block}.woocommerce a.button.bookacti-booking-group-action,.woocommerce a.button.bookacti-booking-action{margin:5px}

43
functions/functions-booking-system.php

@ -296,12 +296,11 @@ function bookacti_get_booking_system_default_attributes() {
/**
* Check booking system attributes and format them to be correct
* @version 1.7.13
* @version 1.7.14
* @param array $atts
* @return type
*/
function bookacti_format_booking_system_attributes( $atts = array() ) {
// Set default value
$defaults = bookacti_get_booking_system_default_attributes();
@ -342,7 +341,6 @@ function bookacti_format_booking_system_attributes( $atts = array() ) {
} else if( in_array( $atts[ 'group_categories' ], array( false, 'none', 'false', 'no' ), true )
|| ( empty( $atts[ 'group_categories' ] ) && ! is_array( $atts[ 'group_categories' ] ) ) ) {
$atts[ 'group_categories' ] = false;
} else if( is_string( $atts[ 'group_categories' ] ) || is_numeric( $atts[ 'group_categories' ] ) ) {
$atts[ 'group_categories' ] = array_map( 'intval', explode( ',', preg_replace( array(
@ -352,6 +350,7 @@ function bookacti_format_booking_system_attributes( $atts = array() ) {
'/,+$/' // Matches trailing commas.
), '', $atts[ 'group_categories' ] ) ) );
}
if( ! is_array( $atts[ 'group_categories' ] ) ) { $atts[ 'group_categories' ] = false; }
// Remove duplicated values
$atts[ 'calendars' ] = array_unique( $atts[ 'calendars' ] );
@ -362,20 +361,22 @@ function bookacti_format_booking_system_attributes( $atts = array() ) {
if( empty( $atts[ 'calendars' ] ) ) {
$bypass_template_managers_check = apply_filters( 'bookacti_bypass_template_managers_check', false );
if( ! $bypass_template_managers_check && ! is_super_admin() ) {
$atts[ 'calendars' ] = $available_template_ids;
$atts[ 'calendars' ] = ! empty( $available_template_ids ) ? $available_template_ids : array( 'none' );
}
} else {
$atts[ 'calendars' ] = array_intersect( $atts[ 'calendars' ], $available_template_ids );
$allowed_templates = array_intersect( $atts[ 'calendars' ], $available_template_ids );
$atts[ 'calendars' ] = ! empty( $allowed_templates ) ? $allowed_templates : array( 'none' );
}
// Check if desired activities are active and allowed according to current user role
$available_activity_ids = bookacti_get_activity_ids_by_template( $atts[ 'calendars' ], false, $atts[ 'check_roles' ] );
$had_activities = ! empty( $atts[ 'activities' ] );
foreach( $atts[ 'activities' ] as $i => $activity_id ) {
if( ! in_array( intval( $activity_id ), $available_activity_ids, true ) ) {
unset( $atts[ 'activities' ][ $i ] );
}
}
if( ! $atts[ 'activities' ] ) { $atts[ 'activities' ] = $available_activity_ids; }
if( ! $atts[ 'activities' ] ) { $atts[ 'activities' ] = ! $had_activities ? $available_activity_ids : array( 'none' ); }
// Check if desired group categories exist and are allowed according to current user role
$available_category_ids = bookacti_get_group_category_ids_by_template( $atts[ 'calendars' ], false, $atts[ 'check_roles' ] );
@ -383,19 +384,9 @@ function bookacti_format_booking_system_attributes( $atts = array() ) {
// Remove duplicated values
$atts[ 'group_categories' ] = array_unique( $atts[ 'group_categories' ] );
foreach( $atts[ 'group_categories' ] as $i => $category_id ) {
$is_existing = false;
foreach( $available_category_ids as $available_category_id ) {
if( $available_category_id == intval( $category_id ) ) {
$is_existing = true;
break;
}
}
if( ! $is_existing ) {
unset( $atts[ 'group_categories' ][ $i ] );
}
}
if( ! $atts[ 'group_categories' ] ) { $atts[ 'group_categories' ] = $available_category_ids; }
// Remove unauthorized values
$allowed_group_categories = array_intersect( $atts[ 'group_categories' ], array_map( 'intval', $available_category_ids ) );
$atts[ 'group_categories' ] = ! empty( $allowed_group_categories ) ? $allowed_group_categories : false;
}
// Format template data
@ -815,7 +806,7 @@ function bookacti_get_booking_system_fields_default_data( $fields = array() ) {
/**
* Check the selected event / group of events data before booking
* @version 1.7.8
* @version 1.7.14
* @param int $group_id
* @param int $event_id
* @param string $event_start Start datetime of the event to check (format 2017-12-31T23:59:59)
@ -956,11 +947,17 @@ function bookacti_validate_booking_form( $group_id, $event_id, $event_start, $ev
if( $min_quantity === 0 || ( $quantity + $quantity_already_booked ) >= $min_quantity ) { $is_qty_sup_to_min = true; }
if( $max_quantity === 0 || $quantity <= ( $max_quantity - $quantity_already_booked ) ) { $is_qty_inf_to_max = true; }
if( $max_users === 0 || $quantity_already_booked || $number_of_users < $max_users ) { $is_users_inf_to_max = true; }
if( ! $allowed_roles || apply_filters( 'bookacti_bypass_roles_check', false ) ) { $has_allowed_roles = true; }
if( ! $allowed_roles
|| in_array( 'all', $allowed_roles, true )
|| apply_filters( 'bookacti_bypass_roles_check', false ) ) { $has_allowed_roles = true; }
else {
$is_allowed = false;
$current_user = wp_get_current_user();
$roles = $current_user->roles;
$is_allowed = array_intersect( $roles, $allowed_roles );
if( $current_user && ! empty( $current_user->roles ) ) {
$is_allowed = array_intersect( $current_user->roles, $allowed_roles );
}
if( $is_allowed ) { $has_allowed_roles = true; }
}

342
functions/functions-bookings.php

@ -344,162 +344,176 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Check if a booking can be cancelled
* @version 1.7.12
* @param object|int $booking_id
* @version 1.7.14
* @param object|int $booking
* @param boolean $bypass_group_check
* @param string $context
* @return boolean
*/
function bookacti_booking_can_be_cancelled( $booking, $bypass_group_check = false ) {
function bookacti_booking_can_be_cancelled( $booking, $bypass_group_check = false, $context = '' ) {
$is_allowed = true;
if( ! current_user_can( 'bookacti_edit_bookings' ) ) {
// Get booking
if( ! is_object( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
if( ! $booking ) { return apply_filters( 'bookacti_booking_can_be_cancelled', false, $booking ); }
$is_cancel_allowed = bookacti_get_setting_value( 'bookacti_cancellation_settings', 'allow_customers_to_cancel' );
$is_grouped = $bypass_group_check ? false : ! empty( $booking->group_id );
$is_in_delay = apply_filters( 'bookacti_bypass_delay', false, $booking ) ? true : bookacti_is_booking_in_delay( $booking, 'cancel' );
// Final check and return the actions array without invalid entries
if( ! $is_cancel_allowed || $is_grouped || ! $is_in_delay ) { $is_allowed = false; }
// Get booking
if( is_numeric( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
if( ! $booking ) { $is_allowed = false; }
else {
if( ! current_user_can( 'bookacti_edit_bookings' ) || $context === 'front' ) {
$is_cancel_allowed = bookacti_get_setting_value( 'bookacti_cancellation_settings', 'allow_customers_to_cancel' );
$is_grouped = $bypass_group_check ? false : ! empty( $booking->group_id );
$is_in_delay = apply_filters( 'bookacti_bypass_delay', false, $booking ) ? true : bookacti_is_booking_in_delay( $booking, 'cancel' );
// Final check and return the actions array without invalid entries
if( ! $is_cancel_allowed || $is_grouped || ! $is_in_delay ) { $is_allowed = false; }
}
if( empty( $booking->active ) ) { $is_allowed = false; }
}
if( ! $booking->active ) { $is_allowed = false; }
return apply_filters( 'bookacti_booking_can_be_cancelled', $is_allowed, $booking );
return apply_filters( 'bookacti_booking_can_be_cancelled', $is_allowed, $booking, $bypass_group_check, $context );
}
/**
* Check if a booking is allowed to be rescheduled
* @version 1.6.0
* @version 1.7.14
* @param object|int $booking
* @param string $context
* @return boolean
*/
function bookacti_booking_can_be_rescheduled( $booking ) {
function bookacti_booking_can_be_rescheduled( $booking, $context = '' ) {
$is_allowed = true;
// Get booking
if( ! is_object( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
if( ! current_user_can( 'bookacti_edit_bookings' ) ) {
if( ! $booking ) { return apply_filters( 'bookacti_booking_can_be_rescheduled', false, $booking ); }
// First check if the booking is part of a group
$is_allowed = empty( $booking->group_id );
if( $is_allowed ) {
// Init variable
$is_reschedule_allowed = bookacti_get_setting_value( 'bookacti_cancellation_settings', 'allow_customers_to_reschedule' );
$is_in_delay = apply_filters( 'bookacti_bypass_delay', false, $booking ) ? true : bookacti_is_booking_in_delay( $booking, 'reschedule' );
if( ! $is_reschedule_allowed || ! $booking->active || ! $is_in_delay ) { $is_allowed = false; }
if( is_numeric( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
if( ! $booking ) { $is_allowed = false; }
else {
if( ! current_user_can( 'bookacti_edit_bookings' ) || $context === 'front' ) {
// First check if the booking is part of a group
$is_group = empty( $booking->group_id );
if( $is_group ) {
// Init variable
$is_reschedule_allowed = bookacti_get_setting_value( 'bookacti_cancellation_settings', 'allow_customers_to_reschedule' );
$is_in_delay = apply_filters( 'bookacti_bypass_delay', false, $booking ) ? true : bookacti_is_booking_in_delay( $booking, 'reschedule' );
if( ! $is_reschedule_allowed || ! $booking->active || ! $is_in_delay ) { $is_allowed = false; }
} else {
$is_allowed = false;
}
}
// If the booked event has been removed, we cannot know its activity, then, the booking cannot be rescheduled.
if( ! bookacti_get_event_by_id( $booking->event_id ) ) { $is_allowed = false; }
}
// If the booked event has been removed, we cannot know its activity, then, the booking cannot be rescheduled.
if( ! bookacti_get_event_by_id( $booking->event_id ) ) { $is_allowed = false; }
return apply_filters( 'bookacti_booking_can_be_rescheduled', $is_allowed, $booking );
return apply_filters( 'bookacti_booking_can_be_rescheduled', $is_allowed, $booking, $context );
}
/**
* Check if a booking can be rescheduled to another event
* @since 1.1.0
* @version 1.6.0
* @version 1.7.14
* @param object|int $booking
* @param int $event_id
* @param string $event_start
* @param string $event_end
* @param string $context
* @return boolean
*/
function bookacti_booking_can_be_rescheduled_to( $booking, $event_id, $event_start, $event_end ) {
function bookacti_booking_can_be_rescheduled_to( $booking, $event_id, $event_start, $event_end, $context = '' ) {
// Get booking
if( ! is_object( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
$return_array = array( 'status' => 'success' );
$is_allowed = bookacti_booking_can_be_rescheduled( $booking );
if( ! $is_allowed ) {
if( is_numeric( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
if( ! $booking ) {
$return_array[ 'status' ] = 'failed';
$return_array[ 'error' ] = 'reschedule_not_allowed';
$return_array[ 'error' ] = 'booking_not_found';
$return_array[ 'message' ] = esc_html__( 'You are not allowed to reschedule this event.', 'booking-activities' );
return apply_filters( 'bookacti_booking_can_be_rescheduled_to', $return_array, $booking, $event_id, $event_start, $event_end );
}
$from_event = bookacti_get_event_by_id( $booking->event_id );
$to_event = bookacti_get_event_by_id( $event_id );
if( $from_event->activity_id !== $to_event->activity_id ) {
$return_array[ 'status' ] = 'failed';
$return_array[ 'error' ] = 'reschedule_to_different_activity';
$return_array[ 'message' ] = esc_html__( 'The desired event haven\'t the same activity as the booked event.', 'booking-activities' );
} else {
$return_array = array( 'status' => 'success' );
$is_allowed = bookacti_booking_can_be_rescheduled( $booking, $context );
if( ! $is_allowed ) {
$return_array[ 'status' ] = 'failed';
$return_array[ 'error' ] = 'reschedule_not_allowed';
$return_array[ 'message' ] = esc_html__( 'You are not allowed to reschedule this event.', 'booking-activities' );
} else {
$from_event = bookacti_get_event_by_id( $booking->event_id );
$to_event = bookacti_get_event_by_id( $event_id );
if( $from_event->activity_id !== $to_event->activity_id ) {
$return_array[ 'status' ] = 'failed';
$return_array[ 'error' ] = 'reschedule_to_different_activity';
$return_array[ 'message' ] = esc_html__( 'The desired event haven\'t the same activity as the booked event.', 'booking-activities' );
}
}
}
return apply_filters( 'bookacti_booking_can_be_rescheduled_to', $return_array, $booking, $event_id, $event_start, $event_end );
return apply_filters( 'bookacti_booking_can_be_rescheduled_to', $return_array, $booking, $event_id, $event_start, $event_end, $context );
}
/**
* Check if a booking can be refunded
* @version 1.6.0
* @version 1.7.14
* @param int $booking
* @param string $refund_action
* @param string $context
* @return boolean
*/
function bookacti_booking_can_be_refunded( $booking, $refund_action = false ) {
// Get booking
if( ! is_object( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
if( ! $booking ) { return apply_filters( 'bookacti_booking_can_be_refunded', false, $booking ); }
$refund_actions = bookacti_get_refund_actions_by_booking_id( $booking );
$true = true;
function bookacti_booking_can_be_refunded( $booking, $refund_action = false, $context = '' ) {
$true = true;
// Disallow refund in those cases:
// -> If the booking is already marked as refunded,
if( $booking->state === 'refunded'
// -> If the booking is part of a group
|| ! empty( $booking->group_id )
// -> If there are no refund action available
|| empty( $refund_actions )
// -> If the refund action is set but doesn't exist in available refund actions list
|| ( ! empty( $refund_action ) && ! array_key_exists( $refund_action, $refund_actions ) )
// -> If the user is not an admin, the booking state has to be 'cancelled' in the first place
|| ( ! current_user_can( 'bookacti_edit_bookings' ) && $booking->state !== 'cancelled' ) ) {
$true = false;
// Get booking
if( is_numeric( $booking ) ) { $booking = bookacti_get_booking_by_id( $booking ); }
if( ! $booking ) { $true = false; }
else {
$refund_actions = bookacti_get_refund_actions_by_booking_id( $booking, $context );
// Disallow refund in those cases:
// -> If the booking is already marked as refunded,
if( $booking->state === 'refunded'
// -> If the booking is part of a group
|| ! empty( $booking->group_id )
// -> If there are no refund action available
|| empty( $refund_actions )
// -> If the refund action is set but doesn't exist in available refund actions list
|| ( ! empty( $refund_action ) && ! array_key_exists( $refund_action, $refund_actions ) )
// -> If the user is not an admin, the booking state has to be 'cancelled' in the first place
|| ( $booking->state !== 'cancelled' && ( ! current_user_can( 'bookacti_edit_bookings' ) || $context === 'front' ) ) ) {
$true = false;
}
}
return apply_filters( 'bookacti_booking_can_be_refunded', $true, $booking );
return apply_filters( 'bookacti_booking_can_be_refunded', $true, $booking, $context );
}
/**
* Check if a booking state can be changed to another
* @version 1.7.0
* @version 1.7.14
* @param object|int $booking
* @param string $new_state
* @param string $context
* @return boolean
*/
function bookacti_booking_state_can_be_changed_to( $booking, $new_state ) {
function bookacti_booking_state_can_be_changed_to( $booking, $new_state, $context = 'admin' ) {
$true = true;
if( ! current_user_can( 'bookacti_edit_bookings' ) ) {
if( ! current_user_can( 'bookacti_edit_bookings' ) || $context === 'front' ) {
switch ( $new_state ) {
case 'delivered':
$true = false;
break;
case 'cancelled':
$true = bookacti_booking_can_be_cancelled( $booking );
$true = bookacti_booking_can_be_cancelled( $booking, false, $context );
break;
case 'refund_requested':
case 'refunded':
$true = bookacti_booking_can_be_refunded( $booking );
$true = bookacti_booking_can_be_refunded( $booking, false, $context );
break;
}
}
return apply_filters( 'bookacti_booking_state_can_be_changed', $true, $booking, $new_state );
return apply_filters( 'bookacti_booking_state_can_be_changed', $true, $booking, $new_state, $context );
}
@ -534,75 +548,82 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Check if a booking group can be cancelled
* @since 1.1.0
* @version 1.7.3
* @version 1.7.14
* @param object $booking_group
* @param string $context
* @return boolean
*/
function bookacti_booking_group_can_be_cancelled( $booking_group ) {
function bookacti_booking_group_can_be_cancelled( $booking_group, $context = '' ) {
$true = true;
// Get booking group
if( ! is_object( $booking_group ) ) { $booking_group = bookacti_get_booking_group_by_id( $booking_group ); }
if( ! current_user_can( 'bookacti_edit_bookings' ) ) {
$filters = bookacti_format_booking_filters( array( 'booking_group_id' => $booking_group->id ) );
$bookings = bookacti_get_bookings( $filters );
foreach( $bookings as $booking ) {
$is_allowed = bookacti_booking_can_be_cancelled( $booking, true );
if( ! $is_allowed ) {
$true = false;
break; // If one of the booking of the group is not allowed, return false immediatly
if( is_numeric( $booking_group ) ) { $booking_group = bookacti_get_booking_group_by_id( $booking_group ); }
if( ! $booking_group ) { $true = false; }
else {
if( ! current_user_can( 'bookacti_edit_bookings' ) || $context === 'front' ) {
$filters = bookacti_format_booking_filters( array( 'booking_group_id' => $booking_group->id ) );
$bookings = bookacti_get_bookings( $filters );
foreach( $bookings as $booking ) {
$is_allowed = bookacti_booking_can_be_cancelled( $booking, true, $context );
if( ! $is_allowed ) {
$true = false;
break; // If one of the booking of the group is not allowed, return false immediatly
}
}
}
if( ! $booking_group->active ) { $true = false; }
}
if( ! $booking_group->active ) { $true = false; }
return apply_filters( 'bookacti_booking_group_can_be_cancelled', $true, $booking_group );
return apply_filters( 'bookacti_booking_group_can_be_cancelled', $true, $booking_group, $context );
}
/**
* Check if a booking group can be refunded
* @since 1.1.0
* @version 1.6.0
* @version 1.7.14
* @param object|int $booking_group
* @param string $refund_action
* @param string $context
* @return boolean
*/
function bookacti_booking_group_can_be_refunded( $booking_group, $refund_action = false ) {
// Get booking group
if( ! is_object( $booking_group ) ) { $booking_group = bookacti_get_booking_group_by_id( $booking_group ); }
$true = true;
$refund_actions = bookacti_get_refund_actions_by_booking_group_id( $booking_group );
function bookacti_booking_group_can_be_refunded( $booking_group, $refund_action = false, $context = '' ) {
$true = true;
// Disallow refund in those cases:
// -> If the booking group is already marked as refunded,
if( $booking_group->state === 'refunded'
// -> If there are no refund action available
|| empty( $refund_actions )
// -> If the refund action is set but doesn't exist in available refund actions list
|| ( ! empty( $refund_action ) && ! array_key_exists( $refund_action, $refund_actions ) )
// -> If the user is not an admin, the booking group state has to be 'cancelled' in the first place
|| ( ! current_user_can( 'bookacti_edit_bookings' ) && $booking_group->state !== 'cancelled' ) ) {
$true = false;
// Get booking group
if( is_numeric( $booking_group ) ) { $booking_group = bookacti_get_booking_group_by_id( $booking_group ); }
if( ! $booking_group ) { $true = false; }
else {
$refund_actions = bookacti_get_refund_actions_by_booking_group_id( $booking_group, $context );
// Disallow refund in those cases:
// -> If the booking group is already marked as refunded,
if( $booking_group->state === 'refunded'
// -> If there are no refund action available
|| empty( $refund_actions )
// -> If the refund action is set but doesn't exist in available refund actions list
|| ( ! empty( $refund_action ) && ! array_key_exists( $refund_action, $refund_actions ) )
// -> If the user is not an admin, the booking group state has to be 'cancelled' in the first place
|| ( $booking_group->state !== 'cancelled' && ( ! current_user_can( 'bookacti_edit_bookings' ) || $context === 'front' ) ) ) {
$true = false;
}
}
return apply_filters( 'bookacti_booking_group_can_be_refunded', $true, $booking_group );
return apply_filters( 'bookacti_booking_group_can_be_refunded', $true, $booking_group, $context );
}
/**
* Check if a booking group state can be changed to another
* @since 1.1.0
* @version 1.7.0
* @version 1.7.14
* @param object $booking_group
* @param string $new_state
* @param string $context
* @return boolean
*/
function bookacti_booking_group_state_can_be_changed_to( $booking_group, $new_state ) {
function bookacti_booking_group_state_can_be_changed_to( $booking_group, $new_state, $context = 'admin' ) {
$true = true;
$can_edit_bookings = current_user_can( 'bookacti_edit_bookings' );
switch ( $new_state ) {
@ -610,18 +631,18 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$true = $can_edit_bookings;
break;
case 'cancelled':
$true = bookacti_booking_group_can_be_cancelled( $booking_group );
$true = bookacti_booking_group_can_be_cancelled( $booking_group, $context );
break;
case 'refund_requested':
if( ! $can_edit_bookings ) {
$true = bookacti_booking_group_can_be_refunded( $booking_group );
if( ! $can_edit_bookings || $context === 'front' ) {
$true = bookacti_booking_group_can_be_refunded( $booking_group, false, $context );
}
break;
case 'refunded':
$true = bookacti_booking_group_can_be_refunded( $booking_group );
$true = bookacti_booking_group_can_be_refunded( $booking_group, false, $context );
break;
}
return apply_filters( 'bookacti_booking_group_state_can_be_changed', $true, $booking_group, $new_state );
return apply_filters( 'bookacti_booking_group_state_can_be_changed', $true, $booking_group, $new_state, $context );
}
@ -691,7 +712,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Get booking actions according to booking id
* @since 1.6.0 (replace bookacti_get_booking_actions_array)
* @version 1.7.10
* @version 1.7.14
* @param object|int $booking
* @param string $admin_or_front Can be "both", "admin", "front. Default "both".
* @return array
@ -705,13 +726,13 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
if( isset( $actions[ 'change-state' ] ) ) { unset( $actions[ 'change-state' ] ); }
if( isset( $actions[ 'change-quantity' ] ) ){ unset( $actions[ 'change-quantity' ] ); }
}
if( isset( $actions[ 'cancel' ] ) && ! bookacti_booking_can_be_cancelled( $booking ) ) {
if( isset( $actions[ 'cancel' ] ) && ! bookacti_booking_can_be_cancelled( $booking, false, $admin_or_front ) ) {
unset( $actions[ 'cancel' ] );
}
if( isset( $actions[ 'reschedule' ] ) && ! bookacti_booking_can_be_rescheduled( $booking ) ) {
if( isset( $actions[ 'reschedule' ] ) && ! bookacti_booking_can_be_rescheduled( $booking, $admin_or_front ) ) {
unset( $actions[ 'reschedule' ] );
}
if( isset( $actions[ 'refund' ] ) && ! bookacti_booking_can_be_refunded( $booking ) ) {
if( isset( $actions[ 'refund' ] ) && ! bookacti_booking_can_be_refunded( $booking, false, $admin_or_front ) ) {
unset( $actions[ 'refund' ] );
}
if( isset( $actions[ 'delete' ] ) && ! current_user_can( 'bookacti_delete_bookings' ) ) {
@ -859,7 +880,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Get booking actions according to booking id
* @since 1.6.0 (replace bookacti_get_booking_actions_array)
* @version 1.7.10
* @version 1.7.14
* @param object|int $booking_group
* @param string $admin_or_front Can be "both", "admin", "front. Default "both".
* @return array
@ -874,10 +895,10 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
if( isset( $actions[ 'change-quantity' ] ) ){ unset( $actions[ 'change-quantity' ] ); }
if( isset( $actions[ 'edit-single' ] ) ) { unset( $actions[ 'edit-single' ] ); }
}
if( isset( $actions[ 'cancel' ] ) && ! bookacti_booking_group_can_be_cancelled( $booking_group ) ) {
if( isset( $actions[ 'cancel' ] ) && ! bookacti_booking_group_can_be_cancelled( $booking_group, $admin_or_front ) ) {
unset( $actions[ 'cancel' ] );
}
if( isset( $actions[ 'refund' ] ) && ! bookacti_booking_group_can_be_refunded( $booking_group ) ) {
if( isset( $actions[ 'refund' ] ) && ! bookacti_booking_group_can_be_refunded( $booking_group, false, $admin_or_front ) ) {
unset( $actions[ 'refund' ] );
}
if( isset( $actions[ 'delete' ] ) && ! current_user_can( 'bookacti_delete_bookings' ) ) {
@ -1239,41 +1260,42 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Get refund actions for a specific booking
* @version 1.6.0
* @version 1.7.14
* @param int|object $booking
* @param string $context
* @return array
*/
function bookacti_get_refund_actions_by_booking_id( $booking ) {
return bookacti_get_refund_actions_by_booking_type( $booking, 'single' );
function bookacti_get_refund_actions_by_booking_id( $booking, $context = '' ) {
return bookacti_get_refund_actions_by_booking_type( $booking, 'single', $context );
}
/**
* Get refund actions for a specific booking group
*
* @since 1.1.0
*
* @version 1.7.14
* @param int|object $booking_group
* @param string $context
* @return array
*/
function bookacti_get_refund_actions_by_booking_group_id( $booking_group ) {
return bookacti_get_refund_actions_by_booking_type( $booking_group, 'group' );
function bookacti_get_refund_actions_by_booking_group_id( $booking_group, $context = '' ) {
return bookacti_get_refund_actions_by_booking_type( $booking_group, 'group', $context );
}
/**
* Get refund actions for a specific booking or booking group
* @since 1.1.0
* @version 1.6.0
* @version 1.7.14
* @param int|object $booking
* @param string $booking_type Defined if the given id is a booking id or a booking group id. Accepted values are 'single' and 'group'.
* @param string $context
* @return array
*/
function bookacti_get_refund_actions_by_booking_type( $booking, $booking_type = 'single' ) {
function bookacti_get_refund_actions_by_booking_type( $booking, $booking_type = 'single', $context = '' ) {
$possible_actions = bookacti_get_refund_actions();
// If current user is a customer
if( ! current_user_can( 'bookacti_edit_bookings' ) ) {
if( ! current_user_can( 'bookacti_edit_bookings' ) || $context === 'front' ) {
// Keep only allowed action
$allowed_actions = bookacti_get_setting_value( 'bookacti_cancellation_settings', 'refund_actions_after_cancellation' );
if( ! is_array( $allowed_actions ) ) {
@ -1293,9 +1315,9 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
}
if( $booking_type === 'single' ) {
$possible_actions = apply_filters( 'bookacti_refund_actions_by_booking', $possible_actions, $booking );
$possible_actions = apply_filters( 'bookacti_refund_actions_by_booking', $possible_actions, $booking, $context );
} else if( $booking_type === 'group' ) {
$possible_actions = apply_filters( 'bookacti_refund_actions_by_booking_group', $possible_actions, $booking );
$possible_actions = apply_filters( 'bookacti_refund_actions_by_booking_group', $possible_actions, $booking, $context );
}
return $possible_actions;
@ -1304,41 +1326,39 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Get dialog refund text for a specific booking
*
* @version 1.1.0
*
* @version 1.7.14
* @param int $booking_id
* @param string $context
* @return string
*/
function bookacti_get_refund_dialog_html_by_booking_id( $booking_id ) {
return bookacti_get_refund_dialog_html_by_booking_type( $booking_id, 'single' );
function bookacti_get_refund_dialog_html_by_booking_id( $booking_id, $context = '' ) {
return bookacti_get_refund_dialog_html_by_booking_type( $booking_id, 'single', $context );
}
/**
* Get dialog refund text for a specific booking
*
* @version 1.1.0
*
* @version 1.7.14
* @param int $booking_group_id
* @param string $context
* @return string
*/
function bookacti_get_refund_dialog_html_by_booking_group_id( $booking_group_id ) {
return bookacti_get_refund_dialog_html_by_booking_type( $booking_group_id, 'group' );
function bookacti_get_refund_dialog_html_by_booking_group_id( $booking_group_id, $context = '' ) {
return bookacti_get_refund_dialog_html_by_booking_type( $booking_group_id, 'group', $context );
}
/**
* Get dialog refund text for a specific booking
* @since 1.1.0
* @version 1.7.4
* @version 1.7.14
* @param int $booking_or_booking_group_id
* @param string $booking_type Defined if the given id is a booking id or a booking group id. Accepted values are 'single' and 'group'.
* @param string $context
* @return string
*/
function bookacti_get_refund_dialog_html_by_booking_type( $booking_or_booking_group_id, $booking_type = 'single' ) {
$possible_actions = bookacti_get_refund_actions_by_booking_type( $booking_or_booking_group_id, $booking_type );
function bookacti_get_refund_dialog_html_by_booking_type( $booking_or_booking_group_id, $booking_type = 'single', $context = '' ) {
$possible_actions = bookacti_get_refund_actions_by_booking_type( $booking_or_booking_group_id, $booking_type, $context );
$actions_list = '';
foreach( $possible_actions as $possible_action ){

81
functions/functions-global.php

@ -244,6 +244,87 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// ADD-ONS
/**
* Get the active Booking Activities add-ons
* @since 1.7.14
*/
function bookacti_get_active_add_ons() {
$add_ons_data = bookacti_get_add_ons_data();
$active_add_ons = array();
foreach( $add_ons_data as $prefix => $add_on_data ) {
$add_on_path = $add_on_data[ 'plugin_name' ] . '/' . $add_on_data[ 'plugin_name' ] . '.php';
if( bookacti_is_plugin_active( $add_on_path ) ) {
$active_add_ons[ $prefix ] = $add_on_data;
}
}
return $active_add_ons;
}
/**
* Get add-on data by prefix
* @since 1.7.14
* @param string $prefix
* @return string|array
*/
function bookacti_get_add_ons_data( $prefix = '' ) {
$addons_data = array(
'badp' => array(
'title' => 'Display Pack',
'slug' => 'display-pack',
'plugin_name' => 'ba-display-pack',
'download_id' => 482
),
'banp' => array(
'title' => 'Notification Pack',
'slug' => 'notification-pack',
'plugin_name' => 'ba-notification-pack',
'download_id' => 1393
),
'bapap' => array(
'title' => 'Prices and Credits',
'slug' => 'prices-and-credits',
'plugin_name' => 'ba-prices-and-credits',
'download_id' => 438
),
'baaf' => array(
'title' => 'Advanced Forms',
'slug' => 'advanced-forms',
'plugin_name' => 'ba-advanced-forms',
'download_id' => 2705
),
'baofc' => array(
'title' => 'Order for Customers',
'slug' => 'order-for-customers',
'plugin_name' => 'ba-order-for-customers',
'download_id' => 436
),
'bapos' => array(
'title' => 'Points of Sale',
'slug' => 'points-of-sale',
'plugin_name' => 'ba-points-of-sale',
'download_id' => 416
),
'batest' => array(
'title' => 'Test add-on',
'slug' => 'test',
'plugin_name' => 'ba-test',
'download_id' => 3011
)
);
if( ! $prefix ) { return $addons_data; }
return isset( $addons_data[ $prefix ] ) ? $addons_data[ $prefix ] : '';
}
// LOCALE
/**

23
functions/functions-settings.php

@ -100,6 +100,7 @@ function bookacti_settings_section_general_callback() { }
function bookacti_settings_section_cancellation_callback() { }
function bookacti_settings_section_template_callback() { }
function bookacti_settings_section_bookings_callback() { }
function bookacti_settings_section_licenses_callback() { }
// BOOKINGS SETTINGS
@ -721,7 +722,7 @@ function bookacti_settings_section_bookings_callback() { }
/**
* Get all default messages
* @since 1.2.0
* @version 1.7.8
* @version 1.7.14
*/
function bookacti_get_default_messages() {
$wp_date_format_link = '<a href="https://wordpress.org/support/article/formatting-date-and-time/" target="_blank" >' . esc_html__( 'Formatting Date and Time', 'booking-activities' ) . '</a>';
@ -761,6 +762,26 @@ function bookacti_settings_section_bookings_callback() { }
'value' => esc_html__( 'Pick an event on the calendar:', 'booking-activities' ),
'description' => esc_html__( 'Instructions displayed before the calendar.', 'booking-activities' )
),
'selected_event' => array(
'value' => esc_html__( 'Selected event', 'booking-activities' ),
/* translators: %s can be either "singular" or "plural" */
'description' => sprintf( esc_html__( 'Title displayed before the selected events list (%s).', 'booking-activities' ), esc_html__( 'singular', 'booking-activities' ) )
),
'selected_events' => array(
'value' => esc_html__( 'Selected events', 'booking-activities' ),
'description' => sprintf( esc_html__( 'Title displayed before the selected events list (%s).', 'booking-activities' ), esc_html__( 'plural', 'booking-activities' ) )
),
'avail' => array(
/* translators: This particle is used right after the quantity of available bookings. Put the singular here. Ex: 1 avail. . */
'value' => esc_html_x( 'avail.', 'Short for availability [singular noun]', 'booking-activities' ),
/* translators: %s can be either "singular" or "plural" */
'description' => sprintf( esc_html__( 'Particle displayed after the number of available places onto the events (%s).', 'booking-activities' ), esc_html__( 'singular', 'booking-activities' ) )
),
'avails' => array(
/* translators: This particle is used right after the quantity of available bookings. Put the plural here. Ex: 2 avail. . */
'value' => esc_html_x( 'avail.', 'Short for availabilities [plural noun]', 'booking-activities' ),
'description' => sprintf( esc_html__( 'Particle displayed after the number of available places onto the events (%s).', 'booking-activities' ), esc_html__( 'plural', 'booking-activities' ) )
),
'booking_success' => array(
'value' => esc_html__( 'Your reservation has been processed!', 'booking-activities' ),
'description' => esc_html__( 'When a reservation has been successfully registered.', 'booking-activities' )

19
functions/functions-templates-forms-control.php

@ -162,7 +162,7 @@ function bookacti_format_activity_managers( $activity_managers = array() ) {
/**
* Format activity settings
* @version 1.7.13
* @version 1.7.14
* @param array $activity_settings
* @return array
*/
@ -170,7 +170,7 @@ function bookacti_format_activity_settings( $activity_settings ) {
if( empty( $activity_settings ) ) { $activity_settings = array(); }
// Default settings
$default_settings = apply_filters( 'bookacti_activity_default_settings', array(
$init_default_settings = array(
'unit_name_singular' => '',
'unit_name_plural' => '',
'show_unit_in_availability' => 0,
@ -180,7 +180,8 @@ function bookacti_format_activity_settings( $activity_settings ) {
'max_users_per_event' => 0,
'booking_changes_deadline' => -1,
'allowed_roles' => array()
) );
);
$default_settings = apply_filters( 'bookacti_activity_default_settings', $init_default_settings );
$settings = array();
foreach( $default_settings as $setting_key => $setting_default_value ){
@ -195,7 +196,7 @@ function bookacti_format_activity_settings( $activity_settings ) {
'int' => array( 'places_number', 'min_bookings_per_user', 'max_bookings_per_user', 'max_users_per_event', 'booking_changes_deadline' ),
'array' => array( 'allowed_roles' )
);
$settings = bookacti_sanitize_values( $default_settings, $settings, $keys_by_type );
$settings = bookacti_sanitize_values( $default_settings, $settings, $keys_by_type, array_diff_key( $settings, $init_default_settings ) );
return apply_filters( 'bookacti_activity_settings', $settings, $activity_settings, $default_settings );
}
@ -389,9 +390,8 @@ function bookacti_validate_group_category_data( $title ) {
/**
* Format group category data or apply default value
*
* @since 1.1.0
* @version 1.7.13
* @version 1.7.14
* @param array $category_settings
* @return array
*/
@ -399,14 +399,15 @@ function bookacti_format_group_category_settings( $category_settings ) {
if( empty( $category_settings ) ) { $category_settings = array(); }
// Default settings
$default_settings = apply_filters( 'bookacti_group_category_default_settings', array(
$init_default_settings = array(
'min_bookings_per_user' => 0,
'max_bookings_per_user' => 0,
'max_users_per_event' => 0,
'booking_changes_deadline' => -1,
'started_groups_bookable' => -1,
'allowed_roles' => array()
) );
);
$default_settings = apply_filters( 'bookacti_group_category_default_settings', $init_default_settings );
$settings = array();
@ -421,7 +422,7 @@ function bookacti_format_group_category_settings( $category_settings ) {
'int' => array( 'min_bookings_per_user', 'max_bookings_per_user', 'max_users_per_event', 'booking_changes_deadline', 'started_groups_bookable' ),
'array' => array( 'allowed_roles' )
);
$settings = bookacti_sanitize_values( $default_settings, $settings, $keys_by_type );
$settings = bookacti_sanitize_values( $default_settings, $settings, $keys_by_type, array_diff_key( $settings, $init_default_settings ) );
// started_groups_bookable
if( $settings[ 'started_groups_bookable' ] > 1 || $settings[ 'started_groups_bookable' ] < -1 ) { $settings[ 'started_groups_bookable' ] = $default_settings[ 'started_groups_bookable' ]; }

11
functions/functions-woocommerce.php

@ -846,7 +846,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
* Change cart item quantity to make them respect the booking restrictions (min booking per user, max...)
*
* @since 1.4.0
* @version 1.7.8
* @version 1.7.14
* @global woocommerce $woocommerce
* @param int $user_id
* @return void|int
@ -960,13 +960,14 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
}
// Check if the product has to be removed
if( $allowed_roles && ! apply_filters( 'bookacti_bypass_roles_check', false ) ) {
if( $allowed_roles && ! in_array( 'all', $allowed_roles, true ) && ! apply_filters( 'bookacti_bypass_roles_check', false ) ) {
$is_allowed = false;
$current_user = $user_id ? get_user_by( 'id', $user_id ) : wp_get_current_user();
if( $current_user ) {
$roles = $current_user->roles;
$is_allowed = array_intersect( $roles, $allowed_roles );
if( $current_user && ! empty( $current_user->roles ) ) {
$is_allowed = array_intersect( $current_user->roles, $allowed_roles );
}
if( ! $is_allowed ) {
$restricted_quantity = 0;
$message = '';

6
i18n-config.json

@ -1,4 +1,4 @@
{ "vendor": { "plugins/booking-activities": "1.7.7" },
{ "vendor": { "plugins/booking-activities": "1.7.14" },
"admin-config":{
"bookacti_calendars":{
"pages":{ "admin.php":"" },
@ -40,6 +40,10 @@
"bookacti_messages_settings_date_time_separator":{},
"bookacti_messages_settings_quantity_separator":{},
"bookacti_messages_settings_calendar_title":{},
"bookacti_messages_settings_selected_event":{},
"bookacti_messages_settings_selected_events":{},
"bookacti_messages_settings_avail":{},
"bookacti_messages_settings_avails":{},
"bookacti_messages_settings_booking_success":{},
"bookacti_messages_settings_booking_form_submit_button":{},
"bookacti_messages_settings_booking_form_new_booking_button":{},

15
js/booking-system-functions.js

@ -66,7 +66,7 @@ function bookacti_fetch_events( booking_system, interval ) {