You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Woocommerce多商品带附加组件的URL添加购物车方案问询

问题描述

我用ChatGPT编写了一款WooCommerce插件,支持通过URL将带附加组件的商品加入外部购物车,但目前仅支持单个商品。我需要扩展功能,实现多个带不同附加组件的商品通过URL批量加入购物车。

现有单商品URL结构

https://example.local:8890/example/basket/?add-to-cart=1099&quantity=1&size=16%20(2-3yrs)&shirt_name=MESSI&shirt_number=10&add_matching_socks=true&add_league_patches_to_arms=true

现有插件代码

<?php
/**
 * Plugin Name: Custom Add to Cart
 * Description: Adds support for adding multiple products with quantities to the cart via URL.
 * Version: 1.0
 * Author: Chris / ChatGPT
 * Author URI: https://example.com/
 * Text Domain: custom-add-to-cart
 * Domain Path: /languages
 */

function webroom_modify_cart_data($cart_item_data, $product_id, $variation_id, $quantity) {
    // Process add-ons
    $addons = array();
    if (isset($_REQUEST['size'])) {
        $addons['size'] = sanitize_text_field($_REQUEST['size']);
    }
    if (isset($_REQUEST['shirt_name'])) {
        $addons['shirt_name'] = sanitize_text_field($_REQUEST['shirt_name']);
    }
    if (isset($_REQUEST['shirt_number'])) {
        $addons['shirt_number'] = sanitize_text_field($_REQUEST['shirt_number']);
    }
    if (isset($_REQUEST['add_matching_socks'])) {
        $addons['add_matching_socks'] = filter_var($_REQUEST['add_matching_socks'], FILTER_VALIDATE_BOOLEAN);
    }
    if (isset($_REQUEST['add_league_patches_to_arms'])) {
        $addons['add_league_patches_to_arms'] = filter_var($_REQUEST['add_league_patches_to_arms'], FILTER_VALIDATE_BOOLEAN);
    }

    // Add add-ons as cart item data
    foreach ($addons as $addon_name => $addon_value) {
        $cart_item_data["webroom_{$addon_name}"] = $addon_value;
    }

    return $cart_item_data;
}

add_filter('woocommerce_add_cart_item_data', 'webroom_modify_cart_data', 10, 4);

function webroom_get_cart_item_from_session($cart_item, $values) {
    // Add add-ons from session data to cart item
    if (is_array($values)) {
        foreach ($values as $key => $value) {
            if (strpos($key, 'webroom_') === 0) {
                $cart_item[$key] = $value;
            }
        }
    }

    return $cart_item;
}

add_filter('woocommerce_get_cart_item_from_session', 'webroom_get_cart_item_from_session', 20, 2);

function webroom_add_cart_item_data($item_data, $cart_item) {
    // Add custom data to cart item display
    foreach ($cart_item as $key => $value) {
        if (strpos($key, 'webroom_') === 0) {
            if ($key === 'webroom_add_matching_socks') {
                $value = $value ? '(+£3.49)' : '';
            } elseif ($key === 'webroom_add_league_patches_to_arms') {
                $value = $value ? '(+£1.99)' : '';
            }
            $item_data[] = array(
                'name'  => str_replace('_', ' ', substr($key, 8)),
                'value' => $value
            );
        }
    }

    return $item_data;
}

add_filter('woocommerce_get_item_data', 'webroom_add_cart_item_data', 10, 2);

function webroom_calculate_cart_totals($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        // Check if the cart item was added via URL or manually
        $added_via_url = isset($cart_item['webroom_size']) && isset($cart_item['webroom_shirt_name']);

        // Get the product price based on how it was added to the cart
        if ($added_via_url) {
            $product = wc_get_product($cart_item['product_id']);
            $product_price = $product->get_price();
        } else {
            $product = $cart_item['data'];
            $product_price = $cart_item['line_subtotal'] / $cart_item['quantity'];
        }

        // Calculate add-ons cost
        $add_ons_cost = 0;
        if (isset($cart_item['webroom_add_matching_socks']) && $cart_item['webroom_add_matching_socks']) {
            $add_ons_cost += 3.49;
        }
        if (isset($cart_item['webroom_add_league_patches_to_arms']) && $cart_item['webroom_add_league_patches_to_arms']) {
            $add_ons_cost += 1.99;
        }

        // Calculate item subtotal and total based on add-ons
        $item_subtotal = $product_price + $add_ons_cost;
        $item_total = $item_subtotal * $cart_item['quantity'];

        // Update cart item data with new totals
        $cart_item['data']->set_price($item_subtotal);
        $cart_item['line_subtotal'] = $item_subtotal;
        $cart_item['line_total'] = $item_total;

        // Save updated data back to the cart
        $cart->cart_contents[$cart_item_key] = $cart_item;
    }
}

add_action('woocommerce_calculate_totals', 'webroom_calculate_cart_totals');

附加组件说明

size:16 (2-3yrs) shirt name:MESSI shirt number:10 add matching socks:(+£3.49) add league patches to arms:(+£1.99)

技术需求

需要构造包含多个商品的URL(比如另一个商品:球衣名KANE、号码9,其他附加组件可自定义),并修改插件代码以支持批量处理这些商品,实现多商品带附加组件加入购物车。


解决方案

1. 多商品URL构造规则

采用数组式参数命名,每个商品的参数通过索引区分(从0开始):

  • 商品ID:add-to-cart[0]=1099、add-to-cart[1]=1099(同一款商品ID可重复)
  • 数量:quantity[0]=1、quantity[1]=1
  • 附加组件:size[0]=16%20(2-3yrs)、shirt_name[0]=MESSI;size[1]=18%20(4-5yrs)、shirt_name[1]=KANE

示例URL

https://example.local:8890/example/basket/?add-to-cart[0]=1099&quantity[0]=1&size[0]=16%20(2-3yrs)&shirt_name[0]=MESSI&shirt_number[0]=10&add_matching_socks[0]=true&add_league_patches_to_arms[0]=true&add-to-cart[1]=1099&quantity[1]=1&size[1]=18%20(4-5yrs)&shirt_name[1]=KANE&shirt_number[1]=9&add_matching_socks[1]=false&add_league_patches_to_arms[1]=true

2. 插件代码修改

替换原有的webroom_modify_cart_data函数,新增批量处理逻辑,其他函数保持不变:

修改后的完整插件代码

<?php
/**
 * Plugin Name: Custom Add to Cart
 * Description: Adds support for adding multiple products with quantities to the cart via URL.
 * Version: 2.0
 * Author: Chris / ChatGPT
 * Text Domain: custom-add-to-cart
 * Domain Path: /languages
 */

// 批量处理多商品添加请求
function webroom_handle_multiple_add_to_cart() {
    if (isset($_REQUEST['add-to-cart']) && is_array($_REQUEST['add-to-cart'])) {
        foreach ($_REQUEST['add-to-cart'] as $index => $product_id) {
            $product_id = sanitize_text_field($product_id);
            $quantity = isset($_REQUEST['quantity'][$index]) ? absint($_REQUEST['quantity'][$index]) : 1;
            
            // 收集当前商品的附加组件
            $addons = [];
            $addon_fields = ['size', 'shirt_name', 'shirt_number', 'add_matching_socks', 'add_league_patches_to_arms'];
            foreach ($addon_fields as $field) {
                if (isset($_REQUEST[$field][$index])) {
                    if (in_array($field, ['add_matching_socks', 'add_league_patches_to_arms'])) {
                        $addons[$field] = filter_var($_REQUEST[$field][$index], FILTER_VALIDATE_BOOLEAN);
                    } else {
                        $addons[$field] = sanitize_text_field($_REQUEST[$field][$index]);
                    }
                }
            }

            // 添加商品到购物车,并传递附加组件数据
            $cart_item_data = [];
            foreach ($addons as $addon_name => $addon_value) {
                $cart_item_data["webroom_{$addon_name}"] = $addon_value;
            }

            WC()->cart->add_to_cart($product_id, $quantity, 0, [], $cart_item_data);
        }
        // 重定向到购物车页面(可选,根据需求调整)
        wp_redirect(wc_get_cart_url());
        exit;
    }
}
add_action('template_redirect', 'webroom_handle_multiple_add_to_cart');

function webroom_get_cart_item_from_session($cart_item, $values) {
    // Add add-ons from session data to cart item
    if (is_array($values)) {
        foreach ($values as $key => $value) {
            if (strpos($key, 'webroom_') === 0) {
                $cart_item[$key] = $value;
            }
        }
    }

    return $cart_item;
}

add_filter('woocommerce_get_cart_item_from_session', 'webroom_get_cart_item_from_session', 20, 2);

function webroom_add_cart_item_data($item_data, $cart_item) {
    // Add custom data to cart item display
    foreach ($cart_item as $key => $value) {
        if (strpos($key, 'webroom_') === 0) {
            if ($key === 'webroom_add_matching_socks') {
                $value = $value ? '(+£3.49)' : '';
            } elseif ($key === 'webroom_add_league_patches_to_arms') {
                $value = $value ? '(+£1.99)' : '';
            }
            $item_data[] = array(
                'name'  => str_replace('_', ' ', substr($key, 8)),
                'value' => $value
            );
        }
    }

    return $item_data;
}

add_filter('woocommerce_get_item_data', 'webroom_add_cart_item_data', 10, 2);

function webroom_calculate_cart_totals($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        // Check if the cart item was added via URL or manually
        $added_via_url = isset($cart_item['webroom_size']) && isset($cart_item['webroom_shirt_name']);

        // Get the product price based on how it was added to the cart
        if ($added_via_url) {
            $product = wc_get_product($cart_item['product_id']);
            $product_price = $product->get_price();
        } else {
            $product = $cart_item['data'];
            $product_price = $cart_item['line_subtotal'] / $cart_item['quantity'];
        }

        // Calculate add-ons cost
        $add_ons_cost = 0;
        if (isset($cart_item['webroom_add_matching_socks']) && $cart_item['webroom_add_matching_socks']) {
            $add_ons_cost += 3.49;
        }
        if (isset($cart_item['webroom_add_league_patches_to_arms']) && $cart_item['webroom_add_league_patches_to_arms']) {
            $add_ons_cost += 1.99;
        }

        // Calculate item subtotal and total based on add-ons
        $item_subtotal = $product_price + $add_ons_cost;
        $item_total = $item_subtotal * $cart_item['quantity'];

        // Update cart item data with new totals
        $cart_item['data']->set_price($item_subtotal);
        $cart_item['line_subtotal'] = $item_subtotal;
        $cart_item['line_total'] = $item_total;

        // Save updated data back to the cart
        $cart->cart_contents[$cart_item_key] = $cart_item;
    }
}

add_action('woocommerce_calculate_totals', 'webroom_calculate_cart_totals');

代码修改说明

  1. 新增webroom_handle_multiple_add_to_cart函数:

    • 检测URL中的数组形式参数add-to-cart,遍历每个商品索引
    • 按索引收集对应商品的数量和附加组件参数
    • 调用WC()->cart->add_to_cart()逐个添加商品,并传递附加组件数据
    • 可选重定向到购物车页面,避免重复提交
  2. 移除原woocommerce_add_cart_item_data钩子绑定:

    • 批量处理时已直接传递cart_item_data,无需再通过该钩子处理

内容的提问来源于stack exchange,提问作者Amesey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:42:02