PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.64
Timetics – Appointment Booking Calendar & Scheduling v1.0.64
1.0.64 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 All 65 releases
← All changes | core/staffs/api-staff.php +184 -47 1.0.1 → 1.0.64 View file →
@@ -5,12 +5,15 @@
5 5 * @package Timetics
6 6 */
7 7 namespace Timetics\Core\Staffs;
8 8
9 +defined( 'ABSPATH' ) || exit;
10 +
9 11 use Timetics\Base\Api;
10 12 use Timetics\Core\Integrations\Google\Client;
11 13 use Timetics\Core\Staffs\Staff;
12 14 use Timetics\Utils\Singleton;
15 +use Timetics\Core\Emails\Re_Invite_Staff;
13 16 use WP_Error;
14 17 use WP_HTTP_Response;
15 18 use WP_User_Query;
16 19
@@ -43,16 +46,14 @@
43 46 register_rest_route(
44 47 $this->namespace, $this->rest_base, [
45 48 [
46 49 'methods' => \WP_REST_Server::READABLE,
47 - 'callback' => [ $this, 'get_items' ],
48 - 'permission_callback' => function () {
49 - return true;
50 - },
50 + 'callback' => [$this, 'get_items'],
51 + 'permission_callback' => [$this, 'get_staffs_permission_callback'],
51 52 ],
52 53 [
53 54 'methods' => \WP_REST_Server::CREATABLE,
54 - 'callback' => [ $this, 'create_item' ],
55 + 'callback' => [$this, 'create_item'],
55 56 'permission_callback' => function () {
56 57 return current_user_can( 'manage_timetics' );
57 58 },
58 59 ],
@@ -57,11 +58,11 @@
57 58 },
58 59 ],
59 60 [
60 61 'methods' => \WP_REST_Server::DELETABLE,
61 - 'callback' => [ $this, 'bulk_delete' ],
62 + 'callback' => [$this, 'bulk_delete'],
62 63 'permission_callback' => function () {
63 - return current_user_can( 'manage_timetics' );
64 + return current_user_can( 'manage_options' );
64 65 },
65 66 ],
66 67 ]
67 68 );
@@ -74,9 +75,9 @@
74 75 register_rest_route(
75 76 $this->namespace, '/' . $this->rest_base . '/(?P<staff_id>[\d]+)', [
76 77 [
77 78 'methods' => \WP_REST_Server::READABLE,
78 - 'callback' => [ $this, 'get_item' ],
79 + 'callback' => [$this, 'get_item'],
79 80 'permission_callback' => function () {
80 81 return true;
81 82 },
82 83 ],
@@ -81,30 +82,49 @@
81 82 },
82 83 ],
83 84 [
84 85 'methods' => \WP_REST_Server::EDITABLE,
85 - 'callback' => [ $this, 'update_item' ],
86 - 'permission_callback' => function () {
87 - return current_user_can( 'manage_timetics' );
86 + 'callback' => [$this, 'update_item'],
87 + 'permission_callback' => function ( $request ) {
88 + return current_user_can( 'manage_options' ) || (int) $request['staff_id'] === get_current_user_id();
88 89 },
89 90 ],
90 91 [
91 92 'methods' => \WP_REST_Server::DELETABLE,
92 - 'callback' => [ $this, 'delete_item' ],
93 + 'callback' => [$this, 'delete_item'],
93 94 'permission_callback' => function () {
94 - return current_user_can( 'manage_timetics' );
95 + return current_user_can( 'manage_options' );
95 96 },
96 97 ],
98 + [
99 + 'methods' => \WP_REST_Server::READABLE,
100 + 'callback' => [$this, 'get_item'],
101 + 'permission_callback' => function () {
102 + return true;
103 + },
104 + ],
97 105 ]
98 106 );
99 107
100 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 current_user_can( 'manage_options' );
115 + },
116 + ],
117 + ]
118 + );
119 +
120 + register_rest_route(
101 121 $this->namespace, $this->rest_base . '/search', [
102 122 [
103 123 'methods' => \WP_REST_Server::READABLE,
104 - 'callback' => [ $this, 'search_items' ],
124 + 'callback' => [$this, 'search_items'],
105 125 'permission_callback' => function () {
106 - return current_user_can( 'edit_posts' );
126 + return current_user_can( 'manage_timetics' );
107 127 },
108 128 ],
109 129 ]
110 130 );
@@ -112,11 +132,11 @@
112 132 register_rest_route(
113 133 $this->namespace, $this->rest_base . '/(?P<staff_id>[\d]+)/integrations', [
114 134 [
115 135 'methods' => \WP_REST_Server::READABLE,
116 - 'callback' => [ $this, 'get_integrations' ],
117 - 'permission_callback' => function () {
118 - return current_user_can( 'edit_posts' );
136 + 'callback' => [$this, 'get_integrations'],
137 + 'permission_callback' => function ( $request ) {
138 + return current_user_can( 'manage_options' ) || (int) $request['staff_id'] === get_current_user_id();
119 139 },
120 140 ],
121 141 ]
122 142 );
@@ -124,16 +144,39 @@
124 144 register_rest_route(
125 145 $this->namespace, $this->rest_base . '/(?P<staff_id>[\d]+)/integrations/auth-revoke', [
126 146 [
127 147 'methods' => \WP_REST_Server::READABLE,
128 - 'callback' => [ $this, 'auth_revoke' ],
129 - 'permission_callback' => function () {
130 - return current_user_can( 'edit_posts' );
148 + 'callback' => [$this, 'auth_revoke'],
149 + 'permission_callback' => function ( $request ) {
150 + return current_user_can( 'manage_options' ) || (int) $request['staff_id'] === get_current_user_id();
131 151 },
132 152 ],
133 153 ]
134 154 );
135 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 +
136 179 /**
137 180 * Get all appointments
138 181 *
139 182 * @param WP_Rest_Request $request
@@ -156,8 +199,13 @@
156 199 foreach ( $staff['items'] as $item ) {
157 200 $items[] = $this->prepare_item( $item->ID );
158 201 }
159 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 +
160 208 $data = [
161 209 'success' => 1,
162 210 'data' => [
163 211 'total' => $staff['total'],
@@ -181,9 +229,9 @@
181 229
182 230 if ( ! $staff->is_staff() ) {
183 231 return [
184 232 'status_code' => 404,
185 - 'message' => __( 'Invalid staff id.', 'timetics' ),
233 + 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
186 234 'data' => [],
187 235 ];
188 236 }
189 237
@@ -273,8 +321,23 @@
273 321 *
274 322 * @return JSON | WP_Error
275 323 */
276 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 +
277 340 return $this->save_staff( $request );
278 341 }
279 342
280 343 /**
@@ -290,9 +353,9 @@
290 353
291 354 if ( ! $staff->is_staff() ) {
292 355 $data = [
293 356 'status_code' => 404,
294 - 'message' => __( 'Invalid staff id.', 'timetics' ),
357 + 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
295 358 'data' => [],
296 359 ];
297 360
298 361 return new WP_HTTP_Response( $data, 404 );
@@ -297,8 +360,21 @@
297 360
298 361 return new WP_HTTP_Response( $data, 404 );
299 362 }
300 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 +
301 377 return $this->save_staff( $request, $staff_id );
302 378 }
303 379
304 380 /**
@@ -314,9 +390,9 @@
314 390
315 391 if ( ! $staff->is_staff() ) {
316 392 $data = [
317 393 'status_code' => 404,
318 - 'message' => __( 'Invalid staff id.', 'timetics' ),
394 + 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
319 395 'data' => [],
320 396 ];
321 397
322 398 return new WP_HTTP_Response( $data, 404 );
@@ -325,9 +401,9 @@
325 401 $staff->delete();
326 402
327 403 $response = [
328 404 'status_code' => 200,
329 - 'message' => __( 'Successfully deleted staff', 'timetics' ),
405 + 'message' => esc_html__( 'Successfully deleted staff', 'timetics' ),
330 406 'data' => [],
331 407 ];
332 408
333 409 return rest_ensure_response( $response );
@@ -349,9 +425,9 @@
349 425 if ( ! $staff->is_staff() ) {
350 426 $data = [
351 427 'success' => 1,
352 428 'status' => 404,
353 - 'message' => __( 'Invalid staff id.', 'timetics' ),
429 + 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
354 430 'data' => [],
355 431 ];
356 432
357 433 return new WP_HTTP_Response( $data, 404 );
@@ -359,12 +435,17 @@
359 435
360 436 $staff->delete();
361 437 }
362 438
439 + /**
440 + * Added temporary for leagacy sass. It will remove in future.
441 + */
442 + do_action( 'timetics/admin/staff/bulk_delete', $staffs );
443 +
363 444 return [
364 445 'success' => 1,
365 446 'status' => 200,
366 - 'message' => __( 'Successfully deleted staff', 'timetics' ),
447 + 'message' => esc_html__( 'Successfully deleted staff', 'timetics' ),
367 448 'data' => [
368 449 'items' => $staffs,
369 450 ],
370 451 ];
@@ -383,9 +464,9 @@
383 464
384 465 if ( ! $staff->is_staff() ) {
385 466 $data = [
386 467 'status_code' => 404,
387 - 'message' => __( 'Invalid staff id.', 'timetics' ),
468 + 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
388 469 'data' => [],
389 470 ];
390 471
391 472 return new WP_HTTP_Response( $data, 404 );
@@ -410,9 +491,9 @@
410 491
411 492 if ( ! $staff->is_staff() ) {
412 493 $data = [
413 494 'status_code' => 404,
414 - 'message' => __( 'Invalid staff id.', 'timetics' ),
495 + 'message' => esc_html__( 'Invalid staff id.', 'timetics' ),
415 496 'data' => [],
416 497 ];
417 498
418 499 return new WP_HTTP_Response( $data, 404 );
@@ -417,31 +498,53 @@
417 498
418 499 return new WP_HTTP_Response( $data, 404 );
419 500 }
420 501
421 - $token = timetics_get_google_access_token( $staff_id );
422 502 $client = new Client();
423 503
424 - if ( 'google-auth' === $integration ) {
425 - $revoked = $client->revoke( $token );
504 + $revoked = false;
426 505
427 - if ( ! $revoked ) {
428 - $data = [
429 - 'success' => 0,
430 - 'status_code' => 409,
431 - 'message' => __( 'Something went wrong, please try again', 'timetics' ),
432 - ];
506 + switch( $integration ) {
507 + case 'google-auth':
508 + $refresh_token = timetics_get_google_refresh_token( $staff_id );
509 + if ( ! empty( $refresh_token ) ) {
510 + $client->revoke( $refresh_token );
511 + }
433 512
434 - return new WP_HTTP_Response( $data, 409 );
435 - }
513 + // Always clear ALL local Google credentials so the account can be reconnected cleanly.
514 + delete_user_meta( $staff_id, 'timetics_google_auth' );
515 + delete_user_meta( $staff_id, 'timetics_google_refresh_token' );
516 + delete_user_meta( $staff_id, 'timetics_google_auth_code' );
517 + delete_user_meta( $staff_id, 'timetics_google_auth_error' );
436 518
437 - update_user_meta( $staff_id, 'timetics_google_auth_code', '' );
519 + $revoked = true;
520 +
521 + break;
522 + case 'zoom-auth':
523 + $revoked = true;
524 + update_user_meta( $staff_id, 'timetics_zoom_token', '' );
525 + break;
526 +
527 + case 'outlook-auth':
528 + $revoked = true;
529 + update_user_meta( $staff_id, 'timetics_outlook_token', '');
530 + break;
438 531 }
439 532
533 + if ( ! $revoked ) {
534 + $data = [
535 + 'success' => 0,
536 + 'status_code' => 409,
537 + 'message' => esc_html__( 'Something went wrong, please try again', 'timetics' ),
538 + ];
539 +
540 + return new WP_HTTP_Response( $data, 409 );
541 + }
542 +
440 543 return [
441 544 'success' => 1,
442 545 'status_code' => 200,
443 - 'message' => __( 'Successfully disconnected', 'timetics' ),
546 + 'message' => esc_html__( 'Successfully disconnected', 'timetics' ),
444 547 ];
445 548 }
446 549
447 550 /**
@@ -460,10 +563,11 @@
460 563 $email = ! empty( $data['email'] ) ? $data['email'] : '';
461 564 $phone = ! empty( $data['phone'] ) ? $data['phone'] : '';
462 565 $service = ! empty( $data['service'] ) ? $data['service'] : [];
463 566 $schedule = ! empty( $data['schedule'] ) ? $data['schedule'] : [];
464 - $image = ! empty( $data['image'] ) ? intval( $data['image'] ) : '';
567 + $image = ! empty( $data['image'] ) ? $data['image'] : '';
465 568 $password = ! empty( $data['password'] ) ? sanitize_text_field( $data['password'] ) : '';
569 + $current_password = ! empty( $data['current_password'] ) ? sanitize_text_field( $data['current_password'] ) : '';
466 570 $action = $id ? 'updated' : 'created';
467 571
468 572 // Validate input data.
469 573 $validate = $this->validate(
@@ -468,9 +572,8 @@
468 572 // Validate input data.
469 573 $validate = $this->validate(
470 574 $data, [
471 575 'first_name',
472 - 'last_name',
473 576 'email',
474 577 ]
475 578 );
476 579
@@ -499,9 +602,19 @@
499 602 'user_pass' => $password,
500 603 ];
501 604
502 605 if ( $id ) {
503 - $staff_id = $staff->update( $args );
606 + if ( $password && ! wp_check_password( $current_password, $staff->get_password(), $id ) ) {
607 + $data = [
608 + 'success' => 0,
609 + 'status_code' => 409,
610 + 'message' => esc_html__( 'Current password does not match', 'timetics' ),
611 + ];
612 +
613 + return new WP_HTTP_Response( $data, 400 );
614 + }
615 +
616 + $staff_id = $staff->update( $args );
504 617 } else {
505 618 $staff_id = $staff->create( $args );
506 619 }
507 620
@@ -515,13 +628,18 @@
515 628 }
516 629 // Prepare for response.
517 630 $item = $this->prepare_item( $staff );
518 631
632 + /**
633 + * Added temporary for leagacy sass. It will remove in future.
634 + */
635 + do_action( 'timetics/admin/staff/create_item', $item );
636 +
519 637 $data = [
520 638 'success' => 1,
521 639 'status' => 200,
522 640 /* translators: Action */
523 - 'message' => sprintf( __( 'Successfully %s staff', 'timetics' ), $action ),
641 + 'message' => sprintf( esc_html__( 'Successfully %s staff', 'timetics' ), $action ),
524 642 'data' => $item,
525 643 ];
526 644
527 645 return rest_ensure_response( $data );
@@ -552,9 +670,28 @@
552 670 * @return array staff data
553 671 */
554 672 public function prepare_item( $staff ) {
555 673 $staff = new Staff( $staff );
674 + $data = $staff->get_data();
556 675
557 - return $staff->get_data();
676 + if ( ! current_user_can( 'manage_timetics' ) ) {
677 + unset( $data['email'], $data['phone'], $data['user_name'] );
678 + }
679 +
680 + return $data;
558 681 }
559 682
683 + /**
684 + * Get items permission callback
685 + *
686 + * @param WP_Rest_Request $request
687 + *
688 + * @return boolean true if user has permission, false otherwise
689 + */
690 + public function get_staffs_permission_callback($request){
691 + $nonce = $request->get_header('X-WP-Nonce');
692 + if (wp_verify_nonce($nonce, 'wp_rest') && ( current_user_can( 'manage_timetics' ) || current_user_can( 'manage_options' ) ) ) {
693 + return true;
694 + }
695 + return false;
696 + }
560 697 }