PluginProbe
Bookit — Booking & Appointment Calendar / 2.6.0.5
Bookit — Booking & Appointment Calendar v2.6.0.5
2.6.0.5 2.6.0.4 2.6.0.3 2.6.0.2 2.6.0.1 2.6.0 trunk 1.2 1.2.2 1.2.3 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 All 62 releases
bookit / includes / classes / admin / AppointmentsController.php

AppointmentsController.php in Bookit — Booking & Appointment Calendar 2.6.0.5, at includes/classes/admin/AppointmentsController.php

703 lines 23.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Bookit\Classes\Admin;
4
5 use Bookit\Classes\Base\Plugin;
6 use Bookit\Classes\Database\Appointments;
7 use Bookit\Classes\Database\Customers;
8 use Bookit\Classes\Database\Payments;
9 use Bookit\Classes\Database\Services;
10 use Bookit\Classes\Database\Staff;
11 use Bookit\Classes\Payments\PayPal;
12 use Bookit\Gateways\StripeConnect\Merchant;
13 use Bookit\Classes\Template;
14 use Bookit\Helpers\CleanHelper;
15 use Bookit\Helpers\TimeSlotHelper;
16
17 class AppointmentsController extends DashboardController {
18
19 private static function getCleanRules() {
20 return array(
21 'id' => array( 'type' => 'intval' ),
22 'limit' => array( 'type' => 'intval' ),
23 'offset' => array( 'type' => 'intval' ),
24 'sort' => array( 'type' => 'strval' ),
25 'order' => array( 'type' => 'strval' ),
26 'status' => array( 'type' => 'strval' ),
27 'staff_id' => array( 'type' => 'intval' ),
28 'service_id' => array( 'type' => 'intval' ),
29 'service_ids' => array(
30 'function' => array(
31 'custom' => true,
32 'name' => 'custom_comma_separated_ids',
33 ),
34 ),
35 'start_timestamp',
36 'end_timestamp',
37 'start_time' => array( 'type' => 'intval' ),
38 'end_time' => array( 'type' => 'intval' ),
39 'date_timestamp' => array( 'type' => 'intval' ),
40 'price' => array( 'type' => 'floatval' ),
41 'customer_phone' => array(
42 'function' => array(
43 'custom' => true,
44 'name' => 'custom_sanitize_phone',
45 ),
46 ),
47 );
48 }
49
50 /**
51 * Display Rendered Template
52 * @return bool|string
53 */
54 public static function render() {
55 self::enqueue_styles_scripts();
56 return Template::load_template( 'dashboard/bookit-appointments', self::get_form_data(), true );
57 }
58
59 /**
60 * Get Appointment form data
61 */
62 public static function get_form_data() {
63 $payments = get_option_by_path( 'bookit_settings.payments' );
64 $payments = array_filter(
65 $payments,
66 function ( $payment ) {
67 return $payment['enabled'];
68 }
69 );
70 $payment_methods = array_keys( $payments );
71
72 array_push( $payment_methods, Payments::$freeType );
73
74 $payment_method_labels = array(
75 'locally' => esc_html__( 'locally', 'bookit' ),
76 'stripeConnect' => esc_html__( 'stripeConnect', 'bookit' ),
77 'paypal' => esc_html__( 'paypal', 'bookit' ),
78 'stripe' => esc_html__( 'stripe', 'bookit' ),
79 'woocommerce' => esc_html__( 'woocommerce', 'bookit' ),
80 'free' => esc_html__( 'free', 'bookit' ),
81 );
82 $payment_methods = array_combine( $payment_methods, $payment_methods );
83 array_walk(
84 $payment_methods,
85 function ( &$value ) use ( $payment_method_labels ) {
86 $value = $payment_method_labels[ $value ] ?? esc_html( $value );
87 }
88 );
89
90 $payment_status_labels = array(
91 'pending' => esc_html__( 'pending', 'bookit' ),
92 'cancelled' => esc_html__( 'cancelled', 'bookit' ),
93 'rejected' => esc_html__( 'rejected', 'bookit' ),
94 'complete' => esc_html__( 'complete', 'bookit' ),
95 );
96 $payment_statuses = array_combine( Payments::$statusList, Payments::$statusList );
97 array_walk(
98 $payment_statuses,
99 function ( &$value ) use ( $payment_status_labels ) {
100 $value = $payment_status_labels[ $value ] ?? esc_html( $value );
101 }
102 );
103
104 $appointment_status_labels = array(
105 'pending' => esc_html__( 'Pending', 'bookit' ),
106 'approved' => esc_html__( 'Approved', 'bookit' ),
107 'cancelled' => esc_html__( 'Cancelled', 'bookit' ),
108 'delete' => esc_html__( 'Delete', 'bookit' ),
109 );
110 $statuses = array_combine( Appointments::$statusList, Appointments::$statusList );
111 array_walk(
112 $statuses,
113 function ( &$value ) use ( $appointment_status_labels ) {
114 $value = $appointment_status_labels[ $value ] ?? esc_html( ucwords( $value ) );
115 }
116 );
117 unset( $statuses[ Appointments::$delete ] );
118
119 $appointment_statuses = array(
120 'payment' => $payment_statuses,
121 'appointment' => $statuses,
122 );
123
124 $services = Services::get_all_with_category();
125 $filterServices = self::parseServices( $services );
126 $staff = StaffController::parseStaff( Staff::get_all() );
127 $customers = Customers::get_all();
128 // Remove extra backslashes from the full_name field
129 array_walk( $customers, function ( &$row ) {
130 $row['full_name'] = stripslashes( $row['full_name'] );
131 } );
132
133 $service_start = 0;
134 $service_end = TimeSlotHelper::DAY_IN_SECONDS;
135 $time_format = get_option( 'time_format' );
136 $time_slot_list = TimeSlotHelper::getTimeList( $service_start, $service_end );
137 $settings = SettingsController::get_settings();
138
139 $autorefresh_list = array(
140 60 => __( '1m', 'bookit' ),
141 180 => __( '3m', 'bookit' ),
142 300 => __( '5m', 'bookit' ),
143 600 => __( '10m', 'bookit' ),
144 );
145
146 return array(
147 'page' => __( 'Appointments', 'bookit' ),
148 'settings' => $settings,
149 'filter_services' => $filterServices,
150 'services' => $services,
151 'staff' => $staff,
152 'customers' => $customers,
153 'payment_methods' => $payment_methods,
154 'appointment_statuses' => $appointment_statuses,
155 'time_format' => $time_format,
156 'time_slot_list' => $time_slot_list,
157 'autorefresh_list' => $autorefresh_list,
158 );
159 }
160
161 /**
162 * @param Services $services
163 * @return array as tree category with child services
164 */
165 public static function parseServices( $services ) {
166 $result = array();
167 $category = array();
168
169 foreach ( $services as $key => $service ) {
170 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
171 $existIndex = array_search( '0_' . $service->category_id, array_column( $result, 'id' ) );
172 if ( false === $existIndex ) {
173 $category['id'] = '0_' . $service->category_id;
174 $category['label'] = $service->category;
175 $category['children'] = array();
176
177 array_push(
178 $category['children'],
179 array(
180 'id' => $service->id,
181 'label' => $service->title,
182 )
183 );
184 array_push( $result, $category );
185 } else {
186 $child = array(
187 'id' => $service->id,
188 'label' => $service->title,
189 );
190 array_push( $result[ $existIndex ]['children'], $child );
191 }
192 }
193 unset( $services );
194 return $result;
195 }
196
197 /**
198 * Get Appointments with Pagination
199 */
200 public static function get_appointments() {
201 check_ajax_referer( 'bookit_get_appointments', 'nonce' );
202
203 if ( ! current_user_can( 'manage_options' ) ) {
204 return false;
205 }
206
207 $data = CleanHelper::cleanData( $_GET, self::getCleanRules() );
208 $filter = array();
209
210 if ( empty( $data['limit'] ) ) {
211 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
212 }
213
214 /** Date filter */
215 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
216 if (
217 ! empty( $data['start'] )
218 && isDateByFormat( $data['start'], 'Y-m-d H:i' )
219 ) {
220 $start = \DateTime::createFromFormat( 'Y-m-d H:i', $data['start'], wp_timezone() );
221 $filter['start'] = $start->format( 'U' );
222 }
223
224 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
225 if (
226 ! empty( $data['end'] )
227 && isDateByFormat( $data['end'], 'Y-m-d H:i' )
228 ) {
229 $end = \DateTime::createFromFormat( 'Y-m-d H:i', $data['end'], wp_timezone() );
230 $filter['end'] = $end->format( 'U' );
231 }
232
233 /** Search filter */
234 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
235 if (
236 ! empty( $data['search'] )
237 && strlen( $data['search'] ) > 2
238 ) {
239 $filter['search'] = sanitize_text_field( $data['search'] );
240 }
241
242 $appointments = (array) Appointments::get_paged(
243 $data['limit'],
244 $data['offset'],
245 ( isset( $data['status'] )
246 && in_array( // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
247 $data['status'],
248 array( Appointments::$pending, Appointments::$approved, Appointments::$cancelled )
249 ) ) ? $data['status'] : '',
250 ( isset( $data['sort'] ) && 'id' === $data['sort'] ) ? $data['sort'] : '',
251 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
252 ( isset( $data['order'] ) && in_array( $data['order'], array( 'asc', 'desc' ) ) ) ? $data['order'] : '',
253 $filter
254 );
255
256 array_walk(
257 $appointments,
258 function ( &$value, $key ) {
259 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
260 $value['notes'] = unserialize( trim( $value['notes'] ) );
261
262 $payment = (object) array(
263 'total' => $value['total'],
264 'notes' => $value['payment_notes'],
265 );
266
267 $value['payment_flag_reason'] = null;
268 if ( 'paypal' === $value['payment_method'] && ( new PayPal() )->is_payment_mismatch( $payment ) ) {
269 $value['payment_flag_reason'] = 'mismatch';
270 } elseif ( 'stripeConnect' === $value['payment_method'] && ( new Merchant() )->is_payment_reuse( $payment ) ) {
271 $value['payment_flag_reason'] = 'reuse';
272 }
273 unset( $value['payment_notes'] );
274
275 $dateTimestamp = \DateTime::createFromFormat( 'U', $value['date_timestamp'], wp_timezone() );
276 $value['date_timestamp'] = $dateTimestamp->format( 'U' );
277 $value['date_timestamp_title'] = $dateTimestamp->format( 'd.m.Y' );
278 $value['start_time_formatted'] = $dateTimestamp->format( 'H:i' );
279
280 $value['price_row'] = get_option_by_path( 'bookit_settings.currency_symbol' ) . $value['price'];
281
282 $startTime = \DateTime::createFromFormat( 'U', $value['start_time'], wp_timezone() );
283 $value['time_title'] = $startTime->format( 'H:i' );
284
285 $value['customer_name'] = stripslashes( $value['customer_name'] );
286 }
287 );
288
289 $response['appointments'] = $appointments;
290 $response['total'] = Appointments::get_appointments_count( $data['status'], $filter );
291
292 wp_send_json_success( $response );
293 }
294
295 /** Get Appointment by id **/
296 public static function get_appointment_by_id() {
297 check_ajax_referer( 'bookit_get_appointment', 'nonce' );
298
299 if ( ! current_user_can( 'manage_options' ) ) {
300 return false;
301 }
302
303 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
304
305 if ( empty( $data['id'] ) ) {
306 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
307 }
308
309 $appointment = Appointments::get_full_appointment_by_id( $data['id'] );
310
311 /** Show email and phone from appointment notes */
312 if ( property_exists( $appointment, 'notes' ) ) {
313 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
314 $notes = unserialize( trim( $appointment->notes ) );
315
316 if ( key_exists( 'email', $notes ) ) {
317 $appointment->customer_email = $notes['email'];
318 }
319
320 if ( key_exists( 'phone', $notes ) ) {
321 $appointment->customer_phone = $notes['phone'];
322 }
323 }
324
325 /** Currency symbol with price */
326 $appointment->price_row = get_option_by_path( 'bookit_settings.currency_symbol' ) . $appointment->price;
327
328 $response['appointment'] = $appointment;
329 wp_send_json_success( $response );
330 }
331
332 /** Get Appointment form data to edit/create **/
333 public static function get_appointment_form_data() {
334 check_ajax_referer( 'bookit_get_appointment_form_data', 'nonce' );
335
336 if ( ! current_user_can( 'manage_options' ) ) {
337 return false;
338 }
339
340 wp_send_json_success( self::get_form_data() );
341 }
342
343 /**
344 * Get Appointments Short data by date range
345 */
346 public static function get_calendar_appointments() {
347 check_ajax_referer( 'bookit_get_calendar_appointments', 'nonce' );
348
349 if ( ! current_user_can( 'manage_options' ) ) {
350 return false;
351 }
352
353 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
354
355 if ( empty( $data ) || ! key_exists( 'start_timestamp', $data ) || ! key_exists( 'end_timestamp', $data ) ) {
356 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
357 }
358
359 /** check status **/
360 if ( key_exists( 'status', $data ) && ! empty( $data['status'] )
361 && ! in_array( strtolower( $data['status'] ), Appointments::$statusList, true ) ) {
362 wp_send_json_error( array( 'message' => __( 'Wrong status value', 'bookit' ) ) );
363 }
364
365 $start = $data['start_timestamp'];
366 $end = $data['end_timestamp'];
367
368 unset( $data['start_timestamp'] );
369 unset( $data['end_timestamp'] );
370
371 $appointments = Appointments::appointments_by_date_full( $start, $end, $data );
372 $appointments = self::parseAppointments( $appointments, $data['is_detail'] );
373
374 wp_send_json_success( $appointments );
375 }
376
377 /**
378 * @param Appointments $appointments
379 * @return array key is day number
380 */
381 public static function parseAppointments( $appointments, $is_detail = false ) {
382 $result = array();
383
384 foreach ( $appointments as $key => $appointment ) {
385 if ( ! key_exists( date( 'j_n', $appointment->start_time ), $result ) ) {
386 $result[ date( 'j_n', $appointment->start_time ) ] = array();
387 }
388
389 $item = (array) $appointment;
390 $item['customer_name'] = stripslashes( $item['customer_name'] );
391 $item['start'] = date( 'h:ia', $appointment->start_time );
392 $item['end'] = date( 'h:ia', $appointment->end_time );
393 $item['popup'] = false;
394
395 $item['price_row'] = get_option_by_path( 'bookit_settings.currency_symbol' ) . $appointment->price;
396 $item['icon_url'] = ( ! empty( $appointment->icon ) ) ? wp_get_attachment_url( $appointment->icon ) : null;
397
398 if ( property_exists( $appointment, 'notes' ) ) {
399 // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
400 $notes = unserialize( trim( $appointment->notes ) );
401 if ( key_exists( 'email', $notes ) ) {
402 $item['customer_email'] = $notes['email'];
403 }
404 if ( key_exists( 'phone', $notes ) ) {
405 $item['customer_phone'] = $notes['phone'];
406 }
407 if ( key_exists( 'comment', $notes ) ) {
408 $item['comment'] = $notes['comment'];
409 }
410 }
411
412 if ( ! $appointment->staff_name ) {
413 $item['staff_name'] = __( 'Not Set', 'bookit' );
414 }
415
416 array_push( $result[ date( 'j_n', $appointment->start_time ) ], $item );
417 }
418
419 unset( $appointments );
420 return $result;
421 }
422
423 /**
424 * Validation
425 * @param $data
426 */
427 public static function validate( $data ) {
428 $errors = array();
429 $settings = SettingsController::get_settings();
430
431 $appointmentId = (int) Appointments::checkAppointment( $data );
432
433 if (
434 (
435 null !== $appointmentId
436 && 0 !== $appointmentId
437 && ! isset( $data['id'] )
438 )
439 ||
440 (
441 null !== $appointmentId
442 && 0 !== $appointmentId
443 && isset( $data['id'] )
444 && $appointmentId !== $data['id']
445 )
446 ) {
447 $errors['dates'] = __( 'Selected Service Time is not available!', 'bookit' );
448 }
449
450 if ( ! in_array( $data['payment_method'], Payments::$typeList ) // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
451 || false === ( $settings['payments'][ $data['payment_method'] ]['enabled']
452 && Payments::$freeType !== $data['payment_method'] ) ) {
453 $errors['payment_method'] = __( 'Please choose correct payment method', 'bookit' );
454 }
455
456 if ( ! in_array( $data['payment_status'], Payments::$statusList ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
457 $errors['payment_status'] = __( 'Please choose correct payment status', 'bookit' );
458 }
459
460 if ( ! in_array( $data['status'], Appointments::$statusList ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
461 $errors['status'] = __( 'Please choose correct appointment status', 'bookit' );
462 }
463
464 if ( ! $data['customer_id'] ) {
465 $errors['customer_id'] = __( 'Please choose customer', 'bookit' );
466 }
467
468 if ( ! $data['staff_id'] ) {
469 $errors['staff_id'] = __( 'Please choose staff', 'bookit' );
470 }
471
472 if ( ! $data['service_id'] ) {
473 $errors['service_id'] = __( 'Please choose service', 'bookit' );
474 }
475
476 if ( $data['staff_id'] && $data['service_id'] ) {
477 $staff_service = Staff::get_by_id_and_service( $data['staff_id'], $data['service_id'] );
478
479 if ( null === $staff_service ) {
480 $errors['staff_service'] = __( 'Please choose correct staff and service', 'bookit' );
481 }
482 }
483
484 if ( 0 === $data['start_time'] || 0 === $data['end_time'] ) {
485 $errors['dates'] = __( 'Please choose appointment time', 'bookit' );
486 }
487
488 if ( empty( $data['date_timestamp'] ) || 0 === $data['date_timestamp'] ) {
489 $errors['dates'] = __( 'Please choose appointment date', 'bookit' );
490 }
491
492 if ( $data['customer_phone'] || false === $data['customer_phone'] ) {
493 if ( ! preg_match( '/^((\+)?[0-9]{8,14})$/', $data['customer_phone'] ) ) {
494 $errors['customer_phone'] = __( 'Please enter a valid phone number', 'bookit' );
495 }
496 }
497
498 if ( count( $errors ) > 0 ) {
499 wp_send_json_error( array( 'errors' => $errors ) );
500 }
501 }
502
503 /**
504 * Create Appointment
505 */
506 public static function save() {
507 check_ajax_referer( 'bookit_add_appointment', 'nonce' );
508
509 if ( ! current_user_can( 'manage_options' ) ) {
510 return false;
511 }
512 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
513 self::validate( $data );
514
515 /**
516 * CREATE APPOINTMENT CODE
517 */
518 if ( ! empty( $data ) ) {
519 $data['created_from'] = 'back';
520 $notes['comment'] = $data['comment'];
521
522 $customer = Customers::get( 'id', $data['customer_id'] );
523
524 if ( $customer->phone !== $data['customer_phone'] ) {
525 $notes['phone'] = $data['customer_phone'];
526 }
527 /** add phone to customer if not filled yet and value exist **/
528 if ( null === $customer->phone && ! empty( $data['customer_phone'] ) ) {
529 Customers::update( array( 'phone' => $data['customer_phone'] ), array( 'id' => $customer->id ) );
530 }
531
532 $data['notes'] = serialize( $notes ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
533
534 $id = Appointments::create_appointment( $data );
535
536 do_action( 'bookit_appointment_created', $id );
537
538 $appointment = (array) Appointments::get_full_appointment_by_id( $id );
539 $appointment['notes'] = unserialize( trim( $data['notes'] ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
540
541 $dateTimestamp = \DateTime::createFromFormat( 'U', $appointment['date_timestamp'], wp_timezone() );
542 $appointment['date_timestamp_title'] = $dateTimestamp->format( 'd.m.Y' );
543 $startTime = \DateTime::createFromFormat( 'U', $appointment['start_time'], wp_timezone() );
544 $endTime = \DateTime::createFromFormat( 'U', $appointment['end_time'], wp_timezone() );
545 $appointment['time_title'] = $startTime->format( 'H:i' ) . ' - ' . $endTime->format( 'H:i' );
546
547 /** if google calendar addon is installed */
548 if (
549 Plugin::isAddonInstalledAndEnabled( self::$proAddon )
550 && has_action( 'bookit_google_calendar_create_appointment' )
551 ) {
552 do_action( 'bookit_google_calendar_create_appointment', $appointment );
553 }
554 /** if google calendar addon is installed | end */
555
556 wp_send_json_success(
557 array(
558 'appointment' => $appointment,
559 'message' => __( 'Appointment Saved!', 'bookit' ),
560 )
561 );
562 }
563 }
564
565 /**
566 * Update Appointment
567 */
568 public static function update() {
569 check_ajax_referer( 'bookit_edit_appointment', 'nonce' );
570
571 if ( ! current_user_can( 'manage_options' ) ) {
572 return false;
573 }
574
575 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
576 self::validate( $data );
577
578 if ( ! empty( $data['id'] ) ) {
579
580 $appointment = (array) Appointments::get_full_appointment_by_id( $data['id'] );
581 $notes = unserialize( $appointment['notes'] ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
582
583 $customer = Customers::get( 'id', $data['customer_id'] );
584 if ( isset( $customer->phone ) && $customer->phone !== $data['customer_phone'] && isset( $notes['phone'] ) && $notes['phone'] !== $data['customer_phone'] ) {
585 $notes['phone'] = $data['customer_phone'];
586 }
587 if ( isset( $data['comment'] ) && $data['comment'] && $notes['comment'] !== $data['comment'] ) {
588 $notes['comment'] = $data['comment'];
589 }
590 $data['notes'] = serialize( $notes ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize
591
592 Appointments::update_appointment( $data, $data['id'] );
593 /** add phone to customer if not filled yet and value exist **/
594 if ( null === $customer->phone && ! empty( $data['customer_phone'] ) ) {
595 Customers::update( array( 'phone' => $data['customer_phone'] ), array( 'id' => $customer->id ) );
596 }
597
598 do_action( 'bookit_appointment_updated', $data['id'] );
599
600 $updatedAppointment = (array) Appointments::get_full_appointment_by_id( $data['id'] );
601 $updatedAppointment['notes'] = unserialize( trim( $updatedAppointment['notes'] ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize
602
603 $dateTimestamp = \DateTime::createFromFormat( 'U', $updatedAppointment['date_timestamp'], wp_timezone() );
604 $updatedAppointment['date_timestamp_title'] = $dateTimestamp->format( 'd.m.Y' );
605 $startTime = \DateTime::createFromFormat( 'U', $updatedAppointment['start_time'], wp_timezone() );
606 $endTime = \DateTime::createFromFormat( 'U', $updatedAppointment['end_time'], wp_timezone() );
607 $updatedAppointment['time_title'] = $startTime->format( 'H:i' ) . ' - ' . $endTime->format( 'H:i' );
608
609 /** if google calendar addon is installed */
610 if (
611 Plugin::isAddonInstalledAndEnabled( self::$proAddon )
612 && has_action( 'bookit_google_calendar_update_appointment' )
613 ) {
614 do_action( 'bookit_google_calendar_update_appointment', $appointment, $updatedAppointment );
615 }
616 /** if google calendar addon is installed | end */
617
618 wp_send_json_success(
619 array(
620 'appointment' => $updatedAppointment,
621 'message' => __( 'Appointment Updated!', 'bookit' ),
622 )
623 );
624 }
625
626 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
627 }
628
629 /**
630 * Change Status of Appointment
631 */
632 public static function change_status() {
633 check_ajax_referer( 'bookit_appointment_status', 'nonce' );
634
635 if ( ! current_user_can( 'manage_options' ) ) {
636 return false;
637 }
638
639 $data = CleanHelper::cleanData( $_GET, self::getCleanRules() );
640
641 if ( isset( $data['id'] ) && in_array( $data['status'], array( Appointments::$approved, Appointments::$cancelled, Appointments::$pending ), true ) ) {
642 $appointment = (array) Appointments::get_full_appointment_by_id( $data['id'] );
643 Appointments::change_status( $data['id'], $data['status'] );
644
645 do_action( 'bookit_appointment_status_changed', $data['id'] );
646
647 /** if google calendar addon is installed */
648 if (
649 Plugin::isAddonInstalledAndEnabled( self::$proAddon )
650 && has_action( 'bookit_google_calendar_update_appointment' )
651 ) {
652 $updatedAppointment = $appointment;
653 $updatedAppointment['status'] = $data['status'];
654
655 do_action( 'bookit_google_calendar_update_appointment', $appointment, $updatedAppointment );
656 }
657 /** if google calendar addon is installed | end */
658
659 wp_send_json_success( array( 'message' => __( 'Appointment Status Changed!', 'bookit' ) ) );
660 }
661
662 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
663 }
664
665 /**
666 * Delete the Appointment
667 */
668 public static function delete() {
669 check_ajax_referer( 'bookit_delete_item', 'nonce' );
670
671 if ( ! current_user_can( 'manage_options' ) ) {
672 return false;
673 }
674
675 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
676
677 if ( isset( $data['id'] ) ) {
678
679 $id = $data['id'];
680
681 $send_notification = json_decode( stripslashes( $data['send_notification'] ), true );
682 do_action( 'bookit_appointment_deleted', $data['id'], $send_notification, $data['reason'] );
683
684 /** if google calendar addon is installed */
685 if (
686 Plugin::isAddonInstalledAndEnabled( self::$proAddon )
687 && has_action( 'bookit_google_calendar_create_appointment' )
688 ) {
689 $appointment = (array) Appointments::get_full_appointment_by_id( $id );
690 do_action( 'bookit_google_calendar_delete_appointment', $appointment );
691 }
692 /** if google calendar addon is installed | end */
693
694 Appointments::delete_appointment( $id );
695
696 wp_send_json_success( array( 'message' => __( 'Appointment Deleted!', 'bookit' ) ) );
697 }
698
699 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
700 }
701
702 }
703