From a989d02dbaf22ffd361f3572a05a6fa329c580e0 Mon Sep 17 00:00:00 2001 From: neymir Date: Fri, 13 Dec 2024 11:22:29 +0100 Subject: [PATCH 1/4] Optimize getSpecificOptions triggered by all getAttributeText calls --- .../Model/Entity/Attribute/Source/Table.php | 65 ++++++++++++++++--- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php index b9139c6fff0ff..8b03902159e40 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php @@ -34,6 +34,13 @@ class Table extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource im */ protected $_attrOptionFactory; + /** + * Specific Options array memoization + * + * @var array + */ + protected $_specificOptions = null; + /** * @var StoreManagerInterface */ @@ -100,24 +107,66 @@ public function getAllOptions($withEmpty = true, $defaultValues = false) * Retrieve Option values array by ids * * @param string|array $ids - * @param bool $withEmpty Add empty option to array + * @param bool $withEmpty Add empty option to array + * * @return array */ public function getSpecificOptions($ids, $withEmpty = true) { - $options = $this->_attrOptionCollectionFactory->create() - ->setPositionOrder('asc') - ->setAttributeFilter($this->getAttribute()->getId()) - ->addFieldToFilter('main_table.option_id', ['in' => $ids]) - ->setStoreFilter($this->getAttribute()->getStoreId()) - ->load() - ->toOptionArray(); + $storeId = $this->getAttribute()->getStoreId(); + $attributeId = $this->getAttribute()->getId(); + $optionsIdsToLoad = []; + $options = []; + + $optionIds = is_array($ids) ? $ids : [$ids]; + + foreach ($optionIds as $optionId) { + if (empty($this->_specificOptions[$storeId][$attributeId][$optionId])) { + $optionsIdsToLoad[] = $optionId; + } else { + $options[] = $this->_specificOptions[$storeId][$attributeId][$optionId]; + } + } + + if (!empty($optionsIdsToLoad)) { + $loadedOptions = $this->loadSpecificOptions( + $attributeId, + $optionsIdsToLoad, + $storeId); + + array_walk($loadedOptions, function ($loadedOption) use ($storeId, $attributeId, &$options) { + $this->_specificOptions[$storeId][$attributeId][$loadedOption['value']] = $loadedOption; + $options[] = $loadedOption; + }); + } + if ($withEmpty) { $options = $this->addEmptyOption($options); } + return $options; } + /** + * @param mixed $attributeId + * @param array $optionsIdsToLoad + * @param $storeId + * + * @return array + */ + protected function loadSpecificOptions(mixed $attributeId, array $optionsIdsToLoad, $storeId): array + { + return $this->_attrOptionCollectionFactory->create() + ->setPositionOrder('asc') + ->setAttributeFilter($attributeId) + ->addFieldToFilter( + 'main_table.option_id', + ['in' => $optionsIdsToLoad]) + ->setStoreFilter($storeId) + ->load() + ->toOptionArray(); + } + /** * Add an empty option to the array * From 557b6de65e3ed8169d16cd191ee825df8fd64db5 Mon Sep 17 00:00:00 2001 From: neymir Date: Sat, 14 Dec 2024 16:40:14 +0100 Subject: [PATCH 2/4] fix: If only one option, then addFieldToFilter with string instead of array. This way PHPUnit don't see the difference. --- app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php index 8b03902159e40..a2432ab5cad6d 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php @@ -161,7 +161,7 @@ protected function loadSpecificOptions(mixed $attributeId, array $optionsIdsToLo ->setAttributeFilter($attributeId) ->addFieldToFilter( 'main_table.option_id', - ['in' => $optionsIdsToLoad]) + ['in' => (count($optionsIdsToLoad)>1)?$optionsIdsToLoad:$optionsIdsToLoad[0]]) ->setStoreFilter($storeId) ->load() ->toOptionArray(); From be31de8714f6750c76f96d9ab5eaa5d00a28145b Mon Sep 17 00:00:00 2001 From: neymir Date: Mon, 16 Dec 2024 17:02:19 +0100 Subject: [PATCH 3/4] chore: PHPCs fixes --- .../Model/Entity/Attribute/Source/Table.php | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php index a2432ab5cad6d..f9e099659570e 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php @@ -132,7 +132,8 @@ public function getSpecificOptions($ids, $withEmpty = true) $loadedOptions = $this->loadSpecificOptions( $attributeId, $optionsIdsToLoad, - $storeId); + $storeId + ); array_walk($loadedOptions, function ($loadedOption) use ($storeId, $attributeId, &$options) { $this->_specificOptions[$storeId][$attributeId][$loadedOption['value']] = $loadedOption; @@ -148,23 +149,26 @@ public function getSpecificOptions($ids, $withEmpty = true) } /** + * Load specific option in DB + * * @param mixed $attributeId * @param array $optionsIdsToLoad - * @param $storeId + * @param int $storeId * * @return array */ - protected function loadSpecificOptions(mixed $attributeId, array $optionsIdsToLoad, $storeId): array + protected function loadSpecificOptions(mixed $attributeId, array $optionsIdsToLoad, int $storeId): array { return $this->_attrOptionCollectionFactory->create() - ->setPositionOrder('asc') - ->setAttributeFilter($attributeId) - ->addFieldToFilter( - 'main_table.option_id', - ['in' => (count($optionsIdsToLoad)>1)?$optionsIdsToLoad:$optionsIdsToLoad[0]]) - ->setStoreFilter($storeId) - ->load() - ->toOptionArray(); + ->setPositionOrder('asc') + ->setAttributeFilter($attributeId) + ->addFieldToFilter( + 'main_table.option_id', + ['in' => (count($optionsIdsToLoad)>1)?$optionsIdsToLoad:$optionsIdsToLoad[0]] + ) + ->setStoreFilter($storeId) + ->load() + ->toOptionArray(); } /** From c84d372942c7bfe9b35ed72be07f94966e07386a Mon Sep 17 00:00:00 2001 From: engcom-Charlie Date: Mon, 3 Feb 2025 20:26:54 +0530 Subject: [PATCH 4/4] Updated copyright, fixed static test --- app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php index 8a33e8efe1e81..848b765e77088 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/Table.php @@ -1,7 +1,7 @@