Created
May 24, 2019 18:30
-
-
Save carlosvarela/7e302e3a0e859e1716582343a2d78fbc to your computer and use it in GitHub Desktop.
only let purchase one specific product in woocommerce
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
/** | |
* 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