namespace, '/' . $this->rest_base . '/(?P[\d]+)', array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_cashier' ), 'permission_callback' => array( $this, 'check_cashier_permissions' ), 'args' => array( 'id' => array( 'description' => /* translators: REST API schema field label or error message. */ __( 'Unique identifier for the cashier (WordPress user ID).', 'woocommerce-pos' ), 'type' => 'integer', 'required' => true, ), ), ) ); // Get cashier stores: /wcpos/v1/cashier/{id}/stores. register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/stores', array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_cashier_stores' ), 'permission_callback' => array( $this, 'check_cashier_permissions' ), 'args' => array( 'id' => array( 'description' => /* translators: REST API schema field label or error message. */ __( 'Unique identifier for the cashier (WordPress user ID).', 'woocommerce-pos' ), 'type' => 'integer', 'required' => true, ), ), ) ); // Get specific store for cashier: /wcpos/v1/cashier/{id}/stores/{store_id}. register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/stores/(?P[\d]+)', array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_cashier_store' ), 'permission_callback' => array( $this, 'check_cashier_permissions' ), 'args' => array( 'id' => array( 'description' => /* translators: REST API schema field label or error message. */ __( 'Unique identifier for the cashier (WordPress user ID).', 'woocommerce-pos' ), 'type' => 'integer', 'required' => true, ), 'store_id' => array( 'description' => __( 'Unique identifier for the store.', 'woocommerce-pos' ), 'type' => 'integer', 'required' => true, ), ), ) ); } /** * Check permissions for cashier endpoints. * * Ensures the user is authenticated and can only access their own data. * * @param WP_REST_Request $request The REST request object. * * @return bool|WP_Error True if authorized, WP_Error otherwise. */ public function check_cashier_permissions( WP_REST_Request $request ) { // Check if user is authenticated. if ( ! is_user_logged_in() ) { return new WP_Error( 'woocommerce_pos_rest_unauthorized', /* translators: REST API schema field label or error message. */ __( 'Authentication required.', 'woocommerce-pos' ), array( 'status' => 401 ) ); } $current_user_id = get_current_user_id(); $requested_id = (int) $request->get_param( 'id' ); // Check if the requested user exists. $user = get_user_by( 'id', $requested_id ); if ( ! $user ) { return new WP_Error( 'woocommerce_pos_cashier_not_found', /* translators: REST API schema field label or error message. */ __( 'Cashier not found.', 'woocommerce-pos' ), array( 'status' => 404 ) ); } $cashier_service = CashierService::instance(); // Check if user has POS cashier permissions. if ( ! $cashier_service->has_cashier_permissions( $user ) ) { return new WP_Error( 'woocommerce_pos_rest_forbidden', __( 'User does not have POS cashier permissions.', 'woocommerce-pos' ), array( 'status' => 403 ) ); } // Validate access permissions. if ( ! $cashier_service->validate_cashier_access( $current_user_id, $requested_id ) ) { return new WP_Error( 'woocommerce_pos_rest_forbidden', __( 'You can only access your own cashier data.', 'woocommerce-pos' ), array( 'status' => 403 ) ); } return true; } /** * Get cashier data. * * @param WP_REST_Request $request The REST request object. * * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_cashier( WP_REST_Request $request ) { $user_id = (int) $request->get_param( 'id' ); $user = get_user_by( 'id', $user_id ); if ( ! $user ) { return new WP_Error( 'woocommerce_pos_cashier_not_found', /* translators: REST API schema field label or error message. */ __( 'Cashier not found.', 'woocommerce-pos' ), array( 'status' => 404 ) ); } $cashier_service = CashierService::instance(); $data = $cashier_service->get_cashier_data( $user, true ); /** * Filter cashier data for REST API response. * * @param array $data Cashier data. * @param WP_User $user User object. * @param WP_REST_Request $request Request object. */ $data = apply_filters( 'woocommerce_pos_rest_prepare_cashier', $data, $user, $request ); return rest_ensure_response( $data ); } /** * Get stores accessible by the cashier. * * @param WP_REST_Request $request The REST request object. * * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_cashier_stores( WP_REST_Request $request ) { $user_id = (int) $request->get_param( 'id' ); $user = get_user_by( 'id', $user_id ); if ( ! $user ) { return new WP_Error( 'woocommerce_pos_cashier_not_found', /* translators: REST API schema field label or error message. */ __( 'Cashier not found.', 'woocommerce-pos' ), array( 'status' => 404 ) ); } try { $cashier_service = CashierService::instance(); $stores = $cashier_service->get_accessible_stores( $user ); $response = array(); foreach ( $stores as $store ) { $data = $this->prepare_store_for_response( $store, $request ); $response[] = $data; } $response = rest_ensure_response( $response ); $response->header( 'X-WP-Total', (string) \count( $stores ) ); $response->header( 'X-WP-TotalPages', '1' ); return $response; } catch ( Exception $e ) { return new WP_Error( 'woocommerce_pos_stores_retrieval_failed', __( 'Failed to retrieve store data.', 'woocommerce-pos' ), array( 'status' => 500 ) ); } } /** * Get a specific store for the cashier. * * @param WP_REST_Request $request The REST request object. * * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_cashier_store( WP_REST_Request $request ) { $user_id = (int) $request->get_param( 'id' ); $store_id = (int) $request->get_param( 'store_id' ); $user = get_user_by( 'id', $user_id ); if ( ! $user ) { return new WP_Error( 'woocommerce_pos_cashier_not_found', /* translators: REST API schema field label or error message. */ __( 'Cashier not found.', 'woocommerce-pos' ), array( 'status' => 404 ) ); } $cashier_service = CashierService::instance(); $store = $cashier_service->get_accessible_store( $user, $store_id ); if ( ! $store ) { return new WP_Error( 'woocommerce_pos_store_not_found', __( 'Store not found or not accessible by this cashier.', 'woocommerce-pos' ), array( 'status' => 404 ) ); } $data = $this->prepare_store_for_response( $store, $request ); return rest_ensure_response( $data ); } /** * Prepare store data for response. * * @param Store $store Store object. * @param WP_REST_Request $request Request object. * * @return array Prepared store data. */ protected function prepare_store_for_response( Store $store, WP_REST_Request $request ): array { $data = $store->get_data(); /* * Filter store data for REST API response. * * @param array $data Store data. * @param Store $store Store object. * @param WP_REST_Request $request Request object. */ return apply_filters( 'woocommerce_pos_rest_prepare_store', $data, $store, $request ); } }