5
5
*/
6
6
namespace Magento \CatalogImportExport \Model \Import \Product \Type ;
7
7
8
- use Magento \Framework \ App \ ResourceConnection ;
8
+ use Magento \Catalog \ Model \ ResourceModel \ Eav \ Attribute ;
9
9
use Magento \CatalogImportExport \Model \Import \Product \RowValidatorInterface ;
10
- use Magento \CatalogImportExport \Model \Import \Product ;
10
+ use Magento \Eav \Model \Entity \Attribute \Source \Table ;
11
+ use Magento \Eav \Model \ResourceModel \Entity \Attribute \Option \CollectionFactory as AttributeOptionCollectionFactory ;
12
+ use Magento \Framework \App \ObjectManager ;
13
+ use Magento \Framework \App \ResourceConnection ;
11
14
use Magento \Framework \EntityManager \MetadataPool ;
12
15
13
16
/**
@@ -151,6 +154,11 @@ abstract class AbstractType
151
154
*/
152
155
private $ productEntityLinkField ;
153
156
157
+ /**
158
+ * @var AttributeOptionCollectionFactory
159
+ */
160
+ private $ attributeOptionCollectionFactory ;
161
+
154
162
/**
155
163
* AbstractType constructor
156
164
*
@@ -159,20 +167,24 @@ abstract class AbstractType
159
167
* @param ResourceConnection $resource
160
168
* @param array $params
161
169
* @param MetadataPool|null $metadataPool
170
+ * @param AttributeOptionCollectionFactory|null $attributeOptionCollectionFactory
162
171
* @throws \Magento\Framework\Exception\LocalizedException
163
172
*/
164
173
public function __construct (
165
174
\Magento \Eav \Model \ResourceModel \Entity \Attribute \Set \CollectionFactory $ attrSetColFac ,
166
175
\Magento \Catalog \Model \ResourceModel \Product \Attribute \CollectionFactory $ prodAttrColFac ,
167
176
\Magento \Framework \App \ResourceConnection $ resource ,
168
177
array $ params ,
169
- MetadataPool $ metadataPool = null
178
+ MetadataPool $ metadataPool = null ,
179
+ AttributeOptionCollectionFactory $ attributeOptionCollectionFactory = null
170
180
) {
171
181
$ this ->_attrSetColFac = $ attrSetColFac ;
172
182
$ this ->_prodAttrColFac = $ prodAttrColFac ;
173
183
$ this ->_resource = $ resource ;
174
184
$ this ->connection = $ resource ->getConnection ();
175
185
$ this ->metadataPool = $ metadataPool ?: $ this ->getMetadataPool ();
186
+ $ this ->attributeOptionCollectionFactory = $ attributeOptionCollectionFactory
187
+ ?: ObjectManager::getInstance ()->get (AttributeOptionCollectionFactory::class);
176
188
if ($ this ->isSuitable ()) {
177
189
if (!isset ($ params [0 ])
178
190
|| !isset ($ params [1 ])
@@ -183,11 +195,9 @@ public function __construct(
183
195
}
184
196
$ this ->_entityModel = $ params [0 ];
185
197
$ this ->_type = $ params [1 ];
186
-
187
198
$ this ->initMessageTemplates (
188
199
array_merge ($ this ->_genericMessageTemplates , $ this ->_messageTemplates )
189
200
);
190
-
191
201
$ this ->_initAttributes ();
192
202
}
193
203
}
@@ -257,6 +267,10 @@ protected function _getProductAttributes($attrSetData)
257
267
/**
258
268
* Initialize attributes parameters for all attributes' sets.
259
269
*
270
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
271
+ * @SuppressWarnings(PHPMD.NPathComplexity)
272
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
273
+ *
260
274
* @return $this
261
275
*/
262
276
protected function _initAttributes ()
@@ -284,80 +298,168 @@ protected function _initAttributes()
284
298
$ absentKeys [$ attributeRow ['attribute_set_name ' ]][] = $ attributeRow ['attribute_id ' ];
285
299
}
286
300
}
287
- foreach ($ absentKeys as $ attributeSetName => $ attributeIds ) {
301
+ $ addedAttributes = [];
302
+ foreach ($ absentKeys as $ attributeIds ) {
288
303
$ unknownAttributeIds = array_diff (
289
304
$ attributeIds ,
290
305
array_keys (self ::$ commonAttributesCache ),
291
306
self ::$ invAttributesCache
292
307
);
293
- if ($ unknownAttributeIds || $ this ->_forcedAttributesCodes ) {
294
- $ this ->attachAttributesById ($ attributeSetName , $ attributeIds );
308
+ if ($ unknownAttributeIds ) {
309
+ $ addedAttributes [] = $ this ->attachAttributesByOnlyId ($ unknownAttributeIds );
310
+ }
311
+ }
312
+ if ($ this ->_forcedAttributesCodes ) {
313
+ $ addedAttributes [] = $ this ->attachAttributesByForcedCodes ();
314
+ }
315
+ $ addedAttributes = array_merge (...$ addedAttributes );
316
+ $ attributesToLoadFromTable = [];
317
+ foreach ($ addedAttributes as $ addedAttribute ) {
318
+ if (isset ($ addedAttribute ['options_use_table ' ])) {
319
+ $ attributesToLoadFromTable [] = $ addedAttribute ['id ' ];
320
+ unset(self ::$ commonAttributesCache [$ addedAttribute ['id ' ]]['options_use_table ' ]);
321
+ }
322
+ }
323
+ foreach (array_chunk ($ attributesToLoadFromTable , 1000 ) as $ attributesToLoadFromTableChunk ) {
324
+ $ collection = $ this ->attributeOptionCollectionFactory ->create ();
325
+ $ collection ->setAttributeFilter (['in ' => $ attributesToLoadFromTableChunk ]);
326
+ $ collection ->setStoreFilter (\Magento \Store \Model \Store::DEFAULT_STORE_ID );
327
+ foreach ($ collection as $ option ) {
328
+ $ attributeId = $ option ->getAttributeId ();
329
+ $ value = strtolower ($ option ->getValue ());
330
+ self ::$ commonAttributesCache [$ attributeId ]['options ' ][$ value ] = $ option ->getOptionId ();
295
331
}
296
332
}
297
333
foreach ($ entityAttributes as $ attributeRow ) {
298
334
if (isset (self ::$ commonAttributesCache [$ attributeRow ['attribute_id ' ]])) {
299
335
$ attribute = self ::$ commonAttributesCache [$ attributeRow ['attribute_id ' ]];
300
- $ this ->_addAttributeParams (
301
- $ attributeRow ['attribute_set_name ' ],
302
- self ::$ commonAttributesCache [$ attributeRow ['attribute_id ' ]],
303
- $ attribute
304
- );
336
+ $ this ->_addAttributeParams ($ attributeRow ['attribute_set_name ' ], $ attribute , $ attribute );
337
+ }
338
+ }
339
+ foreach (array_keys ($ this ->_attributes ) as $ setName ) {
340
+ foreach ($ this ->_forcedAttributesCodes as $ code ) {
341
+ $ attributeId = self ::$ attributeCodeToId [$ code ] ?? null ;
342
+ if (null === $ attributeId ) {
343
+ continue ;
344
+ }
345
+ if (isset ($ this ->_attributes [$ setName ][$ code ])) {
346
+ continue ;
347
+ }
348
+ $ attribute = self ::$ commonAttributesCache [$ attributeId ] ?? null ;
349
+ if (!$ attribute ) {
350
+ continue ;
351
+ }
352
+ $ this ->_addAttributeParams ($ setName , $ attribute , $ attribute );
305
353
}
306
354
}
307
355
return $ this ;
308
356
}
309
357
310
358
/**
311
- * Attach Attributes By Id
359
+ * Attach Attributes By Id and _forcedAttributesCodes
312
360
*
313
361
* @param string $attributeSetName
314
362
* @param array $attributeIds
315
363
* @return void
364
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
365
+ * @deprecated use attachAttributesByOnlyId and attachAttributesByForcedCodes
366
+ * @see attachAttributesByOnlyId() and attachAttributesByForcedCodes()
316
367
*/
317
368
protected function attachAttributesById ($ attributeSetName , $ attributeIds )
318
369
{
319
370
foreach ($ this ->_prodAttrColFac ->create ()->addFieldToFilter (
320
371
['main_table.attribute_id ' , 'main_table.attribute_code ' ],
321
- [
322
- ['in ' => $ attributeIds ],
323
- ['in ' => $ this ->_forcedAttributesCodes ]
324
- ]
372
+ [['in ' => $ attributeIds ], ['in ' => $ this ->_forcedAttributesCodes ]]
325
373
) as $ attribute ) {
326
- $ attributeCode = $ attribute -> getAttributeCode ( );
327
- $ attributeId = $ attribute -> getId ();
328
-
329
- if ( $ attribute -> getIsVisible () || in_array ( $ attributeCode , $ this -> _forcedAttributesCodes )) {
330
- if (! isset ( self :: $ commonAttributesCache [ $ attributeId ])) {
331
- $ defaultValue = $ attribute -> getDefaultValue ();
332
- self :: $ commonAttributesCache [ $ attributeId ] = [
333
- ' id ' => $ attributeId ,
334
- ' code ' => $ attributeCode ,
335
- ' is_global ' => $ attribute -> getIsGlobal (),
336
- ' is_required ' => $ attribute -> getIsRequired (),
337
- ' is_unique ' => $ attribute -> getIsUnique (),
338
- ' frontend_label ' => $ attribute -> getFrontendLabel (),
339
- ' is_static ' => $ attribute -> isStatic (),
340
- ' apply_to ' => $ attribute -> getApplyTo () ,
341
- ' type ' => \ Magento \ ImportExport \ Model \Import:: getAttributeType ( $ attribute ),
342
- ' default_value ' => ( is_string ( $ defaultValue ) && strlen ( $ defaultValue )) ?
343
- $ attribute -> getDefaultValue () : null ,
344
- ' options ' => $ this -> _entityModel -> getAttributeOptions (
345
- $ attribute ,
346
- $ this -> _indexValueAttributes
347
- ),
348
- ] ;
349
- }
374
+ $ this -> attachAttribute ( $ attribute );
375
+ }
376
+ }
377
+
378
+ /**
379
+ * Attach Attributes By Id
380
+ *
381
+ * @param array $attributeIds
382
+ * @return array
383
+ */
384
+ private function attachAttributesByOnlyId ( array $ attributeIds ) : array
385
+ {
386
+ $ addedAttributes = [];
387
+ foreach ( $ this -> _prodAttrColFac -> create ()-> addFieldToFilter (
388
+ [ ' main_table.attribute_id ' ] ,
389
+ [[ ' in ' => $ attributeIds ]]
390
+ ) as $ attribute ) {
391
+ $ cachedAttribute = $ this -> attachAttribute ( $ attribute );
392
+ if ( null !== $ cachedAttribute ) {
393
+ $ addedAttributes [] = $ cachedAttribute ;
394
+ }
395
+ }
396
+ return $ addedAttributes ;
397
+ }
350
398
399
+ /**
400
+ * Attach Attributes By _forcedAttributesCodes
401
+ *
402
+ * @return array
403
+ */
404
+ private function attachAttributesByForcedCodes () : array
405
+ {
406
+ $ addedAttributes = [];
407
+ foreach ($ this ->_prodAttrColFac ->create ()->addFieldToFilter (
408
+ ['main_table.attribute_code ' ],
409
+ [['in ' => $ this ->_forcedAttributesCodes ]]
410
+ ) as $ attribute ) {
411
+ $ cachedAttribute = $ this ->attachAttribute ($ attribute );
412
+ if (null !== $ cachedAttribute ) {
413
+ $ addedAttributes [] = $ cachedAttribute ;
414
+ }
415
+ }
416
+ return $ addedAttributes ;
417
+ }
418
+
419
+ /**
420
+ * Attach Attribute to self::$commonAttributesCache or self::$invAttributesCache
421
+ *
422
+ * @param Attribute $attribute
423
+ * @return array|null
424
+ */
425
+ private function attachAttribute (Attribute $ attribute )
426
+ {
427
+ $ cachedAttribute = null ;
428
+ $ attributeCode = $ attribute ->getAttributeCode ();
429
+ $ attributeId = $ attribute ->getId ();
430
+ if ($ attribute ->getIsVisible () || in_array ($ attributeCode , $ this ->_forcedAttributesCodes )) {
431
+ if (!isset (self ::$ commonAttributesCache [$ attributeId ])) {
432
+ $ defaultValue = $ attribute ->getDefaultValue ();
433
+ $ cachedAttribute = [
434
+ 'id ' => $ attributeId ,
435
+ 'code ' => $ attributeCode ,
436
+ 'is_global ' => $ attribute ->getIsGlobal (),
437
+ 'is_required ' => $ attribute ->getIsRequired (),
438
+ 'is_unique ' => $ attribute ->getIsUnique (),
439
+ 'frontend_label ' => $ attribute ->getFrontendLabel (),
440
+ 'is_static ' => $ attribute ->isStatic (),
441
+ 'apply_to ' => $ attribute ->getApplyTo (),
442
+ 'type ' => \Magento \ImportExport \Model \Import::getAttributeType ($ attribute ),
443
+ 'default_value ' => (is_string ($ defaultValue ) && strlen ($ defaultValue )) ?
444
+ $ attribute ->getDefaultValue () : null ,
445
+ 'options ' => [],
446
+ ];
447
+ $ sourceModel = $ attribute ->getSourceModel ();
448
+ if (Table::class === $ sourceModel ) {
449
+ $ cachedAttribute ['options_use_table ' ] = true ;
450
+ } else {
451
+ $ cachedAttribute ['options ' ] = $ this ->_entityModel ->getAttributeOptions (
452
+ $ attribute ,
453
+ $ this ->_indexValueAttributes
454
+ );
455
+ }
456
+ self ::$ commonAttributesCache [$ attributeId ] = $ cachedAttribute ;
351
457
self ::$ attributeCodeToId [$ attributeCode ] = $ attributeId ;
352
- $ this ->_addAttributeParams (
353
- $ attributeSetName ,
354
- self ::$ commonAttributesCache [$ attributeId ],
355
- $ attribute
356
- );
357
- } else {
358
- self ::$ invAttributesCache [] = $ attributeId ;
359
458
}
459
+ } else {
460
+ self ::$ invAttributesCache [] = $ attributeId ;
360
461
}
462
+ return $ cachedAttribute ;
361
463
}
362
464
363
465
/**
@@ -524,7 +626,6 @@ public function isSuitable()
524
626
public function prepareAttributesWithDefaultValueForSave (array $ rowData , $ withDefaultValue = true )
525
627
{
526
628
$ resultAttrs = [];
527
-
528
629
foreach ($ this ->_getProductAttributes ($ rowData ) as $ attrCode => $ attrParams ) {
529
630
if ($ attrParams ['is_static ' ]) {
530
631
continue ;
@@ -548,7 +649,6 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe
548
649
$ resultAttrs [$ attrCode ] = $ attrParams ['default_value ' ];
549
650
}
550
651
}
551
-
552
652
return $ resultAttrs ;
553
653
}
554
654
0 commit comments