@@ -81,6 +81,12 @@ class Options implements OptionProviderInterface
81
81
*/
82
82
private ?int $ statusAttributeId = null ;
83
83
84
+ /**
85
+ * Local cache for attribute option values data without filtration by product ids
86
+ * @var array
87
+ */
88
+ private static array $ optionValuesPerAttributesCache = [];
89
+
84
90
/**
85
91
* @param ResourceConnection $resourceConnection
86
92
* @param ProductOptionQuery $productOptionQuery
@@ -197,14 +203,31 @@ private function getPossibleAttributeValues(int $entityId, int $attributeId, str
197
203
*/
198
204
private function getOptionValuesData (array $ arguments ): array
199
205
{
200
- $ arguments ['attributes ' ] = $ this ->getAttributeIds ($ arguments );
206
+ $ attributeIdsAssignedToProduct = $ this ->getAttributeIds ($ arguments );
207
+ $ attributeIds = array_combine ($ attributeIdsAssignedToProduct , $ attributeIdsAssignedToProduct );
208
+
209
+ // we should verify that attribute ids cached with requested store view code
210
+ // possible further optimization - fetch attributes from DB only for requested store view code
211
+ foreach (self ::$ optionValuesPerAttributesCache as $ attributeId => $ dataByStore ) {
212
+ foreach (array_keys ($ dataByStore ) as $ storeCode ) {
213
+ if (in_array ($ storeCode , $ arguments ['storeViewCode ' ])) {
214
+ unset($ attributeIds [$ attributeId ]);
215
+ }
216
+ }
217
+ }
218
+
219
+ if (!$ attributeIds ) {
220
+ // all attributes already in cache - retrieve it
221
+ return $ this ->getOptionValuesFromCache ($ attributeIdsAssignedToProduct );
222
+ }
223
+ $ arguments ['attributes ' ] = $ attributeIds ;
224
+ // attribute option values are selected without restrictions by product ids
225
+ unset($ arguments ['productId ' ]);
201
226
$ select = $ this ->productOptionValueQuery ->getQuery ($ arguments );
202
227
203
228
$ cursor = $ this ->resourceConnection ->getConnection ()->query ($ select );
204
-
205
- $ data = [];
206
229
while ($ row = $ cursor ->fetch ()) {
207
- $ data [$ row ['attribute_id ' ]][$ row ['storeViewCode ' ]][$ row ['optionId ' ]] = [
230
+ self :: $ optionValuesPerAttributesCache [$ row ['attribute_id ' ]][$ row ['storeViewCode ' ]][$ row ['optionId ' ]] = [
208
231
'id ' => $ this ->optionValueUid ->resolve ($ row ['attribute_id ' ], $ row ['optionId ' ]),
209
232
'label ' => $ row ['label ' ],
210
233
'sortOrder ' => $ row ['sortOrder ' ],
@@ -218,7 +241,19 @@ private function getOptionValuesData(array $arguments): array
218
241
) ? $ row ['swatchValue ' ] : null
219
242
];
220
243
}
221
- return $ data ;
244
+
245
+ return $ this ->getOptionValuesFromCache ($ attributeIdsAssignedToProduct );
246
+ }
247
+
248
+ /**
249
+ * Get option values from cache
250
+ *
251
+ * @param array $attributeIds
252
+ * @return array
253
+ */
254
+ private function getOptionValuesFromCache (array $ attributeIds ): array
255
+ {
256
+ return \array_intersect_key (self ::$ optionValuesPerAttributesCache , \array_flip (array_filter ($ attributeIds )));
222
257
}
223
258
224
259
/**
@@ -326,7 +361,10 @@ public function get(array $values): array
326
361
*/
327
362
private function getAssignedAttributeValues (array $ attributeValuesList , array $ assignedAttributeValuesId ): array
328
363
{
329
- $ assignedAttributeValues = array_intersect_key ($ attributeValuesList , array_flip ($ assignedAttributeValuesId ));
364
+ $ assignedAttributeValues = array_intersect_key (
365
+ $ attributeValuesList ,
366
+ array_flip (array_filter ($ assignedAttributeValuesId ))
367
+ );
330
368
331
369
return !empty ($ assignedAttributeValues ) ? \array_values ($ assignedAttributeValues ) : [];
332
370
}
0 commit comments