Version Description
(2021-08-23) = - Updated the payment gateway option, so you can now offer PayPal and Stripe at the same time (your customers can choose which to use). - Fixed issue with Early Bookings feature were the X day option was calculating using hours instead of days. - Fixed an issue in which, if there was only one valid time slot left, it would sometimes not display as available. - Fixed an issue in which, if your set timezone was on a different day than UTC (e.g. near midnight), it would sometimes show the incorrect hours as available. - Fixed an issue loading the customizer for the email templates. - Fixed an issue causing the reservation reminder and late arrival notifications to still send if no time interval was specified. - Fixed an issue in which the red badge would still show beside the Bookings WP admin menu item even if there were no pending bookings.
Release Info
Developer | Rustaurius |
Plugin | Restaurant Reservations |
Version | 2.3.0 |
Comparing to | |
See all releases |
Code changes from version 2.2.12 to 2.3.0
- assets/css/admin.css +4 -0
- assets/js/stripe-payment.js +7 -1
- includes/Ajax.class.php +11 -169
- includes/Booking.class.php +72 -10
- includes/Cron.class.php +10 -11
- includes/CustomPostTypes.class.php +4 -8
- includes/Migration.class.php +62 -0
- includes/PaymentGateway.interface.php +41 -0
- includes/PaymentGatewayPayPal.class.php +216 -0
- includes/PaymentGatewayStripe.class.php +462 -0
- includes/PaymentManager.class.php +710 -0
- includes/Settings.class.php +145 -375
- includes/WP_List_Table.BookingsTable.class.php +4 -1
- includes/load-customizer.php +3 -1
- includes/template-functions.php +36 -341
- lib/simple-admin-pages/classes/AdminPage.class.php +27 -16
- lib/simple-admin-pages/classes/AdminPageSetting.Checkbox.class.php +17 -2
- lib/simple-admin-pages/classes/Library.class.php +1 -0
- lib/simple-admin-pages/js/count.js +9 -4
- readme.txt +10 -1
- restaurant-reservations.php +22 -2
@@ -2707,3 +2707,7 @@ NEW DATE SELETION FILTERS
|
|
2707 |
color: #555;
|
2708 |
}
|
2709 |
|
|
|
|
|
|
|
|
2707 |
color: #555;
|
2708 |
}
|
2709 |
|
2710 |
+
|
2711 |
+
.bookings_page_rtb-settings .wrap h1 {
|
2712 |
+
width: 100%;
|
2713 |
+
}
|
@@ -144,7 +144,13 @@ jQuery(document).ready(function($) {
|
|
144 |
result = JSON.parse(result);
|
145 |
|
146 |
if(true == result.success) {
|
147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
}
|
149 |
});
|
150 |
});
|
144 |
result = JSON.parse(result);
|
145 |
|
146 |
if(true == result.success) {
|
147 |
+
var url = new URL(window.location.pathname, window.location.origin);
|
148 |
+
|
149 |
+
for(const [key, value] of Object.entries(result.urlParams)) {
|
150 |
+
url.searchParams.append(key, value);
|
151 |
+
}
|
152 |
+
|
153 |
+
window.location = url.href;
|
154 |
}
|
155 |
});
|
156 |
});
|
@@ -55,12 +55,6 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
55 |
|
56 |
add_action( 'wp_ajax_rtb_get_available_tables', array( $this, 'get_available_tables' ) );
|
57 |
add_action( 'wp_ajax_nopriv_rtb_get_available_tables', array( $this, 'get_available_tables' ) );
|
58 |
-
|
59 |
-
add_action( 'wp_ajax_rtb_stripe_get_intent', array( $this, 'create_stripe_pmtIntnt' ) );
|
60 |
-
add_action( 'wp_ajax_nopriv_rtb_stripe_get_intent', array( $this, 'create_stripe_pmtIntnt' ) );
|
61 |
-
|
62 |
-
add_action( 'wp_ajax_rtb_stripe_pmt_succeed', array( $this, 'stripe_sca_succeed' ) );
|
63 |
-
add_action( 'wp_ajax_nopriv_rtb_stripe_pmt_succeed', array( $this, 'stripe_sca_succeed' ) );
|
64 |
}
|
65 |
|
66 |
/**
|
@@ -304,7 +298,7 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
304 |
];
|
305 |
}
|
306 |
$all_bookings_by_slots[$booking_time]['total_bookings']++;
|
307 |
-
$all_bookings_by_slots[$booking_time]['total_guest'] += $booking->party;
|
308 |
|
309 |
/**
|
310 |
* Expanding bookings
|
@@ -324,7 +318,7 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
324 |
}
|
325 |
$all_bookings_by_slots[$next]['overlapped'] = true;
|
326 |
$all_bookings_by_slots[$next]['total_bookings']++;
|
327 |
-
$all_bookings_by_slots[$next]['total_guest'] += $booking->party;
|
328 |
$next += $interval;
|
329 |
}
|
330 |
}
|
@@ -412,7 +406,7 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
412 |
// consolidating timeslots to timeframes
|
413 |
$timeframe = [];
|
414 |
$available_slots_count = count( $available_slots );
|
415 |
-
if(
|
416 |
|
417 |
$current_pair = [ 'from' => $available_slots[ 0 ] ];
|
418 |
|
@@ -543,13 +537,6 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
543 |
public function get_earliest_time( $open_time ) {
|
544 |
global $rtb_controller;
|
545 |
|
546 |
-
// Only make adjustments for current day selections
|
547 |
-
if ( date( 'y-m-d', strtotime( $this->year . '-' . $this->month . '-' . $this->day ) ) !== date( 'y-m-d' ) ) {
|
548 |
-
return $open_time;
|
549 |
-
}
|
550 |
-
|
551 |
-
$late_bookings = ( is_admin() && current_user_can( 'manage_bookings' ) ) ? '' : $rtb_controller->settings->get_setting( 'late-bookings' );
|
552 |
-
|
553 |
$interval = $rtb_controller->settings->get_setting( 'time-interval' ) * 60;
|
554 |
|
555 |
$timezone = wp_timezone();
|
@@ -557,6 +544,14 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
557 |
|
558 |
// adjust open time with respect to the current time of the day for upcoming timeslots
|
559 |
$current_time = time() + $offset;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
560 |
if( $current_time > $open_time ) {
|
561 |
while( $current_time > $open_time ) {
|
562 |
$open_time += $interval;
|
@@ -835,158 +830,5 @@ if ( !class_exists( 'rtbAJAX' ) ) {
|
|
835 |
public function format_pickadate_time( $time ) {
|
836 |
return array( date( 'G', $time ), date( 'i', $time ) );
|
837 |
}
|
838 |
-
|
839 |
-
/**
|
840 |
-
* Create Stripe payment intent for reservation deposits
|
841 |
-
* @since 2.2.8
|
842 |
-
*/
|
843 |
-
function create_stripe_pmtIntnt()
|
844 |
-
{
|
845 |
-
global $rtb_controller;
|
846 |
-
|
847 |
-
$response = function ($success, $msg, $data = []) {
|
848 |
-
echo json_encode(
|
849 |
-
array_merge(
|
850 |
-
[
|
851 |
-
'success' => $success,
|
852 |
-
'message' => $msg
|
853 |
-
],
|
854 |
-
$data
|
855 |
-
)
|
856 |
-
);
|
857 |
-
|
858 |
-
exit(0);
|
859 |
-
};
|
860 |
-
|
861 |
-
if( ! array_key_exists('booking_id', $_POST) ) {
|
862 |
-
$response(false, 'Invalid booking.');
|
863 |
-
}
|
864 |
-
|
865 |
-
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
866 |
-
$booking = new rtbBooking();
|
867 |
-
$booking->load_post( $_POST['booking_id'] );
|
868 |
-
|
869 |
-
$payment_amount = "JPY" != $rtb_controller->settings->get_setting( 'rtb-currency' )
|
870 |
-
? $booking->calculate_deposit() * 100
|
871 |
-
: $booking->calculate_deposit();
|
872 |
-
|
873 |
-
// load the stripe libraries
|
874 |
-
require_once(RTB_PLUGIN_DIR . '/lib/stripe/init.php');
|
875 |
-
|
876 |
-
$stripe_secret = 'test' == $rtb_controller->settings->get_setting( 'rtb-stripe-mode' )
|
877 |
-
? $rtb_controller->settings->get_setting( 'rtb-stripe-test-secret' )
|
878 |
-
: $rtb_controller->settings->get_setting( 'rtb-stripe-live-secret' );
|
879 |
-
|
880 |
-
try {
|
881 |
-
\Stripe\Stripe::setApiKey( $stripe_secret );
|
882 |
-
|
883 |
-
// $customer = \Stripe\Customer::create([
|
884 |
-
// 'email' => $booking->email,
|
885 |
-
// 'name' => $booking->name
|
886 |
-
// ]);
|
887 |
-
|
888 |
-
// $booking->stripe_customer_id = $customer->id;
|
889 |
-
// $booking->insert_post_data();
|
890 |
-
|
891 |
-
$metadata = array_filter([
|
892 |
-
'Booking ID' => $booking->ID,
|
893 |
-
'Email' => $booking->email,
|
894 |
-
'Name' => $booking->name,
|
895 |
-
'Date' => $booking->date,
|
896 |
-
'Party' => $booking->party
|
897 |
-
]);
|
898 |
-
|
899 |
-
if( is_array( $booking->table ) && ! empty( $booking->table ) ) {
|
900 |
-
$metadata['Table'] = implode('+', $booking->table);
|
901 |
-
}
|
902 |
-
|
903 |
-
$desc = implode(', ', $metadata );
|
904 |
-
$stmt_desc = substr( implode( ';', $metadata ), 0, 22 );
|
905 |
-
|
906 |
-
$intent = \Stripe\PaymentIntent::create([
|
907 |
-
'amount' => $payment_amount,
|
908 |
-
'currency' => $rtb_controller->settings->get_setting( 'rtb-currency' ),
|
909 |
-
'payment_method_types' => ['card'],
|
910 |
-
'receipt_email' => $booking->email,
|
911 |
-
'description' => apply_filters( 'rtb-stripe-payment-desc', $desc ),
|
912 |
-
'statement_descriptor' => apply_filters( 'rtb-stripe-payment-stmnt-desc', $stmt_desc ),
|
913 |
-
'metadata' => $metadata
|
914 |
-
]);
|
915 |
-
|
916 |
-
$response(
|
917 |
-
true,
|
918 |
-
'Payment Intent generated succsssfully',
|
919 |
-
[
|
920 |
-
'clientSecret' => $intent->client_secret,
|
921 |
-
'name' => $booking->name,
|
922 |
-
'email' => $booking->email,
|
923 |
-
]
|
924 |
-
);
|
925 |
-
}
|
926 |
-
catch(Exception $ex) {
|
927 |
-
$response( false, 'Please try again.', ['error' => $ex->getError()] );
|
928 |
-
}
|
929 |
-
}
|
930 |
-
|
931 |
-
/**
|
932 |
-
* Stripe SCA payment success for reservation deposits
|
933 |
-
* @since 2.2.8
|
934 |
-
*/
|
935 |
-
public function stripe_sca_succeed()
|
936 |
-
{
|
937 |
-
global $rtb_controller;
|
938 |
-
|
939 |
-
$response = function ($success = false, $urlParams = '') {
|
940 |
-
echo json_encode([
|
941 |
-
'success' => $success,
|
942 |
-
'urlParams' => $urlParams
|
943 |
-
]);
|
944 |
-
|
945 |
-
exit(0);
|
946 |
-
};
|
947 |
-
|
948 |
-
$success = false;
|
949 |
-
$urlParams = '';
|
950 |
-
|
951 |
-
if( ! array_key_exists('booking_id', $_POST) ) {
|
952 |
-
$response();
|
953 |
-
}
|
954 |
-
|
955 |
-
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
956 |
-
$booking = new rtbBooking();
|
957 |
-
$booking->load_post( $_POST['booking_id'] );
|
958 |
-
|
959 |
-
if( array_key_exists('success', $_POST) && 'false' != $_POST['success'] ) {
|
960 |
-
|
961 |
-
$booking->deposit = "JPY" != $rtb_controller->settings->get_setting( 'rtb-currency' )
|
962 |
-
? $_POST['payment_amount'] / 100
|
963 |
-
: $_POST['payment_amount'];
|
964 |
-
|
965 |
-
$booking->receipt_id = $_POST['payment_id'];
|
966 |
-
$booking->determine_status( true );
|
967 |
-
|
968 |
-
do_action( 'rtb_booking_paid', $booking );
|
969 |
-
|
970 |
-
// urlParams on successful payment
|
971 |
-
$success = true;
|
972 |
-
$urlParams = add_query_arg(
|
973 |
-
array(
|
974 |
-
'payment' => 'paid',
|
975 |
-
'booking_id' => $booking->ID
|
976 |
-
),
|
977 |
-
$booking_page
|
978 |
-
);
|
979 |
-
|
980 |
-
}
|
981 |
-
else {
|
982 |
-
$booking->post_status = 'payment_failed';
|
983 |
-
$booking->payment_failure_message = ! empty( $_POST['message'] )
|
984 |
-
? $_POST['message'] : '';
|
985 |
-
}
|
986 |
-
|
987 |
-
$booking->insert_post_data();
|
988 |
-
|
989 |
-
$response($success, $urlParams);
|
990 |
-
}
|
991 |
}
|
992 |
}
|
55 |
|
56 |
add_action( 'wp_ajax_rtb_get_available_tables', array( $this, 'get_available_tables' ) );
|
57 |
add_action( 'wp_ajax_nopriv_rtb_get_available_tables', array( $this, 'get_available_tables' ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
}
|
59 |
|
60 |
/**
|
298 |
];
|
299 |
}
|
300 |
$all_bookings_by_slots[$booking_time]['total_bookings']++;
|
301 |
+
$all_bookings_by_slots[$booking_time]['total_guest'] += intval( $booking->party );
|
302 |
|
303 |
/**
|
304 |
* Expanding bookings
|
318 |
}
|
319 |
$all_bookings_by_slots[$next]['overlapped'] = true;
|
320 |
$all_bookings_by_slots[$next]['total_bookings']++;
|
321 |
+
$all_bookings_by_slots[$next]['total_guest'] += intval( $booking->party );
|
322 |
$next += $interval;
|
323 |
}
|
324 |
}
|
406 |
// consolidating timeslots to timeframes
|
407 |
$timeframe = [];
|
408 |
$available_slots_count = count( $available_slots );
|
409 |
+
if( 0 < $available_slots_count ) {
|
410 |
|
411 |
$current_pair = [ 'from' => $available_slots[ 0 ] ];
|
412 |
|
537 |
public function get_earliest_time( $open_time ) {
|
538 |
global $rtb_controller;
|
539 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
540 |
$interval = $rtb_controller->settings->get_setting( 'time-interval' ) * 60;
|
541 |
|
542 |
$timezone = wp_timezone();
|
544 |
|
545 |
// adjust open time with respect to the current time of the day for upcoming timeslots
|
546 |
$current_time = time() + $offset;
|
547 |
+
|
548 |
+
// Only make adjustments for current day selections
|
549 |
+
if ( date( 'y-m-d', strtotime( "{$this->year}-{$this->month}-{$this->day}" ) ) !== date( 'y-m-d', $current_time) ) {
|
550 |
+
return $open_time;
|
551 |
+
}
|
552 |
+
|
553 |
+
$late_bookings = ( is_admin() && current_user_can( 'manage_bookings' ) ) ? '' : $rtb_controller->settings->get_setting( 'late-bookings' );
|
554 |
+
|
555 |
if( $current_time > $open_time ) {
|
556 |
while( $current_time > $open_time ) {
|
557 |
$open_time += $interval;
|
830 |
public function format_pickadate_time( $time ) {
|
831 |
return array( date( 'G', $time ), date( 'i', $time ) );
|
832 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
833 |
}
|
834 |
}
|
@@ -23,6 +23,13 @@ class rtbBooking {
|
|
23 |
*/
|
24 |
public $request_inserted = false;
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
public function __construct() {}
|
27 |
|
28 |
/**
|
@@ -86,7 +93,6 @@ class rtbBooking {
|
|
86 |
'table' => array(),
|
87 |
'payment_failure_message' => '',
|
88 |
'receipt_id' => '',
|
89 |
-
'stripe_customer_id' => '',
|
90 |
'reminder_sent' => false,
|
91 |
'late_arrival_sent' => false,
|
92 |
);
|
@@ -110,7 +116,6 @@ class rtbBooking {
|
|
110 |
$this->table = $meta['table'];
|
111 |
$this->payment_failure_message = $meta['payment_failure_message'];
|
112 |
$this->receipt_id = $meta['receipt_id'];
|
113 |
-
$this->stripe_customer_id = $meta['stripe_customer_id'];
|
114 |
$this->late_arrival_sent = $meta['late_arrival_sent'];
|
115 |
$this->reminder_sent = $meta['reminder_sent'];
|
116 |
}
|
@@ -207,6 +212,39 @@ class rtbBooking {
|
|
207 |
|
208 |
/**
|
209 |
* Validate submission data. Expects to find data in $_POST.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
* @since 0.0.1
|
211 |
*/
|
212 |
public function validate_submission($action = null, $by_admin = false) {
|
@@ -214,6 +252,11 @@ class rtbBooking {
|
|
214 |
global $rtb_controller;
|
215 |
|
216 |
$this->validation_errors = array();
|
|
|
|
|
|
|
|
|
|
|
217 |
|
218 |
// Date
|
219 |
$date = empty( $_POST['rtb-date'] ) ? false : stripslashes_deep( $_POST['rtb-date'] );
|
@@ -267,8 +310,10 @@ class rtbBooking {
|
|
267 |
|
268 |
$early_bookings = $rtb_controller->settings->get_setting( 'early-bookings' );
|
269 |
if ( !empty( $early_bookings ) ) {
|
270 |
-
$
|
271 |
-
|
|
|
|
|
272 |
$this->validation_errors[] = array(
|
273 |
'field' => 'time',
|
274 |
'error_msg' => 'Booking request too far in the future',
|
@@ -487,7 +532,7 @@ class rtbBooking {
|
|
487 |
// Table
|
488 |
$table = empty( $_POST['rtb-table'] ) ? array() : explode( ',', sanitize_text_field( stripslashes_deep( $_POST['rtb-table'] ) ) );
|
489 |
$this->table = is_array( $table ) ? array_map( 'sanitize_text_field', $table ) : array();
|
490 |
-
|
491 |
$table_required = $rtb_controller->settings->get_setting( 'require-table' );
|
492 |
if ( $table_required && empty( $this->table ) ) {
|
493 |
$this->validation_errors[] = array(
|
@@ -860,7 +905,7 @@ class rtbBooking {
|
|
860 |
if ( isset( $this->ID ) and $booking->ID == $this->ID ) { continue; }
|
861 |
|
862 |
$booking_time = strtotime( $booking->date );
|
863 |
-
if ( isset( $times[$booking_time] ) ) { $times[$booking_time] += $booking->party; }
|
864 |
else { $times[$booking_time] = (int) $booking->party; }
|
865 |
}
|
866 |
|
@@ -1183,10 +1228,6 @@ class rtbBooking {
|
|
1183 |
$meta['receipt_id'] = $this->receipt_id;
|
1184 |
}
|
1185 |
|
1186 |
-
if ( !empty( $this->stripe_customer_id ) ) {
|
1187 |
-
$meta['stripe_customer_id'] = $this->stripe_customer_id;
|
1188 |
-
}
|
1189 |
-
|
1190 |
if ( !empty( $this->reminder_sent ) ) {
|
1191 |
$meta['reminder_sent'] = $this->reminder_sent;
|
1192 |
}
|
@@ -1200,5 +1241,26 @@ class rtbBooking {
|
|
1200 |
return update_post_meta( $this->ID, 'rtb', $meta );
|
1201 |
}
|
1202 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1203 |
}
|
1204 |
} // endif;
|
23 |
*/
|
24 |
public $request_inserted = false;
|
25 |
|
26 |
+
/**
|
27 |
+
* Raw input, clone of $_POST
|
28 |
+
* @var array
|
29 |
+
* @since 2.3.0
|
30 |
+
*/
|
31 |
+
public $raw_input = array();
|
32 |
+
|
33 |
public function __construct() {}
|
34 |
|
35 |
/**
|
93 |
'table' => array(),
|
94 |
'payment_failure_message' => '',
|
95 |
'receipt_id' => '',
|
|
|
96 |
'reminder_sent' => false,
|
97 |
'late_arrival_sent' => false,
|
98 |
);
|
116 |
$this->table = $meta['table'];
|
117 |
$this->payment_failure_message = $meta['payment_failure_message'];
|
118 |
$this->receipt_id = $meta['receipt_id'];
|
|
|
119 |
$this->late_arrival_sent = $meta['late_arrival_sent'];
|
120 |
$this->reminder_sent = $meta['reminder_sent'];
|
121 |
}
|
212 |
|
213 |
/**
|
214 |
* Validate submission data. Expects to find data in $_POST.
|
215 |
+
*
|
216 |
+
* ************************** NOTE **************************
|
217 |
+
* This function also create and assign all the required member variable with
|
218 |
+
* the acurate values which will be insreted in the DB. One special member,
|
219 |
+
* raw_input of type array holds the exact copy of $_POST
|
220 |
+
*
|
221 |
+
* Example:
|
222 |
+
* class a {
|
223 |
+
* public function a() {
|
224 |
+
* $this->name = 'John Doe';
|
225 |
+
* }
|
226 |
+
* public function b() {
|
227 |
+
* echo $this->name;
|
228 |
+
* }
|
229 |
+
* }
|
230 |
+
*
|
231 |
+
* $a = new a();
|
232 |
+
*
|
233 |
+
* var_dump($a);
|
234 |
+
* object(a)#1 (0) {
|
235 |
+
* }
|
236 |
+
*
|
237 |
+
* $a->a();
|
238 |
+
*
|
239 |
+
* var_dump($a);
|
240 |
+
* object(a)#1 (1) {
|
241 |
+
* ["name"]=>
|
242 |
+
* string(8) "John Doe"
|
243 |
+
* }
|
244 |
+
*
|
245 |
+
* $a->b();
|
246 |
+
* John Doe
|
247 |
+
*
|
248 |
* @since 0.0.1
|
249 |
*/
|
250 |
public function validate_submission($action = null, $by_admin = false) {
|
252 |
global $rtb_controller;
|
253 |
|
254 |
$this->validation_errors = array();
|
255 |
+
/**
|
256 |
+
* Raw, unprocessed value so that it can be used to preselect the form
|
257 |
+
* field values, eg. table
|
258 |
+
*/
|
259 |
+
$this->raw_input = $_POST;
|
260 |
|
261 |
// Date
|
262 |
$date = empty( $_POST['rtb-date'] ) ? false : stripslashes_deep( $_POST['rtb-date'] );
|
310 |
|
311 |
$early_bookings = $rtb_controller->settings->get_setting( 'early-bookings' );
|
312 |
if ( !empty( $early_bookings ) ) {
|
313 |
+
$uppar_bound = ( new DateTime( 'now' ) )->setTime( 23, 59 );
|
314 |
+
$uppar_bound->add( new DateInterval( "P{$early_bookings}D" ) );
|
315 |
+
|
316 |
+
if ( $request > $uppar_bound ) {
|
317 |
$this->validation_errors[] = array(
|
318 |
'field' => 'time',
|
319 |
'error_msg' => 'Booking request too far in the future',
|
532 |
// Table
|
533 |
$table = empty( $_POST['rtb-table'] ) ? array() : explode( ',', sanitize_text_field( stripslashes_deep( $_POST['rtb-table'] ) ) );
|
534 |
$this->table = is_array( $table ) ? array_map( 'sanitize_text_field', $table ) : array();
|
535 |
+
|
536 |
$table_required = $rtb_controller->settings->get_setting( 'require-table' );
|
537 |
if ( $table_required && empty( $this->table ) ) {
|
538 |
$this->validation_errors[] = array(
|
905 |
if ( isset( $this->ID ) and $booking->ID == $this->ID ) { continue; }
|
906 |
|
907 |
$booking_time = strtotime( $booking->date );
|
908 |
+
if ( isset( $times[$booking_time] ) ) { $times[$booking_time] += intval( $booking->party ); }
|
909 |
else { $times[$booking_time] = (int) $booking->party; }
|
910 |
}
|
911 |
|
1228 |
$meta['receipt_id'] = $this->receipt_id;
|
1229 |
}
|
1230 |
|
|
|
|
|
|
|
|
|
1231 |
if ( !empty( $this->reminder_sent ) ) {
|
1232 |
$meta['reminder_sent'] = $this->reminder_sent;
|
1233 |
}
|
1241 |
return update_post_meta( $this->ID, 'rtb', $meta );
|
1242 |
}
|
1243 |
|
1244 |
+
public function payment_paid()
|
1245 |
+
{
|
1246 |
+
if( isset( $this->ID ) ) {
|
1247 |
+
$this->determine_status( true );
|
1248 |
+
|
1249 |
+
$this->insert_post_data();
|
1250 |
+
|
1251 |
+
do_action( 'rtb_booking_paid', $this );
|
1252 |
+
}
|
1253 |
+
}
|
1254 |
+
|
1255 |
+
public function payment_failed( $message = '' )
|
1256 |
+
{
|
1257 |
+
$this->post_status = 'payment_failed';
|
1258 |
+
$this->payment_failure_message = $message;
|
1259 |
+
|
1260 |
+
$this->insert_post_data();
|
1261 |
+
|
1262 |
+
do_action( 'rtb_booking_paid', $this );
|
1263 |
+
}
|
1264 |
+
|
1265 |
}
|
1266 |
} // endif;
|
@@ -155,11 +155,7 @@ class rtbCron {
|
|
155 |
public function get_late_arrival_posts() {
|
156 |
global $rtb_controller;
|
157 |
|
158 |
-
$
|
159 |
-
$count = substr( $late_arrival_time, 0, strpos( $late_arrival_time, "_" ) );
|
160 |
-
$unit = substr( $late_arrival_time, strpos( $late_arrival_time, "_" ) + 1 );
|
161 |
-
|
162 |
-
$time_interval = $this->get_time_interval( $count, $unit );
|
163 |
|
164 |
$after_datetime = new DateTime( 'now', wp_timezone() );
|
165 |
$before_datetime = new DateTime( 'now', wp_timezone() );
|
@@ -192,11 +188,7 @@ class rtbCron {
|
|
192 |
public function get_reminder_posts() {
|
193 |
global $rtb_controller;
|
194 |
|
195 |
-
$
|
196 |
-
$count = substr( $reminder_time, 0, strpos( $reminder_time, "_" ) );
|
197 |
-
$unit = substr( $reminder_time, strpos( $reminder_time, "_" ) + 1 );
|
198 |
-
|
199 |
-
$time_interval = $this->get_time_interval( $count, $unit );
|
200 |
|
201 |
$after_datetime = new DateTime( 'now', wp_timezone() );
|
202 |
$before_datetime = new DateTime( 'now', wp_timezone() );
|
@@ -227,7 +219,14 @@ class rtbCron {
|
|
227 |
*
|
228 |
* @since 2.0.0
|
229 |
*/
|
230 |
-
public function get_time_interval( $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
switch ($unit) {
|
232 |
case 'days':
|
233 |
$multiplier = 24*3600;
|
155 |
public function get_late_arrival_posts() {
|
156 |
global $rtb_controller;
|
157 |
|
158 |
+
$time_interval = $this->get_time_interval( 'time-late-user' );
|
|
|
|
|
|
|
|
|
159 |
|
160 |
$after_datetime = new DateTime( 'now', wp_timezone() );
|
161 |
$before_datetime = new DateTime( 'now', wp_timezone() );
|
188 |
public function get_reminder_posts() {
|
189 |
global $rtb_controller;
|
190 |
|
191 |
+
$time_interval = $this->get_time_interval( 'time-reminder-user' );
|
|
|
|
|
|
|
|
|
192 |
|
193 |
$after_datetime = new DateTime( 'now', wp_timezone() );
|
194 |
$before_datetime = new DateTime( 'now', wp_timezone() );
|
219 |
*
|
220 |
* @since 2.0.0
|
221 |
*/
|
222 |
+
public function get_time_interval( $setting ) {
|
223 |
+
global $rtb_controller;
|
224 |
+
|
225 |
+
$late_arrival_time = $rtb_controller->settings->get_setting( $setting );
|
226 |
+
|
227 |
+
$count = intval( substr( $late_arrival_time, 0, strpos( $late_arrival_time, "_" ) ) );
|
228 |
+
$unit = substr( $late_arrival_time, strpos( $late_arrival_time, "_" ) + 1 );
|
229 |
+
|
230 |
switch ($unit) {
|
231 |
case 'days':
|
232 |
$multiplier = 24*3600;
|
@@ -379,13 +379,9 @@ class rtbCustomPostTypes {
|
|
379 |
*/
|
380 |
public function show_pending_count() {
|
381 |
|
382 |
-
$
|
383 |
-
|
384 |
-
|
385 |
-
global $rtb_controller;
|
386 |
-
$rtb_controller->cpts->update_pending_count();
|
387 |
-
$pending_count = get_option( 'rtb_pending_count', 0 );
|
388 |
-
}
|
389 |
|
390 |
if ( !$pending_count ) {
|
391 |
return;
|
@@ -420,7 +416,7 @@ class rtbCustomPostTypes {
|
|
420 |
$current_date_time = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) - HOUR_IN_SECONDS );
|
421 |
$count = $wpdb->get_var(
|
422 |
$wpdb->prepare(
|
423 |
-
"SELECT COUNT(
|
424 |
RTB_BOOKING_POST_TYPE,
|
425 |
$current_date_time
|
426 |
)
|
379 |
*/
|
380 |
public function show_pending_count() {
|
381 |
|
382 |
+
global $rtb_controller;
|
383 |
+
$rtb_controller->cpts->update_pending_count();
|
384 |
+
$pending_count = get_option( 'rtb_pending_count', 0 );
|
|
|
|
|
|
|
|
|
385 |
|
386 |
if ( !$pending_count ) {
|
387 |
return;
|
416 |
$current_date_time = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) - HOUR_IN_SECONDS );
|
417 |
$count = $wpdb->get_var(
|
418 |
$wpdb->prepare(
|
419 |
+
"SELECT COUNT(ID) FROM {$wpdb->prefix}posts WHERE post_type=%s AND post_status='pending' AND post_date>=%s;",
|
420 |
RTB_BOOKING_POST_TYPE,
|
421 |
$current_date_time
|
422 |
)
|
@@ -12,6 +12,10 @@ class rtbMigrationManager {
|
|
12 |
public function __construct() {
|
13 |
|
14 |
$this->convert_draft_status_to_payment_pending_status();
|
|
|
|
|
|
|
|
|
15 |
}
|
16 |
|
17 |
|
@@ -40,6 +44,64 @@ class rtbMigrationManager {
|
|
40 |
`post_status` = 'draft' AND `post_type` = 'rtb-booking'
|
41 |
");
|
42 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
44 |
|
45 |
}
|
12 |
public function __construct() {
|
13 |
|
14 |
$this->convert_draft_status_to_payment_pending_status();
|
15 |
+
|
16 |
+
$this->convert_payment_gateway_setting();
|
17 |
+
|
18 |
+
$this->update_invalid_setting_values();
|
19 |
}
|
20 |
|
21 |
|
44 |
`post_status` = 'draft' AND `post_type` = 'rtb-booking'
|
45 |
");
|
46 |
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Update the rtb-payment-gateway setting from string to array
|
50 |
+
* Previously this setting was a radio, now it is a checkbox.
|
51 |
+
*
|
52 |
+
* @since 2.3.0
|
53 |
+
*/
|
54 |
+
public function convert_payment_gateway_setting()
|
55 |
+
{
|
56 |
+
$settings_page = 'rtb-settings';
|
57 |
+
$options = get_option( $settings_page );
|
58 |
+
|
59 |
+
if( ! is_array( $options['rtb-payment-gateway'] ) && version_compare( RTB_VERSION, '2.2.11', '>' ) ) {
|
60 |
+
$options['rtb-payment-gateway'] = [ $options['rtb-payment-gateway'] ];
|
61 |
+
|
62 |
+
update_option( $settings_page, $options, true);
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Update setting of type count, which are 'time-reminder-user' and
|
68 |
+
* 'time-late-user'. When no value is being set in admin, it has underscore
|
69 |
+
* at least. Whereas, its expected to be empty
|
70 |
+
*
|
71 |
+
* @since 2.3.1
|
72 |
+
*/
|
73 |
+
public function update_invalid_setting_values() {
|
74 |
+
$settings_page = 'rtb-settings';
|
75 |
+
$options = get_option( $settings_page );
|
76 |
+
|
77 |
+
if(
|
78 |
+
is_array( $options )
|
79 |
+
&&
|
80 |
+
isset( $options['time-reminder-user'] )
|
81 |
+
&&
|
82 |
+
'_' == $options['time-reminder-user']
|
83 |
+
&&
|
84 |
+
version_compare( RTB_VERSION, '2.2.11', '>' )
|
85 |
+
)
|
86 |
+
{
|
87 |
+
$options['time-reminder-user'] = '';
|
88 |
+
}
|
89 |
+
|
90 |
+
if(
|
91 |
+
is_array( $options )
|
92 |
+
&&
|
93 |
+
isset( $options['time-late-user'] )
|
94 |
+
&&
|
95 |
+
'_' == $options['time-late-user']
|
96 |
+
&&
|
97 |
+
version_compare( RTB_VERSION, '2.2.11', '>' )
|
98 |
+
)
|
99 |
+
{
|
100 |
+
$options['time-late-user'] = '';
|
101 |
+
}
|
102 |
+
|
103 |
+
update_option( $settings_page, $options, true);
|
104 |
+
}
|
105 |
}
|
106 |
|
107 |
}
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( !defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
if ( !interface_exists( 'rtbPaymentGateway' ) ) {
|
5 |
+
/**
|
6 |
+
* Base interface to implement a Payment Gateway for Restaurant Reservations
|
7 |
+
*
|
8 |
+
* This class enforces the Payment Gateway base settings and their processing
|
9 |
+
* methods. This class should be implemented for each type of
|
10 |
+
* Payment Gateway. So, there would be a rtbPaymentStripe class or a
|
11 |
+
* rtbPaymentPayPal class.
|
12 |
+
*
|
13 |
+
* @since 2.3.0
|
14 |
+
*/
|
15 |
+
interface rtbPaymentGateway {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Register the gateway.
|
19 |
+
*
|
20 |
+
* $gateway_list['stripe'] => [
|
21 |
+
* 'label' => __( 'Stripe', 'restaurant-reservations' ),
|
22 |
+
* 'instance' => $this
|
23 |
+
* ];
|
24 |
+
*
|
25 |
+
* @param array $gateway_list
|
26 |
+
* @return array $gateway_list
|
27 |
+
*/
|
28 |
+
public static function register_gateway( array $gateway_list );
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Print the payment form. The booking has been made and is on payment_pending
|
32 |
+
* status. Display the payment form/button here
|
33 |
+
*
|
34 |
+
* @param rtbBooking $booking booking for which the payment is required
|
35 |
+
* @return void Print the HTML
|
36 |
+
*/
|
37 |
+
public function print_payment_form( $booking );
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
}
|
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( !defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
if ( !class_exists( 'rtbPaymentGatewayPayPal' ) ) {
|
5 |
+
/**
|
6 |
+
* This class is responsible for payment processing via Paypal
|
7 |
+
*
|
8 |
+
* @since 2.3.0
|
9 |
+
*/
|
10 |
+
class rtbPaymentGatewayPayPal implements rtbPaymentGateway {
|
11 |
+
|
12 |
+
private static $_instance;
|
13 |
+
|
14 |
+
private final function __construct() {
|
15 |
+
|
16 |
+
$this->register_hooks();
|
17 |
+
|
18 |
+
}
|
19 |
+
|
20 |
+
public static function register_gateway (array $gateway_list )
|
21 |
+
{
|
22 |
+
return array_merge(
|
23 |
+
$gateway_list,
|
24 |
+
[
|
25 |
+
'paypal' => [
|
26 |
+
'label' => __( 'PayPal', 'restaurant-reservations' ),
|
27 |
+
'instance' => self::get_instance()
|
28 |
+
]
|
29 |
+
]
|
30 |
+
);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Get singleton instance of the class
|
35 |
+
*
|
36 |
+
* @return rtbPaymentGatewayPayPal instance
|
37 |
+
*/
|
38 |
+
public static function get_instance()
|
39 |
+
{
|
40 |
+
if( ! isset( self::$_instance ) ) {
|
41 |
+
self::$_instance = new rtbPaymentGatewayPayPal();
|
42 |
+
}
|
43 |
+
|
44 |
+
return self::$_instance;
|
45 |
+
}
|
46 |
+
|
47 |
+
public function register_hooks() {
|
48 |
+
// If there's an IPN request, add our setup function to potentially handle it
|
49 |
+
if ( isset($_POST['ipn_track_id']) ) {
|
50 |
+
add_action( 'init', [$this, 'handle_ipn'], 11 );
|
51 |
+
|
52 |
+
// add an output buffer layer for the plugin
|
53 |
+
add_action( 'init', [$this, 'ob_start'] );
|
54 |
+
add_action( 'shutdown', [$this, 'flush_ob_end'] );
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
public function print_payment_form( $booking )
|
59 |
+
{
|
60 |
+
global $rtb_controller;
|
61 |
+
|
62 |
+
// Define the form's action parameter
|
63 |
+
$booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
|
64 |
+
if ( !empty( $booking_page ) ) {
|
65 |
+
$booking_page = get_permalink( $booking_page );
|
66 |
+
}
|
67 |
+
|
68 |
+
$item_name = substr(get_bloginfo('name'), 0, 100) . 'Reservation Deposit';
|
69 |
+
$amount = $booking->calculate_deposit();
|
70 |
+
$business = $rtb_controller->settings->get_setting( 'rtb-paypal-email' );
|
71 |
+
$currency = $rtb_controller->settings->get_setting( 'rtb-currency' );
|
72 |
+
$notify_url = get_site_url();
|
73 |
+
|
74 |
+
echo "
|
75 |
+
<form action='https://www.paypal.com/cgi-bin/webscr' method='post' class='standard-form'>
|
76 |
+
<input type='hidden' name='item_name_1' value='{$item_name}' />
|
77 |
+
<input type='hidden' name='custom' value='booking_id={$booking->ID}' />
|
78 |
+
<input type='hidden' name='quantity_1' value='1' />
|
79 |
+
<input type='hidden' name='amount_1' value='{$amount}' />
|
80 |
+
<input type='hidden' name='cmd' value='_cart' />
|
81 |
+
<input type='hidden' name='upload' value='1' />
|
82 |
+
<input type='hidden' name='business' value='{$business}' />
|
83 |
+
<input type='hidden' name='currency_code' value='{$currency}' />
|
84 |
+
<input type='hidden' name='return' value='{$booking_page}' />
|
85 |
+
<input type='hidden' name='notify_url' value='{$notify_url}' />
|
86 |
+
<input type='submit' class='submit-button' value='Pay via PayPal' />
|
87 |
+
</form>
|
88 |
+
";
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Handle PayPal IPN requests
|
93 |
+
*
|
94 |
+
* @since 2.1.0
|
95 |
+
*/
|
96 |
+
public function handle_ipn()
|
97 |
+
{
|
98 |
+
global $rtb_controller;
|
99 |
+
|
100 |
+
if ( ! $rtb_controller->settings->get_setting( 'require-deposit' ) ) {
|
101 |
+
return;
|
102 |
+
}
|
103 |
+
|
104 |
+
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
|
105 |
+
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
|
106 |
+
// Set this to 0 once you go live or don't require logging.
|
107 |
+
$debug = get_option( 'rtb_enable_payment_debugging' );
|
108 |
+
|
109 |
+
// Set to 0 once you're ready to go live
|
110 |
+
define("RTB_USE_SANDBOX", 0);
|
111 |
+
define("RTB_LOG_FILE", "ipn.log");
|
112 |
+
|
113 |
+
// Read POST data
|
114 |
+
// reading posted data directly from $_POST causes serialization
|
115 |
+
// issues with array data in POST. Reading raw POST data from input stream instead.
|
116 |
+
$raw_post_data = file_get_contents('php://input');
|
117 |
+
$raw_post_array = explode('&', $raw_post_data);
|
118 |
+
$myPost = array();
|
119 |
+
foreach ($raw_post_array as $keyval) {
|
120 |
+
$keyval = explode ('=', $keyval);
|
121 |
+
if (count($keyval) == 2)
|
122 |
+
$myPost[$keyval[0]] = urldecode($keyval[1]);
|
123 |
+
}
|
124 |
+
|
125 |
+
// read the post from PayPal system and add 'cmd'
|
126 |
+
$req = 'cmd=_notify-validate';
|
127 |
+
if(function_exists('get_magic_quotes_gpc')) {
|
128 |
+
$get_magic_quotes_exists = true;
|
129 |
+
}
|
130 |
+
|
131 |
+
foreach ($myPost as $key => $value) {
|
132 |
+
if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
|
133 |
+
$value = urlencode(stripslashes($value));
|
134 |
+
} else {
|
135 |
+
$value = urlencode($value);
|
136 |
+
}
|
137 |
+
$req .= "&$key=$value";
|
138 |
+
}
|
139 |
+
|
140 |
+
// Post IPN data back to PayPal to validate the IPN data is genuine
|
141 |
+
// Without this step anyone can fake IPN data
|
142 |
+
if(RTB_USE_SANDBOX == true) {
|
143 |
+
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
|
144 |
+
} else {
|
145 |
+
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
|
146 |
+
}
|
147 |
+
|
148 |
+
$response = wp_remote_post($paypal_url, array(
|
149 |
+
'method' => 'POST',
|
150 |
+
'body' => $req,
|
151 |
+
'timeout' => 30
|
152 |
+
));
|
153 |
+
|
154 |
+
// Inspect IPN validation result and act accordingly
|
155 |
+
// Split response headers and payload, a better way for strcmp
|
156 |
+
$tokens = explode("\r\n\r\n", trim($response['body']));
|
157 |
+
$res = trim(end($tokens));
|
158 |
+
|
159 |
+
if ( $debug ) {
|
160 |
+
update_option( 'rtb_debugging', get_option( 'rtb_debugging' ) . print_r( date('[Y-m-d H:i e] '). "IPN response: $res - $req ". PHP_EOL, true ) );
|
161 |
+
}
|
162 |
+
|
163 |
+
if (strcmp ($res, "VERIFIED") == 0) {
|
164 |
+
|
165 |
+
$paypal_receipt_number = $_POST['txn_id'];
|
166 |
+
$payment_amount = $_POST['mc_gross'];
|
167 |
+
|
168 |
+
parse_str($_POST['custom'], $custom_vars);
|
169 |
+
$booking_id = intval( $custom_vars['booking_id'] );
|
170 |
+
|
171 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
172 |
+
|
173 |
+
$booking = new rtbBooking();
|
174 |
+
$booking->load_post( $booking_id );
|
175 |
+
|
176 |
+
if ( ! $booking ) { return; }
|
177 |
+
|
178 |
+
$booking->deposit = sanitize_text_field( $payment_amount );
|
179 |
+
$booking->receipt_id = sanitize_text_field( $paypal_receipt_number );
|
180 |
+
|
181 |
+
$booking->payment_paid();
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Opens a buffer when handling PayPal IPN requests
|
187 |
+
*
|
188 |
+
* @since 2.1.0
|
189 |
+
*/
|
190 |
+
public function ob_start()
|
191 |
+
{
|
192 |
+
ob_start();
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Closes a buffer when handling PayPal IPN requests
|
197 |
+
*
|
198 |
+
* @since 2.1.0
|
199 |
+
*/
|
200 |
+
public function flush_ob_end()
|
201 |
+
{
|
202 |
+
if ( ob_get_length() ) {
|
203 |
+
ob_end_clean();
|
204 |
+
}
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Gateway has to register itself
|
212 |
+
*/
|
213 |
+
add_filter(
|
214 |
+
'rtb-payment-gateway-register',
|
215 |
+
['rtbPaymentGatewayPayPal', 'register_gateway']
|
216 |
+
);
|
@@ -0,0 +1,462 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( !defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
if ( !class_exists( 'rtbPaymentGatewayStripe' ) ) {
|
5 |
+
/**
|
6 |
+
* This class is responsible for payment processing via Stripe
|
7 |
+
*
|
8 |
+
* @since 2.3.0
|
9 |
+
*/
|
10 |
+
class rtbPaymentGatewayStripe implements rtbPaymentGateway {
|
11 |
+
|
12 |
+
private static $_instance;
|
13 |
+
|
14 |
+
private final function __construct() {
|
15 |
+
|
16 |
+
$this->register_hooks();
|
17 |
+
|
18 |
+
}
|
19 |
+
|
20 |
+
public static function register_gateway (array $gateway_list )
|
21 |
+
{
|
22 |
+
return array_merge(
|
23 |
+
$gateway_list,
|
24 |
+
[
|
25 |
+
'stripe' => [
|
26 |
+
'label' => __( 'Stripe', 'restaurant-reservations' ),
|
27 |
+
'instance' => self::get_instance()
|
28 |
+
]
|
29 |
+
]
|
30 |
+
);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Get singleton instance of the class
|
35 |
+
*
|
36 |
+
* @return rtbPaymentGatewayStripe instance
|
37 |
+
*/
|
38 |
+
public static function get_instance()
|
39 |
+
{
|
40 |
+
if( ! isset( self::$_instance ) ) {
|
41 |
+
self::$_instance = new rtbPaymentGatewayStripe();
|
42 |
+
}
|
43 |
+
|
44 |
+
return self::$_instance;
|
45 |
+
}
|
46 |
+
|
47 |
+
public function register_hooks()
|
48 |
+
{
|
49 |
+
add_action( 'rtb_booking_form_init', [$this, 'process_payment'] );
|
50 |
+
|
51 |
+
add_action( 'wp_ajax_rtb_stripe_get_intent', array( $this, 'create_stripe_pmtIntnt' ) );
|
52 |
+
add_action( 'wp_ajax_nopriv_rtb_stripe_get_intent', array( $this, 'create_stripe_pmtIntnt' ) );
|
53 |
+
|
54 |
+
add_action( 'wp_ajax_rtb_stripe_pmt_succeed', array( $this, 'stripe_sca_succeed' ) );
|
55 |
+
add_action( 'wp_ajax_nopriv_rtb_stripe_pmt_succeed', array( $this, 'stripe_sca_succeed' ) );
|
56 |
+
|
57 |
+
add_filter( 'rtb_booking_metadata_defaults', [$this, 'default_booking_stripe_info'], 30, 1 );
|
58 |
+
add_action( 'rtb_booking_load_post_data', [$this, 'populate_booking_stripe_info'], 30, 2 );
|
59 |
+
add_filter( 'rtb_insert_booking_metadata', [$this, 'save_booking_gateway_info'], 30, 2 );
|
60 |
+
}
|
61 |
+
|
62 |
+
public function print_payment_form( $booking )
|
63 |
+
{
|
64 |
+
global $rtb_controller;
|
65 |
+
|
66 |
+
// Function alias
|
67 |
+
$_gs = [$rtb_controller->settings, 'get_setting'];
|
68 |
+
$SCA = $_gs( 'rtb-stripe-sca' );
|
69 |
+
|
70 |
+
$btn_disabled = '';
|
71 |
+
$stripe_lib_version = 'v2';
|
72 |
+
|
73 |
+
if( $SCA )
|
74 |
+
{
|
75 |
+
$btn_disabled = "disabled='disabled'";
|
76 |
+
$stripe_lib_version = 'v3';
|
77 |
+
}
|
78 |
+
|
79 |
+
// Stripe Lib
|
80 |
+
wp_enqueue_script(
|
81 |
+
'rtb-stripe',
|
82 |
+
"https://js.stripe.com/{$stripe_lib_version}/",
|
83 |
+
array( 'jquery' ),
|
84 |
+
RTB_VERSION,
|
85 |
+
true
|
86 |
+
);
|
87 |
+
|
88 |
+
// Stripe-JS processing logic
|
89 |
+
wp_enqueue_script(
|
90 |
+
'rtb-stripe-payment',
|
91 |
+
RTB_PLUGIN_URL . '/assets/js/stripe-payment.js',
|
92 |
+
array( 'jquery', 'rtb-stripe' ),
|
93 |
+
RTB_VERSION,
|
94 |
+
true
|
95 |
+
);
|
96 |
+
|
97 |
+
wp_localize_script(
|
98 |
+
'rtb-stripe-payment',
|
99 |
+
'rtb_stripe_payment',
|
100 |
+
array(
|
101 |
+
'stripe_mode' => $_gs( 'rtb-stripe-mode' ),
|
102 |
+
'stripe_sca' => $SCA,
|
103 |
+
'live_publishable_key' => $_gs( 'rtb-stripe-live-publishable' ),
|
104 |
+
'test_publishable_key' => $_gs( 'rtb-stripe-test-publishable' ),
|
105 |
+
)
|
106 |
+
);
|
107 |
+
|
108 |
+
$payment_amount = $_gs( 'rtb-currency-symbol-location' ) == 'before'
|
109 |
+
? $_gs( 'rtb-stripe-currency-symbol' ) . $booking->calculate_deposit()
|
110 |
+
: $booking->calculate_deposit() . $_gs( 'rtb-stripe-currency-symbol' );
|
111 |
+
|
112 |
+
$cc_exp_single_field = null != $_gs( 'rtb-expiration-field-single' )
|
113 |
+
? "<input type='text' data-stripe='exp_month_year' class='single-masked'>"
|
114 |
+
: "<input type='text' size='2' data-stripe='exp_month'>
|
115 |
+
<span> / </span>
|
116 |
+
<input type='text' size='4' data-stripe='exp_year'>";
|
117 |
+
?>
|
118 |
+
|
119 |
+
<h2>
|
120 |
+
<?php _e('Deposit Required: ', 'restaurant-reservations' ) . $payment_amount; ?>
|
121 |
+
</h2>
|
122 |
+
|
123 |
+
<div class='payment-errors'></div>
|
124 |
+
|
125 |
+
<form
|
126 |
+
action='#'
|
127 |
+
method='POST'
|
128 |
+
id='stripe-payment-form'
|
129 |
+
data-booking_id='<?php echo $booking->ID ;?>'>
|
130 |
+
|
131 |
+
<?php if( $SCA ) { ?>
|
132 |
+
|
133 |
+
<div class='form-row'>
|
134 |
+
<label><?php _e('Card Detail', 'restaurant-reservations'); ?></label>
|
135 |
+
<span id="cardElement"></span>
|
136 |
+
</div>
|
137 |
+
|
138 |
+
<?php } else { ?>
|
139 |
+
|
140 |
+
<div class='form-row'>
|
141 |
+
<label><?php _e('Card Number', 'restaurant-reservations'); ?></label>
|
142 |
+
<input type='text' size='20' autocomplete='off' data-stripe='card_number'/>
|
143 |
+
</div>
|
144 |
+
<div class='form-row'>
|
145 |
+
<label><?php _e('CVC', 'restaurant-reservations'); ?></label>
|
146 |
+
<input type='text' size='4' autocomplete='off' data-stripe='card_cvc'/>
|
147 |
+
</div>
|
148 |
+
<div class='form-row'>
|
149 |
+
<label><?php _e('Expiration (MM/YYYY)', 'restaurant-reservations'); ?></label>
|
150 |
+
<?php echo $cc_exp_single_field; ?>
|
151 |
+
</div>
|
152 |
+
<input type='hidden' name='action' value='rtb_stripe_booking_payment'/>
|
153 |
+
<input type='hidden' name='currency' value='<?php echo $_gs( 'rtb-currency' ); ?>' data-stripe='currency' />
|
154 |
+
<input type='hidden' name='payment_amount' value='<?php echo $booking->calculate_deposit(); ?>' />
|
155 |
+
<input type='hidden' name='booking_id' value='<?php echo $booking->ID; ?>' />
|
156 |
+
|
157 |
+
<?php } ?>
|
158 |
+
|
159 |
+
<p class="stripe-payment-help-text">
|
160 |
+
<?php _e( 'Please wait. Do not refresh until the button enables or the page reloads.', 'restaurant-reservations' ); ?>
|
161 |
+
</p>
|
162 |
+
|
163 |
+
<button type='submit' id='stripe-submit' <?php echo $btn_disabled; ?>>
|
164 |
+
<?php _e( 'Make Deposit', 'restaurant-reservations'); ?>
|
165 |
+
</button>
|
166 |
+
|
167 |
+
</form>
|
168 |
+
<?php
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Maybe process payment, if coming from Stripe payment form
|
173 |
+
*
|
174 |
+
* @return void Redirect and exit or return
|
175 |
+
*/
|
176 |
+
public function process_payment()
|
177 |
+
{
|
178 |
+
global $rtb_controller;
|
179 |
+
|
180 |
+
if ( ! isset( $_POST['stripeToken'] ) || ! isset( $_POST['booking_id'] ) ) {
|
181 |
+
return;
|
182 |
+
}
|
183 |
+
|
184 |
+
// Function alias
|
185 |
+
$_gs = [$rtb_controller->settings, 'get_setting'];
|
186 |
+
$booking_id = $_POST['booking_id'];
|
187 |
+
|
188 |
+
// Define the form's action parameter
|
189 |
+
$booking_page = $_gs( 'booking-page' );
|
190 |
+
if ( ! empty( $booking_page ) ) {
|
191 |
+
$booking_page = get_permalink( $booking_page );
|
192 |
+
}
|
193 |
+
else {
|
194 |
+
$booking_page = get_permalink();
|
195 |
+
}
|
196 |
+
|
197 |
+
// load the stripe libraries
|
198 |
+
require_once(RTB_PLUGIN_DIR . '/lib/stripe/init.php');
|
199 |
+
|
200 |
+
// retrieve the token generated by stripe.js
|
201 |
+
$token = $_POST['stripeToken'];
|
202 |
+
|
203 |
+
// JPY currency does not have any decimal palces
|
204 |
+
$is_JPY = "JPY" != $_gs( 'rtb-currency' );
|
205 |
+
$payment_amount = $is_JPY ? ( $_POST['payment_amount'] * 100 ) : $_POST['payment_amount'];
|
206 |
+
|
207 |
+
$stripe_secret = 'test' == $_gs( 'rtb-stripe-mode' )
|
208 |
+
? $_gs( 'rtb-stripe-test-secret' )
|
209 |
+
: $_gs( 'rtb-stripe-live-secret' );
|
210 |
+
|
211 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
212 |
+
$booking = new rtbBooking();
|
213 |
+
$booking->load_post( $booking_id );
|
214 |
+
|
215 |
+
try {
|
216 |
+
\Stripe\Stripe::setApiKey( $stripe_secret );
|
217 |
+
$charge = \Stripe\Charge::create(array(
|
218 |
+
'amount' => $payment_amount,
|
219 |
+
'currency' => strtolower( $_gs( 'rtb-currency' ) ),
|
220 |
+
'card' => $token
|
221 |
+
)
|
222 |
+
);
|
223 |
+
|
224 |
+
$booking->deposit = $is_JPY ? $payment_amount / 100 : $payment_amount;
|
225 |
+
$booking->receipt_id = $charge->id;
|
226 |
+
|
227 |
+
$booking->determine_status( true );
|
228 |
+
|
229 |
+
$booking->insert_post_data();
|
230 |
+
|
231 |
+
do_action( 'rtb_booking_paid', $booking );
|
232 |
+
|
233 |
+
// redirect on successful payment
|
234 |
+
$redirect = add_query_arg(
|
235 |
+
array(
|
236 |
+
'payment' => 'paid',
|
237 |
+
'booking_id' => $booking_id
|
238 |
+
),
|
239 |
+
$booking_page
|
240 |
+
);
|
241 |
+
|
242 |
+
} catch (Exception $e) {
|
243 |
+
|
244 |
+
$booking->post_status = 'payment_failed';
|
245 |
+
$booking->payment_failure_message = $e->getDeclineCode();
|
246 |
+
|
247 |
+
$booking->insert_post_data();
|
248 |
+
|
249 |
+
// redirect on failed payment
|
250 |
+
$redirect = add_query_arg(
|
251 |
+
array(
|
252 |
+
'payment' => 'failed',
|
253 |
+
'booking_id' => $booking_id,
|
254 |
+
'error_code' => urlencode( $e->getDeclineCode() )
|
255 |
+
),
|
256 |
+
$booking_page
|
257 |
+
);
|
258 |
+
}
|
259 |
+
|
260 |
+
// redirect back to our previous page with the added query variable
|
261 |
+
wp_redirect($redirect); exit;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Create Stripe payment intent for reservation deposits
|
266 |
+
* Respond to AJAX/XHR request
|
267 |
+
*
|
268 |
+
* @since 2.2.8
|
269 |
+
*/
|
270 |
+
public function create_stripe_pmtIntnt()
|
271 |
+
{
|
272 |
+
global $rtb_controller;
|
273 |
+
|
274 |
+
$response = function ($success, $msg, $data = []) {
|
275 |
+
echo json_encode(
|
276 |
+
array_merge(
|
277 |
+
[
|
278 |
+
'success' => $success,
|
279 |
+
'message' => $msg
|
280 |
+
],
|
281 |
+
$data
|
282 |
+
)
|
283 |
+
);
|
284 |
+
|
285 |
+
exit(0);
|
286 |
+
};
|
287 |
+
|
288 |
+
if( ! isset( $_POST['booking_id'] ) ) {
|
289 |
+
$response(false, 'Invalid booking.');
|
290 |
+
}
|
291 |
+
|
292 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
293 |
+
$booking = new rtbBooking();
|
294 |
+
$booking->load_post( $_POST['booking_id'] );
|
295 |
+
|
296 |
+
$payment_amount = "JPY" != $rtb_controller->settings->get_setting( 'rtb-currency' )
|
297 |
+
? $booking->calculate_deposit() * 100
|
298 |
+
: $booking->calculate_deposit();
|
299 |
+
|
300 |
+
// load the stripe libraries
|
301 |
+
require_once(RTB_PLUGIN_DIR . '/lib/stripe/init.php');
|
302 |
+
|
303 |
+
$stripe_secret = 'test' == $rtb_controller->settings->get_setting( 'rtb-stripe-mode' )
|
304 |
+
? $rtb_controller->settings->get_setting( 'rtb-stripe-test-secret' )
|
305 |
+
: $rtb_controller->settings->get_setting( 'rtb-stripe-live-secret' );
|
306 |
+
|
307 |
+
try {
|
308 |
+
\Stripe\Stripe::setApiKey( $stripe_secret );
|
309 |
+
|
310 |
+
// $customer = \Stripe\Customer::create([
|
311 |
+
// 'email' => $booking->email,
|
312 |
+
// 'name' => $booking->name
|
313 |
+
// ]);
|
314 |
+
|
315 |
+
// $booking->stripe_customer_id = $customer->id;
|
316 |
+
// $booking->insert_post_data();
|
317 |
+
|
318 |
+
$metadata = array_filter([
|
319 |
+
'Booking ID' => $booking->ID,
|
320 |
+
'Email' => $booking->email,
|
321 |
+
'Name' => $booking->name,
|
322 |
+
'Date' => $booking->date,
|
323 |
+
'Party' => $booking->party
|
324 |
+
]);
|
325 |
+
|
326 |
+
if( is_array( $booking->table ) && ! empty( $booking->table ) ) {
|
327 |
+
$metadata['Table'] = implode('+', $booking->table);
|
328 |
+
}
|
329 |
+
|
330 |
+
$desc = implode(', ', $metadata );
|
331 |
+
$stmt_desc = substr( implode( ';', $metadata ), 0, 22 );
|
332 |
+
|
333 |
+
$intent = \Stripe\PaymentIntent::create([
|
334 |
+
'amount' => $payment_amount,
|
335 |
+
'currency' => $rtb_controller->settings->get_setting( 'rtb-currency' ),
|
336 |
+
'payment_method_types' => ['card'],
|
337 |
+
'receipt_email' => $booking->email,
|
338 |
+
'description' => apply_filters( 'rtb-stripe-payment-desc', $desc ),
|
339 |
+
'statement_descriptor' => apply_filters( 'rtb-stripe-payment-stmnt-desc', $stmt_desc ),
|
340 |
+
'metadata' => $metadata
|
341 |
+
]);
|
342 |
+
|
343 |
+
$response(
|
344 |
+
true,
|
345 |
+
'Payment Intent generated succsssfully',
|
346 |
+
[
|
347 |
+
'clientSecret' => $intent->client_secret,
|
348 |
+
'name' => $booking->name,
|
349 |
+
'email' => $booking->email,
|
350 |
+
]
|
351 |
+
);
|
352 |
+
}
|
353 |
+
catch(Exception $ex) {
|
354 |
+
$response( false, 'Please try again.', ['error' => $ex->getError()] );
|
355 |
+
}
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Stripe SCA payment's final status for reservation deposits
|
360 |
+
* Respond to AJAX/XHR request
|
361 |
+
*
|
362 |
+
* @since 2.2.8
|
363 |
+
*/
|
364 |
+
public function stripe_sca_succeed()
|
365 |
+
{
|
366 |
+
global $rtb_controller;
|
367 |
+
|
368 |
+
$response = function ($success = false, $urlParams = '') {
|
369 |
+
echo json_encode([
|
370 |
+
'success' => $success,
|
371 |
+
'urlParams' => $urlParams
|
372 |
+
]);
|
373 |
+
|
374 |
+
exit(0);
|
375 |
+
};
|
376 |
+
|
377 |
+
$success = false;
|
378 |
+
$urlParams = '';
|
379 |
+
|
380 |
+
if( ! isset( $_POST['booking_id'] ) ) {
|
381 |
+
$response();
|
382 |
+
}
|
383 |
+
|
384 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
385 |
+
$booking = new rtbBooking();
|
386 |
+
$booking->load_post( $_POST['booking_id'] );
|
387 |
+
|
388 |
+
if( isset( $_POST['success'] ) && 'false' != $_POST['success'] ) {
|
389 |
+
|
390 |
+
$booking->deposit = "JPY" != $rtb_controller->settings->get_setting( 'rtb-currency' )
|
391 |
+
? $_POST['payment_amount'] / 100
|
392 |
+
: $_POST['payment_amount'];
|
393 |
+
|
394 |
+
$booking->receipt_id = $_POST['payment_id'];
|
395 |
+
$booking->payment_paid();
|
396 |
+
|
397 |
+
// urlParams on successful payment
|
398 |
+
$success = true;
|
399 |
+
|
400 |
+
$urlParams = array(
|
401 |
+
'payment' => 'paid',
|
402 |
+
'booking_id' => $booking->ID
|
403 |
+
);
|
404 |
+
|
405 |
+
}
|
406 |
+
else {
|
407 |
+
$payment_failure_message = ! empty( $_POST['message'] )
|
408 |
+
? $_POST['message'] : '';
|
409 |
+
|
410 |
+
$booking->payment_failed( $payment_failure_message );
|
411 |
+
}
|
412 |
+
|
413 |
+
$response($success, $urlParams);
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Repopulate $booking with stripe meta information
|
418 |
+
*
|
419 |
+
* @param rtbBooking $booking
|
420 |
+
* @param WP_Post $wp_post
|
421 |
+
*/
|
422 |
+
public function populate_booking_stripe_info( rtbBooking $booking, $wp_post )
|
423 |
+
{
|
424 |
+
if ( is_array( $meta = get_post_meta( $booking->ID, 'rtb', true ) ) ) {
|
425 |
+
$booking->stripe_customer_id = isset( $meta['stripe_customer_id'] )
|
426 |
+
? $meta['stripe_customer_id']
|
427 |
+
: '';
|
428 |
+
}
|
429 |
+
}
|
430 |
+
|
431 |
+
/**
|
432 |
+
* Set $booking's default stripe meta information
|
433 |
+
*
|
434 |
+
* @param rtbBooking $booking
|
435 |
+
* @param WP_Post $wp_post
|
436 |
+
*/
|
437 |
+
public function default_booking_stripe_info( $info_list )
|
438 |
+
{
|
439 |
+
$info_list['stripe_customer_id'] = '';
|
440 |
+
|
441 |
+
return $info_list;
|
442 |
+
}
|
443 |
+
|
444 |
+
public function save_booking_gateway_info ( $meta, rtbBooking $booking )
|
445 |
+
{
|
446 |
+
if ( isset( $booking->stripe_customer_id ) && !empty( $booking->stripe_customer_id ) ) {
|
447 |
+
$meta['stripe_customer_id'] = $this->stripe_customer_id;
|
448 |
+
}
|
449 |
+
|
450 |
+
return $meta;
|
451 |
+
}
|
452 |
+
}
|
453 |
+
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Gateway has to register itself
|
458 |
+
*/
|
459 |
+
add_filter(
|
460 |
+
'rtb-payment-gateway-register',
|
461 |
+
['rtbPaymentGatewayStripe', 'register_gateway']
|
462 |
+
);
|
@@ -0,0 +1,710 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( !defined( 'ABSPATH' ) ) exit;
|
3 |
+
|
4 |
+
if ( !class_exists( 'rtbPaymentManager' ) ) {
|
5 |
+
/**
|
6 |
+
* This class to handle the Payment options for Restaurant Reservations
|
7 |
+
*
|
8 |
+
* This class sets up the payment options, register all the payment gateways and
|
9 |
+
* acts as a bridge between Rest of the plugin and payment gateways like
|
10 |
+
* rendering forms, processing payments, handling IPNs etc
|
11 |
+
*
|
12 |
+
* @since 2.3.0
|
13 |
+
*/
|
14 |
+
class rtbPaymentManager {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Default values for Payment manager settings
|
18 |
+
*/
|
19 |
+
public $defaults = array();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Should a premium setting be disabled or not
|
23 |
+
*/
|
24 |
+
public $premium_permissions = array();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* All the available payment processing gateway with their internal name,
|
28 |
+
* display name and the PHP Class
|
29 |
+
*
|
30 |
+
* @var array [
|
31 |
+
* 'paypal' => [
|
32 |
+
* 'name' => 'PayPal',
|
33 |
+
* 'instance' => 'new rtbPaymentGatewayPayPal()'
|
34 |
+
* ]
|
35 |
+
* ]
|
36 |
+
*/
|
37 |
+
public $available_gateway_list = array();
|
38 |
+
|
39 |
+
/**
|
40 |
+
* List of enabled gateway list from admin
|
41 |
+
*
|
42 |
+
* @var array ['paypal']
|
43 |
+
*/
|
44 |
+
public $enabled_gateway_list = array();
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Gateway selected for the current booking
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
public $in_use_gateway = '';
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Booking object. ID property does not exist when no booking loaded
|
54 |
+
* @var rtbBooking
|
55 |
+
*/
|
56 |
+
public $booking;
|
57 |
+
|
58 |
+
public $booking_form_field_slug = 'payment-gateway';
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Currencies accepted for deposits
|
62 |
+
*/
|
63 |
+
public $currency_options = array(
|
64 |
+
'AUD' => 'Australian Dollar',
|
65 |
+
'BRL' => 'Brazilian Real',
|
66 |
+
'CAD' => 'Canadian Dollar',
|
67 |
+
'CZK' => 'Czech Koruna',
|
68 |
+
'DKK' => 'Danish Krone',
|
69 |
+
'EUR' => 'Euro',
|
70 |
+
'HKD' => 'Hong Kong Dollar',
|
71 |
+
'HUF' => 'Hungarian Forint',
|
72 |
+
'ILS' => 'Israeli New Sheqel',
|
73 |
+
'JPY' => 'Japanese Yen',
|
74 |
+
'MYR' => 'Malaysian Ringgit',
|
75 |
+
'MXN' => 'Mexican Peso',
|
76 |
+
'NOK' => 'Norwegian Krone',
|
77 |
+
'NZD' => 'New Zealand Dollar',
|
78 |
+
'PHP' => 'Philippine Peso',
|
79 |
+
'PLN' => 'Polish Zloty',
|
80 |
+
'GBP' => 'Pound Sterling',
|
81 |
+
'RUB' => 'Russian Ruble',
|
82 |
+
'SGD' => 'Singapore Dollar',
|
83 |
+
'SEK' => 'Swedish Krona',
|
84 |
+
'CHF' => 'Swiss Franc',
|
85 |
+
'TWD' => 'Taiwan New Dollar',
|
86 |
+
'THB' => 'Thai Baht',
|
87 |
+
'TRY' => 'Turkish Lira',
|
88 |
+
'USD' => 'U.S. Dollar'
|
89 |
+
);
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Constructor
|
93 |
+
*/
|
94 |
+
public function __construct()
|
95 |
+
{
|
96 |
+
$this->load_basics();
|
97 |
+
|
98 |
+
add_filter( 'rtb_settings_check_permissions', [$this, 'check_permissions'] );
|
99 |
+
|
100 |
+
add_filter( 'rtb_settings_defaults', [$this, 'set_defaults'] );
|
101 |
+
|
102 |
+
$this->currency_options = apply_filters( 'rtb_payments_currency_options', $this->currency_options );
|
103 |
+
|
104 |
+
add_filter( 'rtb_settings_page', [$this, 'load_payment_settings'] );
|
105 |
+
|
106 |
+
do_action( 'rtb_payment_manager_init' );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Pre-check the permissions to enable/disable Payment Manager's settings
|
111 |
+
* as per the current license type
|
112 |
+
*
|
113 |
+
* @param array checked permissions array from Main settings class
|
114 |
+
*
|
115 |
+
* @return array checked permissions array amended with payment related permissions
|
116 |
+
*/
|
117 |
+
public function check_permissions( $premium_permissions )
|
118 |
+
{
|
119 |
+
global $rtb_controller;
|
120 |
+
|
121 |
+
$this->premium_permissions['payments'] = array();
|
122 |
+
if ( ! $rtb_controller->permissions->check_permission('payments') ) {
|
123 |
+
$this->premium_permissions['payments'] = array(
|
124 |
+
'disabled' => true,
|
125 |
+
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
126 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/',
|
127 |
+
'ultimate_needed' => 'Yes'
|
128 |
+
);
|
129 |
+
}
|
130 |
+
|
131 |
+
$this->premium_permissions = array_merge( $premium_permissions, $this->premium_permissions );
|
132 |
+
|
133 |
+
return $this->premium_permissions;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Load the Payment Manager's default values in global default values
|
138 |
+
*
|
139 |
+
* @param array $defaults default values of Payment Gateway settings
|
140 |
+
*
|
141 |
+
* @return array $defaults
|
142 |
+
*/
|
143 |
+
public function set_defaults( $defaults )
|
144 |
+
{
|
145 |
+
$this->defaults = array(
|
146 |
+
'rtb-paypal-email' => get_option( 'admin_email' ),
|
147 |
+
'rtb-stripe-mode' => 'test',
|
148 |
+
'rtb-currency' => 'USD',
|
149 |
+
'rtb-stripe-currency-symbol' => '$',
|
150 |
+
'rtb-currency-symbol-location' => 'before'
|
151 |
+
);
|
152 |
+
|
153 |
+
return array_merge( $defaults, $this->defaults );
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Add Payment Manager settings in global settings page
|
158 |
+
*
|
159 |
+
* @param sapLibrary_2_2_0 $settings_page An object of Simple Admin Pages page
|
160 |
+
*
|
161 |
+
* @return sapLibrary_2_2_0
|
162 |
+
*/
|
163 |
+
public function load_payment_settings( $settings_page )
|
164 |
+
{
|
165 |
+
// Add Payment settings tab
|
166 |
+
$settings_page->add_section(
|
167 |
+
'rtb-settings',
|
168 |
+
array(
|
169 |
+
'id' => 'rtb-payments-tab',
|
170 |
+
'title' => __( 'Payments', 'restaurant-reservations' ),
|
171 |
+
'is_tab' => true,
|
172 |
+
'rank' => 5
|
173 |
+
)
|
174 |
+
);
|
175 |
+
|
176 |
+
// Add settings group in Payment settings tab
|
177 |
+
$settings_page->add_section(
|
178 |
+
'rtb-settings',
|
179 |
+
array_merge(
|
180 |
+
array(
|
181 |
+
'id' => 'rtb-general-payment',
|
182 |
+
'title' => __( 'General', 'restaurant-reservations' ),
|
183 |
+
'tab' => 'rtb-payments-tab',
|
184 |
+
),
|
185 |
+
$this->premium_permissions['payments']
|
186 |
+
)
|
187 |
+
);
|
188 |
+
|
189 |
+
// Add settings in General settings group
|
190 |
+
$settings_page->add_setting(
|
191 |
+
'rtb-settings',
|
192 |
+
'rtb-general-payment',
|
193 |
+
'toggle',
|
194 |
+
array(
|
195 |
+
'id' => 'require-deposit',
|
196 |
+
'title' => __( 'Require Deposit', 'restaurant-reservations' ),
|
197 |
+
'description' => __( 'Require guests to make a deposit when making a reservation.', 'restaurant-reservations' )
|
198 |
+
)
|
199 |
+
);
|
200 |
+
$settings_page->add_setting(
|
201 |
+
'rtb-settings',
|
202 |
+
'rtb-general-payment',
|
203 |
+
'checkbox',
|
204 |
+
array(
|
205 |
+
'id' => 'rtb-payment-gateway',
|
206 |
+
'title' => __( 'Payment Gateway', 'restaurant-reservations' ),
|
207 |
+
'description' => __( 'Which payment gateway should be used to accept deposits.', 'restaurant-reservations' ),
|
208 |
+
'options' => $this->get_available_gateway_list()
|
209 |
+
)
|
210 |
+
);
|
211 |
+
$settings_page->add_setting(
|
212 |
+
'rtb-settings',
|
213 |
+
'rtb-general-payment',
|
214 |
+
'radio',
|
215 |
+
array(
|
216 |
+
'id' => 'rtb-deposit-type',
|
217 |
+
'title' => __( 'Deposit Type', 'restaurant-reservations' ),
|
218 |
+
'description' => __( 'What type of deposit should be required, per reservation or per guest?', 'restaurant-reservations' ),
|
219 |
+
'options' => array(
|
220 |
+
'reservation' => 'Per Reservation',
|
221 |
+
'guest' => 'Per Guest'
|
222 |
+
)
|
223 |
+
)
|
224 |
+
);
|
225 |
+
$settings_page->add_setting(
|
226 |
+
'rtb-settings',
|
227 |
+
'rtb-general-payment',
|
228 |
+
'text',
|
229 |
+
array(
|
230 |
+
'id' => 'rtb-deposit-amount',
|
231 |
+
'title' => __( 'Deposit Amount', 'restaurant-reservations' ),
|
232 |
+
'description' => __( 'What deposit amount is required (either per reservation or per guest, depending on the setting above)? Minimum is $0.50 in most currencies.', 'restaurant-reservations' )
|
233 |
+
)
|
234 |
+
);
|
235 |
+
$settings_page->add_setting(
|
236 |
+
'rtb-settings',
|
237 |
+
'rtb-general-payment',
|
238 |
+
'select',
|
239 |
+
array(
|
240 |
+
'id' => 'rtb-currency',
|
241 |
+
'title' => __( 'Currency', 'restaurant-reservations' ),
|
242 |
+
'description' => __( 'Select the currency you accept for your deposits.', 'restaurant-reservations' ),
|
243 |
+
'blank_option' => false,
|
244 |
+
'options' => $this->currency_options
|
245 |
+
)
|
246 |
+
);
|
247 |
+
|
248 |
+
// Add settings group in Payment settings tab
|
249 |
+
$settings_page->add_section(
|
250 |
+
'rtb-settings',
|
251 |
+
array_merge(
|
252 |
+
array(
|
253 |
+
'id' => 'rtb-paypal-payment',
|
254 |
+
'title' => __( 'PayPal', 'restaurant-reservations' ),
|
255 |
+
'tab' => 'rtb-payments-tab',
|
256 |
+
),
|
257 |
+
$this->premium_permissions['payments']
|
258 |
+
)
|
259 |
+
);
|
260 |
+
|
261 |
+
// Add settings in PayPal settings group
|
262 |
+
$settings_page->add_setting(
|
263 |
+
'rtb-settings',
|
264 |
+
'rtb-paypal-payment',
|
265 |
+
'text',
|
266 |
+
array(
|
267 |
+
'id' => 'rtb-paypal-email',
|
268 |
+
'title' => __( 'PayPal Email Address', 'restaurant-reservations' ),
|
269 |
+
'description' => __( 'The email address you\'ll be using to accept PayPal payments.', 'restaurant-reservations' ),
|
270 |
+
'placeholder' =>$this->defaults['rtb-paypal-email']
|
271 |
+
)
|
272 |
+
);
|
273 |
+
|
274 |
+
// Add settings group in Payment settings tab
|
275 |
+
$settings_page->add_section(
|
276 |
+
'rtb-settings',
|
277 |
+
array_merge(
|
278 |
+
array(
|
279 |
+
'id' => 'rtb-stripe-payment',
|
280 |
+
'title' => __( 'Stripe', 'restaurant-reservations' ),
|
281 |
+
'tab' => 'rtb-payments-tab',
|
282 |
+
),
|
283 |
+
$this->premium_permissions['payments']
|
284 |
+
)
|
285 |
+
);
|
286 |
+
|
287 |
+
// Add settings in Stripe settings group
|
288 |
+
$settings_page->add_setting(
|
289 |
+
'rtb-settings',
|
290 |
+
'rtb-stripe-payment',
|
291 |
+
'toggle',
|
292 |
+
array(
|
293 |
+
'id' => 'rtb-stripe-sca',
|
294 |
+
'title' => __( 'Strong Customer Authorization (SCA)', 'restaurant-reservations' ),
|
295 |
+
'description' => __( 'User will be redirected to Stripe and presented with 3D secure or bank redirect for payment authentication. (May be necessary for certain EU compliance.)', 'restaurant-reservations' )
|
296 |
+
)
|
297 |
+
);
|
298 |
+
$settings_page->add_setting(
|
299 |
+
'rtb-settings',
|
300 |
+
'rtb-stripe-payment',
|
301 |
+
'text',
|
302 |
+
array(
|
303 |
+
'id' => 'rtb-stripe-currency-symbol',
|
304 |
+
'title' => __( 'Stripe Currency Symbol', 'restaurant-reservations' ),
|
305 |
+
'description' => __( 'The currency symbol you\'d like displayed before or after the required deposit amount.', 'restaurant-reservations' ),
|
306 |
+
'placeholder' => $this->defaults['rtb-stripe-currency-symbol']
|
307 |
+
)
|
308 |
+
);
|
309 |
+
$settings_page->add_setting(
|
310 |
+
'rtb-settings',
|
311 |
+
'rtb-stripe-payment',
|
312 |
+
'toggle',
|
313 |
+
array(
|
314 |
+
'id' => 'rtb-expiration-field-single',
|
315 |
+
'title' => __( 'CC Expiration Single Field', 'restaurant-reservations' ),
|
316 |
+
'description' => __( 'Should the field for card expiry details be a single field with a mask or two separate fields for month and year?', 'restaurant-reservations' )
|
317 |
+
)
|
318 |
+
);
|
319 |
+
$settings_page->add_setting(
|
320 |
+
'rtb-settings',
|
321 |
+
'rtb-stripe-payment',
|
322 |
+
'radio',
|
323 |
+
array(
|
324 |
+
'id' => 'rtb-currency-symbol-location',
|
325 |
+
'title' => __( 'Currency Symbol Location', 'restaurant-reservations' ),
|
326 |
+
'description' => __( 'Should the currency symbol be placed before or after the deposit amount?', 'restaurant-reservations' ),
|
327 |
+
'options' => array(
|
328 |
+
'before' => 'Before',
|
329 |
+
'after' => 'After'
|
330 |
+
)
|
331 |
+
)
|
332 |
+
);
|
333 |
+
$settings_page->add_setting(
|
334 |
+
'rtb-settings',
|
335 |
+
'rtb-stripe-payment',
|
336 |
+
'radio',
|
337 |
+
array(
|
338 |
+
'id' => 'rtb-stripe-mode',
|
339 |
+
'title' => __( 'Test/Live Mode', 'restaurant-reservations' ),
|
340 |
+
'description' => __( 'Should the system use test or live mode? Test mode should only be used for testing, no deposits will actually be processed while turned on.', 'restaurant-reservations' ),
|
341 |
+
'options' => array(
|
342 |
+
'test' => 'Test',
|
343 |
+
'live' => 'Live'
|
344 |
+
)
|
345 |
+
)
|
346 |
+
);
|
347 |
+
$settings_page->add_setting(
|
348 |
+
'rtb-settings',
|
349 |
+
'rtb-stripe-payment',
|
350 |
+
'text',
|
351 |
+
array(
|
352 |
+
'id' => 'rtb-stripe-live-secret',
|
353 |
+
'title' => __( 'Stripe Live Secret', 'restaurant-reservations' ),
|
354 |
+
'description' => __( 'The live secret that you have set up for your Stripe account.', 'restaurant-reservations' )
|
355 |
+
)
|
356 |
+
);
|
357 |
+
$settings_page->add_setting(
|
358 |
+
'rtb-settings',
|
359 |
+
'rtb-stripe-payment',
|
360 |
+
'text',
|
361 |
+
array(
|
362 |
+
'id' => 'rtb-stripe-live-publishable',
|
363 |
+
'title' => __( 'Stripe Live Publishable', 'restaurant-reservations' ),
|
364 |
+
'description' => __( 'The live publishable that you have set up for your Stripe account.', 'restaurant-reservations' )
|
365 |
+
)
|
366 |
+
);
|
367 |
+
$settings_page->add_setting(
|
368 |
+
'rtb-settings',
|
369 |
+
'rtb-stripe-payment',
|
370 |
+
'text',
|
371 |
+
array(
|
372 |
+
'id' => 'rtb-stripe-test-secret',
|
373 |
+
'title' => __( 'Stripe Test Secret', 'restaurant-reservations' ),
|
374 |
+
'description' => __( 'The test secret that you have set up for your Stripe account. Only needed for testing payments.', 'restaurant-reservations' )
|
375 |
+
)
|
376 |
+
);
|
377 |
+
$settings_page->add_setting(
|
378 |
+
'rtb-settings',
|
379 |
+
'rtb-stripe-payment',
|
380 |
+
'text',
|
381 |
+
array(
|
382 |
+
'id' => 'rtb-stripe-test-publishable',
|
383 |
+
'title' => __( 'Stripe Test Publishable', 'restaurant-reservations' ),
|
384 |
+
'description' => __( 'The test publishable that you have set up for your Stripe account. Only needed for testing payments.', 'restaurant-reservations' )
|
385 |
+
)
|
386 |
+
);
|
387 |
+
|
388 |
+
do_action( 'rtb_settings_payment_manager', $settings_page );
|
389 |
+
|
390 |
+
return $settings_page;
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Acts like a constructor
|
395 |
+
*/
|
396 |
+
public function load_basics()
|
397 |
+
{
|
398 |
+
global $rtb_controller;
|
399 |
+
|
400 |
+
require_once RTB_PLUGIN_DIR . "/includes/PaymentGateway.interface.php";
|
401 |
+
require_once RTB_PLUGIN_DIR . "/includes/PaymentGatewayPayPal.class.php";
|
402 |
+
require_once RTB_PLUGIN_DIR . "/includes/PaymentGatewayStripe.class.php";
|
403 |
+
|
404 |
+
do_action( 'rtb_payment_manager_load_gateways' );
|
405 |
+
|
406 |
+
$this->available_gateway_list = apply_filters(
|
407 |
+
'rtb-payment-gateway-register',
|
408 |
+
$this->available_gateway_list
|
409 |
+
);
|
410 |
+
|
411 |
+
$this->strip_invalid_gateway();
|
412 |
+
|
413 |
+
$this->enabled_gateway_list = $rtb_controller->settings->get_setting( 'rtb-payment-gateway' );
|
414 |
+
|
415 |
+
$this->enabled_gateway_list = apply_filters(
|
416 |
+
'rtb-payment-active-gateway',
|
417 |
+
$this->enabled_gateway_list,
|
418 |
+
$this->available_gateway_list
|
419 |
+
);
|
420 |
+
|
421 |
+
// if multiple gateways enabled, print list to ask for one gateway
|
422 |
+
if ( 1 < count( $this->enabled_gateway_list ) ) {
|
423 |
+
add_filter( 'rtb_booking_form_fields', [$this, 'add_field_booking_form_gateway'], 30, 3 );
|
424 |
+
}
|
425 |
+
|
426 |
+
// Determine $in_use_gateway
|
427 |
+
add_action( 'rtb_validate_booking_submission', [$this, 'validate_booking_form_gateway'] );
|
428 |
+
|
429 |
+
// Save gateway selected/used for booking as booking meta
|
430 |
+
add_filter( 'rtb_insert_booking_metadata', [$this, 'save_booking_gateway_used'], 30, 2 );
|
431 |
+
|
432 |
+
// Repopulate gateway information
|
433 |
+
add_action( 'rtb_booking_load_post_data', [$this, 'populate_booking_gateway_used'], 30, 2 );
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Get available gateway list with gateway slug as key and label as value
|
438 |
+
*
|
439 |
+
* @return array
|
440 |
+
*/
|
441 |
+
public function get_available_gateway_list()
|
442 |
+
{
|
443 |
+
$list = [];
|
444 |
+
|
445 |
+
foreach ($this->available_gateway_list as $key => $value) {
|
446 |
+
$list[$key] = $value['label'];
|
447 |
+
}
|
448 |
+
|
449 |
+
return $list;
|
450 |
+
}
|
451 |
+
|
452 |
+
/**
|
453 |
+
* Get enabled gateway list with gateway slug as key and label as value
|
454 |
+
*
|
455 |
+
* @return array
|
456 |
+
*/
|
457 |
+
public function get_enabled_gateway_list()
|
458 |
+
{
|
459 |
+
$list = [];
|
460 |
+
|
461 |
+
foreach ($this->enabled_gateway_list as $key) {
|
462 |
+
$list[$key] = $this->available_gateway_list[$key]['label'];
|
463 |
+
}
|
464 |
+
|
465 |
+
return $list;
|
466 |
+
}
|
467 |
+
|
468 |
+
/**
|
469 |
+
* Is Payments functionality enabled?
|
470 |
+
*
|
471 |
+
* @return boolean
|
472 |
+
*/
|
473 |
+
public function is_payment_enabled()
|
474 |
+
{
|
475 |
+
global $rtb_controller;
|
476 |
+
|
477 |
+
return (
|
478 |
+
$rtb_controller->settings->get_setting( 'require-deposit' )
|
479 |
+
&&
|
480 |
+
0 < count( $this->get_enabled_gateway_list() )
|
481 |
+
);
|
482 |
+
}
|
483 |
+
|
484 |
+
/**
|
485 |
+
* Add the payment gateway selector field in the bookgin form
|
486 |
+
*
|
487 |
+
* @param array $fields Booking form field array. For more info, refer to
|
488 |
+
* rtbSettings::get_booking_form_fields()
|
489 |
+
* @param stdObject $request
|
490 |
+
* @param array $args
|
491 |
+
*/
|
492 |
+
public function add_field_booking_form_gateway( $fields, $request, $args )
|
493 |
+
{
|
494 |
+
if ( ! $this->is_payment_enabled() ) {
|
495 |
+
return $fields;
|
496 |
+
}
|
497 |
+
|
498 |
+
/**
|
499 |
+
* This is different from admin setting, that is why, to reduce the confusion
|
500 |
+
* we use variabel instead of direct field name
|
501 |
+
*
|
502 |
+
* @var string rtb-payment-gateway
|
503 |
+
*/
|
504 |
+
$prefixed_field_slug = "rtb-{$this->booking_form_field_slug}";
|
505 |
+
|
506 |
+
$payment_gateway_field = [
|
507 |
+
$this->booking_form_field_slug => [
|
508 |
+
// 'legend' => __( 'Payment', 'restaurant-reservations' ),
|
509 |
+
'fields' => [
|
510 |
+
// Field names are prefixed with "rtb-" while rendering field's HTML
|
511 |
+
'payment-gateway' => [
|
512 |
+
'required' => true,
|
513 |
+
'title' => __( 'Payment Gateway', 'restaurant-reservations' ),
|
514 |
+
'callback' => 'rtb_print_form_select_field',
|
515 |
+
'callback_args' => [
|
516 |
+
'options' => $this->get_enabled_gateway_list(),
|
517 |
+
'empty_option' => true
|
518 |
+
],
|
519 |
+
'request_input' => isset( $request->raw_input[$prefixed_field_slug] )
|
520 |
+
? $request->raw_input[$prefixed_field_slug]
|
521 |
+
: (
|
522 |
+
property_exists($request, $this->booking_form_field_slug)
|
523 |
+
? $request->{$this->booking_form_field_slug}
|
524 |
+
: ''
|
525 |
+
)
|
526 |
+
]
|
527 |
+
]
|
528 |
+
]
|
529 |
+
];
|
530 |
+
|
531 |
+
return array_merge( $fields, $payment_gateway_field );
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Validate the payment gateway option
|
536 |
+
*
|
537 |
+
* $booking is not set yet
|
538 |
+
*
|
539 |
+
* @param stdObject $request
|
540 |
+
*/
|
541 |
+
public function validate_booking_form_gateway( $request )
|
542 |
+
{
|
543 |
+
if ( ! $this->is_payment_enabled() ) {
|
544 |
+
return;
|
545 |
+
}
|
546 |
+
|
547 |
+
$prefixed_field_slug = "rtb-{$this->booking_form_field_slug}";
|
548 |
+
|
549 |
+
// Do not validate if only one gateway enabled
|
550 |
+
if ( 1 === count( $this->enabled_gateway_list ) ) {
|
551 |
+
$this->in_use_gateway = $this->enabled_gateway_list[0];
|
552 |
+
}
|
553 |
+
elseif (
|
554 |
+
array_key_exists( $prefixed_field_slug, $_POST )
|
555 |
+
&&
|
556 |
+
! empty( $_POST[$prefixed_field_slug] )
|
557 |
+
&&
|
558 |
+
in_array( $_POST[$prefixed_field_slug], $this->enabled_gateway_list )
|
559 |
+
)
|
560 |
+
{
|
561 |
+
$this->in_use_gateway = $_POST[$prefixed_field_slug];
|
562 |
+
}
|
563 |
+
else {
|
564 |
+
$request->validation_errors[] = array(
|
565 |
+
'field' => $prefixed_field_slug,
|
566 |
+
'message' => __( 'Please select a valid payment gateway.', 'restaurant-reservations' )
|
567 |
+
);
|
568 |
+
}
|
569 |
+
|
570 |
+
if ( $this->isset_gateway_in_use() ) {
|
571 |
+
$request->{$this->booking_form_field_slug} = $this->in_use_gateway;
|
572 |
+
}
|
573 |
+
}
|
574 |
+
|
575 |
+
/**
|
576 |
+
* Attach payment gateway information with the booking
|
577 |
+
*
|
578 |
+
* @param array $meta
|
579 |
+
* @param rtbBooking $booking
|
580 |
+
*
|
581 |
+
* @return array
|
582 |
+
*/
|
583 |
+
public function save_booking_gateway_used( $meta, rtbBooking $booking )
|
584 |
+
{
|
585 |
+
if ( isset( $booking->{$this->booking_form_field_slug} ) ) {
|
586 |
+
$meta[$this->booking_form_field_slug] = $booking->{$this->booking_form_field_slug};
|
587 |
+
}
|
588 |
+
|
589 |
+
return $meta;
|
590 |
+
}
|
591 |
+
|
592 |
+
/**
|
593 |
+
* Repopulate $booking with gateway information
|
594 |
+
*
|
595 |
+
* @param rtbBooking $booking
|
596 |
+
* @param WP_Post $wp_post
|
597 |
+
*/
|
598 |
+
public function populate_booking_gateway_used( rtbBooking $booking, $wp_post )
|
599 |
+
{
|
600 |
+
if ( is_array( $meta = get_post_meta( $booking->ID, 'rtb', true ) ) ) {
|
601 |
+
$booking->{$this->booking_form_field_slug} = isset( $meta[$this->booking_form_field_slug] )
|
602 |
+
? $meta[$this->booking_form_field_slug]
|
603 |
+
: '';
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* Print the payment form's HTML code, after a new booking has been inserted
|
609 |
+
* notices.
|
610 |
+
*
|
611 |
+
* $booking must be set before this.
|
612 |
+
*/
|
613 |
+
public function print_payment_form()
|
614 |
+
{
|
615 |
+
global $rtb_controller;
|
616 |
+
|
617 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
618 |
+
|
619 |
+
if ( ! $this->isset_gateway_in_use() ) {
|
620 |
+
$this->set_gateway_in_use( $this->booking->{$this->booking_form_field_slug} );
|
621 |
+
}
|
622 |
+
|
623 |
+
if (
|
624 |
+
in_array( $this->in_use_gateway, $this->enabled_gateway_list )
|
625 |
+
&&
|
626 |
+
property_exists($this->booking, 'ID')
|
627 |
+
)
|
628 |
+
{
|
629 |
+
$gateway = $this->available_gateway_list[$this->in_use_gateway]['instance'];
|
630 |
+
|
631 |
+
$gateway->print_payment_form( $this->booking );
|
632 |
+
}
|
633 |
+
else {
|
634 |
+
$this->print_invalid_gateway();
|
635 |
+
}
|
636 |
+
}
|
637 |
+
|
638 |
+
public function print_invalid_gateway()
|
639 |
+
{
|
640 |
+
echo __(
|
641 |
+
'Invalid gateweay selected. Please contact us for the confirmation.',
|
642 |
+
'restaurant-reservations'
|
643 |
+
);
|
644 |
+
}
|
645 |
+
|
646 |
+
public function process_payment()
|
647 |
+
{
|
648 |
+
// code...
|
649 |
+
}
|
650 |
+
|
651 |
+
public function is_payment_processed()
|
652 |
+
{
|
653 |
+
// code...
|
654 |
+
}
|
655 |
+
|
656 |
+
public function payment_processing_status()
|
657 |
+
{
|
658 |
+
// code...
|
659 |
+
}
|
660 |
+
|
661 |
+
/**
|
662 |
+
* Set booking object
|
663 |
+
*
|
664 |
+
* @param rtbBooking $booking
|
665 |
+
*/
|
666 |
+
public function set_booking(rtbBooking $booking)
|
667 |
+
{
|
668 |
+
$this->booking = $booking;
|
669 |
+
|
670 |
+
return $this;
|
671 |
+
}
|
672 |
+
|
673 |
+
public function set_gateway_in_use( $gateway )
|
674 |
+
{
|
675 |
+
$this->in_use_gateway = $gateway;
|
676 |
+
}
|
677 |
+
|
678 |
+
public function get_gateway_in_use()
|
679 |
+
{
|
680 |
+
if ( $this->isset_gateway_in_use() ) {
|
681 |
+
return $this->in_use_gateway;
|
682 |
+
}
|
683 |
+
|
684 |
+
return '';
|
685 |
+
}
|
686 |
+
|
687 |
+
public function isset_gateway_in_use()
|
688 |
+
{
|
689 |
+
return in_array( $this->in_use_gateway, $this->enabled_gateway_list );
|
690 |
+
}
|
691 |
+
|
692 |
+
/**
|
693 |
+
* Remove any class registered as payment gateway without implementing the
|
694 |
+
* payment gateway interface
|
695 |
+
*/
|
696 |
+
public function strip_invalid_gateway()
|
697 |
+
{
|
698 |
+
$new_list = [];
|
699 |
+
|
700 |
+
foreach ( $this->available_gateway_list as $gateway => $data ) {
|
701 |
+
if ( $data['instance'] instanceof rtbPaymentGateway ) {
|
702 |
+
$new_list[$gateway] = $data;
|
703 |
+
}
|
704 |
+
}
|
705 |
+
|
706 |
+
$this->available_gateway_list = $new_list;
|
707 |
+
}
|
708 |
+
}
|
709 |
+
|
710 |
+
}
|
@@ -21,6 +21,12 @@ class rtbSettings {
|
|
21 |
*/
|
22 |
public $settings = array();
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
/**
|
25 |
* Languages supported by the pickadate library
|
26 |
*/
|
@@ -70,37 +76,6 @@ class rtbSettings {
|
|
70 |
'zh_TW' => 'zh_TW',
|
71 |
);
|
72 |
|
73 |
-
/**
|
74 |
-
* Currencies accepted for deposits
|
75 |
-
*/
|
76 |
-
public $currency_options = array(
|
77 |
-
'AUD' => 'Australian Dollar',
|
78 |
-
'BRL' => 'Brazilian Real',
|
79 |
-
'CAD' => 'Canadian Dollar',
|
80 |
-
'CZK' => 'Czech Koruna',
|
81 |
-
'DKK' => 'Danish Krone',
|
82 |
-
'EUR' => 'Euro',
|
83 |
-
'HKD' => 'Hong Kong Dollar',
|
84 |
-
'HUF' => 'Hungarian Forint',
|
85 |
-
'ILS' => 'Israeli New Sheqel',
|
86 |
-
'JPY' => 'Japanese Yen',
|
87 |
-
'MYR' => 'Malaysian Ringgit',
|
88 |
-
'MXN' => 'Mexican Peso',
|
89 |
-
'NOK' => 'Norwegian Krone',
|
90 |
-
'NZD' => 'New Zealand Dollar',
|
91 |
-
'PHP' => 'Philippine Peso',
|
92 |
-
'PLN' => 'Polish Zloty',
|
93 |
-
'GBP' => 'Pound Sterling',
|
94 |
-
'RUB' => 'Russian Ruble',
|
95 |
-
'SGD' => 'Singapore Dollar',
|
96 |
-
'SEK' => 'Swedish Krona',
|
97 |
-
'CHF' => 'Swiss Franc',
|
98 |
-
'TWD' => 'Taiwan New Dollar',
|
99 |
-
'THB' => 'Thai Baht',
|
100 |
-
'TRY' => 'Turkish Lira',
|
101 |
-
'USD' => 'U.S. Dollar',
|
102 |
-
);
|
103 |
-
|
104 |
public $country_phone_array = array(
|
105 |
// 'AD' => array( 'name' => 'ANDORRA', 'code' => '376' ),
|
106 |
// 'AE' => array( 'name' => 'UNITED ARAB EMIRATES', 'code' => '971' ),
|
@@ -336,15 +311,102 @@ class rtbSettings {
|
|
336 |
|
337 |
public function __construct() {
|
338 |
|
339 |
-
add_action( 'init', array( $this, '
|
|
|
|
|
340 |
|
341 |
-
add_action( 'init', array( $this, 'load_settings_panel' ) );
|
342 |
|
343 |
// Order schedule exceptions and remove past exceptions
|
344 |
add_filter( 'sanitize_option_rtb-settings', array( $this, 'clean_schedule_exceptions' ), 100 );
|
345 |
|
346 |
}
|
347 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
348 |
/**
|
349 |
* Load the plugin's default settings
|
350 |
* @since 0.0.1
|
@@ -361,13 +423,6 @@ class rtbSettings {
|
|
361 |
'time-format' => _x( 'h:i A', 'Default time format for display. Must match formatting rules at http://amsul.ca/pickadate.js/time/#formats', 'restaurant-reservations' ),
|
362 |
'time-interval' => _x( '30', 'Default interval in minutes when selecting a time.', 'restaurant-reservations' ),
|
363 |
|
364 |
-
// Payment defaults
|
365 |
-
'rtb-paypal-email' => get_option( 'admin_email' ),
|
366 |
-
'rtb-stripe-currency-symbol' => '$',
|
367 |
-
'rtb-currency-symbol-location' => 'before',
|
368 |
-
'rtb-currency' => 'USD',
|
369 |
-
'rtb-stripe-mode' => 'live',
|
370 |
-
|
371 |
// Export defaults
|
372 |
'ebfrtb-paper-size' => 'A4',
|
373 |
'ebfrtb-pdf-lib' => 'mpdf',
|
@@ -561,7 +616,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
561 |
$this->defaults['i8n'] = $i8n;
|
562 |
}
|
563 |
|
564 |
-
$this->defaults = apply_filters( '
|
565 |
}
|
566 |
|
567 |
/**
|
@@ -1157,15 +1212,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
1157 |
)
|
1158 |
);
|
1159 |
|
1160 |
-
if ( ! $rtb_controller->permissions->check_permission('premium_view_bookings') ) {
|
1161 |
-
$premium_view_bookings_permissions = array(
|
1162 |
-
'disabled' => true,
|
1163 |
-
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
1164 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
1165 |
-
);
|
1166 |
-
}
|
1167 |
-
else { $premium_view_bookings_permissions = array(); }
|
1168 |
-
|
1169 |
$sap->add_section(
|
1170 |
'rtb-settings',
|
1171 |
array(
|
@@ -1183,7 +1229,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1183 |
'title' => __( 'View Bookings Form', 'restaurant-reservations' ),
|
1184 |
'tab' => 'rtb-premium',
|
1185 |
),
|
1186 |
-
$
|
1187 |
)
|
1188 |
);
|
1189 |
$sap->add_setting(
|
@@ -1223,15 +1269,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
1223 |
)
|
1224 |
);
|
1225 |
|
1226 |
-
if ( ! $rtb_controller->permissions->check_permission('mailchimp') ) {
|
1227 |
-
$mailchimp_permissions = array(
|
1228 |
-
'disabled' => true,
|
1229 |
-
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
1230 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
1231 |
-
);
|
1232 |
-
}
|
1233 |
-
else { $mailchimp_permissions = array(); }
|
1234 |
-
|
1235 |
$sap->add_section(
|
1236 |
'rtb-settings',
|
1237 |
array_merge(
|
@@ -1240,7 +1277,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1240 |
'title' => __( 'MailChimp', 'restaurant-reservations' ),
|
1241 |
'tab' => 'rtb-premium',
|
1242 |
),
|
1243 |
-
$
|
1244 |
)
|
1245 |
);
|
1246 |
|
@@ -1308,15 +1345,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
1308 |
);
|
1309 |
}
|
1310 |
|
1311 |
-
if ( ! $rtb_controller->permissions->check_permission('premium_seat_restrictions') ) {
|
1312 |
-
$premium_seat_restrictions_permissions = array(
|
1313 |
-
'disabled' => true,
|
1314 |
-
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
1315 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
1316 |
-
);
|
1317 |
-
}
|
1318 |
-
else { $premium_seat_restrictions_permissions = array(); }
|
1319 |
-
|
1320 |
$sap->add_section(
|
1321 |
'rtb-settings',
|
1322 |
array_merge(
|
@@ -1325,7 +1353,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1325 |
'title' => __( 'Seat Restrictions', 'restaurant-reservations' ),
|
1326 |
'tab' => 'rtb-premium',
|
1327 |
),
|
1328 |
-
$
|
1329 |
)
|
1330 |
);
|
1331 |
$sap->add_setting(
|
@@ -1412,16 +1440,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
1412 |
)
|
1413 |
);
|
1414 |
|
1415 |
-
if ( ! $rtb_controller->permissions->check_permission('premium_table_restrictions') ) {
|
1416 |
-
$premium_table_restrictions_permissions = array(
|
1417 |
-
'disabled' => true,
|
1418 |
-
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
1419 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/',
|
1420 |
-
'ultimate_needed' => 'Yes'
|
1421 |
-
);
|
1422 |
-
}
|
1423 |
-
else { $premium_table_restrictions_permissions = array(); }
|
1424 |
-
|
1425 |
$sap->add_section(
|
1426 |
'rtb-settings',
|
1427 |
array_merge(
|
@@ -1430,9 +1448,10 @@ If you were not the one to cancel this booking, please contact us.
|
|
1430 |
'title' => __( 'Table Restrictions', 'restaurant-reservations' ),
|
1431 |
'tab' => 'rtb-premium',
|
1432 |
),
|
1433 |
-
$
|
1434 |
)
|
1435 |
);
|
|
|
1436 |
$sap->add_setting(
|
1437 |
'rtb-settings',
|
1438 |
'rtb-table-assignments',
|
@@ -1443,6 +1462,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1443 |
'description' => __( 'Allow guests to select a table that they\'d like to sit at during their visit.', 'restaurant-reservations' )
|
1444 |
)
|
1445 |
);
|
|
|
1446 |
$sap->add_setting(
|
1447 |
'rtb-settings',
|
1448 |
'rtb-table-assignments',
|
@@ -1453,6 +1473,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1453 |
'description' => __( 'Don\'t allow a reservation to be made without a valid table selected, even if all other booking criteria are met (acceptable party size, below max reservations/seats).', 'restaurant-reservations' )
|
1454 |
)
|
1455 |
);
|
|
|
1456 |
$sap->add_setting(
|
1457 |
'rtb-settings',
|
1458 |
'rtb-table-assignments',
|
@@ -1487,6 +1508,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1487 |
)
|
1488 |
)
|
1489 |
);
|
|
|
1490 |
$sap->add_setting(
|
1491 |
'rtb-settings',
|
1492 |
'rtb-table-assignments',
|
@@ -1527,15 +1549,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
1527 |
)
|
1528 |
);
|
1529 |
|
1530 |
-
if ( ! $rtb_controller->permissions->check_permission('designer') ) {
|
1531 |
-
$designer_permissions = array(
|
1532 |
-
'disabled' => true,
|
1533 |
-
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
1534 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
1535 |
-
);
|
1536 |
-
}
|
1537 |
-
else { $designer_permissions = array(); }
|
1538 |
-
|
1539 |
$sap->add_section(
|
1540 |
'rtb-settings',
|
1541 |
array(
|
@@ -1553,7 +1566,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1553 |
'title' => __( 'Email Templates', 'restaurant-reservations' ),
|
1554 |
'tab' => 'rtb-notifications-tab',
|
1555 |
),
|
1556 |
-
$
|
1557 |
)
|
1558 |
);
|
1559 |
|
@@ -1853,16 +1866,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
1853 |
)
|
1854 |
);
|
1855 |
|
1856 |
-
if ( ! $rtb_controller->permissions->check_permission('reminders') ) {
|
1857 |
-
$reminders_permissions = array(
|
1858 |
-
'disabled' => true,
|
1859 |
-
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
1860 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/',
|
1861 |
-
'ultimate_needed' => 'Yes'
|
1862 |
-
);
|
1863 |
-
}
|
1864 |
-
else { $reminders_permissions = array(); }
|
1865 |
-
|
1866 |
$sap->add_section(
|
1867 |
'rtb-settings',
|
1868 |
array_merge(
|
@@ -1872,7 +1875,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
1872 |
'tab' => 'rtb-notifications-tab',
|
1873 |
'description' => __( 'Set up reservation and late arrival reminders.' ),
|
1874 |
),
|
1875 |
-
$
|
1876 |
)
|
1877 |
);
|
1878 |
|
@@ -1889,7 +1892,9 @@ If you were not the one to cancel this booking, please contact us.
|
|
1889 |
);
|
1890 |
|
1891 |
$country_phone_display_array = array();
|
1892 |
-
foreach ( $this->country_phone_array as $country_code => $country_array ) {
|
|
|
|
|
1893 |
|
1894 |
$sap->add_setting(
|
1895 |
'rtb-settings',
|
@@ -1935,23 +1940,23 @@ If you were not the one to cancel this booking, please contact us.
|
|
1935 |
);
|
1936 |
|
1937 |
$sap->add_setting(
|
1938 |
-
|
1939 |
-
|
1940 |
-
|
1941 |
-
|
1942 |
-
|
1943 |
-
|
1944 |
-
|
1945 |
-
|
1946 |
-
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
|
1953 |
-
|
1954 |
-
|
1955 |
|
1956 |
$sap->add_setting(
|
1957 |
'rtb-settings',
|
@@ -1982,15 +1987,15 @@ If you were not the one to cancel this booking, please contact us.
|
|
1982 |
'rtb-reservation-reminders',
|
1983 |
'count',
|
1984 |
array(
|
1985 |
-
'id'
|
1986 |
-
'title'
|
1987 |
-
'description'
|
1988 |
-
'min_value'
|
1989 |
'max_value' => 60,
|
1990 |
'increment' => 1,
|
1991 |
-
'units'
|
1992 |
-
|
1993 |
-
|
1994 |
)
|
1995 |
)
|
1996 |
);
|
@@ -2051,240 +2056,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
2051 |
)
|
2052 |
);
|
2053 |
|
2054 |
-
if ( ! $rtb_controller->permissions->check_permission('payments') ) {
|
2055 |
-
$payment_permissions = array(
|
2056 |
-
'disabled' => true,
|
2057 |
-
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
2058 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/',
|
2059 |
-
'ultimate_needed' => 'Yes'
|
2060 |
-
);
|
2061 |
-
}
|
2062 |
-
else { $payment_permissions = array(); }
|
2063 |
-
|
2064 |
-
$sap->add_section(
|
2065 |
-
'rtb-settings',
|
2066 |
-
array(
|
2067 |
-
'id' => 'rtb-payments-tab',
|
2068 |
-
'title' => __( 'Payments', 'restaurant-reservations' ),
|
2069 |
-
'is_tab' => true,
|
2070 |
-
)
|
2071 |
-
);
|
2072 |
-
|
2073 |
-
$sap->add_section(
|
2074 |
-
'rtb-settings',
|
2075 |
-
array_merge(
|
2076 |
-
array(
|
2077 |
-
'id' => 'rtb-general-payment',
|
2078 |
-
'title' => __( 'General', 'restaurant-reservations' ),
|
2079 |
-
'tab' => 'rtb-payments-tab',
|
2080 |
-
),
|
2081 |
-
$payment_permissions
|
2082 |
-
)
|
2083 |
-
);
|
2084 |
-
$sap->add_setting(
|
2085 |
-
'rtb-settings',
|
2086 |
-
'rtb-general-payment',
|
2087 |
-
'toggle',
|
2088 |
-
array(
|
2089 |
-
'id' => 'require-deposit',
|
2090 |
-
'title' => __( 'Require Deposit', 'restaurant-reservations' ),
|
2091 |
-
'description' => __( 'Require guests to make a deposit when making a reservation.', 'restaurant-reservations' )
|
2092 |
-
)
|
2093 |
-
);
|
2094 |
-
$sap->add_setting(
|
2095 |
-
'rtb-settings',
|
2096 |
-
'rtb-general-payment',
|
2097 |
-
'radio',
|
2098 |
-
array(
|
2099 |
-
'id' => 'rtb-payment-gateway',
|
2100 |
-
'title' => __( 'Payment Gateway', 'restaurant-reservations' ),
|
2101 |
-
'description' => __( 'Which payment gateway should be used to accept deposits.', 'restaurant-reservations' ),
|
2102 |
-
'options' => array(
|
2103 |
-
'paypal' => 'PayPal',
|
2104 |
-
'stripe' => 'Stripe'
|
2105 |
-
)
|
2106 |
-
)
|
2107 |
-
);
|
2108 |
-
$sap->add_setting(
|
2109 |
-
'rtb-settings',
|
2110 |
-
'rtb-general-payment',
|
2111 |
-
'radio',
|
2112 |
-
array(
|
2113 |
-
'id' => 'rtb-deposit-type',
|
2114 |
-
'title' => __( 'Deposit Type', 'restaurant-reservations' ),
|
2115 |
-
'description' => __( 'What type of deposit should be required, per reservation or per guest?', 'restaurant-reservations' ),
|
2116 |
-
'options' => array(
|
2117 |
-
'reservation' => 'Per Reservation',
|
2118 |
-
'guest' => 'Per Guest'
|
2119 |
-
)
|
2120 |
-
)
|
2121 |
-
);
|
2122 |
-
$sap->add_setting(
|
2123 |
-
'rtb-settings',
|
2124 |
-
'rtb-general-payment',
|
2125 |
-
'text',
|
2126 |
-
array(
|
2127 |
-
'id' => 'rtb-deposit-amount',
|
2128 |
-
'title' => __( 'Deposit Amount', 'restaurant-reservations' ),
|
2129 |
-
'description' => __( 'What deposit amount is required (either per reservation or per guest, depending on the setting above)? Minimum is $0.50 in most currencies.', 'restaurant-reservations' )
|
2130 |
-
)
|
2131 |
-
);
|
2132 |
-
$sap->add_setting(
|
2133 |
-
'rtb-settings',
|
2134 |
-
'rtb-general-payment',
|
2135 |
-
'select',
|
2136 |
-
array(
|
2137 |
-
'id' => 'rtb-currency',
|
2138 |
-
'title' => __( 'Currency', 'restaurant-reservations' ),
|
2139 |
-
'description' => __( 'Select the currency you accept for your deposits.', 'restaurant-reservations' ),
|
2140 |
-
'blank_option' => false,
|
2141 |
-
'options' => $this->currency_options
|
2142 |
-
)
|
2143 |
-
);
|
2144 |
-
|
2145 |
-
$sap->add_section(
|
2146 |
-
'rtb-settings',
|
2147 |
-
array_merge(
|
2148 |
-
array(
|
2149 |
-
'id' => 'rtb-paypal-payment',
|
2150 |
-
'title' => __( 'PayPal', 'restaurant-reservations' ),
|
2151 |
-
'tab' => 'rtb-payments-tab',
|
2152 |
-
),
|
2153 |
-
$payment_permissions
|
2154 |
-
)
|
2155 |
-
);
|
2156 |
-
$sap->add_setting(
|
2157 |
-
'rtb-settings',
|
2158 |
-
'rtb-paypal-payment',
|
2159 |
-
'text',
|
2160 |
-
array(
|
2161 |
-
'id' => 'rtb-paypal-email',
|
2162 |
-
'title' => __( 'PayPal Email Address', 'restaurant-reservations' ),
|
2163 |
-
'description' => __( 'The email address you\'ll be using to accept PayPal payments.', 'restaurant-reservations' ),
|
2164 |
-
'placeholder' =>$this->defaults['rtb-paypal-email']
|
2165 |
-
)
|
2166 |
-
);
|
2167 |
-
|
2168 |
-
$sap->add_section(
|
2169 |
-
'rtb-settings',
|
2170 |
-
array_merge(
|
2171 |
-
array(
|
2172 |
-
'id' => 'rtb-stripe-payment',
|
2173 |
-
'title' => __( 'Stripe', 'restaurant-reservations' ),
|
2174 |
-
'tab' => 'rtb-payments-tab',
|
2175 |
-
),
|
2176 |
-
$payment_permissions
|
2177 |
-
)
|
2178 |
-
);
|
2179 |
-
$sap->add_setting(
|
2180 |
-
'rtb-settings',
|
2181 |
-
'rtb-stripe-payment',
|
2182 |
-
'toggle',
|
2183 |
-
array(
|
2184 |
-
'id' => 'rtb-stripe-sca',
|
2185 |
-
'title' => __( 'Strong Customer Authorization (SCA)', 'restaurant-reservations' ),
|
2186 |
-
'description' => __( 'User will be redirected to Stripe and presented with 3D secure or bank redirect for payment authentication. (May be necessary for certain EU compliance.)', 'restaurant-reservations' )
|
2187 |
-
)
|
2188 |
-
);
|
2189 |
-
$sap->add_setting(
|
2190 |
-
'rtb-settings',
|
2191 |
-
'rtb-stripe-payment',
|
2192 |
-
'text',
|
2193 |
-
array(
|
2194 |
-
'id' => 'rtb-stripe-currency-symbol',
|
2195 |
-
'title' => __( 'Stripe Currency Symbol', 'restaurant-reservations' ),
|
2196 |
-
'description' => __( 'The currency symbol you\'d like displayed before or after the required deposit amount.', 'restaurant-reservations' ),
|
2197 |
-
'placeholder' => $this->defaults['rtb-stripe-currency-symbol']
|
2198 |
-
)
|
2199 |
-
);
|
2200 |
-
$sap->add_setting(
|
2201 |
-
'rtb-settings',
|
2202 |
-
'rtb-stripe-payment',
|
2203 |
-
'toggle',
|
2204 |
-
array(
|
2205 |
-
'id' => 'rtb-expiration-field-single',
|
2206 |
-
'title' => __( 'CC Expiration Single Field', 'restaurant-reservations' ),
|
2207 |
-
'description' => __( 'Should the field for card expiry details be a single field with a mask or two separate fields for month and year?', 'restaurant-reservations' )
|
2208 |
-
)
|
2209 |
-
);
|
2210 |
-
$sap->add_setting(
|
2211 |
-
'rtb-settings',
|
2212 |
-
'rtb-stripe-payment',
|
2213 |
-
'radio',
|
2214 |
-
array(
|
2215 |
-
'id' => 'rtb-currency-symbol-location',
|
2216 |
-
'title' => __( 'Currency Symbol Location', 'restaurant-reservations' ),
|
2217 |
-
'description' => __( 'Should the currency symbol be placed before or after the deposit amount?', 'restaurant-reservations' ),
|
2218 |
-
'options' => array(
|
2219 |
-
'before' => 'Before',
|
2220 |
-
'after' => 'After'
|
2221 |
-
)
|
2222 |
-
)
|
2223 |
-
);
|
2224 |
-
$sap->add_setting(
|
2225 |
-
'rtb-settings',
|
2226 |
-
'rtb-stripe-payment',
|
2227 |
-
'radio',
|
2228 |
-
array(
|
2229 |
-
'id' => 'rtb-stripe-mode',
|
2230 |
-
'title' => __( 'Test/Live Mode', 'restaurant-reservations' ),
|
2231 |
-
'description' => __( 'Should the system use test or live mode? Test mode should only be used for testing, no deposits will actually be processed while turned on.', 'restaurant-reservations' ),
|
2232 |
-
'options' => array(
|
2233 |
-
'test' => 'Test',
|
2234 |
-
'live' => 'Live'
|
2235 |
-
)
|
2236 |
-
)
|
2237 |
-
);
|
2238 |
-
$sap->add_setting(
|
2239 |
-
'rtb-settings',
|
2240 |
-
'rtb-stripe-payment',
|
2241 |
-
'text',
|
2242 |
-
array(
|
2243 |
-
'id' => 'rtb-stripe-live-secret',
|
2244 |
-
'title' => __( 'Stripe Live Secret', 'restaurant-reservations' ),
|
2245 |
-
'description' => __( 'The live secret that you have set up for your Stripe account.', 'restaurant-reservations' )
|
2246 |
-
)
|
2247 |
-
);
|
2248 |
-
$sap->add_setting(
|
2249 |
-
'rtb-settings',
|
2250 |
-
'rtb-stripe-payment',
|
2251 |
-
'text',
|
2252 |
-
array(
|
2253 |
-
'id' => 'rtb-stripe-live-publishable',
|
2254 |
-
'title' => __( 'Stripe Live Publishable', 'restaurant-reservations' ),
|
2255 |
-
'description' => __( 'The live publishable that you have set up for your Stripe account.', 'restaurant-reservations' )
|
2256 |
-
)
|
2257 |
-
);
|
2258 |
-
$sap->add_setting(
|
2259 |
-
'rtb-settings',
|
2260 |
-
'rtb-stripe-payment',
|
2261 |
-
'text',
|
2262 |
-
array(
|
2263 |
-
'id' => 'rtb-stripe-test-secret',
|
2264 |
-
'title' => __( 'Stripe Test Secret', 'restaurant-reservations' ),
|
2265 |
-
'description' => __( 'The test secret that you have set up for your Stripe account. Only needed for testing payments.', 'restaurant-reservations' )
|
2266 |
-
)
|
2267 |
-
);
|
2268 |
-
$sap->add_setting(
|
2269 |
-
'rtb-settings',
|
2270 |
-
'rtb-stripe-payment',
|
2271 |
-
'text',
|
2272 |
-
array(
|
2273 |
-
'id' => 'rtb-stripe-test-publishable',
|
2274 |
-
'title' => __( 'Stripe Test Publishable', 'restaurant-reservations' ),
|
2275 |
-
'description' => __( 'The test publishable that you have set up for your Stripe account. Only needed for testing payments.', 'restaurant-reservations' )
|
2276 |
-
)
|
2277 |
-
);
|
2278 |
-
|
2279 |
-
if ( ! $rtb_controller->permissions->check_permission('export') ) {
|
2280 |
-
$export_permissions = array(
|
2281 |
-
'disabled' => true,
|
2282 |
-
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
2283 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
2284 |
-
);
|
2285 |
-
}
|
2286 |
-
else { $export_permissions = array(); }
|
2287 |
-
|
2288 |
//Create a tab for export settings
|
2289 |
$sap->add_section(
|
2290 |
'rtb-settings',
|
@@ -2303,7 +2074,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
2303 |
'title' => __( 'Settings', 'restaurant-reservations' ),
|
2304 |
'tab' => 'rtb-export-tab',
|
2305 |
),
|
2306 |
-
$
|
2307 |
)
|
2308 |
);
|
2309 |
|
@@ -2351,15 +2122,6 @@ If you were not the one to cancel this booking, please contact us.
|
|
2351 |
)
|
2352 |
);
|
2353 |
|
2354 |
-
if ( ! $rtb_controller->permissions->check_permission('styling') ) {
|
2355 |
-
$styling_permissions = array(
|
2356 |
-
'disabled' => true,
|
2357 |
-
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
2358 |
-
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
2359 |
-
);
|
2360 |
-
}
|
2361 |
-
else { $styling_permissions = array(); }
|
2362 |
-
|
2363 |
// Create a tab for styling settings
|
2364 |
$sap->add_section(
|
2365 |
'rtb-settings',
|
@@ -2378,7 +2140,7 @@ If you were not the one to cancel this booking, please contact us.
|
|
2378 |
'title' => __( 'Reservation Form', 'restaurant-reservations' ),
|
2379 |
'tab' => 'rtb-styling-settings-tab',
|
2380 |
),
|
2381 |
-
$
|
2382 |
)
|
2383 |
);
|
2384 |
|
@@ -2914,10 +2676,18 @@ If you were not the one to cancel this booking, please contact us.
|
|
2914 |
$require_table = $rtb_controller->settings->get_setting( 'require-table' );
|
2915 |
if ( $enable_tables ) {
|
2916 |
|
2917 |
-
|
2918 |
$fields['reservation']['fields']['table'] = array(
|
2919 |
'title' => __( 'Table(s)', 'restaurant-reservations' ),
|
2920 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2921 |
'callback' => 'rtb_print_form_select_field',
|
2922 |
'callback_args' => array(
|
2923 |
'options' => $this->get_form_table_options(),
|
21 |
*/
|
22 |
public $settings = array();
|
23 |
|
24 |
+
/**
|
25 |
+
* Should a premium setting be disabled or not
|
26 |
+
* @since 2.4.0
|
27 |
+
*/
|
28 |
+
public $premium_permissions = array();
|
29 |
+
|
30 |
/**
|
31 |
* Languages supported by the pickadate library
|
32 |
*/
|
76 |
'zh_TW' => 'zh_TW',
|
77 |
);
|
78 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
public $country_phone_array = array(
|
80 |
// 'AD' => array( 'name' => 'ANDORRA', 'code' => '376' ),
|
81 |
// 'AE' => array( 'name' => 'UNITED ARAB EMIRATES', 'code' => '971' ),
|
311 |
|
312 |
public function __construct() {
|
313 |
|
314 |
+
add_action( 'init', array( $this, 'check_permissions' ), 10 );
|
315 |
+
|
316 |
+
add_action( 'init', array( $this, 'set_defaults' ), 11 );
|
317 |
|
318 |
+
add_action( 'init', array( $this, 'load_settings_panel' ), 12 );
|
319 |
|
320 |
// Order schedule exceptions and remove past exceptions
|
321 |
add_filter( 'sanitize_option_rtb-settings', array( $this, 'clean_schedule_exceptions' ), 100 );
|
322 |
|
323 |
}
|
324 |
|
325 |
+
/**
|
326 |
+
* Pre-check the permissions to enable/disable settings as per the
|
327 |
+
* current license type
|
328 |
+
* @return void
|
329 |
+
*/
|
330 |
+
public function check_permissions() {
|
331 |
+
global $rtb_controller;
|
332 |
+
|
333 |
+
$this->premium_permissions['view_bookings'] = array();
|
334 |
+
if ( ! $rtb_controller->permissions->check_permission('premium_view_bookings') ) {
|
335 |
+
$this->premium_permissions['view_bookings'] = array(
|
336 |
+
'disabled' => true,
|
337 |
+
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
338 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
339 |
+
);
|
340 |
+
}
|
341 |
+
|
342 |
+
$this->premium_permissions['mailchimp'] = array();
|
343 |
+
if ( ! $rtb_controller->permissions->check_permission('mailchimp') ) {
|
344 |
+
$this->premium_permissions['mailchimp'] = array(
|
345 |
+
'disabled' => true,
|
346 |
+
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
347 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
348 |
+
);
|
349 |
+
}
|
350 |
+
|
351 |
+
$this->premium_permissions['seat_restrictions'] = array();
|
352 |
+
if ( ! $rtb_controller->permissions->check_permission('premium_seat_restrictions') ) {
|
353 |
+
$this->premium_permissions['seat_restrictions'] = array(
|
354 |
+
'disabled' => true,
|
355 |
+
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
356 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
357 |
+
);
|
358 |
+
}
|
359 |
+
|
360 |
+
$this->premium_permissions['table_restrictions'] = array();
|
361 |
+
if ( ! $rtb_controller->permissions->check_permission('premium_table_restrictions') ) {
|
362 |
+
$this->premium_permissions['table_restrictions'] = array(
|
363 |
+
'disabled' => true,
|
364 |
+
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
365 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/',
|
366 |
+
'ultimate_needed' => 'Yes'
|
367 |
+
);
|
368 |
+
}
|
369 |
+
|
370 |
+
$this->premium_permissions['designer'] = array();
|
371 |
+
if ( ! $rtb_controller->permissions->check_permission('designer') ) {
|
372 |
+
$this->premium_permissions['designer'] = array(
|
373 |
+
'disabled' => true,
|
374 |
+
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
375 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
376 |
+
);
|
377 |
+
}
|
378 |
+
|
379 |
+
$this->premium_permissions['reminders'] = array();
|
380 |
+
if ( ! $rtb_controller->permissions->check_permission('reminders') ) {
|
381 |
+
$this->premium_permissions['reminders'] = array(
|
382 |
+
'disabled' => true,
|
383 |
+
'disabled_image' => 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
384 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/',
|
385 |
+
'ultimate_needed' => 'Yes'
|
386 |
+
);
|
387 |
+
}
|
388 |
+
|
389 |
+
$this->premium_permissions['export'] = array();
|
390 |
+
if ( ! $rtb_controller->permissions->check_permission('export') ) {
|
391 |
+
$this->premium_permissions['export'] = array(
|
392 |
+
'disabled' => true,
|
393 |
+
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
394 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
395 |
+
);
|
396 |
+
}
|
397 |
+
|
398 |
+
$this->premium_permissions['styling'] = array();
|
399 |
+
if ( ! $rtb_controller->permissions->check_permission('styling') ) {
|
400 |
+
$this->premium_permissions['styling'] = array(
|
401 |
+
'disabled' => true,
|
402 |
+
'disabled_image'=> 'https://www.etoilewebdesign.com/wp-content/uploads/2018/06/Logo-White-Filled40-px.png',
|
403 |
+
'purchase_link' => 'https://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/'
|
404 |
+
);
|
405 |
+
}
|
406 |
+
|
407 |
+
$this->premium_permissions = apply_filters( 'rtb_settings_check_permissions', $this->premium_permissions );
|
408 |
+
}
|
409 |
+
|
410 |
/**
|
411 |
* Load the plugin's default settings
|
412 |
* @since 0.0.1
|
423 |
'time-format' => _x( 'h:i A', 'Default time format for display. Must match formatting rules at http://amsul.ca/pickadate.js/time/#formats', 'restaurant-reservations' ),
|
424 |
'time-interval' => _x( '30', 'Default interval in minutes when selecting a time.', 'restaurant-reservations' ),
|
425 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
426 |
// Export defaults
|
427 |
'ebfrtb-paper-size' => 'A4',
|
428 |
'ebfrtb-pdf-lib' => 'mpdf',
|
616 |
$this->defaults['i8n'] = $i8n;
|
617 |
}
|
618 |
|
619 |
+
$this->defaults = apply_filters( 'rtb_settings_defaults', $this->defaults );
|
620 |
}
|
621 |
|
622 |
/**
|
1212 |
)
|
1213 |
);
|
1214 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1215 |
$sap->add_section(
|
1216 |
'rtb-settings',
|
1217 |
array(
|
1229 |
'title' => __( 'View Bookings Form', 'restaurant-reservations' ),
|
1230 |
'tab' => 'rtb-premium',
|
1231 |
),
|
1232 |
+
$this->premium_permissions['view_bookings']
|
1233 |
)
|
1234 |
);
|
1235 |
$sap->add_setting(
|
1269 |
)
|
1270 |
);
|
1271 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1272 |
$sap->add_section(
|
1273 |
'rtb-settings',
|
1274 |
array_merge(
|
1277 |
'title' => __( 'MailChimp', 'restaurant-reservations' ),
|
1278 |
'tab' => 'rtb-premium',
|
1279 |
),
|
1280 |
+
$this->premium_permissions['mailchimp']
|
1281 |
)
|
1282 |
);
|
1283 |
|
1345 |
);
|
1346 |
}
|
1347 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1348 |
$sap->add_section(
|
1349 |
'rtb-settings',
|
1350 |
array_merge(
|
1353 |
'title' => __( 'Seat Restrictions', 'restaurant-reservations' ),
|
1354 |
'tab' => 'rtb-premium',
|
1355 |
),
|
1356 |
+
$this->premium_permissions['seat_restrictions']
|
1357 |
)
|
1358 |
);
|
1359 |
$sap->add_setting(
|
1440 |
)
|
1441 |
);
|
1442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1443 |
$sap->add_section(
|
1444 |
'rtb-settings',
|
1445 |
array_merge(
|
1448 |
'title' => __( 'Table Restrictions', 'restaurant-reservations' ),
|
1449 |
'tab' => 'rtb-premium',
|
1450 |
),
|
1451 |
+
$this->premium_permissions['table_restrictions']
|
1452 |
)
|
1453 |
);
|
1454 |
+
|
1455 |
$sap->add_setting(
|
1456 |
'rtb-settings',
|
1457 |
'rtb-table-assignments',
|
1462 |
'description' => __( 'Allow guests to select a table that they\'d like to sit at during their visit.', 'restaurant-reservations' )
|
1463 |
)
|
1464 |
);
|
1465 |
+
|
1466 |
$sap->add_setting(
|
1467 |
'rtb-settings',
|
1468 |
'rtb-table-assignments',
|
1473 |
'description' => __( 'Don\'t allow a reservation to be made without a valid table selected, even if all other booking criteria are met (acceptable party size, below max reservations/seats).', 'restaurant-reservations' )
|
1474 |
)
|
1475 |
);
|
1476 |
+
|
1477 |
$sap->add_setting(
|
1478 |
'rtb-settings',
|
1479 |
'rtb-table-assignments',
|
1508 |
)
|
1509 |
)
|
1510 |
);
|
1511 |
+
|
1512 |
$sap->add_setting(
|
1513 |
'rtb-settings',
|
1514 |
'rtb-table-assignments',
|
1549 |
)
|
1550 |
);
|
1551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1552 |
$sap->add_section(
|
1553 |
'rtb-settings',
|
1554 |
array(
|
1566 |
'title' => __( 'Email Templates', 'restaurant-reservations' ),
|
1567 |
'tab' => 'rtb-notifications-tab',
|
1568 |
),
|
1569 |
+
$this->premium_permissions['designer']
|
1570 |
)
|
1571 |
);
|
1572 |
|
1866 |
)
|
1867 |
);
|
1868 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1869 |
$sap->add_section(
|
1870 |
'rtb-settings',
|
1871 |
array_merge(
|
1875 |
'tab' => 'rtb-notifications-tab',
|
1876 |
'description' => __( 'Set up reservation and late arrival reminders.' ),
|
1877 |
),
|
1878 |
+
$this->premium_permissions['reminders']
|
1879 |
)
|
1880 |
);
|
1881 |
|
1892 |
);
|
1893 |
|
1894 |
$country_phone_display_array = array();
|
1895 |
+
foreach ( $this->country_phone_array as $country_code => $country_array ) {
|
1896 |
+
$country_phone_display_array[$country_code] = $country_array['name'] . ' (+' . $country_array['code'] . ')';
|
1897 |
+
}
|
1898 |
|
1899 |
$sap->add_setting(
|
1900 |
'rtb-settings',
|
1940 |
);
|
1941 |
|
1942 |
$sap->add_setting(
|
1943 |
+
'rtb-settings',
|
1944 |
+
'rtb-reservation-reminders',
|
1945 |
+
'count',
|
1946 |
+
array(
|
1947 |
+
'id' => 'time-reminder-user',
|
1948 |
+
'title' => __( 'Reservation Reminder Before Time', 'restaurant-reservations' ),
|
1949 |
+
'description' => __( 'How long before a reservation should a reminder email be sent? Leave blank to not send a reservation reminder.', 'restaurant-reservations' ),
|
1950 |
+
'min_value' => 1,
|
1951 |
+
'max_value' => 60,
|
1952 |
+
'increment' => 1,
|
1953 |
+
'units' => array(
|
1954 |
+
'minutes' => 'Minutes',
|
1955 |
+
'hours' => 'Hours',
|
1956 |
+
'days' => 'Days'
|
1957 |
+
)
|
1958 |
+
)
|
1959 |
+
);
|
1960 |
|
1961 |
$sap->add_setting(
|
1962 |
'rtb-settings',
|
1987 |
'rtb-reservation-reminders',
|
1988 |
'count',
|
1989 |
array(
|
1990 |
+
'id' => 'time-late-user',
|
1991 |
+
'title' => __( 'Late for Reservation Time', 'restaurant-reservations' ),
|
1992 |
+
'description' => __( 'How long after being late for a reservation should a late arrival email be sent? Leave blank to not send a late arrival email.', 'restaurant-reservations' ),
|
1993 |
+
'min_value' => 1,
|
1994 |
'max_value' => 60,
|
1995 |
'increment' => 1,
|
1996 |
+
'units' => array(
|
1997 |
+
'minutes' => 'Minutes',
|
1998 |
+
'hours' => 'Hours',
|
1999 |
)
|
2000 |
)
|
2001 |
);
|
2056 |
)
|
2057 |
);
|
2058 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2059 |
//Create a tab for export settings
|
2060 |
$sap->add_section(
|
2061 |
'rtb-settings',
|
2074 |
'title' => __( 'Settings', 'restaurant-reservations' ),
|
2075 |
'tab' => 'rtb-export-tab',
|
2076 |
),
|
2077 |
+
$this->premium_permissions['export']
|
2078 |
)
|
2079 |
);
|
2080 |
|
2122 |
)
|
2123 |
);
|
2124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2125 |
// Create a tab for styling settings
|
2126 |
$sap->add_section(
|
2127 |
'rtb-settings',
|
2140 |
'title' => __( 'Reservation Form', 'restaurant-reservations' ),
|
2141 |
'tab' => 'rtb-styling-settings-tab',
|
2142 |
),
|
2143 |
+
$this->premium_permissions['styling']
|
2144 |
)
|
2145 |
);
|
2146 |
|
2676 |
$require_table = $rtb_controller->settings->get_setting( 'require-table' );
|
2677 |
if ( $enable_tables ) {
|
2678 |
|
|
|
2679 |
$fields['reservation']['fields']['table'] = array(
|
2680 |
'title' => __( 'Table(s)', 'restaurant-reservations' ),
|
2681 |
+
/**
|
2682 |
+
* Raw, unprocessed value because processed value is an array
|
2683 |
+
*/
|
2684 |
+
'request_input' => empty( $request->table )
|
2685 |
+
? ''
|
2686 |
+
: (
|
2687 |
+
array_key_exists( 'rtb-table', $request->raw_input )
|
2688 |
+
? $request->raw_input['rtb-table']
|
2689 |
+
: ''
|
2690 |
+
),
|
2691 |
'callback' => 'rtb_print_form_select_field',
|
2692 |
'callback_args' => array(
|
2693 |
'options' => $this->get_form_table_options(),
|
@@ -318,7 +318,6 @@ class rtbBookingsTable extends WP_List_Table {
|
|
318 |
$views = array(
|
319 |
'all' => sprintf( '<a href="%s"%s>%s</a>', esc_url( remove_query_arg( array( 'status', 'paged' ), $this->query_string ) ), $current === 'all' || $current == '' ? ' class="current"' : '', __( 'All', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['total'] . ')</span>' ),
|
320 |
'pending' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'pending', 'paged' => FALSE ), $this->query_string ) ), $current === 'pending' ? ' class="current"' : '', __( 'Pending', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['pending'] . ')</span>' ),
|
321 |
-
'payment_pending' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'payment_pending', 'paged' => FALSE ), $this->query_string ) ), $current === 'payment_pending' ? ' class="current"' : '', __( 'Payment Pending', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['payment_pending'] . ')</span>' ),
|
322 |
'confirmed' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'confirmed', 'paged' => FALSE ), $this->query_string ) ), $current === 'confirmed' ? ' class="current"' : '', __( 'Confirmed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['confirmed'] . ')</span>' ),
|
323 |
'closed' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'closed', 'paged' => FALSE ), $this->query_string ) ), $current === 'closed' ? ' class="current"' : '', __( 'Closed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['closed'] . ')</span>' ),
|
324 |
'trash' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'trash', 'paged' => FALSE ), $this->query_string ) ), $current === 'trash' ? ' class="current"' : '', __( 'Trash', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['trash'] . ')</span>' ),
|
@@ -328,6 +327,10 @@ class rtbBookingsTable extends WP_List_Table {
|
|
328 |
array_splice($views, 3, 0, array( 'payment_failed' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'payment_failed', 'paged' => FALSE ), $this->query_string ) ), $current === 'payment_failed' ? ' class="current"' : '', __( 'Payment Failed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['payment_failed'] . ')</span>' ), ) );
|
329 |
}
|
330 |
|
|
|
|
|
|
|
|
|
331 |
return apply_filters( 'rtb_bookings_table_views_status', $views );
|
332 |
}
|
333 |
|
318 |
$views = array(
|
319 |
'all' => sprintf( '<a href="%s"%s>%s</a>', esc_url( remove_query_arg( array( 'status', 'paged' ), $this->query_string ) ), $current === 'all' || $current == '' ? ' class="current"' : '', __( 'All', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['total'] . ')</span>' ),
|
320 |
'pending' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'pending', 'paged' => FALSE ), $this->query_string ) ), $current === 'pending' ? ' class="current"' : '', __( 'Pending', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['pending'] . ')</span>' ),
|
|
|
321 |
'confirmed' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'confirmed', 'paged' => FALSE ), $this->query_string ) ), $current === 'confirmed' ? ' class="current"' : '', __( 'Confirmed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['confirmed'] . ')</span>' ),
|
322 |
'closed' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'closed', 'paged' => FALSE ), $this->query_string ) ), $current === 'closed' ? ' class="current"' : '', __( 'Closed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['closed'] . ')</span>' ),
|
323 |
'trash' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'trash', 'paged' => FALSE ), $this->query_string ) ), $current === 'trash' ? ' class="current"' : '', __( 'Trash', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['trash'] . ')</span>' ),
|
327 |
array_splice($views, 3, 0, array( 'payment_failed' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'payment_failed', 'paged' => FALSE ), $this->query_string ) ), $current === 'payment_failed' ? ' class="current"' : '', __( 'Payment Failed', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['payment_failed'] . ')</span>' ), ) );
|
328 |
}
|
329 |
|
330 |
+
if ( isset( $this->booking_counts['payment_pending'] ) and $this->booking_counts['payment_pending'] > 0 ) {
|
331 |
+
array_splice($views, 3, 0, array( 'payment_pending' => sprintf( '<a href="%s"%s>%s</a>', esc_url( add_query_arg( array( 'status' => 'payment_pending', 'paged' => FALSE ), $this->query_string ) ), $current === 'payment_pending' ? ' class="current"' : '', __( 'Payment Pending', 'restaurant-reservations' ) . ' <span class="count">(' . $this->booking_counts['payment_pending'] . ')</span>' ), ) );
|
332 |
+
}
|
333 |
+
|
334 |
return apply_filters( 'rtb_bookings_table_views_status', $views );
|
335 |
}
|
336 |
|
@@ -27,7 +27,9 @@ if ( ! function_exists('etfrtb_customize_init_blank_state') ) {
|
|
27 |
function etfrtb_customize_init_blank_state( $components ) {
|
28 |
global $rtb_controller;
|
29 |
|
30 |
-
if ( ! $rtb_controller->permissions->check_permission( 'templates' ) ) {
|
|
|
|
|
31 |
|
32 |
// Reset the customize register actions
|
33 |
add_action( 'wp_loaded', 'etfrtb_customize_reset_register', 1 );
|
27 |
function etfrtb_customize_init_blank_state( $components ) {
|
28 |
global $rtb_controller;
|
29 |
|
30 |
+
if ( ! $rtb_controller->permissions->check_permission( 'templates' ) ) {
|
31 |
+
return $components;
|
32 |
+
}
|
33 |
|
34 |
// Reset the customize register actions
|
35 |
add_action( 'wp_loaded', 'etfrtb_customize_reset_register', 1 );
|
@@ -29,10 +29,12 @@ add_shortcode( 'booking-form', 'rtb_booking_form_shortcode' );
|
|
29 |
* @since 0.0.1
|
30 |
*/
|
31 |
if ( !function_exists( 'rtb_print_booking_form' ) ) {
|
32 |
-
function rtb_print_booking_form( $args = array() )
|
33 |
-
|
34 |
global $rtb_controller;
|
35 |
|
|
|
|
|
36 |
// Only allow the form to be displayed once on a page
|
37 |
if ( $rtb_controller->form_rendered === true ) {
|
38 |
return;
|
@@ -141,18 +143,25 @@ function rtb_print_booking_form( $args = array() ) {
|
|
141 |
<?php
|
142 |
}
|
143 |
|
144 |
-
|
145 |
-
elseif ( isset($_POST['stripeToken']) ) :
|
146 |
-
rtb_process_stripe_payment();
|
147 |
-
|
148 |
elseif ( $rtb_controller->request->request_inserted === true or isset($_GET['payment']) ) :
|
149 |
if ( isset($_GET['payment']) && 'rtb-delayed-deposit' != $_GET['payment'] ) { ?>
|
150 |
<div class="rtb-message">
|
151 |
<p><?php printf( __( 'Your reservation deposit payment has failed with the following message "%s" Please contact the site administrator for assistance.', 'restaurant-reservations' ), isset( $_GET['error_code'] ) ? esc_html( urldecode( $_GET['error_code'] ) ) : ' unknown error.' ); ?></p>
|
152 |
</div>
|
153 |
<?php }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
|
155 |
-
|
|
|
|
|
|
|
156 |
|
157 |
elseif ( isset($_GET['bookingCancelled']) and $_GET['bookingCancelled'] == 'success') : ?>
|
158 |
<div class="rtb-message">
|
@@ -216,19 +225,26 @@ function rtb_print_booking_form( $args = array() ) {
|
|
216 |
|
217 |
<?php do_action( 'rtb_booking_form_after_fields' ); ?>
|
218 |
|
219 |
-
<
|
220 |
-
|
|
|
221 |
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
|
233 |
|
234 |
</form>
|
@@ -245,327 +261,6 @@ function rtb_print_booking_form( $args = array() ) {
|
|
245 |
}
|
246 |
} // endif;
|
247 |
|
248 |
-
/**
|
249 |
-
* Print the payment form's HTML code, after a new booking has been inserted
|
250 |
-
* notices.
|
251 |
-
* @since 2.1.0
|
252 |
-
*/
|
253 |
-
if ( !function_exists( 'rtb_print_payment_form' ) ) {
|
254 |
-
function rtb_print_payment_form( $args = array() ) {
|
255 |
-
global $rtb_controller;
|
256 |
-
|
257 |
-
// Define the form's action parameter
|
258 |
-
$booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
|
259 |
-
if ( !empty( $booking_page ) ) {
|
260 |
-
$booking_page = get_permalink( $booking_page );
|
261 |
-
}
|
262 |
-
|
263 |
-
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
264 |
-
$booking = new rtbBooking();
|
265 |
-
$booking->load_post( isset( $_GET['booking_id'] ) ? intval( $_GET['booking_id'] ) : $rtb_controller->request->ID );
|
266 |
-
|
267 |
-
if ( $rtb_controller->settings->get_setting( 'rtb-payment-gateway' ) == "paypal" ) { ?>
|
268 |
-
<form action='https://www.paypal.com/cgi-bin/webscr' method='post' class='standard-form'>
|
269 |
-
<input type='hidden' name='item_name_1' value='<?php echo substr(get_bloginfo('name'), 0, 100); ?> Reservation Deposit' />
|
270 |
-
<input type='hidden' name='custom' value='booking_id=<?php echo $booking->ID; ?>' />
|
271 |
-
<input type='hidden' name='quantity_1' value='1' />
|
272 |
-
<input type='hidden' name='amount_1' value='<?php echo $booking->calculate_deposit(); ?>' />
|
273 |
-
<input type='hidden' name='cmd' value='_cart' />
|
274 |
-
<input type='hidden' name='upload' value='1' />
|
275 |
-
<input type='hidden' name='business' value='<?php echo $rtb_controller->settings->get_setting( 'rtb-paypal-email' ); ?>' />
|
276 |
-
<input type='hidden' name='currency_code' value='<?php echo $rtb_controller->settings->get_setting( 'rtb-currency' ); ?>' />
|
277 |
-
<input type='hidden' name='return' value='<?php $booking_page; ?>' />
|
278 |
-
<input type='hidden' name='notify_url' value='<?php echo get_site_url(); ?>' />
|
279 |
-
<input type='submit' class='submit-button' value='Pay via PayPal' />
|
280 |
-
</form>
|
281 |
-
<?php
|
282 |
-
}
|
283 |
-
else {
|
284 |
-
$btn_disabled = '';
|
285 |
-
if( $rtb_controller->settings->get_setting( 'rtb-stripe-sca' ) ) {
|
286 |
-
$btn_disabled = "disabled='disabled'";
|
287 |
-
wp_enqueue_script( 'rtb-stripe', 'https://js.stripe.com/v3/', array( 'jquery' ), RTB_VERSION, true );
|
288 |
-
}
|
289 |
-
else {
|
290 |
-
wp_enqueue_script( 'rtb-stripe', 'https://js.stripe.com/v2/', array( 'jquery' ), RTB_VERSION, true );
|
291 |
-
}
|
292 |
-
|
293 |
-
wp_enqueue_script( 'rtb-stripe-payment', RTB_PLUGIN_URL . '/assets/js/stripe-payment.js', array( 'jquery', 'rtb-stripe' ), RTB_VERSION, true );
|
294 |
-
|
295 |
-
wp_localize_script(
|
296 |
-
'rtb-stripe-payment',
|
297 |
-
'rtb_stripe_payment',
|
298 |
-
array(
|
299 |
-
'stripe_mode' => $rtb_controller->settings->get_setting( 'rtb-stripe-mode' ),
|
300 |
-
'stripe_sca' => $rtb_controller->settings->get_setting( 'rtb-stripe-sca' ),
|
301 |
-
'live_publishable_key' => $rtb_controller->settings->get_setting( 'rtb-stripe-live-publishable' ),
|
302 |
-
'test_publishable_key' => $rtb_controller->settings->get_setting( 'rtb-stripe-test-publishable' ),
|
303 |
-
)
|
304 |
-
);
|
305 |
-
|
306 |
-
$payment_amount = $rtb_controller->settings->get_setting( 'rtb-currency-symbol-location' ) == 'before'
|
307 |
-
? $rtb_controller->settings->get_setting( 'rtb-stripe-currency-symbol' ) . $booking->calculate_deposit()
|
308 |
-
: $booking->calculate_deposit() . $rtb_controller->settings->get_setting( 'rtb-stripe-currency-symbol' );
|
309 |
-
|
310 |
-
$cc_exp_single_field = null != $rtb_controller->settings->get_setting( 'rtb-expiration-field-single' )
|
311 |
-
? "<input type='text' data-stripe='exp_month_year' class='single-masked'>"
|
312 |
-
: "<input type='text' size='2' data-stripe='exp_month'>
|
313 |
-
<span> / </span>
|
314 |
-
<input type='text' size='4' data-stripe='exp_year'>";
|
315 |
-
?>
|
316 |
-
|
317 |
-
<h2><?php echo __('Deposit Required: ', 'restaurant-reservations' ) . $payment_amount; ?></h2>
|
318 |
-
|
319 |
-
<div class='payment-errors'></div>
|
320 |
-
|
321 |
-
<form action='#' method='POST' id='stripe-payment-form' data-booking_id='<?php echo $booking->ID ;?>'>
|
322 |
-
|
323 |
-
<?php if( $rtb_controller->settings->get_setting( 'rtb-stripe-sca' ) ) { ?>
|
324 |
-
<div class='form-row'>
|
325 |
-
<label><?php _e('Card Detail', 'restaurant-reservations'); ?></label>
|
326 |
-
<span id="cardElement"></span>
|
327 |
-
</div>
|
328 |
-
<?php } else { ?>
|
329 |
-
<div class='form-row'>
|
330 |
-
<label><?php _e('Card Number', 'restaurant-reservations'); ?></label>
|
331 |
-
<input type='text' size='20' autocomplete='off' data-stripe='card_number'/>
|
332 |
-
</div>
|
333 |
-
<div class='form-row'>
|
334 |
-
<label><?php _e('CVC', 'restaurant-reservations'); ?></label>
|
335 |
-
<input type='text' size='4' autocomplete='off' data-stripe='card_cvc'/>
|
336 |
-
</div>
|
337 |
-
<div class='form-row'>
|
338 |
-
<label><?php _e('Expiration (MM/YYYY)', 'restaurant-reservations'); ?></label>
|
339 |
-
<?php echo $cc_exp_single_field; ?>
|
340 |
-
</div>
|
341 |
-
<input type='hidden' name='action' value='rtb_stripe_booking_payment'/>
|
342 |
-
<input type='hidden' name='currency' value='<?php echo $rtb_controller->settings->get_setting( 'rtb-currency' ); ?>' data-stripe='currency' />
|
343 |
-
<input type='hidden' name='payment_amount' value='<?php echo $booking->calculate_deposit(); ?>' />
|
344 |
-
<input type='hidden' name='booking_id' value='<?php echo $booking->ID; ?>' />
|
345 |
-
<?php } ?>
|
346 |
-
<p class="stripe-payment-help-text">
|
347 |
-
<?php _e( 'Please wait. Do not refresh until the button enables or the page reloads.', 'restaurant-reservations' ); ?>
|
348 |
-
</p>
|
349 |
-
<button type='submit' id='stripe-submit' <?php echo $btn_disabled; ?>><?php _e( 'Make Deposit', 'restaurant-reservations'); ?></button>
|
350 |
-
</form>
|
351 |
-
<?php }
|
352 |
-
}
|
353 |
-
} // endif;
|
354 |
-
|
355 |
-
/**
|
356 |
-
* Process Stripe payments for reservation deposits
|
357 |
-
* @since 2.1.0
|
358 |
-
*/
|
359 |
-
if ( !function_exists( 'rtb_process_stripe_payment' ) ) {
|
360 |
-
function rtb_process_stripe_payment() {
|
361 |
-
global $rtb_controller;
|
362 |
-
|
363 |
-
$booking_id = isset($_POST['booking_id']) ? absint( $_POST['booking_id'] ) : 0;
|
364 |
-
|
365 |
-
if ( ! $booking_id ) { return; }
|
366 |
-
|
367 |
-
// Define the form's action parameter
|
368 |
-
$booking_page = $rtb_controller->settings->get_setting( 'booking-page' );
|
369 |
-
if ( ! empty( $booking_page ) ) {
|
370 |
-
$booking_page = get_permalink( $booking_page );
|
371 |
-
}
|
372 |
-
else { $booking_page = get_permalink(); }
|
373 |
-
|
374 |
-
|
375 |
-
// load the stripe libraries
|
376 |
-
require_once(RTB_PLUGIN_DIR . '/lib/stripe/init.php');
|
377 |
-
|
378 |
-
// retrieve the token generated by stripe.js
|
379 |
-
$token = $_POST['stripeToken'];
|
380 |
-
|
381 |
-
$payment_amount = ( $rtb_controller->settings->get_setting( 'rtb-currency' ) != "JPY" ? $_POST['payment_amount'] * 100 : $_POST['payment_amount'] );
|
382 |
-
|
383 |
-
$stripe_secret = $rtb_controller->settings->get_setting( 'rtb-stripe-mode' ) == 'test' ? $rtb_controller->settings->get_setting( 'rtb-stripe-test-secret' ) : $rtb_controller->settings->get_setting( 'rtb-stripe-live-secret' );
|
384 |
-
|
385 |
-
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
386 |
-
$booking = new rtbBooking();
|
387 |
-
$booking->load_post( $booking_id );
|
388 |
-
|
389 |
-
try {
|
390 |
-
\Stripe\Stripe::setApiKey( $stripe_secret );
|
391 |
-
$charge = \Stripe\Charge::create(array(
|
392 |
-
'amount' => $payment_amount,
|
393 |
-
'currency' => strtolower( $rtb_controller->settings->get_setting( 'rtb-currency' ) ),
|
394 |
-
'card' => $token
|
395 |
-
)
|
396 |
-
);
|
397 |
-
|
398 |
-
$booking->deposit = ( $rtb_controller->settings->get_setting( 'rtb-currency' ) != "JPY" ? $payment_amount / 100 : $payment_amount );
|
399 |
-
$booking->receipt_id = $charge->id;
|
400 |
-
|
401 |
-
$booking->determine_status( true );
|
402 |
-
|
403 |
-
$booking->insert_post_data();
|
404 |
-
|
405 |
-
do_action( 'rtb_booking_paid', $booking );
|
406 |
-
|
407 |
-
// redirect on successful payment
|
408 |
-
$redirect = add_query_arg(
|
409 |
-
array(
|
410 |
-
'payment' => 'paid',
|
411 |
-
'booking_id' => $booking_id
|
412 |
-
),
|
413 |
-
$booking_page
|
414 |
-
);
|
415 |
-
|
416 |
-
} catch (Exception $e) {
|
417 |
-
|
418 |
-
$booking->post_status = 'payment_failed';
|
419 |
-
$booking->payment_failure_message = $e->getDeclineCode();
|
420 |
-
|
421 |
-
$booking->insert_post_data();
|
422 |
-
|
423 |
-
// redirect on failed payment
|
424 |
-
$redirect = add_query_arg(
|
425 |
-
array(
|
426 |
-
'payment' => 'failed',
|
427 |
-
'booking_id' => $booking_id,
|
428 |
-
'error_code' => urlencode( $e->getDeclineCode() )
|
429 |
-
),
|
430 |
-
$booking_page
|
431 |
-
);
|
432 |
-
}
|
433 |
-
|
434 |
-
// redirect back to our previous page with the added query variable
|
435 |
-
wp_redirect($redirect); exit;
|
436 |
-
}
|
437 |
-
} // endif;
|
438 |
-
|
439 |
-
// add an output buffer layer for the plugin
|
440 |
-
add_action( 'init', 'rtb_add_ob_start' );
|
441 |
-
add_action( 'shutdown', 'rtb_flush_ob_end' );
|
442 |
-
|
443 |
-
// If there's an IPN request, add our setup function to potentially handle it
|
444 |
-
if ( isset($_POST['ipn_track_id']) ) { add_action( 'init', 'rtb_setup_paypal_ipn', 11 ); }
|
445 |
-
|
446 |
-
/**
|
447 |
-
* Sets up the PayPal IPN process
|
448 |
-
* @since 2.1.0
|
449 |
-
*/
|
450 |
-
if ( !function_exists( 'rtb_handle_paypal_ipn' ) ) {
|
451 |
-
function rtb_setup_paypal_ipn() {
|
452 |
-
global $rtb_controller;
|
453 |
-
|
454 |
-
if ( ! $rtb_controller->settings->get_setting( 'require-deposit' ) ) { return; }
|
455 |
-
|
456 |
-
rtb_handle_paypal_ipn();
|
457 |
-
}
|
458 |
-
} // endif;
|
459 |
-
|
460 |
-
/**
|
461 |
-
* Handle PayPal IPN requests
|
462 |
-
* @since 2.1.0
|
463 |
-
*/
|
464 |
-
if ( !function_exists( 'rtb_handle_paypal_ipn' ) ) {
|
465 |
-
function rtb_handle_paypal_ipn() {
|
466 |
-
|
467 |
-
// CONFIG: Enable debug mode. This means we'll log requests into 'ipn.log' in the same directory.
|
468 |
-
// Especially useful if you encounter network errors or other intermittent problems with IPN (validation).
|
469 |
-
// Set this to 0 once you go live or don't require logging.
|
470 |
-
$debug = get_option( 'rtb_enable_payment_debugging' );
|
471 |
-
|
472 |
-
// Set to 0 once you're ready to go live
|
473 |
-
define("RTB_USE_SANDBOX", 0);
|
474 |
-
define("RTB_LOG_FILE", "ipn.log");
|
475 |
-
// Read POST data
|
476 |
-
// reading posted data directly from $_POST causes serialization
|
477 |
-
// issues with array data in POST. Reading raw POST data from input stream instead.
|
478 |
-
$raw_post_data = file_get_contents('php://input');
|
479 |
-
$raw_post_array = explode('&', $raw_post_data);
|
480 |
-
$myPost = array();
|
481 |
-
foreach ($raw_post_array as $keyval) {
|
482 |
-
$keyval = explode ('=', $keyval);
|
483 |
-
if (count($keyval) == 2)
|
484 |
-
$myPost[$keyval[0]] = urldecode($keyval[1]);
|
485 |
-
}
|
486 |
-
// read the post from PayPal system and add 'cmd'
|
487 |
-
$req = 'cmd=_notify-validate';
|
488 |
-
if(function_exists('get_magic_quotes_gpc')) {
|
489 |
-
$get_magic_quotes_exists = true;
|
490 |
-
}
|
491 |
-
foreach ($myPost as $key => $value) {
|
492 |
-
if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
|
493 |
-
$value = urlencode(stripslashes($value));
|
494 |
-
} else {
|
495 |
-
$value = urlencode($value);
|
496 |
-
}
|
497 |
-
$req .= "&$key=$value";
|
498 |
-
}
|
499 |
-
// Post IPN data back to PayPal to validate the IPN data is genuine
|
500 |
-
// Without this step anyone can fake IPN data
|
501 |
-
if(RTB_USE_SANDBOX == true) {
|
502 |
-
$paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
|
503 |
-
} else {
|
504 |
-
$paypal_url = "https://www.paypal.com/cgi-bin/webscr";
|
505 |
-
}
|
506 |
-
|
507 |
-
$response = wp_remote_post($paypal_url, array(
|
508 |
-
'method' => 'POST',
|
509 |
-
'body' => $req,
|
510 |
-
'timeout' => 30
|
511 |
-
));
|
512 |
-
|
513 |
-
// Inspect IPN validation result and act accordingly
|
514 |
-
// Split response headers and payload, a better way for strcmp
|
515 |
-
$tokens = explode("\r\n\r\n", trim($response['body']));
|
516 |
-
$res = trim(end($tokens));
|
517 |
-
|
518 |
-
if ( $debug ) {
|
519 |
-
update_option( 'rtb_debugging', get_option( 'rtb_debugging' ) . print_r( date('[Y-m-d H:i e] '). "IPN response: $res - $req ". PHP_EOL, true ) );
|
520 |
-
}
|
521 |
-
|
522 |
-
if (strcmp ($res, "VERIFIED") == 0) {
|
523 |
-
|
524 |
-
$paypal_receipt_number = $_POST['txn_id'];
|
525 |
-
$payment_amount = $_POST['mc_gross'];
|
526 |
-
|
527 |
-
parse_str($_POST['custom'], $custom_vars);
|
528 |
-
$booking_id = intval( $custom_vars['booking_id'] );
|
529 |
-
|
530 |
-
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
531 |
-
|
532 |
-
$booking = new rtbBooking();
|
533 |
-
$booking->load_post( $booking_id );
|
534 |
-
|
535 |
-
if ( ! $booking ) { return; }
|
536 |
-
|
537 |
-
$booking->deposit = sanitize_text_field( $payment_amount );
|
538 |
-
$booking->receipt_id = sanitize_text_field( $paypal_receipt_number );
|
539 |
-
|
540 |
-
$booking->determine_status( true );
|
541 |
-
|
542 |
-
$booking->insert_post_data();
|
543 |
-
|
544 |
-
do_action( 'rtb_booking_paid', $booking );
|
545 |
-
}
|
546 |
-
}
|
547 |
-
} // endif;
|
548 |
-
|
549 |
-
/**
|
550 |
-
* Opens a buffer when handling PayPal IPN requests
|
551 |
-
* @since 2.1.0
|
552 |
-
*/
|
553 |
-
if ( !function_exists( 'rtb_add_ob_start' ) ) {
|
554 |
-
function rtb_add_ob_start() {
|
555 |
-
ob_start();
|
556 |
-
}
|
557 |
-
} // endif;
|
558 |
-
|
559 |
-
/**
|
560 |
-
* Closes a buffer when handling PayPal IPN requests
|
561 |
-
* @since 2.1.0
|
562 |
-
*/
|
563 |
-
if ( !function_exists( 'rtb_flush_ob_end' ) ) {
|
564 |
-
function rtb_flush_ob_end() {
|
565 |
-
if ( ob_get_length() ) { ob_end_clean(); }
|
566 |
-
}
|
567 |
-
} // endif;
|
568 |
-
|
569 |
/**
|
570 |
* Create a shortcode to view and (optionally) sign in bookings
|
571 |
* @since 2.0.0
|
@@ -936,7 +631,7 @@ if ( !function_exists( 'rtb_print_form_select_field' ) ) {
|
|
936 |
function rtb_print_form_select_field( $slug, $title, $value, $args ) {
|
937 |
|
938 |
$slug = esc_attr( $slug );
|
939 |
-
$value = esc_attr( $value );
|
940 |
$options = is_array( $args['options'] ) ? $args['options'] : array();
|
941 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
942 |
$classes[] = 'rtb-select';
|
29 |
* @since 0.0.1
|
30 |
*/
|
31 |
if ( !function_exists( 'rtb_print_booking_form' ) ) {
|
32 |
+
function rtb_print_booking_form( $args = array() )
|
33 |
+
{
|
34 |
global $rtb_controller;
|
35 |
|
36 |
+
do_action( 'rtb_booking_form_init' );
|
37 |
+
|
38 |
// Only allow the form to be displayed once on a page
|
39 |
if ( $rtb_controller->form_rendered === true ) {
|
40 |
return;
|
143 |
<?php
|
144 |
}
|
145 |
|
|
|
|
|
|
|
|
|
146 |
elseif ( $rtb_controller->request->request_inserted === true or isset($_GET['payment']) ) :
|
147 |
if ( isset($_GET['payment']) && 'rtb-delayed-deposit' != $_GET['payment'] ) { ?>
|
148 |
<div class="rtb-message">
|
149 |
<p><?php printf( __( 'Your reservation deposit payment has failed with the following message "%s" Please contact the site administrator for assistance.', 'restaurant-reservations' ), isset( $_GET['error_code'] ) ? esc_html( urldecode( $_GET['error_code'] ) ) : ' unknown error.' ); ?></p>
|
150 |
</div>
|
151 |
<?php }
|
152 |
+
|
153 |
+
$booking_id = isset( $_GET['booking_id'] )
|
154 |
+
? intval( $_GET['booking_id'] )
|
155 |
+
: $rtb_controller->request->ID;
|
156 |
+
|
157 |
+
require_once( RTB_PLUGIN_DIR . '/includes/Booking.class.php' );
|
158 |
+
$booking = new rtbBooking();
|
159 |
+
$booking->load_post( $booking_id );
|
160 |
|
161 |
+
$rtb_controller
|
162 |
+
->payment_manager
|
163 |
+
->set_booking( $booking )
|
164 |
+
->print_payment_form();
|
165 |
|
166 |
elseif ( isset($_GET['bookingCancelled']) and $_GET['bookingCancelled'] == 'success') : ?>
|
167 |
<div class="rtb-message">
|
225 |
|
226 |
<?php do_action( 'rtb_booking_form_after_fields' ); ?>
|
227 |
|
228 |
+
<fieldset class="rtb-form-footer">
|
229 |
+
<div id='rtb_recaptcha'></div>
|
230 |
+
<?php echo rtb_print_form_error( 'recaptcha' ); ?>
|
231 |
|
232 |
+
<?php
|
233 |
+
$button_text = $rtb_controller->settings->get_setting( 'require-deposit' )
|
234 |
+
? __( 'Proceed to Deposit', 'restaurant-reservations' )
|
235 |
+
: __( 'Request Booking', 'restaurant-reservations' );
|
236 |
+
|
237 |
+
$button = sprintf(
|
238 |
+
'<button type="submit">%s</button>',
|
239 |
+
apply_filters( 'rtb_booking_form_submit_label', $button_text )
|
240 |
+
);
|
241 |
+
|
242 |
+
echo sprintf(
|
243 |
+
'<div class="rtb-form-submit">%s</div>',
|
244 |
+
apply_filters( 'rtb_booking_form_submit_button', $button )
|
245 |
+
);
|
246 |
+
?>
|
247 |
+
</fieldset>
|
248 |
|
249 |
|
250 |
</form>
|
261 |
}
|
262 |
} // endif;
|
263 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
/**
|
265 |
* Create a shortcode to view and (optionally) sign in bookings
|
266 |
* @since 2.0.0
|
631 |
function rtb_print_form_select_field( $slug, $title, $value, $args ) {
|
632 |
|
633 |
$slug = esc_attr( $slug );
|
634 |
+
$value = is_array( $value ) ? array_map( 'esc_attr', $value ) : esc_attr( $value );
|
635 |
$options = is_array( $args['options'] ) ? $args['options'] : array();
|
636 |
$classes = isset( $args['classes'] ) ? $args['classes'] : array();
|
637 |
$classes[] = 'rtb-select';
|
@@ -175,6 +175,21 @@ class sapAdminPage_2_2_0 {
|
|
175 |
|
176 |
$current_page = $this->get_current_page( $_GET );
|
177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
?>
|
179 |
|
180 |
<div class="wrap">
|
@@ -184,22 +199,18 @@ class sapAdminPage_2_2_0 {
|
|
184 |
<?php if ( isset( $this->default_tab ) ) : ?>
|
185 |
<h2 class="nav-tab-wrapper">
|
186 |
<?php
|
187 |
-
foreach( $
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
echo '<a href="' . esc_url( $tab_url ) . '" title="' . esc_attr( $section->title ) . '" class="nav-tab' . $active . '">';
|
200 |
-
echo esc_html( $section->title );
|
201 |
-
echo '</a>';
|
202 |
-
}
|
203 |
}
|
204 |
?>
|
205 |
</h2>
|
175 |
|
176 |
$current_page = $this->get_current_page( $_GET );
|
177 |
|
178 |
+
// Fetch and Order sections/tabs
|
179 |
+
$tab_list = [];
|
180 |
+
foreach( $this->sections as $section ) {
|
181 |
+
if ( isset( $section->is_tab ) && $section->is_tab === true ) {
|
182 |
+
if( property_exists( $section, 'rank' ) ) {
|
183 |
+
// array start from 0, rank start from 1
|
184 |
+
array_splice($tab_list, ($section->rank - 1), 0, [$section]);
|
185 |
+
}
|
186 |
+
else {
|
187 |
+
$tab_list[] = $section;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
|
193 |
?>
|
194 |
|
195 |
<div class="wrap">
|
199 |
<?php if ( isset( $this->default_tab ) ) : ?>
|
200 |
<h2 class="nav-tab-wrapper">
|
201 |
<?php
|
202 |
+
foreach( $tab_list as $section ) {
|
203 |
+
$tab_url = add_query_arg(
|
204 |
+
array(
|
205 |
+
'settings-updated' => false,
|
206 |
+
'tab' => $section->id
|
207 |
+
)
|
208 |
+
);
|
209 |
+
|
210 |
+
$active = $current_page == $section->id ? ' nav-tab-active' : '';
|
211 |
+
echo '<a href="' . esc_url( $tab_url ) . '" title="' . esc_attr( $section->title ) . '" class="nav-tab' . $active . '">';
|
212 |
+
echo esc_html( $section->title );
|
213 |
+
echo '</a>';
|
|
|
|
|
|
|
|
|
214 |
}
|
215 |
?>
|
216 |
</h2>
|
@@ -21,8 +21,6 @@
|
|
21 |
|
22 |
class sapAdminPageSettingCheckbox_2_2_0 extends sapAdminPageSetting_2_2_0 {
|
23 |
|
24 |
-
//public $sanitize_callback = 'sanitize_text_field';
|
25 |
-
|
26 |
/**
|
27 |
* Display this setting
|
28 |
* @since 2.0
|
@@ -49,4 +47,21 @@ class sapAdminPageSettingCheckbox_2_2_0 extends sapAdminPageSetting_2_2_0 {
|
|
49 |
|
50 |
}
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
}
|
21 |
|
22 |
class sapAdminPageSettingCheckbox_2_2_0 extends sapAdminPageSetting_2_2_0 {
|
23 |
|
|
|
|
|
24 |
/**
|
25 |
* Display this setting
|
26 |
* @since 2.0
|
47 |
|
48 |
}
|
49 |
|
50 |
+
public function sanitize_callback_wrapper( $values ) {
|
51 |
+
return is_array( $values ) ? array_map( $this->sanitize_callback, $values ) : array();
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Escape the value to display it safely HTML textarea fields
|
56 |
+
* @since 2.0.a.5
|
57 |
+
*/
|
58 |
+
public function esc_value( $val ) {
|
59 |
+
|
60 |
+
foreach ($val as $value) {
|
61 |
+
$escaped[] = esc_attr($value);
|
62 |
+
}
|
63 |
+
|
64 |
+
return $escaped;
|
65 |
+
}
|
66 |
+
|
67 |
}
|
@@ -301,6 +301,7 @@ class sapLibrary_2_2_0 {
|
|
301 |
$this->pages[ $page ]->sections[ $section ]->add_setting( new $class( $args ) );
|
302 |
}
|
303 |
|
|
|
304 |
}
|
305 |
|
306 |
/**
|
301 |
$this->pages[ $page ]->sections[ $section ]->add_setting( new $class( $args ) );
|
302 |
}
|
303 |
|
304 |
+
return $this;
|
305 |
}
|
306 |
|
307 |
/**
|
@@ -4,7 +4,12 @@ jQuery(document).ready(function() {
|
|
4 |
|
5 |
var count = jQuery('#' + id + '_count').val();
|
6 |
var unit = jQuery('#' + id + '_unit').val();
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
}
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
var count = jQuery('#' + id + '_count').val();
|
6 |
var unit = jQuery('#' + id + '_unit').val();
|
7 |
+
|
8 |
+
if( count && unit ) {
|
9 |
+
jQuery('#' + id).val(count + '_' + unit);
|
10 |
+
}
|
11 |
+
else {
|
12 |
+
jQuery('#' + id).val('');
|
13 |
+
}
|
14 |
+
});
|
15 |
+
});
|
@@ -3,7 +3,7 @@ Contributors: FiveStarPlugins
|
|
3 |
Requires at Least: 4.4
|
4 |
Tested Up To: 5.8
|
5 |
Tags: reservation, reservations, restaurant reservations, reservation form, restaurant booking, restaurant reservation form, restaurant booking form, restaurant booking system, reservation system, online reservations, online restaurant booking, dinner reservations, restaurant form, gutenberg reservations, gutenberg restaurant reservations, gutenberg restaurant booking, mobile reservations, responsive reservations, table reservations, open table, book table, reserve table, easy reservations, simple reservations, quick restaurant reservations, custom reservation form, custom restaurant reservations
|
6 |
-
Stable tag: 2.
|
7 |
License: GPLv3
|
8 |
License URI:http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
Donate Link: https://www.etoilewebdesign.com/plugin-donations/
|
@@ -197,6 +197,15 @@ Find answers to even more questions in the [FAQ](http://doc.fivestarplugins.com/
|
|
197 |
|
198 |
== Changelog ==
|
199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
= 2.2.12 (2021-07-21) =
|
201 |
- The plugin has been tested up to WordPress version 5.8.
|
202 |
|
3 |
Requires at Least: 4.4
|
4 |
Tested Up To: 5.8
|
5 |
Tags: reservation, reservations, restaurant reservations, reservation form, restaurant booking, restaurant reservation form, restaurant booking form, restaurant booking system, reservation system, online reservations, online restaurant booking, dinner reservations, restaurant form, gutenberg reservations, gutenberg restaurant reservations, gutenberg restaurant booking, mobile reservations, responsive reservations, table reservations, open table, book table, reserve table, easy reservations, simple reservations, quick restaurant reservations, custom reservation form, custom restaurant reservations
|
6 |
+
Stable tag: 2.3.0
|
7 |
License: GPLv3
|
8 |
License URI:http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
Donate Link: https://www.etoilewebdesign.com/plugin-donations/
|
197 |
|
198 |
== Changelog ==
|
199 |
|
200 |
+
= 2.3.0 (2021-08-23) =
|
201 |
+
- Updated the payment gateway option, so you can now offer PayPal and Stripe at the same time (your customers can choose which to use).
|
202 |
+
- Fixed issue with Early Bookings feature were the X day option was calculating using hours instead of days.
|
203 |
+
- Fixed an issue in which, if there was only one valid time slot left, it would sometimes not display as available.
|
204 |
+
- Fixed an issue in which, if your set timezone was on a different day than UTC (e.g. near midnight), it would sometimes show the incorrect hours as available.
|
205 |
+
- Fixed an issue loading the customizer for the email templates.
|
206 |
+
- Fixed an issue causing the reservation reminder and late arrival notifications to still send if no time interval was specified.
|
207 |
+
- Fixed an issue in which the red badge would still show beside the Bookings WP admin menu item even if there were no pending bookings.
|
208 |
+
|
209 |
= 2.2.12 (2021-07-21) =
|
210 |
- The plugin has been tested up to WordPress version 5.8.
|
211 |
|
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Five Star Restaurant Reservations - WordPress Booking Plugin
|
4 |
* Plugin URI: http://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/
|
5 |
* Description: Restaurant reservations made easy. Accept bookings online. Quickly confirm or reject reservations, send email notifications, set booking times and more.
|
6 |
-
* Version: 2.
|
7 |
* Author: FiveStarPlugins
|
8 |
* Author URI: https://profiles.wordpress.org/fivestarplugins/
|
9 |
* Text Domain: restaurant-reservations
|
@@ -39,7 +39,7 @@ class rtbInit {
|
|
39 |
public function __construct() {
|
40 |
|
41 |
// Common strings
|
42 |
-
define( 'RTB_VERSION', '2.
|
43 |
define( 'RTB_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
|
44 |
define( 'RTB_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
|
45 |
define( 'RTB_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
|
@@ -51,8 +51,12 @@ class rtbInit {
|
|
51 |
|
52 |
// Set up empty request object
|
53 |
$this->request = new stdClass();
|
|
|
54 |
$this->request->request_processed = false;
|
55 |
$this->request->request_inserted = false;
|
|
|
|
|
|
|
56 |
|
57 |
// Load query class
|
58 |
require_once( RTB_PLUGIN_DIR . '/includes/Query.class.php' );
|
@@ -107,6 +111,10 @@ class rtbInit {
|
|
107 |
require_once( RTB_PLUGIN_DIR . '/includes/Settings.class.php' );
|
108 |
$this->settings = new rtbSettings();
|
109 |
|
|
|
|
|
|
|
|
|
110 |
// Load plugin dashboard
|
111 |
require_once( RTB_PLUGIN_DIR . '/includes/Dashboard.class.php' );
|
112 |
new rtbDashboard();
|
@@ -490,3 +498,15 @@ class rtbInit {
|
|
490 |
global $rtb_controller;
|
491 |
$rtb_controller = new rtbInit();
|
492 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
* Plugin Name: Five Star Restaurant Reservations - WordPress Booking Plugin
|
4 |
* Plugin URI: http://www.fivestarplugins.com/plugins/five-star-restaurant-reservations/
|
5 |
* Description: Restaurant reservations made easy. Accept bookings online. Quickly confirm or reject reservations, send email notifications, set booking times and more.
|
6 |
+
* Version: 2.3.0
|
7 |
* Author: FiveStarPlugins
|
8 |
* Author URI: https://profiles.wordpress.org/fivestarplugins/
|
9 |
* Text Domain: restaurant-reservations
|
39 |
public function __construct() {
|
40 |
|
41 |
// Common strings
|
42 |
+
define( 'RTB_VERSION', '2.3.0' );
|
43 |
define( 'RTB_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
|
44 |
define( 'RTB_PLUGIN_URL', untrailingslashit( plugins_url( basename( plugin_dir_path( __FILE__ ) ), basename( __FILE__ ) ) ) );
|
45 |
define( 'RTB_PLUGIN_FNAME', plugin_basename( __FILE__ ) );
|
51 |
|
52 |
// Set up empty request object
|
53 |
$this->request = new stdClass();
|
54 |
+
$this->request->raw_input = array();
|
55 |
$this->request->request_processed = false;
|
56 |
$this->request->request_inserted = false;
|
57 |
+
}
|
58 |
+
|
59 |
+
public function boot() {
|
60 |
|
61 |
// Load query class
|
62 |
require_once( RTB_PLUGIN_DIR . '/includes/Query.class.php' );
|
111 |
require_once( RTB_PLUGIN_DIR . '/includes/Settings.class.php' );
|
112 |
$this->settings = new rtbSettings();
|
113 |
|
114 |
+
// Load Payment Manager
|
115 |
+
require_once( RTB_PLUGIN_DIR . '/includes/PaymentManager.class.php' );
|
116 |
+
$this->payment_manager = new rtbPaymentManager();
|
117 |
+
|
118 |
// Load plugin dashboard
|
119 |
require_once( RTB_PLUGIN_DIR . '/includes/Dashboard.class.php' );
|
120 |
new rtbDashboard();
|
498 |
global $rtb_controller;
|
499 |
$rtb_controller = new rtbInit();
|
500 |
|
501 |
+
/**
|
502 |
+
* Because we refer $rtb_controller in many other modules during their object
|
503 |
+
* construction, separating the object construction from its uses. Please refer
|
504 |
+
* to the link after the constructor's official PHP definition.
|
505 |
+
*
|
506 |
+
* "Classes which have a constructor method call this method on each newly-
|
507 |
+
* created object, so it is suitable for any initialization that the object
|
508 |
+
* may need before it is used."
|
509 |
+
*
|
510 |
+
* https://www.php.net/manual/en/language.oop5.decon.php
|
511 |
+
*/
|
512 |
+
$rtb_controller->boot();
|