PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.38
Timetics – Appointment Booking Calendar & Scheduling v1.0.38
1.0.61 1.0.60 1.0.59 1.0.58 1.0.57 1.0.56 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 All 62 releases
timetics / core / bookings / hooks.php

hooks.php in Timetics – Appointment Booking Calendar & Scheduling 1.0.38, at core/bookings/hooks.php

396 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Booking related hooks
4 *
5 * @package Timetics
6 */
7
8 namespace Timetics\Core\Bookings;
9
10 use Timetics\Core\Appointments\Appointment;
11 use Timetics\Core\Emails\Customer_Booking_Reminder_Email;
12 use Timetics\Core\Emails\Staff_Booking_Reminder_Email;
13 use Timetics\Utils\Singleton;
14
15 /**
16 * Class Hooks
17 */
18 class Hooks {
19 use Singleton;
20
21 /**
22 * Initialization
23 *
24 * @return void
25 */
26 public function init() {
27 add_action( 'timetics_after_booking_create', [$this, 'register_schedule'] );
28 add_action( 'init', [$this, 'run_booking_schedule'] );
29 add_action( 'timetics_booking_clear_schedule', [$this, 'clear_booking_schedule'] );
30
31 add_action( 'timetics_after_booking_create', [$this, 'reschedule_booking'], 10, 4 );
32
33 add_action( 'init', [$this, 'register_booking_status'] );
34
35 add_action('woocommerce_before_calculate_totals', [ $this, 'timetics_variation_ticket_total_price' ] );
36
37 add_filter( 'woocommerce_add_cart_item_data', [ $this, 'timetics_add_cart_item_data' ], 10, 2 );
38
39 add_action( 'admin_init', [$this, 'delete_booking_before_paid'] );
40 }
41
42 /**
43 * Register cron job for schedule a reminder email
44 *
45 * @param integer $booking_id
46 *
47 * @return void
48 */
49 public function register_schedule( $booking_id ) {
50 $booking = new Booking( $booking_id );
51
52 $date = $booking->get_start_date();
53 $time = $booking->get_start_time();
54
55 $booking_timestamp = strtotime( $date . ' ' . $time );
56
57 $reminder_time = timetics_get_option( 'remainder_time' );
58
59 if ( ! $reminder_time ) {
60 return;
61 }
62
63 foreach ( $reminder_time as $time ) {
64 $timestamp = null;
65 $duration = $time['duration-time'];
66
67 switch ( $time['custom_duration_type'] ) {
68 case 'min':
69 $timestamp = $duration * 60;
70 break;
71 case 'hour':
72 $timestamp = $duration * 60 * 60;
73 break;
74 case 'day':
75 $timestamp = ( $duration * 24 ) * 60 * 60;
76 break;
77 }
78
79 $timestamp = intval($booking_timestamp)- intval($timestamp);
80
81 if ( ! wp_next_scheduled( 'timetics_booking_remainder_' . $booking_id ) ) {
82 wp_schedule_single_event( $timestamp, 'timetics_booking_remainder_' . $booking_id, [$booking_id] );
83 }
84 }
85 }
86
87 /**
88 * Booking schedule
89 *
90 * @return void
91 */
92 public function run_booking_schedule() {
93 $bookins = Booking::all();
94
95 if ( ! $bookins ) {
96 return;
97 }
98
99 // Run cron action.
100 foreach ( $bookins['items'] as $booking ) {
101 add_action( 'timetics_booking_remainder_' . $booking->ID, [$this, 'send_reminder_email'] );
102 }
103 }
104
105 /**
106 * Send booking reminder email
107 *
108 * @param integer $booking_id
109 *
110 * @return void
111 */
112 public function send_reminder_email( $booking_id ) {
113 $booking_reminder_customer = timetics_get_option( 'booking_reminder_customer' );
114 $booking_reminder_host = timetics_get_option( 'booking_reminder_host' );
115
116 $booking = new Booking( $booking_id );
117
118 if ( $booking_reminder_customer ) {
119 $customer_reminder = new Customer_Booking_Reminder_Email( $booking );
120 $customer_reminder->send();
121 }
122
123 if ( $booking_reminder_host ) {
124 $staff_reminder = new Staff_Booking_Reminder_Email( $booking );
125 $staff_reminder->send();
126 }
127
128 }
129
130 /**
131 * Clear cron job schedule
132 *
133 * @return
134 */
135 public function clear_booking_schedule() {
136 $bookins = Booking::all();
137
138 if ( ! $bookins ) {
139 return;
140 }
141
142 // Run cron action.
143 foreach ( $bookins['items'] as $booking ) {
144 $timestamp = wp_next_scheduled( 'timetics_booking_remainder_' . $booking->ID );
145
146 if ( $timestamp && $timestamp < time() ) {
147 wp_unschedule_event( $timestamp, 'timetics_booking_remainder_' . $booking->ID );
148 }
149 }
150 }
151
152 /**
153 * Update bookked entry if reschedule
154 *
155 * @param integer $booking_id
156 * @param integer $customer_id
157 * @param integer $meeting_id
158 * @param array $data
159 * @param integer $booking_entry
160 *
161 * @return void
162 */
163 public function reschedule_booking( $booking_id, $customer_id, $meeting_id, $data ) {
164 $reschedule = ! empty( $data['reschedule'] ) ? $data['reschedule'] : false;
165 $booking = new Booking( $booking_id );
166 $meeting = new Appointment( $meeting_id );
167 $booking_entry = new Booking_Entry();
168
169 if ( ! $reschedule ) {
170 return;
171 }
172
173 $entries = $booking_entry->find(
174 [
175 'staff_id' => $booking->get_staff_id(),
176 'meeting_id' => $meeting->get_id(),
177 'date' => $booking->get_start_date(),
178 'start' => $booking->get_start_time(),
179 ]
180 );
181
182 if ( ! $entries ) {
183 return;
184 }
185
186 $entry = $booking_entry->first();
187 $booked_seat = ! empty( $booking->get_seat() ) ? $booking->get_seat() : [];
188 $existing_seat = ! empty( $entry->get_seats() ) ? $entry->get_seats() : [];
189
190 if ( 'one-to-one' === strtolower( $meeting->get_type() ) ) {
191 $entry->delete();
192 } else {
193 $booked = intval( $entry->get_booked() ) - 1;
194
195 $entry->update( [
196 'booked' => $booked,
197 'seats' => array_values( array_diff( $existing_seat, $booked_seat ) ),
198 ] );
199 }
200 }
201
202 /**
203 * Register booking statuses
204 *
205 * @return void
206 */
207 public function register_booking_status() {
208 $statuses = timetics_get_post_status();
209
210 foreach ( $statuses as $status ) {
211
212 register_post_status( $status, array(
213 'public' => true,
214 'exclude_from_search' => false,
215 'show_in_admin_all_list' => false,
216 'show_in_admin_status_list' => false,
217 'label_count' => _n_noop( "$status (%s)", "$status (%s)", 'timetics' ),
218 ) );
219 }
220 }
221
222 /**
223 * Delete bookings if unpaid before 30 mins
224 *
225 * @return void
226 */
227 public function delete_booking_before_paid() {
228 $args = [
229 'post_type' => 'timetics-booking',
230 'numberposts' => -1,
231 'meta_query' => array(
232 'relation' => 'OR',
233 array(
234 'key' => '_tt_booking_payment_method',
235 'value' => 'stripe',
236 'compare' => '=',
237 ),
238 array(
239 'key' => '_tt_booking_payment_method',
240 'value' => 'paypal',
241 'compare' => '=',
242 ),
243 ),
244 ];
245
246 $bookings = get_posts( $args );
247
248 foreach ( $bookings as $booking ) {
249 $booking = new Booking( $booking->ID );
250
251 if ( 'completed' != $booking->get_status() && $this->is_booking_payment_expire( $booking ) ) {
252 $this->update_booking_entry( $booking->get_id() );
253 }
254 }
255 }
256
257 /**
258 * Check booking payment time expaire or not
259 *
260 * @param Object $booking
261 *
262 * @return bool
263 */
264 public function is_booking_payment_expire( $booking ) {
265 // Booking date and time
266 $post = get_post( $booking->get_id() );
267 $booking_datetime = $post->post_date;
268
269 // Convert the booking date and time to a DateTime object
270 $booking_datetime_object = new \DateTime( $booking_datetime );
271
272 // Calculate 30 minutes from the booking date and time
273 $target_datetime = clone $booking_datetime_object;
274 $target_datetime->modify( '+30 minutes' );
275
276 // Get the current date and time
277 $current_datetime = new \DateTime();
278
279 // Check if 30 minutes have passed
280 if ( $current_datetime > $target_datetime ) {
281 return true;
282 }
283
284 return false;
285 }
286
287 /**
288 * Update booking entry if payment time expire
289 *
290 * @param integer $booking_id
291 *
292 * @return void
293 */
294 public function update_booking_entry( $booking_id ) {
295 $booking = new Booking( $booking_id );
296 $meeting = new Appointment( $booking->get_appointment() );
297
298 if ( ! $booking->is_booking() ) {
299 return false;
300 }
301
302 $current_user_id = get_current_user_id();
303
304 if (
305 $meeting->is_appointment()
306 && ! user_can( $current_user_id, 'manage_options' )
307 && $meeting->get_author() != $current_user_id
308 ) {
309 $data = [
310 'success' => 0,
311 'message' => __( 'You are not allowed to delete this booking.', 'timetics' ),
312 ];
313
314 return new \WP_HTTP_Response( $data, 403 );
315 }
316
317 $booking_entry = new Booking_Entry();
318
319 $date_time = timetics_convert_timezone( $booking->get_start_date() . ' ' . $booking->get_start_time(), $booking->get_timezone(), $meeting->get_timezone() );
320
321 $entries = $booking_entry->find(
322 [
323 'staff_id' => $booking->get_staff_id(),
324 'meeting_id' => $booking->get_appointment(),
325 'date' => $date_time->format( 'Y-m-d' ),
326 'start' => $date_time->format( 'h:i a' ),
327 ]
328 );
329
330 if ( $entries ) {
331 $entry = $booking_entry->first();
332
333 if ( 'one-to-one' == strtolower( $meeting->get_type() ) ) {
334 $entry->delete();
335 } else {
336 $booked = intval( $entry->get_booked() ) - 1;
337 $booked_seat = ! empty( $booking->get_seat() ) ? $booking->get_seat() : [];
338 $existing_seat = ! empty( $entry->get_seats() ) ? $entry->get_seats() : [];
339
340 $entry->update( [
341 'booked' => $booked,
342 'seats' => array_values( array_diff( $existing_seat, $booked_seat ) ),
343 ] );
344 }
345 }
346 }
347
348 /**
349 * Change price for cart item
350 */
351 public function timetics_variation_ticket_total_price( $cart_object ) {
352 foreach ( $cart_object->cart_contents as $key => $value ) {
353 if ( ! empty( $value['booking_id'] ) && $value['booking_id'] !== 0 ) {
354 $order_total = !empty( $value['_timetics_variation_total_price'] ) ? $value['_timetics_variation_total_price'] : 0;
355
356 $value['data']->get_price();
357 $value['data']->set_price($order_total);
358 $value['data']->set_regular_price($order_total);
359 $value['data']->set_sale_price($order_total);
360
361 }
362 }
363
364 }
365
366 /**
367 * add booking_id as cart item data
368 *
369 * @param integer $booking_id
370 *
371 * @return void
372 */
373 public function timetics_add_cart_item_data( $cart_item_data ) {
374 $session_data = WC()->session->get( 'timetics_data' );
375 $booking_id = $session_data['booking_id'];
376 $booking = new Booking( $booking_id );
377 $total_price = floatval($booking->get_total()); // Ensure $total_price is a float
378
379 if ( is_array( $booking->get_seat() ) ) {
380 $total_quantity = count( $booking->get_seat() );
381 } else {
382 $total_quantity = 1;
383 }
384
385 if( ! empty( $booking_id ) && $total_price !== 0 ) {
386 $cart_item_data['_timetics_variation_total_quantity'] = $total_quantity;
387 $cart_item_data['booking_id'] = $booking_id;
388
389 // For balancing the cart item price
390 $cart_item_data['_timetics_variation_total_price'] = $total_price / $total_quantity;
391 }
392
393 return $cart_item_data;
394 }
395 }
396