Browse Source

Merge branch 'upstream_master' into feature/upstream_1.7.20

develop
Sam Black 2 years ago
parent
commit
c36fc2e96b
Signed by: samwwwblack GPG Key ID: 0FF0223994EA47D8
  1. 215
      booking-activities.php
  2. 7
      class/class-forms-list.php
  3. 54
      controller/controller-booking-system.php
  4. 8
      controller/controller-bookings.php
  5. 747
      controller/controller-forms.php
  6. 157
      controller/controller-settings.php
  7. 14
      controller/controller-shortcodes.php
  8. 62
      controller/controller-templates.php
  9. 50
      controller/controller-woocommerce-backend.php
  10. 132
      controller/controller-woocommerce-bookings.php
  11. 216
      controller/controller-woocommerce-forms.php
  12. 740
      controller/controller-woocommerce-frontend.php
  13. 46
      controller/controller-woocommerce-notifications.php
  14. 155
      controller/controller-woocommerce-settings.php
  15. 4
      css/backend.css
  16. 2
      css/backend.min.css
  17. 13
      css/bookings.css
  18. 2
      css/bookings.min.css
  19. 21
      css/forms.css
  20. 2
      css/forms.min.css
  21. 12
      css/frontend.css
  22. 2
      css/frontend.min.css
  23. 11
      css/global.css
  24. 2
      css/global.min.css
  25. 5
      css/templates.css
  26. 2
      css/templates.min.css
  27. 9
      css/woocommerce.css
  28. 2
      css/woocommerce.min.css
  29. 1105
      functions/functions-booking-system.php
  30. 8
      functions/functions-bookings.php
  31. 261
      functions/functions-forms.php
  32. 662
      functions/functions-global.php
  33. 202
      functions/functions-notifications.php
  34. 169
      functions/functions-settings.php
  35. 38
      functions/functions-templates-forms-control.php
  36. 161
      functions/functions-templates.php
  37. 922
      functions/functions-woocommerce.php
  38. 96
      js/backend-functions.js
  39. 6
      js/backend-functions.min.js
  40. 672
      js/booking-method-calendar.js
  41. 6
      js/booking-method-calendar.min.js
  42. 2470
      js/booking-system-functions.js
  43. 6
      js/booking-system-functions.min.js
  44. 47
      js/booking-system.js
  45. 6
      js/booking-system.min.js
  46. 14
      js/bookings-dialogs.js
  47. 6
      js/bookings-dialogs.min.js
  48. 891
      js/bookings-functions.js
  49. 6
      js/bookings-functions.min.js
  50. 8
      js/bookings.js
  51. 6
      js/bookings.min.js
  52. 46
      js/form-editor-dialogs.js
  53. 6
      js/form-editor-dialogs.min.js
  54. 97
      js/form-editor.js
  55. 6
      js/form-editor.min.js
  56. 85
      js/forms.js
  57. 6
      js/forms.min.js
  58. 254
      js/global-functions.js
  59. 6
      js/global-functions.min.js
  60. 188
      js/templates-dialogs.js
  61. 6
      js/templates-dialogs.min.js
  62. 13
      js/templates-forms-control.js
  63. 6
      js/templates-forms-control.min.js
  64. 118
      js/templates-functions.js
  65. 6
      js/templates-functions.min.js
  66. 51
      js/templates.js
  67. 6
      js/templates.min.js
  68. 73
      js/woocommerce-backend.js
  69. 6
      js/woocommerce-backend.min.js
  70. 57
      js/woocommerce-frontend.js
  71. 6
      js/woocommerce-frontend.min.js
  72. 104
      js/woocommerce-global.js
  73. 6
      js/woocommerce-global.min.js
  74. 2730
      languages/booking-activities.pot
  75. 44
      languages/script-translation.php
  76. 1
      lib/select2/select2.min.css
  77. 2
      lib/select2/select2.min.js
  78. 98
      model/model-booking-system.php
  79. 826
      model/model-bookings.php
  80. 26
      model/model-forms.php
  81. 13
      model/model-global.php
  82. 112
      model/model-templates.php
  83. 51
      model/model-woocommerce.php
  84. 70
      readme.txt
  85. 24
      view/view-bookings.php
  86. 5
      view/view-form-editor-dialogs.php
  87. 4
      view/view-form-editor.php
  88. 6
      view/view-landing.php
  89. 4
      view/view-settings.php
  90. 447
      view/view-templates-dialogs.php
  91. 18
      view/view-templates.php

215
booking-activities.php

@ -1,37 +1,37 @@
<?php
<?php
/**
* 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.14.20200103
* Version: 1.7.20.20200307
* 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
*
*
* This file is part of Booking Activities.
*
*
* Booking Activities is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
*
* Booking Activities is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with Booking Activities. If not, see <http://www.gnu.org/licenses/>.
*
*
* @package Booking Activities
* @category Core
* @author Booking Activities Team
*
*
* Copyright 2018 Yoan Cutillas
* Copyright 2018, 2019 Sam Black <samwwwblack@lapwing.org>
*/
@ -41,7 +41,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// GLOBALS AND CONSTANTS
if( ! defined( 'BOOKACTI_VERSION' ) ) { define( 'BOOKACTI_VERSION', '1.7.14.20200103' ); }
if( ! defined( 'BOOKACTI_VERSION' ) ) { define( 'BOOKACTI_VERSION', '1.7.20.20200307' ); }
if( ! defined( 'BOOKACTI_PLUGIN_NAME' ) ) { define( 'BOOKACTI_PLUGIN_NAME', 'booking-activities' ); }
if( ! defined( 'BOOKACTI_PLUGIN_DIR' ) ) { define( 'BOOKACTI_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); }
@ -55,13 +55,13 @@ __( 'Booking system specialized in activities (sports, cultural, leisure, events
* Load or reload Booking Activities translations
* @version 1.7.8
*/
function bookacti_load_textdomain() {
function bookacti_load_textdomain() {
$locale = is_admin() && function_exists( 'get_user_locale' ) ? get_user_locale() : get_locale();
$locale = apply_filters( 'plugin_locale', $locale, 'booking-activities' );
unload_textdomain( 'booking-activities' );
load_textdomain( 'booking-activities', WP_LANG_DIR . '/' . BOOKACTI_PLUGIN_NAME . '/' . BOOKACTI_PLUGIN_NAME . '-' . $locale . '.mo' );
load_plugin_textdomain( 'booking-activities', false, plugin_basename( dirname( __FILE__ ) ) . '/languages/' );
load_plugin_textdomain( 'booking-activities', false, plugin_basename( dirname( __FILE__ ) ) . '/languages/' );
}
add_action( 'plugins_loaded', 'bookacti_load_textdomain' );
@ -69,8 +69,8 @@ add_action( 'plugins_loaded', 'bookacti_load_textdomain' );
// INCLUDE PHP FUNCTIONS
include_once( 'functions/functions-global.php' );
include_once( 'functions/functions-booking-system.php' );
include_once( 'functions/functions-global.php' );
include_once( 'functions/functions-booking-system.php' );
include_once( 'functions/functions-templates.php' );
include_once( 'functions/functions-templates-forms-control.php' );
include_once( 'functions/functions-bookings.php' );
@ -116,6 +116,7 @@ if( bookacti_is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
require_once( 'model/model-woocommerce.php' );
}
// Include BA:Silicon files
include_once 'silicon/silicon.php';
@ -124,32 +125,32 @@ include_once 'silicon/silicon.php';
/**
* Enqueue high priority scripts
* @version 1.7.0
* @version 1.7.19
* @global array $bookacti_translation_array
*/
function bookacti_enqueue_high_priority_global_scripts() {
// On backend, only include these scripts on Booking Activities pages
if( is_admin() && ! bookacti_is_booking_activities_screen() ) { return; }
// INCLUDE LIBRARIES
wp_enqueue_script( 'bookacti-js-moment', plugins_url( 'lib/fullcalendar/moment.min.js', __FILE__ ), array( 'jquery' ), BOOKACTI_VERSION, true );
wp_enqueue_style ( 'bookacti-css-fullcalendar', plugins_url( 'lib/fullcalendar/fullcalendar.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
wp_enqueue_style ( 'bookacti-css-fullcalendar-print', plugins_url( 'lib/fullcalendar/fullcalendar.print.min.css', __FILE__ ), array( 'bookacti-css-fullcalendar' ), BOOKACTI_VERSION, 'print' );
wp_enqueue_script( 'bookacti-js-fullcalendar', plugins_url( 'lib/fullcalendar/fullcalendar.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-moment' ), BOOKACTI_VERSION, true );
wp_enqueue_script( 'bookacti-js-fullcalendar-locale-all', plugins_url( 'lib/fullcalendar/locale-all.js', __FILE__ ), array( 'jquery', 'bookacti-js-fullcalendar' ), BOOKACTI_VERSION, true );
// INCLUDE JAVASCRIPT FILES
wp_register_script( 'bookacti-js-global-var', plugins_url( 'js/global-var.min.js', __FILE__ ), array( 'jquery' ), BOOKACTI_VERSION, false ); // Load in header
wp_register_script( 'bookacti-js-global-functions', plugins_url( 'js/global-functions.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'jquery-ui-autocomplete', 'jquery-ui-tooltip' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-global-functions', plugins_url( 'js/global-functions.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'jquery-ui-tooltip' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-booking-system-functions', plugins_url( 'js/booking-system-functions.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-fullcalendar', 'jquery-effects-highlight' ), BOOKACTI_VERSION, true );
// LOCALIZE SCRIPTS
global $bookacti_translation_array;
require_once( 'languages/script-translation.php' );
wp_localize_script( 'bookacti-js-global-var', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-global-functions', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-booking-system-functions', 'bookacti_localized', $bookacti_translation_array );
// ENQUEUE SCRIPTS
wp_enqueue_script ( 'bookacti-js-global-var' );
wp_enqueue_script ( 'bookacti-js-global-functions' );
@ -161,13 +162,13 @@ add_action( 'wp_enqueue_scripts', 'bookacti_enqueue_high_priority_global_scripts
/**
* Enqueue normal priority scripts
* @version 1.7.9
* @version 1.7.16
* @global array $bookacti_translation_array
*/
function bookacti_enqueue_global_scripts() {
global $bookacti_translation_array;
if( empty( $bookacti_translation_array ) ) { require_once( 'languages/script-translation.php' ); }
// Include WooCommerce style and scripts
if( bookacti_is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
if( ! is_admin() || bookacti_is_wc_screen( array( 'product', 'product_variation', 'shop_order' ) ) ) {
@ -182,25 +183,25 @@ function bookacti_enqueue_global_scripts() {
wp_localize_script( 'bookacti-js-woocommerce-global', 'bookacti_localized', $bookacti_translation_array );
wp_enqueue_script( 'bookacti-js-woocommerce-global' );
}
// On backend, only include these scripts on Booking Activities pages
if( is_admin() && ! bookacti_is_booking_activities_screen() ) { return; }
// INCLUDE STYLESHEETS
wp_enqueue_style ( 'bookacti-css-global', plugins_url( 'css/global.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
wp_enqueue_style ( 'bookacti-css-fonts', plugins_url( 'css/fonts.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
wp_enqueue_style ( 'bookacti-css-bookings', plugins_url( 'css/bookings.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
wp_enqueue_style ( 'bookacti-css-forms', plugins_url( 'css/forms.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
wp_enqueue_style ( 'jquery-ui-bookacti-theme', plugins_url( 'lib/jquery-ui/themes/booking-activities/jquery-ui.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
// INCLUDE JAVASCRIPT FILES
wp_register_script( 'bookacti-js-booking-system', plugins_url( 'js/booking-system.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-fullcalendar', 'bookacti-js-global-functions' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-booking-system-dialogs', plugins_url( 'js/booking-system-dialogs.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-moment', 'jquery-ui-dialog' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-booking-method-calendar', plugins_url( 'js/booking-method-calendar.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-fullcalendar', 'bookacti-js-global-functions' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-bookings-functions', plugins_url( 'js/bookings-functions.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-fullcalendar', 'bookacti-js-global-functions', ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-bookings-dialogs', plugins_url( 'js/bookings-dialogs.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-global-functions', 'bookacti-js-moment', 'jquery-ui-dialog' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-forms', plugins_url( 'js/forms.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-functions', 'jquery-ui-dialog', 'password-strength-meter' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-forms', plugins_url( 'js/forms.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-functions', 'jquery-ui-dialog' ), BOOKACTI_VERSION, true );
// LOCALIZE SCRIPTS
wp_localize_script( 'bookacti-js-booking-system', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-booking-system-dialogs', 'bookacti_localized', $bookacti_translation_array );
@ -208,7 +209,7 @@ function bookacti_enqueue_global_scripts() {
wp_localize_script( 'bookacti-js-bookings-functions', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-bookings-dialogs', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-forms', 'bookacti_localized', $bookacti_translation_array );
// ENQUEUE SCRIPTS
wp_enqueue_script( 'bookacti-js-booking-system' );
wp_enqueue_script( 'bookacti-js-booking-system-dialogs' );
@ -223,21 +224,25 @@ add_action( 'wp_enqueue_scripts', 'bookacti_enqueue_global_scripts', 20 );
/**
* Enqueue high priority scripts in backend only
* @version 1.7.0
* @version 1.7.19
* @global array $bookacti_translation_array
*/
function bookacti_enqueue_high_priority_backend_scripts() {
// On backend, only include these scripts on Booking Activities pages
if( ! bookacti_is_booking_activities_screen() ) { return; }
// INCLUDE LIBRARIES
$select2_version = '4.0.13';
wp_enqueue_script( 'select2', plugins_url( 'lib/select2/select2.min.js', __FILE__ ), array( 'jquery' ), $select2_version, true );
wp_enqueue_style( 'select2', plugins_url( 'lib/select2/select2.min.css', __FILE__ ), array(), $select2_version );
// INCLUDE JAVASCRIPT FILES
wp_register_script( 'bookacti-js-backend-functions', plugins_url( 'js/backend-functions.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-global-functions', 'jquery-ui-dialog', 'jquery-ui-tabs', 'jquery-ui-tooltip' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-bookings', plugins_url( 'js/bookings.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-fullcalendar', 'bookacti-js-global-functions', 'bookacti-js-backend-functions' ), BOOKACTI_VERSION, true );
// LOCALIZE SCRIPTS
global $bookacti_translation_array;
wp_localize_script( 'bookacti-js-bookings', 'bookacti_localized', $bookacti_translation_array );
// ENQUEUE SCRIPTS
wp_enqueue_script ( 'bookacti-js-backend-functions' );
wp_enqueue_script ( 'bookacti-js-bookings' );
@ -253,7 +258,7 @@ add_action( 'admin_enqueue_scripts','bookacti_enqueue_high_priority_backend_scri
function bookacti_enqueue_backend_scripts() {
global $bookacti_translation_array;
if( empty( $bookacti_translation_array ) ) { require_once( 'languages/script-translation.php' ); }
// Include WooCommerce scripts
if( bookacti_is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
if( bookacti_is_wc_screen( array( 'product', 'product_variation', 'shop_order' ) ) || bookacti_is_booking_activities_screen() ) {
@ -262,7 +267,7 @@ function bookacti_enqueue_backend_scripts() {
wp_enqueue_script ( 'bookacti-js-woocommerce-backend' );
}
}
// On backend, only include these scripts on Booking Activities pages
if( ! bookacti_is_booking_activities_screen() ) { return; }
@ -270,7 +275,7 @@ function bookacti_enqueue_backend_scripts() {
wp_enqueue_style ( 'bookacti-css-backend', plugins_url( 'css/backend.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
wp_enqueue_style ( 'bookacti-css-templates',plugins_url( 'css/templates.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
wp_enqueue_style ( 'bookacti-css-landing', plugins_url( 'css/landing.min.css', __FILE__ ), array(), BOOKACTI_VERSION );
// INCLUDE JAVASCRIPT FILES
wp_register_script( 'bookacti-js-templates-forms-control', plugins_url( 'js/templates-forms-control.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-moment' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-templates-functions', plugins_url( 'js/templates-functions.min.js', __FILE__ ), array( 'jquery', 'jquery-touch-punch', 'bookacti-js-global-var', 'bookacti-js-fullcalendar', 'jquery-effects-highlight' ), BOOKACTI_VERSION, true );
@ -279,7 +284,7 @@ function bookacti_enqueue_backend_scripts() {
wp_register_script( 'bookacti-js-settings', plugins_url( 'js/settings.min.js', __FILE__ ), array( 'jquery' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-form-editor-dialogs', plugins_url( 'js/form-editor-dialogs.min.js', __FILE__ ), array( 'jquery', 'bookacti-js-global-var', 'bookacti-js-moment', 'jquery-ui-dialog', 'bookacti-js-backend-functions' ), BOOKACTI_VERSION, true );
wp_register_script( 'bookacti-js-form-editor', plugins_url( 'js/form-editor.min.js', __FILE__ ), array( 'jquery', 'jquery-touch-punch', 'bookacti-js-global-var', 'bookacti-js-booking-system-functions', 'jquery-ui-sortable', 'bookacti-js-forms', 'bookacti-js-form-editor-dialogs' ), BOOKACTI_VERSION, true );
// LOCALIZE SCRIPTS
wp_localize_script( 'bookacti-js-templates-forms-control', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-templates-functions', 'bookacti_localized', $bookacti_translation_array );
@ -288,7 +293,7 @@ function bookacti_enqueue_backend_scripts() {
wp_localize_script( 'bookacti-js-settings', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-form-editor-dialogs', 'bookacti_localized', $bookacti_translation_array );
wp_localize_script( 'bookacti-js-form-editor', 'bookacti_localized', $bookacti_translation_array );
// ENQUEUE SCRIPTS
wp_enqueue_script ( 'bookacti-js-templates-forms-control' );
wp_enqueue_script ( 'bookacti-js-templates-functions' );
@ -328,22 +333,22 @@ function bookacti_activate() {
// Create tables in database
bookacti_create_tables();
// Keep in memory the first installed date
$install_date = get_option( 'bookacti-install-date' );
if( ! $install_date ) {
update_option( 'bookacti-install-date', date( 'Y-m-d H:i:s' ) );
}
// Check if the plugin is being updated
bookacti_check_version( true );
// Update current version
delete_option( 'bookacti_version' );
add_option( 'bookacti_version', BOOKACTI_VERSION );
do_action( 'bookacti_activate' );
// Flush rules after install
flush_rewrite_rules();
}
@ -367,17 +372,17 @@ register_deactivation_hook( __FILE__, 'bookacti_deactivate' );
function bookacti_uninstall() {
// Delete notices acknowledgement
bookacti_reset_notices();
if( bookacti_get_setting_value( 'bookacti_general_settings', 'delete_data_on_uninstall' ) ) {
// Delete plugin settings
bookacti_delete_settings();
// Delete user meta related to Booking Activities
bookacti_delete_user_data();
// Drop tables and every Booking Activities Data
bookacti_drop_tables();
// Delete Booking Activities files
$uploads_dir = wp_upload_dir();
$bookacti_upload_dir = trailingslashit( str_replace( '\\', '/', $uploads_dir[ 'basedir' ] ) ) . BOOKACTI_PLUGIN_NAME . '/';
@ -385,12 +390,12 @@ function bookacti_uninstall() {
bookacti_delete_files( $bookacti_upload_dir, true );
}
}
// Unset roles and capabilities
bookacti_unset_role_and_cap();
do_action( 'bookacti_uninstall' );
// Clear any cached data that has been removed
wp_cache_flush();
}
@ -409,6 +414,102 @@ function bookacti_check_version( $from_activate = false ) {
}
}
add_action( 'init', 'bookacti_check_version', 5 );
/**
* Update the form settings and the template settings that relies on global settings removed in 1.7.16
* This function is temporary
* @since 1.7.16
* @global wpdb $wpdb
* @param string $old_version
*/
function bookacti_update_removed_global_settings_in_1_7_16( $old_version ) {
// Do it only once, when Booking Activities is updated for the first time after 1.7.16
if( version_compare( $old_version, '1.7.16', '<' ) ) {
// Get the global values
$global_booking_method = bookacti_get_setting_value( 'bookacti_general_settings', 'booking_method' );
$global_availability_period_start = bookacti_get_setting_value( 'bookacti_general_settings', 'availability_period_start' );
$global_availability_period_end = bookacti_get_setting_value( 'bookacti_general_settings', 'availability_period_end' );
global $wpdb;
// Update the "Booking method" setting (Calendar form fields)
$booking_method_updated = $wpdb->update(
BOOKACTI_TABLE_META,
array( 'meta_value' => $global_booking_method ? $global_booking_method : 'calendar' ),
array( 'meta_key' => 'method', 'meta_value' => 'site' ),
array( '%s' ),
array( '%s', '%s' )
);
$wc_product_booking_method_updated = $wpdb->update(
$wpdb->postmeta,
array( 'meta_value' => $global_booking_method ? $global_booking_method : 'calendar' ),
array( 'meta_key' => '_bookacti_booking_method', 'meta_value' => 'site' ),
array( '%s' ),
array( '%s', '%s' )
);
$wc_variation_booking_method_updated = $wpdb->update(
$wpdb->postmeta,
array( 'meta_value' => $global_booking_method ? $global_booking_method : 'calendar' ),
array( 'meta_key' => 'bookacti_variable_booking_method', 'meta_value' => 'site' ),
array( '%s' ),
array( '%s', '%s' )
);
// Update the "Events will be bookable in" setting (Templates, Calendar form fields)
$availability_period_start_updated = $wpdb->update(
BOOKACTI_TABLE_META,
array( 'meta_value' => $global_availability_period_start ? $global_availability_period_start : 0 ),
array( 'meta_key' => 'availability_period_start', 'meta_value' => -1 ),
array( '%d' ),
array( '%s', '%d' )
);
// Update the "Events will be bookable in" setting (Templates, Calendar form fields)
$availability_period_end_updated = $wpdb->update(
BOOKACTI_TABLE_META,
array( 'meta_value' => $global_availability_period_end ? $global_availability_period_end : 0 ),
array( 'meta_key' => 'availability_period_end', 'meta_value' => -1 ),
array( '%d' ),
array( '%s', '%d' )
);
}
}
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' );
@ -423,13 +524,13 @@ function bookacti_create_menu() {
// Add a menu and submenus
$icon_url = 'dashicons-calendar-alt';
add_menu_page( 'Booking Activities', 'Booking Activities', 'bookacti_manage_booking_activities', 'booking-activities', null, $icon_url, '56.5' );
add_submenu_page( 'booking-activities', 'Booking Activities', _x( 'Home', 'Landing page tab name', 'booking-activities' ),'bookacti_manage_booking_activities', 'booking-activities', 'bookacti_landing_page' );
add_submenu_page( 'booking-activities', 'Booking Activities', _x( 'Home', 'Landing page tab name', 'booking-activities' ),'bookacti_manage_booking_activities', 'booking-activities', 'bookacti_landing_page' );
add_submenu_page( 'booking-activities', __( 'Calendar editor', 'booking-activities' ), __( 'Calendar editor', 'booking-activities' ), 'bookacti_manage_templates', 'bookacti_calendars', 'bookacti_templates_page' );
add_submenu_page( 'booking-activities', __( 'Booking forms', 'booking-activities' ), __( 'Booking forms', 'booking-activities' ), 'bookacti_manage_forms', 'bookacti_forms', 'bookacti_forms_page' );
add_submenu_page( 'booking-activities', __( 'Bookings', 'booking-activities' ), __( 'Bookings', 'booking-activities' ), 'bookacti_manage_bookings', 'bookacti_bookings', 'bookacti_bookings_page' );
do_action( 'bookacti_admin_menu' );
add_submenu_page( 'booking-activities', __( 'Settings', 'booking-activities' ), __( 'Settings', 'booking-activities' ), 'bookacti_manage_booking_activities_settings', 'bookacti_settings', 'bookacti_settings_page' );
}
add_action( 'admin_menu', 'bookacti_create_menu' );
@ -454,18 +555,18 @@ function bookacti_templates_page() {
* @since 1.5.0
*/
function bookacti_forms_page() {
$can_create_form = current_user_can( 'bookacti_create_forms' );
$can_edit_form = current_user_can( 'bookacti_edit_forms' );
$load_form_editor = false;
if( ! empty( $_GET[ 'action' ] ) ) {
if( ( $_GET[ 'action' ] === 'new' && $can_create_form )
|| ( $_GET[ 'action' ] === 'edit' && ! empty( $_GET[ 'form_id' ] ) && is_numeric( $_GET[ 'form_id' ] ) && $can_edit_form ) ) {
$load_form_editor = true;
}
}
if( $load_form_editor ) {
include_once( 'view/view-form-editor.php' );
} else {
@ -485,4 +586,4 @@ function bookacti_bookings_page() {
*/
function bookacti_settings_page() {
include_once( 'view/view-settings.php' );
}
}

7
class/class-forms-list.php

@ -210,7 +210,7 @@ if( ! class_exists( 'Forms_List_Table' ) ) {
/**
* Fill "Title" column and add action buttons
* @version 1.7.12
* @version 1.7.18
* @access public
* @param array $item
* @return string
@ -221,11 +221,14 @@ if( ! class_exists( 'Forms_List_Table' ) ) {
if( current_user_can( 'bookacti_edit_forms' ) ) {
// Add the 'edit' action
// Add the 'edit' and the 'duplicate' actions
if( $item[ 'active_raw' ] ) {
$actions[ 'edit' ] = '<a href="' . esc_url( admin_url( 'admin.php?page=bookacti_forms&action=edit&form_id=' . $form_id ) ) . '" >'
. esc_html_x( 'Edit', 'forms', 'booking-activities' )
. '</a>';
$actions[ 'duplicate' ] = '<a href="' . esc_url( wp_nonce_url( admin_url( 'admin.php?page=bookacti_forms&action=duplicate&form_id=' . $form_id ), 'duplicate-form_' . $form_id ) ) . '" >'
. esc_html_x( 'duplicate', 'forms', 'booking-activities' )
. '</a>';
}
if( current_user_can( 'bookacti_delete_forms' ) ) {

54
controller/controller-booking-system.php

@ -5,17 +5,17 @@ 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
$is_admin = intval( $_POST[ 'is_admin' ] );
$raw_attributes = json_decode( stripslashes( $_POST[ 'attributes' ] ), true );
$attributes = bookacti_format_booking_system_attributes( $raw_attributes );
// On admin side only, check capabilities
$is_allowed = true;
if( $is_admin && ! is_super_admin() ) {
if( $is_admin && ! is_super_admin() ) {
$bypass_template_managers_check = apply_filters( 'bookacti_bypass_template_managers_check', false );
if( ! $bypass_template_managers_check ){
// Remove templates current user is not allowed to manage
@ -28,7 +28,7 @@ function bookacti_controller_fetch_events() {
if( empty( $attributes[ 'calendars' ] ) ) { $is_allowed = false; }
}
}
if( ! $is_allowed ) { bookacti_send_json_not_allowed( 'fetch_events' ); }
$events_interval = bookacti_sanitize_events_interval( isset( $_POST[ 'interval' ] ) ? $_POST[ 'interval' ] : null );
@ -37,20 +37,20 @@ 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' ] ) {
$events = bookacti_fetch_booked_events( $attributes[ 'calendars' ], $attributes[ 'activities' ], $attributes[ 'status' ], $attributes[ 'user_id' ], $attributes[ 'past_events' ], $events_interval );
} else {
$events = bookacti_fetch_events( $attributes[ 'calendars' ], $attributes[ 'activities' ], $attributes[ 'past_events' ], $events_interval );
$events = bookacti_fetch_events( $attributes[ 'calendars' ], $attributes[ 'activities' ], $attributes[ 'past_events' ], $events_interval );
}
$events = apply_filters( 'bookacti_events_data_from_interval', $events, $events_interval, $attributes );
bookacti_send_json( array(
'status' => 'success',
'events' => $events[ 'events' ] ? $events[ 'events' ] : array(),
bookacti_send_json( array(
'status' => 'success',
'events' => $events[ 'events' ] ? $events[ 'events' ] : array(),
'events_data' => $events[ 'data' ] ? $events[ 'data' ] : array()
), 'fetch_events' );
}
@ -61,15 +61,15 @@ add_action( 'wp_ajax_nopriv_bookactiFetchEvents', 'bookacti_controller_fetch_eve
/**
* Reload booking system with new attributes via AJAX
* @since 1.1.0
* @version 1.7.4
* @version 1.7.15
*/
function bookacti_controller_reload_booking_system() {
$is_admin = intval( $_POST[ 'is_admin' ] );
$atts = bookacti_format_booking_system_attributes( json_decode( stripslashes( $_POST[ 'attributes' ] ), true ) );
// On admin side only, check capabilities
$is_allowed = true;
if( $is_admin && ! is_super_admin() ) {
if( $is_admin && ! is_super_admin() ) {
$bypass_template_managers_check = apply_filters( 'bookacti_bypass_template_managers_check', false );
if( ! $bypass_template_managers_check ){
// Remove templates current user is not allowed to manage
@ -82,19 +82,25 @@ function bookacti_controller_reload_booking_system() {
if( empty( $atts[ 'calendars' ] ) ) { $is_allowed = false; }
}
}
if( ! $is_allowed ) { bookacti_send_json_not_allowed( 'reload_booking_system' ); }
$atts[ 'auto_load' ] = 1;
$booking_system_data = bookacti_get_booking_system_data( $atts );
// Get HTML elements used by the booking method
$html_elements = bookacti_get_booking_method_html( $booking_system_data[ 'method' ], $booking_system_data );
bookacti_send_json( array(
'status' => 'success',
'html_elements' => $html_elements,
'booking_system_data' => $booking_system_data
// Encrypt user id
$public_user_id = ! empty( $atts[ 'user_id' ] ) ? $atts[ 'user_id' ] : 0;
if( $public_user_id && ( ( is_numeric( $public_user_id ) && strlen( (string) $public_user_id ) < 16 ) || is_email( $public_user_id ) ) ) { $public_user_id = bookacti_encrypt( $public_user_id ); }
// Let plugins define what data should be passed to JS
$public_booking_system_data = apply_filters( 'bookacti_public_booking_system_data', array_merge( $booking_system_data, array( 'user_id' => $public_user_id ) ), $atts );
bookacti_send_json( array(
'status' => 'success',
'html_elements' => $html_elements,
'booking_system_data' => $public_booking_system_data
), 'reload_booking_system' );
}
add_action( 'wp_ajax_bookactiReloadBookingSystem', 'bookacti_controller_reload_booking_system' );
@ -103,7 +109,7 @@ add_action( 'wp_ajax_nopriv_bookactiReloadBookingSystem', 'bookacti_controller_r
/**
* AJAX Controller - Get booking numbers for a given template and / or event
*
*
* @version 1.5.0
*/
function bookacti_controller_get_booking_numbers() {
@ -122,4 +128,4 @@ function bookacti_controller_get_booking_numbers() {
}
}
add_action( 'wp_ajax_bookactiGetBookingNumbers', 'bookacti_controller_get_booking_numbers' );
add_action( 'wp_ajax_nopriv_bookactiGetBookingNumbers', 'bookacti_controller_get_booking_numbers' );
add_action( 'wp_ajax_nopriv_bookactiGetBookingNumbers', 'bookacti_controller_get_booking_numbers' );

8
controller/controller-bookings.php

@ -263,7 +263,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Get booking system data by booking ID
* @version 1.7.4
* @version 1.7.18
*/
function bookacti_controller_get_booking_data() {
// Check nonce, no need to check capabilities
@ -273,9 +273,11 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$booking_id = intval( $_POST[ 'booking_id' ] );
$booking_data = bookacti_get_booking_data( $booking_id );
if( ! empty( $booking_data ) && is_array( $booking_data ) ) {
bookacti_send_json( array( 'status' => 'success', 'booking_data' => $booking_data ), 'get_booking_data' );
$calendar_field_data = ! empty( $booking_data[ 'form_id' ] ) ? bookacti_get_form_field_data_by_name( $booking_data[ 'form_id' ], 'calendar' ) : bookacti_get_default_form_fields_data( 'calendar' );
bookacti_send_json( array( 'status' => 'success', 'booking_data' => $booking_data, 'calendar_field_data' => $calendar_field_data ), 'get_booking_data' );
} else {
bookacti_send_json( array( 'status' => 'failed', 'error' => 'empty_data' ), 'get_booking_data' );
}

747
controller/controller-forms.php

File diff suppressed because it is too large

157
controller/controller-settings.php

@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Init Booking Activities settings
* @version 1.7.14
* @version 1.7.16
*/
function bookacti_init_settings() {
@ -17,11 +17,19 @@ function bookacti_init_settings() {
);
add_settings_field(
'booking_method',
esc_html__( 'Booking method', 'booking-activities' ),
'bookacti_settings_field_booking_method_callback',
'timezone',
esc_html__( 'Calendars timezone', 'booking-activities' ),
'bookacti_settings_field_timezone_callback',
'bookacti_general_settings',
'bookacti_settings_section_general'
'bookacti_settings_section_general'
);
add_settings_field(
'default_calendar_view_threshold',
esc_html__( 'Load the "Day" view if the calendar width is less than', 'booking-activities' ),
'bookacti_settings_field_default_calendar_view_threshold_callback',
'bookacti_general_settings',
'bookacti_settings_section_general'
);
add_settings_field(
@ -55,25 +63,7 @@ function bookacti_init_settings() {
'bookacti_general_settings',
'bookacti_settings_section_general'
);
add_settings_field(
'availability_period_start',
/* translators: Followed by a field indicating a number of days before the event. E.g.: "Events will be bookable in 2 days from today". */
esc_html__( 'Events will be bookable in', 'booking-activities' ),
'bookacti_settings_field_availability_period_start_callback',
'bookacti_general_settings',
'bookacti_settings_section_general'
);
add_settings_field(
'availability_period_end',
/* translators: Followed by a field indicating a number of days before the event. E.g.: "Events are bookable for up to 30 days from today". */
esc_html__( 'Events are bookable for up to', 'booking-activities' ),
'bookacti_settings_field_availability_period_end_callback',
'bookacti_general_settings',
'bookacti_settings_section_general'
);
add_settings_field(
'default_booking_state',
esc_html__( 'Default booking state', 'booking-activities' ),
@ -89,23 +79,7 @@ function bookacti_init_settings() {
'bookacti_general_settings',
'bookacti_settings_section_general'
);
add_settings_field(
'timezone',
esc_html__( 'Calendars timezone', 'booking-activities' ),
'bookacti_settings_field_timezone_callback',
'bookacti_general_settings',
'bookacti_settings_section_general'
);
add_settings_field(
'default_calendar_view_threshold',
esc_html__( 'Load the "Day" view if the calendar width is less than', 'booking-activities' ),
'bookacti_settings_field_default_calendar_view_threshold_callback',
'bookacti_general_settings',
'bookacti_settings_section_general'
);
add_settings_field(
'delete_data_on_uninstall',
esc_html__( 'Delete data on uninstall', 'booking-activities' ),
@ -210,9 +184,16 @@ function bookacti_init_settings() {
'bookacti_messages_settings'
);
add_settings_field(
'calendar_localization',
esc_html__( 'Calendar localization', 'booking-activities' ),
'bookacti_settings_field_calendar_localization_callback',
'bookacti_messages_settings',
'bookacti_settings_section_messages'
);
/* Messages settings Section */
/* System settings Section */
add_settings_section(
'bookacti_settings_section_system',
esc_html__( 'System', 'booking-activities' ),
@ -895,7 +876,7 @@ add_filter( 'plugin_row_meta', 'bookacti_meta_links_in_plugins_table', 10, 2 );
/**
* Ask to rate the plugin 5 stars
* @version 1.7.8
* @version 1.7.16
*/
function bookacti_5stars_rating_notice() {
if( ! bookacti_is_booking_activities_screen() ) { return; }
@ -907,21 +888,21 @@ function bookacti_5stars_rating_notice() {
$install_datetime = DateTime::createFromFormat( 'Y-m-d H:i:s', $install_date );
$current_datetime = new DateTime();
$nb_days = floor( $install_datetime->diff( $current_datetime )->days );
if( $nb_days >= 92 ) {
if( $nb_days >= 61 ) {
?>
<div class='notice notice-info bookacti-5stars-rating-notice is-dismissible' >
<p>
<?php
_e( '<strong>Booking Activities</strong> has been helping you for three months now.', 'booking-activities' );
_e( '<strong>Booking Activities</strong> has been helping you for two months now.', 'booking-activities' );
echo '<br/>'
/* translators: %s: five stars */
. sprintf( esc_html__( 'Would you help it back leaving us a %s rating? We need you now to make it last!', 'booking-activities' ),
. sprintf( esc_html__( 'Would you help us back leaving a %s rating? We need you too.', 'booking-activities' ),
'<a href="https://wordpress.org/support/plugin/booking-activities/reviews?rate=5#new-post" target="_blank" >&#9733;&#9733;&#9733;&#9733;&#9733;</a>' );
?>
</p>
<p>
<a class='button' href='<?php echo esc_url( 'https://wordpress.org/support/plugin/booking-activities/reviews?rate=5#new-post' ); ?>' target='_blank' ><?php esc_html_e( "Ok, I'll rate you five stars!", 'booking-activities' ); ?></a>
<span class='button' id='bookacti-dismiss-5stars-rating' ><?php esc_html_e( "I already rated you, hide this message", 'booking-activities' ); ?></span>
<a class='button' href='<?php echo esc_url( 'https://wordpress.org/support/plugin/booking-activities/reviews?rate=5#new-post' ); ?>' target='_blank' ><?php esc_html_e( 'Ok, I\'ll rate you five stars!', 'booking-activities' ); ?></a>
<span class='button' id='bookacti-dismiss-5stars-rating' ><?php esc_html_e( 'I already rated you, hide this message', 'booking-activities' ); ?></span>
</p>
</div>
<?php
@ -959,7 +940,7 @@ add_action( 'wp_ajax_bookactiDismiss5StarsRatingNotice', 'bookacti_dismiss_5star
/**
* Display a custom message in the footer
*
* @version 1.7.16
* @param string $footer_text
* @return string
*/
@ -976,7 +957,7 @@ function bookacti_admin_footer_text( $footer_text ) {
// Change the footer text
if ( ! get_option( 'woocommerce_admin_footer_text_rated' ) ) {
/* translators: %s: five stars */
$footer_text = sprintf( __( 'If <strong>Booking Activities</strong> helps you, help it back leaving us a %s rating. We need you now to make it last!', 'booking-activities' ), '<a href="https://wordpress.org/support/plugin/booking-activities/reviews?rate=5#new-post" target="_blank" >&#9733;&#9733;&#9733;&#9733;&#9733;</a>' );
$footer_text = sprintf( __( 'Does <strong>Booking Activities</strong> help you? Help us back leaving a %s rating. We need you too.', 'booking-activities' ), '<a href="https://wordpress.org/support/plugin/booking-activities/reviews?rate=5#new-post" target="_blank" >&#9733;&#9733;&#9733;&#9733;&#9733;</a>' );
}
}
@ -1049,4 +1030,78 @@ function bookacti_add_editable_extensions( $editable_extensions, $plugin ) {
$editable_extensions[] = 'log';
return $editable_extensions;
}
add_filter( 'editable_extensions', 'bookacti_add_editable_extensions', 10, 2 );
add_filter( 'editable_extensions', 'bookacti_add_editable_extensions', 10, 2 );
// AJAX SELECTBOXES
/**
* Search users for AJAX selectbox
* @since 1.7.19
*/
function bookacti_controller_search_select2_users() {
// Check nonce
$is_nonce_valid = check_ajax_referer( 'bookacti_query_select2_options', 'nonce', false );
if( ! $is_nonce_valid ) { bookacti_send_json_not_allowed( 'search_select2_users' ); }
// Check query
$term = isset( $_REQUEST[ 'term' ] ) ? sanitize_text_field( stripslashes( $_REQUEST[ 'term' ] ) ) : '';
if( ! $term ) { bookacti_send_json( array( 'status' => 'failed', 'error' => 'empty_query' ), 'search_select2_users' ); }
$defaults = array(
'name' => isset( $_REQUEST[ 'name' ] ) ? sanitize_title_with_dashes( stripslashes( $_REQUEST[ 'name' ] ) ) : '',
'id' => isset( $_REQUEST[ 'id' ] ) ? sanitize_title_with_dashes( stripslashes( $_REQUEST[ 'id' ] ) ) : '',
'search' => '*' . esc_attr( $term ) . '*',
'search_columns' => array( 'user_login', 'user_url', 'user_email', 'user_nicename', 'display_name' ),
'option_label' => array( 'first_name', ' ', 'last_name', ' (', 'user_login', ' / ', 'user_email', ')' ),
'allow_current' => 0,
'include' => array(), 'exclude' => array(),
'role' => array(), 'role__in' => array(), 'role__not_in' => array(),
'orderby' => 'display_name', 'order' => 'ASC'
);
$args = apply_filters( 'bookacti_ajax_select2_users_args', $defaults );
$users = bookacti_get_users_data( $args );
$options = array();
// Add "Current user" option
if( ! empty( $_REQUEST[ 'allow_current' ] ) ) {
$options[] = array( 'id' => 'current', 'text' => esc_html__( 'Current user', 'booking-activities' ) );
}
// Add user options
foreach( $users as $user ) {
// Build the option label based on the array
$label = '';
foreach( $args[ 'option_label' ] as $show ) {
// If the key contain "||" display the first not empty value
if( strpos( $show, '||' ) !== false ) {
$keys = explode( '||', $show );
$show = $keys[ 0 ];
foreach( $keys as $key ) {
if( ! empty( $user->{ $key } ) ) { $show = $key; break; }
}
}
// Display the value if the key exists, else display the key as is, as a separator
if( isset( $user->{ $show } ) ) {
$label .= $user->{ $show };
} else {
$label .= $show;
}
}
$options[] = array( 'id' => $user->ID, 'text' => esc_html( $label ) );
}
// Allow plugins to add their values
$select2_options = apply_filters( 'bookacti_ajax_select2_users_options', $options, $args );
if( ! $select2_options ) {
bookacti_send_json( array( 'status' => 'failed', 'error' => 'no_results' ), 'search_select2_users' );
}
bookacti_send_json( array( 'status' => 'success', 'options' => $select2_options ), 'search_select2_users' );
}
add_action( 'wp_ajax_bookactiSelect2Query_users', 'bookacti_controller_search_select2_users' );

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'

62
controller/controller-templates.php

@ -705,7 +705,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Create a new template
* @version 1.7.10
* @version 1.7.19
*/
function bookacti_controller_insert_template() {
// Check nonce and capabilities
@ -716,10 +716,10 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json_not_allowed( 'insert_template' );
}
$template_title = sanitize_text_field( stripslashes( $_POST['template-title'] ) );
$template_start = bookacti_sanitize_date( $_POST['template-opening'] );
$template_end = bookacti_sanitize_date( $_POST['template-closing'] );
$template_title = sanitize_text_field( stripslashes( $_POST[ 'template-title' ] ) );
$template_start = bookacti_sanitize_date( $_POST[ 'template-opening' ] ) ? bookacti_sanitize_date( $_POST[ 'template-opening' ] ) : date( 'Y-m-d' );
$template_end = bookacti_sanitize_date( $_POST[ 'template-closing' ] ) ? bookacti_sanitize_date( $_POST[ 'template-closing' ] ) : '2037-12-31';
$is_template_valid = bookacti_validate_template_data( $template_title, $template_start, $template_end );
// Create template only if its data are consistent
@ -727,9 +727,9 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json( array( 'status' => 'failed' ), 'insert_template' );
}
$duplicated_template_id = intval( $_POST['duplicated-template-id'] );
$managers_array = isset( $_POST['template-managers'] ) ? bookacti_ids_to_array( $_POST['template-managers'] ) : array();
$options_array = isset( $_POST['templateOptions'] ) && is_array( $_POST['templateOptions'] ) ? $_POST['templateOptions'] : array();
$duplicated_template_id = ! empty( $_POST[ 'duplicated-template-id' ] ) ? intval( $_POST[ 'duplicated-template-id' ] ) : 0;
$managers_array = isset( $_POST[ 'template-managers' ] ) ? bookacti_ids_to_array( $_POST[ 'template-managers' ] ) : array();
$options_array = isset( $_POST[ 'templateOptions' ] ) && is_array( $_POST[ 'templateOptions' ] ) ? $_POST[ 'templateOptions' ] : array();
$template_managers = bookacti_format_template_managers( $managers_array );
$template_settings = bookacti_format_template_settings( $options_array );
@ -749,7 +749,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Update template
* @version 1.7.10
* @version 1.7.18
*/
function bookacti_controller_update_template() {
$template_id = intval( $_POST['template-id'] );
@ -762,10 +762,10 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
bookacti_send_json_not_allowed( 'update_template' );
}
$template_title = sanitize_text_field( stripslashes( $_POST['template-title'] ) );
$template_start = bookacti_sanitize_date( $_POST['template-opening'] );
$template_end = bookacti_sanitize_date( $_POST['template-closing'] );
$template_title = sanitize_text_field( stripslashes( $_POST[ 'template-title' ] ) );
$template_start = bookacti_sanitize_date( $_POST[ 'template-opening' ] ) ? bookacti_sanitize_date( $_POST[ 'template-opening' ] ) : date( 'Y-m-d' );
$template_end = bookacti_sanitize_date( $_POST[ 'template-closing' ] ) ? bookacti_sanitize_date( $_POST[ 'template-closing' ] ) : '2037-12-31';
$is_template_valid = bookacti_validate_template_data( $template_title, $template_start, $template_end );
// Update template only if its data are consistent
@ -776,17 +776,14 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
$updated_template = bookacti_update_template( $template_id, $template_title, $template_start, $template_end );
$updated_metadata = 0;
if( isset( $_POST['templateOptions'] ) ) {
$template_settings = bookacti_format_template_settings( $_POST['templateOptions'] );
if( isset( $_POST[ 'templateOptions' ] ) ) {
$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();
@ -976,7 +975,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Create an association between existing activities (on various templates) and current template
* @version 1.7.10
* @version 1.7.15
*/
function bookacti_controller_import_activities() {
$template_id = intval( $_POST[ 'template_id' ] );
@ -1007,7 +1006,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
}
if( $inserted ) {
$activities_data = bookacti_get_activities_by_template( $template_id, false );
$activities_data = bookacti_get_activities_by_template( $template_id, false, true );
$activity_list = bookacti_get_template_activities_list( $template_id );
do_action( 'bookacti_activities_imported', $template_id, $activity_ids, $activities_data );
@ -1077,7 +1076,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Get activities by template
* @version 1.7.4
* @version 1.7.16
*/
function bookacti_controller_get_activities_by_template() {
@ -1092,13 +1091,14 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
if( $selected_template_id === $current_template_id ) { bookacti_send_json( array( 'status' => 'failed', 'error' => 'no_change' ), 'get_activities_by_template' ); }
$new_activities = bookacti_get_activities_by_template( $selected_template_id, false );
$new_activities = bookacti_get_activities_by_template( $selected_template_id, false, true );
$current_activities = bookacti_get_activity_ids_by_template( $current_template_id, false );
// Check activity permissions, and remove not allowed activity ids
$user_id = get_current_user_id();
foreach( $new_activities as $new_activity_id => $new_activity ) {
if( ! in_array( $new_activity_id, $current_activities ) ) {
$is_allowed = bookacti_user_can_manage_activity( $new_activity_id );
$is_allowed = bookacti_user_can_manage_activity( $new_activity_id, $user_id, $new_activity[ 'admin' ] );
if( ! $is_allowed || ! $new_activity[ 'active' ] ) {
unset( $new_activities[ $new_activity_id ] );
}

50
controller/controller-woocommerce-backend.php

@ -463,7 +463,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Bypass template manager check for shop managers
*
* @version 1.7.19
* @param boolean $allowed
* @return boolean
*/
@ -472,10 +472,11 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
}
add_filter( 'bookacti_bypass_template_managers_check', 'bookacti_bypass_checks_for_shop_managers', 10, 1 );
add_filter( 'bookacti_bypass_activity_managers_check', 'bookacti_bypass_checks_for_shop_managers', 10, 1 );
add_filter( 'bookacti_bypass_form_managers_check', 'bookacti_bypass_checks_for_shop_managers', 10, 1 );
// CUSTOM PRODUCTS OPTIONS
/**
@ -520,7 +521,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Content of the activity tab
* @version 1.7.12
* @version 1.7.16
* @global int $thepostid
*/
function bookacti_activity_tab_content() {
@ -612,7 +613,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
</div>
<div class='options_group bookacti-deprecated-hidden'>
<?php
$booking_methods_array = array_merge( array( 'site' => __( 'Site setting', 'booking-activities' ) ), bookacti_get_available_booking_methods() );
$booking_methods_array = bookacti_get_available_booking_methods();
woocommerce_wp_select(
array(
@ -829,17 +830,13 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Save custom activity product type and activity tab content
* @version 1.5.0
* @version 1.7.18
* @param int $post_id
*/
function bookacti_save_custom_product_type_and_tab_content( $post_id ) {
if( ! empty( $_POST['_bookacti_is_activity'] ) ) {
update_post_meta( $post_id, '_bookacti_is_activity', sanitize_text_field( 'yes' ) );
//Force the product to be flagged as virtual if it is an activity
if( empty( $_POST['_virtual'] ) ) {
update_post_meta( $post_id, '_virtual', wc_clean( 'yes' ) );
}
} else {
update_post_meta( $post_id, '_bookacti_is_activity', sanitize_text_field( 'no' ) );
}
@ -923,7 +920,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Add custom fields for activity variation product type
* @version 1.7.12
* @version 1.7.16
* @param int $loop
* @param array $variation_data
* @param WP_Post $variation
@ -1063,12 +1060,6 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
<option value='parent' <?php selected( true, $is_default_booking_method, true ); ?> >
<?php esc_html_e( 'Parent setting', 'booking-activities' ); ?>
</option>
<option value='site' <?php selected( 'site', esc_attr( $current_booking_method ), true ); ?> >
<?php
/* translators: This is an option in a select box that means 'Use the setting of the whole website' */
esc_html_e( 'Site setting', 'booking-activities' );
?>
</option>
<?php
$available_booking_methods = bookacti_get_available_booking_methods();
foreach( $available_booking_methods as $booking_method_id => $booking_method_label ) {
@ -1288,7 +1279,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Save custom variation product
* @version 1.5.0
* @version 1.7.18
* @param int $post_id
*/
function bookacti_save_variation_option( $post_id ) {
@ -1304,11 +1295,6 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
if ( isset( $_POST[ 'bookacti_variable_is_activity' ][ $key ] ) ) {
$variable_is_activity = $_POST[ 'bookacti_variable_is_activity' ][ $key ] === 'yes' ? 'yes' : 'no';
update_post_meta( $variation_id, 'bookacti_variable_is_activity', $variable_is_activity );
// Force the variation to be flagged as virtual if it is an activity
if( $variable_is_activity === 'yes' ) {
update_post_meta( $variation_id, '_virtual', 'yes' );
}
}
// Save form
@ -1325,8 +1311,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// Build array of available booking methods
$avail_booking_methods = array_keys( bookacti_get_available_booking_methods() );
$avail_booking_methods[] = 'parent';
$avail_booking_methods[] = 'site';
// Check selected booking methods against available ones
$sanitized_booking_method = sanitize_title_with_dashes( $_POST[ 'bookacti_variable_booking_method' ][ $key ] );
$variable_booking_method = in_array( $sanitized_booking_method, $avail_booking_methods, true ) ? $sanitized_booking_method : 'parent';
@ -1427,7 +1412,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* AJAX Controller - Migrate product or variation settings to a new booking form
* @since 1.5.0
* @version 1.7.12
* @version 1.7.17
*/
function bookacti_controller_migrate_product_settings_to_booking_form() {
$json_action = 'migrate_product_settings';
@ -1454,9 +1439,9 @@ 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 !== 'site' ? $booking_method : bookacti_get_setting_value( 'bookacti_general_settings', 'booking_method' ),
'method' => $booking_method,
'calendars' => get_post_meta( $product_id, '_bookacti_template', true ),
'activities' => get_post_meta( $product_id, '_bookacti_activity', true ),
'group_categories' => $group_categories,
@ -1478,7 +1463,6 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// Format variation meta
$booking_method = get_post_meta( $variation_id, 'bookacti_variable_booking_method', true );
if( $booking_method === 'site' ) { $booking_method = bookacti_get_setting_value( 'bookacti_general_settings', 'booking_method' ); }
$calendars = get_post_meta( $variation_id, 'bookacti_variable_template', true );
$activities = get_post_meta( $variation_id, 'bookacti_variable_activity', true );
$group_categories = get_post_meta( $variation_id, 'bookacti_variable_group_categories', true );
@ -1527,9 +1511,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 );

132
controller/controller-woocommerce-bookings.php

@ -237,16 +237,14 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Turn paid order status to complete if the order has only activities
*
* @version 1.5.8
* Turn paid order status to complete if the order has only virtual activities
* @version 1.7.18
* @param string $order_status
* @param int $order_id
* @return string
*/
function bookacti_set_order_status_to_completed_after_payment( $order_status, $order_id ) {
if( ! in_array( $order_status, array( 'processing', 'pending' ), true ) ) { return $order_status; }
if( ! in_array( $order_status, array( 'completed', 'processing', 'pending' ), true ) ) { return $order_status; }
$order = wc_get_order( $order_id );
if( empty( $order ) ) { return $order_status; }
@ -262,21 +260,33 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
break;
}
}
// Check if the order is only composed of activities
// Check if the order is only composed of (virtual) activities
$are_activities = true;
$are_virtual_activities = true;
foreach( $items as $item ) {
// Is activity
if( ! isset( $item[ 'bookacti_booking_id' ] ) && ! isset( $item[ 'bookacti_booking_group_id' ] ) ) {
$are_activities = false;
break;
}
// Is virtual
$product = $item[ 'variation_id' ] ? wc_get_product( $item[ 'variation_id' ] ) : wc_get_product( $item[ 'product_id' ] );
if( $product && ! $product->is_virtual() ) {
$are_virtual_activities = false;
}
}
// If there are only activities, mark the order as 'completed' and
// If there are only virtual activities, mark the order as 'completed' and
// a function hooked to woocommerce_order_status_completed will mark the activities as 'booked'
if( $are_activities ) {
if( $are_activities && $are_virtual_activities ) {
$order_status = 'completed';
// If there are only virtual activities, but not virtuals, mark the order as 'processing' and
// mark the activities as 'booked'
} else if( $are_activities ) {
$order_status = 'processing';
// If there are at least one activity in the middle of other products,
// we won't mark the order as 'completed', but we still need to mark the bookings as 'pending' and 'owed'
// until the order changes state. At that time the bookings state will be redefined by other hooks
@ -291,13 +301,12 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Turn bookings of a paid order containing non-activity products to booked
* @version 1.6.0
* Turn the bookings bound to order items of a paid order to booked
* @since 1.7.18 (was bookacti_turn_non_activity_order_bookings_to_permanent)
* @param int $order_id
* @param WC_Order $order
*/
function bookacti_turn_non_activity_order_bookings_to_permanent( $order_id, $order = null ) {
function bookacti_turn_paid_order_item_bookings_to_permanent( $order_id, $order = null ) {
if( ! $order ) { $order = wc_get_order( $order_id ); }
if( ! $order ) { return false; }
@ -312,31 +321,59 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
// Retrieve bought items
$items = $order->get_items();
// Check if the order has at least 1 activity
$has_activities = false;
foreach( $items as $item ) {
if( isset( $item[ 'bookacti_booking_id' ] ) || isset( $item[ 'bookacti_booking_group_id' ] ) ) {
$has_activities = true;
break;
}
}
// Check if the order is only composed of activities
$are_activities = true;
// Get virtual order item booking ids
$virtual_item_booking_ids = array();
$virtual_item_booking_group_ids = array();
$non_virtual_item_booking_ids = array();
$non_virtual_item_booking_group_ids = array();
foreach( $items as $item ) {
if( ! isset( $item[ 'bookacti_booking_id' ] ) && ! isset( $item[ 'bookacti_booking_group_id' ] ) ) {
$are_activities = false;
break;
// Is activity
if( ! isset( $item[ 'bookacti_booking_id' ] ) && ! isset( $item[ 'bookacti_booking_group_id' ] ) ) { continue; }
// Is virtual
$product = $item[ 'variation_id' ] ? wc_get_product( $item[ 'variation_id' ] ) : wc_get_product( $item[ 'product_id' ] );
if( ! $product ) { continue; }
if( $product->is_virtual() ) {
if( isset( $item[ 'bookacti_booking_id' ] ) ) { $virtual_item_booking_ids[] = $item[ 'bookacti_booking_id' ]; }
if( isset( $item[ 'bookacti_booking_group_id' ] ) ) { $virtual_item_booking_group_ids[] = $item[ 'bookacti_booking_group_id' ]; }
} else {
if( isset( $item[ 'bookacti_booking_id' ] ) ) { $non_virtual_item_booking_ids[] = $item[ 'bookacti_booking_id' ]; }
if( isset( $item[ 'bookacti_booking_group_id' ] ) ) { $non_virtual_item_booking_group_ids[] = $item[ 'bookacti_booking_group_id' ]; }
}
}
// If there are at least one activity in the middle of other products,
// mark the bookings as 'booked' and 'paid'
if( ! $are_activities && $has_activities ) {
// Allow plugins to change the default booking status of paid non virtual bookings
$non_virtual_booking_status = apply_filters( 'bookacti_paid_non_virtual_booking_status', 'booked' );
// Turn all order bookings to booked
if( $non_virtual_booking_status === 'booked' ) {
bookacti_turn_temporary_booking_to_permanent( $order_id, $order, 'booked', 'paid' );
} else {
$updated_bookings = array( 'booking_ids' => array(), 'booking_group_ids' => array() );
// Turn non virtual activities to their permanent booking status
if( $non_virtual_item_booking_ids || $non_virtual_item_booking_group_ids ) {
$updated_bookings = bookacti_turn_order_bookings_to( $order, $non_virtual_booking_status, 'paid', true, array( 'states_in' => array( 'in_cart', 'pending' ), 'in__booking_id' => $non_virtual_item_booking_ids, 'in__booking_group_id' => $non_virtual_item_booking_group_ids, 'is_new_order' => true ) );
if( $updated_bookings && is_numeric( $updated_bookings[ 'updated' ] ) && intval( $updated_bookings[ 'updated' ] ) === 0 ) {
$notification_args = array_merge( $updated_bookings, array( 'is_new_order' => true ) );
bookacti_send_notification_when_order_status_changes( $order_id, $non_virtual_booking_status, $notification_args );
}
}
// Turn virtual activities to booked in any case
if( $virtual_item_booking_ids || $virtual_item_booking_group_ids ) {
$updated_virtual_bookings = bookacti_turn_order_bookings_to( $order, 'booked', 'paid', true, array( 'states_in' => array( 'in_cart', 'pending' ), 'in__booking_id' => $virtual_item_booking_ids, 'in__booking_group_id' => $virtual_item_booking_group_ids ) );
if( $updated_virtual_bookings ) {
$updated_bookings[ 'booking_ids' ] = array_merge( $updated_bookings[ 'booking_ids' ], $updated_virtual_bookings[ 'booking_ids' ] );
$updated_bookings[ 'booking_group_ids' ]= array_merge( $updated_bookings[ 'booking_group_ids' ], $updated_virtual_bookings[ 'booking_group_ids' ] );
}
}
// Remove remaining undesired bookings
bookacti_cancel_order_pending_bookings( $order_id, $updated_bookings[ 'booking_ids' ], $updated_bookings[ 'booking_group_ids' ] );
}
}
add_action( 'woocommerce_order_status_pending_to_processing', 'bookacti_turn_non_activity_order_bookings_to_permanent', 5, 2 );
add_action( 'woocommerce_order_status_pending_to_processing', 'bookacti_turn_paid_order_item_bookings_to_permanent', 5, 2 );
add_action( 'woocommerce_order_status_pending_to_on-hold', 'bookacti_turn_paid_order_item_bookings_to_permanent', 5, 2 );
@ -925,31 +962,32 @@ if ( ! defined( 'ABSPATH' ) ) { exit; }
/**
* Turn order items booking status meta to new status
*
* @since 1.2.0
* @version 1.5.6
*
* @version 1.7.18
* @param WC_Order $order
* @param string $new_state
* @param array $args
*/
function bookacti_update_order_items_booking_status_by_order_id( $order, $new_state, $args ) {
if( is_numeric( $order ) ) {
$order = wc_get_order( $order );
}
if( is_numeric( $order ) ) { $order = wc_get_order( $order ); }
if( ! $order ) { return; }
$order_items = $order->get_items();
if( ! $order_items ) { return; }
foreach( $order_items as $order_item_id => $order_item ) {
$item = $order_item;
if( version_compare( WC_VERSION, '3.0.0', '<' ) ) {
$item[ 'id' ] = $order_item_id;
}
$in__booking_id = ! empty( $args[ 'booking_ids' ] ) ? $args[ 'booking_ids' ] : array();
$in__booking_group_id = ! empty( $args[ 'booking_group_ids' ] ) ? $args[ 'booking_group_ids' ] : array();
foreach( $order_items as $item_id => $item ) {
// Make sure the order item has a booking
if( ! isset( $item[ 'bookacti_booking_id' ] ) && ! isset( $item[ 'bookacti_booking_group_id' ] ) ) { continue; }
// Make sure the booking is part of those updated
if( isset( $item[ 'bookacti_booking_id' ] ) && ( $in__booking_id || $in__booking_group_id ) && ! in_array( $item[ 'bookacti_booking_id' ], $in__booking_id ) ) { continue; }
if( isset( $item[ 'bookacti_booking_group_id' ] ) && ( $in__booking_id || $in__booking_group_id ) && ! in_array( $item[ 'bookacti_booking_group_id' ], $in__booking_group_id ) ) { continue; }
if( version_compare( WC_VERSION, '3.0.0', '<' ) ) { $item[ 'id' ] = $item_id; }
// Do not allow to update order status based on new bookings status
// because this function is actually triggered after order status changed

216
controller/controller-woocommerce-forms.php

@ -57,6 +57,21 @@ function bookacti_form_editor_wc_description( $form ) {
add_action( 'bookacti_form_editor_description_after', 'bookacti_form_editor_wc_description', 20, 1 );
/**
* Display a WC notice in the form editor, Calendar field settings, "Actions" tab
* @since 1.7.15
* @param array $params
*/
function bookacti_form_action_wc_notice( $params ) {
?>
<div class='bookacti-form-action-wc-notice'>
<?php esc_html_e( 'The form action is not taken into account on WooCommerce product pages.', 'booking-activities' ); ?>
</div>
<?php
}
add_action( 'bookacti_calendar_dialog_actions_tab_after', 'bookacti_form_action_wc_notice', 10, 1 );
/**
* Set WC booking system attributes
* @since 1.7.0
@ -72,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
@ -92,57 +123,80 @@ 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;