WooCommerce 添加到购物车,从自定义 select 字段添加第二个产品
WooCommerce Add to cart, add second product from a custom select field
我需要的
我想简单地实现产品附加组件,而不使用对我的需求来说过于强大的重量级插件。此外,我希望能够跟踪任何插件不提供的附加组件库存。为了让事情更清楚一点,我可以说主要产品是一个吊坠,附加产品是一条链子。客户应该能够 select 吊坠页面上的链条,当他或她单击“添加到购物车”按钮时,两个项目都应添加到购物车。
所以我想我可以把隐藏的单品作为附加品。我的想法是在我的附加产品中添加一个下拉列表,并通过 POST 获得 selected 值,并将其与主要产品一起添加到购物车。到目前为止一切顺利。
我做了什么
这是我的代码:
add_action( 'woocommerce_before_add_to_cart_button', 'chain_selection_field' );
function chain_selection_field() {
global $product;
$domain = 'woocommerce';
$args = array(
'sku' => 'SOME_TEXT',
'stock_status' => 'instock',
);
$products = wc_get_products( $args );
foreach ($products as $product) {
$product_id = $product->get_id();
$options[$product_id] = $product->get_name();
}
woocommerce_form_field('chain_type', array(
'type' => 'select',
'label' => __('Chain type selection', $domain),
'required' => true,
'options' => $options,
),'');
}
add_action('woocommerce_add_to_cart', 'product_option_add_to_cart');
function product_option_add_to_cart() {
$product_id = $_POST['chain_type'];
$found = false;
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
WC()->cart->add_to_cart( $product_id );
}
}
添加到购物车的实现取自此处 - How to add filter or hook for "woocommerce_add_to_cart"
有什么问题?
其实有很多问题:
- 只要我 select 下拉列表中的某个值就会永久保留。即使在刷新页面后,即使我选择了另一个值,它仍然会添加到购物车中。看来我必须以某种方式清除 POST 值。我尝试在添加到购物车功能的末尾添加
$_POST = array();
或 unset($_POST);
,但这没有用。
- 主要产品未添加到购物车 - 当我点击 "add to cart" 时,只有附加产品添加到购物车。我用预设的产品 ID 分别检查了添加到购物车功能,发现它按预期工作并且两个产品都添加到购物车。
问题是我在 foreach 循环中使用了全局变量 $product
。所以它打破了循环逻辑并使用全局 $product
而不是所需的数组值。因此,要使代码正常工作,只需将 foreach 循环代码更改为类似以下内容:
foreach ($products as $single_product) {
$product_id = $single_product->get_id();
$options[$product_id] = $single_product->get_name();
除此之外,代码运行良好,但我必须做几点说明:
- 代码只有在通过按添加到购物车按钮提交的
<form> ... </form>
内部调用的钩子插入时才有效,即 woocommerce_before_add_to_cart_button
、woocommerce_before_add_to_cart_quantity
和 woocommerce_after_add_to_cart_quantity
(你可以在模板中自己检查 - https://github.com/woocommerce/woocommerce/blob/4.1.0/templates/single-product/add-to-cart/simple.php) for simple product and also a few hooks called inside variation loop vor variable product which can be found here - https://github.com/woocommerce/woocommerce/blob/4.1.0/templates/single-product/add-to-cart/variable.php
- 当通过
woocommerce_before_add_to_cart_button
插入时,输入字段位于产品库存文本和添加到购物车按钮之间,这不是最佳位置,看起来您要么必须编辑模板文件,要么使用 JS 来实现更好的放置使用当前的 WC (4.1) 挂钩。
wc_get_products ()
函数比较慢。在我的测试中,它比通过 $wpdb->get_results
进行的类似查询慢 10 倍
- 最好将
product_option_add_to_cart()
自定义函数代码插入 if (isset($_POST['chain_type'])) { ... }
以防止 PHP 在由于某种原因没有 $_POST 值时出现通知
我需要的
我想简单地实现产品附加组件,而不使用对我的需求来说过于强大的重量级插件。此外,我希望能够跟踪任何插件不提供的附加组件库存。为了让事情更清楚一点,我可以说主要产品是一个吊坠,附加产品是一条链子。客户应该能够 select 吊坠页面上的链条,当他或她单击“添加到购物车”按钮时,两个项目都应添加到购物车。
所以我想我可以把隐藏的单品作为附加品。我的想法是在我的附加产品中添加一个下拉列表,并通过 POST 获得 selected 值,并将其与主要产品一起添加到购物车。到目前为止一切顺利。
我做了什么
这是我的代码:
add_action( 'woocommerce_before_add_to_cart_button', 'chain_selection_field' );
function chain_selection_field() {
global $product;
$domain = 'woocommerce';
$args = array(
'sku' => 'SOME_TEXT',
'stock_status' => 'instock',
);
$products = wc_get_products( $args );
foreach ($products as $product) {
$product_id = $product->get_id();
$options[$product_id] = $product->get_name();
}
woocommerce_form_field('chain_type', array(
'type' => 'select',
'label' => __('Chain type selection', $domain),
'required' => true,
'options' => $options,
),'');
}
add_action('woocommerce_add_to_cart', 'product_option_add_to_cart');
function product_option_add_to_cart() {
$product_id = $_POST['chain_type'];
$found = false;
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
WC()->cart->add_to_cart( $product_id );
}
}
添加到购物车的实现取自此处 - How to add filter or hook for "woocommerce_add_to_cart"
有什么问题?
其实有很多问题:
- 只要我 select 下拉列表中的某个值就会永久保留。即使在刷新页面后,即使我选择了另一个值,它仍然会添加到购物车中。看来我必须以某种方式清除 POST 值。我尝试在添加到购物车功能的末尾添加
$_POST = array();
或unset($_POST);
,但这没有用。 - 主要产品未添加到购物车 - 当我点击 "add to cart" 时,只有附加产品添加到购物车。我用预设的产品 ID 分别检查了添加到购物车功能,发现它按预期工作并且两个产品都添加到购物车。
问题是我在 foreach 循环中使用了全局变量 $product
。所以它打破了循环逻辑并使用全局 $product
而不是所需的数组值。因此,要使代码正常工作,只需将 foreach 循环代码更改为类似以下内容:
foreach ($products as $single_product) {
$product_id = $single_product->get_id();
$options[$product_id] = $single_product->get_name();
除此之外,代码运行良好,但我必须做几点说明:
- 代码只有在通过按添加到购物车按钮提交的
<form> ... </form>
内部调用的钩子插入时才有效,即woocommerce_before_add_to_cart_button
、woocommerce_before_add_to_cart_quantity
和woocommerce_after_add_to_cart_quantity
(你可以在模板中自己检查 - https://github.com/woocommerce/woocommerce/blob/4.1.0/templates/single-product/add-to-cart/simple.php) for simple product and also a few hooks called inside variation loop vor variable product which can be found here - https://github.com/woocommerce/woocommerce/blob/4.1.0/templates/single-product/add-to-cart/variable.php - 当通过
woocommerce_before_add_to_cart_button
插入时,输入字段位于产品库存文本和添加到购物车按钮之间,这不是最佳位置,看起来您要么必须编辑模板文件,要么使用 JS 来实现更好的放置使用当前的 WC (4.1) 挂钩。 wc_get_products ()
函数比较慢。在我的测试中,它比通过$wpdb->get_results
进行的类似查询慢 10 倍- 最好将
product_option_add_to_cart()
自定义函数代码插入if (isset($_POST['chain_type'])) { ... }
以防止 PHP 在由于某种原因没有 $_POST 值时出现通知
- 最好将