10
10
use Magento \Framework \App \ObjectManager ;
11
11
use Magento \ImportExport \Model \Import \ErrorProcessing \ProcessingErrorAggregatorInterface ;
12
12
use Magento \Store \Model \Store ;
13
+ use Magento \CustomerImportExport \Model \ResourceModel \Import \Address \Storage as AddressStorage ;
14
+ use Magento \ImportExport \Model \Import \AbstractSource ;
13
15
14
16
/**
15
17
* Customer address import
@@ -85,20 +87,6 @@ class Address extends AbstractCustomer
85
87
*/
86
88
protected $ _permanentAttributes = [self ::COLUMN_WEBSITE , self ::COLUMN_EMAIL , self ::COLUMN_ADDRESS_ID ];
87
89
88
- /**
89
- * Existing addresses
90
- *
91
- * Example Array: [customer ID] => array(
92
- * address ID 1,
93
- * address ID 2,
94
- * ...
95
- * address ID N
96
- * )
97
- *
98
- * @var array
99
- */
100
- protected $ _addresses = [];
101
-
102
90
/**
103
91
* Attributes with index (not label) value
104
92
*
@@ -180,13 +168,6 @@ class Address extends AbstractCustomer
180
168
*/
181
169
protected $ _attributeCollection ;
182
170
183
- /**
184
- * Collection of existent addresses
185
- *
186
- * @var \Magento\Customer\Model\ResourceModel\Address\Collection
187
- */
188
- protected $ _addressCollection ;
189
-
190
171
/**
191
172
* Store imported row primary keys
192
173
*
@@ -252,6 +233,11 @@ class Address extends AbstractCustomer
252
233
*/
253
234
private $ optionsByWebsite = [];
254
235
236
+ /**
237
+ * @var AddressStorage
238
+ */
239
+ private $ addressStorage ;
240
+
255
241
/**
256
242
* @param \Magento\Framework\Stdlib\StringUtils $string
257
243
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -266,12 +252,12 @@ class Address extends AbstractCustomer
266
252
* @param \Magento\Customer\Model\AddressFactory $addressFactory
267
253
* @param \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionColFactory
268
254
* @param \Magento\Customer\Model\CustomerFactory $customerFactory
269
- * @param \Magento\Customer\Model\ResourceModel\Address\CollectionFactory $addressColFactory
270
255
* @param \Magento\Customer\Model\ResourceModel\Address\Attribute\CollectionFactory $attributesFactory
271
256
* @param \Magento\Framework\Stdlib\DateTime $dateTime
272
257
* @param \Magento\Customer\Model\Address\Validator\Postcode $postcodeValidator
273
258
* @param array $data
274
259
* @param CountryWithWebsitesSource|null $countryWithWebsites
260
+ * @param AddressStorage|null $addressStorage
275
261
*
276
262
* @SuppressWarnings(PHPMD.NPathComplexity)
277
263
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -290,12 +276,12 @@ public function __construct(
290
276
\Magento \Customer \Model \AddressFactory $ addressFactory ,
291
277
\Magento \Directory \Model \ResourceModel \Region \CollectionFactory $ regionColFactory ,
292
278
\Magento \Customer \Model \CustomerFactory $ customerFactory ,
293
- \Magento \Customer \Model \ResourceModel \Address \CollectionFactory $ addressColFactory ,
294
279
\Magento \Customer \Model \ResourceModel \Address \Attribute \CollectionFactory $ attributesFactory ,
295
280
\Magento \Framework \Stdlib \DateTime $ dateTime ,
296
281
\Magento \Customer \Model \Address \Validator \Postcode $ postcodeValidator ,
297
282
array $ data = [],
298
- CountryWithWebsitesSource $ countryWithWebsites = null
283
+ CountryWithWebsitesSource $ countryWithWebsites = null ,
284
+ AddressStorage $ addressStorage = null
299
285
) {
300
286
$ this ->_customerFactory = $ customerFactory ;
301
287
$ this ->_addressFactory = $ addressFactory ;
@@ -326,9 +312,6 @@ public function __construct(
326
312
$ data
327
313
);
328
314
329
- $ this ->_addressCollection = isset (
330
- $ data ['address_collection ' ]
331
- ) ? $ data ['address_collection ' ] : $ addressColFactory ->create ();
332
315
$ this ->_entityTable = isset (
333
316
$ data ['entity_table ' ]
334
317
) ? $ data ['entity_table ' ] : $ addressFactory ->create ()->getResource ()->getEntityTable ();
@@ -346,9 +329,11 @@ public function __construct(
346
329
self ::ERROR_DUPLICATE_PK ,
347
330
__ ('We found another row with this email, website and address ID combination. ' )
348
331
);
332
+ $ this ->addressStorage = $ addressStorage
333
+ ?: ObjectManager::getInstance ()->get (AddressStorage::class);
349
334
350
335
$ this ->_initAttributes ();
351
- $ this ->_initAddresses ()-> _initCountryRegions ();
336
+ $ this ->_initCountryRegions ();
352
337
}
353
338
354
339
/**
@@ -435,27 +420,6 @@ protected function _getNextEntityId()
435
420
return $ this ->_nextEntityId ++;
436
421
}
437
422
438
- /**
439
- * Initialize existent addresses data
440
- *
441
- * @return $this
442
- */
443
- protected function _initAddresses ()
444
- {
445
- /** @var $address \Magento\Customer\Model\Address */
446
- foreach ($ this ->_addressCollection as $ address ) {
447
- $ customerId = $ address ->getParentId ();
448
- if (!isset ($ this ->_addresses [$ customerId ])) {
449
- $ this ->_addresses [$ customerId ] = [];
450
- }
451
- $ addressId = $ address ->getId ();
452
- if (!in_array ($ addressId , $ this ->_addresses [$ customerId ])) {
453
- $ this ->_addresses [$ customerId ][] = $ addressId ;
454
- }
455
- }
456
- return $ this ;
457
- }
458
-
459
423
/**
460
424
* Initialize country regions hash for clever recognition
461
425
*
@@ -475,6 +439,56 @@ protected function _initCountryRegions()
475
439
return $ this ;
476
440
}
477
441
442
+ /**
443
+ * Pre-loading customers for existing customers checks in order
444
+ * to perform mass validation/import efficiently.
445
+ * Also loading existing addresses for requested customers.
446
+ *
447
+ * @param array|AbstractSource $rows Each row must contain data from columns email
448
+ * and website code.
449
+ *
450
+ * @return void
451
+ */
452
+ public function prepareCustomerData ($ rows ): void
453
+ {
454
+ $ customersPresent = [];
455
+ foreach ($ rows as $ rowData ) {
456
+ $ email = $ rowData [static ::COLUMN_EMAIL ] ?? null ;
457
+ $ websiteId = isset ($ rowData [static ::COLUMN_WEBSITE ])
458
+ ? $ this ->getWebsiteId ($ rowData [static ::COLUMN_WEBSITE ]) : false ;
459
+ if ($ email && $ websiteId !== false ) {
460
+ $ customersPresent [] = [
461
+ 'email ' => $ email ,
462
+ 'website_id ' => $ websiteId ,
463
+ ];
464
+ }
465
+ }
466
+ $ this ->getCustomerStorage ()->prepareCustomers ($ customersPresent );
467
+
468
+ $ ids = [];
469
+ foreach ($ customersPresent as $ customerData ) {
470
+ $ id = $ this ->getCustomerStorage ()->getCustomerId (
471
+ $ customerData ['email ' ],
472
+ $ customerData ['website_id ' ]
473
+ );
474
+ if ($ id ) {
475
+ $ ids [] = $ id ;
476
+ }
477
+ }
478
+
479
+ $ this ->addressStorage ->prepareAddresses ($ ids );
480
+ }
481
+
482
+ /**
483
+ * @inheritDoc
484
+ */
485
+ public function validateData ()
486
+ {
487
+ $ this ->prepareCustomerData ($ this ->getSource ());
488
+
489
+ return parent ::validateData ();
490
+ }
491
+
478
492
/**
479
493
* Import data rows
480
494
*
@@ -484,6 +498,16 @@ protected function _initCountryRegions()
484
498
*/
485
499
protected function _importData ()
486
500
{
501
+ //Preparing data for mass validation/import.
502
+ $ rows = [];
503
+ while ($ bunch = $ this ->_dataSourceModel ->getNextBunch ()) {
504
+ $ rows = array_merge ($ rows , $ bunch );
505
+ }
506
+ $ this ->prepareCustomerData ($ rows );
507
+ unset($ bunch , $ rows );
508
+ $ this ->_dataSourceModel ->getIterator ()->rewind ();
509
+
510
+ //Importing
487
511
while ($ bunch = $ this ->_dataSourceModel ->getNextBunch ()) {
488
512
$ newRows = [];
489
513
$ updateRows = [];
@@ -554,7 +578,7 @@ protected function _mergeEntityAttributes(array $newAttributes, array $attribute
554
578
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
555
579
* @SuppressWarnings(PHPMD.NPathComplexity)
556
580
*/
557
- protected function _prepareDataForUpdate (array $ rowData )
581
+ protected function _prepareDataForUpdate (array $ rowData ): array
558
582
{
559
583
$ multiSeparator = $ this ->getMultipleValueSeparator ();
560
584
$ email = strtolower ($ rowData [self ::COLUMN_EMAIL ]);
@@ -568,12 +592,11 @@ protected function _prepareDataForUpdate(array $rowData)
568
592
$ defaults = [];
569
593
$ newAddress = true ;
570
594
// get address id
571
- if (isset (
572
- $ this ->_addresses [$ customerId ]
573
- ) && in_array (
574
- $ rowData [self ::COLUMN_ADDRESS_ID ],
575
- $ this ->_addresses [$ customerId ]
576
- )
595
+ if ($ rowData [self ::COLUMN_ADDRESS_ID ]
596
+ && $ this ->addressStorage ->doesExist (
597
+ $ rowData [self ::COLUMN_ADDRESS_ID ],
598
+ (string )$ customerId
599
+ )
577
600
) {
578
601
$ newAddress = false ;
579
602
$ addressId = $ rowData [self ::COLUMN_ADDRESS_ID ];
@@ -823,12 +846,11 @@ protected function _validateRowForUpdate(array $rowData, $rowNumber)
823
846
$ rowNumber ,
824
847
$ multiSeparator
825
848
);
826
- } elseif ($ attributeParams ['is_required ' ] && (!isset (
827
- $ this ->_addresses [$ customerId ]
828
- ) || !in_array (
829
- $ addressId ,
830
- $ this ->_addresses [$ customerId ]
831
- ))
849
+ } elseif ($ attributeParams ['is_required ' ]
850
+ && !$ this ->addressStorage ->doesExist (
851
+ (string )$ addressId ,
852
+ (string )$ customerId
853
+ )
832
854
) {
833
855
$ this ->addRowError (self ::ERROR_VALUE_IS_REQUIRED , $ rowNumber , $ attributeCode );
834
856
}
@@ -883,7 +905,10 @@ protected function _validateRowForDelete(array $rowData, $rowNumber)
883
905
} else {
884
906
if (!strlen ($ addressId )) {
885
907
$ this ->addRowError (self ::ERROR_ADDRESS_ID_IS_EMPTY , $ rowNumber );
886
- } elseif (!in_array ($ addressId , $ this ->_addresses [$ customerId ])) {
908
+ } elseif (!$ this ->addressStorage ->doesExist (
909
+ (string )$ addressId ,
910
+ (string )$ customerId
911
+ )) {
887
912
$ this ->addRowError (self ::ERROR_ADDRESS_NOT_FOUND , $ rowNumber );
888
913
}
889
914
}
@@ -899,7 +924,10 @@ protected function _validateRowForDelete(array $rowData, $rowNumber)
899
924
*/
900
925
protected function _checkRowDuplicate ($ customerId , $ addressId )
901
926
{
902
- if (isset ($ this ->_addresses [$ customerId ]) && in_array ($ addressId , $ this ->_addresses [$ customerId ])) {
927
+ if ($ this ->addressStorage ->doesExist (
928
+ (string )$ addressId ,
929
+ (string )$ customerId
930
+ )) {
903
931
if (!isset ($ this ->_importedRowPks [$ customerId ][$ addressId ])) {
904
932
$ this ->_importedRowPks [$ customerId ][$ addressId ] = true ;
905
933
return false ;
0 commit comments