Skip to content

Commit f96307c

Browse files
committed
Add command to update settings
1 parent c4a48cd commit f96307c

File tree

4 files changed

+180
-2
lines changed

4 files changed

+180
-2
lines changed

config/services.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@
7878
<tag name="console.command" />
7979
</service>
8080

81+
<service id="Meilisearch\Bundle\Command\MeilisearchUpdateSettingsCommand">
82+
<argument type="service" id="meilisearch.service" />
83+
<argument type="service" id="meilisearch.settings_updater" />
84+
<argument type="service" id="event_dispatcher" />
85+
<tag name="console.command" />
86+
</service>
87+
8188
<service id="Meilisearch\Bundle\Services\UnixTimestampNormalizer">
8289
<tag name="serializer.normalizer" />
8390
</service>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Meilisearch\Bundle\Command;
6+
7+
use Meilisearch\Bundle\Collection;
8+
use Meilisearch\Bundle\EventListener\ConsoleOutputSubscriber;
9+
use Meilisearch\Bundle\Model\Aggregator;
10+
use Meilisearch\Bundle\SearchService;
11+
use Meilisearch\Bundle\Services\SettingsUpdater;
12+
use Symfony\Component\Console\Input\InputInterface;
13+
use Symfony\Component\Console\Input\InputOption;
14+
use Symfony\Component\Console\Output\OutputInterface;
15+
use Symfony\Component\Console\Style\SymfonyStyle;
16+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17+
18+
final class MeilisearchUpdateSettingsCommand extends IndexCommand
19+
{
20+
private SettingsUpdater $settingsUpdater;
21+
private EventDispatcherInterface $eventDispatcher;
22+
23+
public function __construct(SearchService $searchService, SettingsUpdater $settingsUpdater, EventDispatcherInterface $eventDispatcher)
24+
{
25+
parent::__construct($searchService);
26+
27+
$this->settingsUpdater = $settingsUpdater;
28+
$this->eventDispatcher = $eventDispatcher;
29+
}
30+
31+
public static function getDefaultName(): string
32+
{
33+
return 'meilisearch:update-settings';
34+
}
35+
36+
public static function getDefaultDescription(): string
37+
{
38+
return 'Push settings to meilisearch';
39+
}
40+
41+
protected function configure(): void
42+
{
43+
$this
44+
->setDescription(self::getDefaultDescription())
45+
->addOption('indices', 'i', InputOption::VALUE_OPTIONAL, 'Comma-separated list of index names')
46+
->addOption(
47+
'response-timeout',
48+
't',
49+
InputOption::VALUE_REQUIRED,
50+
'Timeout (in ms) to get response from the search engine',
51+
self::DEFAULT_RESPONSE_TIMEOUT
52+
)
53+
;
54+
}
55+
56+
protected function execute(InputInterface $input, OutputInterface $output): int
57+
{
58+
$this->eventDispatcher->addSubscriber(new ConsoleOutputSubscriber(new SymfonyStyle($input, $output)));
59+
60+
$indexes = $this->getEntitiesFromArgs($input, $output);
61+
$entitiesToIndex = $this->entitiesToIndex($indexes);
62+
$responseTimeout = ((int) $input->getOption('response-timeout')) ?: self::DEFAULT_RESPONSE_TIMEOUT;
63+
64+
/** @var array $index */
65+
foreach ($entitiesToIndex as $index) {
66+
$entityClassName = $index['class'];
67+
68+
if (!$this->searchService->isSearchable($entityClassName)) {
69+
continue;
70+
}
71+
72+
$this->settingsUpdater->update($index['prefixed_name'], $responseTimeout);
73+
}
74+
75+
$output->writeln('<info>Done!</info>');
76+
77+
return 0;
78+
}
79+
80+
private function entitiesToIndex($indexes): array
81+
{
82+
foreach ($indexes as $key => $index) {
83+
$entityClassName = $index['class'];
84+
85+
if (!is_subclass_of($entityClassName, Aggregator::class)) {
86+
continue;
87+
}
88+
89+
$indexes->forget($key);
90+
91+
$indexes = new Collection(array_merge(
92+
$indexes->all(),
93+
array_map(
94+
static fn ($entity) => ['name' => $index['name'], 'prefixed_name' => $index['prefixed_name'], 'class' => $entity],
95+
$entityClassName::getEntities()
96+
)
97+
));
98+
}
99+
100+
return array_unique($indexes->all(), SORT_REGULAR);
101+
}
102+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Meilisearch\Bundle\Tests\Integration\Command;
6+
7+
use Meilisearch\Bundle\Tests\BaseKernelTestCase;
8+
use Symfony\Bundle\FrameworkBundle\Console\Application;
9+
use Symfony\Component\Console\Tester\CommandTester;
10+
11+
final class MeilisearchUpdateSettingsCommandTest extends BaseKernelTestCase
12+
{
13+
private Application $application;
14+
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
18+
19+
$this->application = new Application(self::createKernel());
20+
}
21+
22+
public function testWithoutIndices(): void
23+
{
24+
for ($i = 0; $i <= 5; ++$i) {
25+
$this->createPost();
26+
}
27+
28+
$importCommand = $this->application->find('meilisearch:update-settings');
29+
$importCommandTester = new CommandTester($importCommand);
30+
$importCommandTester->execute([]);
31+
32+
$importOutput = $importCommandTester->getDisplay();
33+
34+
$this->assertSame(<<<'EOD'
35+
Setting "stopWords" updated of "sf_phpunit__posts".
36+
Setting "filterableAttributes" updated of "sf_phpunit__posts".
37+
Setting "searchCutoffMs" updated of "sf_phpunit__posts".
38+
Setting "typoTolerance" updated of "sf_phpunit__posts".
39+
Setting "filterableAttributes" updated of "sf_phpunit__dynamic_settings".
40+
Setting "searchableAttributes" updated of "sf_phpunit__dynamic_settings".
41+
Setting "stopWords" updated of "sf_phpunit__dynamic_settings".
42+
Setting "synonyms" updated of "sf_phpunit__dynamic_settings".
43+
Done!
44+
45+
EOD, $importOutput);
46+
}
47+
48+
public function testWithIndices(): void
49+
{
50+
for ($i = 0; $i <= 5; ++$i) {
51+
$this->createPost();
52+
}
53+
54+
$importCommand = $this->application->find('meilisearch:update-settings');
55+
$importCommandTester = new CommandTester($importCommand);
56+
$importCommandTester->execute(['--indices' => 'posts']);
57+
58+
$importOutput = $importCommandTester->getDisplay();
59+
60+
$this->assertSame(<<<'EOD'
61+
Setting "stopWords" updated of "sf_phpunit__posts".
62+
Setting "filterableAttributes" updated of "sf_phpunit__posts".
63+
Setting "searchCutoffMs" updated of "sf_phpunit__posts".
64+
Setting "typoTolerance" updated of "sf_phpunit__posts".
65+
Done!
66+
67+
EOD, $importOutput);
68+
}
69+
}

tests/Integration/SettingsTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ public function testUpdateSettings(): void
4747
$output = $commandTester->getDisplay();
4848

4949
$this->assertStringContainsString('Setting "stopWords" updated of "sf_phpunit__posts".', $output);
50-
$this->assertEquals(['a', 'an', 'the'], $settings['stopWords']);
50+
$this->assertSame(['a', 'an', 'the'], $settings['stopWords']);
5151

5252
$this->assertStringContainsString('Setting "searchCutoffMs" updated of "sf_phpunit__posts".', $output);
53-
$this->assertEquals(1500, $settings['searchCutoffMs']);
53+
$this->assertSame(1500, $settings['searchCutoffMs']);
5454

5555
$this->assertStringContainsString('Setting "filterableAttributes" updated of "sf_phpunit__posts".', $output);
5656
$this->assertSame(['publishedAt', 'title'], $settings['filterableAttributes']);

0 commit comments

Comments
 (0)