Skip to content

Commit a3a41bf

Browse files
committed
MAGE-941 Separate sorting transformation operations from god class to make more composable
1 parent 8d542e2 commit a3a41bf

File tree

6 files changed

+308
-194
lines changed

6 files changed

+308
-194
lines changed

Block/Algolia.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Algolia\AlgoliaSearch\Helper\Entity\SuggestionHelper;
1212
use Algolia\AlgoliaSearch\Helper\LandingPageHelper;
1313
use Algolia\AlgoliaSearch\Registry\CurrentCategory;
14+
use Algolia\AlgoliaSearch\Service\Product\SortingTransformer;
1415
use Magento\Catalog\Model\Product;
1516
use Magento\Checkout\Model\Session as CheckoutSession;
1617
use Magento\Customer\Model\Context as CustomerContext;
@@ -24,6 +25,7 @@
2425
use Magento\Framework\Stdlib\DateTime\DateTime;
2526
use Magento\Framework\Url\Helper\Data;
2627
use Magento\Framework\View\Element\Template;
28+
use Magento\Framework\View\Element\Template\Context;
2729
use Magento\Sales\Model\Order;
2830
use Magento\Search\Helper\Data as CatalogSearchHelper;
2931

@@ -104,7 +106,8 @@ class Algolia extends Template implements CollectionDataSourceInterface
104106
protected $priceKey;
105107

106108
/**
107-
* @param Template\Context $context
109+
* @param SortingTransformer $sortingTransformer
110+
* @param Context $context
108111
* @param ConfigHelper $config
109112
* @param CatalogSearchHelper $catalogSearchHelper
110113
* @param ProductHelper $productHelper
@@ -122,9 +125,11 @@ class Algolia extends Template implements CollectionDataSourceInterface
122125
* @param PersonalizationHelper $personalizationHelper
123126
* @param CheckoutSession $checkoutSession
124127
* @param DateTime $date
128+
* @param CurrentCategory $currentCategory
125129
* @param array $data
126130
*/
127131
public function __construct(
132+
protected SortingTransformer $sortingTransformer,
128133
Template\Context $context,
129134
ConfigHelper $config,
130135
CatalogSearchHelper $catalogSearchHelper,

Block/Configuration.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
class Configuration extends Algolia implements CollectionDataSourceInterface
1212
{
13-
//Placeholder for future implementation (requires customer renderer for hierarchicalMenu widget)
13+
//Placeholder for future implementation (requires custom renderer for hierarchicalMenu widget)
1414
private const IS_CATEGORY_NAVIGATION_ENABLED = false;
1515

1616
public function isSearchPage()
@@ -255,9 +255,8 @@ public function getConfiguration()
255255
'facets' => $facets,
256256
'areCategoriesInFacets' => $areCategoriesInFacets,
257257
'hitsPerPage' => (int) $config->getNumberOfProductResults(),
258-
'sortingIndices' => array_values($config->getSortingIndices(
258+
'sortingIndices' => array_values($this->sortingTransformer->getSortingIndices(
259259
$this->getStoreId(),
260-
null,
261260
$customerGroupId
262261
)),
263262
'isSearchPage' => $this->isSearchPage(),

Helper/ConfigHelper.php

Lines changed: 72 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,17 @@
33
namespace Algolia\AlgoliaSearch\Helper;
44

55
use Algolia\AlgoliaSearch\Api\Product\ReplicaManagerInterface;
6-
use Algolia\AlgoliaSearch\Service\IndexNameFetcher;
76
use Magento;
87
use Magento\Cookie\Helper\Cookie as CookieHelper;
9-
use Magento\Customer\Api\GroupExcludedWebsiteRepositoryInterface;
10-
use Magento\Customer\Model\ResourceModel\Group\Collection as GroupCollection;
118
use Magento\Directory\Model\Currency as DirCurrency;
129
use Magento\Framework\App\Filesystem\DirectoryList;
1310
use Magento\Framework\DataObject;
14-
use Magento\Framework\Exception\LocalizedException;
15-
use Magento\Framework\Exception\NoSuchEntityException;
1611
use Magento\Framework\Locale\Currency;
1712
use Magento\Framework\Serialize\SerializerInterface;
1813
use Magento\Store\Model\ScopeInterface;
1914
use Magento\Store\Model\StoreManagerInterface;
15+
use Magento\Customer\Api\GroupExcludedWebsiteRepositoryInterface;
16+
use Magento\Customer\Model\ResourceModel\Group\Collection as GroupCollection;
2017

2118
class ConfigHelper
2219
{
@@ -155,26 +152,6 @@ class ConfigHelper
155152
public const NUMBER_OF_ELEMENT_BY_PAGE = 'algoliasearch_advanced/queue/number_of_element_by_page';
156153
public const ARCHIVE_LOG_CLEAR_LIMIT = 'algoliasearch_advanced/queue/archive_clear_limit';
157154

158-
/**
159-
* @var array<int,<array<string, mixed>>>
160-
*/
161-
protected array $_sortingIndices = [];
162-
163-
/**
164-
* @param Magento\Framework\App\Config\ScopeConfigInterface $configInterface
165-
* @param StoreManagerInterface $storeManager
166-
* @param Currency $currency
167-
* @param DirCurrency $dirCurrency
168-
* @param DirectoryList $directoryList
169-
* @param Magento\Framework\Module\ResourceInterface $moduleResource
170-
* @param Magento\Framework\App\ProductMetadataInterface $productMetadata
171-
* @param Magento\Framework\Event\ManagerInterface $eventManager
172-
* @param SerializerInterface $serializer
173-
* @param GroupCollection $groupCollection
174-
* @param GroupExcludedWebsiteRepositoryInterface $groupExcludedWebsiteRepository
175-
* @param CookieHelper $cookieHelper
176-
177-
*/
178155
public function __construct(
179156
protected Magento\Framework\App\Config\ScopeConfigInterface $configInterface,
180157
protected Magento\Framework\App\Config\Storage\WriterInterface $configWriter,
@@ -189,7 +166,6 @@ public function __construct(
189166
protected GroupCollection $groupCollection,
190167
protected GroupExcludedWebsiteRepositoryInterface $groupExcludedWebsiteRepository,
191168
protected CookieHelper $cookieHelper,
192-
protected IndexNameFetcher $indexNameFetcher
193169
)
194170
{}
195171

@@ -1034,160 +1010,106 @@ public function getAutocompleteMinimumCharacterLength($storeId = null): int
10341010
}
10351011

10361012
/**
1037-
* When group pricing is enabled a replica must be created for each possible sort
1038-
*
1039-
* @param string $originalIndexName
1040-
* @param int $customerGroupId
1041-
* @param string $currency
1042-
* @param array $origAttr
1013+
* @param $originalIndexName
1014+
* @param $storeId
1015+
* @param $currentCustomerGroupId
1016+
* @param $attrs
10431017
* @return array
1018+
* @throws Magento\Framework\Exception\LocalizedException
1019+
* @throws Magento\Framework\Exception\NoSuchEntityException
1020+
* @deprecated This method has been deprecated and should no longer be used
1021+
* @see \Algolia\AlgoliaSearch\Service\Product\SortingTransformer
10441022
*/
1045-
protected function getCustomerGroupSortPriceOverride(
1046-
string $originalIndexName,
1047-
int $customerGroupId,
1048-
string $currency,
1049-
array $origAttr): array
1050-
{
1051-
$attrName = $origAttr['attribute'];
1052-
$sortDir = $origAttr['sort'];
1053-
$groupIndexNameSuffix = 'group_' . $customerGroupId;
1054-
$groupIndexName = $originalIndexName . '_' . $attrName . '_' . $groupIndexNameSuffix . '_' . $sortDir;
1055-
1056-
$newAttr = array_merge(
1057-
$origAttr,
1058-
['name' => $groupIndexName]
1059-
);
1060-
1061-
$groupSortAttribute = $attrName . '.' . $currency . '.' . $groupIndexNameSuffix;
1062-
$newAttr['ranking'] = $this->getSortAttributingRankingSetting($groupSortAttribute, $sortDir);
1063-
return $this->decorateSortAttribute($newAttr);
1064-
}
1065-
1066-
/*
1067-
* Add data to the sort attribute object
1068-
*/
1069-
protected function decorateSortAttribute(array $attr): array {
1070-
if (!array_key_exists('label', $attr) && array_key_exists('sortLabel', $attr)) {
1071-
$attr['label'] = $attr['sortLabel'];
1072-
}
1073-
return $attr;
1074-
}
1075-
1076-
/**
1077-
* Get ranking setting to be used for the standard sorting replica
1078-
* @param string $attrName
1079-
* @param string $sortDir
1080-
* @return string[]
1081-
*/
1082-
protected function getSortAttributingRankingSetting(string $attrName, string $sortDir): array
1083-
{
1084-
return [
1085-
$sortDir . '(' . $attrName . ')',
1086-
'typo',
1087-
'geo',
1088-
'words',
1089-
'filters',
1090-
'proximity',
1091-
'attribute',
1092-
'exact',
1093-
'custom',
1094-
];
1095-
}
1096-
1097-
/**
1098-
* @throws LocalizedException
1099-
*/
1100-
protected function isGroupPricingExcludedFromWebsite(int $customerGroupId, int $websiteId): bool
1023+
public function getSortingIndices($originalIndexName, $storeId = null, $currentCustomerGroupId = null, $attrs = null)
11011024
{
1102-
$excludedWebsites = $this->groupExcludedWebsiteRepository->getCustomerGroupExcludedWebsites($customerGroupId);
1103-
return in_array($websiteId, $excludedWebsites);
1104-
}
1105-
1106-
/**
1107-
* Augment sorting configuration with corresponding replica indices, ranking,
1108-
* and (as needed) customer group pricing
1109-
*
1110-
* @param ?int $storeId
1111-
* @param ?int $currentCustomerGroupId
1112-
* @param ?array $attrs - serialized array of sorting attributes to transform (defaults to saved sorting config)
1113-
* @return array of transformed sorting / replica objects
1114-
* @throws LocalizedException
1115-
* @throws NoSuchEntityException
1116-
*/
1117-
public function getSortingIndices(
1118-
?int $storeId = null,
1119-
?int $currentCustomerGroupId = null,
1120-
?array $attrs = null
1121-
): array
1122-
{
1123-
// Selectively cache this result - only cache manipulation of saved settings per store
1124-
$useCache = is_null($currentCustomerGroupId) && is_null($attrs);
1125-
1126-
if ($useCache
1127-
&& array_key_exists($storeId, $this->_sortingIndices)
1128-
&& is_array($this->_sortingIndices[$storeId])) {
1129-
return $this->_sortingIndices[$storeId];
1130-
}
1131-
1132-
// If no sorting configuration is supplied - obtain from the saved configuration
1133-
if (!$attrs) {
1025+
if (!$attrs){
11341026
$attrs = $this->getSorting($storeId);
11351027
}
11361028

1137-
$primaryIndexName = $this->indexNameFetcher->getProductIndexName($storeId);
11381029
$currency = $this->getCurrencyCode($storeId);
11391030
$attributesToAdd = [];
11401031
foreach ($attrs as $key => $attr) {
11411032
$indexName = false;
11421033
$sortAttribute = false;
1143-
// Group pricing
1144-
if ($this->isCustomerGroupsEnabled($storeId) && $attr[ReplicaManagerInterface::SORT_KEY_ATTRIBUTE_NAME] === ReplicaManagerInterface::SORT_ATTRIBUTE_PRICE) {
1145-
$websiteId = (int) $this->storeManager->getStore($storeId)->getWebsiteId();
1034+
if ($this->isCustomerGroupsEnabled($storeId) && $attr['attribute'] === 'price') {
1035+
$websiteId = (int)$this->storeManager->getStore($storeId)->getWebsiteId();
11461036
$groupCollection = $this->groupCollection;
11471037
if (!is_null($currentCustomerGroupId)) {
11481038
$groupCollection->addFilter('customer_group_id', $currentCustomerGroupId);
11491039
}
11501040
foreach ($groupCollection as $group) {
1151-
$customerGroupId = (int) $group->getData('customer_group_id');
1152-
if (!$this->isGroupPricingExcludedFromWebsite($customerGroupId, $websiteId)) {
1153-
$newAttr = $this->getCustomerGroupSortPriceOverride($primaryIndexName, $customerGroupId, $currency, $attr);;
1154-
$attributesToAdd[$newAttr['sort']][] = $this->decorateSortAttribute($newAttr);
1041+
$customerGroupId = (int)$group->getData('customer_group_id');
1042+
$excludedWebsites = $this->groupExcludedWebsiteRepository->getCustomerGroupExcludedWebsites($customerGroupId);
1043+
if (in_array($websiteId, $excludedWebsites)) {
1044+
continue;
11551045
}
1046+
$groupIndexNameSuffix = 'group_' . $customerGroupId;
1047+
$groupIndexName =
1048+
$originalIndexName . '_' . $attr['attribute'] . '_' . $groupIndexNameSuffix . '_' . $attr['sort'];
1049+
$groupSortAttribute = $attr['attribute'] . '.' . $currency . '.' . $groupIndexNameSuffix;
1050+
$newAttr = [];
1051+
$newAttr['name'] = $groupIndexName;
1052+
$newAttr['attribute'] = $attr['attribute'];
1053+
$newAttr['sort'] = $attr['sort'];
1054+
$newAttr['sortLabel'] = $attr['sortLabel'];
1055+
if (!array_key_exists('label', $newAttr) && array_key_exists('sortLabel', $newAttr)) {
1056+
$newAttr['label'] = $newAttr['sortLabel'];
1057+
}
1058+
$newAttr['ranking'] = [
1059+
$newAttr['sort'] . '(' . $groupSortAttribute . ')',
1060+
'typo',
1061+
'geo',
1062+
'words',
1063+
'filters',
1064+
'proximity',
1065+
'attribute',
1066+
'exact',
1067+
'custom',
1068+
];
1069+
$attributesToAdd[$newAttr['sort']][] = $newAttr;
11561070
}
1157-
// Regular pricing
1158-
} elseif ($attr[ReplicaManagerInterface::SORT_KEY_ATTRIBUTE_NAME] === ReplicaManagerInterface::SORT_ATTRIBUTE_PRICE) {
1159-
$indexName = $primaryIndexName . '_' . $attr['attribute'] . '_' . 'default' . '_' . $attr['sort'];
1071+
} elseif ($attr['attribute'] === 'price') {
1072+
$indexName = $originalIndexName . '_' . $attr['attribute'] . '_' . 'default' . '_' . $attr['sort'];
11601073
$sortAttribute = $attr['attribute'] . '.' . $currency . '.' . 'default';
1161-
// All other sort attributes
11621074
} else {
1163-
$indexName = $primaryIndexName . '_' . $attr['attribute'] . '_' . $attr['sort'];
1075+
$indexName = $originalIndexName . '_' . $attr['attribute'] . '_' . $attr['sort'];
11641076
$sortAttribute = $attr['attribute'];
11651077
}
1166-
1167-
// Decorate all non group pricing attributes
11681078
if ($indexName && $sortAttribute) {
11691079
$attrs[$key]['name'] = $indexName;
1170-
$attrs[$key]['ranking'] = $this->getSortAttributingRankingSetting($sortAttribute, $attr['sort']);
1171-
$attrs[$key] = $this->decorateSortAttribute($attrs[$key]);
1080+
if (!array_key_exists('label', $attrs[$key]) && array_key_exists('sortLabel', $attrs[$key])) {
1081+
$attrs[$key]['label'] = $attrs[$key]['sortLabel'];
1082+
}
1083+
$attrs[$key]['ranking'] = [
1084+
$attr['sort'] . '(' . $sortAttribute . ')',
1085+
'typo',
1086+
'geo',
1087+
'words',
1088+
'filters',
1089+
'proximity',
1090+
'attribute',
1091+
'exact',
1092+
'custom',
1093+
];
11721094
}
11731095
}
11741096
$attrsToReturn = [];
1175-
1176-
foreach ($attrs as $attr) {
1177-
if ($attr[ReplicaManagerInterface::SORT_KEY_ATTRIBUTE_NAME] == ReplicaManagerInterface::SORT_ATTRIBUTE_PRICE
1178-
&& count($attributesToAdd)
1179-
&& isset($attributesToAdd[$attr['sort']])) {
1180-
$attrsToReturn = array_merge($attrsToReturn, $attributesToAdd[$attr['sort']]);
1181-
} else {
1182-
$attrsToReturn[] = $attr;
1097+
if (count($attributesToAdd) > 0) {
1098+
foreach ($attrs as $key => $attr) {
1099+
if ($attr['attribute'] == 'price' && isset($attributesToAdd[$attr['sort']])) {
1100+
$attrsToReturn = array_merge($attrsToReturn, $attributesToAdd[$attr['sort']]);
1101+
} else {
1102+
$attrsToReturn[] = $attr;
1103+
}
11831104
}
11841105
}
1185-
1186-
if ($useCache) {
1187-
$this->_sortingIndices[$storeId] = $attrsToReturn;
1106+
if (count($attrsToReturn) > 0) {
1107+
return $attrsToReturn;
11881108
}
1189-
1190-
return $attrsToReturn;
1109+
if (is_array($attrs)) {
1110+
return $attrs;
1111+
}
1112+
return [];
11911113
}
11921114

11931115
/***

Helper/Entity/ProductHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,7 @@ function($sort) {
14091409
*/
14101410
public function handlingReplica(string $indexName, int $storeId, array|bool $sortingAttribute = false): void
14111411
{
1412-
$sortingIndices = $this->configHelper->getSortingIndices($storeId, null, $sortingAttribute);
1412+
$sortingIndices = $this->configHelper->getSortingIndices($indexName, $storeId, null, $sortingAttribute);
14131413
if ($this->configHelper->isInstantEnabled($storeId)) {
14141414
$newReplicas = $this->decorateReplicasSetting($sortingIndices);
14151415

0 commit comments

Comments
 (0)