PluginProbe
Booktics – Appointment Booking Calendar for Service Businesses / 1.0.0
Booktics – Appointment Booking Calendar for Service Businesses v1.0.0
1.0.25 1.0.24 1.0.23 1.0.22 1.0.21 1.0.20 1.0.19 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.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 All 27 releases
booktics / core / customer / controllers / customer-controller.php

customer-controller.php in Booktics – Appointment Booking Calendar for Service Businesses 1.0.0, at core/customer/controllers/customer-controller.php

483 lines 14.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Booktics\Customer\Controllers;
4
5 use Booktics\Abstracts\Base_Rest_Controller;
6 use Booktics\Abstracts\Booktics_Database;
7 use Booktics\Abstracts\User_Model;
8 use Booktics\Customer\Handlers\Customer_Event_Handler;
9 use Booktics\Models\Appointment_Model;
10 use Booktics\Models\Customer_Model;
11 use Booktics\Models\Order_Model;
12 use Booktics\Models\Payment_Model;
13 use WP_Error;
14 use WP_HTTP_Response;
15 use WP_REST_Response;
16 use WP_REST_Server;
17
18 /**
19 * Customer controller
20 *
21 * @package Booktics/Customer
22 */
23 class Customer_Controller extends Base_Rest_Controller {
24
25 /**
26 * Store namespace of api
27 *
28 * @var string
29 */
30 protected $namespace = 'booktics/v1';
31
32 /**
33 * Store base url
34 *
35 * @var string
36 */
37 protected $base = 'customers';
38
39 /**
40 *
41 *
42 * @return void
43 */
44 public function register_routes(): void {
45 register_rest_route(
46 $this->namespace, $this->base, array(
47 array(
48 'methods' => WP_REST_Server::CREATABLE,
49 'callback' => array( $this, 'create_item' ),
50 'permission_callback' => array(
51 $this,
52 'create_customer_permission',
53 ),
54 ),
55 array(
56 'methods' => WP_REST_Server::READABLE,
57 'callback' => array( $this, 'get_items' ),
58 'permission_callback' => array(
59 $this,
60 'get_customer_permission',
61 ),
62 ),
63 array(
64 'methods' => WP_REST_Server::DELETABLE,
65 'callback' => array( $this, 'delete_items' ),
66 'permission_callback' => array(
67 $this,
68 'delete_customer_permission',
69 ),
70 ),
71 )
72 );
73
74 register_rest_route(
75 $this->namespace, '/' . $this->base . '/(?P<id>[\d]+)', array(
76 array(
77 'methods' => WP_REST_Server::EDITABLE,
78 'callback' => array( $this, 'update_item' ),
79 'permission_callback' => array(
80 $this,
81 'update_customer_permission',
82 ),
83 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
84 ),
85 array(
86 'methods' => WP_REST_Server::DELETABLE,
87 'callback' => array( $this, 'delete_item' ),
88 'permission_callback' => array(
89 $this,
90 'delete_customer_permission',
91 ),
92 ),
93 array(
94 'method' => WP_REST_Server::READABLE,
95 'callback' => array( $this, 'get_item' ),
96 'permission_callback' => array(
97 $this,
98 'get_customer_permission',
99 ),
100 ),
101 )
102 );
103 }
104
105 /**
106 * Check if a given request has access to create items.
107 *
108 * @param $request Full data about the request.
109 */
110 public function create_customer_permission( $request ) {
111 return true;
112 }
113
114 /**
115 * Prepare and validate customer data
116 *
117 * @param $request
118 *
119 * @return array|bool|WP_Error
120 */
121 protected function prepare_customer_data( $request ) {
122 $input_data = json_decode( $request->get_body(), true );
123
124 $validate = booktics_validate(
125 $input_data, array(
126 'first_name' => array(
127 'required',
128 ),
129 'email' => array(
130 'required',
131 'unique:wp_users,email',
132 ),
133 )
134 );
135
136 if ( is_wp_error( $validate ) ) {
137 return $validate;
138 }
139
140 return array(
141 'first_name' => $input_data['first_name'],
142 'last_name' => $input_data['last_name'],
143 'user_email' => $input_data['email'],
144 'user_login' => User_Model::generate_username( $input_data['email'] ),
145 'phone' => $input_data['phone'],
146 'email' => $input_data['email'],
147 'status' => 'pending',
148 );
149 }
150
151 /**
152 * Store new customer data
153 *
154 * @param $request
155 *
156 * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response
157 */
158 public function create_item( $request ) {
159 $prepared_data = $this->prepare_customer_data( $request );
160 if ( is_wp_error( $prepared_data ) ) {
161 return $this->error(
162 $prepared_data->get_error_message(),
163 422,
164 'Validation',
165 $prepared_data->errors
166 );
167 }
168
169 $customer = new Customer_Model();
170 $created = $customer->save( $prepared_data );
171
172 $image_url = $request->get_param( 'image' );
173 if ( $image_url ) {
174 $customer->update( array( 'image' => esc_url_raw( $image_url ) ) );
175 }
176
177 if ( ! $created ) {
178 return $this->error( __( 'Customer create error', 'booktics' ), 500 );
179 }
180
181 do_action( 'booktics_customer_created', $customer, $request );
182
183 ( new Customer_Event_Handler() )->on_customer_create( $created );
184 $customer = $customer->find( $created );
185
186 return $this->response( $customer, __( 'Successfully created customer', 'booktics' ), 201 );
187 }
188
189 /**
190 * Check if a given request has access to get all customer
191 *
192 * @param $request
193 *
194 * @return bool
195 */
196 public function get_customer_permission( $request ) {
197 return true;
198 }
199
200 /**
201 * Get paginated list items for customer
202 *
203 * @param $request
204 *
205 * @return WP_Error|WP_HTTP_Response|WP_REST_Response
206 */
207 public function get_items( $request ) {
208 $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20;
209 $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1;
210 $first_name = ! empty( $request['first_name'] ) ? trim( $request['first_name'] ) : '';
211 $last_name = ! empty( $request['last_name'] ) ? trim( $request['last_name'] ) : '';
212 $email = ! empty( $request['email'] ) ? trim( $request['email'] ) : '';
213 $phone = ! empty( $request['phone'] ) ? trim( $request['phone'] ) : '';
214 $user_name = ! empty( $request['user_name'] ) ? trim( $request['user_name'] ) : '';
215 $search = ! empty( $request['search'] ) ? trim( $request['search'] ) : '';
216
217 $customers = ( new Customer_Model() )
218 ->when(
219 $first_name, function ( $q, $v ) {
220 $q->where( 'first_name', $v, 'LIKE' );
221 }
222 )
223 ->when(
224 $last_name, function ( $q, $v ) {
225 $q->where( 'last_name', $v, 'LIKE' );
226 }
227 )
228 ->when(
229 $email, function ( $q, $v ) {
230 $q->where( 'user_email', $v, 'LIKE' );
231 }
232 )
233 ->when(
234 $phone, function ( $q, $v ) {
235 $q->where( 'phone', $v, 'LIKE' );
236 }
237 )
238 ->when(
239 $user_name, function ( $q, $v ) {
240 $q->where( 'user_login', 'LIKE', $v, 'LIKE' );
241 }
242 )
243 ->when(
244 $search, function ( $q, $v ) {
245 $q->where( 'first_name', $v, 'LIKE' )
246 ->or_where( 'last_name', $v, 'LIKE' )
247 ->or_where( 'phone', $v, 'LIKE' );
248 }
249 )->all(
250 array(
251 'paged' => $paged,
252 'number' => $per_page,
253 )
254 );
255
256 return $this->response( $customers, __( 'Successfully fetched customer', 'booktics' ) );
257 }
258
259 /**
260 * Checks if a given request has access to delete a team member.
261 *
262 * @param $request
263 *
264 * @return bool
265 */
266 public function delete_customer_permission( $request ) {
267 return true;
268 }
269
270 /**
271 * Delete a customer
272 *
273 * @param $request
274 *
275 * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response
276 */
277 public function delete_item( $request ) {
278 $id = intval( $request['id'] );
279
280 $db = new Booktics_Database();
281 $orderModel = new Order_Model( $db );
282 $orders = $orderModel->get( array( 'customer_id' => $id ) );
283 foreach ( $orders['items'] as $order ) {
284 $appointmentModel = new Appointment_Model();
285 $appointments = $appointmentModel->where( 'order_id', $order->id );
286 foreach ( $appointments as $appointment ) {
287 $appointment->delete();
288 }
289 $paymentModel = new Payment_Model( $db );
290 $payments = $paymentModel->get( array( 'order_id' => $order->id ) );
291 foreach ( $payments['items'] as $payment ) {
292 ( new Payment_Model( $db ) )->delete( $payment->id );
293 }
294 $orderModel->delete( $order->id );
295 }
296
297 $customer = new Customer_Model( $id );
298 $previous = $customer->find( $id );
299 $deleted = $customer->delete();
300
301 if ( ! $deleted ) {
302 return $this->error( __( 'Customer delete error', 'booktics' ), 500 );
303 }
304
305 do_action( 'booktics_customers_deleted', $request );
306
307 return $this->response( $previous, __( 'Successfully deleted customer', 'booktics' ) );
308 }
309
310 /**
311 * Delete multiple customer
312 *
313 * @param $request
314 *
315 * @return array|WP_Error|WP_HTTP_Response
316 */
317 public function delete_items( $request ) {
318 $ids = ! empty( $request['ids'] ) ? $request['ids'] : array();
319
320 if ( ! $ids ) {
321 return $this->error( __( 'Customer ids cannot be empty', 'booktics' ), 500 );
322 }
323 $count = 0;
324 $db = new Booktics_Database();
325 foreach ( $ids as $id ) {
326 // Delete all orders (and their related appointments and payments) for this customer
327 $orderModel = new Order_Model( $db );
328 $orders = $orderModel->get( array( 'customer_id' => $id ) );
329 foreach ( $orders['items'] as $order ) {
330 // Delete related appointments
331 $appointmentModel = new Appointment_Model();
332 $appointments = $appointmentModel->where( 'order_id', $order->id );
333 foreach ( $appointments as $appointment ) {
334 $appointment->delete();
335 }
336 // Delete related payments
337 $paymentModel = new Payment_Model( $db );
338 $payments = $paymentModel->get( array( 'order_id' => $order->id ) );
339 foreach ( $payments['items'] as $payment ) {
340 ( new Payment_Model( $db ) )->delete( $payment->id );
341 }
342 // Delete the order
343 $orderModel->delete( $order->id );
344 }
345 $customer = new Customer_Model( $id );
346 if ( $customer->delete() ) {
347 ++$count;
348 }
349 }
350 if ( $count == 0 ) {
351 return $this->error( __( 'Customer delete error', 'booktics' ), 500 );
352 }
353
354 do_action( 'booktics_customers_deleted', $request );
355
356 return $this->response( array(), __( 'Successfully deleted customer', 'booktics' ) );
357 }
358
359 /**
360 * Get single customer
361 *
362 * @param $request
363 *
364 * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response
365 */
366 public function get_item( $request ) {
367 $id = intval( $request['id'] );
368 $customer = new Customer_Model( $id );
369 $customer = $customer->find( $id );
370 if ( ! $customer ) {
371 return $this->error( __( 'Customer not found', 'booktics' ), 404 );
372 }
373
374 $db = new Booktics_Database();
375 $orders = ( new Order_Model( $db ) )->get( array( 'customer_id' => $id ) );
376 $customer_data = $customer->to_array();
377 $customer_data['orders'] = array_map(
378 function ( $order ) {
379 $booking_count = ( new Appointment_Model() )
380 ->get_appointments_count_by_order_id( $order->id );
381
382 return array(
383 'date' => $order->created_at ? gmdate( 'j F, Y', strtotime( $order->created_at ) ) : '',
384 'total_booking' => $booking_count,
385 'total_amount' => $order->total,
386 );
387 }, $orders['items']
388 );
389
390 return $this->response( $customer_data, __( 'Customer found successfully', 'booktics' ) );
391 }
392
393 /**
394 * Checks if a given request has access to update a customer.
395 *
396 * @param $request
397 *
398 * @return bool True if the request has access to update the item, WP_Error object otherwise.
399 */
400 public function update_customer_permission( $request ) {
401 return true;
402 }
403
404 /**
405 * Prepare data for customer update
406 *
407 * @param $request
408 *
409 * @return array|bool|WP_Error
410 */
411 public function prepare_customer_update( $request ) {
412 $input_data = json_decode( $request->get_body(), true );
413 $validation_rules = array(
414 'first_name' => array(
415 'required',
416 ),
417 'email' => array(
418 'required',
419 'unique:wp_users,email,' . $request['id'],
420 ),
421 );
422 $update_validation_rules = array();
423 $validated_data = array();
424
425 if ( ! is_array( $input_data ) ) {
426 return new WP_Error(
427 'invalid_input_data',
428 'Invalid data'
429 );
430 }
431
432 foreach ( $input_data as $key => $value ) {
433 if ( $key == 'email' ) {
434 $update_validation_rules[ $key ] = $validation_rules[ $key ];
435 $validated_data['user_email'] = sanitize_email( $value );
436 continue;
437 }
438 $validated_data[ $key ] = $value;
439 }
440
441 $validate = booktics_validate( $input_data, $update_validation_rules );
442
443 if ( is_wp_error( $validate ) ) {
444 return $validate;
445 }
446 $validated_data['status'] = 'active';
447
448 return $validated_data;
449 }
450
451 /**
452 * @param $request
453 *
454 * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response
455 */
456 public function update_item( $request ) {
457 if ( ! isset( $request['id'] ) ) {
458 return $this->error( 'Invalid team member id', 400 );
459 }
460 $prepared_data = $this->prepare_customer_update( $request );
461
462 if ( is_wp_error( $prepared_data ) ) {
463 return $this->error( __( 'Customer validation error', 'booktics' ), 422, 'Validation', $prepared_data->errors );
464 }
465
466 $customer = new Customer_Model( $request['id'] );
467 $updated = $customer->update( $prepared_data );
468 $image_url = $request->get_param( 'image' );
469 if ( $image_url ) {
470 $customer->update( array( 'image' => esc_url_raw( $image_url ) ) );
471 }
472
473 if ( ! $updated ) {
474 return $this->error( __( 'Customer update error', 'booktics' ), 500 );
475 }
476
477 do_action( 'booktics_customer_updated', $customer, $request );
478 $customer = $customer->find( $request['id'] );
479
480 return $this->response( $customer, __( 'Successfully updated customer', 'booktics' ) );
481 }
482 }
483