PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.22
Timetics – Appointment Booking Calendar & Scheduling v1.0.22
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 / appointments / api-appointment.php

api-appointment.php in Timetics – Appointment Booking Calendar & Scheduling 1.0.22, at core/appointments/api-appointment.php

879 lines 31.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Apointment api
4 *
5 * @since 1.0.0
6 *
7 * @package Timetics
8 */
9 namespace Timetics\Core\Appointments;
10
11 use Timetics\Base\Api;
12 use Timetics\Core\Appointments\Appointment;
13 use Timetics\Core\Staffs\Staff;
14 use Timetics\Utils\Singleton;
15 use WP_Error;
16 use WP_HTTP_Response;
17 use WP_REST_Request;
18
19 /**
20 * Api_Appointment class
21 *
22 * @since 1.0.0
23 */
24 class Api_Appointment extends Api {
25
26 use Singleton;
27
28 /**
29 * Store api namespace
30 *
31 * @since 1.0.0
32 *
33 * @var string $namespace
34 */
35 protected $namespace = 'timetics/v1';
36
37 /**
38 * Store rest base
39 *
40 * @since 1.0.0
41 *
42 * @var string $rest_base
43 */
44 protected $rest_base = 'appointments';
45
46 /**
47 * Register rest routes.
48 *
49 * @since 1.0.0
50 *
51 * @return void
52 */
53 public function register_routes() {
54 /*
55 * Register route
56 */
57 register_rest_route( $this->namespace, $this->rest_base, [
58 [
59 'methods' => \WP_REST_Server::READABLE,
60 'callback' => [$this, 'get_items'],
61 'permission_callback' => function () {
62 return true;
63 },
64 ],
65 [
66 'methods' => \WP_REST_Server::CREATABLE,
67 'callback' => [$this, 'create_item'],
68 'permission_callback' => function () {
69 return current_user_can( 'read_meeting' );
70 },
71 ],
72 [
73 'methods' => \WP_REST_Server::DELETABLE,
74 'callback' => [$this, 'bulk_delete'],
75 'permission_callback' => function () {
76 return current_user_can( 'read_meeting' );
77 },
78 ],
79 ] );
80
81 /**
82 * Register route
83 *
84 * @var void
85 */
86 register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<appointment_id>[\d]+)', [
87 [
88 'methods' => \WP_REST_Server::READABLE,
89 'callback' => [$this, 'get_item'],
90 'permission_callback' => function () {
91 return true;
92 },
93 ],
94 [
95 'methods' => \WP_REST_Server::EDITABLE,
96 'callback' => [$this, 'update_item'],
97 'permission_callback' => function () {
98 return current_user_can( 'read_meeting' );
99 },
100 ],
101 [
102 'methods' => \WP_REST_Server::DELETABLE,
103 'callback' => [$this, 'delete_item'],
104 'permission_callback' => function () {
105 return current_user_can( 'read_meeting' );
106 },
107 ],
108 ] );
109
110 register_rest_route( $this->namespace, $this->rest_base . '/search', [
111 [
112 'methods' => \WP_REST_Server::READABLE,
113 'callback' => [$this, 'search_items'],
114 'permission_callback' => function () {
115 return current_user_can( 'edit_posts' );
116 },
117 ],
118 ] );
119
120 register_rest_route( $this->namespace, $this->rest_base . '/filter', [
121 [
122 'methods' => \WP_REST_Server::READABLE,
123 'callback' => [$this, 'filter_items'],
124 'permission_callback' => function () {
125 return true;
126 },
127 ],
128 ] );
129
130 register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<appointment_id>[\d]+)' . '/duplicate', [
131 [
132 'methods' => \WP_REST_Server::CREATABLE,
133 'callback' => [$this, 'duplicate_item'],
134 'permission_callback' => function () {
135 return current_user_can( 'edit_meeting' );
136 },
137 ],
138 ] );
139 }
140
141 /**
142 * Get all appointments
143 *
144 * @param WP_Rest_Request $request
145 *
146 * @return JSON
147 */
148 public function get_items( $request ) {
149
150 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
151 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
152 $type = ! empty( $request['type'] ) ? sanitize_text_field( $request['type'] ) : '';
153
154 $args = [
155 'posts_per_page' => $per_page,
156 'paged' => $paged,
157 'type' => $type,
158 ];
159
160 if ( ! current_user_can( 'edit_meeting' ) ) {
161 $args['staff'] = get_current_user_id();
162 }
163
164 $appoint = Appointment::all( $args );
165
166 $items = [];
167
168 foreach ( $appoint['items'] as $item ) {
169 $items[] = $this->prepare_item( $item->ID );
170 }
171
172 $data = [
173 'success' => 1,
174 'status_code' => 200,
175 'data' => [
176 'total' => $appoint['total'],
177 'items' => $items,
178 ],
179 ];
180
181 return rest_ensure_response( $data );
182 }
183
184 /**
185 * Search appointment
186 *
187 * @param Object $request
188 *
189 * @return JSON
190 */
191 public function search_items( $request ) {
192
193 // Prepare search args.
194 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
195 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
196 $search = ! empty( $request['search'] ) ? sanitize_text_field( $request['search'] ) : '';
197
198 // Get search.
199 $appointments = new \WP_Query(
200 array(
201 'post_type' => 'timetics-appointment',
202 'posts_per_page' => $per_page,
203 'paged' => $paged,
204 'orderby' => 'ID',
205 'order' => 'DESC',
206
207 // @codingStandardsIgnoreStart
208 'meta_query' => array(
209 'relation' => 'OR',
210 array(
211 'key' => '_tt_apointment_name',
212 'value' => $search,
213 'compare' => 'LIKE',
214 ),
215 array(
216 'key' => '_tt_apointment_type',
217 'value' => $search,
218 'compare' => 'LIKE',
219 ),
220 array(
221 'key' => '_tt_apointment_description',
222 'value' => $search,
223 'compare' => 'LIKE',
224 ),
225 array(
226 'key' => '_tt_apointment_location',
227 'value' => $search,
228 'compare' => 'LIKE',
229 ),
230 array(
231 'key' => '_tt_apointment_duration',
232 'value' => $search,
233 'compare' => 'LIKE',
234 ),
235 array(
236 'key' => '_tt_apointment_schedule',
237 'value' => $search,
238 'compare' => 'LIKE',
239 ),
240 ),
241 // @codingStandardsIgnoreEnd
242 )
243 );
244
245 // Prepare items for response.
246 $items = [];
247
248 foreach ( $appointments->posts as $item ) {
249 $items[] = $this->prepare_item( $item->ID );
250 }
251
252 $data = [
253 'success' => 1,
254 'status' => 200,
255 'data' => [
256 'total' => $appointments->found_posts,
257 'items' => $items,
258 ],
259 ];
260
261 return rest_ensure_response( $data );
262 }
263
264 public function filter_items( $request ) {
265
266 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
267 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
268 $staff = ! empty( $request['staff_id'] ) ? intval( $request['staff_id'] ) : 0;
269 $category = ! empty( $request['category'] ) ? intval( $request['category'] ) : 0;
270 $visibility = ! empty( $request['visibility'] ) ? sanitize_text_field( $request['visibility'] ) : '';
271
272 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
273 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
274
275 $appoint = Appointment::all( [
276 'posts_per_page' => $per_page,
277 'paged' => $paged,
278 'visibility' => $visibility,
279 'staff' => $staff,
280 'category' => $category,
281 ] );
282
283 $items = [];
284
285 foreach ( $appoint['items'] as $item ) {
286 $items[] = $this->prepare_item( $item->ID );
287 }
288
289 $data = [
290 'success' => 1,
291 'status' => 200,
292 'data' => [
293 'total' => $appoint['total'],
294 'items' => $items,
295 ],
296 ];
297
298 return rest_ensure_response( $data );
299 }
300
301 /**
302 * Create appointment
303 *
304 * @param WP_Rest_Request $request
305 *
306 * @return JSON Newly created appointment data
307 */
308 public function create_item( $request ) {
309
310 /**
311 * Added temporary for leagacy sass. It will remove in future.
312 */
313
314 $meetings_count = Appointment::all();
315 $data = json_decode( $request->get_body(), true );
316
317 $response = [
318 'success' => 0,
319 'status_code' => 403,
320 'message' => esc_html__( 'Something went wrong', 'timetics' ),
321 'data' => [],
322 ];
323
324 if ( ! empty( $data['price'] ) && apply_filters( 'timetics/staff/appointment/price_check', false, $data['price'] ) == true ) {
325 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'price_check' ), 403 );
326 }
327
328 if ( apply_filters( 'timetics/staff/appointment/count_check', false, $meetings_count ) == true ) {
329 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'count_check' ), 403 );
330 }
331
332 $type = ! empty( $data['type'] ) ? sanitize_text_field( $data['type'] ) : '';
333
334 if ( apply_filters( 'timetics/staff/appointment/type_check', false, $type ) == true ) {
335 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'type_check' ), 403 );
336 }
337
338 $categories = ! empty( $data['categories'] ) ? $data['categories'] : '';
339
340 if ( apply_filters( 'timetics/staff/appointment/category_check', false, $categories ) == true ) {
341 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'category_check' ), 403 );
342 }
343
344 $staff = ! empty( $data['staff'] ) ? array_map( 'intval', $data['staff'] ) : [];
345
346 if ( apply_filters( 'timetics/staff/appointment/staff_check', false, $staff ) == true ) {
347 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'staff_check' ), 403 );
348 }
349
350 $custom_fields = ! empty( $data['custom_fields'] ) ? $data['custom_fields'] : [];
351
352 if ( apply_filters( 'timetics/staff/appointment/custom_field_check', false, $custom_fields ) == true ) {
353 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'custom_field_check' ), 403 );
354 }
355
356 $recurring_limit = ! empty( $data['recurring_limit'] ) ? $data['recurring_limit'] : [];
357
358 if ( apply_filters( 'timetics/staff/appointment/recurring_limit_check', false, $recurring_limit ) == true ) {
359
360 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'recurring_limit_check' ), 403 );
361 }
362
363 // End
364
365 return $this->save_appointment( $request );
366 }
367
368 /**
369 * Update appointment
370 *
371 * @param WP_Rest_Request $request
372 *
373 * @return JSON Updated appointment data
374 */
375 public function update_item( $request ) {
376
377 $appointment_id = (int) $request['appointment_id'];
378 $appoint = new Appointment( $appointment_id );
379
380 $data = json_decode( $request->get_body(), true );
381
382 /**
383 * Added temporary for leagacy sass. It will remove in future.
384 */
385 $response = [
386 'success' => 0,
387 'status_code' => 502,
388 'message' => esc_html__( 'Something went wrong', 'timetics' ),
389 'data' => [],
390 ];
391
392 if ( !empty($data['availability']) && $data['availability'] && apply_filters('timetics/staff/meeting/availability', false)) {
393 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'availability_update' ), 403 );
394 }
395
396 if ( ! empty( $data['price'] ) && apply_filters( 'timetics/staff/appointment/price_check', false, $data['price'] ) == true ) {
397 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'price_check' ), 403 );
398 }
399
400 $categories = ! empty( $data['categories'] ) ? $data['categories'] : '';
401
402 if ( apply_filters( 'timetics/staff/appointment/category_check', false, $categories ) == true ) {
403 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'category_check' ), 403 );
404 }
405
406 $staff = ! empty( $data['staff'] ) ? array_map( 'intval', $data['staff'] ) : [];
407
408 if ( apply_filters( 'timetics/staff/appointment/staff_check', false, $staff ) == true ) {
409 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'staff_check' ), 403 );
410 }
411
412 $custom_fields = ! empty( $data['custom_fields'] ) ? $data['custom_fields'] : [];
413
414 if ( apply_filters( 'timetics/staff/appointment/custom_field_check', false, $custom_fields ) == true ) {
415 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'custom_field_check' ), 403 );
416 }
417
418 $recurring_limit = ! empty( $data['recurring_limit'] ) ? $data['recurring_limit'] : [];
419
420 if ( apply_filters( 'timetics/staff/appointment/recurring_limit_check', false, $recurring_limit ) == true ) {
421
422 return new WP_HTTP_Response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'recurring_limit_check' ), 403 );
423 }
424
425 // End.
426
427 if ( ! $appoint->is_appointment() ) {
428
429 $response = [
430 'success' => 0,
431 'status_code' => 404,
432 'message' => esc_html__( 'Invalid appointment id.', 'timetics' ),
433 'data' => [],
434 ];
435
436 return new WP_HTTP_Response( $response, 404 );
437 }
438
439 return $this->save_appointment( $request, $appointment_id );
440 }
441
442 /**
443 * Get single appointment
444 *
445 * @param WP_Rest_Requesr $request
446 *
447 * @return JSON Single appointment data
448 */
449 public function get_item( $request ) {
450 $appoinment_id = (int) $request['appointment_id'];
451 $appoint = new Appointment( $appoinment_id );
452
453 if ( ! $appoint->is_appointment() ) {
454
455 $data = [
456 'status_code' => 404,
457 'message' => esc_html__( 'Invalid appointment id.', 'timetics' ),
458 'data' => [],
459 ];
460
461 return new WP_HTTP_Response( $data, 404 );
462 }
463
464 $response = [
465 'status_code' => 200,
466 'message' => esc_html__( 'Successfully retrieved appointments', 'timetics' ),
467 'data' => $this->prepare_item( $appoint ),
468 ];
469
470 return rest_ensure_response( $response );
471 }
472
473 /**
474 * Delete single appointment
475 *
476 * @param WP_Rest_Request $request
477 *
478 * @return
479 */
480 public function delete_item( $request ) {
481
482 $appoinment_id = (int) $request['appointment_id'];
483 $appoint = new Appointment( $appoinment_id );
484
485 $current_user_id = get_current_user_id();
486
487 if ( $appoint->get_author() != $current_user_id ) {
488 $data = [
489 'success' => 0,
490 'message' => __( 'You are not allowed to delete this meeting.', 'timetics' ),
491 ];
492
493 return new WP_HTTP_Response( $data, 403 );
494 }
495
496 if ( ! $appoint->is_appointment() ) {
497 return [
498 'status_code' => 404,
499 'message' => esc_html__( 'Invalid appointment id.', 'timetics' ),
500 'data' => [],
501 ];
502 }
503
504 $appoint->delete();
505
506 $response = [
507 'status_code' => 201,
508 'message' => esc_html__( 'Successfully deleted appointment', 'timetics' ),
509 'data' => [
510 'item' => $appoinment_id,
511 ],
512 ];
513
514 return rest_ensure_response( $response );
515 }
516
517 /**
518 * Delete multiples
519 *
520 * @param WP_Rest_Request $request
521 *
522 * @return JSON
523 */
524 public function bulk_delete( $request ) {
525
526 $appointments = json_decode( $request->get_body(), true );
527
528 foreach ( $appointments as $appoint ) {
529 $appoint = new Appointment( $appoint );
530
531 if ( ! $appoint->is_appointment() ) {
532 $data = [
533 'success' => 0,
534 'status' => 404,
535 'message' => esc_html__( 'Invalid appointment id.', 'timetics' ),
536 'data' => [],
537 ];
538
539 return new WP_HTTP_Response( $data, 404 );
540 }
541
542 $appoint->delete();
543 }
544
545 return rest_ensure_response( [
546 'success' => 1,
547 'status' => 201,
548 'message' => esc_html__( 'Successfully deleted all appointments', 'timetics' ),
549 'data' => [
550 'items' => $appointments,
551 ],
552 ] );
553 }
554
555 /**
556 * Duplicate appointment
557 *
558 * @since 1.0.0
559 *
560 * @param object $request
561 *
562 * @return JSON
563 */
564 public function duplicate_item( $request ) {
565
566 /**
567 * Added temporary for leagacy sass. It will remove in future.
568 */
569
570 $meetings_count = Appointment::all();
571
572 $response = [
573 'success' => 0,
574 'status_code' => 502,
575 'message' => esc_html__( 'Something went wrong', 'timetics' ),
576 'data' => [],
577 ];
578
579 if ( apply_filters( 'timetics/staff/appointment/count_check', false, $meetings_count ) == true ) {
580 return rest_ensure_response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'count_check' ) );
581 }
582
583 $custom_fields = ! empty( $data['custom_fields'] ) ? $data['custom_fields'] : [];
584
585 if ( apply_filters( 'timetics/staff/appointment/custom_field_check', false, $custom_fields ) == true ) {
586 return rest_ensure_response( apply_filters( 'timetics/admin/appointment/error_data', $response, 'custom_field_check' ) );
587 }
588
589 $appoinment_id = (int) $request['appointment_id'];
590 $appoint = new Appointment( $appoinment_id );
591
592 if ( ! $appoint->is_appointment() ) {
593 return new WP_HTTP_Response(
594 [
595 'success' => 0,
596 'status_code' => 404,
597 'message' => esc_html__( 'Invalid appointment id.', 'timetics' ),
598 'data' => [],
599 ],
600 404
601 );
602 }
603
604 $appoint->duplicate();
605
606 $item = $this->prepare_item( $appoint );
607
608 $response = [
609 'success' => 1,
610 'status_code' => 201,
611 'message' => esc_html__( 'Successfully duplicated appointment', 'timetics' ),
612 'data' => $item,
613 ];
614
615 return rest_ensure_response( $response );
616 }
617
618 /**
619 * Save appointment
620 *
621 * @param WP_Rest_Request $request
622 * @param integer $id Appointment id
623 *
624 * @return JSON Updated appoitment data
625 */
626 public function save_appointment( $request, $id = 0 ) {
627 $appoint = new Appointment( $id );
628
629 $data = json_decode( $request->get_body(), true );
630
631 $data = apply_filters( 'timetics_meeting_data', $data );
632
633 $name = ! empty( $data['name'] ) ? sanitize_text_field( $data['name'] ) : $appoint->get_name();
634 $type = ! empty( $data['type'] ) ? sanitize_text_field( $data['type'] ) : $appoint->get_type();
635 $description = ! empty( $data['description'] ) ? sanitize_text_field( $data['description'] ) : '';
636 $staff = ! empty( $data['staff'] ) ? array_map( 'intval', $data['staff'] ) : $appoint->get_staff();
637 $locations = ! empty( $data['locations'] ) ? $data['locations'] : $appoint->get_locations();
638 $duration = ! empty( $data['duration'] ) ? sanitize_text_field( $data['duration'] ) : '';
639 $schedule = ! empty( $data['schedule'] ) ? $data['schedule'] : $appoint->get_schedule();
640 $blocked_schedule = ! empty( $data['blocked_schedule'] ) ? $data['blocked_schedule'] : $appoint->get_blocked_schedule();
641 $price = ! empty( $data['price'] ) ? $data['price'] : '';
642 $categories = ! empty( $data['categories'] ) ? $data['categories'] : '';
643 $buffer_time = ! empty( $data['buffer_time'] ) ? $data['buffer_time'] : '';
644 $timezone = ! empty( $data['timezone'] ) ? $data['timezone'] : '';
645 $availability = ! empty( $data['availability'] ) ? $data['availability'] : '';
646 $visibility = ! empty( $data['visibility'] ) ? strtolower( $data['visibility'] ) : 'enabled';
647 $notifications = ! empty( $data['notifications'] ) ? $data['notifications'] : '';
648 $fleunt_crm_webhook = ! empty( $data['fleunt_crm_webhook'] ) ? $data['fleunt_crm_webhook'] : '';
649 $fluent_hook_overwrite = ! empty( $data['fluent_hook_overwrite'] ) ? (bool) $data['fluent_hook_overwrite'] : false;
650 $pabbly_hook_overwrite = ! empty( $data['pabbly_hook_overwrite'] ) ? (bool) $data['pabbly_hook_overwrite'] : false;
651 $zapier_hook_overwrite = ! empty( $data['zapier_hook_overwrite'] ) ? (bool) $data['zapier_hook_overwrite'] : false;
652 $pabbly_webook = ! empty( $data['pabbly_webook'] ) ? $data['pabbly_webook'] : '';
653 $zapier_webook = ! empty( $data['zapier_webook'] ) ? $data['zapier_webook'] : '';
654 $min_notice_time = ! empty( $data['min_notice_time'] ) ? $data['min_notice_time'] : '';
655 $custom_fields = ! empty( $data['custom_fields'] ) ? $data['custom_fields'] : [];
656 $guest_enabled = ! empty( $data['guest_enabled'] ) ? intval( $data['guest_enabled'] ) : false;
657 $guest_limit = ! empty( $data['guest_limit'] ) ? intval( $data['guest_limit'] ) : 1;
658 $capacity = ! empty( $data['capacity'] ) ? intval( $data['capacity'] ) : 1;
659 $appointment_id = ! empty( $data['appointment'] ) ? intval( $data['appointment'] ) : 1;
660 $action = $id ? 'update' : 'created';
661
662 if ( $id ) {
663 $current_user_id = get_current_user_id();
664 $dulicate = $appoint->get_duplicate_nuber();
665
666 if ( $appoint->get_author() != $current_user_id ) {
667 $data = [
668 'success' => 0,
669 'message' => __( 'You are not allowed to update this meeting.', 'timetics' ),
670 ];
671
672 return new WP_HTTP_Response( $data, 403 );
673 }
674
675 if ( $dulicate && strpos( $name, '-Duplicate' ) == 0 ) {
676 $appoint->update([
677 'duplicate' => 0
678 ]);
679 }
680 }
681
682 if ( is_array( $price ) ) {
683 $ticket_quantity = 0;
684 foreach ( $price as &$ticket ) {
685 if ( empty( $ticket['ticket_price'] ) ) {
686 $ticket['ticket_price'] = 0;
687 }
688 if ( ! empty( $ticket['ticket_quantity'] ) ) {
689 $ticket_quantity += intval( $ticket['ticket_quantity'] );
690 }
691 }
692
693 $capacity = $ticket_quantity;
694 }
695
696 $validate_data = [
697 'name' => $name,
698 'type' => $type,
699 'locations' => $locations,
700 'schedule' => $schedule,
701 'blocked_schedule' => $blocked_schedule,
702 'staff' => $staff,
703
704 ];
705 // Validate input data.
706 $validate = $this->validate( $validate_data, [
707 'name',
708 'type',
709 'locations',
710 'schedule',
711 'staff',
712 ] );
713
714 if ( ! timetics_is_valid_timezone( $timezone ) ) {
715 return new WP_Error( 'timezone_error', __( 'Your timezone is invaid.', 'timetics' ) );
716 }
717
718 $lolcation_errors = $this->get_location_errors( $locations, $staff );
719
720 if ( $lolcation_errors ) {
721 $data = [
722 'status_code' => 409,
723 'success' => 0,
724 'message' => $lolcation_errors,
725 'data' => [],
726 ];
727
728 return new WP_HTTP_Response( $data, 409 );
729 }
730
731 if ( is_wp_error( $validate ) ) {
732 $data = [
733 'status_code' => 409,
734 'success' => 0,
735 'message' => $validate->get_error_messages(),
736 'data' => [],
737 ];
738
739 return new WP_HTTP_Response( $data, 409 );
740 }
741
742 // Save appointment.
743 $appointment_data = [
744 'name' => str_replace( '-Duplicate', '', $name ),
745 'description' => $description,
746 'type' => $type,
747 'locations' => $locations,
748 'staff' => $staff,
749 'duration' => $duration,
750 'price' => $price,
751 'capacity' => $capacity,
752 'schedule' => $schedule,
753 'blocked_schedule' => $blocked_schedule,
754 'categories' => $categories,
755 'timezone' => $timezone,
756 'availability' => $availability,
757 'visibility' => $visibility,
758 'buffer_time' => $buffer_time,
759 'notifications' => $notifications,
760 'fleunt_crm_webhook' => $fleunt_crm_webhook,
761 'fluent_hook_overwrite' => $fluent_hook_overwrite,
762 'pabbly_hook_overwrite' => $pabbly_hook_overwrite,
763 'zapier_hook_overwrite' => $zapier_hook_overwrite,
764 'pabbly_webook' => $pabbly_webook,
765 'zapier_webook' => $zapier_webook,
766 'min_notice_time' => $min_notice_time,
767 'custom_fields' => $custom_fields,
768 'guest_enabled' => $guest_enabled,
769 'guest_limit' => $guest_limit,
770
771 ];
772
773 $appointment_data = apply_filters( 'timetics_meeting_insert_data', $data, $appointment_data );
774
775 $appoint->set_props( $appointment_data );
776 $appoint->save();
777
778 // Assign meeting category.
779 wp_set_post_terms( $appoint->get_id(), $categories, 'timetics-meeting-category' );
780
781 do_action( 'timetics_meeting_after_insert', $appoint, $data );
782
783 // Prepare response data.
784 $item = $this->prepare_item( $appoint );
785
786 $response = [
787 'status_code' => 201,
788 'success' => 1,
789 'message' => sprintf( esc_html__( 'Succssfully %s appointment', 'timetics' ), $action ),
790 'data' => $item,
791 ];
792
793 return rest_ensure_response( $response );
794 }
795
796 /**
797 * Prepare item for response
798 *
799 * @param integer $appoinment_id
800 *
801 * @return array
802 */
803 public function prepare_item( $appoint_id, $timezone = '' ) {
804 $appointment = new Appointment( $appoint_id );
805 $dulicate = $appointment->get_duplicate_nuber();
806
807 $dulicate_text = $dulicate ? ' -Duplicate' : '';
808 $custom_fields = $appointment->get_custom_fields();
809 $data = [
810 'id' => $appointment->get_id(),
811 'name' => $appointment->get_name() . $dulicate_text,
812 'image' => $appointment->get_image(),
813 // 'link' => $appointment->get_link(),
814 'description' => $appointment->get_description(),
815 'type' => $appointment->get_type(),
816 'locations' => $appointment->get_locations(),
817 'schedule' => $appointment->get_schedule(),
818 'blocked_schedule' => $appointment->get_blocked_schedule(),
819 'price' => $appointment->get_price(),
820 'categories' => $appointment->get_category_ids(),
821 'staff' => $appointment->get_staff(),
822 'buffer_time' => $appointment->get_buffer_time(),
823 'timezone' => $appointment->get_timezone(),
824 'availability' => $appointment->get_availability(),
825 'visibility' => $appointment->get_visibility(),
826 'duration' => $appointment->get_duration(),
827 'notifications' => $appointment->get_notifications(),
828 'capacity' => $appointment->get_capacity(),
829 'fluent_hook_overwrite' => $appointment->get_fluent_hook_overwrite(),
830 'fleunt_crm_webhook' => $appointment->get_fleunt_crm_webhook(),
831 'pabbly_hook_overwrite' => $appointment->get_pabbly_hook_overwrite(),
832 'pabbly_webook' => $appointment->get_pabbly_webook(),
833 'zapier_hook_overwrite' => $appointment->get_zapier_hook_overwrite(),
834 'zapier_webook' => $appointment->get_zapier_webook(),
835 'min_notice_time' => $appointment->get_min_notice_time(),
836 'custom_fields' => $custom_fields ?: [],
837 'permalink' => get_permalink( $appointment->get_id() ),
838 'guest_enabled' => $appointment->get_guest_enabled(),
839 'guest_limit' => $appointment->get_guest_limit(),
840 'author' => $appointment->get_author(),
841 ];
842
843 return apply_filters( 'timetics_meeting_json_data', $data, $appointment );
844 }
845
846 /**
847 * Validate location with zoom and google connection
848 *
849 * @param array $locations
850 * @param array $staffs
851 *
852 * @return array
853 */
854 public function get_location_errors( $locations, $staffs ) {
855
856 $errors = [];
857
858 foreach ( $staffs as $staff_id ) {
859 $staff = new Staff( $staff_id );
860 foreach ( $locations as $location ) {
861 switch ( $location['location_type'] ) {
862 case 'google-meet':
863 if ( ! timetics_is_google_meet_connected( $staff_id ) ) {
864 $errors[] = sprintf( '%s %s', $staff->get_display_name(), esc_html__( 'is not connected to google meet. Please connect to google meet then try again', 'timetics' ) );
865 }
866 break;
867 case 'zoom':
868 if ( ! timetics_is_zoom_connected( $staff_id ) ) {
869 $errors[] = sprintf( '%s %s', $staff->get_display_name(), esc_html__( 'is not connected to zoom. Please connect to zoom then try again', 'timetics' ) );
870 }
871 break;
872 }
873 }
874 }
875
876 return $errors;
877 }
878 }
879