5
5
*/
6
6
namespace Magento \CatalogImportExport \Model \Import \Product \Type ;
7
7
8
- use Magento \Framework \ App \ ResourceConnection ;
8
+ use Magento \Catalog \ Api \ Data \ ProductAttributeInterface ;
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
}
@@ -284,35 +294,71 @@ protected function _initAttributes()
284
294
$ absentKeys [$ attributeRow ['attribute_set_name ' ]][] = $ attributeRow ['attribute_id ' ];
285
295
}
286
296
}
297
+ $ addedAttributes = [];
287
298
foreach ($ absentKeys as $ attributeSetName => $ attributeIds ) {
288
299
$ unknownAttributeIds = array_diff (
289
300
$ attributeIds ,
290
301
array_keys (self ::$ commonAttributesCache ),
291
302
self ::$ invAttributesCache
292
303
);
293
- if ($ unknownAttributeIds || $ this ->_forcedAttributesCodes ) {
294
- $ this ->attachAttributesById ($ attributeSetName , $ attributeIds );
304
+ if ($ unknownAttributeIds ) {
305
+ $ addedAttributes [] = $ this ->attachAttributesByOnlyId ($ attributeSetName , $ unknownAttributeIds );
306
+ }
307
+ if ($ this ->_forcedAttributesCodes ) {
308
+ $ addedAttributes [] = $ this ->attachAttributesByForcedCodes ($ attributeSetName );
309
+ }
310
+ }
311
+ $ addedAttributes = array_merge (...$ addedAttributes );
312
+ $ attributesToLoadFromTable = [];
313
+ foreach ($ addedAttributes as $ addedAttribute ) {
314
+ if (isset ($ addedAttribute ['options_use_table ' ])) {
315
+ $ attributesToLoadFromTable [] = $ addedAttribute ['id ' ];
316
+ unset(self ::$ commonAttributesCache [$ addedAttribute ['id ' ]]['options_use_table ' ]);
317
+ }
318
+ }
319
+ if (!empty ($ attributesToLoadFromTable )) {
320
+ $ collection = $ this ->attributeOptionCollectionFactory ->create ();
321
+ $ collection ->setAttributeFilter (['in ' => $ attributesToLoadFromTable ]);
322
+ $ collection ->setStoreFilter (\Magento \Store \Model \Store::DEFAULT_STORE_ID );
323
+ foreach ($ collection as $ option ) {
324
+ $ attributeId = $ option ->getAttributeId ();
325
+ $ value = strtolower ($ option ->getValue ());
326
+ self ::$ commonAttributesCache [$ attributeId ]['options ' ][$ value ] = $ option ->getOptionId ();
295
327
}
296
328
}
297
329
foreach ($ entityAttributes as $ attributeRow ) {
298
330
if (isset (self ::$ commonAttributesCache [$ attributeRow ['attribute_id ' ]])) {
299
331
$ attribute = self ::$ commonAttributesCache [$ attributeRow ['attribute_id ' ]];
300
- $ this ->_addAttributeParams (
301
- $ attributeRow ['attribute_set_name ' ],
302
- self ::$ commonAttributesCache [$ attributeRow ['attribute_id ' ]],
303
- $ attribute
304
- );
332
+ $ this ->_addAttributeParams ($ attributeRow ['attribute_set_name ' ], $ attribute , $ attribute );
333
+ }
334
+ }
335
+ foreach (array_keys ($ this ->_attributes ) as $ setName ) {
336
+ foreach ($ this ->_forcedAttributesCodes as $ code ) {
337
+ $ attributeId = self ::$ attributeCodeToId [$ code ] ?? null ;
338
+ if (null === $ attributeId ) {
339
+ continue ;
340
+ }
341
+ if (isset ($ this ->_attributes [$ setName ][$ code ])) {
342
+ continue ;
343
+ }
344
+ $ attribute = self ::$ commonAttributesCache [$ attributeId ] ?? null ;
345
+ if (!$ attribute ) {
346
+ continue ;
347
+ }
348
+ $ this ->_addAttributeParams ($ setName , $ attribute , $ attribute );
305
349
}
306
350
}
307
351
return $ this ;
308
352
}
309
353
310
354
/**
311
- * Attach Attributes By Id
355
+ * Attach Attributes By Id and _forcedAttributesCodes
312
356
*
313
357
* @param string $attributeSetName
314
358
* @param array $attributeIds
315
359
* @return void
360
+ * @deprecated use attachAttributesOnlyById and attachAttributesByForcedCodes
361
+ * @see attachAttributesOnlyById() and attachAttributesByForcedCodes()
316
362
*/
317
363
protected function attachAttributesById ($ attributeSetName , $ attributeIds )
318
364
{
@@ -323,41 +369,97 @@ protected function attachAttributesById($attributeSetName, $attributeIds)
323
369
['in ' => $ this ->_forcedAttributesCodes ]
324
370
]
325
371
) 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
- }
372
+ $ this ->attachAttribute ($ attributeSetName , $ attribute );
373
+ }
374
+ }
350
375
376
+ /**
377
+ * Attach Attributes By Id
378
+ *
379
+ * @param string $attributeSetName
380
+ * @param array $attributeIds
381
+ * @return array
382
+ */
383
+ private function attachAttributesByOnlyId (string $ attributeSetName , array $ attributeIds ) : array
384
+ {
385
+ $ addedAttributes = [];
386
+ foreach ($ this ->_prodAttrColFac ->create ()->addFieldToFilter (
387
+ ['main_table.attribute_id ' , 'main_table.attribute_code ' ],
388
+ [['in ' => $ attributeIds ]]
389
+ ) as $ attribute ) {
390
+ $ cachedAttribute = $ this ->attachAttribute ($ attributeSetName , $ attribute );
391
+ if (null !== $ cachedAttribute ) {
392
+ $ addedAttributes [] = $ cachedAttribute ;
393
+ }
394
+ }
395
+ return $ addedAttributes ;
396
+ }
397
+
398
+ /**
399
+ * Attach Attributes By _forcedAttributesCodes
400
+ *
401
+ * @param string $attributeSetName
402
+ * @return array
403
+ */
404
+ private function attachAttributesByForcedCodes (string $ attributeSetName ) : 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 ($ attributeSetName , $ attribute );
412
+ if (null !== $ cachedAttribute ) {
413
+ $ addedAttributes [] = $ cachedAttribute ;
414
+ }
415
+ }
416
+ return $ addedAttributes ;
417
+ }
418
+
419
+ /**
420
+ * Attach Attributes By Id
421
+ *
422
+ * @param string $attributeSetName
423
+ * @param ProductAttributeInterface $attribute
424
+ * @return array|null
425
+ */
426
+ private function attachAttribute (string $ attributeSetName , ProductAttributeInterface $ attribute ) {
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
/**
0 commit comments