Skip to content

Commit 9a29e1b

Browse files
authored
MDEE-864: add local cache for attribute options data (#447)
* MDEE-864: add local cache for attribute options data
1 parent 8bd3003 commit 9a29e1b

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

ConfigurableProductDataExporter/Model/Provider/Product/Options.php

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ class Options implements OptionProviderInterface
8181
*/
8282
private ?int $statusAttributeId = null;
8383

84+
/**
85+
* Local cache for attribute option values data without filtration by product ids
86+
* @var array
87+
*/
88+
private static array $optionValuesPerAttributesCache = [];
89+
8490
/**
8591
* @param ResourceConnection $resourceConnection
8692
* @param ProductOptionQuery $productOptionQuery
@@ -197,14 +203,31 @@ private function getPossibleAttributeValues(int $entityId, int $attributeId, str
197203
*/
198204
private function getOptionValuesData(array $arguments): array
199205
{
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']);
201226
$select = $this->productOptionValueQuery->getQuery($arguments);
202227

203228
$cursor = $this->resourceConnection->getConnection()->query($select);
204-
205-
$data = [];
206229
while ($row = $cursor->fetch()) {
207-
$data[$row['attribute_id']][$row['storeViewCode']][$row['optionId']] = [
230+
self::$optionValuesPerAttributesCache[$row['attribute_id']][$row['storeViewCode']][$row['optionId']] = [
208231
'id' => $this->optionValueUid->resolve($row['attribute_id'], $row['optionId']),
209232
'label' => $row['label'],
210233
'sortOrder' => $row['sortOrder'],
@@ -218,7 +241,19 @@ private function getOptionValuesData(array $arguments): array
218241
) ? $row['swatchValue'] : null
219242
];
220243
}
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)));
222257
}
223258

224259
/**
@@ -326,7 +361,10 @@ public function get(array $values): array
326361
*/
327362
private function getAssignedAttributeValues(array $attributeValuesList, array $assignedAttributeValuesId): array
328363
{
329-
$assignedAttributeValues = array_intersect_key($attributeValuesList, array_flip($assignedAttributeValuesId));
364+
$assignedAttributeValues = array_intersect_key(
365+
$attributeValuesList,
366+
array_flip(array_filter($assignedAttributeValuesId))
367+
);
330368

331369
return !empty($assignedAttributeValues) ? \array_values($assignedAttributeValues) : [];
332370
}

ConfigurableProductDataExporter/Model/Query/ProductOptionValueQuery.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
use Magento\Framework\DB\Sql\Expression;
2222

2323
/**
24-
* Configurable option values data query for product data exporter
24+
* Query obtains attribute option values used in configurable products.
2525
*/
2626
class ProductOptionValueQuery
2727
{
@@ -90,8 +90,11 @@ public function getQuery(array $arguments): Select
9090
'swatchType' => new Expression('CASE WHEN aos.value IS NULL THEN aod.type ELSE aos.type END'),
9191
]
9292
)
93-
->where('eao.attribute_id IN (?)', $attributeIds)
94-
->where('s.code IN (?)', $storeViewCodes);
93+
->where('eao.attribute_id IN (?)', $attributeIds);
94+
95+
if ($storeViewCodes) {
96+
$select->where('s.code IN (?)', $storeViewCodes);
97+
}
9598
return $select;
9699
}
97100
}

0 commit comments

Comments
 (0)