If you have an attribute that has a value and you import an empty string because the value needs to be empty, the attribute will not be overwritten with the empty string.
This issue can be traced back to \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType where the clearEmptyData function unsets all empty rows.
public function clearEmptyData(array $rowData)
{
foreach ($this->_getProductAttributes($rowData) as $attrCode => $attrParams) {
if (!$attrParams['is_static'] && empty($rowData[$attrCode])) {
unset($rowData[$attrCode]);
}
}
return $rowData;
}
It is my opinion that support for empty rows should be allowed.
My suggested fix is adding a constant to the AbstractType class and set the row values that contain that constant value to an empty string. That way if the constant value is used in the import csv, the importer will know which fields are just empty and which fields contain empty values.
CONST EMPTY_ROW_VALUE = '__EMPTY__';
public function clearEmptyData(array $rowData)
{
foreach ($this->_getProductAttributes($rowData) as $attrCode => $attrParams) {
if (!$attrParams['is_static'] && empty($rowData[$attrCode])) {
unset($rowData[$attrCode]);
continue;
}
if ($rowData[$attrCode] === self::EMPTY_ROW_VALUE) {
$rowData[$attrCode] = '';
}
}
return $rowData;
}
It would be even better to allow for setting custom values for the EMPTY_ROW_VALUE constant through the backend.
Addendum to this;
If chosen to support the constant value, support should also be implemented in \Magento\CatalogImportExport\Model\Import\Product\Validator in the isAttributeValid function.
To allow for every type of attribute to have support for empty values, something like this should be added
...
if (!strlen(trim($rowData[$attrCode]))) {
return true;
}
if ($rowData[$attrCode] === \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType::EMPTY_ROW_VALUE) {
return true;
}
switch ($attrParams['type']) {
...
@koenner01 thank you for your feedback.
Internal issue created: MAGETWO-61593
I have found a problem when using the empty logic;
If you try to import an empty value '' for a product's special_price, it will result in special_price 0.
The problem is an insert being doing in \Magento\CatalogImportExport\Model\Import\Product in function _saveProductAttributes:
protected function _saveProductAttributes(array $attributesData)
{
foreach ($attributesData as $tableName => $skuData) {
$tableData = [];
foreach ($skuData as $sku => $attributes) {
$linkId = $this->_connection->fetchOne(
$this->_connection->select()
->from($this->getResource()->getTable('catalog_product_entity'))
->where('sku = ?', $sku)
->columns($this->getProductEntityLinkField())
);
foreach ($attributes as $attributeId => $storeValues) {
foreach ($storeValues as $storeId => $storeValue) {
$tableData[] = [
$this->getProductEntityLinkField() => $linkId,
'attribute_id' => $attributeId,
'store_id' => $storeId,
'value' => $storeValue,
];
}
}
}
$this->_connection->insertOnDuplicate($tableName, $tableData, ['value']);
}
return $this;
}
If an empty string value is being inserted into the entity_int or entity_decimal tables they result into value 0.
Another issue in the same clearEmptyData function https://github.com/magento/magento2/issues/10006
Any update on this from the Magento team?
@koenner01, thank you for your report.
We've created internal ticket(s) MAGETWO-61593 to track progress on the issue.
This issue was moved to magento-engcom/import-export-improvements#49
Most helpful comment
Addendum to this;
If chosen to support the constant value, support should also be implemented in \Magento\CatalogImportExport\Model\Import\Product\Validator in the isAttributeValid function.
To allow for every type of attribute to have support for empty values, something like this should be added