diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 389428b..f48c8c5 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -8,9 +8,12 @@ use Setono\SyliusMeilisearchPlugin\Document\Product; use Setono\SyliusMeilisearchPlugin\Event\QueryBuilderForDataProvisionCreated; use Setono\SyliusMeilisearchPlugin\Filter\Entity\EntityFilterInterface; +use Setono\SyliusMeilisearchPlugin\Form\Type\IndexSettingsType; use Setono\SyliusMeilisearchPlugin\Form\Type\SynonymType; use Setono\SyliusMeilisearchPlugin\Indexer\DefaultIndexer; +use Setono\SyliusMeilisearchPlugin\Model\IndexSettings; use Setono\SyliusMeilisearchPlugin\Model\Synonym; +use Setono\SyliusMeilisearchPlugin\Repository\IndexSettingsRepository; use Setono\SyliusMeilisearchPlugin\Repository\SynonymRepository; use Sylius\Bundle\ResourceBundle\Controller\ResourceController; use Sylius\Component\Resource\Factory\Factory; @@ -174,6 +177,22 @@ private function addResourcesSection(ArrayNodeDefinition $node): void ->arrayNode('resources') ->addDefaultsIfNotSet() ->children() + ->arrayNode('index_settings') + ->addDefaultsIfNotSet() + ->children() + ->variableNode('options')->end() + ->arrayNode('classes') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('model')->defaultValue(IndexSettings::class)->cannotBeEmpty()->end() + ->scalarNode('controller')->defaultValue(ResourceController::class)->cannotBeEmpty()->end() + ->scalarNode('repository')->defaultValue(IndexSettingsRepository::class)->cannotBeEmpty()->end() + ->scalarNode('form')->defaultValue(IndexSettingsType::class)->end() + ->scalarNode('factory')->defaultValue(Factory::class)->end() + ->end() + ->end() + ->end() + ->end() ->arrayNode('synonym') ->addDefaultsIfNotSet() ->children() diff --git a/src/DependencyInjection/SetonoSyliusMeilisearchExtension.php b/src/DependencyInjection/SetonoSyliusMeilisearchExtension.php index 3905158..3deec14 100644 --- a/src/DependencyInjection/SetonoSyliusMeilisearchExtension.php +++ b/src/DependencyInjection/SetonoSyliusMeilisearchExtension.php @@ -121,6 +121,37 @@ public function prepend(ContainerBuilder $container): void ], ], 'grids' => [ + 'setono_sylius_meilisearch_admin_index_settings' => [ + 'driver' => [ + 'name' => SyliusResourceBundle::DRIVER_DOCTRINE_ORM, + 'options' => [ + 'class' => '%setono_sylius_meilisearch.model.index_settings.class%', + ], + ], + 'limits' => [100, 250, 500, 1000], + 'fields' => [ + 'index' => [ + 'type' => 'string', + 'label' => 'setono_sylius_meilisearch.ui.index', + ], + ], + 'filters' => [ + 'search' => [ + 'type' => 'string', + 'label' => 'sylius.ui.search', + 'options' => [ + 'fields' => ['index'], + ], + ], + ], + 'actions' => [ + 'item' => [ + 'update' => [ + 'type' => 'update', + ], + ], + ], + ], 'setono_sylius_meilisearch_admin_synonym' => [ 'driver' => [ 'name' => SyliusResourceBundle::DRIVER_DOCTRINE_ORM, diff --git a/src/EventSubscriber/AddMenuSubscriber.php b/src/EventSubscriber/AddMenuSubscriber.php index 92a42c3..082e41f 100644 --- a/src/EventSubscriber/AddMenuSubscriber.php +++ b/src/EventSubscriber/AddMenuSubscriber.php @@ -25,6 +25,14 @@ public function add(MenuBuilderEvent $event): void $header = $this->getHeader($menu); + $header + ->addChild('settings', [ + 'route' => 'setono_sylius_meilisearch_admin_index_settings_index', + ]) + ->setLabel('setono_sylius_meilisearch.menu.admin.main.meilisearch.settings') + ->setLabelAttribute('icon', 'cog') + ; + $header ->addChild('synonyms', [ 'route' => 'setono_sylius_meilisearch_admin_synonym_index', diff --git a/src/EventSubscriber/EnsureIndexSettingsAreCreatedSubscriber.php b/src/EventSubscriber/EnsureIndexSettingsAreCreatedSubscriber.php new file mode 100644 index 0000000..b25f9c9 --- /dev/null +++ b/src/EventSubscriber/EnsureIndexSettingsAreCreatedSubscriber.php @@ -0,0 +1,40 @@ + 'ensure', + ]; + } + + public function ensure(): void + { + foreach ($this->indexRegistry->getNames() as $name) { + $indexSettings = $this->indexSettingsRepository->findOneByIndex($name); + if (null !== $indexSettings) { + continue; + } + + $indexSettings = $this->indexSettingsFactory->createWithIndexName($name); + $this->indexSettingsRepository->add($indexSettings); + } + } +} diff --git a/src/Factory/IndexSettingsFactory.php b/src/Factory/IndexSettingsFactory.php new file mode 100644 index 0000000..f91fdec --- /dev/null +++ b/src/Factory/IndexSettingsFactory.php @@ -0,0 +1,34 @@ + $decorated */ + private readonly FactoryInterface $decorated, + ) { + } + + public function createNew(): IndexSettingsInterface + { + $obj = $this->decorated->createNew(); + $obj->setSettings(new Settings()); + + return $obj; + } + + public function createWithIndexName(string $index): IndexSettingsInterface + { + $obj = $this->createNew(); + $obj->setIndexName($index); + + return $obj; + } +} diff --git a/src/Factory/IndexSettingsFactoryInterface.php b/src/Factory/IndexSettingsFactoryInterface.php new file mode 100644 index 0000000..afbd16d --- /dev/null +++ b/src/Factory/IndexSettingsFactoryInterface.php @@ -0,0 +1,18 @@ + + */ +interface IndexSettingsFactoryInterface extends FactoryInterface +{ + public function createNew(): IndexSettingsInterface; + + public function createWithIndexName(string $index): IndexSettingsInterface; +} diff --git a/src/Form/Type/IndexSettingsType.php b/src/Form/Type/IndexSettingsType.php new file mode 100644 index 0000000..7d81f8a --- /dev/null +++ b/src/Form/Type/IndexSettingsType.php @@ -0,0 +1,19 @@ +add('indexName', IndexChoiceType::class) + ->add('settings', SettingsType::class) + ; + } +} diff --git a/src/Form/Type/SettingsType.php b/src/Form/Type/SettingsType.php new file mode 100644 index 0000000..3422b9e --- /dev/null +++ b/src/Form/Type/SettingsType.php @@ -0,0 +1,34 @@ +getProperties(\ReflectionProperty::IS_PUBLIC); + foreach ($properties as $property) { + $builder->add($property->getName()); + } + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Settings::class, + ]); + } + + public function getBlockPrefix(): string + { + return 'setono_sylius_meilisearch_settings'; + } +} diff --git a/src/Model/IndexSettings.php b/src/Model/IndexSettings.php new file mode 100644 index 0000000..1bbaddb --- /dev/null +++ b/src/Model/IndexSettings.php @@ -0,0 +1,47 @@ +id; + } + + public function setId(?int $id): void + { + $this->id = $id; + } + + public function getIndexName(): ?string + { + return $this->indexName; + } + + public function setIndexName(Index|string|null $indexName): void + { + $this->indexName = $indexName instanceof Index ? $indexName->name : $indexName; + } + + public function getSettings(): ?Settings + { + return $this->settings; + } + + public function setSettings(?Settings $settings): void + { + $this->settings = $settings; + } +} diff --git a/src/Model/IndexSettingsInterface.php b/src/Model/IndexSettingsInterface.php new file mode 100644 index 0000000..895e257 --- /dev/null +++ b/src/Model/IndexSettingsInterface.php @@ -0,0 +1,22 @@ +name : $index; + + $obj = $this->findOneBy(['index' => $index]); + Assert::nullOrIsInstanceOf($obj, IndexSettingsInterface::class); + + return $obj; + } +} diff --git a/src/Repository/IndexSettingsRepositoryInterface.php b/src/Repository/IndexSettingsRepositoryInterface.php new file mode 100644 index 0000000..30a85fd --- /dev/null +++ b/src/Repository/IndexSettingsRepositoryInterface.php @@ -0,0 +1,17 @@ + + */ +interface IndexSettingsRepositoryInterface extends RepositoryInterface +{ + public function findOneByIndex(string|Index $index): ?IndexSettingsInterface; +} diff --git a/src/Resources/config/doctrine/model/IndexSettings.orm.xml b/src/Resources/config/doctrine/model/IndexSettings.orm.xml new file mode 100644 index 0000000..2a12913 --- /dev/null +++ b/src/Resources/config/doctrine/model/IndexSettings.orm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/src/Resources/config/routes/admin.yaml b/src/Resources/config/routes/admin.yaml index 0df6bb6..662c5ae 100644 --- a/src/Resources/config/routes/admin.yaml +++ b/src/Resources/config/routes/admin.yaml @@ -1,3 +1,19 @@ +setono_sylius_meilisearch_admin_index_settings: + resource: | + section: admin + alias: setono_sylius_meilisearch.index_settings + templates: "@SyliusAdmin\\Crud" + redirect: index + permission: true + grid: setono_sylius_meilisearch_admin_index_settings + vars: + all: + header: setono_sylius_meilisearch.ui.index_settings_header + subheader: setono_sylius_meilisearch.ui.index_settings_subheader + templates: + form: "@SetonoSyliusMeilisearchPlugin/admin/index_settings/_form.html.twig" + type: sylius.resource + setono_sylius_meilisearch_admin_synonym: resource: | section: admin diff --git a/src/Resources/config/services/event_subscriber.xml b/src/Resources/config/services/event_subscriber.xml index 55b399e..dfe0485 100644 --- a/src/Resources/config/services/event_subscriber.xml +++ b/src/Resources/config/services/event_subscriber.xml @@ -6,6 +6,14 @@ + + + + + + + + diff --git a/src/Resources/config/services/factory.xml b/src/Resources/config/services/factory.xml index 70a0914..72c3a6b 100644 --- a/src/Resources/config/services/factory.xml +++ b/src/Resources/config/services/factory.xml @@ -2,6 +2,11 @@ + + + + diff --git a/src/Resources/config/services/form.xml b/src/Resources/config/services/form.xml index da2d6bd..90234b7 100644 --- a/src/Resources/config/services/form.xml +++ b/src/Resources/config/services/form.xml @@ -2,6 +2,9 @@ + + setono_sylius_meilisearch + setono_sylius_meilisearch @@ -58,6 +61,13 @@ + + %setono_sylius_meilisearch.model.index_settings.class% + %setono_sylius_meilisearch.form.type.index_settings.validation_groups% + + + + %setono_sylius_meilisearch.model.synonym.class% diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml index 2d9dd3e..5ad520b 100644 --- a/src/Resources/translations/messages.en.yaml +++ b/src/Resources/translations/messages.en.yaml @@ -38,9 +38,13 @@ setono_sylius_meilisearch: main: meilisearch: header: Meilisearch + settings: Settings synonyms: Synonyms ui: indexes: Indexes + index_settings: Index settings + index_settings_header: Index settings + index_settings_subheader: Update your index settings to optimize the search experience no_indexes: No indexes search: Search search_placeholder: Search... diff --git a/src/Resources/views/admin/index_settings/_form.html.twig b/src/Resources/views/admin/index_settings/_form.html.twig new file mode 100644 index 0000000..255a120 --- /dev/null +++ b/src/Resources/views/admin/index_settings/_form.html.twig @@ -0,0 +1,9 @@ +{{ form_errors(form) }} +
+
+ {{ form_row(form.index) }} +
+
+ {{ form_row(form.settings) }} +
+
diff --git a/src/Settings/Settings.php b/src/Settings/Settings.php index ce54a45..3b38e64 100644 --- a/src/Settings/Settings.php +++ b/src/Settings/Settings.php @@ -9,7 +9,7 @@ * * See https://www.meilisearch.com/docs/reference/api/settings */ -class Settings +final class Settings { /** * Fields displayed in the returned documents