E-Commerce Core Concepts
InnoShop has five core data models: Category, Brand, Specification (Variant), Option, and Attribute. Understanding their differences and use cases is fundamental for customization.
Concept Comparison
| Concept | Purpose | Affects Price | Affects Stock | Relationship |
|---|---|---|---|---|
| Category | Organize products | ❌ | ❌ | Many-to-many (product_categories) |
| Brand | Identify manufacturer | ❌ | ❌ | One-to-many (brand_id) |
| Specification | Product variant SKU | ✅ | ✅ | One-to-many (product_skus) |
| Option | Value-added service | ✅ | ✅ | Many-to-many (product_options) |
| Attribute | Product specs display | ❌ | ❌ | Many-to-many (product_attributes) |
1. Category
Organize products in a hierarchy for navigation and filtering.
Electronics
└── Phones
└── SmartphonesFeatures: Tree hierarchy (parent_id), multi-category per product, SEO support, multi-language.
Database Tables: categories (main), category_translations, product_categories (pivot)
Code Location: innopacks/common/src/Models/Category.php, Repositories/CategoryRepo.php
$category->children(); // Child categories
$category->activeChildren(); // Active children
$category->parent(); // Parent category
$category->products(); // Products in category2. Brand
Identify the product manufacturer for brand-based filtering.
Features: Direct brand_id foreign key, brand logo support, first-letter filtering.
Database Tables: brands (main, no translation table needed)
Code Location: innopacks/common/src/Models/Brand.php, Repositories/BrandRepo.php
$brand->products();
BrandRepo::getInstance()->autocomplete($keyword);3. Specification (Variant)
Define different product versions/SKUs. Each specification combination maps to an independent stock unit.
| Spec Combo | SKU Code | Price | Stock |
|---|---|---|---|
| Red - Large | SKU-001 | $99 | 50 |
| Red - Medium | SKU-002 | $89 | 30 |
Key Concepts:
- Variant Dimension (
product_variants): e.g. Color, Size — each product has an ordered list of dimensions. - Variant Value (
product_variant_values): e.g. Red, Large — each dimension has an ordered list of selectable values. - SKU-Variant Pivot (
product_sku_variant_values): links a SKU to exactly one value per dimension, enforced by aUNIQUE(sku_id, variant_id)constraint. - Variant Template (
variant_templates): reusable dimension + SKU matrix presets for quickly applying common configurations to new products.
Data Model (normalized since 2026-07):
product_variants (dimensions)
├── id, product_id, position, is_image
└── product_variant_translations (locale, name)
product_variant_values (values per dimension)
├── id, variant_id, image, position
└── product_variant_value_translations (locale, name)
product_skus (stock units)
└── product_sku_variant_values (pivot)
├── sku_id, variant_id, value_id
└── UNIQUE(sku_id, variant_id)The legacy products.variables JSON column has been removed. For backward compatibility, $product->variables is now an accessor that synthesizes the legacy shape from the normalized tables via LegacyVariablesBuilder.
Example synthesized $product->variables shape:
[
{
"name": {"en": "Color", "zh-cn": "颜色"},
"isImage": false,
"values": [
{"name": {"en": "Red", "zh-cn": "红色"}, "image": ""},
{"name": {"en": "Blue", "zh-cn": "蓝色"}, "image": ""}
]
}
]Database Tables: product_variants, product_variant_translations, product_variant_values, product_variant_value_translations, product_sku_variant_values, product_skus, variant_templates
Code Location: Models/Product.php, Models/Product/Sku.php, Models/Product/Variant.php, Models/Product/Variant/Value.php, Models/Product/Sku/VariantValue.php, Models/Product/VariantTemplate.php, Repositories/ProductRepo.php, Repositories/Product/VariantRepo.php, Services/LegacyVariablesBuilder.php
// Product-level access
$product->skus(); // All SKUs (HasMany)
$product->masterSku(); // Master SKU (HasOne, is_default=1)
$product->variants(); // Variant dimensions (HasMany, ordered by position)
$product->isMultiple(); // Has multiple variants?
$product->variables; // Legacy shape (accessor via LegacyVariablesBuilder)
$product->variant_dimensions; // Structured shape with stable DB ids
// SKU-level access
$sku->variantValues(); // BelongsToMany via product_sku_variant_values pivot
$sku->getLocaleLabels(); // [['name'=>'Color','value'=>'Red'], ...]
$sku->variant_label; // "Color:Red; Size:L"
$sku->full_name; // "Product Name (Color:Red; Size:L)"
// Variant-level access
$variant->values(); // Values for this dimension (ordered by position)
$variant->translation->name; // Localized dimension name4. Option
Value-added services or add-ons selectable during purchase. These are supplementary services, not product variants.
| Option Name | Values | Price Impact |
|---|---|---|
| Gift Wrap | Standard / Gift Box | +$10 |
| Warranty | 1-year / 2-year extended | +$99 |
Features: Price adjustment, required/optional, select/radio/checkbox display types, multi-language JSON.
Database Tables: options, option_values, product_options, product_option_values
Code Location: Models/Option.php, Models/OptionValue.php, Repositories/OptionRepo.php
$product->options(); // Product options
$product->productOptions(); // Option configurations
$option->values(); // Option values5. Attribute
Describe product specifications and technical parameters for detail page display and category page filtering.
| Attribute | Value |
|---|---|
| Material | Cotton |
| Weight | 500g |
Features: Product spec display, filtering, grouped management. Filter logic: different attribute groups use AND, values within the same group use OR.
Filter URL format: attr=1:10,11|2:20 means (attr1=value10 OR value11) AND (attr2=value20)
Database Tables: attributes, attribute_translations, attribute_groups, attribute_values, product_attributes
Code Location: Models/Attribute.php, Models/Attribute/Group.php, Repositories/AttributeRepo.php
$product->productAttributes(); // Product attributes
$product->groupedAttributes(); // Grouped attributes
$attribute->group(); // Attribute group
$attribute->values(); // Attribute values