namespace, $this->base, array( array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check', ), ), ) ); register_rest_route( $this->namespace, $this->base, array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check', ), ), ) ); register_rest_route( $this->namespace, $this->base, array( array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_items' ), 'permission_callback' => array( $this, 'delete_items_permissions_check', ), ), ) ); register_rest_route( $this->namespace, $this->base . '/(?P[\d]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_item_permissions_check', ), ), ) ); 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_item_permissions_check', ), ), ) ); register_rest_route( $this->namespace, $this->base . '/(?P[\d]+)', array( array( 'methods' => WP_REST_Server::DELETABLE, 'callback' => array( $this, 'delete_item' ), 'permission_callback' => array( $this, 'delete_item_permissions_check', ), ), ) ); register_rest_route( $this->namespace, $this->base . '/(?P[\d]+)/clone', array( array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'clone_item' ), 'permission_callback' => array( $this, 'create_item_permissions_check', ), ), ) ); } /** * Get one item from the collection. * * @param $request * * @return WP_HTTP_Response */ public function get_item( $request ) { $id = intval( $request['id'] ); $service = Service_Model::find( $id ); if ( ! $service ) { return $this->error( __( 'Service not found', 'booktics' ), 404 ); } $service = $service->to_array(); $team_member_ids = is_array( $service['team_member'] ) ? array_unique( $service['team_member'] ) : array( $service['team_member'] ); $service['team_member_details'] = $this->team_member_details( $team_member_ids ); $service['team_member'] = $team_member_ids; $category_ids = is_array( $service['categories'] ) ? array_unique( $service['categories'] ) : array( $service['categories'] ); $service['category_details'] = $this->category_details( $category_ids ); $service['categories'] = $category_ids; $schedule_record = ( new Schedule_Record() ) ->get_schedules( $id, 'service' ); $service['schedule'] = empty( $schedule_record['schedule'] ) ? (object) array() : $schedule_record['schedule']; $service['custom'] = $schedule_record['custom']; $service['holiday'] = $schedule_record['holiday']; $service['shortcode'] = '[booktics-service-view id="' . $service['id'] . '"]'; $service = apply_filters( 'booktics_service_format', $service ); return $this->response( $service ); } /** * Check if a given request has access to get a specific item. * * @param $request * * @return WP_Error */ public function get_item_permissions_check( $request ): bool { return true; } /** * Get a collection of items. * * @param $request * * @return WP_HTTP_Response */ public function get_items( $request ) { $per_page = ! empty( $request['per_page'] ) ? intval( $request['per_page'] ) : 10; $paged = ! empty( $request['paged'] ) ? intval( $request['paged'] ) : 1; $args = array( 'per_page' => $per_page, 'paged' => $paged, 'meta_query' => array(), ); if ( ! empty( $request['team_member_id'] ) ) { $args['meta_query'][] = array( 'key' => 'team_member', 'value' => sprintf( 'i:%d;', intval( $request['team_member_id'] ) ), 'compare' => 'LIKE', ); } if ( ! empty( $request['category_id'] ) ) { $args['meta_query'][] = array( 'key' => 'categories', 'value' => sprintf( 'i:%d;', intval( $request['category_id'] ) ), 'compare' => 'LIKE', ); } if ( ! empty( $request['search'] ) ) { $args['s'] = sanitize_text_field( $request['search'] ); } if ( ! empty( $args['meta_query'] ) ) { $args['meta_query']['relation'] = 'AND'; } $data = Service_Model::paginate( $per_page, $paged, $args ); if ( ! $data ) { return $this->error( __( 'No service found', 'booktics' ), 404 ); } if ( ! empty( $data['items'] ) ) { $enhanced_items = array(); foreach ( $data['items'] as $service ) { $service_array = $service->to_array(); if ( ! empty( $service_array['team_member'] ) ) { $team_member_ids = is_array( $service->team_member ) ? array_unique( $service->team_member ) : array( $service->team_member ); $service->team_member = $team_member_ids; $service_array['team_member_details'] = $this->team_member_details( $team_member_ids ); } if ( ! empty( $service_array['categories'] ) ) { $category_ids = is_array( $service->categories ) ? array_unique( $service->categories ) : array( $service->categories ); $service->categories = $category_ids; $service_array['category_details'] = $this->category_details( $category_ids ); } $service_array['shortcode'] = '[booktics-service-view id="' . $service_array['id'] . '"]'; $service_array = apply_filters( 'booktics_service_format', $service_array ); $enhanced_items[] = $service_array; } $data['items'] = $enhanced_items; } return $this->response( $data ); } /** * Check if a given request has access to get items. * * @param $request * * @return WP_Error */ public function get_items_permissions_check( $request ): bool { return true; } /** * Create one item from the collection. * * @param $request * * @return WP_HTTP_Response * @throws Exception */ public function create_item( $request ) { $data = $this->prepare_item_for_database( $request ); if ( is_wp_error( $data ) ) { return $this->error( $data->get_error_message() ); } $service = Service_Model::create( $data ); do_action( 'booktics_service_created', $service, $request ); if ( is_wp_error( $service ) ) { return $this->error( $service->get_error_message() ); } $service = $service->to_array(); $service['shortcode'] = '[booktics-service-view id="' . $service['id'] . '"]'; $service['category_details'] = array(); $service['team_member_details'] = array(); $service = apply_filters( 'booktics_service_format', $service ); return $this->response( $service, __( 'Successfully created service', 'booktics' ) ); } /** * Check if a given request has access to create items. * * @param $request * * @return WP_Error */ public function create_item_permissions_check( $request ): bool { return true; } /** * Update one item from the collection. * * @param $request * * @return WP_HTTP_Response * @throws Exception */ public function update_item( $request ) { $id = (int) $request->get_param( 'id' ); $data = $this->prepare_item_for_database( $request ); if ( is_wp_error( $data ) ) { return $this->error( $data->get_error_message() ); } $service = Service_Model::find( $id ); if ( ! $service ) { return $this->error( __( 'Service not found', 'booktics' ), 404 ); } $result = $service->update( $data ); if ( is_wp_error( $result ) ) { return $this->error( $result->get_error_message() ); } if ( ! empty( $data['team_member'] ) && is_array( $data['team_member'] ) ) { foreach ( $data['team_member'] as $team_member_id ) { $team_member_model = ( new Team_Member_Model( $team_member_id ) ); $team_member = $team_member_model->find( $team_member_id ); $team_member_services = $team_member->services == '' ? array() : $team_member->services; if ( ! in_array( (int) $id, $team_member_services ) ) { $team_member_services[] = (int) $id; if ( $team_member ) { $team_member->update( array( 'services' => $team_member_services, ) ); } } } } $input_data = json_decode( $request->get_body(), true ); if ( isset( $input_data['schedule'] ) || isset( $input_data['custom'] ) || isset( $input_data['holiday'] ) ) { $service_schedule = Schedule_Manager::make( $input_data ); $service_schedule->with_service_id( $request['id'] ); $service_schedule->save(); } do_action( 'booktics_service_updated', $service, $request ); $response = Service_Model::find( $id )->to_array(); $response['shortcode'] = '[booktics-service-view id="' . $response['id'] . '"]'; $response['team_member_details'] = $this->team_member_details( $response['team_member'] ); if ( ! empty( $response['categories'] ) ) { $category_ids = is_array( $response['categories'] ) ? $response['categories'] : array( $response['categories'] ); $response['category_details'] = $this->category_details( $category_ids ); } $response = apply_filters( 'booktics_service_format', $response ); return $this->response( $response, __( 'Successfully updated service', 'booktics' ) ); } /** * Check if a given request has access to update a specific item. * * @param $request * * @return WP_Error */ public function update_item_permissions_check( $request ) { return true; } /** * Delete one item from the collection. * * @param $request * * @return WP_HTTP_Response */ public function delete_item( $request ) { $id = intval( $request['id'] ); $service = Service_Model::find( $id ); if ( ! $service ) { return $this->error( __( 'Service not found', 'booktics' ), 404 ); } $deleted = $service->delete(); if ( is_wp_error( $deleted ) ) { return $this->error( $deleted->get_error_message() ); } return $this->response( (array) $service, __( 'Successfully deleted service', 'booktics' ) ); } /** * Check if a given request has access to delete a specific item. * * @param $request * * @return WP_Error */ public function delete_item_permissions_check( $request ) { return current_user_can( 'manage_options' ); } /** * Delete a collection of items * * @param $request * * @return WP_HTTP_Response */ public function delete_items( $request ) { $ids = $request['ids']; if ( ! is_array( $ids ) ) { return $this->error( __( 'Ids should be an array of items ids', 'booktics' ) ); } $count = 0; $total = count( $ids ); foreach ( $ids as $id ) { $service = Service_Model::find( $id ); if ( $service ) { $service->delete(); ++$count; } } if ( $count === 0 ) { return $this->error( __( 'No item deleted.', 'booktics' ) ); } $message = sprintf( 'Deleted %d items of %d', $count, $total ); return $this->response( array(), $message ); } /** * Check if a given request has access to delete a collection of items. * * @param $request * * @return WP_Error */ public function delete_items_permissions_check( $request ) { return current_user_can( 'manage_options' ); } /** * Prepare the item for create or update operation. * * @param $request * * @return WP_Error */ public function prepare_item_for_database( $request ) { $data = json_decode( $request->get_body(), true ); $validate = booktics_validate( $data, array( 'title' => array( 'required', ), ) ); if ( is_wp_error( $validate ) ) { return $validate; } $data['title'] = ! empty( $data['title'] ) ? sanitize_text_field( $data['title'] ) : ''; $data['description'] = ! empty( $data['description'] ) ? sanitize_text_field( $data['description'] ) : ''; $data['content'] = ! empty( $data['content'] ) ? sanitize_text_field( $data['content'] ) : ''; $data['link'] = ! empty( $data['link'] ) ? sanitize_text_field( $data['link'] ) : ''; $data['image'] = ! empty( $data['image'] ) ? esc_url_raw( $data['image'] ) : ''; $data['image_id'] = ! empty( $data['image_id'] ) ? esc_url_raw( $data['image_id'] ) : ''; $data['interval_time'] = ! empty( $data['interval_time'] ) ? sanitize_text_field( $data['interval_time'] ) : ''; $data['before_buffer_time'] = ! empty( $data['before_buffer_time'] ) ? sanitize_text_field( $data['before_buffer_time'] ) : ''; $data['status'] = ! empty( $data['status'] ) ? sanitize_text_field( $data['status'] ) : 'deactive'; $data['team_member'] = empty( $data['team_member'] ) ? array() : array_unique( $data['team_member'] ); $data['categories'] = empty( $data['categories'] ) ? array() : array_unique( $data['categories'] ); $sanitized_durations = array(); if ( ! empty( $data['additional_durations'] ) ) { foreach ( $data['additional_durations'] as $duration ) { if ( is_array( $duration ) ) { $sanitized_durations[] = array( 'id' => ! empty( $duration['id'] ) ? sanitize_text_field( $duration['id'] ) : '', 'name' => ! empty( $duration['name'] ) ? sanitize_text_field( $duration['name'] ) : '', 'duration_time' => ! empty( $duration['duration_time'] ) ? sanitize_text_field( $duration['duration_time'] ) : '', 'duration_unit' => ! empty( $duration['duration_unit'] ) ? sanitize_text_field( $duration['duration_unit'] ) : '', 'charge_amount' => ! empty( $duration['charge_amount'] ) ? (float) number_format( (float) $duration['charge_amount'], 4, '.', '' ) : '0.0000', 'deposit_amount' => ! empty( $duration['deposit_amount'] ) ? (float) number_format( (float) $duration['deposit_amount'], 4, '.', '' ) : '0.0000', ); } } } $data['additional_durations'] = $sanitized_durations; $data = apply_filters( 'booktics_prepare_service_custom_fields', $data ); $image_url = $request->get_param( 'image' ); if ( $image_url ) { $data['image'] = esc_url_raw( $image_url ); } return $data; } /** * Clone service from the record. * * @param $request * * @return WP_HTTP_Response * @throws Exception */ public function clone_item( $request ) { $id = intval( $request['id'] ); $service = Service_Model::find( $id ); if ( ! $service ) { return $this->error( __( 'Service not found', 'booktics' ), 404 ); } $cloned = Service_Model::create( array( 'title' => $service->title . __( ' Copy', 'booktics' ), 'description' => $service->description, 'content' => $service->content, 'image' => $service->image, 'image_id' => $service->image_id, 'categories' => $service->categories, 'interval_time' => $service->interval_time, 'before_buffer_time' => $service->before_buffer_time, 'after_buffer_time' => $service->after_buffer_time, 'team_member' => $service->team_member, 'show_end_time' => $service->show_end_time, 'additional_durations' => $service->additional_durations, 'enable_custom_holiday' => $service->enable_custom_holiday, 'enable_custom_schedule' => $service->enable_custom_schedule, 'enable_additional_service_duration' => $service->enable_additional_service_duration, 'custom_field' => $service->custom_field, 'extra_services' => $service->extra_services, ) ); if ( is_wp_error( $cloned ) ) { return $this->error( $cloned->get_error_message() ); } $schedule_record = ( new Schedule_Record() ) ->get_schedules( $id, 'service' ); $schedule_data['schedule'] = $schedule_record['schedule']; $schedule_data['custom'] = $schedule_record['custom']; $schedule_data['holiday'] = $schedule_record['holiday']; $service_schedule = Schedule_Manager::make( $schedule_data ); $service_schedule->with_service_id( $cloned->id ); $service_schedule->save(); $team_member_details = $this->team_member_details( $service->team_member ); $cloned = $cloned->to_array(); $cloned['team_member_details'] = $team_member_details; $clone_schedule_record = ( new Schedule_Record() ) ->get_schedules( $cloned['id'], 'service' ); $cloned['schedule'] = empty( $clone_schedule_record['schedule'] ) ? (object) array() : $clone_schedule_record['schedule']; $cloned['custom'] = $clone_schedule_record['custom']; $cloned['holiday'] = $clone_schedule_record['holiday']; $cloned = apply_filters( 'booktics_service_format', $cloned ); return $this->response( $cloned, __( 'Successfully cloned service', 'booktics' ) ); } /** * Map team member details * * @param $team_member_ids * * @return array */ private function team_member_details( $team_member_ids ): array { $team_member_details = array(); foreach ( $team_member_ids as $team_member_id ) { $team_member = ( new Team_Member_Model() )->find( $team_member_id ); if ( $team_member ) { $team_member = $team_member->to_array(); $team_member_details[] = array( 'id' => $team_member['id'], 'display_name' => $team_member['display_name'], 'email' => $team_member['email'], 'image' => $team_member['image'], ); } } return $team_member_details; } /** * Get category details for given category IDs. * * @param array|int[] $category_ids * * @return array */ private function category_details( $category_ids ): array { $category_details = array(); foreach ( $category_ids as $category_id ) { $category = get_term( $category_id, ( new Category() )->get_name() ); if ( $category ) { $category = $category->to_array(); $category_details[] = array( 'id' => $category['term_id'], 'name' => $category['name'], ); } } return $category_details; } }