WooCommerce预购插件

时间:2015-03-30 23:45:23

标签: wordpress plugins woocommerce

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

3 个答案:

答案 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;
&#13;
&#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 );
}

这避免了添加插件的需要