|
5 | 5 | namespace Algolia\AlgoliaSearch\Model\Product;
|
6 | 6 |
|
7 | 7 | use Algolia\AlgoliaSearch\Api\Product\ReplicaManagerInterface;
|
| 8 | +use Algolia\AlgoliaSearch\Exception\ReplicaLimitExceededException; |
| 9 | +use Algolia\AlgoliaSearch\Exception\TooManyCustomerGroupsAsReplicasException; |
8 | 10 | use Algolia\AlgoliaSearch\Exceptions\AlgoliaException;
|
9 | 11 | use Algolia\AlgoliaSearch\Helper\AlgoliaHelper;
|
10 | 12 | use Algolia\AlgoliaSearch\Helper\ConfigHelper;
|
11 | 13 | use Algolia\AlgoliaSearch\Helper\Logger;
|
| 14 | +use Algolia\AlgoliaSearch\Validator\VirtualReplicaValidatorFactory; |
12 | 15 | use Algolia\AlgoliaSearch\Registry\ReplicaState;
|
13 | 16 | use Magento\Framework\Exception\LocalizedException;
|
14 | 17 | use Magento\Framework\Exception\NoSuchEntityException;
|
@@ -37,18 +40,17 @@ class ReplicaManager implements ReplicaManagerInterface
|
37 | 40 | public const REPLICA_TRANSFORM_MODE_VIRTUAL = 2;
|
38 | 41 | public const REPLICA_TRANSFORM_MODE_ACTUAL = 3;
|
39 | 42 |
|
40 |
| - public const SORT_KEY_VIRTUAL_REPLICA = 'virtualReplica'; |
41 |
| - |
42 | 43 | protected const _DEBUG = true;
|
43 | 44 |
|
44 | 45 | protected array $_algoliaReplicaConfig = [];
|
45 | 46 | protected array $_magentoReplicaPossibleConfig = [];
|
46 | 47 |
|
47 | 48 | public function __construct(
|
48 |
| - protected ConfigHelper $configHelper, |
49 |
| - protected AlgoliaHelper $algoliaHelper, |
50 |
| - protected ReplicaState $replicaState, |
51 |
| - protected Logger $logger |
| 49 | + protected ConfigHelper $configHelper, |
| 50 | + protected AlgoliaHelper $algoliaHelper, |
| 51 | + protected ReplicaState $replicaState, |
| 52 | + protected VirtualReplicaValidatorFactory $validatorFactory, |
| 53 | + protected Logger $logger |
52 | 54 | )
|
53 | 55 | {}
|
54 | 56 |
|
@@ -167,9 +169,7 @@ function ($sort) use ($mode) {
|
167 | 169 | $replica = $sort['name'];
|
168 | 170 | if (
|
169 | 171 | $mode === self::REPLICA_TRANSFORM_MODE_VIRTUAL
|
170 |
| - || array_key_exists(self::SORT_KEY_VIRTUAL_REPLICA, $sort) |
171 |
| - && $sort[self::SORT_KEY_VIRTUAL_REPLICA] |
172 |
| - && $mode === self::REPLICA_TRANSFORM_MODE_ACTUAL |
| 172 | + || !empty($sort[self::SORT_KEY_VIRTUAL_REPLICA]) && $mode === self::REPLICA_TRANSFORM_MODE_ACTUAL |
173 | 173 | ) {
|
174 | 174 | $replica = "virtual($replica)";
|
175 | 175 | }
|
@@ -210,9 +210,10 @@ protected function getMagentoReplicaSettingsFromConfig(string $primaryIndexName,
|
210 | 210 | */
|
211 | 211 | public function handleReplicas(string $primaryIndexName, int $storeId, array $primaryIndexSettings): void
|
212 | 212 | {
|
213 |
| - // TODO: Determine if InstantSearch is a hard requirement (i.e. headless implementations may still need replicas) |
| 213 | + // TODO: InstantSearch enablement should not be a hard requirement (i.e. headless implementations may still need replicas) - add an override for this |
214 | 214 | if ($this->configHelper->isInstantEnabled($storeId)
|
215 |
| - && $this->hasReplicaConfigurationChanged($primaryIndexName, $storeId)) { |
| 215 | + && $this->hasReplicaConfigurationChanged($primaryIndexName, $storeId) |
| 216 | + && $this->isReplicaConfigurationValid($primaryIndexName, $storeId)) { |
216 | 217 | $addedReplicas = $this->setReplicasOnPrimaryIndex($primaryIndexName, $storeId);
|
217 | 218 | $this->configureRanking($primaryIndexName, $storeId, $addedReplicas, $primaryIndexSettings);
|
218 | 219 | }
|
@@ -262,6 +263,33 @@ protected function setReplicasOnPrimaryIndex(string $indexName, int $storeId): a
|
262 | 263 | return $replicasToRank;
|
263 | 264 | }
|
264 | 265 |
|
| 266 | + /** |
| 267 | + * @param string $primaryIndexName |
| 268 | + * @param int $storeId |
| 269 | + * @return bool |
| 270 | + * @throws LocalizedException |
| 271 | + * @throws NoSuchEntityException |
| 272 | + * @throws ReplicaLimitExceededException |
| 273 | + */ |
| 274 | + protected function isReplicaConfigurationValid(string $primaryIndexName, int $storeId): bool |
| 275 | + { |
| 276 | + $sortingIndices = $this->configHelper->getSortingIndices($primaryIndexName, $storeId); |
| 277 | + $validator = $this->validatorFactory->create(); |
| 278 | + if (!$validator->isReplicaConfigurationValid($sortingIndices)) { |
| 279 | + // TODO: Implement revert settings via ReplicaState |
| 280 | + if ($validator->isTooManyCustomerGroups()) { |
| 281 | + throw (new TooManyCustomerGroupsAsReplicasException("You have too many customer groups to enable virtual replicas on the pricing sort.")) |
| 282 | + ->withReplicaCount($validator->getReplicaCount()) |
| 283 | + ->withPriceSortReplicaCount($validator->getPriceSortReplicaCount()); |
| 284 | + } |
| 285 | + else { |
| 286 | + throw (new ReplicaLimitExceededException("Replica limit exceeded.")) |
| 287 | + ->withReplicaCount($validator->getReplicaCount()); |
| 288 | + } |
| 289 | + } |
| 290 | + return true; |
| 291 | + } |
| 292 | + |
265 | 293 | /**
|
266 | 294 | * @param string[] $replicas
|
267 | 295 | * @return string[]
|
@@ -316,8 +344,7 @@ function($replica) use ($replicas) {
|
316 | 344 | foreach ($replicaDetails as $replica) {
|
317 | 345 | $replicaName = $replica['name'];
|
318 | 346 | // Virtual replicas - relevant sort
|
319 |
| - if (array_key_exists(self::SORT_KEY_VIRTUAL_REPLICA, $replica) |
320 |
| - && $replica[self::SORT_KEY_VIRTUAL_REPLICA]) { |
| 347 | + if (!empty($replica[self::SORT_KEY_VIRTUAL_REPLICA])) { |
321 | 348 | $customRanking = array_key_exists('customRanking', $primaryIndexSettings)
|
322 | 349 | ? $primaryIndexSettings['customRanking']
|
323 | 350 | : [];
|
|
0 commit comments