Skip to content

Commit ca592dc

Browse files
author
Oleksandr Gorkun
committed
MAGETWO-83426: [Performance] Customer Import check data does not complete
1 parent 586ac08 commit ca592dc

File tree

2 files changed

+157
-30
lines changed

2 files changed

+157
-30
lines changed

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

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
1313
use Magento\Store\Model\Store;
1414
use Magento\ImportExport\Model\Import;
15+
use Magento\CustomerImportExport\Model\ResourceModel\Import\Address\Storage as AddressStorage;
1516

1617
/**
1718
* @SuppressWarnings(PHPMD.TooManyFields)
@@ -100,6 +101,8 @@ class Address extends AbstractCustomer
100101
* )
101102
*
102103
* @var array
104+
* @deprected
105+
* @see $addressStorage
103106
*/
104107
protected $_addresses = [];
105108

@@ -256,6 +259,11 @@ class Address extends AbstractCustomer
256259
*/
257260
private $optionsByWebsite = [];
258261

262+
/**
263+
* @var AddressStorage
264+
*/
265+
private $addressStorage;
266+
259267
/**
260268
* @param \Magento\Framework\Stdlib\StringUtils $string
261269
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -276,6 +284,7 @@ class Address extends AbstractCustomer
276284
* @param \Magento\Customer\Model\Address\Validator\Postcode $postcodeValidator
277285
* @param array $data
278286
* @param Sources\CountryWithWebsites|null $countryWithWebsites
287+
* @param AddressStorage|null $addressStorage
279288
*
280289
* @SuppressWarnings(PHPMD.NPathComplexity)
281290
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -299,7 +308,8 @@ public function __construct(
299308
DateTime $dateTime,
300309
\Magento\Customer\Model\Address\Validator\Postcode $postcodeValidator,
301310
array $data = [],
302-
Sources\CountryWithWebsites $countryWithWebsites = null
311+
Sources\CountryWithWebsites $countryWithWebsites = null,
312+
AddressStorage $addressStorage = null
303313
) {
304314
$this->_customerFactory = $customerFactory;
305315
$this->_addressFactory = $addressFactory;
@@ -352,6 +362,8 @@ public function __construct(
352362
self::ERROR_DUPLICATE_PK,
353363
__('We found another row with this email, website and address ID combination.')
354364
);
365+
$this->addressStorage = $addressStorage
366+
?: ObjectManager::getInstance()->get(AddressStorage::class);
355367

356368
$this->_initAttributes();
357369
$this->_initCountryRegions();
@@ -482,10 +494,11 @@ protected function _initAddresses()
482494
public function prepareCustomerData(\Traversable $rows)
483495
{
484496
parent::prepareCustomerData($rows);
497+
485498
$ids = [];
486499
foreach ($rows as $customerData) {
487500
if (isset($customerData[static::COLUMN_EMAIL])
488-
&& $email = $customerData[static::COLUMN_EMAIL]
501+
&& ($email = $customerData[static::COLUMN_EMAIL])
489502
&& isset($customerData[static::COLUMN_WEBSITE])
490503
&& (
491504
$websiteId = $this->getWebsiteId(
@@ -501,21 +514,7 @@ public function prepareCustomerData(\Traversable $rows)
501514
}
502515
}
503516

504-
$this->_addressCollection->addFieldToFilter(
505-
'parent_id',
506-
['in' => $ids]
507-
);
508-
/** @var $address \Magento\Customer\Model\Address */
509-
foreach ($this->_addressCollection as $address) {
510-
$customerId = $address->getParentId();
511-
if (!isset($this->_addresses[$customerId])) {
512-
$this->_addresses[$customerId] = [];
513-
}
514-
$addressId = $address->getId();
515-
if (!in_array($addressId, $this->_addresses[$customerId])) {
516-
$this->_addresses[$customerId][] = $addressId;
517-
}
518-
}
517+
$this->addressStorage->prepareAddresses($ids);
519518
}
520519

521520
/**
@@ -644,9 +643,10 @@ protected function _prepareDataForUpdate(array $rowData)
644643
$defaults = [];
645644
$newAddress = true;
646645
// get address id
647-
if (isset($this->_addresses[$customerId])
648-
&& in_array($rowData[self::COLUMN_ADDRESS_ID], $this->_addresses[$customerId])
649-
) {
646+
if ($this->addressStorage->doesExist(
647+
$rowData[self::COLUMN_ADDRESS_ID],
648+
$customerId
649+
)) {
650650
$newAddress = false;
651651
$addressId = $rowData[self::COLUMN_ADDRESS_ID];
652652
} else {
@@ -901,12 +901,11 @@ protected function _validateRowForUpdate(array $rowData, $rowNumber)
901901
$rowNumber,
902902
$multiSeparator
903903
);
904-
} elseif ($attributeParams['is_required'] && (!isset(
905-
$this->_addresses[$customerId]
906-
) || !in_array(
907-
$addressId,
908-
$this->_addresses[$customerId]
909-
))
904+
} elseif ($attributeParams['is_required']
905+
&& !$this->addressStorage->doesExist(
906+
$addressId,
907+
$customerId
908+
)
910909
) {
911910
$this->addRowError(self::ERROR_VALUE_IS_REQUIRED, $rowNumber, $attributeCode);
912911
}
@@ -962,9 +961,10 @@ protected function _validateRowForDelete(array $rowData, $rowNumber)
962961
} else {
963962
if (!strlen($addressId)) {
964963
$this->addRowError(self::ERROR_ADDRESS_ID_IS_EMPTY, $rowNumber);
965-
} elseif (!in_array($customerId, $this->_addresses)
966-
|| !in_array($addressId, $this->_addresses[$customerId])
967-
) {
964+
} elseif (!$this->addressStorage->doesExist(
965+
$addressId,
966+
$customerId
967+
)) {
968968
$this->addRowError(self::ERROR_ADDRESS_NOT_FOUND, $rowNumber);
969969
}
970970
}
@@ -980,7 +980,7 @@ protected function _validateRowForDelete(array $rowData, $rowNumber)
980980
*/
981981
protected function _checkRowDuplicate($customerId, $addressId)
982982
{
983-
if (isset($this->_addresses[$customerId]) && in_array($addressId, $this->_addresses[$customerId])) {
983+
if ($this->addressStorage->doesExist($addressId, $customerId)) {
984984
if (!isset($this->_importedRowPks[$customerId][$addressId])) {
985985
$this->_importedRowPks[$customerId][$addressId] = true;
986986
return false;
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
/**
3+
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\CustomerImportExport\Model\ResourceModel\Import\Address;
7+
8+
use Magento\Customer\Api\AddressRepositoryInterface;
9+
use Magento\Framework\Api\FilterBuilder;
10+
use Magento\Framework\Api\SearchCriteriaBuilder;
11+
12+
/**
13+
* Storage to check existing addresses.
14+
*/
15+
class Storage
16+
{
17+
/**
18+
* IDs of addresses grouped by customer IDs.
19+
*
20+
* @var string[][]
21+
*/
22+
private $addresses = [];
23+
24+
/**
25+
* @var AddressRepositoryInterface
26+
*/
27+
private $addressRepository;
28+
29+
/**
30+
* @var SearchCriteriaBuilder
31+
*/
32+
private $searchCriteriaBuilder;
33+
34+
/**
35+
* @var FilterBuilder
36+
*/
37+
private $filterBuilder;
38+
39+
/**
40+
* @param AddressRepositoryInterface $addressRepository
41+
* @param SearchCriteriaBuilder $searchCriteriaBuilder
42+
* @param FilterBuilder $filterBuilder
43+
*/
44+
public function __construct(
45+
AddressRepositoryInterface $addressRepository,
46+
SearchCriteriaBuilder $searchCriteriaBuilder,
47+
FilterBuilder $filterBuilder
48+
) {
49+
$this->addressRepository = $addressRepository;
50+
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
51+
$this->filterBuilder = $filterBuilder;
52+
}
53+
54+
/**
55+
* Record existing address.
56+
*
57+
* @param string $customerId
58+
* @param string $addressId
59+
*
60+
* @return void
61+
*/
62+
private function addRecord($customerId, $addressId)
63+
{
64+
if (!$customerId || !$addressId) {
65+
return;
66+
}
67+
$customerId = (string)$customerId;
68+
$addressId = (string)$addressId;
69+
if (!array_key_exists($customerId, $this->addresses)) {
70+
$this->addresses[$customerId] = [];
71+
}
72+
73+
if (!in_array($addressId, $this->addresses[$customerId], true)) {
74+
$this->addresses[$customerId][] = $addressId;
75+
}
76+
}
77+
78+
/**
79+
* Check if given address exists for given customer.
80+
*
81+
* @param string $addressId
82+
* @param string $forCustomerId
83+
* @return bool
84+
*/
85+
public function doesExist($addressId, $forCustomerId)
86+
{
87+
return array_key_exists($forCustomerId, $this->addresses)
88+
&& in_array(
89+
(string)$addressId,
90+
$this->addresses[$forCustomerId],
91+
true
92+
);
93+
}
94+
95+
/**
96+
* Pre-load addresses for given customers.
97+
*
98+
* @param string[] $forCustomersIds
99+
* @return void
100+
*/
101+
public function prepareAddresses(array $forCustomersIds)
102+
{
103+
if (!$forCustomersIds) {
104+
return;
105+
}
106+
107+
$filters = [];
108+
foreach ($forCustomersIds as $customerId) {
109+
if (!array_key_exists((string)$customerId, $this->addresses)) {
110+
$filters[] = $this->filterBuilder
111+
->setField('parent_id')
112+
->setValue($customerId)
113+
->setConditionType('eq')
114+
->create();
115+
}
116+
}
117+
$this->searchCriteriaBuilder->addFilters($filters);
118+
119+
//Adding addresses that we found.
120+
$found = $this->addressRepository->getList(
121+
$this->searchCriteriaBuilder->create()
122+
);
123+
foreach ($found->getItems() as $address) {
124+
$this->addRecord($address->getCustomerId(), $address->getId());
125+
}
126+
}
127+
}

0 commit comments

Comments
 (0)