Created
October 7, 2019 15:35
-
-
Save helgatheviking/d1e41b5082a66c46afbe8e7e3c4b3244 to your computer and use it in GitHub Desktop.
Forces certain WooCommerce products to be purchased as the only item in cart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: Only Item in WooCommerce Cart | |
* Plugin URI: https://gist.github.com/helgatheviking/d1e41b5082a66c46afbe8e7e3c4b3244 | |
* Description: Forces certain products to be purchased as the only item in cart | |
* Version: 1.0.0 | |
* Author: Kathy Darling | |
* Author URI: http://kathyisawesome.com | |
* Requires at least: 5.2.0 | |
* WC requires at least: 3.6.0 | |
* Tested up to: 5.2.2 | |
* WC tested up to: 3.7.0 | |
* | |
* Text Domain: wc-only-item-in-cart | |
* Domain Path: /languages/ | |
* | |
* Copyright: © 2019 Kathy Darling. | |
* License: GNU General Public License v3.0 | |
* License URI: http://www.gnu.org/licenses/gpl-3.0.html | |
* | |
*/ | |
/** | |
* The Main WC_Only_Item_in_Cart class | |
**/ | |
if ( ! class_exists( 'WC_Only_Item_in_Cart' ) ) : | |
class WC_Only_Item_in_Cart { | |
/** | |
* WC_Only_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.', 'wc-only-item-in-cart' ) | |
) | |
); | |
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 | |
* | |
* @param bool $valid | |
* @param int $product_id | |
* @param int $quantity | |
* @retun bool | |
*/ | |
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['data'] ) ) { | |
$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( __( '"%s" has been removed from your cart. It cannot be purchased in conjunction with other products.', 'wc-only-item-in-cart' ), $product_title ), 'error' ); | |
} | |
} | |
} | |
/** | |
* Check if an item has custom field | |
* | |
* @param int $product_id | |
* @return bool | |
*/ | |
public static function is_item_special( $product_id ){ | |
$product = wc_get_product( $product_id ); | |
return $product && $product->get_meta( '_only_item_in_cart' ) == 'yes' ? true : false; | |
} | |
} //end class: do not remove or there will be no more guacamole for you | |
endif; // end class_exists check | |
// Launch the whole plugin. | |
add_action( 'woocommerce_loaded', array( 'WC_Only_Item_in_Cart', 'init' ) ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment