WooCommerce预购插件


WooCommerce Pre-Orders Plugin

我正在考虑购买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;
}