Attribute Properties
Core Attribute Properties
SELECT
attribute_id,
attribute_code,
backend_type,
frontend_input,
frontend_label,
is_required,
is_filterable,
is_searchable,
is_used_for_sort_by,
scope
FROM eav_attribute
WHERE entity_type_id = 4
LIMIT 15;
+---------------+---------------------+--------------+-----------------+----------------------+-------------+-------------+-------------+-------------------+-------+
| attribute_id | attribute_code | backend_type | frontend_input | frontend_label | is_required | is_filterable | is_searchable | is_used_for_sort_by | scope |
+---------------+---------------------+--------------+-----------------+----------------------+-------------+-------------+-------------+-------------------+-------+
| 71 | name | varchar | text | Name | 1 | 0 | 0 | 0 | 0 |
| 73 | description | text | textarea | Description | 0 | 0 | 0 | 0 | 0 |
| 75 | price | decimal | price | Price | 1 | 0 | 0 | 0 | 1 |
| 77 | sku | varchar | text | SKU | 1 | 0 | 0 | 0 | 2 |
| 85 | small_image | varchar | media_image | Small Image | 0 | 0 | 0 | 0 | 0 |
| 97 | status | int | boolean | Status | 1 | 1 | 0 | 0 | 2 |
| 99 | visibility | int | select | Visibility | 1 | 1 | 0 | 0 | 2 |
+---------------+---------------------+--------------+-----------------+----------------------+-------------+-------------+-------------+-------------------+-------+
Attribute Code Naming
Rules:
- Lowercase only
- Underscores for spaces
- No special characters
- Max 255 characters
- Must be unique per entity type
Examples:
name → Product name
short_description → Short description
special_price → Special price
tax_class_id → Tax class
news_from_date → New from date
Backend Type
Backend Types
The backend_type determines which value table stores the attribute value:
-- varchar: Short text (max 255 chars)
INSERT INTO catalog_product_entity_varchar (attribute_id, entity_id, store_id, value)
VALUES (71, 123, 0, 'T-Shirt');
-- text: Long text (up to 64KB)
INSERT INTO catalog_product_entity_text (attribute_id, entity_id, store_id, value)
VALUES (73, 123, 0, 'This is a detailed product description...');
-- int: Integer values
INSERT INTO catalog_product_entity_int (attribute_id, entity_id, store_id, value)
VALUES (97, 123, 0, 1); -- status: enabled
-- decimal: Precise numeric values
INSERT INTO catalog_product_entity_decimal (attribute_id, entity_id, store_id, value)
VALUES (75, 123, 0, 29.9900); -- price
-- datetime: Date/time values
INSERT INTO catalog_product_entity_datetime (attribute_id, entity_id, store_id, value)
VALUES (101, 123, 0, '2024-01-01 00:00:00'); -- special_price_from
-- static: Stored in entity table itself
-- (e.g., type_id, attribute_set_id in catalog_product_entity)
Backend Type Selection
| Backend Type | Use Cases | Storage |
|---|---|---|
| varchar | Name, SKU, URL key | catalog_*_entity_varchar |
| text | Description, HTML content | catalog_*_entity_text |
| int | Status, visibility, dropdowns | catalog_*_entity_int |
| decimal | Price, weight, dimensions | catalog_*_entity_decimal |
| datetime | Special price dates, created_at | catalog_*_entity_datetime |
| static | Entity table columns | Entity table itself |
Frontend Input Types
Input Types
-- Input types determine admin form rendering
SELECT DISTINCT frontend_input, COUNT(*) as count
FROM eav_attribute
WHERE entity_type_id = 4
GROUP BY frontend_input;
+-----------------+-------+
| frontend_input | count |
+-----------------+-------+
| text | 15 |
| textarea | 5 |
| select | 10 |
| boolean | 3 |
| price | 2 |
| media_image | 3 |
| multiselect | 2 |
| date | 2 |
| weee | 1 |
| weight | 1 |
| gallery | 1 |
+-----------------+-------+
Input Type Examples
// Text input
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_text',
['type' => 'varchar', 'input' => 'text']
);
// Textarea
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_textarea',
['type' => 'text', 'input' => 'textarea']
);
// Select (dropdown)
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_select',
['type' => 'int', 'input' => 'select', 'source' => 'Vendor\Module\Model\Source\Options']
);
// Boolean (yes/no)
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_boolean',
['type' => 'int', 'input' => 'boolean']
);
// Date
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_date',
['type' => 'datetime', 'input' => 'date']
);
// Price
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'custom_price',
['type' => 'decimal', 'input' => 'price']
);
Attribute Validation
Built-in Validation
// Required validation
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'required_field',
[
'type' => 'varchar',
'input' => 'text',
'required' => true,
'validate_rules' => [
'max_text_length' => 255,
'min_text_length' => 1
]
]
);
// Unique validation
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'unique_field',
[
'type' => 'varchar',
'input' => 'text',
'unique' => true
]
);
Custom Validation
// Custom backend model with validation
class Vendor\Module\Model\Product\Attribute\Backend\CustomValidation
extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
{
public function validate($object)
{
$value = $object->getData($this->getAttribute()->getAttributeCode());
if (empty($value)) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Field cannot be empty')
);
}
if (strlen($value) < 3) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Field must be at least 3 characters')
);
}
return true;
}
}
// Register validation
$eavSetup->addAttribute(
\Magento\Catalog\Model\Product::ENTITY,
'validated_field',
[
'type' => 'varchar',
'input' => 'text',
'backend' => 'Vendor\Module\Model\Product\Attribute\Backend\CustomValidation'
]
);
Validation Rules
// Validation rules array
'validate_rules' => [
'max_text_length' => 255,
'min_text_length' => 1,
'max_number_length' => 10,
'min_number_value' => 0,
'max_number_value' => 100,
'input_validation' => 'numeric',
'email_validation' => true,
'url_validation' => true,
]
// In di.xml
<type name="Magento\Catalog\Model\Product">
<plugin name="validate_custom_attribute"
type="Vendor\Module\Plugin\ProductValidatePlugin"/>
</type>
Quiz
1. What backend type stores price values?
2. What does the scope property control?
3. What is a frontend input type?
Flashcards
Question
What are attribute properties?
Click to reveal answer
Answer
attribute_code, backend_type, frontend_input, frontend_label, is_required, scope
Question
What determines value table?
Click to reveal answer
Answer
backend_type: varchar, text, int, decimal, datetime, static
Question
What determines admin input?
Click to reveal answer
Answer
frontend_input: text, textarea, select, boolean, price, date, etc.
Question
What are the scope values?
Click to reveal answer
Answer
0=store, 1=website, 2=global
Question
How to add validation?
Click to reveal answer
Answer
Use backend model with validate() method or validate_rules array
Revision Notes
Key Takeaways
- 1. Attribute properties: code, backend_type, frontend_input, label, required, scope
- 2. Backend type determines value table (varchar, int, decimal, text, datetime)
- 3. Frontend input determines admin form rendering (text, select, boolean, etc.)
- 4. Scope: 0=store, 1=website, 2=global for value storage
- 5. Custom validation via backend models or validate_rules
Interview Tips
- • Explain the difference between backend_type and frontend_input
- • Discuss how scope affects multi-store attribute values
- • Describe custom validation implementation
Cheat Sheet
Attribute Properties:
attribute_code → Unique identifier
backend_type → varchar, text, int, decimal, datetime, static
frontend_input → text, textarea, select, boolean, price, date
frontend_label → Display name
is_required → 0 or 1
scope → 0 (store), 1 (website), 2 (global)
Value Tables:
*_entity_varchar → Short text
*_entity_text → Long text
*_entity_int → Integer/dropdowns
*_entity_decimal → Price/weight
*_entity_datetime → Dates