SHOW:
|
|
- or go back to the newest paste.
| 1 | /** | |
| 2 | - | * Restricts which products can be added to the cart at the same time. Tested |
| 2 | + | * Restricts which products can be added to the cart at the same time. |
| 3 | - | * with WooCommerce up to version 2.5. |
| 3 | + | * Version for WooCommerce 3.x and later. |
| 4 | - | * |
| 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 <[email protected]> | |
| 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 ) ) ) {
|
| 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']; |
| 36 | + | $cart = $saved_cart['cart']; |
| 37 | - | } elseif ( is_null( $cart ) ) {
|
| 37 | + | } |
| 38 | - | $cart = array(); |
| 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 | - | 737, |
| 72 | + | |
| 73 | - | 832, |
| 73 | + | |
| 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 | - | if(in_array($item['data']->id, $restricted_cart_items)) {
|
| 78 | + | 2, |
| 79 | - | $allowed_cart_items[] = $item['data']->id; |
| 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 | - | |
| 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 | - | |
| 97 | + | |
| 98 | // If any of the restricted products is in the cart, any other must be made | |
| 99 | - | $is_purchasable = in_array($product->id, $allowed_cart_items); |
| 99 | + | |
| 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); |