Skip to content

Commit d30c770

Browse files
committed
ACP2E-2261: [Cloud] Product import fails with custom separator value
1 parent c333d32 commit d30c770

File tree

7 files changed

+126
-19
lines changed

7 files changed

+126
-19
lines changed

app/code/Magento/CatalogImportExport/Model/Import/Product.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@
5353
class Product extends AbstractEntity
5454
{
5555
private const COL_NAME_FORMAT = '/[\x00-\x1F\x7F]/';
56-
private const DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR = ',';
5756
public const CONFIG_KEY_PRODUCT_TYPES = 'global/importexport/import_product_types';
5857

5958
/**
@@ -2949,10 +2948,10 @@ private function parseAttributesWithWrappedValues($attributesData)
29492948
* @return array
29502949
* @since 100.1.2
29512950
*/
2952-
public function parseMultiselectValues($values, $delimiter = self::PSEUDO_MULTI_LINE_SEPARATOR)
2951+
public function parseMultiselectValues($values, $delimiter = '')
29532952
{
29542953
if (empty($this->_parameters[Import::FIELDS_ENCLOSURE])) {
2955-
if ($this->getMultipleValueSeparator() !== self::DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR) {
2954+
if (!$delimiter) {
29562955
$delimiter = $this->getMultipleValueSeparator();
29572956
}
29582957

app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,19 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe
633633
$resultAttrs[$attrCode] = $attrParams['options'][strtolower($rowData[$attrCode])];
634634
} elseif ('multiselect' == $attrParams['type']) {
635635
$resultAttrs[$attrCode] = [];
636-
foreach ($this->_entityModel->parseMultiselectValues($rowData[$attrCode]) as $value) {
636+
$delimiter = '';
637+
if (is_string($rowData[$attrCode])
638+
&& str_contains($rowData[$attrCode], Product::PSEUDO_MULTI_LINE_SEPARATOR)) {
639+
if (!empty($rowData['additional_attributes'])
640+
&& str_contains(
641+
$rowData['additional_attributes'],
642+
$attrCode . Product::PAIR_NAME_VALUE_SEPARATOR
643+
)
644+
) {
645+
$delimiter = Product::PSEUDO_MULTI_LINE_SEPARATOR;
646+
}
647+
}
648+
foreach ($this->_entityModel->parseMultiselectValues($rowData[$attrCode], $delimiter) as $value) {
637649
$resultAttrs[$attrCode][] = $attrParams['options'][strtolower($value)];
638650
}
639651
$resultAttrs[$attrCode] = implode(',', $resultAttrs[$attrCode]);

app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Magento\CatalogImportExport\Model\Import\Product;
99
use Magento\Framework\Validator\AbstractValidator;
1010
use Magento\Catalog\Model\Product\Attribute\Backend\Sku;
11+
use Magento\ImportExport\Model\Import;
1112

1213
/**
1314
* Product import model validator
@@ -254,11 +255,23 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData)
254255
*/
255256
private function validateByAttributeType(string $attrCode, array $attrParams, array $rowData): bool
256257
{
258+
$delimiter = '';
259+
if (is_string($rowData[$attrCode]) && str_contains($rowData[$attrCode], Product::PSEUDO_MULTI_LINE_SEPARATOR)) {
260+
if (!empty($rowData['additional_attributes'])
261+
&& str_contains($rowData['additional_attributes'], $attrCode . Product::PAIR_NAME_VALUE_SEPARATOR)) {
262+
$delimiter = Product::PSEUDO_MULTI_LINE_SEPARATOR;
263+
}
264+
}
257265
return match ($attrParams['type']) {
258266
'varchar', 'text' => $this->textValidation($attrCode, $attrParams['type']),
259267
'decimal', 'int' => $this->numericValidation($attrCode, $attrParams['type']),
260268
'select', 'boolean' => $this->validateOption($attrCode, $attrParams['options'], $rowData[$attrCode]),
261-
'multiselect' => $this->validateMultiselect($attrCode, $attrParams['options'], $rowData[$attrCode]),
269+
'multiselect' => $this->validateMultiselect(
270+
$attrCode,
271+
$attrParams['options'],
272+
$rowData[$attrCode],
273+
$delimiter
274+
),
262275
'datetime' => $this->validateDateTime($rowData[$attrCode]),
263276
default => true,
264277
};
@@ -270,13 +283,18 @@ private function validateByAttributeType(string $attrCode, array $attrParams, ar
270283
* @param string $attrCode
271284
* @param array $options
272285
* @param array|string $rowData
286+
* @param string $delimiter
273287
* @return bool
274288
*/
275-
private function validateMultiselect(string $attrCode, array $options, array|string $rowData): bool
276-
{
289+
private function validateMultiselect(
290+
string $attrCode,
291+
array $options,
292+
array|string $rowData,
293+
string $delimiter = ''
294+
): bool {
277295
$valid = true;
278296

279-
$values = $this->context->parseMultiselectValues($rowData);
297+
$values = $this->context->parseMultiselectValues($rowData, $delimiter);
280298
foreach ($values as $value) {
281299
$valid = $this->validateOption($attrCode, $options, $value);
282300
if (!$valid) {

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/ValidatorTest.php

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,33 +169,58 @@ public function attributeValidationProvider()
169169
[
170170
Import::BEHAVIOR_APPEND,
171171
['is_required' => true, 'type' => 'multiselect', 'options' => ['option 1' => 0, 'option 2' => 1]],
172-
['product_type' => 'any', 'attribute_code' => 'Option 1|Option 2|Option 3'],
172+
[
173+
'product_type' => 'any',
174+
'attribute_code' => 'Option 1|Option 2|Option 3',
175+
'additional_attributes' => 'test_attribute=any,attribute_code=Option 1|Option 2|Option 3'
176+
],
173177
false
174178
],
175179
[
176180
Import::BEHAVIOR_APPEND,
177181
['is_required' => true, 'type' => 'multiselect', 'options' => ['option 1' => 0, 'option 2' => 1]],
178-
['product_type' => 'any', 'attribute_code' => 'Option 1|Option 2'],
182+
[
183+
'product_type' => 'any',
184+
'attribute_code' => 'Option 1|Option 2',
185+
'additional_attributes' => 'test_attribute=any,attribute_code=Option 1|Option 2'
186+
],
179187
true
180188
],
181189
[
182190
Import::BEHAVIOR_APPEND,
183-
['is_required' => true, 'type' => 'multiselect',
184-
'options' => ['option 1' => 0, 'option 2' => 1, 'option 3']],
185-
['product_type' => 'any', 'attribute_code' => 'Option 1|Option 2|Option 1'],
191+
[
192+
'is_required' => true,
193+
'type' => 'multiselect',
194+
'options' => ['option 1' => 0, 'option 2' => 1, 'option 3']
195+
],
196+
[
197+
'product_type' => 'any',
198+
'attribute_code' => 'Option 1|Option 2|Option 1',
199+
'additional_attributes' => 'test_attribute=any,attribute_code=Option 1|Option 2|Option 1'
200+
],
186201
false
187202
],
188203
[
189204
Import::BEHAVIOR_APPEND,
190-
['is_required' => true, 'type' => 'multiselect',
191-
'options' => ['option 1' => 0, 'option 2' => 1, 'option 3']],
192-
['product_type' => 'any', 'attribute_code' => 'Option 3|Option 3|Option 3|Option 1'],
205+
[
206+
'is_required' => true, 'type' => 'multiselect',
207+
'options' => ['option 1' => 0, 'option 2' => 1, 'option 3']
208+
],
209+
[
210+
'product_type' => 'any',
211+
'attribute_code' => 'Option 3|Option 3|Option 3|Option 1',
212+
'additional_attributes' => 'test_attribute=any,attribute_code=Option 3|Option 3|Option 3|Option 1'
213+
],
193214
false
194215
],
195216
[
196217
Import::BEHAVIOR_APPEND,
197218
['is_required' => true, 'type' => 'multiselect', 'options' => ['option 1' => 0]],
198-
['product_type' => 'any', 'attribute_code' => 'Option 1|Option 1|Option 1|Option 1'],
219+
[
220+
'product_type' => 'any',
221+
'attribute_code' => 'Option 1|Option 1|Option 1|Option 1',
222+
'additional_attributes' => 'test_attribute=any,attribute_code=Option 1|Option 1|Option 1|Option 1'
223+
],
199224
false
200225
],
201226
[

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/ProductTest.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,4 +2191,57 @@ protected function createModelMockWithErrorAggregator(
21912191

21922192
return $importProduct;
21932193
}
2194+
2195+
/**
2196+
* @dataProvider valuesDataProvider
2197+
*/
2198+
public function testParseMultiselectValues($value, $fieldSeparator, $valueSeparator)
2199+
{
2200+
$this->importProduct->setParameters(
2201+
[
2202+
Import::FIELD_FIELD_SEPARATOR => $fieldSeparator,
2203+
Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR => $valueSeparator
2204+
]
2205+
);
2206+
$this->assertEquals(explode($valueSeparator, $value), $this->importProduct->parseMultiselectValues($value));
2207+
}
2208+
2209+
/**
2210+
* @return array
2211+
*/
2212+
public function valuesDataProvider(): array
2213+
{
2214+
return [
2215+
'pipeWithCustomFieldSeparator' => [
2216+
'value' => 'L|C|D|T|H',
2217+
'fieldSeparator' => ';',
2218+
'valueSeparator' => '|'
2219+
],
2220+
'commaWithCustomFieldSeparator' => [
2221+
'value' => 'L,C,D,T,H',
2222+
'fieldSeparator' => ';',
2223+
'valueSeparator' => ','
2224+
],
2225+
'pipeWithDefaultFieldSeparator' => [
2226+
'value' => 'L|C|D|T|H',
2227+
'fieldSeparator' => ',',
2228+
'valueSeparator' => '|'
2229+
],
2230+
'commaWithDefaultFieldSeparator' => [
2231+
'value' => 'L,C,D,T,H',
2232+
'fieldSeparator' => ',',
2233+
'valueSeparator' => ','
2234+
],
2235+
'anonymousValueSeparatorWithDefaultFieldSeparator' => [
2236+
'value' => 'L+C+D+T+H',
2237+
'fieldSeparator' => ',',
2238+
'valueSeparator' => '+'
2239+
],
2240+
'anonymousValueSeparatorWithDefaultFieldSeparatorAndSingleValue' => [
2241+
'value' => 'L',
2242+
'fieldSeparator' => ',',
2243+
'valueSeparator' => '*'
2244+
]
2245+
];
2246+
}
21942247
}

dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest/ProductValidationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ public function testValidateMultiselectValuesWithCustomSeparator(): void
392392
$params = [
393393
'behavior' => Import::BEHAVIOR_ADD_UPDATE,
394394
'entity' => 'catalog_product',
395-
Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR => '|||'
395+
Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR => '###'
396396
];
397397

398398
$errors = $this->_model->setParameters($params)
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
sku,store_view_code,product_type,name,price,additional_attributes
2-
simple_ms_2,,simple,"With Multiselect 2",10,"multiselect_attribute=Option 2|||Option 3"
2+
simple_ms_2,,simple,"With Multiselect 2",10,"multiselect_attribute=Option 2###Option 3"

0 commit comments

Comments
 (0)