我正在考虑购买WooCommerce Pre Orders,并一直在寻找朋友的副本进行演示。这是一个很棒的插件,但我有一个似乎无法解决的问题。
订购时,您一次只能订购1种产品。您可以在购物车中编辑该变体的数量,但不能同时将同一产品的两种变体添加到同一购物车中。如果这样做,它将清空推车并将其替换为当前选择。由于我要接受丝网印刷服装的预购(类似于teespring),因此一次订购多种变化(在这种情况下为大小)非常重要。让他们从同一产品中获得多个订单只会将他们赶走。
我不想让客户立刻从多个预订单订购,因为每个预订产品都有不同的发布/发货日期,但我想让他们订购多个版本,即小T恤,中T恤和大型三通,特定产品,因为它们都可以同时发货。
我希望所有这些都是有道理的。
以下是负责购物车限制的代码。非常感谢任何帮助。
/ ** *当预购订单添加到购物车时,请删除任何其他产品 * * @since 1.0 * @param bool $有效 * @param $ product_id * @return bool * / public function validate_cart($ valid,$ product_id){ 全球$ 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;
}
}
答案 0 :(得分:3)
我知道这篇文章很老了。但是遇到同样的问题,我已经解决了这个问题。
我更改了woocommerce-pre-orders / 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'作为您的选择。
谢谢。
答案 1 :(得分:2)
我一直有同样的问题,只是在这里找到答案(我希望): Pre-orders can only purchase one at a time
我设法实现了hortongroup的插件修复,如评论中所述。 描述中的短代码行有轻微错误,应该是:
echo do_shortcode('[pre_order_fix]');

现在看起来工作得很好,我等待WooCommerce Pre Orders的下一次更新,看看插件修复是否仍然有效。 理想情况下,通过这样做,我们不必在每次更新后改变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');
?>
&#13;
希望这也适合你:)
亲切的问候, JP
答案 2 :(得分:0)
我知道这已经很长时间了,但我认为这对某人仍然有用。如果您有子主题,则可以将其添加到 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 );
}
这避免了添加插件的需要