我正在考虑购买WooCommerce预购,并一直在查看朋友的副本以进行演示。这是一个很棒的插件,但我有一个问题似乎无法解决。
订购时,一次只能订购一种产品。您可以在购物车中编辑该变体的数量,但不能同时将同一产品的两个变体添加到同一购物车中。如果您这样做,它将清空购物车并将其替换为当前选择。由于我会接受丝网印刷服装的预购(类似于teebring),因此一次订购多种款式(在本例中为尺码)很重要。让他们从同一个产品上下多个订单只会把他们赶走。
我不想让客户同时从多个预购中订购,因为每个预购的产品都有不同的发布/发货日期,但我想让他们订购特定产品的多种变体,即小t恤、中t恤和大t恤,因为它们都会同时发货。
我希望所有这些都有意义。
这是负责购物车限制的代码。非常感谢您的帮助。
/**
* When a pre-order is added to the cart, remove any other products
*
* @since 1.0
* @param bool $valid
* @param $product_id
* @return bool
*/
public function validate_cart( $valid, $product_id ) {
global $woocommerce;
if ( WC_Pre_Orders_Product::product_can_be_pre_ordered( $product_id ) ) {
// if a pre-order product is being added to cart, check if the cart already contains other products and empty it if it does
if( $woocommerce->cart->get_cart_contents_count() >= 1 ) {
$woocommerce->cart->empty_cart();
$string = __( 'Your previous cart was emptied because pre-orders must be purchased separately.', 'wc-pre-orders' );
// Backwards compatible (pre 2.1) for outputting notice
if ( function_exists( 'wc_add_notice' ) ) {
wc_add_notice( $string );
} else {
$woocommerce->add_message( $string );
}
}
// return what was passed in, allowing the pre-order to be added
return $valid;
} else {
// if there's a pre-order in the cart already, prevent anything else from being added
if ( $this->cart_contains_pre_order() ) {
// Backwards compatible (pre 2.1) for outputting notice
if ( function_exists( 'wc_add_notice' ) ) {
wc_add_notice( __( 'This product cannot be added to your cart because it already contains a pre-order, which must be purchased separately.', 'wc-pre-orders' ) );
} else {
$woocommerce->add_error( __( 'This product cannot be added to your cart because it already contains a pre-order, which must be purchased separately.', 'wc-pre-orders' ) );
}
$valid = false;
}
}
return $valid;
}
/**
* Add any applicable pre-order fees when calculating totals
*
* @since 1.0
*/
public function maybe_add_pre_order_fee() {
global $woocommerce;
// Only add pre-order fees if the cart contains a pre-order
if ( ! $this->cart_contains_pre_order() ) {
return;
}
// Make sure the pre-order fee hasn't already been added
if ( $this->cart_contains_pre_order_fee() ) {
return;
}
$product = self::get_pre_order_product();
// Get pre-order amount
$amount = WC_Pre_Orders_Product::get_pre_order_fee( $product );
if ( 0 >= $amount ) {
return;
}
$fee = apply_filters( 'wc_pre_orders_fee', array(
'label' => __( 'Pre-Order Fee', 'wc-pre-orders' ),
'amount' => $amount,
'tax_status' => WC_Pre_Orders_Product::get_pre_order_fee_tax_status( $product ), // pre order fee inherits tax status of product
) );
// Add fee
$woocommerce->cart->add_fee( $fee['label'], $fee['amount'], $fee['tax_status'] );
}
/**
* Checks if the current cart contains a product with pre-orders enabled
*
* @since 1.0
* @return bool true if the cart contains a pre-order, false otherwise
*/
public static function cart_contains_pre_order() {
global $woocommerce;
$contains_pre_order = false;
if ( ! empty( $woocommerce->cart->cart_contents ) ) {
foreach ( $woocommerce->cart->cart_contents as $cart_item ) {
if ( WC_Pre_Orders_Product::product_can_be_pre_ordered( $cart_item['product_id'] ) ) {
$contains_pre_order = true;
break;
}
}
}
return $contains_pre_order;
}
/**
* Checks if the current cart contains a pre-order fee
*
* @since 1.0
* @return bool true if the cart contains a pre-order fee, false otherwise
*/
public static function cart_contains_pre_order_fee() {
global $woocommerce;
foreach ( $woocommerce->cart->get_fees() as $fee ) {
if ( is_object( $fee ) && 'pre-order-fee' == $fee->id )
return true;
}
return false;
}
/**
* Since a cart may only contain a single pre-ordered product, this returns the pre-ordered product object or
* null if the cart does not contain a pre-order
*
* @since 1.0
* @return object|null the pre-ordered product object, or null if the cart does not contain a pre-order
*/
public static function get_pre_order_product() {
global $woocommerce;
if ( self::cart_contains_pre_order() ) {
foreach ( $woocommerce->cart->cart_contents as $cart_item ) {
if ( WC_Pre_Orders_Product::product_can_be_pre_ordered( $cart_item['product_id'] ) ) {
// return the product object
return get_product( $cart_item['variation_id'] ? $cart_item['variation_id'] : $cart_item['product_id'] );
}
}
} else {
// cart doesn't contain pre-order
return null;
}
}
我知道这篇文章很旧。但遇到同样的问题,我就这样解决了我的问题。
我更改了wooccommerce预购/classes/class-wc-pre-orders-cart.php 中的validate_cart()函数
它是这样的:
public function validate_cart( $valid, $product_id ) {
global $woocommerce;
if ( WC_Pre_Orders_Product::product_can_be_pre_ordered( $product_id ) ) {
if( $woocommerce->cart->get_cart_contents_count() >= 1 ) {
if ( $this->cart_contains_pre_order() ) {
return $valid;
}
$string = __( 'Your cart contains items, please complete that order first and then purchase pre-order items, because pre-orders must be purchased separately.', 'wc-pre-orders' );
// Backwards compatible (pre 2.1) for outputting notice
if ( function_exists( 'wc_add_notice' ) ) {
wc_add_notice( $string );
} else {
$woocommerce->add_message( $string );
}
$valid = false;
return $valid;
}
else
{
return $valid;
}
} else {
// if there's a pre-order in the cart already, prevent anything else from being added
if ( $this->cart_contains_pre_order() ) {
// Backwards compatible (pre 2.1) for outputting notice
if ( function_exists( 'wc_add_notice' ) ) {
wc_add_notice( __( 'This product cannot be added to your cart because it already contains a pre-order, which must be purchased separately.', 'wc-pre-orders' ) );
} else {
$woocommerce->add_error( __( 'This product cannot be added to your cart because it already contains a pre-order, which must be purchased separately.', 'wc-pre-orders' ) );
}
$valid = false;
}
}
return $valid;
}
注意:我知道这不是正确的实施方式。因为我直接在插件中进行编辑。所以当插件更新时,更改就不存在了。您可以使用任何"return$valid"、"return true"或"return false"作为您的选择。
谢谢。
我知道这已经很长时间了,但我认为这对某人仍然有用。如果你有一个子主题,你可以把它添加到functions.php
:
//remove pre-order limitations --> only one item per order
add_action( 'init', 'remove_validation_cart' );
function remove_validation_cart(){
remove_filter( 'woocommerce_add_to_cart_validation', array( $GLOBALS['wc_pre_orders']->cart, 'validate_cart' ), 15, 2 );
}
这避免了添加插件的需要
我也遇到了同样的问题,只是在这里找到了答案(我希望):预购一次只能购买一个
我设法实现了hortongroup的插件修复,如评论中所述。描述中的短代码行有一个轻微错误,应该是:
echo do_shortcode('[pre_order_fix]');
现在它似乎工作得很好,我将等待WooCommerce预购的下一次更新,看看插件修复是否仍然有效。理想情况下,通过这种方式,我们不必在每次更新后更改WooCommerce预购。
以下是我用于自定义插件的代码:
<?php
/**
* Plugin Name: Woo Pre-Order Fix
* Plugin URI:
* Description: Fix the one item only issue with Woocommerce Pre-Orders
* Version: 1.0
* Author: hortongroup
* Author URI:
* License: GPL12
*/
function pre_order_fix_shortcode() {
if ( in_array( 'woocommerce-pre-orders/woocommerce-pre-orders.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
remove_filter( 'woocommerce_add_to_cart_validation', array( $GLOBALS['wc_pre_orders']->cart, 'validate_cart' ), 15, 2 );
}
}
add_shortcode('pre_order_fix', 'pre_order_fix_shortcode');
?>
希望这对你也有用:)
谨致问候,JP
由于这个问题今天仍然存在,而且我的场景略有不同,所以我使用了以下过滤器来解决我的问题。
我希望进行预购,但不是每个订单一个预购项目,一个订单中可能有多个数量和不同的预购产品。我唯一想防止的情况是,常规产品与预购混合在一起(这不可能)。
也许其他人都可以使用这种方法(将来检查一些自定义的东西,你可以将其添加到你的子主题中),这会更好,因为它现在可以被更新覆盖。
/**
* When a pre-order is added to the cart, remove any other products
*
* @since 1.0
* @param bool $valid
* @param $product_id
* @return bool
*/
public function validate_cart( $valid, $product_id ) {
global $woocommerce;
if ( WC_Pre_Orders_Product::product_can_be_pre_ordered( $product_id ) ) {
// if a pre-order product is being added to cart, check if the cart already contains other products and empty it if it does
if( $woocommerce->cart->get_cart_contents_count() >= 1 ) {
// count the amount of regular items in the cart
$regularCount = 0;
foreach ($woocommerce->cart->get_cart() as $item) {
// continue of the product is a pre-order product...
if (WC_Pre_Orders_Product::product_can_be_pre_ordered( $item['product_id'] )) {
continue;
}
$regularCount++;
}
// only clear the cart if the current items in it are having regular products...
if ($regularCount > 0) {
$woocommerce->cart->empty_cart();
$string = __( 'Your previous cart was emptied because pre-orders must be purchased separately.', 'wc-pre-orders' );
// Backwards compatible (pre 2.1) for outputting notice
if ( function_exists( 'wc_add_notice' ) ) {
wc_add_notice( $string );
} else {
$woocommerce->add_message( $string );
}
}
}
// return what was passed in, allowing the pre-order to be added
return $valid;
} else {
// if there's a pre-order in the cart already, prevent anything else from being added
if ( $this->cart_contains_pre_order() ) {
// Backwards compatible (pre 2.1) for outputting notice
if ( function_exists( 'wc_add_notice' ) ) {
wc_add_notice( __( 'This product cannot be added to your cart because it already contains a pre-order, which must be purchased separately.', 'wc-pre-orders' ) );
} else {
$woocommerce->add_error( __( 'This product cannot be added to your cart because it already contains a pre-order, which must be purchased separately.', 'wc-pre-orders' ) );
}
$valid = false;
}
}
return $valid;
}