Skip to content

Product Variations & Lines

Flow ID: CF-25 | Module(s): variations, Product domain | Complexity: High

Business Overview

Variations model product options (Size, Color) as a matrix. Products with the same variations are grouped for frontend switching.

Hierarchy:

  • Variation Group: Dimension (e.g., "Size") with display type (text, hex-color, image, range)
  • Variation Value: Option (e.g., "S", "M", "L")
  • Product Code (SKU): Purchasable unit with independent stock
  • Product Variation: Links product to group, designates master

Key business behaviors:

  • Stock is per-SKU (product_codes.stock)
  • Cart stores productCodeId (specific SKU)
  • Master product in variation group is the "primary" display product
  • Display position: 0=ALL, 1=PRODUCT only, 2=FILTER only, 3=NONE

API Reference

REST Endpoints

MethodPathAuthDescription
GET/rest/product/variationGuestList product variations
GET/rest/product/variation-groupGuestList variation groups (sorts: priority)
GET/rest/product/variation-valueGuestList variation values
GET/rest/product/lineGuestList product codes/SKUs

Full CRUD with Backend auth for all.


Domain Layer

ComponentPath
Variation Servicesrc/Domains/Product/Variation/Service.php
VariationGroup Servicesrc/Domains/Product/Variation/Group/Service.php
VariationValue Servicesrc/Domains/Product/Variation/Value/Service.php
Line Servicesrc/Domains/Product/Line/Service.php

Note: product_code_attributes table maps SKU → variation values (not product_variation_values).


Client Extension Points

  • Stock aggregation: Override Service for custom stock summing
  • Master selection: WriteService logic for is_master designation
  • Filter config: category_level_for_variations_in_sidebar, enableProductVariations
  • Attribute groups: Registry AFFILIATION_ATTRS_GROUPS.GROUPS_FOR_SIZE/COLOR

Data Model

variation_groups

ColumnTypeDescription
idint (PK, AI)Group identifier
display_typevarcharRendering mode: text, hex-color, image, range
priorityintSort order for display

variation_groups_mui

ColumnTypeDescription
idint (PK, AI)Translation row ID
variation_group_idint (FK)Parent group
namevarcharDisplay name (e.g., "Size", "Color")
langvarcharLanguage code

variation_values / variation_values_mui

ColumnTypeDescription
idint (PK, AI)Value identifier
variation_group_idint (FK)Parent group
hex_valuevarchar (nullable)Hex color code (for hex-color type)
imagevarchar (nullable)Image path (for image type)

product_variations

ColumnTypeDescription
idint (PK, AI)Row ID
product_idint (FK)Product in the variation group
variation_group_idint (FK)Variation dimension
is_mastertinyint1 = primary display product
priorityintSort position

product_codes (SKUs)

ColumnTypeDescription
idint (PK, AI)SKU identifier
product_idint (FK)Parent product
stockintAvailable stock for this SKU
skuvarcharExternal SKU code
barcodevarchar (nullable)EAN/barcode

product_code_attributes

ColumnTypeDescription
idint (PK, AI)Row ID
product_code_idint (FK)SKU
variation_value_idint (FK)Attribute value (e.g., "Red", "XL")

Variation Traits (Legacy Controllers)

Two shared traits encapsulate the variation logic used across storefront and admin controllers:

ProductVariationsTrait

  • Merges live product data with variation definitions
  • Builds variation group data structures including SEO-friendly URLs for each variant
  • Used when rendering the product detail page variation matrix

ProductVariationsListingTrait

  • Filters variation products from listing queries (excludes child/non-master products per configuration)
  • Loads variation groups for displayed products
  • Processes variation filter parameters from the query string (e.g., ?variation_1=3&variation_2=7)

Trait Usage

ControllerTrait(s)Context
Adv_products_admin.phpProductVariationsTraitAdmin product editing
AdvApiVariationsController.phpProductVariationsTraitAdmin API for variation management
Adv_products.phpProductVariationsTrait, ProductVariationsListingTraitStorefront product detail + listings
Listing controllersProductVariationsListingTraitCategory/search result pages

Legacy AJAX API

These endpoints are served by AdvApiVariationsController (ecommercen/api/controllers/AdvApiVariationsController.php) and are used by the admin panel Vue components to manage variation groups, values, and product assignments. All endpoints accept JSON request bodies (parsed via jsonDecodeInputStream()) and return JSON responses via sendOutput().

Base path: /api/variations/{method} (routed via api/api_variations)

MethodPathParametersResponseDescription
POST/api/variations/getVariationGroupProductsApiproductId (int, required){variationGroupProducts: [...]}Get all products in the same variation group as the given product
POST/api/variations/updateProductVariationproductId (int, required), productVariation[] (array, required), masterProductId (int, optional){}Update variation value assignments for a product; returns 422 if any values are empty
POST/api/variations/updateVariationGroupMastergroupId (int, required), productId (int, required){}Set a product as the master (primary display) in a variation group
POST/api/variations/getAllVariation(none){allVariation: [...]}Get all variation values across all groups
POST/api/variations/getVariationGroupMuigroupId (int, required){variationGroupMui: [...]}Get multi-language names for a variation group
POST/api/variations/getVariationGroupNameproductId (int, required){variationGroupName: ...}Get the variation group name for a product
POST/api/variations/getVariationGroupIdproductId (int, required){variationGroupId: ...}Get the variation group ID that a product belongs to
POST/api/variations/getProductVariationsvariationGroupProductIds[] (array, required){productVariationData: {[productId]: {[groupId]: {...}}}}Get variation details for multiple products, keyed by product ID and group ID
POST/api/variations/deleteProductFromVariationGroupgroupId (int, required), productId (int, required){}Remove a product from a variation group
POST/api/variations/addVariationProductToGroupgroupId (int, required), productId (int, required){}Add a product to an existing variation group; returns 422 if product is already in another group
POST/api/variations/addVariationProductToGroup (new group)groupId (falsy/0), productId (int, required), productName (string, required), variationGroupMui[] (array, required){groupId: int}When groupId is falsy, creates a new variation group and adds the product to it
POST/api/variations/batchActionMoveVariationValuescurrentGroupId (int, required), targetGroupId (int, required), variationValueIds[] (array, required){}Move variation values from one group to another
POST/api/variations/changeVariationGroupProductsPriorityvariationProducts[] (array, required){}Update display priority/sort order for products within a variation group
POST/api/variations/batchActionMassDeleteValuesvariationValueIds[] (array, required){}Batch delete variation values
POST/api/variations/updateProductVariationGroupNameMuigroupId (int, required), variationGroupMui[] (array, required){}Update multi-language names for a variation group
POST/api/variations/updateProductStockproductId (int, required), productCodeId (int, required), stock (int, required){}Update stock for a specific product SKU
POST/api/variations/getVariationByVariationValueIdvariationValueId (int, required)[{...}]Get variation details by variation value ID

Error format: {error: {field: message}, statusCode: 400, statusMsg: "Bad Request"} for validation failures; 422 for business rule violations.