我们有独家类别X 和其他常规类别Y 。我想要的是什么:
我怎么能实现这个目标?
我从其他帖子中获取此代码,但其过时且不满意:
<?php
// Enforce single parent category items in cart at a time based on first item in cart
function get_product_top_level_category ( $product_id ) {
$product_terms = get_the_terms ( $product_id, 'product_cat' );
$product_category = $product_terms[0]->parent;
$product_category_term = get_term ( $product_category, 'product_cat' );
$product_category_parent = $product_category_term->parent;
$product_top_category = $product_category_term->term_id;
while ( $product_category_parent != 0 ) {
$product_category_term = get_term ( $product_category_parent, 'product_cat' );
$product_category_parent = $product_category_term->parent;
$product_top_category = $product_category_term->term_id;
}
return $product_top_category;
}
add_filter ( 'woocommerce_before_cart', 'restrict_cart_to_single_category' );
function restrict_cart_to_single_category() {
global $woocommerce;
$cart_contents = $woocommerce->cart->get_cart( );
$cart_item_keys = array_keys ( $cart_contents );
$cart_item_count = count ( $cart_item_keys );
// Do nothing if the cart is empty
// Do nothing if the cart only has one item
if ( ! $cart_contents || $cart_item_count == 1 ) {
return null;
}
// Multiple Items in cart
$first_item = $cart_item_keys[0];
$first_item_id = $cart_contents[$first_item]['product_id'];
$first_item_top_category = get_product_top_level_category ( $first_item_id );
$first_item_top_category_term = get_term ( $first_item_top_category, 'product_cat' );
$first_item_top_category_name = $first_item_top_category_term->name;
// Now we check each subsequent items top-level parent category
foreach ( $cart_item_keys as $key ) {
if ( $key == $first_item ) {
continue;
}
else {
$product_id = $cart_contents[$key]['product_id'];
$product_top_category = get_product_top_level_category( $product_id );
if ( $product_top_category != $first_item_top_category ) {
$woocommerce->cart->set_quantity ( $key, 0, true );
$mismatched_categories = 1;
}
}
}
// we really only want to display this message once for anyone, including those that have carts already prefilled
if ( isset ( $mismatched_categories ) ) {
echo '<p class="woocommerce-error">Only one category allowed in cart at a time.<br />You are currently allowed only <strong>'.$first_item_top_category_name.'</strong> items in your cart.<br />To order a different category empty your cart first.</p>';
}
}
?>
由于
答案 0 :(得分:3)
更新了(2019)
就像所有内容都在转变您的专属类别 category X
一样,您需要为此类别使用条件。
你有机会因为有一个特殊功能可以与woocommerce产品类别结合使用。让我们说**cat_x**
是您的独家类别的slug,正如您所知, product_cat
是获取产品类别的论据。
因此,使用 has_term ()
条件函数,您将使用此功能:
if ( has_term ('cat_x', 'product_cat', $item_id ) ) { // or $product_id
// doing something when product item has 'cat_x'
} else {
// doing something when product item has NOT 'cat_x'
}
我们需要在foreach循环中运行购物车项目2次:
cat_x
项。 cat_x
并触发正确的消息,则删除其他商品。在下面的代码中,我已经更改为更有用的钩子。此挂钩将检查您的购物车中有什么。想法是在购物车中添加“cat_x”项目时删除购物车中的其他类别项目。
代码评论很好。最后,您会发现触发的不同通知。您需要将真实文本放在每个文本中。
add_action( 'woocommerce_check_cart_items', 'checking_cart_items' );
function checking_cart_items() {
// Set your product category slug
$category = 'cat_x';
$number_of_items = sizeof( WC()->cart->get_cart() );
$found = false; // Initializing
$notice = ''; // Initializing
if ( $number_of_items > 0 ) {
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product = $cart_item['data'];
$product_id = $cart_item['product_id'];
// Detecting if the defined category is in cart
if ( has_term( $category, 'product_cat', $product_id ) ) {
$found = true;
break; // Stop the loop
}
}
// Re-loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$product_id = $cart_item['product_id'];
if ( $found ) // If the defined product category is in cart
{
if ( $number_of_items == 1 ) { // only one defined product category
if ( empty( $notice ) ){
$notice = '1';
}
}
if ( $number_of_items >= 2 ) { // The defined product category + other categories in cart
// removing other categories items from cart
if ( ! has_term( $category, 'product_cat', $product_id ) ) {
WC()->cart->remove_cart_item( $cart_item_key ); // removing item from cart
if ( empty( $notice ) || $notice == '1' ){
$notice = '2';
}
}
}
} else { // Only other categories items
if ( empty( $notice ) ){
$notice = '3';
}
}
}
// Firing woocommerce notices
if ( $notice == '1' ) { // message for an 'cat_x' item only (alone)
wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla one category X item in the cart</p>' ), 'success' );
} elseif ( $notice == '2' ) { // message for an 'cat_x' item and other ones => removed other ones
wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla ther is already category X in the cart => Other category items has been removed</p>' ), 'error' );
} elseif ( $notice == '3' ) { // message for other categories items (if needed)
wc_add_notice( sprintf( '<p class="woocommerce-error">bla bla bla NOT category X in the cart</p>' ), 'success' );
}
}
}
我无法真正测试此代码(但它不会引发错误)......
<强> @edit 强>
我们可以使用除通知之外的其他内容......一切皆有可能。但这是一个很好的起始解决方案,可以进行微调。
您需要将 'cat_x'
替换为真实的类别slug (在开头) ......
答案 1 :(得分:0)
2020年的答案
最近,我需要几乎相同的要求。但是,我必须检查项目是否属于一组类别,而不是单个类别。
考虑我有6个类别。我将6个类别分为3组。我的客户只能在一个订单中购买一个类别组(但多个类别)中的物品。
下面是代码段。
function sa45er_category_group_validation($valid, $product_id, $quantity) {
global $woocommerce;
if($woocommerce->cart->cart_contents_count == 0){
return $valid;
}
$target_cat_group = array(
array(17,20), // Update your product category
array(19,18), // Update your product category
);
$this_product_terms = get_the_terms( $product_id, 'product_cat' );
foreach ($this_product_terms as $term) {
$this_product_cat_ids[] = $term->term_id;
}
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
$terms = get_the_terms( $_product->get_ID(), 'product_cat' );
foreach ($terms as $term) {
$cart_cat_ids[] = $term->term_id;
}
}
$all_cats = array_merge($this_product_cat_ids,$cart_cat_ids);
$result = array();
foreach($target_cat_group as $target_cat_group_item){
$intrsct = array_intersect($all_cats, $target_cat_group_item);
if( !empty( $intrsct ) ){
$result[] = $intrsct;
}
}
if(count($result) > 1){
wc_add_notice( 'You can\'t add this product with your current cart items.', 'error' );
return false;
}
return $valid;
}
add_filter( 'woocommerce_add_to_cart_validation', 'sa45er_category_group_validation',10,3);