PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.60
Timetics – Appointment Booking Calendar & Scheduling v1.0.60
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 / staffs / api-staff.php

api-staff.php in Timetics – Appointment Booking Calendar & Scheduling 1.0.60, at core/staffs/api-staff.php

689 lines 20.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Api Staff
4 *
5 * @package Timetics
6 */
7 namespace Timetics\Core\Staffs;
8
9 use Timetics\Base\Api;
10 use Timetics\Core\Integrations\Google\Client;
11 use Timetics\Core\Staffs\Staff;
12 use Timetics\Utils\Singleton;
13 use Timetics\Core\Emails\Re_Invite_Staff;
14 use WP_Error;
15 use WP_HTTP_Response;
16 use WP_User_Query;
17
18 /**
19 * Class Api_Staff
20 */
21 class Api_Staff extends Api {
22 use Singleton;
23
24 /**
25 * Store namespace
26 *
27 * @var string
28 */
29 protected $namespace = 'timetics/v1';
30
31 /**
32 * Store rest base
33 *
34 * @var string
35 */
36 protected $rest_base = 'staffs';
37
38 /**
39 * Register rest route
40 *
41 * @return void
42 */
43 public function register_routes() {
44 register_rest_route(
45 $this->namespace, $this->rest_base, [
46 [
47 'methods' => \WP_REST_Server::READABLE,
48 'callback' => [$this, 'get_items'],
49 'permission_callback' => [$this, 'get_staffs_permission_callback'],
50 ],
51 [
52 'methods' => \WP_REST_Server::CREATABLE,
53 'callback' => [$this, 'create_item'],
54 'permission_callback' => function () {
55 return current_user_can( 'manage_timetics' );
56 },
57 ],
58 [
59 'methods' => \WP_REST_Server::DELETABLE,
60 'callback' => [$this, 'bulk_delete'],
61 'permission_callback' => function () {
62 return current_user_can( 'manage_timetics' );
63 },
64 ],
65 ]
66 );
67
68 /**
69 * Register route
70 *
71 * @var void
72 */
73 register_rest_route(
74 $this->namespace, '/' . $this->rest_base . '/(?P<staff_id>[\d]+)', [
75 [
76 'methods' => \WP_REST_Server::READABLE,
77 'callback' => [$this, 'get_item'],
78 'permission_callback' => function () {
79 return true;
80 },
81 ],
82 [
83 'methods' => \WP_REST_Server::EDITABLE,
84 'callback' => [$this, 'update_item'],
85 'permission_callback' => function () {
86 return current_user_can( 'manage_timetics' );
87 },
88 ],
89 [
90 'methods' => \WP_REST_Server::DELETABLE,
91 'callback' => [$this, 'delete_item'],
92 'permission_callback' => function () {
93 return current_user_can( 'manage_timetics' );
94 },
95 ],
96 [
97 'methods' => \WP_REST_Server::READABLE,
98 'callback' => [$this, 'get_item'],
99 'permission_callback' => function () {
100 return true;
101 },
102 ],
103 ]
104 );
105
106 register_rest_route(
107 $this->namespace, $this->rest_base . '/re-invite'. '/(?P<staff_id>[\d]+)', [
108 [
109 'methods' => \WP_REST_Server::READABLE,
110 'callback' => [$this, 're_invite_staff'],
111 'permission_callback' => function () {
112 return current_user_can( 'manage_timetics' );
113 },
114 ],
115 ]
116 );
117
118 register_rest_route(
119 $this->namespace, $this->rest_base . '/search', [
120 [
121 'methods' => \WP_REST_Server::READABLE,
122 'callback' => [$this, 'search_items'],
123 'permission_callback' => function () {
124 return current_user_can( 'manage_timetics' );
125 },
126 ],
127 ]
128 );
129
130 register_rest_route(
131 $this->namespace, $this->rest_base . '/(?P<staff_id>[\d]+)/integrations', [
132 [
133 'methods' => \WP_REST_Server::READABLE,
134 'callback' => [$this, 'get_integrations'],
135 'permission_callback' => function () {
136 return current_user_can( 'manage_timetics' );
137 },
138 ],
139 ]
140 );
141
142 register_rest_route(
143 $this->namespace, $this->rest_base . '/(?P<staff_id>[\d]+)/integrations/auth-revoke', [
144 [
145 'methods' => \WP_REST_Server::READABLE,
146 'callback' => [$this, 'auth_revoke'],
147 'permission_callback' => function () {
148 return current_user_can( 'manage_timetics' );
149 },
150 ],
151 ]
152 );
153 }
154
155 public function re_invite_staff( $request ) {
156 $id = ! empty( $request['staff_id'] ) ? intval( $request['staff_id'] ) : null ;
157 $success = true;
158 $message = esc_html__("Invitation Email send successfully","timetics");
159 if ( empty( $id ) ) {
160 $success = true;
161 $message = esc_html__("Staff ID missing","timetics");
162 }
163 $re_invite_staff = new Re_Invite_Staff( $id );
164 $re_invite_staff->send();
165
166 $data = [
167 'success' => 1,
168 'message' => $message,
169 'data' => [
170 'sent' => $success,
171 ]
172 ];
173
174 return rest_ensure_response( $data );
175 }
176
177 /**
178 * Get all appointments
179 *
180 * @param WP_Rest_Request $request
181 *
182 * @return JSON
183 */
184 public function get_items( $request ) {
185 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
186 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
187
188 $staff = Staff::all(
189 [
190 'number' => $per_page,
191 'paged' => $paged,
192 ]
193 );
194
195 $items = [];
196
197 foreach ( $staff['items'] as $item ) {
198 $items[] = $this->prepare_item( $item->ID );
199 }
200
201 /**
202 * Added temporary for leagacy sass. It will remove in future.
203 */
204 $items = apply_filters( 'timetics/admin/staff/get_items', $items );
205
206 $data = [
207 'success' => 1,
208 'data' => [
209 'total' => $staff['total'],
210 'items' => $items,
211 ],
212 ];
213
214 return rest_ensure_response( $data );
215 }
216
217 /**
218 * Get single staff
219 *
220 * @param WP_Rest_Requesr $request
221 *
222 * @return JSON Single staff data
223 */
224 public function get_item( $request ) {
225 $staff_id = (int) $request['staff_id'];
226 $staff = new Staff( $staff_id );
227
228 if ( ! $staff->is_staff() ) {
229 return [
230 'status_code' => 404,
231 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
232 'data' => [],
233 ];
234 }
235
236 $response = [
237 'status_code' => 200,
238 'data' => $this->prepare_item( $staff ),
239 ];
240
241 return rest_ensure_response( $response );
242 }
243
244 /**
245 * Search staff
246 *
247 * @return JSON
248 */
249 public function search_items( $request ) {
250
251 // Prepare search args.
252 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
253 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
254 $search = ! empty( $request['search'] ) ? sanitize_text_field( $request['search'] ) : '';
255
256 // Get search.
257 $users = new WP_User_Query(
258 array(
259 'role' => 'timetics-staff',
260 'number' => $per_page,
261 'paged' => $paged,
262
263 // @codingStandardsIgnoreStart
264 'meta_query' => array(
265 'relation' => 'OR',
266 array(
267 'key' => 'first_name',
268 'value' => $search,
269 'compare' => 'LIKE',
270 ),
271 array(
272 'key' => 'last_name',
273 'value' => $search,
274 'compare' => 'LIKE',
275 ),
276 array(
277 'key' => '_staff_email',
278 'value' => $search,
279 'compare' => 'LIKE',
280 ),
281 array(
282 'key' => '_staff_user_name',
283 'value' => $search,
284 'compare' => 'LIKE',
285 ),
286 array(
287 'key' => '_staff_phone',
288 'value' => $search,
289 'compare' => 'LIKE',
290 ),
291 ),
292 // @codingStandardsIgnoreEnd
293 )
294 );
295
296 // Prepare items for response.
297 $items = [];
298
299 foreach ( $users->get_results() as $item ) {
300 $items[] = $this->prepare_item( $item->ID );
301 }
302
303 $data = [
304 'success' => 1,
305 'status' => 200,
306 'data' => [
307 'total' => $users->get_total(),
308 'items' => $items,
309 ],
310 ];
311
312 return rest_ensure_response( $data );
313 }
314
315 /**
316 * Create staff
317 *
318 * @param WP_Rest_Request $request
319 *
320 * @return JSON | WP_Error
321 */
322 public function create_item( $request ) {
323 /**
324 * Added temporary for leagacy sass. It will remove in future.
325 */
326 $staff = Staff::all();
327
328 $response = [
329 'status_code' => 502,
330 'success' => 0,
331 'message' => esc_html__( 'Something went wrong', 'timetics' ),
332 ];
333
334 if ( apply_filters( 'timetics/staff/members/count_check', false, $staff ) == true ) {
335 return new WP_HTTP_Response( apply_filters( 'timetics/admin/staff/error_data', $response, 'count_check' ), 403 );
336 }
337
338 return $this->save_staff( $request );
339 }
340
341 /**
342 * Update staff
343 *
344 * @param WP_Rest_Request $request
345 *
346 * @return JSON | WP_Error
347 */
348 public function update_item( $request ) {
349 $staff_id = (int) $request['staff_id'];
350 $staff = new Staff( $staff_id );
351
352 if ( ! $staff->is_staff() ) {
353 $data = [
354 'status_code' => 404,
355 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
356 'data' => [],
357 ];
358
359 return new WP_HTTP_Response( $data, 404 );
360 }
361
362 $payload = json_decode( $request->get_body(), true );
363
364 if ( !empty($payload['schedule']) && $payload['schedule'] && apply_filters('timetics/staff/member/availability', false)) {
365
366 $response = [
367 'status_code' => 502,
368 'success' => 0,
369 'message' => esc_html__( 'Something went wrong', 'timetics' ),
370 ];
371
372 return new WP_HTTP_Response( apply_filters( 'timetics/admin/staff/error_data', $response, 'availability_update' ), 403 );
373 }
374
375 return $this->save_staff( $request, $staff_id );
376 }
377
378 /**
379 * Delete staff
380 *
381 * @param WP_Rest_Request $request
382 *
383 * @return JSON
384 */
385 public function delete_item( $request ) {
386 $staff_id = (int) $request['staff_id'];
387 $staff = new Staff( $staff_id );
388
389 if ( ! $staff->is_staff() ) {
390 $data = [
391 'status_code' => 404,
392 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
393 'data' => [],
394 ];
395
396 return new WP_HTTP_Response( $data, 404 );
397 }
398
399 $staff->delete();
400
401 $response = [
402 'status_code' => 200,
403 'message' => esc_html__( 'Successfully deleted staff', 'timetics' ),
404 'data' => [],
405 ];
406
407 return rest_ensure_response( $response );
408 }
409
410 /**
411 * Delete multiples
412 *
413 * @param WP_Rest_Request $request
414 *
415 * @return JSON
416 */
417 public function bulk_delete( $request ) {
418 $staffs = json_decode( $request->get_body(), true );
419
420 foreach ( $staffs as $staff ) {
421 $staff = new Staff( $staff );
422
423 if ( ! $staff->is_staff() ) {
424 $data = [
425 'success' => 1,
426 'status' => 404,
427 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
428 'data' => [],
429 ];
430
431 return new WP_HTTP_Response( $data, 404 );
432 }
433
434 $staff->delete();
435 }
436
437 /**
438 * Added temporary for leagacy sass. It will remove in future.
439 */
440 do_action( 'timetics/admin/staff/bulk_delete', $staffs );
441
442 return [
443 'success' => 1,
444 'status' => 200,
445 'message' => esc_html__( 'Successfully deleted staff', 'timetics' ),
446 'data' => [
447 'items' => $staffs,
448 ],
449 ];
450 }
451
452 /**
453 * Get staff integrations
454 *
455 * @param WP_Rest_Request $request
456 *
457 * @return JSON
458 */
459 public function get_integrations( $request ) {
460 $staff_id = (int) $request['staff_id'];
461 $staff = new Staff( $staff_id );
462
463 if ( ! $staff->is_staff() ) {
464 $data = [
465 'status_code' => 404,
466 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
467 'data' => [],
468 ];
469
470 return new WP_HTTP_Response( $data, 404 );
471 }
472
473 $integrations = timetics_get_staff_integrations( $staff_id );
474
475 return rest_ensure_response( $integrations );
476 }
477
478 /**
479 * Remove staff authentication for integrations
480 *
481 * @param WP_Rest_Request $request
482 *
483 * @return JSON
484 */
485 public function auth_revoke( $request ) {
486 $staff_id = (int) $request['staff_id'];
487 $staff = new Staff( $staff_id );
488 $integration = ! empty( $request['integration_name'] ) ? sanitize_text_field( $request['integration_name'] ) : '';
489
490 if ( ! $staff->is_staff() ) {
491 $data = [
492 'status_code' => 404,
493 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
494 'data' => [],
495 ];
496
497 return new WP_HTTP_Response( $data, 404 );
498 }
499
500 $token = timetics_get_google_access_token( $staff_id );
501 $client = new Client();
502
503 $revoked = false;
504
505 switch( $integration ) {
506 case 'google-auth':
507 $revoked = $client->revoke( $token );
508 if ( $revoked ) {
509 update_user_meta( $staff_id, 'timetics_google_auth', '' );
510 }
511
512 break;
513 case 'zoom-auth':
514 $revoked = true;
515 update_user_meta( $staff_id, 'timetics_zoom_token', '' );
516 break;
517
518 case 'outlook-auth':
519 $revoked = true;
520 update_user_meta( $staff_id, 'timetics_outlook_token', '');
521 break;
522 }
523
524 if ( ! $revoked ) {
525 $data = [
526 'success' => 0,
527 'status_code' => 409,
528 'message' => esc_html__( 'Something went wrong, please try again', 'timetics' ),
529 ];
530
531 return new WP_HTTP_Response( $data, 409 );
532 }
533
534 return [
535 'success' => 1,
536 'status_code' => 200,
537 'message' => esc_html__( 'Successfully disconnected', 'timetics' ),
538 ];
539 }
540
541 /**
542 * Save staff
543 *
544 * @param WP_Rest_Request $request
545 * @param integer $id [$id description]
546 *
547 * @return JSON | WP_Error
548 */
549 public function save_staff( $request, $id = 0 ) {
550 $data = json_decode( $request->get_body(), true );
551
552 $first_name = ! empty( $data['first_name'] ) ? sanitize_text_field( $data['first_name'] ) : '';
553 $last_name = ! empty( $data['last_name'] ) ? sanitize_text_field( $data['last_name'] ) : '';
554 $email = ! empty( $data['email'] ) ? $data['email'] : '';
555 $phone = ! empty( $data['phone'] ) ? $data['phone'] : '';
556 $service = ! empty( $data['service'] ) ? $data['service'] : [];
557 $schedule = ! empty( $data['schedule'] ) ? $data['schedule'] : [];
558 $image = ! empty( $data['image'] ) ? $data['image'] : '';
559 $password = ! empty( $data['password'] ) ? sanitize_text_field( $data['password'] ) : '';
560 $current_password = ! empty( $data['current_password'] ) ? sanitize_text_field( $data['current_password'] ) : '';
561 $action = $id ? 'updated' : 'created';
562
563 // Validate input data.
564 $validate = $this->validate(
565 $data, [
566 'first_name',
567 'email',
568 ]
569 );
570
571 if ( is_wp_error( $validate ) ) {
572 $data = [
573 'success' => 0,
574 'status_code' => 409,
575 'message' => $validate->get_error_messages(),
576 'data' => [],
577 ];
578
579 return new WP_HTTP_Response( $data, 409 );
580 }
581
582 // Save staff data.
583 $staff = new Staff( $id );
584
585 $args = [
586 'first_name' => $first_name,
587 'last_name' => $last_name,
588 'user_email' => $email,
589 'user_login' => $this->generate_username( $email ),
590 'phone' => $phone,
591 'image' => $image,
592 'schedule' => $schedule,
593 'user_pass' => $password,
594 ];
595
596 if ( $id ) {
597 if ( $password && ! wp_check_password( $current_password, $staff->get_password(), $id ) ) {
598 $data = [
599 'success' => 0,
600 'status_code' => 409,
601 'message' => esc_html__( 'Current password does not match', 'timetics' ),
602 ];
603
604 return new WP_HTTP_Response( $data, 400 );
605 }
606
607 $staff_id = $staff->update( $args );
608 } else {
609 $staff_id = $staff->create( $args );
610 }
611
612 if ( is_wp_error( $staff_id ) ) {
613 return [
614 'success' => 0,
615 'status' => 409,
616 'message' => $staff_id->get_error_message(),
617 'data' => [],
618 ];
619 }
620 // Prepare for response.
621 $item = $this->prepare_item( $staff );
622
623 /**
624 * Added temporary for leagacy sass. It will remove in future.
625 */
626 do_action( 'timetics/admin/staff/create_item', $item );
627
628 $data = [
629 'success' => 1,
630 'status' => 200,
631 /* translators: Action */
632 'message' => sprintf( esc_html__( 'Successfully %s staff', 'timetics' ), $action ),
633 'data' => $item,
634 ];
635
636 return rest_ensure_response( $data );
637 }
638
639 /**
640 * Generate username from email
641 *
642 * @param string $email
643 *
644 * @return string
645 */
646 public function generate_username( $email ) {
647 $username = strtok( $email, '@' );
648
649 if ( username_exists( $username ) ) {
650 $username = $username . wp_rand( 10, 100 );
651 }
652
653 return $username;
654 }
655
656 /**
657 * Prepare item
658 *
659 * @param integer | Staff $staff_id Staff Id
660 *
661 * @return array staff data
662 */
663 public function prepare_item( $staff ) {
664 $staff = new Staff( $staff );
665 $data = $staff->get_data();
666
667 if ( ! current_user_can( 'manage_timetics' ) ) {
668 unset( $data['email'], $data['phone'], $data['user_name'] );
669 }
670
671 return $data;
672 }
673
674 /**
675 * Get items permission callback
676 *
677 * @param WP_Rest_Request $request
678 *
679 * @return boolean true if user has permission, false otherwise
680 */
681 public function get_staffs_permission_callback($request){
682 $nonce = $request->get_header('X-WP-Nonce');
683 if (wp_verify_nonce($nonce, 'wp_rest') && ( current_user_can( 'manage_timetics' ) || current_user_can( 'manage_options' ) ) ) {
684 return true;
685 }
686 return false;
687 }
688 }
689