$max ) { $n = $max; } return $n . 'px'; } /** * Clamp a value to an integer range. * * @param mixed $value Raw value. * @param int $min Minimum. * @param int $max Maximum. * @param int $fallback Fallback when non-numeric. * @return int */ public static function clampInt( $value, $min, $max, $fallback ) { if ( ! is_numeric( $value ) ) { return (int) $fallback; } $value = (int) $value; if ( $value < $min ) { return (int) $min; } if ( $value > $max ) { return (int) $max; } return $value; } /** * Handle the `bb_atc_add_to_cart` AJAX request for simple products. * * Returns JSON: { added, productName, cartCount, cartUrl } or an error. */ public function ajaxAddToCart() { check_ajax_referer( 'bb_atc_add_to_cart', 'nonce' ); if ( ! function_exists( 'WC' ) || ! WC()->cart ) { wp_send_json_error( [ 'message' => __( 'WooCommerce is not available.', 'b-blocks' ) ] ); } $productId = isset( $_POST['product_id'] ) ? absint( wp_unslash( $_POST['product_id'] ) ) : 0; if ( $productId < 1 ) { wp_send_json_error( [ 'message' => __( 'Invalid product.', 'b-blocks' ) ] ); } $quantity = isset( $_POST['quantity'] ) ? absint( wp_unslash( $_POST['quantity'] ) ) : 1; $quantity = self::clampInt( $quantity, 1, 99, 1 ); $product = wc_get_product( $productId ); if ( ! $product || ! is_a( $product, 'WC_Product' ) ) { wp_send_json_error( [ 'message' => __( 'Product not found.', 'b-blocks' ) ] ); } if ( ! $product->is_type( 'simple' ) || ! $product->is_purchasable() || ! $product->is_in_stock() ) { wp_send_json_error( [ 'message' => __( 'This product cannot be added to the cart.', 'b-blocks' ) ] ); } $added = WC()->cart->add_to_cart( $productId, $quantity ); if ( ! $added ) { wp_send_json_error( [ 'message' => __( 'Could not add the product to the cart.', 'b-blocks' ) ] ); } wp_send_json_success( [ 'added' => true, 'productName' => wp_strip_all_tags( $product->get_name() ), 'cartCount' => WC()->cart->get_cart_contents_count(), 'cartUrl' => function_exists( 'wc_get_cart_url' ) ? wc_get_cart_url() : '', ] ); } } new WooAddToCart();