businessdad

WooCommerce - Allow specific products in cart (WC 3.x)

Mar 1st, 2018
2,353
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.
  3.  * Version for WooCommerce 3.x and later.
  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_' . get_current_blog_id(), true ) ) ) { // @codingStandardsIgnoreLine
  36.         $cart                = $saved_cart['cart'];
  37.     }
  38.     elseif ( is_null( $cart ) ) {
  39.         $cart = array();
  40.     }
  41.     elseif ( is_array( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), true ) ) ) { // @codingStandardsIgnoreLine
  42.         $cart                = array_merge( $saved_cart['cart'], $cart );
  43.     }
  44.  
  45.   if ( is_array( $cart ) ) {
  46.     foreach ( $cart as $key => $values ) {
  47.       $_product = wc_get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );
  48.  
  49.       if ( ! empty( $_product ) && $_product->exists() && $values['quantity'] > 0 ) {
  50.         if ( $_product->is_purchasable() ) {
  51.           // Put session data into array. Run through filter so other plugins can load their own session data
  52.           $session_data = array_merge( $values, array( 'data' => $_product ) );
  53.           $cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
  54.         }
  55.       }
  56.     }
  57.   }
  58.   return $cart_contents;
  59. }
  60.  
  61. // Step 1 - Keep track of cart contents
  62. add_action('wp_loaded', function() {
  63.   // If there is no session, then we don't have a cart and we should not take
  64.   // any action
  65.   if(!is_object(WC()->session)) {
  66.     return;
  67.   }
  68.  
  69.   // This variable must be global, we will need it later. If this code were
  70.   // packaged as a plugin, a property could be used instead
  71.   global $allowed_cart_items;
  72.   // We decided that products with ID 737 and 832 can go together. If any of them
  73.   // is in the cart, all other products cannot be added to it
  74.   global $restricted_cart_items;
  75.   $restricted_cart_items = array(
  76.         // Set the IDs of the products that can be added to the cart at the same time
  77.     1,
  78.     2,
  79.     3,
  80.   );
  81.  
  82.   // "Snoop" into the cart contents, without actually loading the whole cart
  83.   foreach(aelia_get_cart_contents() as $item) {
  84.     if(in_array($item['data']->get_id(), $restricted_cart_items)) {
  85.       $allowed_cart_items[] = $item['data']->get_id();
  86.  
  87.       // If you need to allow MULTIPLE restricted items in the cart, comment
  88.       // the line below
  89.       break;
  90.     }
  91.   }
  92.  
  93.   // Step 2 - Make disallowed products "not purchasable"
  94.   add_filter('woocommerce_is_purchasable', function($is_purchasable, $product) {
  95.     global $restricted_cart_items;
  96.     global $allowed_cart_items;
  97.  
  98.     // If any of the restricted products is in the cart, any other must be made
  99.     // "not purchasable"
  100.     if(!empty($allowed_cart_items)) {
  101.       // To allow MULTIPLE products from the restricted ones, use the line below
  102.       //$is_purchasable = in_array($product->id, $allowed_cart_items) || in_array($product->id, $restricted_cart_items);
  103.  
  104.       // To allow a SINGLE  products from the restricted ones, use the line below
  105.       $is_purchasable = in_array($product->get_id(), $allowed_cart_items);
  106.     }
  107.     return $is_purchasable;
  108.   }, 10, 2);
  109. }, 10);
  110.  
  111. // Step 3 - Explain customers why they can't add some products to the cart
  112. add_filter('woocommerce_get_price_html', function($price_html, $product) {
  113.   if(!$product->is_purchasable() && is_product()) {
  114.     $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>';
  115.   }
  116.   return $price_html;
  117. }, 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.

×