diff --git a/src/Command/MeiliSearchCreateCommand.php b/src/Command/MeiliSearchCreateCommand.php new file mode 100644 index 00000000..46c44564 --- /dev/null +++ b/src/Command/MeiliSearchCreateCommand.php @@ -0,0 +1,93 @@ +searchClient = $searchClient; + } + + protected function configure(): void + { + $this + ->setDescription('Create indexes') + ->addOption('indices', 'i', InputOption::VALUE_OPTIONAL, 'Comma-separated list of index names'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $indexes = $this->getEntitiesFromArgs($input, $output); + + foreach ($indexes as $key => $index) { + $entityClassName = $index['class']; + if (is_subclass_of($entityClassName, Aggregator::class)) { + $indexes->forget($key); + + $indexes = collect(array_merge( + $indexes->toArray(), + array_map( + static fn ($entity) => ['name' => $index['name'], 'class' => $entity], + $entityClassName::getEntities() + ) + )); + } + } + + $entitiesToIndex = array_unique($indexes->toArray(), SORT_REGULAR); + + /** @var array $index */ + foreach ($entitiesToIndex as $index) { + $entityClassName = $index['class']; + + if (!$this->searchService->isSearchable($entityClassName)) { + continue; + } + + $output->writeln('Creating index '.$index['name'].' for '.$entityClassName.''); + + $indexInstance = $this->searchClient->getOrCreateIndex($index['name']); + + if (isset($index['settings']) && is_array($index['settings'])) { + foreach ($index['settings'] as $variable => $value) { + $method = sprintf('update%s', ucfirst($variable)); + + if (false === method_exists($indexInstance, $method)) { + throw new InvalidSettingName(sprintf('Invalid setting name: "%s"', $variable)); + } + + $update = $indexInstance->{$method}($value); + + $indexInstance->waitForPendingUpdate($update['updateId']); + $updateStatus = $indexInstance->getUpdateStatus($update['updateId']); + + if ('failed' === $updateStatus['status']) { + throw new UpdateException($updateStatus['error']); + } + } + } + } + + $output->writeln('Done!'); + + return 0; + } +} diff --git a/tests/Integration/CommandsTest.php b/tests/Integration/CommandsTest.php index 84dc2cc4..dc1170c0 100644 --- a/tests/Integration/CommandsTest.php +++ b/tests/Integration/CommandsTest.php @@ -213,4 +213,42 @@ public function testImportingIndexNameWithAndWithoutPrefix(): void $this->assertStringContainsString('Done!', $output); $this->assertSame(0, $return); } + + public function testSearchCreateWithoutIndices(): void + { + $createCommand = $this->application->find('meili:create'); + $createCommandTester = new CommandTester($createCommand); + $createCommandTester->execute([]); + + $createOutput = $createCommandTester->getDisplay(); + + $this->assertSame(<<<'EOD' +Creating index sf_phpunit__posts for MeiliSearch\Bundle\Test\Entity\Post +Creating index sf_phpunit__comments for MeiliSearch\Bundle\Test\Entity\Comment +Creating index sf_phpunit__tags for MeiliSearch\Bundle\Test\Entity\Tag +Creating index sf_phpunit__tags for MeiliSearch\Bundle\Test\Entity\Link +Creating index sf_phpunit__pages for MeiliSearch\Bundle\Test\Entity\Page +Creating index sf_phpunit__aggregated for MeiliSearch\Bundle\Test\Entity\Post +Creating index sf_phpunit__aggregated for MeiliSearch\Bundle\Test\Entity\Tag +Done! + +EOD, $createOutput); + } + + public function testSearchCreateWithIndices(): void + { + $createCommand = $this->application->find('meili:create'); + $createCommandTester = new CommandTester($createCommand); + $createCommandTester->execute([ + '--indices' => 'posts', + ]); + + $createOutput = $createCommandTester->getDisplay(); + + $this->assertSame(<<<'EOD' +Creating index sf_phpunit__posts for MeiliSearch\Bundle\Test\Entity\Post +Done! + +EOD, $createOutput); + } }