bump_module = new \ArrayFunnel\Features\OrderBumps\Services\OrderBump( false ); parent::__construct(); } public function registerRoutes(): void { // GET/POST /arrayfunnel/v1/bumps register_rest_route( $this->namespace, '/bumps', [ [ 'methods' => \WP_REST_Server::READABLE, 'callback' => [ $this, 'getBumps' ], 'permission_callback' => [ $this, 'checkPermission' ], ], [ 'methods' => \WP_REST_Server::CREATABLE, 'callback' => [ $this, 'createBump' ], 'permission_callback' => [ $this, 'checkPermission' ], 'args' => [ 'title' => [ 'sanitize_callback' => 'sanitize_text_field', ], 'product_id' => [ 'required' => true, 'sanitize_callback' => 'absint', 'validate_callback' => function ( $value ) { return (int) $value > 0; }, ], 'condition_type' => [ 'sanitize_callback' => 'sanitize_key', 'validate_callback' => function ( $value ) { return in_array( (string) $value, [ 'all', 'product', 'category', 'cart_total' ], true ); }, ], 'template' => [ 'sanitize_callback' => 'sanitize_key', 'validate_callback' => function ( $value ) { return in_array( (string) $value, [ 'classic', 'highlight', 'minimal' ], true ); }, ], 'status' => [ 'sanitize_callback' => 'absint', 'validate_callback' => function ( $value ) { return in_array( (int) $value, [ 0, 1 ], true ); }, ], 'priority' => [ 'sanitize_callback' => 'absint', 'validate_callback' => function ( $value ) { return (int) $value >= 0 && (int) $value <= 999; }, ], ], ], ] ); // GET/PUT/DELETE /arrayfunnel/v1/bumps/{id} register_rest_route( $this->namespace, '/bumps/(?P\d+)', [ [ 'methods' => \WP_REST_Server::READABLE, 'callback' => [ $this, 'getBump' ], 'permission_callback' => [ $this, 'checkPermission' ], ], [ 'methods' => \WP_REST_Server::EDITABLE, 'callback' => [ $this, 'updateBump' ], 'permission_callback' => [ $this, 'checkPermission' ], 'args' => [ 'id' => [ 'required' => true, 'sanitize_callback' => 'absint', 'validate_callback' => function ( $value ) { return (int) $value > 0; }, ], 'title' => [ 'sanitize_callback' => 'sanitize_text_field', ], 'product_id' => [ 'sanitize_callback' => 'absint', 'validate_callback' => function ( $value ) { return '' === $value || (int) $value > 0; }, ], 'condition_type' => [ 'sanitize_callback' => 'sanitize_key', 'validate_callback' => function ( $value ) { return '' === $value || in_array( (string) $value, [ 'all', 'product', 'category', 'cart_total' ], true ); }, ], 'template' => [ 'sanitize_callback' => 'sanitize_key', 'validate_callback' => function ( $value ) { return '' === $value || in_array( (string) $value, [ 'classic', 'highlight', 'minimal' ], true ); }, ], 'status' => [ 'sanitize_callback' => 'absint', 'validate_callback' => function ( $value ) { return '' === $value || in_array( (int) $value, [ 0, 1 ], true ); }, ], ], ], [ 'methods' => \WP_REST_Server::DELETABLE, 'callback' => [ $this, 'deleteBump' ], 'permission_callback' => [ $this, 'checkPermission' ], 'args' => [ 'id' => [ 'required' => true, 'sanitize_callback' => 'absint', 'validate_callback' => function ( $value ) { return (int) $value > 0; }, ], ], ], ] ); } public function getBumps( \WP_REST_Request $request ): \WP_REST_Response { $page = max( 1, (int) $request->get_param( 'page' ) ); $per_page = min( 100, max( 1, (int) ( $request->get_param( 'per_page' ) ?? 20 ) ) ); $offset = ( $page - 1 ) * $per_page; $bumps = $this->bump_module->getBumps( $per_page, $offset ); // Enrich with product data $enriched = array_map( function ( $bump ) { $product = wc_get_product( $bump->product_id ); $bump->product_name = $product ? $product->get_name() : ''; $bump->product_price_value = $product ? (float) $product->get_price() : 0.0; $bump->product_price_formatted = $product ? wc_price( (float) $product->get_price() ) : ''; $bump->product_image = $product ? wp_get_attachment_image_url( $product->get_image_id(), 'thumbnail' ) : ''; $bump->display_settings = json_decode( $bump->display_settings ?? '{}', true ); $bump->condition_value = json_decode( $bump->condition_value ?? 'null', true ); $bump->status = (int) $bump->status; return $bump; }, $bumps ); $total_count = $this->bump_module->countBumps(); return $this->success( [ 'items' => $enriched, 'total_count' => $total_count, ] ); } public function getBump( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error { $bump = $this->bump_module->getBump( (int) $request->get_param( 'id' ) ); if ( ! $bump ) { return $this->error( __( 'Bump not found.', 'arrayfunnel' ), 404 ); } $bump->display_settings = json_decode( $bump->display_settings ?? '{}', true ); $bump->condition_value = json_decode( $bump->condition_value ?? 'null', true ); $bump->status = (int) $bump->status; return $this->success( $bump ); } public function createBump( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error { $product_id = (int) $request->get_param( 'product_id' ); if ( ! $product_id || ! wc_get_product( $product_id ) ) { return $this->error( __( 'Valid product_id is required.', 'arrayfunnel' ), 400 ); } $id = $this->bump_module->createBump( [ 'title' => $request->get_param( 'title' ) ?? '', 'product_id' => $product_id, 'condition_type' => $request->get_param( 'condition_type' ) ?? 'all', 'condition_value' => $request->get_param( 'condition_value' ), 'display_settings' => $request->get_param( 'display_settings' ) ?? [], 'template' => $request->get_param( 'template' ) ?? 'classic', 'status' => $request->get_param( 'status' ) ?? 1, 'priority' => $request->get_param( 'priority' ) ?? 0, ] ); $bump = $this->bump_module->getBump( $id ); return $this->success( $bump, 201 ); } public function updateBump( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error { $id = (int) $request->get_param( 'id' ); $existing = $this->bump_module->getBump( $id ); if ( ! $existing ) { return $this->error( __( 'Bump not found.', 'arrayfunnel' ), 404 ); } $this->bump_module->updateBump( $id, $request->get_params() ); $bump = $this->bump_module->getBump( $id ); $bump->display_settings = json_decode( $bump->display_settings ?? '{}', true ); return $this->success( $bump ); } public function deleteBump( \WP_REST_Request $request ): \WP_REST_Response|\WP_Error { $id = (int) $request->get_param( 'id' ); if ( ! $this->bump_module->getBump( $id ) ) { return $this->error( __( 'Bump not found.', 'arrayfunnel' ), 404 ); } $this->bump_module->deleteBump( $id ); return $this->success( [ 'deleted' => true ] ); } }