Skip to content

Module Architecture

Super attributes, product linking, and pricing architecture for configurable products.

Conceptual Overview

A configurable product is a composite product type that allows customers to select from predefined attribute options to choose a specific product variant. The configurable product itself has no stock or price - these come from the simple product children.

Configurable Product (T-Shirt)
Color (Super Attribute)
Size (Super Attribute)
Red - S
Red - M
Red - L
Blue - S
Blue - M
Blue - L

Simple Product Children (Actual SKUs with stock/price)

Super Attributes System

Super attributes are EAV attributes designated as configuration axes for a configurable product. Only attributes with select frontend input type and global scope can be used as super attributes.

Super Attribute Requirements

Attribute Properties

  • frontend_input = 'select'
  • is_global = 1 (Global scope)
  • is_user_defined = 1 (or core like color/size)
  • Must have predefined options

Attribute Storage

  • catalog_product_super_attribute table
  • Links attribute_id to product_id
  • Position determines display order
  • Store-specific labels supported

Database Schema

-- Super attribute definition (links attribute to configurable product)
CREATE TABLE catalog_product_super_attribute (
    product_super_attribute_id INT UNSIGNED AUTO_INCREMENT,
    product_id INT UNSIGNED,      -- Configurable product entity_id
    attribute_id SMALLINT UNSIGNED, -- EAV attribute_id
    position SMALLINT UNSIGNED,     -- Display order
    PRIMARY KEY (product_super_attribute_id),
    UNIQUE (product_id, attribute_id)
);

-- Store-specific labels for super attributes
CREATE TABLE catalog_product_super_attribute_label (
    value_id INT UNSIGNED AUTO_INCREMENT,
    product_super_attribute_id INT UNSIGNED,
    store_id SMALLINT UNSIGNED,
    use_default SMALLINT UNSIGNED DEFAULT 0,
    value VARCHAR(255),
    PRIMARY KEY (value_id)
);

Loading Super Attributes

// Get configurable attributes for a product
$configurableType = $product->getTypeInstance();
$superAttributes = $configurableType->getConfigurableAttributes($product);

foreach ($superAttributes as $attribute) {
    $attributeCode = $attribute->getProductAttribute()->getAttributeCode();
    $label = $attribute->getLabel();
    $position = $attribute->getPosition();

    // Get available options from child products
    $options = $attribute->getOptions();
}

Parent-Child Product Linking

The super_link table establishes the relationship between configurable parents and simple product children. Each child must have values for all super attributes of the parent.

Link Table Schema

-- Links simple products to configurable parent
CREATE TABLE catalog_product_super_link (
    link_id INT UNSIGNED AUTO_INCREMENT,
    product_id INT UNSIGNED,  -- Child simple product entity_id
    parent_id INT UNSIGNED,   -- Parent configurable product entity_id
    PRIMARY KEY (link_id),
    UNIQUE (product_id, parent_id),
    FOREIGN KEY (product_id) REFERENCES catalog_product_entity(entity_id),
    FOREIGN KEY (parent_id) REFERENCES catalog_product_entity(entity_id)
);

Important Constraint

A simple product can be linked to multiple configurable parents, but the combination of (product_id, parent_id) must be unique. This enables the same simple product to appear as an option in multiple configurables.

Getting Child Products

// Get all linked simple products
$configurableType = $product->getTypeInstance();

// Full product objects (loads EAV attributes)
$usedProducts = $configurableType->getUsedProducts($product);

// Just product IDs (faster, no EAV load)
$childIds = $configurableType->getChildrenIds($product->getId());

// Find specific child by attribute values
$attributes = ['color' => 'red', 'size' => 'M'];
$child = $configurableType->getProductByAttributes($attributes, $product);

Pricing Architecture

Configurable products don't have their own price. Instead, the price is derived from the child products. Magento provides flexible price resolution strategies.

Price Resolution Flow

ConfigurablePriceResolver
FinalPriceResolver
RegularPriceResolver
LowestPriceOptionsProvider
Child 1 Price
Child 2 Price
Child N Price

Price Type Classes

Class Purpose
ConfigurablePriceResolver Main resolver that delegates to specific price type resolvers
FinalPrice Calculates final price (lowest among salable children)
ConfigurableRegularPrice Calculates regular price before discounts
LowestPriceOptionsProvider Finds the child product with lowest price
ConfigurableOptionsProvider Provides all option prices for frontend display

Price Calculation Example

// Getting configurable product price
$priceInfo = $product->getPriceInfo();

// Final price (lowest salable child)
$finalPrice = $priceInfo->getPrice('final_price')->getAmount();

// Regular price
$regularPrice = $priceInfo->getPrice('regular_price')->getAmount();

// All option prices for swatch/dropdown display
$optionsProvider = $objectManager->get(ConfigurableOptionsProviderInterface::class);
$options = $optionsProvider->getProducts($product);

Product Type Model

The Configurable type class extends AbstractType and provides all configurable-specific behavior.

Key Methods

Method Purpose
getConfigurableAttributes($product) Returns collection of super attributes for the product
getUsedProducts($product, $attributes) Returns all linked simple products (with optional attribute filter)
getProductByAttributes($attributes, $product) Finds the specific child matching attribute values
isSalable($product) Returns true if at least one child is salable
prepareForCartAdvanced($buyRequest, $product) Prepares products for adding to cart (returns [parent, child])
getSelectedAttributesInfo($product) Gets selected option info for order/cart display
getConfigurableOptions($product) Returns all available options for frontend JSON

Type Model Flow

// Product type identification
$product->getTypeId(); // Returns 'configurable'
$product->getTypeInstance(); // Returns Configurable type model

// Check if product is configurable
if ($product->getTypeId() === Configurable::TYPE_CODE) {
    $superAttributes = $product->getTypeInstance()
        ->getConfigurableAttributes($product);
}

EntityManager Integration

Configurable product data is persisted through EntityManager handlers that process super attributes and links during product save/load operations.

Extension Handlers

<!-- di.xml EntityManager configuration -->
<type name="Magento\Framework\EntityManager\Operation\ExtensionPool">
    <arguments>
        <argument name="extensionActions" xsi:type="array">
            <item name="Magento\Catalog\Api\Data\ProductInterface">
                <item name="create">
                    <item name="create_configurable_options">
                        Magento\ConfigurableProduct\Model\Product\SaveHandler
                    </item>
                </item>
            </item>
        </argument>
    </arguments>
</type>

Handler Responsibilities

SaveHandler

  • Saves super attributes to catalog_product_super_attribute
  • Saves attribute labels per store
  • Creates/updates super_link relationships
  • Validates child products have required attributes

ReadHandler

  • Loads super attributes into extension_attributes
  • Populates configurable_product_options
  • Loads configurable_product_links (child IDs)
  • Sets data on product model for type instance

Variation Generator

The variation generator creates all possible simple product combinations from selected super attributes. This is used in admin when creating configurable products.

// Generate all variations programmatically
$management = $objectManager->get(ConfigurableProductManagementInterface::class);

// Define attributes and their options
$options = [
    [
        'attribute_id' => '93',  // Color
        'values' => [
            ['value_index' => '49'],  // Black
            ['value_index' => '50'],  // Blue
        ]
    ],
    [
        'attribute_id' => '141', // Size
        'values' => [
            ['value_index' => '166'], // S
            ['value_index' => '167'], // M
            ['value_index' => '168'], // L
        ]
    ]
];

// Generates 6 variations: Black-S, Black-M, Black-L, Blue-S, Blue-M, Blue-L
$variations = $management->generateVariation($product, $options);