Module Architecture
Super attributes, product linking, and pricing architecture for configurable products.
Super attributes, product linking, and pricing architecture for configurable products.
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.
Simple Product Children (Actual SKUs with stock/price)
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.
frontend_input = 'select'is_global = 1 (Global scope)is_user_defined = 1 (or core like color/size)catalog_product_super_attribute table-- 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) );
// 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(); }
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.
-- 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) );
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.
// 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);
Configurable products don't have their own price. Instead, the price is derived from the child products. Magento provides flexible price resolution strategies.
| 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 |
// 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);
The Configurable type class extends AbstractType and provides all configurable-specific behavior.
| 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 |
// 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); }
Configurable product data is persisted through EntityManager handlers that process super attributes and links during product save/load operations.
<!-- 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>
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);