Skip to content

Commit 0b06f75

Browse files
committed
MAGE-938 Implement replica sync command with variable store ID argument
1 parent 9ba7d13 commit 0b06f75

File tree

1 file changed

+106
-8
lines changed

1 file changed

+106
-8
lines changed

Console/Command/ReplicaCommand.php

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,41 @@
33
namespace Algolia\AlgoliaSearch\Console\Command;
44

55
use Algolia\AlgoliaSearch\Api\Product\ReplicaManagerInterface;
6+
use Algolia\AlgoliaSearch\Exceptions\AlgoliaException;
7+
use Algolia\AlgoliaSearch\Exceptions\ExceededRetriesException;
8+
use Algolia\AlgoliaSearch\Helper\Entity\ProductHelper;
9+
use Magento\Framework\App\Area;
10+
use Magento\Framework\App\State;
611
use Magento\Framework\Console\Cli;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Exception\NoSuchEntityException;
14+
use Magento\Store\Model\StoreManagerInterface;
715
use Symfony\Component\Console\Command\Command;
816
use Symfony\Component\Console\Input\InputInterface;
917
use Symfony\Component\Console\Input\InputArgument;
1018
use Symfony\Component\Console\Output\OutputInterface;
1119

1220
class ReplicaCommand extends Command
1321
{
14-
const STORE_ARGUMENT = 'store';
22+
protected const STORE_ARGUMENT = 'store';
23+
24+
protected ?OutputInterface $output = null;
25+
26+
/** @var string[] */
27+
protected array $_storeNames = [];
1528

1629
/**
30+
* @param ProductHelper $productHelper
1731
* @param ReplicaManagerInterface $replicaManager
32+
* @param StoreManagerInterface $storeManager
1833
* @param string|null $name
1934
*/
2035
public function __construct(
36+
protected State $state,
37+
protected ProductHelper $productHelper,
2138
protected ReplicaManagerInterface $replicaManager,
22-
?string $name = null
39+
protected StoreManagerInterface $storeManager,
40+
?string $name = null
2341
)
2442
{
2543
parent::__construct($name);
@@ -33,25 +51,105 @@ protected function configure(): void
3351
$this->setName('algolia:replicas:sync')
3452
->setDescription('Sync configured sorting attributes in Magento to Algolia replica indices')
3553
->setDefinition([
36-
new InputArgument(self::STORE_ARGUMENT, InputArgument::OPTIONAL, 'ID for store to be synced with Algolia (optional), if not specified all stores will be synced'),
54+
new InputArgument(
55+
self::STORE_ARGUMENT,
56+
InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
57+
'ID(s) for store to be synced with Algolia (optional), if not specified all stores will be synced'
58+
)
3759
]);
3860

3961
parent::configure();
4062
}
4163

42-
/** @inheritDoc */
64+
/**
65+
* @inheritDoc
66+
* @param InputInterface $input
67+
* @param OutputInterface $output
68+
* @return int
69+
* @throws AlgoliaException
70+
* @throws ExceededRetriesException
71+
* @throws LocalizedException
72+
* @throws NoSuchEntityException
73+
*/
4374
protected function execute(InputInterface $input, OutputInterface $output): int
4475
{
45-
$storeIds = $input->getArgument(self::STORE_ARGUMENT);
76+
$storeIds = (array) $input->getArgument(self::STORE_ARGUMENT);
4677

78+
$msg = 'Syncing replicas for ' . ($storeIds ? count($storeIds) : 'all') . ' store' . (!$storeIds || count($storeIds) > 1 ? 's' : '');
4779
if ($storeIds) {
48-
$output->writeln('<info>Syncing store ' . $storeIds . '!</info>');
80+
/** @var string[] $storeNames */
81+
$storeNames = array_map(
82+
function($storeId) {
83+
return $this->getStoreName($storeId);
84+
},
85+
$storeIds
86+
);
87+
$output->writeln("<info>$msg: " . join(", ", $storeNames) . '</info>');
4988
} else {
50-
$output->writeln('<info>Syncing all stores</info>');
89+
$output->writeln("<info>$msg</info>");
5190
}
5291

53-
// $this->replicaManager->syncReplicasToAlgolia();
92+
$this->output = $output;
93+
$this->state->setAreaCode(Area::AREA_ADMINHTML);
94+
$this->syncReplicas($storeIds);
5495

5596
return Cli::RETURN_SUCCESS;
5697
}
98+
99+
/**
100+
* @throws NoSuchEntityException
101+
*/
102+
protected function getStoreName(int $storeId): string
103+
{
104+
if (!isset($this->_storeNames[$storeId])) {
105+
$this->_storeNames[$storeId] = $this->storeManager->getStore($storeId)->getName();
106+
}
107+
return $this->_storeNames[$storeId];
108+
}
109+
110+
/**
111+
* @param int[] $storeIds
112+
* @return void
113+
* @throws AlgoliaException
114+
* @throws ExceededRetriesException
115+
* @throws LocalizedException
116+
* @throws NoSuchEntityException
117+
*/
118+
protected function syncReplicas(array $storeIds = []): void
119+
{
120+
if (count($storeIds)) {
121+
foreach ($storeIds as $storeId) {
122+
$this->syncReplicasForStore($storeId);
123+
}
124+
} else {
125+
$this->syncReplicasForAllStores();
126+
}
127+
}
128+
129+
/**
130+
* @throws NoSuchEntityException
131+
* @throws ExceededRetriesException
132+
* @throws AlgoliaException
133+
* @throws LocalizedException
134+
*/
135+
protected function syncReplicasForStore(int $storeId): void
136+
{
137+
$this->output->writeln('<info>Syncing ' . $this->getStoreName($storeId) . '...</info>');
138+
$this->replicaManager->syncReplicasToAlgolia($storeId, $this->productHelper->getIndexSettings($storeId));
139+
}
140+
141+
/**
142+
* @throws NoSuchEntityException
143+
* @throws ExceededRetriesException
144+
* @throws AlgoliaException
145+
* @throws LocalizedException
146+
*/
147+
protected function syncReplicasForAllStores(): void
148+
{
149+
$storeIds = array_keys($this->storeManager->getStores());
150+
foreach ($storeIds as $storeId) {
151+
$this->syncReplicasForStore($storeId);
152+
}
153+
154+
}
57155
}

0 commit comments

Comments
 (0)