Attribute & Property Mapping
Attribute and property mapping is essential for synchronizing product data between Magento and PlentyONE. This guide explains how to configure mappings and handle various attribute types.
Understanding the Difference
Magento Attributes
Attributes in Magento define product characteristics:
- Product attributes (name, description, SKU, price)
- Custom attributes (brand, material, size, color)
- System attributes (status, visibility, weight)
Attribute Types:
- Text (text field, textarea)
- Select (dropdown, multi-select)
- Boolean (yes/no)
- Date
- Price
- Media (image, gallery)
PlentyONE Properties
Properties in PlentyONE serve similar purposes but with different structure:
- Item properties (characteristics)
- Property groups (organization)
- Property selections (predefined values)
- Property relations (linking)
Property Synchronization Workflow
graph LR
A[Magento Attributes] --> B[Collect from Magento]
B --> C[Transform to PlentyONE Format]
C --> D[Export to PlentyONE]
D --> E[Create Properties]
E --> F[Link to Items]
P[PlentyONE Properties] --> Q[Collect from PlentyONE]
Q --> R[Transform to Magento Format]
R --> S[Import to Magento]
S --> T[Create Attributes]
T --> U[Assign to Products]
Initial Property Setup
Step 1: Collect Attribute Configuration
# Collect all Magento attributes
bin/magento plenty:attribute:collect --verbose
# Output:
# ✓ Collected 45 product attributes
# ✓ Collected 12 attribute sets
# ✓ Stored in softcommerce_plenty_attribute table
What gets collected:
- Attribute codes
- Attribute labels (all store views)
- Attribute types
- Frontend input types
- Backend types
- Source models (for select attributes)
- Attribute options and values
Step 2: Export to PlentyONE
# Export attributes to create properties in PlentyONE
bin/magento plenty:attribute:export --verbose
# Output:
# Processing attribute: brand
# ✓ Created property: brand (ID: 100)
# Processing attribute: material
# ✓ Created property: material (ID: 101)
# ...
# ✓ Exported 45 attributes
Step 3: Import Properties from PlentyONE
# Collect properties from PlentyONE
bin/magento plenty:property:collect --verbose
# Import properties to create attributes in Magento
bin/magento plenty:property:import --verbose
Attribute Mapping Configuration
Configure Mapping in Profile
- Navigate to SoftCommerce → Profiles → Manage Profiles
- Select your Item Import or Item Export profile
- Go to Configuration → Attribute Mapping
Mapping Structure
{
"attribute_mapping": {
"name": {
"plenty_property": "texts.name",
"direction": "bidirectional"
},
"description": {
"plenty_property": "texts.description",
"direction": "bidirectional"
},
"short_description": {
"plenty_property": "texts.shortDescription",
"direction": "bidirectional"
},
"brand": {
"plenty_property": "properties.brand",
"plenty_property_id": 100,
"direction": "export"
},
"color": {
"plenty_property": "properties.color",
"plenty_property_id": 101,
"direction": "bidirectional"
}
}
}
Mapping Directions
Direction | Description | Use Case |
---|---|---|
bidirectional | Sync both ways | Product name, description |
export | Magento → PlentyONE only | Magento-specific attributes |
import | PlentyONE → Magento only | PlentyONE-specific properties |
none | No synchronization | Excluded attributes |
Common Attribute Mappings
Basic Product Information
Magento Attribute | PlentyONE Property | Notes |
---|---|---|
name | texts.name | Required, bidirectional |
description | texts.description | HTML content |
short_description | texts.shortDescription | Plain text recommended |
sku | variations.number | Unique identifier |
price | variations.prices | Handled separately |
weight | variations.weightG | Convert to grams |
status | isActive | Boolean mapping |
Custom Attributes
Configure via profile configuration:
'custom_attribute_mapping' => [
'brand' => [
'plenty_property_id' => 100,
'plenty_property_type' => 'selection',
'transform' => 'mapBrandValue'
],
'material' => [
'plenty_property_id' => 101,
'plenty_property_type' => 'text',
'transform' => null
],
'color' => [
'plenty_property_id' => 102,
'plenty_property_type' => 'selection',
'transform' => 'mapColorValue'
],
'size' => [
'plenty_property_id' => 103,
'plenty_property_type' => 'selection',
'transform' => 'mapSizeValue'
]
]
Media Attributes
Magento | PlentyONE | Referrer |
---|---|---|
image | images[] | magento_image |
small_image | images[] | magento_small_image |
thumbnail | images[] | magento_thumbnail |
swatch_image | images[] | magento_swatch_image |
gallery | images[] | magento_gallery |
Attribute Type Mapping
Text Attributes
Magento:
$product->setData('custom_text', 'Some value');
PlentyONE Property:
{
"property": {
"id": 100,
"propertyType": "text",
"value": "Some value"
}
}
Configuration:
'custom_text' => [
'plenty_property_id' => 100,
'plenty_property_type' => 'text'
]
Select (Dropdown) Attributes
Magento:
// Attribute with options
$attribute = $product->getResource()->getAttribute('brand');
$optionId = $product->getData('brand'); // e.g., 42
$optionText = $attribute->getSource()->getOptionText($optionId); // e.g., "Nike"
PlentyONE Property:
{
"property": {
"id": 100,
"propertyType": "selection",
"propertySelection": {
"id": 5,
"name": "Nike"
}
}
}
Configuration:
'brand' => [
'plenty_property_id' => 100,
'plenty_property_type' => 'selection',
'value_mapping' => [
42 => 5, // Magento option ID => PlentyONE selection ID
43 => 6, // "Adidas"
44 => 7 // "Puma"
]
]
Multi-Select Attributes
Magento:
$product->setData('categories', '10,20,30'); // Comma-separated
PlentyONE:
{
"properties": [
{"propertyId": 100, "propertySelectionId": 10},
{"propertyId": 100, "propertySelectionId": 20},
{"propertyId": 100, "propertySelectionId": 30}
]
}
Configuration:
'categories' => [
'plenty_property_id' => 100,
'plenty_property_type' => 'multi_selection',
'split_character' => ','
]
Boolean (Yes/No) Attributes
Magento:
$product->setData('is_featured', 1); // 1 or 0
PlentyONE:
{
"property": {
"id": 100,
"propertyType": "text",
"value": "true" // or "false"
}
}
Configuration:
'is_featured' => [
'plenty_property_id' => 100,
'plenty_property_type' => 'text',
'transform' => 'booleanToString',
'value_mapping' => [
1 => 'true',
0 => 'false'
]
]
Date Attributes
Magento:
$product->setData('release_date', '2025-01-13'); // Y-m-d format
PlentyONE:
{
"property": {
"id": 100,
"propertyType": "date",
"value": "2025-01-13T00:00:00+00:00" // ISO 8601
}
}
Configuration:
'release_date' => [
'plenty_property_id' => 100,
'plenty_property_type' => 'date',
'transform' => 'dateToIso8601'
]
Property Groups
Create Property Groups
Property groups organize related properties in PlentyONE:
# Export attribute sets as property groups
bin/magento plenty:attribute:export-groups --verbose
# Output:
# Processing attribute set: Default
# ✓ Created property group: Magento Default (ID: 10)
# Processing attribute set: Clothing
# ✓ Created property group: Magento Clothing (ID: 11)
Configure Group Mapping
'property_group_mapping' => [
4 => 10, // Magento attribute set ID => PlentyONE property group ID
9 => 11, // "Default" => "Magento Default"
10 => 12 // "Clothing" => "Magento Clothing"
]
Advanced Mapping Scenarios
Conditional Mapping
Map attributes based on conditions:
'conditional_mapping' => [
'special_price' => [
'condition' => 'hasSpecialPrice',
'plenty_property_id' => 200,
'fallback' => 'price'
]
]
Composite Attributes
Combine multiple Magento attributes into one PlentyONE property:
'composite_mapping' => [
'full_description' => [
'plenty_property_id' => 105,
'combine' => ['description', 'additional_info'],
'separator' => "\n\n"
]
]
Calculated Attributes
Generate property values from calculations:
'calculated_mapping' => [
'price_per_unit' => [
'plenty_property_id' => 106,
'calculation' => 'dividePrice',
'params' => ['price', 'qty']
]
]
Locale-Specific Mapping
Map attributes per store view/locale:
'locale_mapping' => [
'name' => [
'plenty_property' => 'texts.name',
'locales' => [
'en_US' => 'lang=en',
'de_DE' => 'lang=de',
'fr_FR' => 'lang=fr'
]
]
]
Testing Attribute Mapping
Test Single Product
# Export single product with verbose output
bin/magento plenty:item:export --sku=TEST-SKU --verbose
# Check logs for attribute mapping
tail -f var/log/plenty_item.log | grep "attribute"
# Verify in PlentyONE backend
# Items → Item Overview → Search TEST-SKU → Properties tab
Verify Mapping
# Check attribute entity table
mysql> SELECT * FROM plenty_attribute_entity WHERE attribute_code = 'size';
# Check property mapping
mysql> SELECT * FROM plenty_property_entity WHERE property_code = 'custom_atttribute';
# View collected attributes
mysql> SELECT entity_id, attribute_code, status FROM plenty_attribute_entity;
Validate Property Values
-- Check exported property values
SELECT
p.sku,
a.attribute_code,
pv.value as magento_value,
pa.plenty_property_id
FROM catalog_product_entity p
JOIN catalog_product_entity_varchar pv ON p.entity_id = pv.entity_id
JOIN eav_attribute a ON pv.attribute_id = a.attribute_id
JOIN softcommerce_plenty_attribute pa ON a.attribute_id = pa.magento_attribute_id
WHERE p.sku = 'TEST-SKU'
AND pa.sync_direction IN ('export', 'bidirectional');
Troubleshooting Mapping Issues
Issue: Attribute Not Syncing
Check:
- Attribute is in mapping configuration
- Sync direction is correct
- Property ID is valid
- Attribute has value
# Debug single attribute
bin/magento plenty:attribute:export --attribute=brand --verbose
Issue: Wrong Value Synced
Check:
- Value mapping configuration
- Data transformation functions
- Type compatibility
# View raw attribute value
mysql> SELECT value FROM catalog_product_entity_int WHERE entity_id = 123 AND attribute_id = 100;
# View mapped property value in PlentyONE
# Items → Item → Properties
Issue: Property Not Created
Possible causes:
- Property already exists with different configuration
- Insufficient API permissions
- Invalid property type
Solution:
# Check existing properties
bin/magento plenty:property:collect --verbose
# View collected properties with selection type
mysql> SELECT
ppe.entity_id as property_id,
ppe.property_code,
ppe.property_type,
ppe.attribute_code,
pps.entity_id as selection_id,
pps.position as selection_position,
ppsv.lang,
ppsv.value as selection_value
FROM plenty_property_entity ppe
LEFT JOIN plenty_property_selection pps ON pps.parent_id = ppe.entity_id
LEFT JOIN plenty_property_selection_value ppsv ON ppsv.parent_id = pps.entity_id
WHERE ppe.property_type = 'selection'
ORDER BY ppe.entity_id, pps.position;
# Manually create property if needed via PlentyONE backend
# Setup → Item → Properties
Best Practices
-
Plan Mapping Before Export:
- Document all attributes to sync
- Define sync directions
- Map attribute types correctly
-
Use Property Groups:
- Organize properties logically
- Map attribute sets to property groups
- Maintain consistency
-
Test Incrementally:
- Start with basic attributes (name, description)
- Add custom attributes one by one
- Verify each mapping before proceeding
-
Handle Option Values:
- Map select options explicitly
- Keep value mappings documented
- Update mappings when options change
-
Consider Performance:
- Sync only necessary attributes
- Use appropriate batch sizes
- Enable caching for property data
-
Maintain Consistency:
- Use same property IDs across environments
- Document custom mappings
- Version control configuration
-
Monitor Synchronization:
- Check logs regularly
- Verify property values
- Track failed mappings
Attribute Mapping Maintenance
Update Mappings
# Re-collect attributes after changes
bin/magento plenty:attribute:collect --verbose
# Update property mapping
bin/magento plenty:attribute:map --force
# Re-export with new mapping
bin/magento plenty:item:export --sku=TEST-SKU --force
Add New Attributes
- Create attribute in Magento
- Collect attributes:
bin/magento plenty:attribute:collect
- Export to create property:
bin/magento plenty:attribute:export --attribute=new_attribute
- Add to profile configuration
- Test with sample product
Remove Attributes
- Update profile configuration (remove mapping)
- Clear cache:
bin/magento cache:flush
- Optionally delete property from PlentyONE backend
Related Documentation
- Product Attributes - Product-specific attribute mapping
- First Synchronization - Initial sync guide
- Profile Configuration - Configure profiles
- Troubleshooting - Common issues
Pro Tip: Start with a minimal attribute mapping configuration and expand gradually. Test each new attribute mapping with a single product before applying to all products. This iterative approach helps identify and fix issues early.