PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.2
Timetics – Appointment Booking Calendar & Scheduling v1.0.2
1.0.62 1.0.63 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 All 64 releases
timetics / core / appointments / api-appointment.php

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

606 lines 19.1 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\Utils\Singleton;
14 use WP_HTTP_Response;
15 use WP_REST_Request;
16
17 /**
18 * Api_Appointment class
19 *
20 * @since 1.0.0
21 */
22 class Api_Appointment extends Api {
23
24 use Singleton;
25
26 /**
27 * Store api namespace
28 *
29 * @since 1.0.0
30 *
31 * @var string $namespace
32 */
33 protected $namespace = 'timetics/v1';
34
35 /**
36 * Store rest base
37 *
38 * @since 1.0.0
39 *
40 * @var string $rest_base
41 */
42 protected $rest_base = 'appointments';
43
44 /**
45 * Register rest routes.
46 *
47 * @since 1.0.0
48 *
49 * @return void
50 */
51 public function register_routes() {
52 /*
53 * Register route
54 */
55 register_rest_route( $this->namespace, $this->rest_base, [
56 [
57 'methods' => \WP_REST_Server::READABLE,
58 'callback' => [$this, 'get_items'],
59 'permission_callback' => function () {
60 return true;
61 },
62 ],
63 [
64 'methods' => \WP_REST_Server::CREATABLE,
65 'callback' => [$this, 'create_item'],
66 'permission_callback' => function () {
67 return current_user_can( 'edit_meeting' );
68 },
69 ],
70 [
71 'methods' => \WP_REST_Server::DELETABLE,
72 'callback' => [$this, 'bulk_delete'],
73 'permission_callback' => function () {
74 return current_user_can( 'edit_meeting' );
75 },
76 ],
77 ] );
78
79 /**
80 * Register route
81 *
82 * @var void
83 */
84 register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<appointment_id>[\d]+)', [
85 [
86 'methods' => \WP_REST_Server::READABLE,
87 'callback' => [$this, 'get_item'],
88 'permission_callback' => function () {
89 return true;
90 },
91 ],
92 [
93 'methods' => \WP_REST_Server::EDITABLE,
94 'callback' => [$this, 'update_item'],
95 'permission_callback' => function () {
96 return current_user_can( 'edit_meeting' );
97 },
98 ],
99 [
100 'methods' => \WP_REST_Server::DELETABLE,
101 'callback' => [$this, 'delete_item'],
102 'permission_callback' => function () {
103 return current_user_can( 'edit_meeting' );
104 },
105 ],
106 ] );
107
108 register_rest_route( $this->namespace, $this->rest_base . '/search', [
109 [
110 'methods' => \WP_REST_Server::READABLE,
111 'callback' => [$this, 'search_items'],
112 'permission_callback' => function () {
113 return current_user_can( 'edit_posts' );
114 },
115 ],
116 ] );
117
118 register_rest_route( $this->namespace, $this->rest_base . '/filter', [
119 [
120 'methods' => \WP_REST_Server::READABLE,
121 'callback' => [$this, 'filter_items'],
122 'permission_callback' => function () {
123 return current_user_can( 'edit_posts' );
124 },
125 ],
126 ] );
127
128 register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<appointment_id>[\d]+)' . '/duplicate', [
129 [
130 'methods' => \WP_REST_Server::CREATABLE,
131 'callback' => [$this, 'duplicate_item'],
132 'permission_callback' => function () {
133 return current_user_can( 'edit_meeting' );
134 },
135 ],
136 ] );
137 }
138
139 /**
140 * Get all appointments
141 *
142 * @param WP_Rest_Request $request
143 *
144 * @return JSON
145 */
146 public function get_items( $request ) {
147
148 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
149 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
150 $type = ! empty( $request['type'] ) ? sanitize_text_field( $request['type'] ) : '';
151
152 $args = [
153 'posts_per_page' => $per_page,
154 'paged' => $paged,
155 'type' => $type,
156 ];
157
158 if ( ! current_user_can( 'edit_meeting' ) ) {
159 $args['staff'] = get_current_user_id();
160 }
161
162 $appoint = Appointment::all( $args );
163
164 $items = [];
165
166 foreach ( $appoint['items'] as $item ) {
167 $items[] = $this->prepare_item( $item->ID );
168 }
169
170 $data = [
171 'success' => 1,
172 'status_code' => 200,
173 'data' => [
174 'total' => $appoint['total'],
175 'items' => $items,
176 ],
177 ];
178
179 return rest_ensure_response( $data );
180 }
181
182 /**
183 * Search appointment
184 *
185 * @param Object $request
186 *
187 * @return JSON
188 */
189 public function search_items( $request ) {
190 // Prepare search args.
191 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
192 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
193 $search = ! empty( $request['search'] ) ? sanitize_text_field( $request['search'] ) : '';
194
195 // Get search.
196 $appointments = new \WP_Query(
197 array(
198 'post_type' => 'timetics-appointment',
199 'posts_per_page' => $per_page,
200 'paged' => $paged,
201 'orderby' => 'ID',
202 'order' => 'DESC',
203
204 // @codingStandardsIgnoreStart
205 'meta_query' => array(
206 'relation' => 'OR',
207 array(
208 'key' => '_tt_apointment_name',
209 'value' => $search,
210 'compare' => 'LIKE',
211 ),
212 array(
213 'key' => '_tt_apointment_type',
214 'value' => $search,
215 'compare' => 'LIKE',
216 ),
217 array(
218 'key' => '_tt_apointment_description',
219 'value' => $search,
220 'compare' => 'LIKE',
221 ),
222 array(
223 'key' => '_tt_apointment_location',
224 'value' => $search,
225 'compare' => 'LIKE',
226 ),
227 array(
228 'key' => '_tt_apointment_duration',
229 'value' => $search,
230 'compare' => 'LIKE',
231 ),
232 array(
233 'key' => '_tt_apointment_schedule',
234 'value' => $search,
235 'compare' => 'LIKE',
236 ),
237 ),
238 // @codingStandardsIgnoreEnd
239 )
240 );
241
242 // Prepare items for response.
243 $items = [];
244
245 foreach ( $appointments->posts as $item ) {
246 $items[] = $this->prepare_item( $item->ID );
247 }
248
249 $data = [
250 'success' => 1,
251 'status' => 200,
252 'data' => [
253 'total' => $appointments->found_posts,
254 'items' => $items,
255 ],
256 ];
257
258 return rest_ensure_response( $data );
259 }
260
261 public function filter_items( $request ) {
262 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
263 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
264 $staff = ! empty( $request['staff_id'] ) ? intval( $request['staff_id'] ) : 0;
265 $visibility = ! empty( $request['visibility'] ) ? sanitize_text_field( $request['visibility'] ) : 'enabled';
266
267 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
268 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
269
270 $appoint = Appointment::all( [
271 'posts_per_page' => $per_page,
272 'paged' => $paged,
273 'visibility' => $visibility,
274 'staff' => $staff,
275 ] );
276
277 $items = [];
278
279 foreach ( $appoint['items'] as $item ) {
280 $items[] = $this->prepare_item( $item->ID );
281 }
282
283 $data = [
284 'success' => 1,
285 'status' => 200,
286 'data' => [
287 'total' => $appoint['total'],
288 'items' => $items,
289 ],
290 ];
291
292 return rest_ensure_response( $data );
293 }
294
295 /**
296 * Create appointment
297 *
298 * @param WP_Rest_Request $request
299 *
300 * @return JSON Newly created appointment data
301 */
302 public function create_item( $request ) {
303 return $this->save_appointment( $request );
304 }
305
306 /**
307 * Update appointment
308 *
309 * @param WP_Rest_Request $request
310 *
311 * @return JSON Updated appointment data
312 */
313 public function update_item( $request ) {
314 $appointment_id = (int) $request['appointment_id'];
315 $appoint = new Appointment( $appointment_id );
316
317 if ( ! $appoint->is_appointment() ) {
318
319 $data = [
320 'success' => 0,
321 'status_code' => 404,
322 'message' => __( 'Invalid appointment id.', 'timetics' ),
323 'data' => [],
324 ];
325
326 return new WP_HTTP_Response( $data, 404 );
327 }
328
329 return $this->save_appointment( $request, $appointment_id );
330 }
331
332 /**
333 * Get single appointment
334 *
335 * @param WP_Rest_Requesr $request
336 *
337 * @return JSON Single appointment data
338 */
339 public function get_item( $request ) {
340 $appoinment_id = (int) $request['appointment_id'];
341 $appoint = new Appointment( $appoinment_id );
342
343 if ( ! $appoint->is_appointment() ) {
344
345 $data = [
346 'status_code' => 404,
347 'message' => __( 'Invalid appointment id.', 'timetics' ),
348 'data' => [],
349 ];
350
351 return new WP_HTTP_Response( $data, 404 );
352 }
353
354 $response = [
355 'status_code' => 200,
356 'message' => __( 'Successfully retrieved appointments', 'timetics' ),
357 'data' => $this->prepare_item( $appoint ),
358 ];
359
360 return rest_ensure_response( $response );
361 }
362
363 /**
364 * Delete single appointment
365 *
366 * @param WP_Rest_Request $request
367 *
368 * @return
369 */
370 public function delete_item( $request ) {
371 $appoinment_id = (int) $request['appointment_id'];
372 $appoint = new Appointment( $appoinment_id );
373
374 if ( ! $appoint->is_appointment() ) {
375 return [
376 'status_code' => 404,
377 'message' => __( 'Invalid appointment id.', 'timetics' ),
378 'data' => [],
379 ];
380 }
381
382 $appoint->delete();
383
384 $response = [
385 'status_code' => 201,
386 'message' => __( 'Successfully deleted appointment', 'timetics' ),
387 'data' => [
388 'item' => $appoinment_id,
389 ],
390 ];
391
392 return rest_ensure_response( $response );
393 }
394
395 /**
396 * Delete multiples
397 *
398 * @param WP_Rest_Request $request
399 *
400 * @return JSON
401 */
402 public function bulk_delete( $request ) {
403 $appointments = json_decode( $request->get_body(), true );
404
405 foreach ( $appointments as $appoint ) {
406 $appoint = new Appointment( $appoint );
407
408 if ( ! $appoint->is_appointment() ) {
409 $data = [
410 'success' => 0,
411 'status' => 404,
412 'message' => __( 'Invalid appointment id.', 'timetics' ),
413 'data' => [],
414 ];
415
416 return new WP_HTTP_Response( $data, 404 );
417 }
418
419 $appoint->delete();
420 }
421
422 return rest_ensure_response( [
423 'success' => 1,
424 'status' => 201,
425 'message' => __( 'Successfully deleted all appointments', 'timetics' ),
426 'data' => [
427 'items' => $appointments,
428 ],
429 ] );
430 }
431
432 /**
433 * Duplicate appointment
434 *
435 * @since 1.0.0
436 *
437 * @param object $request
438 *
439 * @return JSON
440 */
441 public function duplicate_item( $request ) {
442 $appoinment_id = (int) $request['appointment_id'];
443 $appoint = new Appointment( $appoinment_id );
444
445 if ( ! $appoint->is_appointment() ) {
446 return new WP_HTTP_Response(
447 [
448 'success' => 0,
449 'status_code' => 404,
450 'message' => __( 'Invalid appointment id.', 'timetics' ),
451 'data' => [],
452 ],
453 404
454 );
455 }
456
457 $appoint->duplicate();
458
459 $item = $this->prepare_item( $appoint );
460
461 $response = [
462 'success' => 1,
463 'status_code' => 201,
464 'message' => __( 'Successfully duplicated appointment', 'timetics' ),
465 'data' => $item,
466 ];
467
468 return rest_ensure_response( $response );
469 }
470
471 /**
472 * Save appointment
473 *
474 * @param WP_Rest_Request $request
475 * @param integer $id Appointment id
476 *
477 * @return JSON Updated appoitment data
478 */
479 public function save_appointment( $request, $id = 0 ) {
480 $appoint = new Appointment( $id );
481
482 $data = json_decode( $request->get_body(), true );
483
484 $data = apply_filters( 'timetics_meeting_data', $data );
485
486 $name = ! empty( $data['name'] ) ? sanitize_text_field( $data['name'] ) : $appoint->get_name();
487 $type = ! empty( $data['type'] ) ? sanitize_text_field( $data['type'] ) : $appoint->get_type();
488 $description = ! empty( $data['description'] ) ? sanitize_text_field( $data['description'] ) : '';
489 $staff = ! empty( $data['staff'] ) ? array_map( 'intval', $data['staff'] ) : $appoint->get_staff();
490 $locations = ! empty( $data['locations'] ) ? $data['locations'] : $appoint->get_locations();
491 $duration = ! empty( $data['duration'] ) ? sanitize_text_field( $data['duration'] ) : '';
492 $schedule = ! empty( $data['schedule'] ) ? $data['schedule'] : $appoint->get_schedule();
493 $price = ! empty( $data['price'] ) ? $data['price'] : '';
494 $categories = ! empty( $data['categories'] ) ? $data['categories'] : '';
495 $buffer_time = ! empty( $data['buffer_time'] ) ? $data['buffer_time'] : '';
496 $timezone = ! empty( $data['timezone'] ) ? $data['timezone'] : '';
497 $availability = ! empty( $data['availability'] ) ? $data['availability'] : '';
498 $visibility = ! empty( $data['visibility'] ) ? strtolower( $data['visibility'] ) : 'enabled';
499 $notifications = ! empty( $data['notifications'] ) ? $data['notifications'] : '';
500 $capacity = ! empty( $data['capacity'] ) ? intval( $data['capacity'] ) : 1;
501 $action = $id ? 'update' : 'created';
502
503 $validate_data = [
504 'name' => $name,
505 'type' => $type,
506 'locations' => $locations,
507 'schedule' => $schedule,
508 'staff' => $staff,
509
510 ];
511 // Validate input data.
512 $validate = $this->validate( $validate_data, [
513 'name',
514 'type',
515 'locations',
516 'schedule',
517 'staff',
518 ] );
519
520 if ( is_wp_error( $validate ) ) {
521 $data = [
522 'status_code' => 409,
523 'success' => 0,
524 'message' => $validate->get_error_messages(),
525 'data' => [],
526 ];
527
528 return new WP_HTTP_Response( $data, 409 );
529 }
530
531 // Save appointment.
532 $appointment_data = [
533 'name' => $name,
534 'description' => $description,
535 'type' => $type,
536 'locations' => $locations,
537 'staff' => $staff,
538 'duration' => $duration,
539 'price' => $price,
540 'capacity' => $capacity,
541 'schedule' => $schedule,
542 'categories' => $categories,
543 'timezone' => $timezone,
544 'availability' => $availability,
545 'visibility' => $visibility,
546 'buffer_time' => $buffer_time,
547 'notifications' => $notifications,
548 ];
549
550 $appointment_data = apply_filters( 'timetics_meeting_insert_data', $data, $appointment_data );
551
552 $appoint->set_props( $appointment_data );
553 $appoint->save();
554
555 do_action( 'timetics_meeting_after_insert', $appoint, $data );
556
557 // Prepare response data.
558 $item = $this->prepare_item( $appoint );
559
560 $response = [
561 'status_code' => 201,
562 'success' => 1,
563 'message' => sprintf( __( 'Succssfully %s appointment', 'timetics' ), $action ),
564 'data' => $item,
565 ];
566
567 return rest_ensure_response( $response );
568 }
569
570 /**
571 * Prepare item for response
572 *
573 * @param integer $appoinment_id
574 *
575 * @return array
576 */
577 public function prepare_item( $appoint_id ) {
578 $appointment = new Appointment( $appoint_id );
579 $dulicate = $appointment->get_duplicate_nuber();
580 $dulicate_text = $dulicate ? ' -Duplicate' : '';
581 $data = [
582 'id' => $appointment->get_id(),
583 'name' => $appointment->get_name() . $dulicate_text,
584 'image' => $appointment->get_image(),
585 // 'link' => $appointment->get_link(),
586 'description' => $appointment->get_description(),
587 'type' => $appointment->get_type(),
588 'locations' => $appointment->get_locations(),
589 'schedule' => $appointment->get_schedule(),
590 'price' => $appointment->get_price(),
591 'categories' => $appointment->get_categories(),
592 'staff' => $appointment->get_staff(),
593 'buffer_time' => $appointment->get_buffer_time(),
594 'timezone' => $appointment->get_timezone(),
595 'availability' => $appointment->get_availability(),
596 'visibility' => $appointment->get_visibility(),
597 'duration' => $appointment->get_duration(),
598 'notifications' => $appointment->get_notifications(),
599 'capacity' => $appointment->get_capacity(),
600 ];
601
602 return apply_filters( 'timetics_meeting_json_data', $data, $appointment );
603 }
604
605 }
606