PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.21
Timetics – Appointment Booking Calendar & Scheduling v1.0.21
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.21, at core/staffs/api-staff.php

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