namespace, $this->base, array( array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_customer_permission', ), ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_customer_permission', ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_items' ), 'permission_callback' => array( $this, 'delete_customer_permission', ), ), ) ); register_rest_route( $this->namespace, '/' . $this->base . '/(?P[\d]+)', array( array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'update_customer_permission', ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_customer_permission', ), ), array( 'method' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_customer_permission', ), ), ) ); } /** * Check if a given request has access to create items. * * @param $request Full data about the request. */ public function create_customer_permission( $request ) { return true; } /** * Prepare and validate customer data * * @param $request * * @return array|bool|WP_Error */ protected function prepare_customer_data( $request ) { $input_data = json_decode( $request->get_body(), true ); $validate = booktics_validate( $input_data, array( 'first_name' => array( 'required', ), 'email' => array( 'required', 'unique:wp_users,email', ), ) ); if ( is_wp_error( $validate ) ) { return $validate; } return array( 'first_name' => $input_data['first_name'], 'last_name' => $input_data['last_name'], 'user_email' => $input_data['email'], 'user_login' => User_Model::generate_username( $input_data['email'] ), 'phone' => $input_data['phone'], 'email' => $input_data['email'], 'status' => 'pending', ); } /** * Store new customer data * * @param $request * * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response */ public function create_item( $request ) { $prepared_data = $this->prepare_customer_data( $request ); if ( is_wp_error( $prepared_data ) ) { return $this->error( $prepared_data->get_error_message(), 422, 'Validation', $prepared_data->errors ); } $customer = new Customer_Model(); $created = $customer->save( $prepared_data ); $image_url = $request->get_param( 'image' ); if ( $image_url ) { $customer->update( array( 'image' => esc_url_raw( $image_url ) ) ); } if ( ! $created ) { return $this->error( __( 'Customer create error', 'booktics' ), 500 ); } do_action( 'booktics_customer_created', $customer, $request ); ( new Customer_Event_Handler() )->on_customer_create( $created ); $customer = $customer->find( $created ); return $this->response( $customer, __( 'Successfully created customer', 'booktics' ), 201 ); } /** * Check if a given request has access to get all customer * * @param $request * * @return bool */ public function get_customer_permission( $request ) { return true; } /** * Get paginated list items for customer * * @param $request * * @return WP_Error|WP_HTTP_Response|WP_REST_Response */ public function get_items( $request ) { $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 20; $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1; $first_name = ! empty( $request['first_name'] ) ? trim( $request['first_name'] ) : ''; $last_name = ! empty( $request['last_name'] ) ? trim( $request['last_name'] ) : ''; $email = ! empty( $request['email'] ) ? trim( $request['email'] ) : ''; $phone = ! empty( $request['phone'] ) ? trim( $request['phone'] ) : ''; $user_name = ! empty( $request['user_name'] ) ? trim( $request['user_name'] ) : ''; $search = ! empty( $request['search'] ) ? trim( $request['search'] ) : ''; $customers = ( new Customer_Model() ) ->when( $first_name, function ( $q, $v ) { $q->where( 'first_name', $v, 'LIKE' ); } ) ->when( $last_name, function ( $q, $v ) { $q->where( 'last_name', $v, 'LIKE' ); } ) ->when( $email, function ( $q, $v ) { $q->where( 'user_email', $v, 'LIKE' ); } ) ->when( $phone, function ( $q, $v ) { $q->where( 'phone', $v, 'LIKE' ); } ) ->when( $user_name, function ( $q, $v ) { $q->where( 'user_login', 'LIKE', $v, 'LIKE' ); } ) ->when( $search, function ( $q, $v ) { $q->where( 'first_name', $v, 'LIKE' ) ->or_where( 'last_name', $v, 'LIKE' ) ->or_where( 'phone', $v, 'LIKE' ); } )->all( array( 'paged' => $paged, 'number' => $per_page, ) ); return $this->response( $customers, __( 'Successfully fetched customer', 'booktics' ) ); } /** * Checks if a given request has access to delete a team member. * * @param $request * * @return bool */ public function delete_customer_permission( $request ) { return true; } /** * Delete a customer * * @param $request * * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response */ public function delete_item( $request ) { $id = intval( $request['id'] ); $db = new Booktics_Database(); $orderModel = new Order_Model( $db ); $orders = $orderModel->get( array( 'customer_id' => $id ) ); foreach ( $orders['items'] as $order ) { $appointmentModel = new Appointment_Model(); $appointments = $appointmentModel->where( 'order_id', $order->id ); foreach ( $appointments as $appointment ) { $appointment->delete(); } $paymentModel = new Payment_Model( $db ); $payments = $paymentModel->get( array( 'order_id' => $order->id ) ); foreach ( $payments['items'] as $payment ) { ( new Payment_Model( $db ) )->delete( $payment->id ); } $orderModel->delete( $order->id ); } $customer = new Customer_Model( $id ); $previous = $customer->find( $id ); $deleted = $customer->delete(); if ( ! $deleted ) { return $this->error( __( 'Customer delete error', 'booktics' ), 500 ); } do_action( 'booktics_customers_deleted', $request ); return $this->response( $previous, __( 'Successfully deleted customer', 'booktics' ) ); } /** * Delete multiple customer * * @param $request * * @return array|WP_Error|WP_HTTP_Response */ public function delete_items( $request ) { $ids = ! empty( $request['ids'] ) ? $request['ids'] : array(); if ( ! $ids ) { return $this->error( __( 'Customer ids cannot be empty', 'booktics' ), 500 ); } $count = 0; $db = new Booktics_Database(); foreach ( $ids as $id ) { // Delete all orders (and their related appointments and payments) for this customer $orderModel = new Order_Model( $db ); $orders = $orderModel->get( array( 'customer_id' => $id ) ); foreach ( $orders['items'] as $order ) { // Delete related appointments $appointmentModel = new Appointment_Model(); $appointments = $appointmentModel->where( 'order_id', $order->id ); foreach ( $appointments as $appointment ) { $appointment->delete(); } // Delete related payments $paymentModel = new Payment_Model( $db ); $payments = $paymentModel->get( array( 'order_id' => $order->id ) ); foreach ( $payments['items'] as $payment ) { ( new Payment_Model( $db ) )->delete( $payment->id ); } // Delete the order $orderModel->delete( $order->id ); } $customer = new Customer_Model( $id ); if ( $customer->delete() ) { ++$count; } } if ( $count == 0 ) { return $this->error( __( 'Customer delete error', 'booktics' ), 500 ); } do_action( 'booktics_customers_deleted', $request ); return $this->response( array(), __( 'Successfully deleted customer', 'booktics' ) ); } /** * Get single customer * * @param $request * * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response */ public function get_item( $request ) { $id = intval( $request['id'] ); $customer = new Customer_Model( $id ); $customer = $customer->find( $id ); if ( ! $customer ) { return $this->error( __( 'Customer not found', 'booktics' ), 404 ); } $db = new Booktics_Database(); $orders = ( new Order_Model( $db ) )->get( array( 'customer_id' => $id ) ); $customer_data = $customer->to_array(); $customer_data['orders'] = array_map( function ( $order ) { $booking_count = ( new Appointment_Model() ) ->get_appointments_count_by_order_id( $order->id ); return array( 'date' => $order->created_at ? gmdate( 'j F, Y', strtotime( $order->created_at ) ) : '', 'total_booking' => $booking_count, 'total_amount' => $order->total, ); }, $orders['items'] ); return $this->response( $customer_data, __( 'Customer found successfully', 'booktics' ) ); } /** * Checks if a given request has access to update a customer. * * @param $request * * @return bool True if the request has access to update the item, WP_Error object otherwise. */ public function update_customer_permission( $request ) { return true; } /** * Prepare data for customer update * * @param $request * * @return array|bool|WP_Error */ public function prepare_customer_update( $request ) { $input_data = json_decode( $request->get_body(), true ); $validation_rules = array( 'first_name' => array( 'required', ), 'email' => array( 'required', 'unique:wp_users,email,' . $request['id'], ), ); $update_validation_rules = array(); $validated_data = array(); if ( ! is_array( $input_data ) ) { return new WP_Error( 'invalid_input_data', 'Invalid data' ); } foreach ( $input_data as $key => $value ) { if ( $key == 'email' ) { $update_validation_rules[ $key ] = $validation_rules[ $key ]; $validated_data['user_email'] = sanitize_email( $value ); continue; } $validated_data[ $key ] = $value; } $validate = booktics_validate( $input_data, $update_validation_rules ); if ( is_wp_error( $validate ) ) { return $validate; } $validated_data['status'] = 'active'; return $validated_data; } /** * @param $request * * @return array|WP_Error|WP_HTTP_Response|WP_REST_Response */ public function update_item( $request ) { if ( ! isset( $request['id'] ) ) { return $this->error( 'Invalid team member id', 400 ); } $prepared_data = $this->prepare_customer_update( $request ); if ( is_wp_error( $prepared_data ) ) { return $this->error( __( 'Customer validation error', 'booktics' ), 422, 'Validation', $prepared_data->errors ); } $customer = new Customer_Model( $request['id'] ); $updated = $customer->update( $prepared_data ); $image_url = $request->get_param( 'image' ); if ( $image_url ) { $customer->update( array( 'image' => esc_url_raw( $image_url ) ) ); } if ( ! $updated ) { return $this->error( __( 'Customer update error', 'booktics' ), 500 ); } do_action( 'booktics_customer_updated', $customer, $request ); $customer = $customer->find( $request['id'] ); return $this->response( $customer, __( 'Successfully updated customer', 'booktics' ) ); } }