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 +119 -21 1.0.11 → 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
@@ -44,11 +47,9 @@
44 47 $this->namespace, $this->rest_base, [
45 48 [
46 49 'methods' => \WP_REST_Server::READABLE,
47 50 'callback' => [$this, 'get_items'],
48 - 'permission_callback' => function () {
49 - return true;
50 - },
51 + 'permission_callback' => [$this, 'get_staffs_permission_callback'],
51 52 ],
52 53 [
53 54 'methods' => \WP_REST_Server::CREATABLE,
54 55 'callback' => [$this, 'create_item'],
@@ -59,9 +60,9 @@
59 60 [
60 61 'methods' => \WP_REST_Server::DELETABLE,
61 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 );
@@ -82,10 +83,10 @@
82 83 ],
83 84 [
84 85 'methods' => \WP_REST_Server::EDITABLE,
85 86 'callback' => [$this, 'update_item'],
86 - 'permission_callback' => function () {
87 - return current_user_can( 'manage_timetics' );
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,
@@ -90,21 +91,40 @@
90 91 [
91 92 'methods' => \WP_REST_Server::DELETABLE,
92 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 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 );
@@ -113,10 +133,10 @@
113 133 $this->namespace, $this->rest_base . '/(?P<staff_id>[\d]+)/integrations', [
114 134 [
115 135 'methods' => \WP_REST_Server::READABLE,
116 136 'callback' => [$this, 'get_integrations'],
117 - 'permission_callback' => function () {
118 - return current_user_can( 'edit_posts' );
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 );
@@ -125,15 +145,38 @@
125 145 $this->namespace, $this->rest_base . '/(?P<staff_id>[\d]+)/integrations/auth-revoke', [
126 146 [
127 147 'methods' => \WP_REST_Server::READABLE,
128 148 'callback' => [$this, 'auth_revoke'],
129 - 'permission_callback' => function () {
130 - return current_user_can( 'edit_posts' );
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
@@ -290,10 +333,10 @@
290 333 'message' => esc_html__( 'Something went wrong', 'timetics' ),
291 334 ];
292 335
293 336 if ( apply_filters( 'timetics/staff/members/count_check', false, $staff ) == true ) {
294 - return rest_ensure_response( apply_filters( 'timetics/admin/stuff/error_data', $response, 'count_check' ) );
295 - } // End.
337 + return new WP_HTTP_Response( apply_filters( 'timetics/admin/staff/error_data', $response, 'count_check' ), 403 );
338 + }
296 339
297 340 return $this->save_staff( $request );
298 341 }
299 342
@@ -317,8 +360,21 @@
317 360
318 361 return new WP_HTTP_Response( $data, 404 );
319 362 }
320 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 +
321 377 return $this->save_staff( $request, $staff_id );
322 378 }
323 379
324 380 /**
@@ -442,9 +498,8 @@
442 498
443 499 return new WP_HTTP_Response( $data, 404 );
444 500 }
445 501
446 - $token = timetics_get_google_access_token( $staff_id );
447 502 $client = new Client();
448 503
449 504 $revoked = false;
450 505
@@ -449,17 +504,31 @@
449 504 $revoked = false;
450 505
451 506 switch( $integration ) {
452 507 case 'google-auth':
453 - $revoked = $client->revoke( $token );
454 - if ( $revoked ) {
455 - update_user_meta( $staff_id, 'timetics_google_auth_code', '' );
508 + $refresh_token = timetics_get_google_refresh_token( $staff_id );
509 + if ( ! empty( $refresh_token ) ) {
510 + $client->revoke( $refresh_token );
456 511 }
512 +
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' );
518 +
519 + $revoked = true;
520 +
457 521 break;
458 522 case 'zoom-auth':
459 523 $revoked = true;
460 524 update_user_meta( $staff_id, 'timetics_zoom_token', '' );
461 525 break;
526 +
527 + case 'outlook-auth':
528 + $revoked = true;
529 + update_user_meta( $staff_id, 'timetics_outlook_token', '');
530 + break;
462 531 }
463 532
464 533 if ( ! $revoked ) {
465 534 $data = [
@@ -494,10 +563,11 @@
494 563 $email = ! empty( $data['email'] ) ? $data['email'] : '';
495 564 $phone = ! empty( $data['phone'] ) ? $data['phone'] : '';
496 565 $service = ! empty( $data['service'] ) ? $data['service'] : [];
497 566 $schedule = ! empty( $data['schedule'] ) ? $data['schedule'] : [];
498 - $image = ! empty( $data['image'] ) ? intval( $data['image'] ) : '';
567 + $image = ! empty( $data['image'] ) ? $data['image'] : '';
499 568 $password = ! empty( $data['password'] ) ? sanitize_text_field( $data['password'] ) : '';
569 + $current_password = ! empty( $data['current_password'] ) ? sanitize_text_field( $data['current_password'] ) : '';
500 570 $action = $id ? 'updated' : 'created';
501 571
502 572 // Validate input data.
503 573 $validate = $this->validate(
@@ -502,9 +572,8 @@
502 572 // Validate input data.
503 573 $validate = $this->validate(
504 574 $data, [
505 575 'first_name',
506 - 'last_name',
507 576 'email',
508 577 ]
509 578 );
510 579
@@ -533,8 +602,18 @@
533 602 'user_pass' => $password,
534 603 ];
535 604
536 605 if ( $id ) {
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 +
537 616 $staff_id = $staff->update( $args );
538 617 } else {
539 618 $staff_id = $staff->create( $args );
540 619 }
@@ -591,9 +670,28 @@
591 670 * @return array staff data
592 671 */
593 672 public function prepare_item( $staff ) {
594 673 $staff = new Staff( $staff );
674 + $data = $staff->get_data();
595 675
596 - 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;
597 681 }
598 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 + }
599 697 }