Tudor Gibson
Tudor Gibson

Reputation: 131

Woocmmerce how to allow only one product in cart of certain type

Sounds bizarre for me to ask this, in woocommerce is there anyway to have a specific product, which could be controlled via the product id, to only have one in the cart, so in our scenario they select one or the other, if they try to re-add to cart it simply replaces or swaps that item in the cart. Our main products would not then be affected by this rule.

Upvotes: 0

Views: 1877

Answers (1)

helgatheviking
helgatheviking

Reputation: 26319

I know that I've already posted this somewhere, but I can't find it so I will just repost it. This is an entire plugin (so add it as a file to wp-content/plugins) that will 1. add a checkbox to the product information meta box and 2. limit the cart to only that item if that checkbox is checked.

<?php
/*
Plugin Name: WooCommerce Restrict Items in Cart
Description: Forces cart to remove certain items if other items are added
Version: 1.0
Author: Kathy Darling
Author URI: http://kathyisawesome.com
Requires at least: 4.1.0
Tested up to: 4.1.0

Copyright: © 2015 Kathy Darling.
License: GNU General Public License v3.0
License URI: http://www.gnu.org/licenses/gpl-3.0.html

*/



/**
 * The Main WC_Restrict_Item_in_Cart class
 **/
if ( ! class_exists( 'WC_Restrict_Item_in_Cart' ) ) :

class WC_Restrict_Item_in_Cart {


    /**
     * WC_Restrict_Item_in_Cart init
     *
     * @access public
     * @since 1.0
     */

    public static function init() { 

        // product meta
        add_action( 'woocommerce_product_options_general_product_data', array( __CLASS__, 'add_to_wc_metabox' ) );
        add_action( 'woocommerce_process_product_meta', array( __CLASS__, 'process_wc_meta_box' ), 1, 2 );

        // validation - ensure product is never in the cart with other products
        add_filter( 'woocommerce_add_to_cart_validation', array( __CLASS__, 'maybe_remove_items' ), 10, 3 );

    }

    /*-----------------------------------------------------------------------------------*/
    /* Product Write Panels */
    /*-----------------------------------------------------------------------------------*/


    /*
    * Add text inputs to product metabox
    * @since 1.0
    */
    public static function add_to_wc_metabox(){
        global $post;

        echo '<div class="options_group">';

        echo woocommerce_wp_checkbox( array(
            'id' => '_only_item_in_cart',
            'label' => __( 'Only Item In Cart' ) ,
            'description' => __( 'For special items that need to be purchased individually.' )
            )
        );

        echo '</div>';

    }


    /*
     * Save extra meta info
     * @since 1.0
     */
    public static function process_wc_meta_box( $post_id, $post ) {

        if ( isset( $_POST['_only_item_in_cart'] ) ) {
            update_post_meta( $post_id, '_only_item_in_cart', 'yes' );
        } else {
            update_post_meta( $post_id, '_only_item_in_cart', 'no' );
        }

    }


    /*-----------------------------------------------------------------------------------*/
    /* Check Cart for presence of certain items */
    /*-----------------------------------------------------------------------------------*/


    /**
     * When an item is added to the cart, remove other products
     * based on WooCommerce Subscriptions code
     */
    public static function maybe_remove_items( $valid, $product_id, $quantity ) {

        if ( self::is_item_special( $product_id ) && WC()->cart->get_cart_contents_count() > 0 ){

            self::remove_specials_from_cart();

        } 

        return $valid;
    }

    /*-----------------------------------------------------------------------------------*/
    /* Helper methods */
    /*-----------------------------------------------------------------------------------*/

    /*
     * I've added a custom field 'only_item_in_cart' on items on 'special' products
     * check for this field similar to how Subscriptions checks cart for subscription items
     */

    public static function check_cart_for_specials() {

        $contains_special = false;

        foreach ( WC()->cart->get_cart() as $cart_item ) {
            if ( self::is_item_special( $cart_item['product_id'] ) ) {
                $contains_special = true;
                break;
            }
        }

        return $contains_special;
    }

    /**
    * Removes all special products from the shopping cart.
    */
    public static function remove_specials_from_cart(){

        foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ){
            if ( self::is_item_special( $cart_item['product_id'] ) ){
                WC()->cart->set_quantity( $cart_item_key, 0 );
                $product_title = $cart_item['data']->get_title();

                wc_add_notice( sprintf( __( '&quot;%s&quot; has been removed from your cart. Due to shipping calculations, it cannot be purchased in conjunction with other products.', 'wc_Restrict_Item_in_cart' ), $product_title ), 'error' );
            }

        }

    }

    /*
     * check if an item has custom field
     */
    public static function is_item_special( $product_id ){

        if ( 'yes' == get_post_meta( $product_id, '_only_item_in_cart', true ) ){ 
            return TRUE;
        } else {
            return false;
        }
    }

} //end class: do not remove or there will be no more guacamole for you

endif; // end class_exists check

// Launch the whole plugin
WC_Restrict_Item_in_Cart::init();

Upvotes: 1

Related Questions