Browse Source

** Booking Activities 1.7.17 **

* Tweak - Add a "All" option in activities and group categories selectboxes in Calendar fields settings
* Tweak - Remove the availability period settings from calendar editor. Set them in form editor, in the Calendar field settings.
* Tweak - You can use tags in email notifications titles
* Fix - Calendar managers were not removed if none were selected
* Fix - Check if the (groups of) event(s) is in its calendar range before booking
* Fix - Keep the first selected option when switching a selectbox from multiple to simple
* Fix - Avoid serialization problems while updating metadata
* Fix - Infinite calendar loading if the booking form redirects to an anchor
* Fix - Couldn't select groups of events in Bookings filters
* Fix - Feedback messages not displayed after adding a product to cart with a booking form with WooCommerce >= 3.9
* Fix - Inconsistent show / hide icon after updating the activity list in calendar editor
* Fix - Javascript error due to null activity duration or null event duration
* Dev - Refactor the Calendar field data and the booking system data to make them independent and more consistent
* Dev - Add JS hooks before booking form redirect and after add to cart
develop 1.7.17
yoan_cutillas 3 years ago
parent
commit
3abff70ad7
  1. 42
      booking-activities.php
  2. 4
      controller/controller-booking-system.php
  3. 59
      controller/controller-forms.php
  4. 14
      controller/controller-shortcodes.php
  5. 23
      controller/controller-templates.php
  6. 8
      controller/controller-woocommerce-backend.php
  7. 93
      controller/controller-woocommerce-forms.php
  8. 604
      functions/functions-booking-system.php
  9. 234
      functions/functions-forms.php
  10. 12
      functions/functions-global.php
  11. 5
      functions/functions-notifications.php
  12. 36
      functions/functions-templates-forms-control.php
  13. 95
      functions/functions-templates.php
  14. 33
      functions/functions-woocommerce.php
  15. 45
      js/backend-functions.js
  16. 2
      js/backend-functions.min.js
  17. 19
      js/booking-method-calendar.js
  18. 2
      js/booking-method-calendar.min.js
  19. 98
      js/booking-system-functions.js
  20. 2
      js/booking-system-functions.min.js
  21. 6
      js/bookings-dialogs.js
  22. 2
      js/bookings-dialogs.min.js
  23. 16
      js/bookings-functions.js
  24. 2
      js/bookings-functions.min.js
  25. 21
      js/form-editor-dialogs.js
  26. 2
      js/form-editor-dialogs.min.js
  27. 64
      js/form-editor.js
  28. 2
      js/form-editor.min.js
  29. 4
      js/forms.js
  30. 2
      js/forms.min.js
  31. 38
      js/templates-dialogs.js
  32. 2
      js/templates-dialogs.min.js
  33. 95
      js/templates-functions.js
  34. 2
      js/templates-functions.min.js
  35. 29
      js/templates.js
  36. 2
      js/templates.min.js
  37. 8
      js/woocommerce-backend.js
  38. 2
      js/woocommerce-backend.min.js
  39. 10
      js/woocommerce-frontend.js
  40. 2
      js/woocommerce-frontend.min.js
  41. 9
      js/woocommerce-global.js
  42. 2
      js/woocommerce-global.min.js
  43. 800
      languages/booking-activities.pot
  44. 72
      model/model-booking-system.php
  45. 13
      model/model-global.php
  46. 18
      readme.txt
  47. 14
      view/view-bookings.php
  48. 6
      view/view-landing.php
  49. 49
      view/view-templates-dialogs.php
  50. 16
      view/view-templates.php

42
booking-activities.php

@ -3,13 +3,13 @@
* 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.16
* Version: 1.7.17
* Author: Booking Activities Team
* Author URI: https://booking-activities.fr/en/?utm_source=plugin&utm_medium=plugin&utm_content=header
* Text Domain: booking-activities
* Domain Path: /languages/
* WC requires at least: 2.6
* WC tested up to: 3.8
* WC tested up to: 3.9
* License: GPL3
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
*
@ -40,7 +40,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// GLOBALS AND CONSTANTS
if( ! defined( 'BOOKACTI_VERSION' ) ) { define( 'BOOKACTI_VERSION', '1.7.16' ); }
if( ! defined( 'BOOKACTI_VERSION' ) ) { define( 'BOOKACTI_VERSION', '1.7.17' ); }
if( ! defined( 'BOOKACTI_PLUGIN_NAME' ) ) { define( 'BOOKACTI_PLUGIN_NAME', 'booking-activities' ); }
@ -470,6 +470,42 @@ function bookacti_update_removed_global_settings_in_1_7_16( $old_version ) {
add_action( 'bookacti_updated', 'bookacti_update_removed_global_settings_in_1_7_16' );
/**
* Remove the template settings removed in 1.7.17
* This function is temporary
* @since 1.7.17
* @global wpdb $wpdb
* @param string $old_version
*/
function bookacti_delete_removed_template_settings_in_1_7_17( $old_version ) {
// Do it only once, when Booking Activities is updated for the first time after 1.7.17
if( version_compare( $old_version, '1.7.17', '<' ) ) {
global $wpdb;
// Delete templates availability_period_start
$availability_period_start_deleted = $wpdb->delete(
BOOKACTI_TABLE_META,
array(
'object_type' => 'template',
'meta_key' => 'availability_period_start'
),
array( '%s', '%s' )
);
// Delete templates availability_period_end
$availability_period_end_deleted = $wpdb->delete(
BOOKACTI_TABLE_META,
array(
'object_type' => 'template',
'meta_key' => 'availability_period_end'
),
array( '%s', '%s' )
);
}
}
add_action( 'bookacti_updated', 'bookacti_delete_removed_template_settings_in_1_7_17' );
// ADMIN MENU

4
controller/controller-booking-system.php

@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Fetch events in order to display them
* @version 1.7.4
* @version 1.7.17
*/
function bookacti_controller_fetch_events() {
// Check nonce
@ -37,7 +37,7 @@ function bookacti_controller_fetch_events() {
if( $attributes[ 'groups_only' ] ) {
$groups_data = isset( $raw_attributes[ 'groups_data' ] ) ? (array) $raw_attributes[ 'groups_data' ] : array();
$groups_ids = $groups_data ? array_keys( $groups_data ) : array();
if( $groups_ids ) {
if( $groups_ids && ! in_array( 'none', $attributes[ 'group_categories' ], true ) ) {
$events = bookacti_fetch_grouped_events( $attributes[ 'calendars' ], $attributes[ 'activities' ], $groups_ids, $attributes[ 'group_categories' ], $attributes[ 'past_events' ], $events_interval );
}
} else if( $attributes[ 'bookings_only' ] ) {

59
controller/controller-forms.php

@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Display the form field 'calendar'
* @since 1.5.0
* @version 1.7.13
* @version 1.7.17
* @param array $field
* @param string $instance_id
* @param string $context
@ -35,8 +35,10 @@ function bookacti_display_form_field_calendar( $field, $instance_id, $context )
$field = apply_filters( 'bookacti_form_field_calendar_attributes', $field, $instance_id, $context );
$booking_system_atts = bookacti_get_calendar_field_booking_system_attributes( $field );
// Display the booking system
bookacti_get_booking_system( $field, true );
bookacti_get_booking_system( $booking_system_atts, true );
}
add_action( 'bookacti_display_form_field_calendar', 'bookacti_display_form_field_calendar', 10, 3 );
@ -887,7 +889,7 @@ add_action( 'admin_footer-booking-activities_page_bookacti_forms', 'bookacti_pri
/**
* Create a booking form from REQUEST parameters
* @since 1.5.0
* @version 1.6.0
* @version 1.7.17
*/
function bookacti_controller_create_form() {
if( empty( $_REQUEST[ 'action' ] ) || $_REQUEST[ 'action' ] !== 'new' ) { return; }
@ -902,16 +904,18 @@ function bookacti_controller_create_form() {
if( ! $form_id ) { esc_html_e( 'Error occurs when trying to create the form.', 'booking-activities' ); exit; }
// Insert calendar data (if any)
if( ! empty( $_REQUEST[ 'calendar_field' ] ) ) {
if( ! empty( $_REQUEST[ 'calendar_field' ] ) && is_array( $_REQUEST[ 'calendar_field' ] ) ) {
$default_calendar_meta = array();
if( isset( $_REQUEST[ 'calendar_field' ][ 'calendars' ] ) ) {
$template_data = bookacti_get_mixed_template_data( $_REQUEST[ 'calendar_field' ][ 'calendars' ], false );
$default_calendar_meta = $template_data[ 'settings' ];
$default_calendar_meta[ 'start' ] = $template_data[ 'start' ];
$default_calendar_meta[ 'end' ] = $template_data[ 'end' ];
if( ! empty( $_REQUEST[ 'calendar_field' ][ 'calendars' ] ) ) {
$calendar_ids = bookacti_ids_to_array( $_REQUEST[ 'calendar_field' ][ 'calendars' ] );
$template_data = bookacti_get_mixed_template_data( $calendar_ids, false );
$default_calendar_meta = $template_data[ 'settings' ];
}
$raw_calendar_meta = array_merge( $default_calendar_meta, $_REQUEST[ 'calendar_field' ] );
if( $raw_calendar_meta ) {
// $raw_calendar_meta will be sanitized in bookacti_update_form_field_meta
bookacti_update_form_field_meta( $raw_calendar_meta, 'calendar', $form_id );
}
$raw_calendar_meta = array_merge( array( 'start' => 'default', 'end' => 'default' ), $default_calendar_meta, $_REQUEST[ 'calendar_field' ] );
bookacti_update_form_field_meta( $raw_calendar_meta, 'calendar', $form_id );
}
// Change current url to the edit url
@ -1286,7 +1290,7 @@ add_action( 'wp_ajax_bookactiSaveFormFieldOrder', 'bookacti_controller_save_form
/**
* AJAX Controller - Update a field
* @since 1.5.0
* @version 1.5.4
* @version 1.7.17
*/
function bookacti_controller_update_form_field() {
// Check nonce
@ -1321,10 +1325,8 @@ function bookacti_controller_update_form_field() {
// Extract metadata only
$field_meta = array_intersect_key( $sanitized_data, bookacti_get_default_form_fields_meta( $field[ 'name' ] ) );
// Update field metadata
if( $field_meta ) {
// Unserialize values before preocessing through bookacti_update_metadata
foreach( $field_meta as $key => $value ) { $field_meta[ $key ] = maybe_unserialize( $value ); }
// Update field metadata
bookacti_update_metadata( 'form_field', $field_id, $field_meta );
}
@ -1333,7 +1335,7 @@ function bookacti_controller_update_form_field() {
// Get field data and HTML for editor
$field_data = bookacti_get_form_field_data( $field_id );
$field_html = bookacti_display_form_field_for_editor( $field_data, false );
bookacti_send_json( array( 'status' => 'success', 'field_data' => $field_data, 'field_html' => $field_html ), 'update_form_field' );
}
add_action( 'wp_ajax_bookactiUpdateFormField', 'bookacti_controller_update_form_field', 10 );
@ -1342,9 +1344,9 @@ add_action( 'wp_ajax_bookactiUpdateFormField', 'bookacti_controller_update_form_
/**
* AJAX Controller - Reset form meta
* @since 1.5.0
* @version 1.7.17
*/
function bookacti_controller_reset_form_field() {
$field_id = intval( $_POST[ 'field_id' ] );
$field = bookacti_get_form_field_data( $field_id );
$form_id = $field[ 'form_id' ];
@ -1361,7 +1363,6 @@ function bookacti_controller_reset_form_field() {
$updated = bookacti_update_form_field( $defaults_data );
if( $updated !== false ) {
// Delete all metadata to apply default
$defaults_meta = bookacti_get_default_form_fields_meta( $field[ 'name' ] );
if( $defaults_meta ) {
@ -1374,13 +1375,13 @@ function bookacti_controller_reset_form_field() {
$field_data = bookacti_get_form_field_data( $field_id );
$field_html = bookacti_display_form_field_for_editor( $field_data, false );
wp_send_json( array( 'status' => 'success', 'field_data' => $field_data, 'field_html' => $field_html ) );
bookacti_send_json( array( 'status' => 'success', 'field_data' => $field_data, 'field_html' => $field_html ), 'reset_form_field' );
} else {
wp_send_json( array( 'status' => 'failed', 'error' => 'not_updated' ) );
bookacti_send_json( array( 'status' => 'failed', 'error' => 'not_updated' ), 'reset_form_field' );
}
} else {
wp_send_json( array( 'status' => 'failed', 'error' => 'not_allowed' ) );
bookacti_send_json( array( 'status' => 'failed', 'error' => 'not_allowed' ), 'reset_form_field' );
}
}
add_action( 'wp_ajax_bookactiResetFormField', 'bookacti_controller_reset_form_field', 10 );
@ -1408,6 +1409,22 @@ function bookacti_reset_calendar_form_field_exceptions( $field_data ) {
add_action( 'bookacti_form_field_reset', 'bookacti_reset_calendar_form_field_exceptions', 10, 1 );
/**
* Add booking system data to calendar field data after updating the field data
* @since 1.7.17
* @param array $response
* @return array
*/
function bookacti_send_booking_system_attributes_to_js_after_calendar_field_update( $response ) {
if( $response[ 'status' ] === 'success' ) {
$response[ 'booking_system_attributes' ] = ! empty( $response[ 'field_data' ] ) ? bookacti_get_calendar_field_booking_system_attributes( $response[ 'field_data' ] ) : array();
}
return $response;
}
add_filter( 'bookacti_send_json_update_form_field', 'bookacti_send_booking_system_attributes_to_js_after_calendar_field_update', 10, 1 );
add_filter( 'bookacti_send_json_reset_form_field', 'bookacti_send_booking_system_attributes_to_js_after_calendar_field_update', 10, 1 );
/**
* Add the "Export" action to the "Calendar" field in form editor
* @version 1.6.0

14
controller/controller-shortcodes.php

@ -46,9 +46,7 @@ function bookacti_shortcode_calendar( $atts = array(), $content = null, $tag = '
/**
* Display a booking form via shortcode
* Eg: [bookingactivities_form form="Your form ID" id="Your form instance CSS ID"]
*
* @version 1.5.0
*
* @version 1.7.17
* @param array $atts [form, id]
* @param string $content
* @param string $tag Should be "bookingactivities_form"
@ -76,10 +74,12 @@ function bookacti_shortcode_booking_form( $atts = array(), $content = null, $tag
// Format form attributes
$atts = array();
$atts[ 'url' ] = ! empty( $atts[ 'url' ] ) ? esc_url( $atts[ 'url' ] ) : '';
$atts[ 'button' ] = ! empty( $atts[ 'button' ] ) ? esc_html( sanitize_text_field( $atts[ 'button' ] ) ) : bookacti_get_message( 'booking_form_submit_button' );
$atts[ 'id' ] = ! empty( $atts[ 'id' ] ) ? esc_attr( $atts[ 'id' ] ) : rand();
$atts = array_merge( $bs_atts, $atts );
$new_atts = array(
'url' => ! empty( $atts[ 'url' ] ) ? esc_url( $atts[ 'url' ] ) : '',
'button' => ! empty( $atts[ 'button' ] ) ? esc_html( sanitize_text_field( $atts[ 'button' ] ) ) : bookacti_get_message( 'booking_form_submit_button' ),
'id' => ! empty( $atts[ 'id' ] ) ? esc_attr( $atts[ 'id' ] ) : rand()
);
$atts = array_merge( $bs_atts, $new_atts );
$output = "<form action='" . $atts[ 'url' ] . "'
class='bookacti-booking-form'

23
controller/controller-templates.php

@ -749,7 +749,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Update template
* @version 1.7.10
* @version 1.7.17
*/
function bookacti_controller_update_template() {
$template_id = intval( $_POST['template-id'] );
@ -780,13 +780,10 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$template_settings = bookacti_format_template_settings( $_POST['templateOptions'] );
$updated_metadata = bookacti_update_metadata( 'template', $template_id, $template_settings );
}
$updated_managers = 0;
if( isset( $_POST['template-managers'] ) ) {
$managers_array = bookacti_ids_to_array( $_POST['template-managers'] );
$template_managers = bookacti_format_template_managers( $managers_array );
$updated_managers = bookacti_update_managers( 'template', $template_id, $template_managers );
}
$managers_array = isset( $_POST[ 'template-managers' ] ) ? bookacti_ids_to_array( $_POST[ 'template-managers' ] ) : array();
$template_managers = bookacti_format_template_managers( $managers_array );
$updated_managers = bookacti_update_managers( 'template', $template_id, $template_managers );
if( $updated_template > 0 || intval( $updated_managers ) > 0 || intval( $updated_metadata ) > 0 ) {
$templates_data = bookacti_get_templates_data( $template_id, true );
@ -868,7 +865,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Create a new activity
* @version 1.7.10
* @version 1.7.17
*/
function bookacti_controller_insert_activity() {
// Check nonce and capabilities
@ -883,7 +880,8 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$activity_title = sanitize_text_field( stripslashes( $_POST['activity-title'] ) );
$activity_color = function_exists( 'sanitize_hex_color' ) ? sanitize_hex_color( $_POST['activity-color'] ) : stripslashes( $_POST['activity-color'] );
$activity_availability = intval( $_POST['activity-availability'] );
$activity_duration = bookacti_sanitize_duration( $_POST['activity-duration'] );
$sanitized_duration = bookacti_sanitize_duration( $_POST['activity-duration'] );
$activity_duration = $sanitized_duration ? $sanitized_duration : '000.01:00:00';
$activity_resizable = intval( $_POST['activity-resizable'] );
$managers_array = isset( $_POST['activity-managers'] ) ? bookacti_ids_to_array( $_POST['activity-managers'] ) : array();
$options_array = isset( $_POST['activityOptions'] ) && is_array( $_POST['activityOptions'] ) ? $_POST['activityOptions'] : array();
@ -921,7 +919,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Update an activity
* @version 1.7.10
* @version 1.7.17
*/
function bookacti_controller_update_activity() {
$activity_id = intval( $_POST['activity-id'] );
@ -939,7 +937,8 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$activity_old_title = sanitize_text_field( stripslashes( $_POST['activity-old-title'] ) );
$activity_color = function_exists( 'sanitize_hex_color' ) ? sanitize_hex_color( $_POST['activity-color'] ) : stripslashes( $_POST['activity-color'] );
$activity_availability = intval( $_POST['activity-availability'] );
$activity_duration = bookacti_sanitize_duration( $_POST['activity-duration'] );
$sanitized_duration = bookacti_sanitize_duration( $_POST['activity-duration'] );
$activity_duration = $sanitized_duration ? $sanitized_duration : '000.01:00:00';
$activity_resizable = intval( $_POST['activity-resizable'] );
$managers_array = isset( $_POST['activity-managers'] ) ? bookacti_ids_to_array( $_POST['activity-managers'] ) : array();
$options_array = isset( $_POST['activityOptions'] ) && is_array( $_POST['activityOptions'] ) ? $_POST['activityOptions'] : array();

8
controller/controller-woocommerce-backend.php

@ -1420,7 +1420,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Migrate product or variation settings to a new booking form
* @since 1.5.0
* @version 1.7.16
* @version 1.7.17
*/
function bookacti_controller_migrate_product_settings_to_booking_form() {
$json_action = 'migrate_product_settings';
@ -1447,7 +1447,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// Format product meta
$booking_method = get_post_meta( $product_id, '_bookacti_booking_method', true );
$group_categories = get_post_meta( $product_id, '_bookacti_group_categories', true );
if( ! $group_categories ) { $group_categories = false; }
if( ! $group_categories ) { $group_categories = array( 'none' ); }
$product_booking_system_meta = array(
'method' => $booking_method,
'calendars' => get_post_meta( $product_id, '_bookacti_template', true ),
@ -1519,9 +1519,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// Insert calendar metadata
$template_data = bookacti_get_mixed_template_data( $booking_system_meta[ 'calendars' ], false );
$default_calendar_meta = $template_data[ 'settings' ];
$default_calendar_meta[ 'start' ] = $template_data[ 'start' ];
$default_calendar_meta[ 'end' ] = $template_data[ 'end' ];
$default_calendar_meta = $template_data[ 'settings' ];
$raw_calendar_field_meta = array_merge( $default_calendar_meta, $booking_system_meta );
$meta_updated = bookacti_update_form_field_meta( $raw_calendar_field_meta, 'calendar', $form_id );

93
controller/controller-woocommerce-forms.php

@ -87,6 +87,22 @@ function bookacti_default_wc_booking_system_attributes( $atts ) {
add_filter( 'bookacti_booking_system_default_attributes', 'bookacti_default_wc_booking_system_attributes', 10, 1 );
/**
* Set WC calendar form field meta
* @since 1.7.17
* @param array $default_meta
* @param string $field_name
* @return array
*/
function bookacti_default_wc_calendar_form_field_meta( $default_meta, $field_name = '' ) {
if( empty( $default_meta[ 'calendar' ] ) ) { $default_meta[ 'calendar' ] = array(); }
$default_meta[ 'calendar' ][ 'product_by_activity' ] = array();
$default_meta[ 'calendar' ][ 'product_by_group_category' ] = array();
return $default_meta;
}
add_filter( 'bookacti_default_form_fields_meta', 'bookacti_default_wc_calendar_form_field_meta', 10, 2 );
/**
* Add an icon before WC unsupported form field in form editor
* @since 1.5.0
@ -107,57 +123,79 @@ 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
* @version 1.7.17
* @param array $formatted_atts
* @param array $raw_atts
* @return array
*/
function bookacti_format_wc_booking_system_attributes( $atts ) {
function bookacti_format_wc_booking_system_attributes( $formatted_atts, $raw_atts ) {
$product_by_activity = array();
if( isset( $atts[ 'product_by_activity' ] ) && is_array( $atts[ 'product_by_activity' ] ) ) {
foreach( $atts[ 'product_by_activity' ] as $activity_id => $product_id ) {
if( isset( $raw_atts[ 'product_by_activity' ] ) && is_array( $raw_atts[ 'product_by_activity' ] ) ) {
foreach( $raw_atts[ 'product_by_activity' ] as $activity_id => $product_id ) {
if( ! is_numeric( $activity_id ) || ! is_numeric( $product_id )
|| empty( $activity_id ) || empty( $product_id )) { continue; }
$product_by_activity[ intval( $activity_id ) ] = intval( $product_id );
}
}
$atts[ 'product_by_activity' ] = $product_by_activity;
$formatted_atts[ 'product_by_activity' ] = $product_by_activity;
$product_by_group_category = array();
if( isset( $atts[ 'product_by_group_category' ] ) && is_array( $atts[ 'product_by_group_category' ] ) ) {
foreach( $atts[ 'product_by_group_category' ] as $group_category_id => $product_id ) {
if( isset( $raw_atts[ 'product_by_group_category' ] ) && is_array( $raw_atts[ 'product_by_group_category' ] ) ) {
foreach( $raw_atts[ 'product_by_group_category' ] as $group_category_id => $product_id ) {
if( ! is_numeric( $group_category_id ) || ! is_numeric( $product_id )
|| empty( $group_category_id ) || empty( $product_id ) ) { continue; }
$product_by_group_category[ intval( $group_category_id ) ] = intval( $product_id );
}
}
$atts[ 'product_by_group_category' ] = $product_by_group_category;
$formatted_atts[ 'product_by_group_category' ] = $product_by_group_category;
if( $atts[ 'form_action' ] === 'redirect_to_product_page' ) {
if( $formatted_atts[ 'form_action' ] === 'redirect_to_product_page' ) {
$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();
if( $products_ids ) {
foreach( $products_ids as $product_id ) {
$product = wc_get_product( $product_id );
if( ! $product ) { continue; }
$formatted_atts[ 'products_page_url' ][ $product_id ] = $product->get_permalink();
}
}
}
return $atts;
return $formatted_atts;
}
add_filter( 'bookacti_formatted_booking_system_attributes', 'bookacti_format_wc_booking_system_attributes', 10, 1 );
add_filter( 'bookacti_formatted_booking_system_attributes', 'bookacti_format_wc_booking_system_attributes', 10, 2 );
/**
* Sanitize WC booking system attributes
* @since 1.7.17
* @param array $field_data
* @param array $raw_field_data
* @return array
*/
function bookacti_format_wc_field_data( $field_data, $raw_field_data ) {
if( $raw_field_data[ 'name' ] === 'calendar' ) {
$default_meta = bookacti_default_wc_calendar_form_field_meta( array() );
$field_data[ 'product_by_activity' ] = isset( $raw_field_data[ 'product_by_activity' ] ) && is_array( $raw_field_data[ 'product_by_activity' ] ) ? bookacti_ids_to_array( $raw_field_data[ 'product_by_activity' ] ) : $default_meta[ 'product_by_activity' ];
$field_data[ 'product_by_group_category' ] = isset( $raw_field_data[ 'product_by_group_category' ] ) && is_array( $raw_field_data[ 'product_by_group_category' ] ) ? bookacti_ids_to_array( $raw_field_data[ 'product_by_group_category' ] ) : $default_meta[ 'product_by_group_category' ];
}
return $field_data;
}
add_filter( 'bookacti_formatted_field_data', 'bookacti_format_wc_field_data', 10, 2 );
/**
* Sanitize WC booking system attributes
* @since 1.7.0
* @version 1.7.17
* @param array $field_data
* @param array $raw_field_data
* @return array
*/
function bookacti_sanitize_wc_field_data( $field_data, $raw_field_data ) {
if( $raw_field_data[ 'name' ] === 'calendar' ) {
$field_data[ 'product_by_activity' ] = maybe_serialize( $field_data[ 'product_by_activity' ] );
$field_data[ 'product_by_group_category' ] = maybe_serialize( $field_data[ 'product_by_group_category' ] );
$default_meta = bookacti_default_wc_calendar_form_field_meta( array() );
$field_data[ 'product_by_activity' ] = isset( $raw_field_data[ 'product_by_activity' ] ) && is_array( $raw_field_data[ 'product_by_activity' ] ) ? bookacti_ids_to_array( $raw_field_data[ 'product_by_activity' ] ) : $default_meta[ 'product_by_activity' ];
$field_data[ 'product_by_group_category' ] = isset( $raw_field_data[ 'product_by_group_category' ] ) && is_array( $raw_field_data[ 'product_by_group_category' ] ) ? bookacti_ids_to_array( $raw_field_data[ 'product_by_group_category' ] ) : $default_meta[ 'product_by_group_category' ];
}
return $field_data;
}
@ -276,7 +314,7 @@ add_filter( 'bookacti_group_category_redirect_url_table', 'bookacti_add_wc_colum
/**
* Add the product bound to the selected event to cart
* @since 1.7.0
* @version 1.7.7
* @version 1.7.17
*/
function bookacti_controller_add_bound_product_to_cart() {
@ -387,10 +425,21 @@ function bookacti_controller_add_bound_product_to_cart() {
$form_url = bookacti_get_metadata( 'form', $form_id, 'redirect_url', true );
$redirect_url = $form_url ? esc_url( apply_filters( 'bookacti_translate_text', $form_url ) ) : $cart_url;
$messages_array = array();
if( ! empty( $wc_notices[ 'error' ] ) ) {
$response = array( 'status' => 'failed', 'messages' => implode( '</li><li>', $wc_notices[ 'error' ] ) );
if( version_compare( WC_VERSION, '3.9.0', '>=' ) ) {
foreach( $wc_notices[ 'error' ] as $wc_notice ) { $messages_array[] = $wc_notice[ 'notice' ]; }
} else {
$messages_array = $wc_notices[ 'error' ];
}
$response = array( 'status' => 'failed', 'messages' => implode( '</li><li>', $messages_array ) );
} else if( ! empty( $wc_notices[ 'success' ] ) ) {
$response = array( 'status' => 'success', 'messages' => implode( '</li><li>', $wc_notices[ 'success' ] ), 'redirect_url' => $redirect_url );
if( version_compare( WC_VERSION, '3.9.0', '>=' ) ) {
foreach( $wc_notices[ 'success' ] as $wc_notice ) { $messages_array[] = $wc_notice[ 'notice' ]; }
} else {
$messages_array = $wc_notices[ 'success' ];
}
$response = array( 'status' => 'success', 'messages' => implode( '</li><li>', $messages_array ), 'redirect_url' => $redirect_url );
} else {
$response = array( 'status' => 'failed', 'error' => 'unknown_error', 'messages' => esc_html__( 'An error occured while trying to add the product to cart.', 'booking-activities' ) );
}

604
functions/functions-booking-system.php

@ -84,7 +84,7 @@ function bookacti_get_booking_system( $atts, $echo = false ) {
/**
* Get booking system data
* @since 1.7.4
* @version 1.7.10
* @version 1.7.17
* @param array $atts (see bookacti_format_booking_system_attributes())
* @return array
*/
@ -93,12 +93,8 @@ function bookacti_get_booking_system_data( $atts ) {
// Events related data
if( $atts[ 'auto_load' ] ) {
if( empty( $atts[ 'template_data' ] ) ) {
$atts[ 'template_data' ] = bookacti_get_mixed_template_data( $atts[ 'calendars' ], $atts[ 'past_events' ] );
}
$events_interval = bookacti_get_new_interval_of_events( $atts[ 'template_data' ], array(), false, $atts[ 'past_events' ] );
$availability_period= array( 'start' => $atts[ 'start' ], 'end' => $atts[ 'end' ] );
$events_interval = bookacti_get_new_interval_of_events( $availability_period, array(), false, $atts[ 'past_events' ] );
$user_ids = array();
$groups_ids = array();
$groups_data = array();
@ -106,8 +102,8 @@ function bookacti_get_booking_system_data( $atts ) {
$groups_events = array();
$events = array( 'events' => array(), 'data' => array() );
if( $atts[ 'group_categories' ] !== false ) {
$groups_data = bookacti_get_groups_of_events( $atts[ 'calendars' ], $atts[ 'group_categories' ], $atts[ 'past_events_bookable' ], true, false, $atts[ 'template_data' ] );
if( ! in_array( 'none', $atts[ 'group_categories' ], true ) ) {
$groups_data = bookacti_get_groups_of_events( $atts[ 'calendars' ], $atts[ 'group_categories' ], $atts[ 'past_events_bookable' ] ? array() : $availability_period, true, false );
$categories_data = bookacti_get_group_categories( $atts[ 'calendars' ], $atts[ 'group_categories' ] );
foreach( $groups_data as $group_id => $group_data ) { $groups_ids[] = $group_id; }
@ -134,7 +130,6 @@ function bookacti_get_booking_system_data( $atts ) {
$booking_system_data[ 'groups_events' ] = $groups_events;
$booking_system_data[ 'groups_data' ] = $groups_data;
$booking_system_data[ 'group_categories_data' ] = $categories_data;
$booking_system_data[ 'template_data' ] = $atts[ 'template_data' ];
}
// Events picked by default
@ -270,59 +265,73 @@ function bookacti_retrieve_calendar_elements( $booking_system_atts ) {
/**
* Get default booking system attributes
* @since 1.5.0
* @version 1.7.0
* @version 1.7.17
* @return array
*/
function bookacti_get_booking_system_default_attributes() {
$timezone = bookacti_get_setting_value( 'bookacti_general_settings', 'timezone' );
$current_datetime = new DateTime( 'now', new DateTimeZone( $timezone ) );
return apply_filters( 'bookacti_booking_system_default_attributes', array(
'id' => '',
'class' => '',
'template_data' => array(),
'calendars' => array(),
'activities' => array(),
'group_categories' => false,
'groups_only' => 0,
'groups_single_events' => 0,
'bookings_only' => 0,
'status' => array(),
'user_id' => 0,
'method' => 'calendar',
'auto_load' => bookacti_get_setting_value( 'bookacti_general_settings', 'when_events_load' ) === 'on_page_load' ? 1 : 0,
'past_events' => 0,
'past_events_bookable' => 0,
'check_roles' => 1,
'picked_events' => array( 'group_id' => '', 'event_id' => '', 'event_start' => '', 'event_end' => '' ),
'id' => '',
'class' => '',
'calendars' => array(),
'activities' => array(),
'group_categories' => array( 'none' ),
'groups_only' => 0,
'groups_single_events' => 0,
'bookings_only' => 0,
'status' => array(),
'user_id' => 0,
'method' => 'calendar',
'auto_load' => bookacti_get_setting_value( 'bookacti_general_settings', 'when_events_load' ) === 'on_page_load' ? 1 : 0,
'start' => $current_datetime->format( 'Y-m-d' ),
'end' => '2037-12-31',
'past_events' => 0,
'past_events_bookable' => 0,
'check_roles' => 1,
'picked_events' => array( 'group_id' => '', 'event_id' => '', 'event_start' => '', 'event_end' => '' ),
'form_id' => 0,
'form_action' => 'default',
'when_perform_form_action' => 'on_submit',
'redirect_url_by_activity' => array(),
'redirect_url_by_group_category'=> array()
) );
'redirect_url_by_group_category'=> array(),
'display_data' => bookacti_get_booking_system_default_display_data()
));
}
/**
* Check booking system attributes and format them to be correct
* @version 1.7.16
* @param array $atts
* @version 1.7.17
* @param array $raw_atts
* @return array
*/
function bookacti_format_booking_system_attributes( $atts = array() ) {
function bookacti_format_booking_system_attributes( $raw_atts = array() ) {
// Set default value
$defaults = bookacti_get_booking_system_default_attributes();
// Replace empty mandatory values by default
$atts = shortcode_atts( $defaults, $atts );
// Make sure that all attributes are set (use default if not)
$atts = array();
foreach( $defaults as $name => $default ) {
$atts[ $name ] = isset( $raw_atts[ $name ] ) ? $raw_atts[ $name ] : $default;
}
foreach( $defaults[ 'picked_events' ] as $name => $default ) {
$atts[ 'picked_events' ][ $name ] = isset( $raw_atts[ 'picked_events' ][ $name ] ) ? $raw_atts[ 'picked_events' ][ $name ] : $default;
}
$formatted_atts = array();
// Sanitize booleans
$booleans_to_check = array( 'bookings_only', 'groups_only', 'groups_single_events', 'auto_load', 'past_events', 'past_events_bookable', 'check_roles' );
foreach( $booleans_to_check as $key ) {
$atts[ $key ] = in_array( $atts[ $key ], array( 1, '1', true, 'true', 'yes', 'ok' ), true ) ? 1 : 0;
$formatted_atts[ $key ] = in_array( $atts[ $key ], array( 1, '1', true, 'true', 'yes', 'ok' ), true ) ? 1 : 0;
}
// Format comma separated lists into arrays of integers
if( is_string( $atts[ 'calendars' ] ) || is_numeric( $atts[ 'calendars' ] ) ) {
$atts[ 'calendars' ] = array_map( 'intval', explode( ',', preg_replace( array(
// Calendars
$calendars = $atts[ 'calendars' ];
if( is_numeric( $atts[ 'calendars' ] ) ) {
$calendars = array_map( 'intval', explode( ',', preg_replace( array(
'/[^\d,]/', // Matches anything that's not a comma or number.
'/(?<=,),+/', // Matches consecutive commas.
'/^,+/', // Matches leading commas.
@ -330,11 +339,13 @@ function bookacti_format_booking_system_attributes( $atts = array() ) {
), '', $atts[ 'calendars' ] ) ) );
}
// Activities
$activities = $atts[ 'activities' ];
if( in_array( $atts[ 'activities' ], array( true, 'all', 'true', 'yes', 'ok' ), true ) ) {
$atts[ 'activities' ] = array();
$activities = array();
} else if( is_string( $atts[ 'activities' ] ) || is_numeric( $atts[ 'activities' ] ) ) {
$atts[ 'activities' ] = array_map( 'intval', explode( ',', preg_replace( array(
} else if( is_numeric( $atts[ 'activities' ] ) ) {
$activities = array_map( 'intval', explode( ',', preg_replace( array(
'/[^\d,]/', // Matches anything that's not a comma or number.
'/(?<=,),+/', // Matches consecutive commas.
'/^,+/', // Matches leading commas.
@ -342,154 +353,223 @@ function bookacti_format_booking_system_attributes( $atts = array() ) {
), '', $atts[ 'activities' ] ) ) );
}
// Group categories
$group_categories = $atts[ 'group_categories' ];
if( in_array( $atts[ 'group_categories' ], array( true, 'all', 'true', 'yes', 'ok' ), true ) ) {
$atts[ 'group_categories' ] = 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;
$group_categories = array();
} else if( is_string( $atts[ 'group_categories' ] ) || is_numeric( $atts[ 'group_categories' ] ) ) {
$atts[ 'group_categories' ] = array_map( 'intval', explode( ',', preg_replace( array(
} else if( is_numeric( $atts[ 'group_categories' ] ) ) {
$group_categories = array_map( 'intval', explode( ',', preg_replace( array(
'/[^\d,]/', // Matches anything that's not a comma or number.
'/(?<=,),+/', // Matches consecutive commas.
'/^,+/', // Matches leading commas.
'/,+$/' // Matches trailing commas.
), '', $atts[ 'group_categories' ] ) ) );
}
if( ! is_array( $atts[ 'group_categories' ] ) ) { $atts[ 'group_categories' ] = false; }
else { $atts[ 'group_categories' ] = array_values( array_unique( $atts[ 'group_categories' ] ) ); }
if( ! is_array( $atts[ 'group_categories' ] ) || in_array( $atts[ 'group_categories' ], array( false, 'none', 'false', 'no' ), true ) ) {
$group_categories = array( 'none' );
}
// Remove duplicated values
$atts[ 'calendars' ] = array_values( array_unique( $atts[ 'calendars' ] ) );
$atts[ 'activities' ] = array_values( array_unique( $atts[ 'activities' ] ) );
$calendars = array_values( array_unique( $calendars ) );
$activities = array_values( array_unique( $activities ) );
// Check if the desired templates are active and allowed
$available_template_ids = array_keys( bookacti_fetch_templates( array(), true ) );
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' ] = ! empty( $available_template_ids ) ? $available_template_ids : array( 'none' );
}
} else {
$allowed_templates = array_values( array_intersect( $atts[ 'calendars' ], $available_template_ids ) );
$atts[ 'calendars' ] = ! empty( $allowed_templates ) ? $allowed_templates : array( 'none' );
}
// Remove unauthorized templates
$had_templates = ! empty( $calendars );
$bypass_template_managers_check = apply_filters( 'bookacti_bypass_template_managers_check', false );
$allowed_templates = ! $bypass_template_managers_check && ! is_super_admin() ? array_values( array_intersect( $calendars, $available_template_ids ) ) : $calendars;
$formatted_atts[ 'calendars' ] = ! empty( $allowed_templates ) ? $allowed_templates : ( ! $had_templates && $available_template_ids ? $available_template_ids : 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' ] = ! $had_activities ? $available_activity_ids : array( 'none' ); }
else { $atts[ 'activities' ] = array_values( $atts[ 'activities' ] ); }
$available_activity_ids = bookacti_get_activity_ids_by_template( $formatted_atts[ 'calendars' ], false, $formatted_atts[ 'check_roles' ] );
// Remove unauthorized activities
$had_activities = ! empty( $activities );
$allowed_activities = array_values( array_intersect( $activities, array_map( 'intval', $available_activity_ids ) ) );
$formatted_atts[ 'activities' ] = ! empty( $allowed_activities ) ? $allowed_activities : ( ! $had_activities && $available_activity_ids ? $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' ] );
if( is_array( $atts[ 'group_categories' ] ) ) {
// Remove duplicated values
$atts[ 'group_categories' ] = array_unique( $atts[ 'group_categories' ] );
// Remove unauthorized values
$allowed_group_categories = array_values( array_intersect( $atts[ 'group_categories' ], array_map( 'intval', $available_category_ids ) ) );
$atts[ 'group_categories' ] = ! empty( $allowed_group_categories ) ? $allowed_group_categories : false;
$available_category_ids = bookacti_get_group_category_ids_by_template( $formatted_atts[ 'calendars' ], false, $formatted_atts[ 'check_roles' ] );
if( ! in_array( 'none', $group_categories, true ) ) {
$group_categories = array_values( array_unique( $group_categories ) );
// Remove unauthorized group categories
$had_group_categories = ! empty( $group_categories );
$allowed_group_categories = array_values( array_intersect( $group_categories, array_map( 'intval', $available_category_ids ) ) );
$group_categories = ! empty( $allowed_group_categories ) ? $allowed_group_categories : ( ! $had_group_categories && $available_category_ids ? $available_category_ids : array( 'none' ) );
}
$formatted_atts[ 'group_categories' ] = $group_categories;
// Format template data
if( ! empty( $atts[ 'template_data' ] ) && is_array( $atts[ 'template_data' ] ) ) {
$templates_data = bookacti_get_mixed_template_data( $atts[ 'calendars' ], $atts[ 'past_events' ] );
$atts[ 'template_data' ][ 'start' ] = ! empty( $atts[ 'template_data' ][ 'start' ] ) && bookacti_sanitize_date( $atts[ 'template_data' ][ 'start' ] ) ? bookacti_sanitize_date( $atts[ 'template_data' ][ 'start' ] ) : bookacti_sanitize_date( $templates_data[ 'start' ] );
$atts[ 'template_data' ][ 'end' ] = ! empty( $atts[ 'template_data' ][ 'end' ] ) && bookacti_sanitize_date( $atts[ 'template_data' ][ 'end' ] ) ? bookacti_sanitize_date( $atts[ 'template_data' ][ 'end' ] ) : bookacti_sanitize_date( $templates_data[ 'end' ] );
$atts[ 'template_data' ][ 'settings' ] = ! empty( $atts[ 'template_data' ][ 'settings' ] ) ? bookacti_format_template_settings( $atts[ 'template_data' ][ 'settings' ] ) : $templates_data[ 'settings' ];
}
// Format Start and End
$sanitized_start = bookacti_sanitize_date( $atts[ 'start' ] );
$sanitized_end = bookacti_sanitize_date( $atts[ 'end' ] );
$formatted_atts[ 'start' ] = $sanitized_start ? $sanitized_start : $defaults[ 'start' ];
$formatted_atts[ 'end' ] = $sanitized_end ? $sanitized_end : $defaults[ 'end' ];
// Format display data
$formatted_atts[ 'display_data' ] = is_array( $atts[ 'display_data' ] ) ? bookacti_format_booking_system_display_data( $atts[ 'display_data' ] ) : array();
// Check if desired booking method is registered
$atts[ 'method' ] = esc_attr( $atts[ 'method' ] );
$available_booking_methods = array_keys( bookacti_get_available_booking_methods() );
if( ! in_array( $atts[ 'method' ], $available_booking_methods, true ) ) {
$atts[ 'method' ] = in_array( $defaults[ 'method' ], $available_booking_methods, true ) ? $defaults[ 'method' ] : 'calendar';
}
$method = esc_attr( $atts[ 'method' ] );
$formatted_atts[ 'method' ] = in_array( $method, $available_booking_methods, true ) ? $method : ( in_array( $defaults[ 'method' ], $available_booking_methods, true ) ? $defaults[ 'method' ] : 'calendar' );
// Sanitize user id
$atts[ 'user_id' ] = is_numeric( $atts[ 'user_id' ] ) ? intval( $atts[ 'user_id' ] ) : esc_attr( $atts[ 'user_id' ] );
if( $atts[ 'user_id' ] === 'current' ) { $atts[ 'user_id' ] = get_current_user_id(); }
if( $atts[ 'user_id' ] && ! is_email( $atts[ 'user_id' ] ) && ( ! is_numeric( $atts[ 'user_id' ] ) || ( is_numeric( $atts[ 'user_id' ] ) && strlen( (string) $atts[ 'user_id' ] ) ) >= 16 ) ) { $atts[ 'user_id' ] = bookacti_decrypt( $atts[ 'user_id' ] ); }
$user_id = is_numeric( $atts[ 'user_id' ] ) ? intval( $atts[ 'user_id' ] ) : esc_attr( $atts[ 'user_id' ] );
if( $user_id === 'current' ) { $user_id = get_current_user_id(); }
if( $user_id && ! is_email( $user_id ) && ( ! is_numeric( $user_id ) || ( is_numeric( $user_id ) && strlen( (string) $user_id ) ) >= 16 ) ) { $user_id = bookacti_decrypt( $user_id ); }
$formatted_atts[ 'user_id' ] = $user_id;
// Sanitize booking status
if( is_string( $atts[ 'status' ] ) ) {
$atts[ 'status' ] = array_map( 'sanitize_title_with_dashes', explode( ',', preg_replace( array(
$status = $atts[ 'status' ];
if( is_string( $status ) ) {
$status = array_map( 'sanitize_title_with_dashes', explode( ',', preg_replace( array(
'/(?<=,),+/', // Matches consecutive commas.
'/^,+/', // Matches leading commas.
'/,+$/' // Matches trailing commas.
), '', $atts[ 'status' ] ) ) );
), '', $status ) ) );
}
// Check if desired status are registered
$available_booking_status = array_keys( bookacti_get_booking_state_labels() );
foreach( $atts[ 'status' ] as $i => $status ) {
if( ! in_array( $status, $available_booking_status, true ) ) {
unset( $atts[ 'status' ][ $i ] );
}
}
$formatted_atts[ 'status' ] = is_array( $status ) ? array_intersect( $status, array_keys( bookacti_get_booking_state_labels() ) ) : array();
// Give a random id if not supplied
if( empty( $atts[ 'id' ] ) ) {
$atts[ 'id' ] = rand();
}
if( substr( strval( $atts[ 'id' ] ), 0, 9 ) !== 'bookacti-' ) {
$atts[ 'id' ] = 'bookacti-booking-system-' . $atts[ 'id' ];
}
$atts[ 'id' ] = esc_attr( $atts[ 'id' ] );
// Prefix the ID with bookacti-booking-system-
$formatted_atts[ 'id' ] = empty( $atts[ 'id' ] ) || ! is_string( $atts[ 'id' ] ) ? rand() : ( substr( strval( $atts[ 'id' ] ), 0, 9 ) !== 'bookacti-' ? 'bookacti-booking-system-' . esc_attr( $atts[ 'id' ] ) : esc_attr( $atts[ 'id' ] ) );
// Format classes
$atts[ 'class' ] = ! empty( $atts[ 'class' ] ) ? esc_attr( $atts[ 'class' ] ) : '';
$formatted_atts[ 'class' ] = is_string( $atts[ 'class' ] ) ? esc_attr( $atts[ 'class' ] ) : $defaults[ 'class' ];
// Format picked events
$atts[ 'picked_events' ] = shortcode_atts( $defaults[ 'picked_events' ], $atts[ 'picked_events' ] );
$atts[ 'picked_events' ][ 'event_id' ] = $atts[ 'picked_events' ][ 'event_id' ] && is_numeric( $atts[ 'picked_events' ][ 'event_id' ] ) ? intval( $atts[ 'picked_events' ][ 'event_id' ] ) : '';
$atts[ 'picked_events' ][ 'event_start' ] = bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_start' ] ) ? bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_start' ] ) : $defaults[ 'picked_events' ][ 'event_start' ];
$atts[ 'picked_events' ][ 'event_end' ] = bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_end' ] ) ? bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_end' ] ) : $defaults[ 'picked_events' ][ 'event_end' ];
$atts[ 'picked_events' ][ 'group_id' ] = $atts[ 'picked_events' ][ 'group_id' ] && is_numeric( $atts[ 'picked_events' ][ 'group_id' ] ) ? intval( $atts[ 'picked_events' ][ 'group_id' ] ) : ( is_numeric( $atts[ 'picked_events' ][ 'event_id' ] ) ? 'single' : '' );
$formatted_atts[ 'picked_events' ] = array(
'event_id' => $atts[ 'picked_events' ][ 'event_id' ] && is_numeric( $atts[ 'picked_events' ][ 'event_id' ] ) ? intval( $atts[ 'picked_events' ][ 'event_id' ] ) : '',
'event_start' => bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_start' ] ) ? bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_start' ] ) : $defaults[ 'picked_events' ][ 'event_start' ],
'event_end' => bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_end' ] ) ? bookacti_sanitize_datetime( $atts[ 'picked_events' ][ 'event_end' ] ) : $defaults[ 'picked_events' ][ 'event_end' ],
'group_id' => $atts[ 'picked_events' ][ 'group_id' ] && is_numeric( $atts[ 'picked_events' ][ 'group_id' ] ) ? intval( $atts[ 'picked_events' ][ 'group_id' ] ) : ( is_numeric( $atts[ 'picked_events' ][ 'event_id' ] ) ? 'single' : '' )
);
// Sanitize form id
$atts[ 'form_id' ] = is_numeric( $atts[ 'form_id' ] ) ? intval( $atts[ 'form_id' ] ) : 0;
$formatted_atts[ 'form_id' ] = is_numeric( $atts[ 'form_id' ] ) ? intval( $atts[ 'form_id' ] ) : 0;
// Format actions
$possible_form_actions = array_keys( apply_filters( 'bookacti_form_action_options', array( 'default' => '', 'redirect_to_url' => '' ) ) );
$possible_form_triggers = array_keys( apply_filters( 'bookacti_when_perform_form_action_options', array( 'on_submit' => '', 'on_event_click' => '' ) ) );
$atts[ 'form_action' ] = in_array( $atts[ 'form_action' ], $possible_form_actions, true ) ? $atts[ 'form_action' ] : $defaults[ 'form_action' ];
$atts[ 'when_perform_form_action' ] = in_array( $atts[ 'when_perform_form_action' ], $possible_form_triggers, true ) ? $atts[ 'when_perform_form_action' ] : $defaults[ 'when_perform_form_action' ];
$possible_form_actions = array_keys( bookacti_get_available_form_actions() );
$possible_form_triggers = array_keys( bookacti_get_available_form_action_triggers() );
$formatted_atts[ 'form_action' ] = in_array( $atts[ 'form_action' ], $possible_form_actions, true ) ? $atts[ 'form_action' ] : $defaults[ 'form_action' ];
$formatted_atts[ 'when_perform_form_action' ] = in_array( $atts[ 'when_perform_form_action' ], $possible_form_triggers, true ) ? $atts[ 'when_perform_form_action' ] : $defaults[ 'when_perform_form_action' ];
$redirect_url_by_group_activity = $defaults[ 'redirect_url_by_activity' ];
if( isset( $atts[ 'redirect_url_by_activity' ] ) && is_array( $atts[ 'redirect_url_by_activity' ] ) ) {
$redirect_url_by_group_activity = array();
if( is_array( $atts[ 'redirect_url_by_activity' ] ) ) {
foreach( $atts[ 'redirect_url_by_activity' ] as $activity_id => $redirect_url ) {
if( ! is_numeric( $activity_id ) || empty( $redirect_url ) ) { continue; }
$redirect_url_by_group_activity[ intval( $activity_id ) ] = esc_url_raw( $redirect_url );
}
}
$atts[ 'redirect_url_by_activity' ] = $redirect_url_by_group_activity;
$formatted_atts[ 'redirect_url_by_activity' ] = $redirect_url_by_group_activity ? $redirect_url_by_group_activity : $defaults[ 'redirect_url_by_activity' ];
$redirect_url_by_group_category = $defaults[ 'redirect_url_by_group_category' ];
if( isset( $atts[ 'redirect_url_by_group_category' ] ) && is_array( $atts[ 'redirect_url_by_group_category' ] ) ) {
$redirect_url_by_group_category = array();
if( is_array( $atts[ 'redirect_url_by_group_category' ] ) ) {
foreach( $atts[ 'redirect_url_by_group_category' ] as $group_category_id => $redirect_url ) {
if( ! is_numeric( $group_category_id ) || empty( $redirect_url ) ) { continue; }
$redirect_url_by_group_category[ intval( $group_category_id ) ] = esc_url_raw( $redirect_url );
}
}
$atts[ 'redirect_url_by_group_category' ] = $redirect_url_by_group_category;
$formatted_atts[ 'redirect_url_by_group_category' ] = $redirect_url_by_group_category ? $redirect_url_by_group_category : $defaults[ 'redirect_url_by_group_category' ];
return apply_filters( 'bookacti_formatted_booking_system_attributes', $formatted_atts, $raw_atts );
}
/**
* Get booking system attributes from calendar field data
* @since 1.7.17
* @param array|int $calendar_field
* @return array
*/
function bookacti_get_calendar_field_booking_system_attributes( $calendar_field ) {
if( is_numeric( $calendar_field ) ) { $calendar_field = bookacti_get_form_field_data( $calendar_field ); }
if( ! is_array( $calendar_field ) ) { $calendar_field = array(); }
// Compute availability period
$availability_period = bookacti_get_calendar_field_availability_period( $calendar_field );
// Isolate display data
$display_data = array_intersect_key( $calendar_field, bookacti_get_booking_system_default_display_data() );
return apply_filters( 'bookacti_formatted_booking_system_attributes', $atts );
// Transform the Calendar field settings to Booking system attributes
$booking_system_atts_raw= array_merge( $calendar_field, $availability_period, array( 'display_data' => $display_data ) );
$booking_system_atts = bookacti_format_booking_system_attributes( $booking_system_atts_raw );
return apply_filters( 'bookacti_calendar_field_booking_system_attributes', $booking_system_atts, $calendar_field );
}
/**
* Get booking system default display data
* @since 1.7.17
* @return array
*/
function bookacti_get_booking_system_default_display_data() {
return apply_filters( 'bookacti_booking_system_default_display_data', array(
'minTime' => '00:00',
'maxTime' => '00:00'
));
}
/**
* Format booking system display data
* @since 1.7.17
* @param array $raw_display_data
* @return array
*/
function bookacti_format_booking_system_display_data( $raw_display_data ) {
// Get the default values
$default_data = bookacti_get_booking_system_default_display_data();
$display_data = array();
// Make sure that all data are set
foreach( $default_data as $key => $default_value ){
if( isset( $raw_display_data[ $key ] ) && is_string( $raw_display_data[ $key ] ) ) { $display_data[ $key ] = stripslashes( $raw_display_data[ $key ] ); }
else if( ! isset( $raw_display_data[ $key ] ) ) { $display_data[ $key ] = $default_value; }
}
// Format 24-h times: minTime and maxTime
if( ! preg_match( '/^([0-1][0-9]|2[0-3]):([0-5][0-9])$/', $display_data[ 'minTime' ] ) ){ $display_data[ 'minTime' ] = $default_data[ 'minTime' ]; }
if( ! preg_match( '/^([0-1][0-9]|2[0-3]):([0-5][0-9])$/', $display_data[ 'maxTime' ] ) ){ $display_data[ 'maxTime' ] = $default_data[ 'maxTime' ]; }
// Make sure minTime is before maxTime
// If maxTime is 00:xx change it to 24:xx
if( $display_data[ 'maxTime' ] === '00:00' ) { $display_data[ 'maxTime' ] = '24:00'; }
// If minTime >= maxTime, permute values
if( intval( substr( $display_data[ 'minTime' ], 0, 2 ) ) >= substr( $display_data[ 'maxTime' ], 0, 2 ) ) {
$temp_max = $display_data[ 'maxTime' ];
$display_data[ 'maxTime' ] = $display_data[ 'minTime' ];
$display_data[ 'minTime' ] = $temp_max;
}
return apply_filters( 'bookacti_formatted_booking_system_display_data', $display_data, $raw_display_data );
}
/**
* Sanitize booking system display data
* @since 1.7.17
* @param array $raw_display_data
* @return array
*/
function bookacti_sanitize_booking_system_display_data( $raw_display_data ) {
// Sanitizing these values happens to be the same process as formatting for now, but it may not always be true
$display_data = bookacti_format_booking_system_display_data( $raw_display_data );
return apply_filters( 'bookacti_sanitized_booking_system_display_data', $display_data, $raw_display_data );
}
/**
* Format booking system attributes passed via the URL
* @since 1.6.0
* @version 1.7.10
* @version 1.7.17
* @param array $atts
* @return array
*/
@ -512,33 +592,28 @@ function bookacti_format_booking_system_url_attributes( $atts = array() ) {
$atts[ 'past_events_bookable' ] = $atts[ 'past_events' ];
$url_raw_atts[ 'past_events_bookable' ] = $atts[ 'past_events' ];
// If the 'past_events' value changed, reset the template dates to compute them again later with bookacti_format_booking_system_attributes
// If the 'past_events' value changed, reset the template dates
if( $atts[ 'past_events' ] && ! $was_past_events ) {
$url_raw_atts[ 'template_data' ][ 'start' ] = '';
$url_raw_atts[ 'template_data' ][ 'end' ] = '';
$url_raw_atts[ 'start' ] = '';
$url_raw_atts[ 'end' ] = '';
}
}
// Format the URL attributes
if( ! empty( $url_raw_atts[ 'start' ] ) || ! empty( $url_raw_atts[ 'end' ] ) ) {
$timezone = new DateTimeZone( bookacti_get_setting_value( 'bookacti_general_settings', 'timezone' ) );
if( ! empty( $url_raw_atts[ 'start' ] ) && (bool)strtotime( $url_raw_atts[ 'start' ] ) ) {
$from_datetime = new DateTime( $url_raw_atts[ 'start' ], $timezone );
$url_raw_atts[ 'template_data' ][ 'start' ] = $from_datetime->format( 'Y-m-d' );
}
if( ! empty( $url_raw_atts[ 'end' ] ) && (bool)strtotime( $url_raw_atts[ 'end' ] ) ) {
$to_datetime = new DateTime( $url_raw_atts[ 'end' ], $timezone );
$url_raw_atts[ 'template_data' ][ 'end' ] = $to_datetime->format( 'Y-m-d' );
}
$timezone = new DateTimeZone( bookacti_get_setting_value( 'bookacti_general_settings', 'timezone' ) );
if( ! empty( $url_raw_atts[ 'start' ] ) && (bool)strtotime( $url_raw_atts[ 'start' ] ) ) {
$from_datetime = new DateTime( $url_raw_atts[ 'start' ], $timezone );
$url_raw_atts[ 'start' ] = $from_datetime->format( 'Y-m-d' );
}
$default_template_settings = bookacti_format_template_settings( array() );
foreach( $default_template_settings as $att_name => $att_value ) {
if( ! isset( $url_raw_atts[ $att_name ] ) || ( ! $url_raw_atts[ $att_name ] && ! in_array( $url_raw_atts[ $att_name ], array( 0, '0' ), true ) ) ) { continue; }
$url_raw_atts[ 'template_data' ][ 'settings' ][ $att_name ] = $url_raw_atts[ $att_name ];
if( ! empty( $url_raw_atts[ 'end' ] ) && (bool)strtotime( $url_raw_atts[ 'end' ] ) ) {
$to_datetime = new DateTime( $url_raw_atts[ 'end' ], $timezone );
$url_raw_atts[ 'end' ] = $to_datetime->format( 'Y-m-d' );
}
$url_atts = bookacti_format_booking_system_attributes( $url_raw_atts );
// Isolate display data
$display_data = array_intersect_key( $url_raw_atts, bookacti_get_booking_system_default_display_data() );
$url_atts = bookacti_format_booking_system_attributes( array_merge( $url_raw_atts, array( 'display_data' => $display_data ) ) );
// Replace booking system attributes with attributes passed through the URL
foreach( $default_atts as $att_name => $att_value ) {
@ -546,14 +621,6 @@ function bookacti_format_booking_system_url_attributes( $atts = array() ) {
if( $att_name === 'past_events' && $url_raw_atts[ 'past_events' ] === 'auto' ) { continue; }
$atts[ $att_name ] = $url_atts[ $att_name ];
}
foreach( $url_atts[ 'template_data' ] as $att_name => $att_value ) {
if( $att_name === 'settings' ) { continue; }
$atts[ 'template_data' ][ $att_name ] = $att_value;
}
foreach( $default_template_settings as $att_name => $att_value ) {
if( ! isset( $url_raw_atts[ $att_name ] ) || ( ! $url_raw_atts[ $att_name ] && ! in_array( $url_raw_atts[ $att_name ], array( 0, '0' ), true ) ) ) { continue; }
$atts[ 'template_data' ][ 'settings' ][ $att_name ] = $url_atts[ 'template_data' ][ 'settings' ][ $att_name ];
}
return apply_filters( 'bookacti_format_booking_system_url_attributes', $atts );
}
@ -562,12 +629,11 @@ function bookacti_format_booking_system_url_attributes( $atts = array() ) {
/**
* Get booking system fields default data
* @since 1.5.0
* @version 1.7.16
* @version 1.7.17
* @param array $fields
* @return array
*/
function bookacti_get_booking_system_fields_default_data( $fields = array() ) {
if( ! is_array( $fields ) ) { $fields = array(); }
$defaults = array();
@ -596,7 +662,7 @@ function bookacti_get_booking_system_fields_default_data( $fields = array() ) {
if( ! $fields || in_array( 'activities', $fields, true ) ) {
// Format activity options array
$activities = bookacti_fetch_activities_with_templates_association();
$activities_options = array();
$activities_options = array( 'all' => esc_html__( 'All', 'booking-activities' ) );
$activities_options_attr = array();
foreach( $activities as $activity ) {
$activities_options[ $activity[ 'id' ] ] = apply_filters( 'bookacti_translate_text', $activity[ 'title' ] );
@ -619,7 +685,7 @@ function bookacti_get_booking_system_fields_default_data( $fields = array() ) {
if( ! $fields || in_array( 'group_categories', $fields, true ) ) {
// Format group category options array
$categories = bookacti_get_group_categories();
$category_options = array( 'none' => _x( 'None', 'About group category', 'booking-activities' ) );
$category_options = array( 'all' => esc_html__( 'All', 'booking-activities' ), 'none' => esc_html_x( 'None', 'About group category', 'booking-activities' ) );
$category_options_attr = array();
foreach( $categories as $category ) {
$category_options[ $category[ 'id' ] ] = apply_filters( 'bookacti_translate_text', $category[ 'title' ] );
@ -676,7 +742,7 @@ function bookacti_get_booking_system_fields_default_data( $fields = array() ) {
if( ! $fields || in_array( 'status', $fields, true ) ) {
// Format status array
$statuses = bookacti_get_booking_state_labels();
$status_options = array( 'none' => _x( 'None', 'About booking status', 'booking-activities' ) );
$status_options = array( 'none' => esc_html__( 'All', 'booking-activities' ) );
foreach ( $statuses as $status_id => $status ) {
$status_options[ $status_id ] = esc_html( $status[ 'label' ] );
}
@ -699,8 +765,8 @@ function bookacti_get_booking_system_fields_default_data( $fields = array() ) {
'options' => array(
'name' => 'user_id',
'id' => 'user_id',
'show_option_all' => __( 'None', 'booking-activities' ),
'show_option_current' => __( 'Current user', 'booking-activities' ),
'show_option_all' => esc_html__( 'All', 'booking-activities' ),
'show_option_current' => esc_html__( 'Current user', 'booking-activities' ),
'option_label' => array( 'user_login', ' (', 'user_email', ')' ),
'selected' => 0,
'echo' => true
@ -1139,7 +1205,7 @@ function bookacti_is_existing_group_of_events( $group ) {
/**
* Check if an event can be book with the given form
* @since 1.5.0
* @version 1.7.8
* @version 1.7.17
* @param int $form_id
* @param int $event_id
* @param string $event_start
@ -1153,8 +1219,8 @@ function bookacti_is_event_available_on_form( $form_id, $event_id, $event_start,
// Check if the form exists and if it has a calendar field (compulsory)
$form_exists = ! empty( $calendar_data );
if( ! $form_exists ) {
$validated['error'] = 'invalid_form';
$validated['message'] = __( 'Failed to retrieve the requested form data.', 'booking-activities' );
$validated[ 'error' ] = 'invalid_form';
$validated[ 'message' ] = esc_html__( 'Failed to retrieve the requested form data.', 'booking-activities' );
return $validated;
}
@ -1167,14 +1233,14 @@ function bookacti_is_event_available_on_form( $form_id, $event_id, $event_start,
if( ( $calendar_data[ 'calendars' ] && ! in_array( $event->template_id, $calendar_data[ 'calendars' ] ) )
|| ( $calendar_data[ 'activities' ] && ! in_array( $event->activity_id, $calendar_data[ 'activities' ] ) ) ) {
$belongs_to_form = false;
$validated['message'] = __( 'The selected event is not supposed to be available on this form.', 'booking-activities' );
$validated[ 'message' ] = esc_html__( 'The selected event is not supposed to be available on this form.', 'booking-activities' );
}
// If the form calendar have groups, with no possibility to book a single event
if( $belongs_to_form && $calendar_data[ 'group_categories' ] !== false && ! $calendar_data[ 'groups_single_events' ] ) {
if( $belongs_to_form && ! in_array( 'none', $calendar_data[ 'group_categories' ], true ) && ! $calendar_data[ 'groups_single_events' ] ) {
if( $calendar_data[ 'groups_only' ] ) {
$belongs_to_form = false;
$validated['message'] = __( 'You cannot book single events with this form, you must select a group of events.', 'booking-activities' );
$validated[ 'message' ] = esc_html__( 'You cannot book single events with this form, you must select a group of events.', 'booking-activities' );
} else {
// Check if the event belong to a group
$event_groups = bookacti_get_event_groups( $event->event_id, $event_start, $event_end );
@ -1186,20 +1252,39 @@ function bookacti_is_event_available_on_form( $form_id, $event_id, $event_start,
}
// If the categories array is empty, it means "take all categories"
if( is_array( $calendar_data[ 'group_categories' ] ) && empty( $calendar_data[ 'group_categories' ] ) ) {
if( empty( $calendar_data[ 'group_categories' ] ) ) {
$calendar_data[ 'group_categories' ] = array_keys( bookacti_get_group_categories( $event->template_id ) );
}
// Check if the event belong to a group available on the calendar
if( array_intersect( $event_categories, $calendar_data[ 'group_categories' ] ) ) {
$belongs_to_form = false;
$validated['message'] = __( 'The selected event is part of a group and cannot be booked alone.', 'booking-activities' );
$validated[ 'message' ] = esc_html__( 'The selected event is part of a group and cannot be booked alone.', 'booking-activities' );
}
}
}
// Check if the groups of events is in its template range
if( $belongs_to_form ) {
$in_template_range = false;
$template_range = bookacti_get_mixed_template_range( $event->template_id );
if( $template_range ) {
$event_start_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $event_start );
$event_end_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $event_end );
$template_start_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $template_range[ 'start' ] . ' 00:00:00' );
$template_end_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $template_range[ 'end' ] . ' 23:59:59' );
if( $event_start_dt >= $template_start_dt && $event_end_dt <= $template_end_dt ) {
$in_template_range = true;
}
}
if( ! $in_template_range ) {
$belongs_to_form = false;
$validated[ 'message' ] = esc_html__( 'The event is out of its calendar range, please pick another event and try again.', 'booking-activities' );
}
}
if( ! $belongs_to_form ) {
$validated['error'] = 'event_not_in_form';
$validated[ 'error' ] = 'event_not_in_form';
return $validated;
}
@ -1214,28 +1299,28 @@ function bookacti_is_event_available_on_form( $form_id, $event_id, $event_start,
$current_time = new DateTime( 'now', $timezone );
if( ( $event_start_obj < $current_time )
&& ! ( $started_events_bookable && $event_end_obj > $current_time ) ) {
$validated['error'] = 'past_event';
$validated['message'] = esc_html__( 'You cannot book a past event.', 'booking-activities' );
$validated[ 'error' ] = 'past_event';
$validated[ 'message' ] = esc_html__( 'You cannot book a past event.', 'booking-activities' );
return $validated;
}
// Check if the event is in the availability period
$availability_period = bookacti_get_availability_period( $calendar_data[ 'template_data' ], $past_events_bookable );
$availability_period = bookacti_get_calendar_field_availability_period( $calendar_data );
$calendar_start = new DateTime( $availability_period[ 'start' ] . ' 00:00:00', $timezone );
$calendar_end = new DateTime( $availability_period[ 'end' ] . ' 23:59:59', $timezone );
if( $event_start_obj < $calendar_start ) {
$validated['error'] = 'event_starts_before_availability_period';
$validated[ 'error' ] = 'event_starts_before_availability_period';
$datetime_formatted = bookacti_format_datetime( $calendar_start->format( 'Y-m-d H:i:s' ), esc_html__( 'F d, Y', 'booking-activities' ) );
/* translators: %s is a formatted date (e.g.: "January 20, 2018") */
$validated['message'] = sprintf( esc_html__( 'You cannot book an event that starts before %s.', 'booking-activities' ), $datetime_formatted );
$validated[ 'message' ] = sprintf( esc_html__( 'You cannot book an event that starts before %s.', 'booking-activities' ), $datetime_formatted );
return $validated;
}
if( $event_end_obj > $calendar_end ) {
$validated['error'] = 'event_ends_after_availability_period';
$validated[ 'error' ] = 'event_ends_after_availability_period';
$datetime_formatted = bookacti_format_datetime( $calendar_end->format( 'Y-m-d H:i:s' ), esc_html__( 'F d, Y', 'booking-activities' ) );
/* translators: %s is a formatted date (e.g.: "January 20, 2018") */
$validated['message'] = sprintf( esc_html__( 'You cannot book an event that takes place after %s.', 'booking-activities' ), $datetime_formatted );
$validated[ 'message' ] = sprintf( esc_html__( 'You cannot book an event that takes place after %s.', 'booking-activities' ), $datetime_formatted );
return $validated;
}
}
@ -1249,7 +1334,7 @@ function bookacti_is_event_available_on_form( $form_id, $event_id, $event_start,
/**
* Check if a group of events can be book with the given form
* @since 1.5.0
* @version 1.7.8
* @version 1.7.17
* @param int $form_id
* @param int $group_id
* @return array
@ -1261,8 +1346,8 @@ function bookacti_is_group_of_events_available_on_form( $form_id, $group_id ) {
// Check if the form exists and if it has a calendar field (compulsory)
$form_exists = ! empty( $calendar_data );
if( ! $form_exists ) {
$validated['error'] = 'invalid_form';
$validated['message'] = __( 'Failed to retrieve the requested form data.', 'booking-activities' );
$validated[ 'error' ] = 'invalid_form';
$validated[ 'message' ] = esc_html__( 'Failed to retrieve the requested form data.', 'booking-activities' );
return $validated;
}
@ -1275,17 +1360,17 @@ function bookacti_is_group_of_events_available_on_form( $form_id, $group_id ) {
// If the form calendar doesn't have the group of events' template
if( $calendar_data[ 'calendars' ] && ! in_array( $category[ 'template_id' ], $calendar_data[ 'calendars' ] ) ) {
$belongs_to_form = false;
$validated['message'] = __( 'The selected events are not supposed to be available on this form.', 'booking-activities' );
$validated[ 'message' ] = esc_html__( 'The selected events are not supposed to be available on this form.', 'booking-activities' );
}
// If the form calendar doesn't have groups
if( $belongs_to_form && $calendar_data[ 'group_categories' ] === false ) {
if( $belongs_to_form && in_array( 'none', $calendar_data[ 'group_categories' ], true ) ) {
$belongs_to_form = false;
$validated['message'] = __( 'You cannot book groups of events with this form, you must select a single event.', 'booking-activities' );
$validated[ 'message' ] = esc_html__( 'You cannot book groups of events with this form, you must select a single event.', 'booking-activities' );
}
// If the form calendar have groups
if( $belongs_to_form && is_array( $calendar_data[ 'group_categories' ] ) ) {
if( $belongs_to_form && ! in_array( 'none', $calendar_data[ 'group_categories' ], true ) ) {
// If the categories array is empty, it means "take all categories"
if( empty( $calendar_data[ 'group_categories' ] ) ) {
$calendar_data[ 'group_categories' ] = array_keys( bookacti_get_group_categories( $category[ 'template_id' ] ) );
@ -1294,12 +1379,31 @@ function bookacti_is_group_of_events_available_on_form( $form_id, $group_id ) {
// Check if the group of event category is available on this form
if( ! in_array( $group->category_id, $calendar_data[ 'group_categories' ] ) ) {
$belongs_to_form = false;
$validated['message'] = __( 'The selected goup of events is not supposed to be available on this form.', 'booking-activities' );
$validated[ 'message' ] = esc_html__( 'The selected goup of events is not supposed to be available on this form.', 'booking-activities' );
}
}
// Check if the groups of events is in its template range
if( $belongs_to_form ) {
$in_template_range = false;
$template_range = bookacti_get_mixed_template_range( $category[ 'template_id' ] );
if( $template_range ) {
$event_start_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $group->start );
$event_end_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $group->end );
$template_start_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $template_range[ 'start' ] . ' 00:00:00' );
$template_end_dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $template_range[ 'end' ] . ' 23:59:59' );
if( $event_start_dt >= $template_start_dt && $event_end_dt <= $template_end_dt ) {
$in_template_range = true;
}
}
if( ! $in_template_range ) {
$belongs_to_form = false;
$validated[ 'message' ] = esc_html__( 'The group of events is out of its calendar range, please pick another event and try again.', 'booking-activities' );
}
}
if( ! $belongs_to_form ) {
$validated['error'] = 'event_not_in_form';
$validated[ 'error' ] = 'event_not_in_form';
return $validated;
}
@ -1314,28 +1418,28 @@ function bookacti_is_group_of_events_available_on_form( $form_id, $group_id ) {
$current_time = new DateTime( 'now', $timezone );
if( ( $group_start < $current_time )
&& ! ( $started_groups_bookable && $group_end > $current_time ) ) {
$validated['error'] = 'past_group_of_events';
$validated['message'] = esc_html__( 'You cannot book a group of events if any of its events is past.', 'booking-activities' );
$validated[ 'error' ] = 'past_group_of_events';
$validated[ 'message' ] = esc_html__( 'You cannot book a group of events if any of its events is past.', 'booking-activities' );
return $validated;
}
// Check if the group of events is in the availability period
$availability_period = bookacti_get_availability_period( $calendar_data[ 'template_data' ], $past_events_bookable );
$availability_period = bookacti_get_calendar_field_availability_period( $calendar_data );
$calendar_start = new DateTime( $availability_period[ 'start' ] . ' 00:00:00', $timezone );
$calendar_end = new DateTime( $availability_period[ 'end' ] . ' 23:59:59', $timezone );
if( $group_start < $calendar_start ) {
$validated['error'] = 'group_of_events_starts_before_availability_period';
$validated[ 'error' ] = 'group_of_events_starts_before_availability_period';
$datetime_formatted = bookacti_format_datetime( $calendar_start->format( 'Y-m-d H:i:s' ), esc_html__( 'F d, Y', 'booking-activities' ) );
/* translators: %s is a formatted date (e.g.: "January 20, 2018") */
$validated['message'] = sprintf( esc_html__( 'You cannot book a group if any of its events starts before %s.', 'booking-activities' ), $datetime_formatted );
$validated[ 'message' ] = sprintf( esc_html__( 'You cannot book a group if any of its events starts before %s.', 'booking-activities' ), $datetime_formatted );
return $validated;
}
if( $group_end > $calendar_end ) {
$validated['error'] = 'group_of_events_ends_after_availability_period';
$validated[ 'error' ] = 'group_of_events_ends_after_availability_period';
$datetime_formatted = bookacti_format_datetime( $calendar_end->format( 'Y-m-d H:i:s' ), esc_html__( 'F d, Y', 'booking-activities' ) );
/* translators: %s is a formatted date (e.g.: "January 20, 2018") */
$validated['message'] = sprintf( esc_html__( 'You cannot book a group if any of its events takes place after %s.', 'booking-activities' ), $datetime_formatted );
$validated[ 'message' ] = sprintf( esc_html__( 'You cannot book a group if any of its events takes place after %s.', 'booking-activities' ), $datetime_formatted );
return $validated;
}
}
@ -1431,29 +1535,21 @@ function bookacti_get_events_array_from_db_events( $events, $past_events, $inter
/**
* Get a new interval of events to load. Computed from the compulsory interval, or now's date and template interval.
*
* @since 1.2.2
* @version 1.7.16
* @param array $template_interval array( 'start'=>Calendar start, 'end'=> Calendar end, 'settings'=> array( 'availability_period_start'=> Relative start from today, 'availability_period_end'=> Relative end from today) )
* @version 1.7.17
* @param array $availability_period array( 'start'=> 'Y-m-d', 'end'=> 'Y-m-d' )
* @param array $min_interval array( 'start'=> Calendar start, 'end'=> Calendar end)
* @param int $interval_duration Number of days of the interval
* @param bool $past_events
* @return array
*/
function bookacti_get_new_interval_of_events( $template_interval, $min_interval = array(), $interval_duration = false, $past_events = false ) {
if( ! isset( $template_interval[ 'start' ] ) || ! isset( $template_interval[ 'end' ] ) ) { return array(); }
// Take default availability period if not set
if( ! isset( $template_interval[ 'settings' ][ 'availability_period_start' ] ) ){ $template_interval[ 'settings' ][ 'availability_period_start' ] = 0; }
if( ! isset( $template_interval[ 'settings' ][ 'availability_period_end' ] ) ) { $template_interval[ 'settings' ][ 'availability_period_end' ] = 0; }
function bookacti_get_new_interval_of_events( $availability_period, $min_interval = array(), $interval_duration = false, $past_events = false ) {
if( ! isset( $availability_period[ 'start' ] ) || ! isset( $availability_period[ 'end' ] ) ) { return array(); }
$timezone = new DateTimeZone( bookacti_get_setting_value( 'bookacti_general_settings', 'timezone' ) );
$current_time = new DateTime( 'now', $timezone );
$current_date = $current_time->format( 'Y-m-d' );
// Restrict template interval if an availability period is set
$availability_period = bookacti_get_availability_period( $template_interval, $past_events );
$calendar_start = new DateTime( $availability_period[ 'start' ] . ' 00:00:00', $timezone );
$calendar_end = new DateTime( $availability_period[ 'end' ] . ' 23:59:59', $timezone );
@ -1506,47 +1602,73 @@ function bookacti_get_new_interval_of_events( $template_interval, $min_interval
}
/**
* Get availability period from calendar field data
* @since 1.7.17
* @param array|int $calendar_field
* @return array
*/
function bookacti_get_calendar_field_availability_period( $calendar_field ) {
if( is_numeric( $calendar_field ) ) { $calendar_field = bookacti_get_form_field_data( $calendar_field ); }
if( ! is_array( $calendar_field ) ) { $calendar_field = array(); }
// Compute availability period
$absolute_period = array(
'start' => ! empty( $calendar_field[ 'start' ] ) ? bookacti_sanitize_date( $calendar_field[ 'start' ] ) : '',
'end' => ! empty( $calendar_field[ 'end' ] ) ? bookacti_sanitize_date( $calendar_field[ 'end' ] ) : ''
);
$relative_period = array(
'start' => ! empty( $calendar_field[ 'availability_period_start' ] ) && is_numeric( $calendar_field[ 'availability_period_start' ] ) ? intval( $calendar_field[ 'availability_period_start' ] ) : 0,
'end' => ! empty( $calendar_field[ 'availability_period_end' ] ) && is_numeric( $calendar_field[ 'availability_period_end' ] ) ? intval( $calendar_field[ 'availability_period_end' ] ) : 0