Skip to content

Commit 3f0d6e9

Browse files
authored
Merge pull request #1700 from algolia/feat/MAGE-1113-refactor-cli
MAGE-1113 Refactor CLI for 3.15
2 parents 03b4530 + aafa0e3 commit 3f0d6e9

13 files changed

+388
-121
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Api\Builder;
4+
5+
use Algolia\AlgoliaSearch\Api\Data\IndexOptionsInterface;
6+
7+
interface EntityIndexOptionsBuilderInterface
8+
{
9+
public function buildEntityIndexOptions(int $storeId, ?bool $isTmp = false): IndexOptionsInterface;
10+
}

Console/Command/AbstractReplicaCommand.php

Lines changed: 3 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2,123 +2,11 @@
22

33
namespace Algolia\AlgoliaSearch\Console\Command;
44

5-
use Algolia\AlgoliaSearch\Service\StoreNameFetcher;
6-
use Magento\Framework\App\Area;
7-
use Magento\Framework\App\State;
8-
use Magento\Framework\Exception\LocalizedException;
9-
use Symfony\Component\Console\Command\Command;
10-
use Symfony\Component\Console\Input\InputArgument;
11-
use Symfony\Component\Console\Input\InputInterface;
12-
use Symfony\Component\Console\Output\OutputInterface;
13-
use Symfony\Component\Console\Question\ConfirmationQuestion;
14-
15-
abstract class AbstractReplicaCommand extends Command
5+
abstract class AbstractReplicaCommand extends AbstractStoreCommand
166
{
17-
protected const STORE_ARGUMENT = 'store';
18-
19-
protected ?OutputInterface $output = null;
20-
protected ?InputInterface $input = null;
21-
22-
public function __construct(
23-
protected State $state,
24-
protected StoreNameFetcher $storeNameFetcher,
25-
?string $name = null
26-
)
27-
{
28-
parent::__construct($name);
29-
}
30-
31-
abstract protected function getReplicaCommandName(): string;
32-
33-
abstract protected function getCommandDescription(): string;
34-
35-
abstract protected function getStoreArgumentDescription(): string;
36-
37-
abstract protected function getAdditionalDefinition(): array;
38-
39-
/**
40-
* @inheritDoc
41-
*/
42-
protected function configure(): void
43-
{
44-
$definition = [$this->getStoreArgumentDefinition()];
45-
$definition = array_merge($definition, $this->getAdditionalDefinition());
46-
47-
$this->setName($this->getCommandName())
48-
->setDescription($this->getCommandDescription())
49-
->setDefinition($definition);
50-
51-
parent::configure();
52-
}
53-
54-
protected function getStoreArgumentDefinition(): InputArgument {
55-
return new InputArgument(
56-
self::STORE_ARGUMENT,
57-
InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
58-
$this->getStoreArgumentDescription()
59-
);
60-
}
61-
62-
public function getCommandName(): string
63-
{
64-
return 'algolia:replicas:' . $this->getReplicaCommandName();
65-
}
66-
67-
protected function setAreaCode(): void
68-
{
69-
try {
70-
$this->state->setAreaCode(Area::AREA_CRONTAB);
71-
} catch (LocalizedException) {
72-
// Area code is already set - nothing to do
73-
}
74-
}
75-
76-
/**
77-
* @param InputInterface $input
78-
* @return int[]
79-
*/
80-
protected function getStoreIds(InputInterface $input): array
81-
{
82-
return (array) $input->getArgument(self::STORE_ARGUMENT);
83-
}
84-
85-
/**
86-
* @param int[] $storeIds
87-
* @return string
88-
*/
89-
protected function getOperationTargetLabel(array $storeIds): string
90-
{
91-
return ($storeIds ? count($storeIds) : 'all') . ' store' . (!$storeIds || count($storeIds) > 1 ? 's' : '');
92-
}
93-
94-
/**
95-
* Generate a CLI operation announcement based on passed store arguments
96-
* @param string $msg Use {{target} in message as a placeholder for inserting the generated target label
97-
* @param int[] $storeIds
98-
* @return string
99-
*/
100-
protected function decorateOperationAnnouncementMessage(string $msg, array $storeIds): string
7+
protected function getCommandPrefix(): string
1018
{
102-
$msg = str_replace('{{target}}', $this->getOperationTargetLabel($storeIds), $msg);
103-
return ($storeIds)
104-
? "<info>$msg: " . join(", ", $this->storeNameFetcher->getStoreNames($storeIds)) . '</info>'
105-
: "<info>$msg</info>";
9+
return parent::getCommandPrefix() . 'replicas:';
10610
}
10711

108-
protected function confirmOperation(string $okMessage = '', string $cancelMessage = 'Operation cancelled'): bool
109-
{
110-
$helper = $this->getHelper('question');
111-
$question = new ConfirmationQuestion('<question>Are you sure wish to proceed? (y/n)</question> ', false);
112-
if (!$helper->ask($this->input, $this->output, $question)) {
113-
if ($cancelMessage) {
114-
$this->output->writeln("<comment>$cancelMessage</comment>");
115-
}
116-
return false;
117-
}
118-
119-
if ($okMessage) {
120-
$this->output->writeln("<comment>$okMessage</comment>");
121-
}
122-
return true;
123-
}
12412
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Console\Command;
4+
5+
use Algolia\AlgoliaSearch\Service\StoreNameFetcher;
6+
use Magento\Framework\App\Area;
7+
use Magento\Framework\App\State;
8+
use Magento\Framework\Exception\LocalizedException;
9+
use Magento\Framework\Exception\NoSuchEntityException;
10+
use Symfony\Component\Console\Command\Command;
11+
use Symfony\Component\Console\Input\InputArgument;
12+
use Symfony\Component\Console\Input\InputInterface;
13+
use Symfony\Component\Console\Output\OutputInterface;
14+
use Symfony\Component\Console\Question\ConfirmationQuestion;
15+
16+
abstract class AbstractStoreCommand extends Command
17+
{
18+
protected const STORE_ARGUMENT = 'store_id';
19+
20+
protected ?OutputInterface $output = null;
21+
protected ?InputInterface $input = null;
22+
23+
abstract protected function getCommandName(): string;
24+
abstract protected function getCommandDescription(): string;
25+
abstract protected function getAdditionalDefinition(): array;
26+
abstract protected function getStoreArgumentDescription(): string;
27+
28+
public function __construct(
29+
protected State $state,
30+
protected StoreNameFetcher $storeNameFetcher,
31+
?string $name = null
32+
)
33+
{
34+
parent::__construct($name);
35+
}
36+
37+
protected function getCommandPrefix(): string
38+
{
39+
return 'algolia:';
40+
}
41+
42+
protected function getFullCommandName(): string
43+
{
44+
return $this->getCommandPrefix() . $this->getCommandName();
45+
}
46+
47+
/**
48+
* @inheritDoc
49+
*/
50+
protected function configure(): void
51+
{
52+
$definition = [$this->getStoreArgumentDefinition()];
53+
$definition = array_merge($definition, $this->getAdditionalDefinition());
54+
55+
$this->setName($this->getFullCommandName())
56+
->setDescription($this->getCommandDescription())
57+
->setDefinition($definition);
58+
59+
parent::configure();
60+
}
61+
62+
protected function setAreaCode(): void
63+
{
64+
try {
65+
$this->state->setAreaCode(Area::AREA_CRONTAB);
66+
} catch (LocalizedException $e) {
67+
// Area code is already set - nothing to do - but report regardless
68+
$this->output->writeln("Unable to set area code due to the following error: " . $e->getMessage());
69+
}
70+
}
71+
72+
/**
73+
* @param InputInterface $input
74+
* @return int[]
75+
* @throws LocalizedException
76+
*/
77+
protected function getStoreIds(InputInterface $input): array
78+
{
79+
return $this->validateStoreIds((array) $input->getArgument(self::STORE_ARGUMENT));
80+
}
81+
82+
/**
83+
* @param array $storeIds
84+
* @return int[]
85+
* @throws LocalizedException
86+
*/
87+
protected function validateStoreIds(array $storeIds): array
88+
{
89+
foreach ($storeIds as $storeId) {
90+
if (!ctype_digit($storeId) || (int) $storeId < 1) {
91+
throw new LocalizedException(__("Store ID argument must be an integer"));
92+
}
93+
}
94+
95+
return array_map('intval', $storeIds);
96+
}
97+
98+
protected function getStoreArgumentDefinition(): InputArgument {
99+
return new InputArgument(
100+
self::STORE_ARGUMENT,
101+
InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
102+
$this->getStoreArgumentDescription()
103+
);
104+
}
105+
106+
/**
107+
* @param int[] $storeIds
108+
* @return string
109+
*/
110+
protected function getOperationTargetLabel(array $storeIds): string
111+
{
112+
return ($storeIds ? count($storeIds) : 'all') . ' store' . (!$storeIds || count($storeIds) > 1 ? 's' : '');
113+
}
114+
115+
/**
116+
* Generate a CLI operation announcement based on passed store arguments
117+
* @param string $msg Use {{target} in message as a placeholder for inserting the generated target label
118+
* @param int[] $storeIds
119+
* @return string
120+
* @throws NoSuchEntityException
121+
*/
122+
protected function decorateOperationAnnouncementMessage(string $msg, array $storeIds): string
123+
{
124+
$msg = str_replace('{{target}}', $this->getOperationTargetLabel($storeIds), $msg);
125+
return ($storeIds)
126+
? "<info>$msg: " . join(", ", $this->storeNameFetcher->getStoreNames($storeIds)) . '</info>'
127+
: "<info>$msg</info>";
128+
}
129+
130+
protected function confirmOperation(string $okMessage = '', string $cancelMessage = 'Operation cancelled'): bool
131+
{
132+
$helper = $this->getHelper('question');
133+
$question = new ConfirmationQuestion('<question>Are you sure wish to proceed? (y/n)</question> ', false);
134+
if (!$helper->ask($this->input, $this->output, $question)) {
135+
if ($cancelMessage) {
136+
$this->output->writeln("<comment>$cancelMessage</comment>");
137+
}
138+
return false;
139+
}
140+
141+
if ($okMessage) {
142+
$this->output->writeln("<comment>$okMessage</comment>");
143+
}
144+
return true;
145+
}
146+
}

Console/Command/ReplicaDeleteCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function __construct(
3333
parent::__construct($state, $storeNameFetcher, $name);
3434
}
3535

36-
protected function getReplicaCommandName(): string
36+
protected function getCommandName(): string
3737
{
3838
return 'delete';
3939
}

Console/Command/ReplicaDisableVirtualCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function __construct(
4242
parent::__construct($state, $storeNameFetcher, $name);
4343
}
4444

45-
protected function getReplicaCommandName(): string
45+
protected function getCommandName(): string
4646
{
4747
return 'disable-virtual-replicas';
4848
}

Console/Command/ReplicaRebuildCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function __construct(
3838
parent::__construct($appState, $storeNameFetcher, $name);
3939
}
4040

41-
protected function getReplicaCommandName(): string
41+
protected function getCommandName(): string
4242
{
4343
return 'rebuild';
4444
}

Console/Command/ReplicaSyncCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function __construct(
3535
parent::__construct($appState, $storeNameFetcher, $name);
3636
}
3737

38-
protected function getReplicaCommandName(): string
38+
protected function getCommandName(): string
3939
{
4040
return 'sync';
4141
}

0 commit comments

Comments
 (0)