PluginProbe
Bookit — Booking & Appointment Calendar / 2.6.0.5
Bookit — Booking & Appointment Calendar v2.6.0.5
2.6.0.5 2.6.0.4 2.6.0.3 2.6.0.2 2.6.0.1 2.6.0 trunk 1.2 1.2.2 1.2.3 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 All 62 releases
bookit / includes / classes / admin / StaffController.php

StaffController.php in Bookit — Booking & Appointment Calendar 2.6.0.5, at includes/classes/admin/StaffController.php

406 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Bookit\Classes\Admin;
4
5 use Bookit\Classes\Base\Plugin;
6 use Bookit\Classes\Base\User;
7 use Bookit\Classes\Database\Appointments;
8 use Bookit\Classes\Database\Customers;
9 use Bookit\Classes\Database\Services;
10 use Bookit\Classes\Database\Staff;
11 use Bookit\Classes\Database\Staff_Services;
12 use Bookit\Classes\Database\Staff_Working_Hours;
13 use Bookit\Classes\Template;
14 use Bookit\Helpers\CleanHelper;
15
16 class StaffController extends DashboardController {
17
18 private static function getCleanRules() {
19 return array(
20 'id' => array( 'type' => 'intval' ),
21 'limit' => array( 'type' => 'intval' ),
22 'offset' => array( 'type' => 'intval' ),
23 'email' => array( 'type' => 'strval' ),
24 'full_name' => array( 'type' => 'strval' ),
25 'phone' => array(
26 'function' => array(
27 'custom' => true,
28 'name' => 'custom_sanitize_phone',
29 ),
30 ),
31 );
32 }
33 /**
34 * Display Rendered Template
35 * @return bool|string
36 */
37 public static function render() {
38
39 $bookitUser = self::bookitUser();
40
41 /** show just self if this staff */
42 if ( true == $bookitUser['is_staff'] ) {
43 $staff = $bookitUser['staff'];
44 } else {
45 $staff = Staff::get_all();
46 }
47
48 $services = Services::get_all_short();
49 $wp_users = get_users(
50 array(
51 'fields' => array( 'ID', 'display_name', 'user_email' ),
52 'role__not_in' => array( 'administrator' ),
53 )
54 );
55
56 $addons = array();
57 $answer = array();
58 $installed = Plugin::isAddonInstalledAndEnabled( self::$proAddon );
59 /** if google calendar addon is installed */
60 if ( Plugin::isAddonInstalledAndEnabled( self::$proAddon ) && has_filter( 'bookit_filter_connect_staff_google_calendar' ) ) {
61 $addons[] = Plugin::getAddonInfo( self::$proAddon );
62 $gcFilterResult = apply_filters( 'bookit_filter_connect_staff_google_calendar', $staff );
63 $staff = $gcFilterResult['staff'];
64 if ( array_key_exists( 'answer', $gcFilterResult ) ) {
65 $answer = $gcFilterResult['answer'];
66 }
67 }
68 /** if google calendar addon is installed | end */
69
70 self::enqueue_styles_scripts();
71
72 return Template::load_template(
73 'dashboard/bookit-staff',
74 array(
75 'staff' => self::parseStaff( $staff ),
76 'services' => $services,
77 'addons' => $addons,
78 'answer' => $answer,
79 'wp_users' => $wp_users,
80 'page' => __( 'Staff', 'bookit' ),
81 ),
82 true
83 );
84 }
85
86
87 /**
88 * Parsers and sanitizes staff data to array.
89 *
90 * @since 1.0.0
91 *
92 * @param array<int, array<string, mixed>> $staff Staff data to parse.
93 *
94 * @return array<int, array<string, mixed>>
95 */
96 public static function parseStaff( $staff ) {
97 $result = array();
98 foreach ( $staff as $key => $employee ) {
99 $item = (array) $employee;
100 $item['full_name'] = stripslashes( $employee['full_name'] );
101 $item['staff_services'] = json_decode( $employee['staff_services'] ?? '', true ) ?: [];
102 $item['working_hours'] = json_decode( $employee['working_hours'] ?? '', true ) ?: [];
103
104 // Ensure gc_token is always an object with auth_url property to prevent frontend errors.
105 if (
106 ! isset( $item['gc_token'] )
107 || null === $item['gc_token']
108 || ! is_array( $item['gc_token'] )
109 ) {
110 $item['gc_token'] = [
111 'auth_url' => '',
112 ];
113 } elseif ( ! isset( $item['gc_token']['auth_url'] ) ) {
114 $item['gc_token']['auth_url'] = '';
115 }
116
117 array_push( $result, $item );
118 }
119 unset( $staff );
120 return $result;
121 }
122
123 /**
124 * Get Staff with Pagination
125 */
126 public static function get_staff() {
127
128 $data = CleanHelper::cleanData( $_GET, self::getCleanRules() );
129
130 if ( ! empty( $data['limit'] ) ) {
131 $response['staff'] = Staff::get_paged( $data['limit'], $data['offset'] );
132 $response['total'] = Staff::get_count();
133
134 wp_send_json_success( $response );
135 }
136
137 array_walk(
138 $response['staff'],
139 function ( &$value, $key ) {
140 $value['full_name'] = stripslashes( $value['full_name'] );
141 }
142 );
143
144 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
145 }
146
147 /**
148 * Validate staff fields
149 */
150 public static function validate( $data ) {
151 $errors = array();
152
153 if ( isset( $data['phone'] ) && ( $data['phone'] !== '' || $data['phone'] === false ) ) {
154 if ( ! preg_match( '/^((\+)?[0-9]{9,14})$/', $data['phone'] ) ) {
155 $errors['phone'] = esc_html__( 'Please enter a valid phone number', 'bookit' );
156 }
157 }
158
159 if ( ! $data['email'] ) {
160 $errors['email'] = esc_html__( 'Email is required', 'bookit' );
161 }
162
163 if ( $data['email'] && ! is_email( $data['email'] ) ) {
164 $errors['email'] = esc_html__( 'Not valid Email', 'bookit' );
165 }
166
167 if ( $data['full_name'] ) {
168 if ( strlen( $data['full_name'] ) < 3 || strlen( $data['full_name'] ) > 50 ) {
169 $errors['full_name'] = esc_html__( 'Full Name must be between 3 and 50 characters long', 'bookit' );
170 }
171 } elseif ( 'wp_user' != $data['object'] ) {
172 $errors['full_name'] = esc_html__( 'Full Name is required.', 'bookit' );
173 }
174
175 if ( count( $errors ) > 0 ) {
176 wp_send_json_error(
177 array(
178 'errors' => $errors,
179 'message' => esc_html__( 'Error occurred!', 'bookit' ),
180 )
181 );
182 }
183 }
184
185 /**
186 * Create WordPress User from staff form
187 */
188 public static function create_wp_user() {
189 check_ajax_referer( 'bookit_save_item', 'nonce' );
190
191 if ( ! current_user_can( 'manage_options' ) ) {
192 return false;
193 }
194
195 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
196 self::validate( $data );
197
198 if ( get_user_by( 'email', $data['email'] ) ) {
199 wp_send_json_error(
200 array(
201 'errors' => array( 'wp_email' => __( 'Wordpress User with such email already exist.', 'bookit' ) ),
202 'message' => __( 'Error occurred!', 'bookit' ),
203 )
204 );
205 }
206 $data['role'] = User::$staff_role;
207
208 $id = Customers::save_or_get_wp_user( $data );
209 $wpUser = get_user_by( 'ID', $id )->data;
210
211 wp_send_json_success(
212 array(
213 'wp_user' => array(
214 'ID' => $wpUser->ID,
215 'display_name' => $wpUser->display_name,
216 'user_email' => $wpUser->user_email,
217 ),
218 'message' => __( 'Customer Saved!', 'bookit' ),
219 )
220 );
221 }
222
223 /**
224 * Save Staff
225 */
226 public static function save() {
227 check_ajax_referer( 'bookit_save_item', 'nonce' );
228
229 if ( ! current_user_can( 'manage_bookit_staff' ) ) {
230 return false;
231 }
232
233 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
234 self::validate( $data );
235
236 $id = ( ! empty( $data['id'] ) ) ? $data['id'] : null;
237
238 /** if this is staff can edit just self data */
239 $bookitUser = self::bookitUser();
240 if ( true == $bookitUser['is_staff'] && ( null == $id || ( (int) $bookitUser['staff'][0]['id'] != (int) $id ) ) ) {
241 return false;
242 }
243
244 if ( empty( $data ) ) {
245 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
246 return false;
247 }
248
249 $data['full_name'] = stripslashes( $data['full_name'] );
250
251 $staff_services = json_decode( stripslashes( $data['staff_services'] ?? '' ) );
252 $working_hours = json_decode( stripslashes( $data['working_hours'] ?? '' ) );
253
254 unset( $data['staff_services'] );
255 unset( $data['working_hours'] );
256 unset( $data['gc_token'] );
257
258 if ( isset( $id ) ) {
259 Staff::update( $data, array( 'id' => $id ) );
260
261 Staff_Services::delete_where( 'staff_id', $id );
262
263 foreach ( $working_hours as $working_hour ) {
264 $update = array(
265 'id' => $working_hour->id,
266 'staff_id' => $id,
267 'weekday' => $working_hour->weekday,
268 'start_time' => $working_hour->start_time,
269 'end_time' => $working_hour->end_time,
270 'break_from' => $working_hour->break_from ?? null,
271 'break_to' => $working_hour->break_to ?? null,
272 );
273 Staff_Working_Hours::update( $update, array( 'id' => $update['id'] ) );
274 }
275 } else {
276 Staff::insert( $data );
277
278 $id = Staff::insert_id();
279
280 foreach ( $working_hours as $working_hour ) {
281 $insert = array(
282 'staff_id' => $id,
283 'weekday' => $working_hour->weekday,
284 'start_time' => $working_hour->start_time,
285 'end_time' => $working_hour->end_time,
286 'break_from' => $working_hour->break_from ?? null,
287 'break_to' => $working_hour->break_to ?? null,
288 );
289 Staff_Working_Hours::insert( $insert );
290 }
291 }
292
293 foreach ( $staff_services as $staff_service ) {
294 $insert = array(
295 'staff_id' => $id,
296 'service_id' => $staff_service->id,
297 'price' => number_format( (float) $staff_service->price, 2, '.', '' ),
298 );
299 Staff_Services::insert( $insert );
300 }
301
302 /** set bookit staff role if WordPress user connected */
303 if ( $data['wp_user_id'] ) {
304 $wpUser = get_user_by( 'ID', $data['wp_user_id'] );
305 $wpUser->set_role( User::$staff_role );
306 }
307
308 // Always return staff data so frontend can use cleaned phone number.
309 $staff = (array) Staff::get( 'id', $id );
310
311 // Required for Google Calendar addon is installed.
312 if ( Plugin::isAddonInstalledAndEnabled( self::$proAddon ) && has_filter( 'bookit_filter_connect_employee_google_calendar' ) ) {
313 $staff = apply_filters( 'bookit_filter_connect_employee_google_calendar', $staff );
314 }
315
316 do_action( 'bookit_staff_saved', $id );
317
318 wp_send_json_success(
319 array(
320 'id' => $id,
321 'staff' => $staff,
322 'message' => __( 'Staff Saved!', 'bookit' ),
323 )
324 );
325 }
326
327 /**
328 * Disconnect google calendar data from staff ( clean gc_token)
329 */
330 public static function clean_gc_token() {
331 check_ajax_referer( 'bookit_save_item', 'nonce' );
332
333 if ( ! current_user_can( 'manage_options' ) ) {
334 return false;
335 }
336
337 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
338
339 if ( ! isset( $data['id'] ) || empty( $data['id'] ) ) {
340 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
341 }
342
343 Staff::update( array( 'gc_token' => null ), array( 'id' => $data['id'] ) );
344 $staff = (array) Staff::get( 'id', $data['id'] );
345
346 /** if google calendar addon is installed */
347 if ( Plugin::isAddonInstalledAndEnabled( self::$proAddon ) && has_action( 'bookit_filter_connect_employee_google_calendar' ) ) {
348 $staff = apply_filters( 'bookit_filter_connect_employee_google_calendar', $staff );
349 }
350 /** if google calendar addon is installed | end */
351
352 wp_send_json_success(
353 array(
354 'id' => $staff['id'],
355 'staff' => $staff,
356 'message' => __( 'Staff disconnected!', 'bookit' ),
357 )
358 );
359 }
360
361 /** Get Staff Assosiated data by id **/
362 public static function get_assosiated_total_data_by_id() {
363 check_ajax_referer( 'bookit_get_staff_assosiated_total_data', 'nonce' );
364
365 if ( ! current_user_can( 'manage_options' ) ) {
366 return false;
367 }
368
369 $data = CleanHelper::cleanData( $_POST, self::getCleanRules() );
370 if ( empty( $data['id'] ) ) {
371 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
372 }
373
374 $services = Staff::get_staff_total_service( $data['id'] );
375 $appointments = Appointments::get_total_active_assosiated_appointments( '', $data['id'] );
376
377 $response = array(
378 'total' => array(
379 'services' => $services,
380 'appointments' => $appointments,
381 ),
382 );
383 wp_send_json_success( $response );
384 }
385
386 /**
387 * Delete the Staff
388 */
389 public static function delete() {
390 check_ajax_referer( 'bookit_delete_item', 'nonce' );
391
392 if ( ! current_user_can( 'manage_options' ) ) {
393 return false;
394 }
395
396 $data = CleanHelper::cleanData( $_GET, self::getCleanRules() );
397
398 if ( isset( $data['id'] ) ) {
399 Staff::deleteStaff( $data['id'] );
400 do_action( 'bookit_staff_deleted', $data['id'] );
401 wp_send_json_success( array( 'message' => __( 'Staff Deleted!', 'bookit' ) ) );
402 }
403 wp_send_json_error( array( 'message' => __( 'Error occurred!', 'bookit' ) ) );
404 }
405 }
406