Guide

Functions and methods

The PHP functions, classes and JavaScript objects that are safe to call from your own code. This is a much smaller surface than the hook reference — the plugin is customised mainly through hooks, and these are what you use inside those callbacks.

Anything not listed here is internal. It may exist, it may look useful, and it may change without notice.

PHP functions

All of these are available once the plugin has loaded. Hook onto mkl_pc_is_loaded, or anything later than plugins_loaded, before calling them.

FunctionReturnsPurpose
mkl_pc( $component = false )object|falseThe plugin instance, or one of its components
mkl_pc_is_configurable( $product_id = null )boolWhether a product has a configurator
mkl_pc_get_configurator_type( $product_id = null )string|false'configurator', '3d', or false
mkl_pc_get_configuration_meta_mode( $product = false )stringHow configuration meta is written to orders
mkl_pc_get_allowed_3d_material_properties()arrayMaterial properties a 3D choice may set
mkl_pc_sanitize_3d_material_property_name( $name )string|falseValidate one against that list
mkl_pc_get_settings_page_url( $query_args = array() )stringURL of the plugin's settings page
mkl_pc_is_settings_page()boolWhether the current screen is that page
mkl_pc_get_admin_menu_slug()stringThe admin menu slug
mkl_pc_get_admin_menu_capability()stringThe capability required to see it
mkl_pc_include_svg_icon( $icon )voidPrint one of the plugin's SVG icons

mkl_pc()

The service locator. Called with no argument it returns the plugin instance; with a component name it returns that component.

php functions.php
$theme       = mkl_pc( 'settings' )->get_theme();$show_prices = mkl_pc( 'settings' )->get( 'show_price_in_configurator' );
mkl_pc().
ComponentWhat it is
settingsPlugin settings and labels
dbThe configuration data store
cacheCached config files
themesConfigurator themes
languagesTranslation integration
frontendFrontend rendering
adminThe editor (admin requests only)
ajaxAJAX endpoints
customizerCustomizer integration
frontend_securityTokens, captcha and rate limiting

An unknown name returns false rather than throwing, so guard when you are not sure:

php functions.php
$admin = mkl_pc( 'admin' );if ( $admin ) {	// only exists on admin requests}
An unknown name returns false rather than throwing, so guard when you are not sure.

mkl_pc_is_configurable() and mkl_pc_get_configurator_type()

The two guards most third-party code needs. Both fall back to the current post when called with no argument, so inside the loop you can omit it.

php functions.php
add_action( 'woocommerce_after_add_to_cart_form', function () {	if ( ! mkl_pc_is_configurable() ) {		return;	}	if ( '3d' === mkl_pc_get_configurator_type() ) {		echo '<p>' . esc_html__( 'Drag to rotate the model.', 'my-plugin' ) . '</p>';	}} );
mkl_pc_is_configurable() and mkl_pc_get_configurator_type().

mkl_pc_get_configurator_type() returns 'configurator' for a 2D configurator, '3d' for a 3D one, and false when the id is not a product at all. It resolves global configurators too, so a product that inherits its configurator still reports the right type.

mkl_pc_get_configuration_meta_mode()

Returns 'single' or 'individual', which determines which order hooks fire. Check it before assuming your filter runs.

Settings

mkl_pc( 'settings' ) is the one component you will use regularly.

MethodPurpose
get( $setting, $default = false, $return_default_if_empty = false )Read a setting
get_label( $setting, $default )Read a translatable label
get_theme()The active configurator theme id
set( $key, $value )Write a setting
php functions.php
$label = mkl_pc( 'settings' )->get_label(	'mkl_pc__button_label',	__( 'Configure', 'my-plugin' ));
Settings.

Use get_label() rather than get() for anything shown to a customer — it runs the value through the translation layer, so WPML and Polylang work.

The third argument to get() matters more than it looks: by default an empty stored value is returned as-is, so a setting a merchant has cleared comes back as '' rather than your default. Pass true to fall back to the default in that case.

set() writes to the options table. It is intended for migrations and admin tooling, not for per-request use.

MKL\PC\Choice

The object representing one selected choice in a configuration. Cart and order hooks hand you these — see mkl_pc_item_meta.

MethodPurpose
get_layer( $key )A value from the layer — name, type, class_name, …
get_choice( $key )A value from the choice — name, sku, extra_price, and any custom field
set_choice( $key, $value )Overwrite a choice value
set_layer_value( $key, $value )Overwrite a layer value
is_choice()Whether this represents a real selection
get_image( $type = 'image' )The image array
get_image_url( $type = 'image' )Its URL
get_image_id( $type = 'image' )Its attachment id
get_choice_thumbnail()The thumbnail array
get_choice_by_id( $id )Another choice from the same layer
php functions.php
add_filter( 'mkl_pc_item_meta', function ( $meta, $layer, $product, $item_key, $context ) {	if ( ! $layer->is_choice() ) {		return $meta;	}	$sku = $layer->get_choice( 'sku' );	if ( $sku ) {		$meta['value'] .= ' <code>' . esc_html( $sku ) . '</code>';	}	return $meta;}, 10, 5 );
MKL\PC\Choice.

The variable is conventionally named $layer in core even though it is a Choice — it carries both the layer and the selected choice, which is why it has two families of getter.

Always call is_choice() first. A Choice can represent a group or a layer with nothing selected, and the getters return empty values in that case rather than failing.

Choices are serialised into cart and order data. A property you add is lost unless you also add it to mkl_pc_choice_sleep_properties.

MKL\PC\Configuration

A saved configuration — the object behind saved designs, presets and order configurations.

MethodPurpose
get_layers()Its choices, as Choice objects
get_item_data( $context = 'cart' )The label/value pairs for display
get_configured_price( $args = array() )base, extra and total
get_image( $size, $attr, $lazy )The rendered preview as an <img>
get_image_url( $lazy, $size )Its URL
save( $args = array() )Persist it
update( $args )Update it
delete()Remove it
configuration_exists()Whether it is stored
configuration_image_exists()Whether its preview has been generated
php functions.php
$configuration = new \MKL\PC\Configuration( $configuration_id );$prices = $configuration->get_configured_price( array( 'quantity' => 2 ) );if ( ! is_wp_error( $prices ) ) {	echo wc_price( $prices['total'] );}foreach ( $configuration->get_layers() as $layer ) {	echo esc_html( $layer->get_layer( 'name' ) . ': ' . $layer->get_choice( 'name' ) );}
MKL\PC\Configuration.

get_configured_price() returns a WP_Error when the product cannot be resolved — check for it. Its extra figure is only meaningful when the Extra Price add-on is active.

Constructing one with an id loads it; constructing with null and an args array builds a new one from raw content, which is how the plugin renders previews for order items.

MKL\PC\Utils

Static helpers. Most are internal, but a few are genuinely reusable:

MethodPurpose
Utils::is_configurable( $product_id )What mkl_pc_is_configurable() calls
Utils::is_product( $post_id )Whether a post is a product or variation
Utils::is_configurator_owner( $post_id )Whether it owns a configurator
Utils::kses_basic_inline_html( $html )Sanitise to the inline tags the plugin allows
Utils::sanitize_html_classes( $classes )Sanitise an array of class names
Utils::get_registered_image_size( $size )Resolve a registered image size
Utils::inline_svg( $file_path )Read an SVG safely for inline output

kses_basic_inline_html() is the one to remember. Cart and order display run every label and value through it, so matching it in your own filters keeps output consistent:

php functions.php
add_filter( 'mkl_pc_cart_item_choice', function ( $html, $key, $value ) {	return \MKL\PC\Utils::kses_basic_inline_html( $html );}, 20, 3 );
MKL\PC\Utils.

Frontend JavaScript

PC.fe is the running configurator. It only exists once the configurator has been opened — do your work from PC.fe.start rather than on page load.

MemberTypePurpose
PC.fe.layersCollectionEvery layer
PC.fe.anglesCollectionEvery angle
PC.fe.currentProductDataobjectThe data the configurator was built from
PC.fe.configobjectBehaviour flags, from PC_config.config
PC.fe.openedboolWhether the configurator is open
PC.fe.is_setting_configboolTrue while a stored configuration is being applied
PC.fe.active_productintThe product being configured
PC.fe.getLayerContent( layerId )Collection|falseA layer's choices
PC.fe.get_choice_model( layerId, choiceId )Model|falseOne choice
PC.fe.get_product_price()numberThe base price
PC.fe.setConfig( configItems )voidApply a stored configuration
PC.fe.open( productId, parentId, $el, reset )voidOpen the configurator
PC.fe.close()voidClose it
PC.fe.goto( … )voidMove to a layer or step
PC.fe.save_data.save()stringThe configuration as JSON
PC.fe.save_data.get_choices( reset )arrayThe same, as an array
PC.fe.save_data.getSaveDataAsync()Promise<string>The same, awaiting registered promises
javascript custom.js
wp.hooks.addAction( 'PC.fe.start', 'my-plugin/configurator', function () {	PC.fe.layers.each( function ( layer ) {		const choices = PC.fe.getLayerContent( layer.id );		const active  = choices ? choices.findWhere( { active: true } ) : null;		console.log( layer.get( 'name' ), '→', active ? active.get( 'name' ) : '(none)' );	} );} );
Frontend JavaScript.

getLayerContent() returns false for a layer with no choices — a group or a summary layer — so check before using it.

PC.fe.is_setting_config is how you distinguish a customer's click from a restored selection inside a PC.fe.choice.set_choice handler:

javascript custom.js
wp.hooks.addAction( 'PC.fe.choice.set_choice', 'my-plugin/configurator', function ( model ) {	if ( PC.fe.is_setting_config ) return; // restoring, not a real click	myAnalytics.track( 'choice', { name: model.get( 'name' ) } );} );
Frontend JavaScript.

Use getSaveDataAsync() rather than save() if anything on the site registers PC.fe.save_data.before_save.promises — Text Overlay and the 3D viewer both do, and save() will not wait for them.

PC.utils

MethodPurpose
PC.utils.formatMoney( amount, useCurrency )Format a number using the store's currency settings
PC.utils.escape_html( string )Escape for output
PC.utils.strip_html( string )Remove tags
PC.utils._isMobile()Mobile viewport check
PC.utils._isTouch()Touch device check
javascript custom.js
document.querySelector( '#my-total' ).textContent = PC.utils.formatMoney( 1234.5 );
PC.utils.

formatMoney() honours the decimal and thousand separators, the symbol position and the precision configured in WooCommerce, so use it rather than toFixed().

3D

The 3D viewer exposes a live runtime API rather than a static object — scene, camera, renderer, material registry, events. See The 3D runtime API.

Constants

ConstantPurpose
MKL_PC_VERSIONPlugin version
MKL_PC_PREFIXMeta key prefix (_mkl_pc_)
MKL_PC_ASSETS_URLURL of the plugin's assets directory
MKL_PC_ASSETS_PATHFilesystem path to it

Use MKL_PC_PREFIX when reading the plugin's own meta directly rather than hard-coding the prefix — it has changed once already.