Skip to content

Commit b31765a

Browse files
author
Bohdan Korablov
committed
MAGETWO-71922: Error in Import Customers Main File with custom attribute.
1 parent 5712618 commit b31765a

File tree

8 files changed

+118
-33
lines changed

8 files changed

+118
-33
lines changed

app/code/Magento/CustomerImportExport/Model/Export/Address.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class Address extends \Magento\ImportExport\Model\Export\Entity\AbstractEav
2929

3030
/**#@-*/
3131

32+
/**
33+
* Country column name for index value
34+
*/
35+
const COLUMN_COUNTRY_ID = 'country_id';
36+
3237
/**#@+
3338
* Particular columns that contains of customer default addresses
3439
*/
@@ -55,6 +60,13 @@ class Address extends \Magento\ImportExport\Model\Export\Entity\AbstractEav
5560
/**#@-*/
5661
protected $_permanentAttributes = [self::COLUMN_WEBSITE, self::COLUMN_EMAIL, self::COLUMN_ADDRESS_ID];
5762

63+
/**
64+
* Attributes with index (not label) value
65+
*
66+
* @var string[]
67+
*/
68+
protected $_indexValueAttributes = [self::COLUMN_COUNTRY_ID];
69+
5870
/**
5971
* Default addresses column names to appropriate customer attribute code
6072
*
@@ -149,7 +161,7 @@ public function __construct(
149161
$data['address_collection']
150162
) ? $data['address_collection'] : $addressColFactory->create();
151163

152-
$this->_initWebsites(true);
164+
$this->_initAttributeValues()->_initAttributeTypes()->_initWebsites(true);
153165
$this->setFileName($this->getEntityTypeCode());
154166
}
155167

app/code/Magento/CustomerImportExport/Model/Export/Customer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public function __construct(
112112
$data['customer_collection']
113113
) ? $data['customer_collection'] : $customerColFactory->create();
114114

115-
$this->_initAttributeValues()->_initStores()->_initWebsites(true);
115+
$this->_initAttributeValues()->_initAttributeTypes()->_initStores()->_initWebsites(true);
116116
}
117117

118118
/**

app/code/Magento/CustomerImportExport/Model/Import/AbstractCustomer.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,4 +248,18 @@ public function getCustomerStorage()
248248
{
249249
return $this->_customerStorage;
250250
}
251+
252+
/**
253+
* Returns id of option by value for select and multiselect attributes
254+
*
255+
* @param array $attributeParameters Parameters of an attribute
256+
* @param int|string $value A value of an attribute
257+
* @return int An option id of attribute
258+
*/
259+
protected function getSelectAttrIdByValue(array $attributeParameters, $value)
260+
{
261+
return isset($attributeParameters['options'][strtolower($value)])
262+
? $attributeParameters['options'][strtolower($value)]
263+
: 0;
264+
}
251265
}

app/code/Magento/CustomerImportExport/Model/Import/Address.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ protected function _mergeEntityAttributes(array $newAttributes, array $attribute
486486
*/
487487
protected function _prepareDataForUpdate(array $rowData)
488488
{
489+
$multiSeparator = $this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR];
489490
$email = strtolower($rowData[self::COLUMN_EMAIL]);
490491
$customerId = $this->_getCustomerId($email, $rowData[self::COLUMN_WEBSITE]);
491492
// entity table data
@@ -523,20 +524,17 @@ protected function _prepareDataForUpdate(array $rowData)
523524
continue;
524525
}
525526
} elseif ($newAddress && !strlen($rowData[$attributeAlias])) {
526-
} elseif ('select' == $attributeParams['type']) {
527-
$value = $attributeParams['options'][strtolower($rowData[$attributeAlias])];
527+
} elseif (in_array($attributeParams['type'], ['select', 'boolean'])) {
528+
$value = $this->getSelectAttrIdByValue($attributeParams, mb_strtolower($rowData[$attributeAlias]));
528529
} elseif ('datetime' == $attributeParams['type']) {
529530
$value = (new \DateTime())->setTimestamp(strtotime($rowData[$attributeAlias]));
530531
$value = $value->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
531532
} elseif ('multiselect' == $attributeParams['type']) {
532-
$separator = isset($this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR]) ?
533-
$this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR] :
534-
Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
535-
$value = str_replace(
536-
$separator,
537-
Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
538-
$rowData[$attributeAlias]
539-
);
533+
$ids = [];
534+
foreach (explode($multiSeparator, mb_strtolower($rowData[$attributeAlias])) as $subValue) {
535+
$ids[] = $this->getSelectAttrIdByValue($attributeParams, $subValue);
536+
}
537+
$value = implode(',', $ids);
540538
} else {
541539
$value = $rowData[$attributeAlias];
542540
}

app/code/Magento/CustomerImportExport/Model/Import/Customer.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\CustomerImportExport\Model\Import;
77

88
use Magento\Customer\Api\Data\CustomerInterface;
9+
use Magento\ImportExport\Model\Import;
910
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;
1011

1112
/**
@@ -338,6 +339,7 @@ protected function _getNextEntityId()
338339
*/
339340
protected function _prepareDataForUpdate(array $rowData)
340341
{
342+
$multiSeparator = $this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR];
341343
$entitiesToCreate = [];
342344
$entitiesToUpdate = [];
343345
$attributesToSave = [];
@@ -376,10 +378,14 @@ protected function _prepareDataForUpdate(array $rowData)
376378
// attribute values
377379
foreach (array_intersect_key($rowData, $this->_attributes) as $attributeCode => $value) {
378380
$attributeParameters = $this->_attributes[$attributeCode];
379-
if ('select' == $attributeParameters['type']) {
380-
$value = isset($attributeParameters['options'][strtolower($value)])
381-
? $attributeParameters['options'][strtolower($value)]
382-
: 0;
381+
if (in_array($attributeParameters['type'], ['select', 'boolean'])) {
382+
$value = $this->getSelectAttrIdByValue($attributeParameters, $value);
383+
} elseif ('multiselect' == $attributeParameters['type']) {
384+
$ids = [];
385+
foreach (explode($multiSeparator, mb_strtolower($value)) as $subValue) {
386+
$ids[] = $this->getSelectAttrIdByValue($attributeParameters, $subValue);
387+
}
388+
$value = implode(',', $ids);
383389
} elseif ('datetime' == $attributeParameters['type'] && !empty($value)) {
384390
$value = (new \DateTime())->setTimestamp(strtotime($value));
385391
$value = $value->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
@@ -535,7 +541,13 @@ protected function _validateRowForUpdate(array $rowData, $rowNumber)
535541
continue;
536542
}
537543
if (isset($rowData[$attributeCode]) && strlen($rowData[$attributeCode])) {
538-
$this->isAttributeValid($attributeCode, $attributeParams, $rowData, $rowNumber);
544+
$this->isAttributeValid(
545+
$attributeCode,
546+
$attributeParams,
547+
$rowData,
548+
$rowNumber,
549+
$this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR]
550+
);
539551
} elseif ($attributeParams['is_required'] && !$this->_getCustomerId($email, $website)) {
540552
$this->addRowError(self::ERROR_VALUE_IS_REQUIRED, $rowNumber, $attributeCode);
541553
}

app/code/Magento/ImportExport/Model/Export/Entity/AbstractEav.php

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
99
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
1010
use Magento\ImportExport\Model\Export;
11+
use Magento\ImportExport\Model\Import;
1112
use Magento\Store\Model\Store;
1213

1314
/**
@@ -27,6 +28,13 @@ abstract class AbstractEav extends \Magento\ImportExport\Model\Export\AbstractEn
2728
*/
2829
protected $_attributeValues = [];
2930

31+
/**
32+
* Attribute code to its types. Only attributes with options
33+
*
34+
* @var array
35+
*/
36+
protected $_attributeTypes = [];
37+
3038
/**
3139
* Entity type id.
3240
*
@@ -88,6 +96,20 @@ protected function _initAttributeValues()
8896
return $this;
8997
}
9098

99+
/**
100+
* Initializes attribute types
101+
*
102+
* @return $this
103+
*/
104+
protected function _initAttributeTypes()
105+
{
106+
/** @var $attribute AbstractAttribute */
107+
foreach ($this->getAttributeCollection() as $attribute) {
108+
$this->_attributeTypes[$attribute->getAttributeCode()] = $attribute->getFrontendInput();
109+
}
110+
return $this;
111+
}
112+
91113
/**
92114
* Apply filter to collection and add not skipped attributes to select
93115
*
@@ -246,19 +268,50 @@ protected function _addAttributeValuesToRow(\Magento\Framework\Model\AbstractMod
246268
foreach ($validAttributeCodes as $attributeCode) {
247269
$attributeValue = $item->getData($attributeCode);
248270

249-
if (isset(
271+
if ($this->isMultiselect($attributeCode)) {
272+
$values = [];
273+
$attributeValue = explode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $attributeValue);
274+
foreach ($attributeValue as $value) {
275+
$values[] = $this->getAttributeValueById($attributeCode, $value);
276+
}
277+
$row[$attributeCode] = implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $values);
278+
} else {
279+
$row[$attributeCode] = $this->getAttributeValueById($attributeCode, $attributeValue);
280+
}
281+
}
282+
283+
return $row;
284+
}
285+
286+
/**
287+
* Checks that attribute is multiselect type by attribute code
288+
*
289+
* @param string $attributeCode An attribute code
290+
* @return bool Returns true if attribute is multiselect type
291+
*/
292+
private function isMultiselect($attributeCode) {
293+
return isset($this->_attributeTypes[$attributeCode])
294+
&& $this->_attributeTypes[$attributeCode] === 'multiselect';
295+
}
296+
297+
/**
298+
* Returns attribute value by id
299+
*
300+
* @param string $attributeCode An attribute code
301+
* @param int|string $valueId
302+
* @return mixed
303+
*/
304+
private function getAttributeValueById($attributeCode, $valueId)
305+
{
306+
if (isset(
250307
$this->_attributeValues[$attributeCode]
251308
) && isset(
252-
$this->_attributeValues[$attributeCode][$attributeValue]
309+
$this->_attributeValues[$attributeCode][$valueId]
253310
)
254-
) {
255-
$attributeValue = $this->_attributeValues[$attributeCode][$attributeValue];
256-
}
257-
if (null !== $attributeValue) {
258-
$row[$attributeCode] = $attributeValue;
259-
}
311+
) {
312+
return $this->_attributeValues[$attributeCode][$valueId];
260313
}
261314

262-
return $row;
315+
return $valueId;
263316
}
264317
}

app/code/Magento/ImportExport/Model/Import/AbstractEntity.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,9 @@ public function isAttributeValid(
691691
break;
692692
case 'select':
693693
case 'multiselect':
694+
case 'boolean':
694695
$valid = true;
695-
foreach (explode($multiSeparator, strtolower($rowData[$attributeCode])) as $value) {
696+
foreach (explode($multiSeparator, mb_strtolower($rowData[$attributeCode])) as $value) {
696697
$valid = isset($attributeParams['options'][$value]);
697698
if (!$valid) {
698699
break;

app/code/Magento/ImportExport/Model/Import/Entity/AbstractEav.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,7 @@ public function getAttributeOptions(
228228
foreach ($value as $innerOption) {
229229
// skip ' -- Please Select -- ' option
230230
if (strlen($innerOption['value'])) {
231-
if ($attribute->isStatic()) {
232-
$options[strtolower($innerOption[$index])] = $innerOption['value'];
233-
} else {
234-
// Non-static attributes flip keys an values
235-
$options[$innerOption['value']] = $innerOption[$index];
236-
}
231+
$options[mb_strtolower($innerOption[$index])] = $innerOption['value'];
237232
}
238233
}
239234
}

0 commit comments

Comments
 (0)