Skip to content

Commit

Permalink
Merge pull request #1479 from magento-thunder/bugfixes
Browse files Browse the repository at this point in the history
Fixed issue:
- MAGETWO-71922 Error in Import Customers Main File with custom attribute.
  • Loading branch information
igrybkov authored Sep 11, 2017
2 parents 89db29c + b584115 commit fc095b1
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 38 deletions.
20 changes: 19 additions & 1 deletion app/code/Magento/CustomerImportExport/Model/Export/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ class Address extends \Magento\ImportExport\Model\Export\Entity\AbstractEav

/**#@-*/

/**
* Country column name for index value
*/
const COLUMN_COUNTRY_ID = 'country_id';

/**
* Name of region id column
*/
const COLUMN_REGION_ID = 'region_id';

/**#@+
* Particular columns that contains of customer default addresses
*/
Expand All @@ -55,6 +65,13 @@ class Address extends \Magento\ImportExport\Model\Export\Entity\AbstractEav
/**#@-*/
protected $_permanentAttributes = [self::COLUMN_WEBSITE, self::COLUMN_EMAIL, self::COLUMN_ADDRESS_ID];

/**
* Attributes with index (not label) value
*
* @var string[]
*/
protected $_indexValueAttributes = [self::COLUMN_COUNTRY_ID];

/**
* Default addresses column names to appropriate customer attribute code
*
Expand Down Expand Up @@ -149,7 +166,7 @@ public function __construct(
$data['address_collection']
) ? $data['address_collection'] : $addressColFactory->create();

$this->_initWebsites(true);
$this->_initAttributeValues()->_initAttributeTypes()->_initWebsites(true);
$this->setFileName($this->getEntityTypeCode());
}

Expand Down Expand Up @@ -243,6 +260,7 @@ public function exportItem($item)
$row[self::COLUMN_ADDRESS_ID] = $item['entity_id'];
$row[self::COLUMN_EMAIL] = $customer['email'];
$row[self::COLUMN_WEBSITE] = $this->_websiteIdToCode[$customer['website_id']];
$row[self::COLUMN_REGION_ID] = $item->getRegionId();

$this->getWriter()->writeRow($row);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public function __construct(
$data['customer_collection']
) ? $data['customer_collection'] : $customerColFactory->create();

$this->_initAttributeValues()->_initStores()->_initWebsites(true);
$this->_initAttributeValues()->_initAttributeTypes()->_initStores()->_initWebsites(true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
namespace Magento\CustomerImportExport\Model\Import;

use Magento\ImportExport\Model\Import;
use Magento\CustomerImportExport\Model\ResourceModel\Import\Customer\Storage;
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;

Expand Down Expand Up @@ -248,4 +249,30 @@ public function getCustomerStorage()
{
return $this->_customerStorage;
}

/**
* Returns id of option by value for select and multiselect attributes
*
* @param array $attributeParameters Parameters of an attribute
* @param int|string $value A value of an attribute
* @return int An option id of attribute
*/
protected function getSelectAttrIdByValue(array $attributeParameters, $value)
{
return isset($attributeParameters['options'][strtolower($value)])
? $attributeParameters['options'][strtolower($value)]
: 0;
}

/**
* Returns multiple value separator
*
* @return string
*/
protected function getMultipleValueSeparator()
{
return isset($this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR])
? $this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR]
: Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
}
}
23 changes: 9 additions & 14 deletions app/code/Magento/CustomerImportExport/Model/Import/Address.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/
namespace Magento\CustomerImportExport\Model\Import;

use Magento\ImportExport\Model\Import;
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;

/**
Expand Down Expand Up @@ -486,6 +485,7 @@ protected function _mergeEntityAttributes(array $newAttributes, array $attribute
*/
protected function _prepareDataForUpdate(array $rowData)
{
$multiSeparator = $this->getMultipleValueSeparator();
$email = strtolower($rowData[self::COLUMN_EMAIL]);
$customerId = $this->_getCustomerId($email, $rowData[self::COLUMN_WEBSITE]);
// entity table data
Expand Down Expand Up @@ -523,20 +523,17 @@ protected function _prepareDataForUpdate(array $rowData)
continue;
}
} elseif ($newAddress && !strlen($rowData[$attributeAlias])) {
} elseif ('select' == $attributeParams['type']) {
$value = $attributeParams['options'][strtolower($rowData[$attributeAlias])];
} elseif (in_array($attributeParams['type'], ['select', 'boolean'])) {
$value = $this->getSelectAttrIdByValue($attributeParams, mb_strtolower($rowData[$attributeAlias]));
} elseif ('datetime' == $attributeParams['type']) {
$value = (new \DateTime())->setTimestamp(strtotime($rowData[$attributeAlias]));
$value = $value->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
} elseif ('multiselect' == $attributeParams['type']) {
$separator = isset($this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR]) ?
$this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR] :
Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
$value = str_replace(
$separator,
Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
$rowData[$attributeAlias]
);
$ids = [];
foreach (explode($multiSeparator, mb_strtolower($rowData[$attributeAlias])) as $subValue) {
$ids[] = $this->getSelectAttrIdByValue($attributeParams, $subValue);
}
$value = implode(',', $ids);
} else {
$value = $rowData[$attributeAlias];
}
Expand Down Expand Up @@ -722,6 +719,7 @@ protected function _isOptionalAddressEmpty(array $rowData)
*/
protected function _validateRowForUpdate(array $rowData, $rowNumber)
{
$multiSeparator = $this->getMultipleValueSeparator();
if ($this->_checkUniqueKey($rowData, $rowNumber)) {
$email = strtolower($rowData[self::COLUMN_EMAIL]);
$website = $rowData[self::COLUMN_WEBSITE];
Expand All @@ -740,9 +738,6 @@ protected function _validateRowForUpdate(array $rowData, $rowNumber)
continue;
}
if (isset($rowData[$attributeCode]) && strlen($rowData[$attributeCode])) {
$multiSeparator = isset($this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR]) ?
$this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR] :
Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
$this->isAttributeValid(
$attributeCode,
$attributeParams,
Expand Down
24 changes: 19 additions & 5 deletions app/code/Magento/CustomerImportExport/Model/Import/Customer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace Magento\CustomerImportExport\Model\Import;

use Magento\Customer\Api\Data\CustomerInterface;
use Magento\ImportExport\Model\Import;
use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface;

/**
Expand Down Expand Up @@ -338,6 +339,7 @@ protected function _getNextEntityId()
*/
protected function _prepareDataForUpdate(array $rowData)
{
$multiSeparator = $this->getMultipleValueSeparator();
$entitiesToCreate = [];
$entitiesToUpdate = [];
$attributesToSave = [];
Expand Down Expand Up @@ -376,10 +378,14 @@ protected function _prepareDataForUpdate(array $rowData)
// attribute values
foreach (array_intersect_key($rowData, $this->_attributes) as $attributeCode => $value) {
$attributeParameters = $this->_attributes[$attributeCode];
if ('select' == $attributeParameters['type']) {
$value = isset($attributeParameters['options'][strtolower($value)])
? $attributeParameters['options'][strtolower($value)]
: 0;
if (in_array($attributeParameters['type'], ['select', 'boolean'])) {
$value = $this->getSelectAttrIdByValue($attributeParameters, $value);
} elseif ('multiselect' == $attributeParameters['type']) {
$ids = [];
foreach (explode($multiSeparator, mb_strtolower($value)) as $subValue) {
$ids[] = $this->getSelectAttrIdByValue($attributeParameters, $subValue);
}
$value = implode(',', $ids);
} elseif ('datetime' == $attributeParameters['type'] && !empty($value)) {
$value = (new \DateTime())->setTimestamp(strtotime($value));
$value = $value->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
Expand Down Expand Up @@ -535,7 +541,15 @@ protected function _validateRowForUpdate(array $rowData, $rowNumber)
continue;
}
if (isset($rowData[$attributeCode]) && strlen($rowData[$attributeCode])) {
$this->isAttributeValid($attributeCode, $attributeParams, $rowData, $rowNumber);
$this->isAttributeValid(
$attributeCode,
$attributeParams,
$rowData,
$rowNumber,
isset($this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR])
? $this->_parameters[Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR]
: Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR
);
} elseif ($attributeParams['is_required'] && !$this->_getCustomerId($email, $website)) {
$this->addRowError(self::ERROR_VALUE_IS_REQUIRED, $rowNumber, $attributeCode);
}
Expand Down
71 changes: 61 additions & 10 deletions app/code/Magento/ImportExport/Model/Export/Entity/AbstractEav.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\ImportExport\Model\Export;
use Magento\ImportExport\Model\Import;
use Magento\Store\Model\Store;

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

/**
* Attribute code to its types. Only attributes with options
*
* @var array
*/
protected $attributeTypes = [];

/**
* Entity type id.
*
Expand Down Expand Up @@ -88,6 +96,20 @@ protected function _initAttributeValues()
return $this;
}

/**
* Initializes attribute types
*
* @return $this
*/
protected function _initAttributeTypes()
{
/** @var $attribute AbstractAttribute */
foreach ($this->getAttributeCollection() as $attribute) {
$this->attributeTypes[$attribute->getAttributeCode()] = $attribute->getFrontendInput();
}
return $this;
}

/**
* Apply filter to collection and add not skipped attributes to select
*
Expand Down Expand Up @@ -246,19 +268,48 @@ protected function _addAttributeValuesToRow(\Magento\Framework\Model\AbstractMod
foreach ($validAttributeCodes as $attributeCode) {
$attributeValue = $item->getData($attributeCode);

if (isset(
$this->_attributeValues[$attributeCode]
) && isset(
$this->_attributeValues[$attributeCode][$attributeValue]
)
) {
$attributeValue = $this->_attributeValues[$attributeCode][$attributeValue];
}
if (null !== $attributeValue) {
$row[$attributeCode] = $attributeValue;
if ($this->isMultiselect($attributeCode)) {
$values = [];
$attributeValue = explode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $attributeValue);
foreach ($attributeValue as $value) {
$values[] = $this->getAttributeValueById($attributeCode, $value);
}
$row[$attributeCode] = implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $values);
} else {
$row[$attributeCode] = $this->getAttributeValueById($attributeCode, $attributeValue);
}
}

return $row;
}

/**
* Checks that attribute is multiselect type by attribute code
*
* @param string $attributeCode An attribute code
* @return bool Returns true if attribute is multiselect type
*/
private function isMultiselect($attributeCode)
{
return isset($this->attributeTypes[$attributeCode])
&& $this->attributeTypes[$attributeCode] === 'multiselect';
}

/**
* Returns attribute value by id
*
* @param string $attributeCode An attribute code
* @param int|string $valueId
* @return mixed
*/
private function getAttributeValueById($attributeCode, $valueId)
{
if (isset($this->_attributeValues[$attributeCode])
&& isset($this->_attributeValues[$attributeCode][$valueId])
) {
return $this->_attributeValues[$attributeCode][$valueId];
}

return $valueId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -691,8 +691,9 @@ public function isAttributeValid(
break;
case 'select':
case 'multiselect':
case 'boolean':
$valid = true;
foreach (explode($multiSeparator, strtolower($rowData[$attributeCode])) as $value) {
foreach (explode($multiSeparator, mb_strtolower($rowData[$attributeCode])) as $value) {
$valid = isset($attributeParams['options'][$value]);
if (!$valid) {
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,7 @@ public function getAttributeOptions(
foreach ($value as $innerOption) {
// skip ' -- Please Select -- ' option
if (strlen($innerOption['value'])) {
if ($attribute->isStatic()) {
$options[strtolower($innerOption[$index])] = $innerOption['value'];
} else {
// Non-static attributes flip keys an values
$options[$innerOption['value']] = $innerOption[$index];
}
$options[mb_strtolower($innerOption[$index])] = $innerOption['value'];
}
}
}
Expand Down

0 comments on commit fc095b1

Please sign in to comment.