businessdad

WooCommerce - Allow specific product combinations in cart

Dec 7th, 2015
2,304
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Restricts which products can be added to the cart at the same time. Tested
  3.  * with WooCommerce up to version 2.5.
  4.  *
  5.  * HOW TO USE THIS CODE
  6.  * 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/).
  7.  * 2. Set the IDs of the products that are allowed to be added to the cart at the same time.
  8.  * 3. Amend the message displayed to customers when products are unavailable after the specified
  9.  *    products have been added to the cart (see function woocommerce_get_price_html(), below).
  10.  *
  11.  * GPL DISCLAIMER
  12.  * Because this code program is free of charge, there is no warranty for it, to the extent permitted by applicable law.
  13.  * Except when otherwise stated in writing the copyright holders and/or other parties provide the program "as is"
  14.  * without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of
  15.  * merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the program
  16.  * is with you. should the program prove defective, you assume the cost of all necessary servicing, repair or correction.
  17.  *
  18.  * Need a consultation, or assistance to customise this code? Find us on Codeable: https://aelia.co/hire_us
  19.  */
  20.  
  21. /**
  22.  * Retrieves the cart contents. We can't just call WC_Cart::get_cart(), because
  23.  * such method runs multiple actions and filters, which we don't want to trigger
  24.  * at this stage.
  25.  *
  26.  * @author Aelia <support@aelia.co>
  27.  */
  28. function aelia_get_cart_contents() {
  29.   $cart_contents = array();
  30.   /**
  31.    * Load the cart object. This defaults to the persistant cart if null.
  32.    */
  33.   $cart = WC()->session->get( 'cart', null );
  34.  
  35.   if ( is_null( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart', true ) ) ) {
  36.     $cart = $saved_cart['cart'];
  37.   } elseif ( is_null( $cart ) ) {
  38.     $cart = array();
  39.   }
  40.  
  41.   if ( is_array( $cart ) ) {
  42.     foreach ( $cart as $key => $values ) {
  43.       $_product = wc_get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );
  44.  
  45.       if ( ! empty( $_product ) && $_product->exists() && $values['quantity'] > 0 ) {
  46.         if ( $_product->is_purchasable() ) {
  47.           // Put session data into array. Run through filter so other plugins can load their own session data
  48.           $session_data = array_merge( $values, array( 'data' => $_product ) );
  49.           $cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
  50.         }
  51.       }
  52.     }
  53.   }
  54.   return $cart_contents;
  55. }
  56.  
  57. // Step 1 - Keep track of cart contents
  58. add_action('wp_loaded', function() {
  59.   // If there is no session, then we don't have a cart and we should not take
  60.   // any action
  61.   if(!is_object(WC()->session)) {
  62.     return;
  63.   }
  64.  
  65.   // This variable must be global, we will need it later. If this code were
  66.   // packaged as a plugin, a property could be used instead
  67.   global $allowed_cart_items;
  68.   // We decided that products with ID 737 and 832 can go together. If any of them
  69.   // is in the cart, all other products cannot be added to it
  70.   global $restricted_cart_items;
  71.   $restricted_cart_items = array(
  72.     737,
  73.     832,
  74.   );
  75.  
  76.   // "Snoop" into the cart contents, without actually loading the whole cart
  77.   foreach(aelia_get_cart_contents() as $item) {
  78.     if(in_array($item['data']->id, $restricted_cart_items)) {
  79.       $allowed_cart_items[] = $item['data']->id;
  80.  
  81.       // If you need to allow MULTIPLE restricted items in the cart, comment
  82.       // the line below
  83.       break;
  84.     }
  85.   }
  86.  
  87.   // Step 2 - Make disallowed products "not purchasable"
  88.   add_filter('woocommerce_is_purchasable', function($is_purchasable, $product) {
  89.     global $restricted_cart_items;
  90.     global $allowed_cart_items;
  91.  
  92.     // If any of the restricted products is in the cart, any other must be made
  93.     // "not purchasable"
  94.     if(!empty($allowed_cart_items)) {
  95.       // To allow MULTIPLE products from the restricted ones, use the line below
  96.       //$is_purchasable = in_array($product->id, $allowed_cart_items) || in_array($product->id, $restricted_cart_items);
  97.  
  98.       // To allow a SINGLE  products from the restricted ones, use the line below
  99.       $is_purchasable = in_array($product->id, $allowed_cart_items);
  100.     }
  101.     return $is_purchasable;
  102.   }, 10, 2);
  103. }, 10);
  104.  
  105. // Step 3 - Explain customers why they can't add some products to the cart
  106. add_filter('woocommerce_get_price_html', function($price_html, $product) {
  107.   if(!$product->is_purchasable() && is_product()) {
  108.     $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>';
  109.   }
  110.   return $price_html;
  111. }, 10, 2);
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×