Once a configuration is added to the cart it stops being browser state and becomes WooCommerce data. These hooks control how it is priced, how it reads in the cart and at checkout, and what is written onto the order.
Cart and order display share most of their machinery — mkl_pc_cart_item_choice and friends are
fired from both — so they are documented together here.
See the hook reference index for how to register callbacks.
Cart display
| Hook | Type | Arguments | Purpose |
|---|---|---|---|
mkl_pc/wc_cart_get_item_data/choices | filter | $choices, $cartItem | The full list of choices shown for a cart line |
mkl_pc/wc_cart_get_item_data/choice | filter | $choice, $selectedChoice, $cartItem | One choice row |
mkl_pc/wc_cart_get_item_data/choice_thumbnail | filter | $html, $selectedChoice | The thumbnail markup beside a choice |
mkl_pc/wc_cart_get_item_data/display_choice_image | filter | true | Whether thumbnails are shown at all |
mkl_pc_cart_item_choice | filter | $html, $key, $value, $before, $after | The finished markup for one choice |
mkl_pc_cart_item_choice_before | filter | $html, $choice | Opening wrapper for a choice |
mkl_pc_cart_item_choice_after | filter | $html, $choice | Closing wrapper |
mkl_pc_cart_item_choice__classes | filter | $classes, $layer | Classes on the wrapper |
mkl_pc_cart_item_choice_data | filter | $item, $choice | The data array a choice row is built from |
mkl_pc_user_can_edit_item_from_cart | filter | $canEdit | Whether the "edit configuration" link is shown |
mkl_pc_edit_configuration_label | filter | $label | That link's label |
mkl_pc/wc_cart_add_item_data/choice_weight | filter | $weight, $layer | Weight a choice contributes to the line |
mkl_pc/cart_item/merge_layer_image_id | filter | $imageToken, $layer | Image token used when merging the preview |
mkl_pc_3d_screenshot_temp_max_age | filter | 48 * HOUR_IN_SECONDS | How long unused 3D screenshots are kept |
mkl_pc_3d_screenshot_dimensions | filter | $dimensions | Size of the 3D cart screenshot, and the largest one accepted |
Order meta
| Hook | Type | Arguments | Purpose |
|---|---|---|---|
mkl_pc/order_created/save_layer_meta | filter | $itemData, $layer, $orderItem, [], $count | One layer's data as it is written to the order |
mkl_pc/order_created/after_save_layer_meta | action | $layer, $orderItem, $order | After each layer is saved |
mkl_pc/order_created/after_saved_data | action | $item, $order, $configuratorData | After the whole configuration is saved |
mkl_pc/order_created/saved_data/label | filter | $label, $item | Meta key for the combined configuration |
mkl_pc/order_created/get_data/label | filter | $label, $orderItem, $configuratorData | Display label for that meta |
mkl_pc/order_created/individual_meta/key | filter | $key, $layer, $item | Meta key for one layer |
mkl_pc/order_created/individual_meta/value | filter | $value, $layer, $item | Meta value for one layer |
mkl_pc/order_created/individual_meta/keep_html | filter | false, $layer, $item | Keep markup in the individual metas |
mkl_pc_order_item_meta | filter | $meta, $layer, $product | A layer's label/value pair, cart and order |
mkl_pc/order_image_size | filter | $size, $orderItem, $configuratorData | Image size for the configuration preview |
mkl_pc/do_not_show_image_download_link | filter | false | Suppress the image download link entirely |
mkl_pc/customer_can_see_image_download_link | filter | $hide, $itemId, $item, $order | Whether to hide it for this order |
mkl_pc_order_item_meta
The single most useful hook in this group. Every layer, in both cart and order, passes through it
as a label / value / layer array. Add-ons build on it — Extra Price appends the price here,
Form Fields appends the field value.
add_filter( 'mkl_pc_order_item_meta', function ( $meta, $layer, $product ) { if ( $sku = $layer->get_choice( 'sku' ) ) { $meta['value'] .= ' <code>' . esc_html( $sku ) . '</code>'; } return $meta;}, 10, 3 );
Return an empty array to drop the layer from display altogether. $layer is an MKL\PC\Choice
— use get_layer( 'name' ) for the layer and get_choice( 'name' ) for the selection.
mkl_pc_cart_item_choice and its wrappers
These build the rendered HTML for a choice row, in the cart and the order. Four filters run in order:
mkl_pc_cart_item_choice__classes— the class list, before sanitisingmkl_pc_cart_item_choice_before— the opening<div …>mkl_pc_cart_item_choice_after— the closing</div>mkl_pc_cart_item_choice— the assembled row, with all of the above already in it
// Tag rows by layer type so they can be styled.add_filter( 'mkl_pc_cart_item_choice__classes', function ( $classes, $layer ) { $classes[] = 'my-row'; return $classes;}, 10, 2 );// Or replace the row wholesale.add_filter( 'mkl_pc_cart_item_choice', function ( $html, $key, $value, $before, $after ) { return $before . '<span class="k">' . $key . '</span><span class="v">' . $value . '</span>' . $after;}, 10, 5 );
The label and value reaching mkl_pc_cart_item_choice have already been through
Utils::kses_basic_inline_html(), so only simple inline markup survives. If you need richer
markup, add it around them in the before/after filters rather than inside the value.
mkl_pc/wc_cart_get_item_data/choices
The complete list of choices for a cart line, just before it is rendered. Use it to reorder, filter or collapse rows:
add_filter( 'mkl_pc/wc_cart_get_item_data/choices', function ( $choices, $cart_item ) { // Show at most five rows in the cart. return array_slice( $choices, 0, 5 );}, 10, 2 );
Each entry is [ 'name' => …, 'value' => …, 'layer' => MKL\PC\Choice ]. Choices whose layer or
choice has Hide in cart set never reach this filter.
mkl_pc/wc_cart_get_item_data/choice_thumbnail and …/display_choice_image
Thumbnails are rendered as <span class="choice-thumb"><img …></span> when the choice has one.
Return an empty string from the first filter to drop it for particular choices, or false from
the second to switch them off site-wide:
add_filter( 'mkl_pc/wc_cart_get_item_data/display_choice_image', '__return_false' );
mkl_pc/wc_cart_add_item_data/choice_weight
Each choice can carry a weight, which is summed into the cart line's shipping weight. This filter sees each one as a float.
add_filter( 'mkl_pc/wc_cart_add_item_data/choice_weight', function ( $weight, $layer ) { // Packaging adds 10% on top of the parts. return $weight * 1.1;}, 10, 2 );
mkl_pc_user_can_edit_item_from_cart and mkl_pc_edit_configuration_label
The first decides whether the cart shows a link back into the configurator, defaulting to the Show edit configuration link setting. The second is that link's text.
add_filter( 'mkl_pc_user_can_edit_item_from_cart', function ( $can_edit ) { // Never offer editing to guests. return is_user_logged_in() ? $can_edit : false;} );
Configuration meta mode, and which order hooks fire
How a configuration is written onto the order depends on the configuration meta mode:
| Mode | Combined meta | Per-layer meta |
|---|---|---|
single (default) | yes | no |
individual | no | yes |
That decides which hooks you get. mkl_pc/order_created/saved_data/label and
mkl_pc/order_created/get_data/label only matter when the combined meta is written; the
individual_meta/* filters only fire in the other case. Check the mode — with
mkl_pc_get_configuration_meta_mode() — before assuming your filter runs.
mkl_pc/order_created/individual_meta/key and …/value
The per-layer meta written for machine readability — for exports, packing slips, and anything reading order meta directly.
add_filter( 'mkl_pc/order_created/individual_meta/key', function ( $key, $layer, $item ) { return 'cfg_' . sanitize_key( $key );}, 10, 3 );
Markup is stripped by default, which is the point of these metas — set
mkl_pc/order_created/individual_meta/keep_html to true only if you have a reason. Empty
values are skipped entirely, so returning '' from the value filter removes the meta.
mkl_pc/order_created/save_layer_meta and …/after_save_layer_meta
The filter shapes each layer's label / value data as it is stored; the action fires
immediately after, and is the place to write meta of your own.
add_action( 'mkl_pc/order_created/after_save_layer_meta', function ( $layer, $order_item, $order ) { if ( $code = $layer->get_choice( 'supplier_code' ) ) { $order_item->add_meta_data( '_supplier_code', $code, false ); }}, 10, 3 );
The item is saved after all layers are processed, so you do not need to call save() yourself.
mkl_pc/order_created/after_saved_data
Fires once per configured item, after the configuration meta and SKU have been written. The right hook for anything that needs the whole configuration — a supplier notification, an ERP push, a production record.
add_action( 'mkl_pc/order_created/after_saved_data', function ( $item, $order, $configurator_data ) { my_queue_production_job( $order->get_id(), $item->get_id(), $configurator_data );}, 10, 3 );
Keep it fast, or schedule the real work — this runs during checkout.
mkl_pc/customer_can_see_image_download_link
Note the inverted sense: returning true hides the link. The default is
'completed' != $order->get_status(), so the link appears only once the order is complete.
// Always show it, whatever the status.add_filter( 'mkl_pc/customer_can_see_image_download_link', '__return_false' );
mkl_pc/do_not_show_image_download_link reads the way you would expect — true suppresses the
link — and is checked first.
mkl_pc/order_image_size
The registered image size used for the configuration preview on an order, defaulting to the Cart thumbnail size setting.
add_filter( 'mkl_pc/order_image_size', function ( $size, $order_item, $data ) { return 'full';}, 10, 3 );
mkl_pc/cart_item/merge_layer_image_id
The image token for a choice when the preview image is merged server-side — usually an attachment id, sometimes the basename of a temporary upload. Returning an empty value drops that layer from the merged image.
It runs on the token the choice has already resolved, which for a cart item, an order or a quote
is the one saved with the configuration — see
mkl_pc/choice/source.
mkl_pc_3d_screenshot_temp_max_age
3D products post a screenshot with the configuration, held in a temporary location until the order is placed. Orphans are cleaned up after 48 hours by default.
add_filter( 'mkl_pc_3d_screenshot_temp_max_age', function () { return 7 * DAY_IN_SECONDS;} );
mkl_pc_3d_screenshot_dimensions
The width and height the 3D viewer captures the cart, quote and order picture at, as
array( 'width' => …, 'height' => … ). It follows the Merge size setting, 800 × 800 for full
size.
It is also the largest picture accepted. The screenshot is posted by the browser, so a picture that is not a PNG, or is larger than this size, is refused and the line has no image. Change the size here rather than in JavaScript, so the two stay in step.
add_filter( 'mkl_pc_3d_screenshot_dimensions', function ( $dimensions ) { return array( 'width' => 1200, 'height' => 900 );} );
WooCommerce hooks fired here
To keep existing customisations working, the plugin fires several WooCommerce hooks itself when
it renders configured lines: woocommerce_cart_item_product, …_product_id, …_visible,
…_permalink, …_thumbnail, and woocommerce_order_item_display_meta_key / …_meta_value. All
carry WooCommerce's own arguments.