MaxtDesign

Two Companion Modes

Required Companions

Force a selection before add-to-cart. The customer picks one product (or multiple, if their role has multi-select access) from a configured list before they can add the parent to the cart.

  • Display: Radio buttons (all options visible) or dropdown (compact)
  • Single-select is default; multi-select is granted by user role under WooCommerce settings
  • Cart line item shows the relationship: Required for [parent]
  • Removing the parent from the cart cascades the removal — the required companion comes out with it
  • Required quantity is read-only in the cart; the customer cannot adjust it independently
  • Add-on Sections

    Optional companions are grouped into named sections, in the order you choose. Each section is checkbox mode (pick any) or radio mode (pick at most one, including none). For example, "Wall Panels" and "Mounting Hardware" can be separate sections on the same product, each with its own rules.

  • Per-section mode: checkbox (any) or radio (at most one)
  • Drag to reorder sections, and reorder companions within a section
  • Cart line item shows: Add-on for [parent]
  • Add-on quantity is editable in cart (unlike required)
  • Removing the parent removes its add-ons by default
  • Automatic Quantity Matching

    When the customer adds N of the parent, N of the required companion are added automatically:

  • Parent: 5 → required companion: 5
  • Add to cart again with parent qty 3 → required companion increases to 8
  • If the customer separately adds the same product as a standalone item (or it was already in cart), the plugin tracks the split:

  • Required: 5 — driven by parent quantity, read-only
  • Extra: 2 — added independently, editable
  • The cart shows the breakdown so the customer understands why the quantity isn't directly editable.

    Incompatibility Rules

    Mark any two add-ons as incompatible, or have a required option rule out specific add-ons. On the product page, selecting an item dims everything incompatible with it and shows a "Not compatible with" explanation. Switching the required selection automatically removes add-ons that no longer fit, with a polite notice.

  • Rules are direct pairs only, there is no chaining
  • Dimmed options carry aria-disabled and are skipped by keyboard navigation
  • The same rules are enforced server side at add-to-cart, so a non-standard path (REST, programmatic) cannot slip a bad combination through
  • Conflict groups from version 1 convert automatically into the equivalent pairwise rules on upgrade
  • Display Label Overrides

    Long product names wreck layouts. Give any companion a shorter "Display as" label that shows on the product page widget only. The real product name still appears in cart, checkout, emails, and orders. A global option truncates long titles to one line with the full name on hover.

    Thumbnail Lightbox

    Companion thumbnails open a larger photo in an accessible lightbox on the single product page, so customers can see what they are picking without leaving the page.

    Pricing Display and Running Total

    Per-product display options for the companion selection UI:

  • Per-option price — each companion lists its own price next to the selection control
  • Combined total — the parent page shows a running total of (parent price × parent qty) + (selected companions × parent qty)
  • Both — per-option price next to each option AND a running total at the bottom
  • The running total updates live as the customer changes their selection, formatted with your store currency and WooCommerce tax display setting. You can rename or hide it under WooCommerce → Settings → Companion Products.

    Section Label Snapshots

    Order line items record the section name and any "Display as" label as they were at purchase time, like "Wall Panels for [parent product]". Renaming a section later never rewrites existing order history, so customer records stay accurate.

    Separate Line Items, Separate SKUs

    This is the operational backbone of the plugin and the reason it works for fulfillment teams.

  • Parent and companion are separate line items in the cart and the order
  • Each carries its own SKU, set independently in the product editor
  • Inventory deducts from each product's stock independently
  • Relationship is preserved in line item meta (_mcp_is_required / _mcp_is_optional / _mcp_parent_product_id / _mcp_group_id) and rendered as a label in cart and admin order detail
  • Your warehouse picks two SKUs, not one. Your accounting books two products at their actual prices. Your reporting sees real volume on the companion.

    HPOS Compatibility

    The plugin declares HPOS compatibility on activation via FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true) and uses WooCommerce order APIs ($order->get_meta(), $order->update_meta_data(), $item->add_meta_data()) throughout — never get_post_meta() against the order ID.

    Both legacy storage and the new HPOS tables are supported with no configuration.

    Caching

    The requirements lookup (which companions does this parent have configured) is cached in a 1-hour WordPress transient. The cache is automatically invalidated when:

  • A product with companion config is saved
  • A companion product's stock status changes
  • An order is completed (so out-of-stock-aware lookups stay accurate)
  • Manual cache flush is available in Tools if you need it.

    Translation Support

    The plugin is translation-ready with the maxtdesign-companion-products text domain and a .pot template at languages/maxtdesign-companion-products.pot.