PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.56
Timetics – Appointment Booking Calendar & Scheduling v1.0.56
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 / customers / api-customer.php

api-customer.php in Timetics – Appointment Booking Calendar & Scheduling 1.0.56, at core/customers/api-customer.php

613 lines 18.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Api Customer
4 *
5 * @package Timetics
6 */
7 namespace Timetics\Core\Customers;
8
9 use Timetics\Base\Api;
10 use Timetics\Core\Bookings\Api_Booking;
11 use Timetics\Utils\Singleton;
12 use WP_HTTP_Response;
13 use WP_User_Query;
14
15 /**
16 * Class Api_customer
17 */
18 class Api_Customer extends Api {
19 use Singleton;
20
21 /**
22 * Store namespace
23 *
24 * @var string
25 */
26 protected $namespace = 'timetics/v1';
27
28 /**
29 * Store rest base
30 *
31 * @var string
32 */
33 protected $rest_base = 'customers';
34
35 /**
36 * Register rest route
37 *
38 * @return void
39 */
40 public function register_routes() {
41 register_rest_route(
42 $this->namespace, $this->rest_base, [
43 [
44 'methods' => \WP_REST_Server::READABLE,
45 'callback' => [$this, 'get_items'],
46 'permission_callback' => function () {
47 return current_user_can( 'manage_timetics' );
48 },
49 ],
50 [
51 'methods' => \WP_REST_Server::CREATABLE,
52 'callback' => [$this, 'create_item'],
53 'permission_callback' => function () {
54 return current_user_can( 'manage_timetics' );
55 },
56 ],
57 [
58 'methods' => \WP_REST_Server::DELETABLE,
59 'callback' => [$this, 'bulk_delete'],
60 'permission_callback' => function () {
61 return current_user_can( 'manage_timetics' );
62 },
63 ],
64 ]
65 );
66
67 /**
68 * Register route
69 *
70 * @var void
71 */
72 register_rest_route(
73 $this->namespace, '/' . $this->rest_base . '/(?P<customer_id>[\d]+)', [
74 [
75 'methods' => \WP_REST_Server::READABLE,
76 'callback' => [$this, 'get_item'],
77 'permission_callback' => function ( $request ) {
78 $customer_id = (int) $request['customer_id'];
79 if ( current_user_can( 'manage_timetics' ) || current_user_can( 'manage_options' ) ) {
80 return true;
81 }
82 return current_user_can( 'timetics-customer' ) && get_current_user_id() === $customer_id;
83 },
84 ],
85 [
86 'methods' => \WP_REST_Server::EDITABLE,
87 'callback' => [$this, 'update_item'],
88 'permission_callback' => [$this, 'update_item_permission_callback'],
89 ],
90 [
91 'methods' => \WP_REST_Server::DELETABLE,
92 'callback' => [$this, 'delete_item'],
93 'permission_callback' => function () {
94 return current_user_can( 'manage_options' );
95 },
96 ],
97 ]
98 );
99
100 register_rest_route(
101 $this->namespace, $this->rest_base . '/search', [
102 [
103 'methods' => \WP_REST_Server::READABLE,
104 'callback' => [$this, 'search_items'],
105 'permission_callback' => function () {
106 return current_user_can( 'manage_timetics' );
107 },
108 ],
109 ]
110 );
111
112 /**
113 * Register route for booking single customer
114 *
115 * @var void
116 */
117 register_rest_route(
118 $this->namespace, '/' . $this->rest_base . '/(?P<customer_id>[\d]+)/bookings', [
119 [
120 'methods' => \WP_REST_Server::READABLE,
121 'callback' => [$this, 'get_bookings'],
122 'permission_callback' => function ( $request ) {
123 $customer_id = (int) $request['customer_id'];
124 if ( current_user_can( 'manage_timetics' ) || current_user_can( 'manage_options' ) ) {
125 return true;
126 }
127 return current_user_can( 'timetics-customer' ) && get_current_user_id() === $customer_id;
128 },
129 ],
130 ]
131 );
132
133 }
134 /**
135 * Get all customers
136 *
137 * @param WP_Rest_Request $request
138 *
139 * @return JSON
140 */
141 public function get_items( $request ) {
142 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
143 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
144
145 $customer = Customer::all(
146 [
147 'number' => $per_page,
148 'paged' => $paged,
149 ]
150 );
151
152 $items = [];
153
154 foreach ( $customer['items'] as $item ) {
155 $items[] = $this->prepare_item( $item->ID );
156 }
157
158 /**
159 * Added temporary for leagacy sass. It will remove in future.
160 */
161 $items = apply_filters( 'timetics/admin/customer/get_items', $items );
162
163 $data = [
164 'success' => 1,
165 'data' => [
166 'total' => $customer['total'],
167 'items' => $items,
168 ],
169 ];
170
171 return rest_ensure_response( $data );
172 }
173
174 /**
175 * Get single customer
176 *
177 * @param WP_Rest_Requesr $request
178 *
179 * @return JSON Single customer data
180 */
181 public function get_item( $request ) {
182 $customer_id = (int) $request['customer_id'];
183 $customer = new Customer( $customer_id );
184
185 if ( ! $customer->is_customer() ) {
186 return [
187 'status_code' => 404,
188 'message' => esc_html__( 'Invalid customer id.', 'timetics' ),
189 'data' => [],
190 ];
191 }
192
193 /**
194 * Added temporary for leagacy sass. It will remove in future.
195 */
196 $item = apply_filters( 'timetics/admin/customer/get_item', $this->prepare_item( $customer ) );
197
198 $response = [
199 'status_code' => 200,
200 'data' => $item,
201 ];
202
203 return rest_ensure_response( $response );
204 }
205
206 /**
207 * Search customer
208 *
209 * @return JSON
210 */
211 public function search_items( $request ) {
212
213 // Prepare search args.
214 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
215 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
216 $search = ! empty( $request['search'] ) ? sanitize_text_field( $request['search'] ) : '';
217
218 // Get search.
219 $users = new WP_User_Query(
220 array(
221 'role' => 'timetics-customer',
222 'number' => $per_page,
223 'paged' => $paged,
224
225 // @codingStandardsIgnoreStart
226 'meta_query' => array(
227 'relation' => 'OR',
228 array(
229 'key' => '_timetics_customer_first_name',
230 'value' => $search,
231 'compare' => 'LIKE',
232 ),
233 array(
234 'key' => '_timetics_customer_last_name',
235 'value' => $search,
236 'compare' => 'LIKE',
237 ),
238 array(
239 'key' => '_timetics_customer_email',
240 'value' => $search,
241 'compare' => 'LIKE',
242 ),
243 array(
244 'key' => '_timetics_customer_phone',
245 'value' => $search,
246 'compare' => 'LIKE',
247 ),
248 ),
249 // @codingStandardsIgnoreEnd
250 )
251 );
252
253 // Prepare items for response.
254 $items = [];
255
256 foreach ( $users->get_results() as $item ) {
257 $items[] = $this->prepare_item( $item->ID );
258 }
259
260 $data = [
261 'success' => 1,
262 'status' => 200,
263 'data' => [
264 'total' => $users->get_total(),
265 'items' => $items,
266 ],
267 ];
268
269 return rest_ensure_response( $data );
270 }
271
272 /**
273 * Create Customer
274 *
275 * @param WP_Rest_Request $request
276 *
277 * @return JSON | WP_Error
278 */
279 public function create_item( $request ) {
280 return $this->save_customer( $request );
281 }
282
283 /**
284 * Update customer Permission check
285 *
286 * @param WP_Rest_Request $request
287 *
288 * @return JSON | WP_Error
289 */
290 public function update_item_permission_callback( $request ) {
291 $customer_id = (int) $request['customer_id'];
292
293 // Admins can always update any customer
294 if ( current_user_can( 'manage_timetics' ) || current_user_can( 'manage_options' ) ) {
295 return true;
296 }
297
298 // Customers can update themselves with a valid nonce
299 $nonce = $request->get_header( 'X-WP-Nonce' );
300 if ( ! empty( $nonce ) && wp_verify_nonce( $nonce, 'wp_rest' ) ) {
301 $current_user_id = get_current_user_id();
302 if ( $customer_id === $current_user_id && $current_user_id > 0 ) {
303 return true;
304 }
305 }
306
307 return false;
308 }
309
310 /**
311 * Update customer
312 *
313 * @param WP_Rest_Request $request
314 *
315 * @return JSON | WP_Error
316 */
317 public function update_item( $request ) {
318 $customer_id = (int) $request['customer_id'];
319 $customer = new Customer( $customer_id );
320
321 if ( ! $customer->is_customer() ) {
322 $data = [
323 'status_code' => 404,
324 'message' => esc_html__( 'Invalid customer id.', 'timetics' ),
325 'data' => [],
326 ];
327
328 return new WP_HTTP_Response( $data, 404 );
329 }
330
331 return $this->save_customer( $request, $customer_id );
332 }
333
334 /**
335 * Delete customer
336 *
337 * @param WP_Rest_Request $request
338 *
339 * @return JSON
340 */
341 public function delete_item( $request ) {
342 $customer_id = (int) $request['customer_id'];
343 $customer = new Customer( $customer_id );
344
345 if ( ! $customer->is_customer() ) {
346 $data = [
347 'status_code' => 404,
348 'message' => esc_html__( 'Invalid customer id.', 'timetics' ),
349 'data' => [],
350 ];
351
352 return new WP_HTTP_Response( $data, 404 );
353 }
354
355 $customer->delete();
356
357 /**
358 * Added temporary for leagacy sass. It will remove in future.
359 */
360 do_action( 'timetics/admin/customer/delete_item', $customer );
361
362 $response = [
363 'status_code' => 200,
364 'message' => esc_html__( 'Successfully deleted customer', 'timetics' ),
365 'data' => [],
366 ];
367
368 return rest_ensure_response( $response );
369 }
370
371 /**
372 * Delete multiples
373 *
374 * @param WP_Rest_Request $request
375 *
376 * @return JSON
377 */
378 public function bulk_delete( $request ) {
379 $customers = json_decode( $request->get_body(), true );
380
381 foreach ( $customers as $customer ) {
382 $customer = new customer( $customer );
383
384 if ( ! $customer->is_customer() ) {
385 $data = [
386 'success' => 1,
387 'status' => 404,
388 'message' => esc_html__( 'Invalid customer id.', 'timetics' ),
389 'data' => [],
390 ];
391
392 return new WP_HTTP_Response( $data, 404 );
393 }
394
395 $customer->delete();
396 }
397
398 /**
399 * Added temporary for leagacy sass. It will remove in future.
400 */
401 do_action( 'timetics/admin/customer/bulk_delete', $customers );
402
403 return [
404 'success' => 1,
405 'status' => 200,
406 'message' => esc_html__( 'Successfully deleted customer', 'timetics' ),
407 'data' => [
408 'items' => $customers,
409 ],
410 ];
411 }
412
413 /**
414 * Save customer
415 *
416 * @param WP_Rest_Request $request
417 * @param integer $id [$id description]
418 *
419 * @return JSON | WP_Error
420 */
421 public function save_customer( $request, $id = 0 ) {
422 $data = json_decode( $request->get_body(), true );
423
424 $first_name = ! empty( $data['first_name'] ) ? $data['first_name'] : '';
425 $last_name = ! empty( $data['last_name'] ) ? $data['last_name'] : '';
426 $email = ! empty( $data['email'] ) ? $data['email'] : '';
427 $phone = ! empty( $data['phone'] ) ? $data['phone'] : '';
428 $image = ! empty( $data['image'] ) ? intval( $data['image'] ) : '';
429 $password = ! empty( $data['password'] ) ? $data['password'] : '';
430 $action = $id ? 'updated' : 'created';
431
432 // Validate input data.
433 $validate = $this->validate(
434 $data, [
435 'first_name',
436 'last_name',
437 'email',
438 ]
439 );
440
441 if ( is_wp_error( $validate ) ) {
442 $data = [
443 'success' => 0,
444 'status_code' => 409,
445 'message' => $validate->get_error_messages(),
446 'data' => [],
447 ];
448
449 return new WP_HTTP_Response( $data, 409 );
450 }
451
452 // Save customer data.
453 $customer = new Customer( $id );
454
455 $customer->set_props(
456 [
457 'first_name' => $first_name,
458 'last_name' => $last_name,
459 'email' => $email,
460 'user_name' => $this->generate_username( $email ),
461 'phone' => $phone,
462 'image' => $image,
463 'password' => $password,
464 ]
465 );
466
467 $customer->save();
468
469 if ( is_wp_error( $customer->error ) ) {
470 return [
471 'success' => 0,
472 'status' => 409,
473 'message' => $customer->error->get_error_message(),
474 'data' => [],
475 ];
476 }
477 // Prepare for response.
478 $item = $this->prepare_item( $customer );
479
480 /**
481 * Added temporary for leagacy sass. It will remove in future.
482 */
483 do_action( 'timetics/admin/customer/create_item', $item );
484
485 $data = [
486 'success' => 1,
487 'status' => 200,
488 /* translators: Action */
489 'message' => sprintf( esc_html__( 'Successfully %s customer', 'timetics' ), $action ),
490 'data' => $item,
491 ];
492
493 return rest_ensure_response( $data );
494 }
495
496 /**
497 * Generate username from email
498 *
499 * @param string $email
500 *
501 * @return string
502 */
503 public function generate_username( $email ) {
504 $username = strtok( $email, '@' );
505
506 if ( username_exists( $username ) ) {
507 $username = $username . wp_rand( 10, 100 );
508 }
509
510 return $username;
511 }
512
513 /**
514 * Prepare item
515 *
516 * @param integer | customer $customer_id customer Id
517 *
518 * @return array customer data
519 */
520 public function prepare_item( $customer ) {
521 $customer = new Customer( $customer );
522
523 return [
524 'id' => $customer->get_id(),
525 'full_name' => $customer->get_display_name(),
526 'first_name' => $customer->get_first_name(),
527 'last_name' => $customer->get_last_name(),
528 'email' => $customer->get_email(),
529 'phone' => $customer->get_phone(),
530 'image' => $customer->get_image(),
531 'total_booking' => $customer->get_total_booking(),
532 ];
533 }
534
535 /**
536 * Get booking list for single customer
537 *
538 * @param integer | customer $customer_id customer Id
539 *
540 * @return array booking data
541 */
542 public function get_bookings( $request ) {
543 $customer_id = (int) $request['customer_id'];
544 $customer = new Customer( $customer_id );
545
546 if ( ! $customer->is_customer() ) {
547 $data = [
548 'status_code' => 404,
549 'message' => esc_html__( 'Invalid customer id.', 'timetics' ),
550 'data' => [],
551 ];
552
553 return new WP_HTTP_Response( $data, 404 );
554 }
555
556 return $this->get_booking_list( $request, $customer_id );
557 }
558
559 /**
560 * Save customer
561 *
562 * @param WP_Rest_Request $request
563 * @param integer $id [$id description]
564 *
565 * @return JSON | WP_Error
566 */
567 public function get_booking_list( $request, $customer_id = 0 ) {
568
569 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
570 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
571
572 $args = [
573 'post_type' => 'timetics-booking',
574 'posts_per_page' => $per_page,
575 'paged' => $paged,
576 'post_status' => 'any',
577 // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Meta query is necessary for filtering bookings by customer
578 'meta_query' => array(
579 'relation' => 'OR',
580 array(
581 'key' => '_tt_booking_customer',
582 'value' => $customer_id,
583 'compare' => '=',
584 ),
585
586 ),
587 ];
588
589 $bookings = new \WP_Query( $args );
590
591 // Prepare items for response.
592 $items = [];
593 $booking = new Api_Booking();
594
595 foreach ( $bookings->posts as $item ) {
596 $items[] = $booking->prepare_item( $item->ID );
597 }
598
599 $data = [
600 'success' => 1,
601 'status' => 200,
602 'data' => [
603 'total' => $bookings->found_posts,
604 'items' => $items,
605 ],
606 ];
607
608 return rest_ensure_response( $data );
609
610 }
611
612 }
613