Advertisement
businessdad

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

Mar 1st, 2018
3,862
0
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);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement