WooCommerce Product Bundles
The WooCommerce Product Bundles extension creates “bundle” products that consist of several child products. When an agent adds a bundle to a phone order, the plugin must handle both the parent bundle item and its child items correctly, avoid double‑counting, and keep the price read‑only.
The code below skips adding child items when the agent adds the bundle, marks child items as “child” items so they can be grouped under the parent, ensures the price is read‑only, and copies the bundle configuration stamp.
The Complete Code Snippet
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
add_filter( 'wpo_skip_add_to_cart_item', function ( $skip, $item ) { return isset($item['bundled_by']) ? true : $skip; }, 10, 2 ); add_filter( 'wpo_is_child_cart_item', function ( $child, $item ) { return isset($item['bundled_by']) ? true : $child; }, 10, 2 ); add_filter( 'wpo_search_product_types', function ( $types ) { $types[] = "bundle"; return $types; } ); add_filter('wpo_add_configured_products_skip_item', function ($skip, $item_data) { return isset($item_data['bundled_by']) ? true : $skip; }, 10, 2); add_filter('wpo_children_cart_item', function ($children, $item) { return isset($item['bundled_items']) ? $item['bundled_items'] : $children; }, 10, 2); add_filter('wpo_cart_item_is_price_readonly', function ($is_readonly, $item) { return isset($item['bundled_items']) ? true : $is_readonly; }, 10, 2); add_filter('wpo_get_item_by_product', function ($product, $item_data) { return array_merge($product, array( 'stamp' => isset($item_data['stamp']) ? $item_data['stamp'] : null, 'readonly_price' => isset($item_data['readonly_price']) ? $item_data['readonly_price'] : null, )); }, 10, 2); add_filter('wpo_update_cart_loaded_product', function ($loaded_product, $item) { return array_merge($loaded_product, array( 'stamp' => isset($item['stamp']) ? $item['stamp'] : null, 'readonly_price' => isset($item['readonly_price']) ? $item['readonly_price'] : null, )); }, 10, 2); add_filter('wpo_update_cart_cart_item_meta', function ($cart_item_meta, $item) { return array_merge($cart_item_meta, array( 'stamp' => isset($item['stamp']) ? $item['stamp'] : null, 'readonly_price' => isset($item['readonly_price']) ? $item['readonly_price'] : null, )); }, 10, 2); add_filter('wpo_add_configured_products_item_data', function ($item_data, $cart_item_data, $cart_item_key, $wc_product) { if ( isset( $cart_item_data['bundled_items'] ) ) { $readonly_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $wc_product ), $cart_item_data, $cart_item_key ); if (preg_match('/</span>([d|.]+)?/i', $readonly_price, $matches)) { $item_data['readonly_price'] = $matches[1]; } } return $item_data; }, 10, 4); add_filter( 'woocommerce_hidden_order_itemmeta', function ( $keys ) { $keys[] = '_stamp'; return $keys; }); |
What the code does
| Filter | Explanation |
|---|---|
wpo_skip_add_to_cart_item | Returns true for any item that has a bundled_bykey (i.e., a child item). The plugin skips adding child items directly; only the parent bundle is added manually. |
wpo_is_child_cart_item | Marks any item with bundled_by as a child cart item. |
wpo_search_product_types | Adds the product type bundle to the product search, so agents can find bundle products in the phone order interface. |
wpo_add_configured_products_skip_item | Skips adding child items when the plugin auto‑configures bundled products. |
wpo_children_cart_item | Returns the array of bundled_items (child item IDs) for a parent bundle item. The plugin uses this to group the child items under the parent. |
wpo_cart_item_is_price_readonly | Makes the price read‑only for any cart item that has bundled_items (i.e., the parent bundle). |
wpo_get_item_by_product, wpo_update_cart_loaded_product, wpo_update_cart_cart_item_meta | Copy the bundle configuration stamp and the read‑only price into the product, cart item, and cart item meta respectively. |
wpo_add_configured_products_item_data | Extracts the final price of the bundle from the cart and stores it as readonly_price. |
woocommerce_hidden_order_itemmeta | Hides the internal _stamp meta key from the order item details display, keeping the UI clean. |
Why you need this code
Without these filters, adding a bundle product to a phone order would either fail completely or result in incorrect pricing. The child items might be added twice, or the bundle might appear as a single product without its components.
How to implement it
- Copy the complete code snippet.
- Add it as a new snippet in the Code Snippets plugin.
- Title it “Phone Orders – Product Bundles”.
- Activate the snippet.
Testing the integration
- Create a bundle product with two or more child products.
- Add the bundle to a phone order.
- Verify that the bundle appears in the cart with all child items listed underneath it.
- Complete the order.
- Check the order details in WooCommerce → Orders. The bundle should be displayed correctly with its child items and the total price should match the bundle’s configuration.