Skip to content

Instantly share code, notes, and snippets.

@carlosvarela
Created May 24, 2019 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlosvarela/7e302e3a0e859e1716582343a2d78fbc to your computer and use it in GitHub Desktop.
Save carlosvarela/7e302e3a0e859e1716582343a2d78fbc to your computer and use it in GitHub Desktop.
only let purchase one specific product in woocommerce
/**
* Restricts which products can be added to the cart at the same time. Tested
* with WooCommerce up to version 2.5.
*
* HOW TO USE THIS CODE
* 1. Add the code to the bottom of your theme's functions.php file (see https://www.skyverge.com/blog/add-custom-code-to-wordpress/).
* 2. Set the IDs of the products that are allowed to be added to the cart at the same time.
* 3. Amend the message displayed to customers when products are unavailable after the specified
* products have been added to the cart (see function woocommerce_get_price_html(), below).
*
* GPL DISCLAIMER
* Because this code program is free of charge, there is no warranty for it, to the extent permitted by applicable law.
* Except when otherwise stated in writing the copyright holders and/or other parties provide the program "as is"
* without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the program
* is with you. should the program prove defective, you assume the cost of all necessary servicing, repair or correction.
*
* Need a consultation, or assistance to customise this code? Find us on Codeable: https://aelia.co/hire_us
*/
/**
* Retrieves the cart contents. We can't just call WC_Cart::get_cart(), because
* such method runs multiple actions and filters, which we don't want to trigger
* at this stage.
*
* @author Aelia <support@aelia.co>
*/
function aelia_get_cart_contents() {
$cart_contents = array();
/**
* Load the cart object. This defaults to the persistant cart if null.
*/
$cart = WC()->session->get( 'cart', null );
if ( is_null( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart', true ) ) ) {
$cart = $saved_cart['cart'];
} elseif ( is_null( $cart ) ) {
$cart = array();
}
if ( is_array( $cart ) ) {
foreach ( $cart as $key => $values ) {
$_product = wc_get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );
if ( ! empty( $_product ) && $_product->exists() && $values['quantity'] > 0 ) {
if ( $_product->is_purchasable() ) {
// Put session data into array. Run through filter so other plugins can load their own session data
$session_data = array_merge( $values, array( 'data' => $_product ) );
$cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
}
}
}
}
return $cart_contents;
}
// Step 1 - Keep track of cart contents
add_action('wp_loaded', function() {
// If there is no session, then we don't have a cart and we should not take
// any action
if(!is_object(WC()->session)) {
return;
}
// This variable must be global, we will need it later. If this code were
// packaged as a plugin, a property could be used instead
global $allowed_cart_items;
// We decided that products with ID 737 and 832 can go together. If any of them
// is in the cart, all other products cannot be added to it
global $restricted_cart_items;
$restricted_cart_items = array(
737,
// if you need add more
//832,
);
// "Snoop" into the cart contents, without actually loading the whole cart
foreach(aelia_get_cart_contents() as $item) {
if(in_array($item['data']->id, $restricted_cart_items)) {
$allowed_cart_items[] = $item['data']->id;
// If you need to allow MULTIPLE restricted items in the cart, comment
// the line below
break;
}
}
// Step 2 - Make disallowed products "not purchasable"
add_filter('woocommerce_is_purchasable', function($is_purchasable, $product) {
global $restricted_cart_items;
global $allowed_cart_items;
// If any of the restricted products is in the cart, any other must be made
// "not purchasable"
if(!empty($allowed_cart_items)) {
// To allow MULTIPLE products from the restricted ones, use the line below
//$is_purchasable = in_array($product->id, $allowed_cart_items) || in_array($product->id, $restricted_cart_items);
// To allow a SINGLE products from the restricted ones, use the line below
$is_purchasable = in_array($product->id, $allowed_cart_items);
}
return $is_purchasable;
}, 10, 2);
}, 10);
// Step 3 - Explain customers why they can't add some products to the cart
add_filter('woocommerce_get_price_html', function($price_html, $product) {
if(!$product->is_purchasable() && is_product()) {
$price_html .= '<p>' . __('This product cannot be purchased together with "Product X" or "Product Y". If you wish to buy this product, please remove the other products from the cart.', 'woocommerce') . '</p>';
}
return $price_html;
}, 10, 2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment