setono / sylius-meilisearch-plugin
Meilisearch integration for your Sylius store
Fund package maintenance!
Setono
Installs: 57
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 5
Forks: 2
Open Issues: 2
Type:sylius-plugin
Requires
- php: >=8.1
- ext-json: *
- doctrine/collections: ^1.8 || ^2.0
- doctrine/event-manager: ^1.2 || ^2.0
- doctrine/orm: ^2.14 || ^3.0
- doctrine/persistence: ^2.5 || ^3.0
- dragon-code/size-sorter: ^1.5
- knplabs/knp-menu: ^3.4
- liip/imagine-bundle: ^2.10
- meilisearch/meilisearch-php: ^1.8
- ocramius/doctrine-batch-utils: ^2.4
- psr/cache: ^1.0 || ^2.0 || ^3.0
- psr/container: ^1.0 || ^2.0
- psr/event-dispatcher: ^1.0
- psr/log: ^1.1 || ^2.0 || ^3.0
- setono/composite-compiler-pass: ^1.2
- setono/doctrine-orm-trait: ^1.1
- sylius/channel: ^1.0
- sylius/channel-bundle: ^1.0
- sylius/core: ^1.0
- sylius/core-bundle: ^1.0
- sylius/currency: ^1.0
- sylius/grid-bundle: ^1.11
- sylius/locale: ^1.0
- sylius/locale-bundle: ^1.0
- sylius/product: ^1.0
- sylius/resource-bundle: ^1.6
- sylius/taxonomy: ^1.0
- sylius/ui-bundle: ^1.0
- symfony/config: ^5.4 || ^6.4 || ^7.0
- symfony/console: ^5.4 || ^6.4 || ^7.0
- symfony/dependency-injection: ^5.4 || ^6.4 || ^7.0
- symfony/event-dispatcher: ^5.4 || ^6.4 || ^7.0
- symfony/form: ^5.4 || ^6.4 || ^7.0
- symfony/http-foundation: ^5.4 || ^6.4 || ^7.0
- symfony/http-kernel: ^5.4 || ^6.4 || ^7.0
- symfony/messenger: ^5.4 || ^6.4 || ^7.0
- symfony/options-resolver: ^5.4 || ^6.4 || ^7.0
- symfony/routing: ^5.4 || ^6.4 || ^7.0
- symfony/serializer: ^5.4 || ^6.4 || ^7.0
- symfony/string: ^5.4 || ^6.4 || ^7.0
- symfony/translation-contracts: ^1.1 || ^2.5 || ^3.2
- symfony/validator: ^5.4 || ^6.4 || ^7.0
- twig/twig: ^2.15 || ^3.0
- webmozart/assert: ^1.11
Requires (Dev)
- api-platform/core: ^2.7.16
- babdev/pagerfanta-bundle: ^3.8
- behat/behat: ^3.14
- doctrine/annotations: ^1.14.4 || ^2.0.2
- doctrine/data-fixtures: ^1.7
- doctrine/doctrine-bundle: ^2.11
- infection/infection: ^0.27.10
- jms/serializer-bundle: ^4.2
- lexik/jwt-authentication-bundle: ^2.17
- matthiasnoback/symfony-dependency-injection-test: ^4.3 || ^5.1
- nyholm/psr7: ^1.8
- phpspec/prophecy-phpunit: ^2.3
- phpunit/phpunit: ^9.6.21
- psalm/plugin-phpunit: ^0.18.4
- setono/code-quality-pack: ^2.8.3
- sylius/sylius: ~1.12.19
- symfony/browser-kit: ^5.4 || ^6.4 || ^7.0
- symfony/debug-bundle: ^5.4 || ^6.4 || ^7.0
- symfony/dotenv: ^5.4 || ^6.4 || ^7.0
- symfony/http-client: ^5.4 || ^6.4 || ^7.0
- symfony/intl: ^5.4 || ^6.4 || ^7.0
- symfony/property-info: ^5.4 || ^6.4 || ^7.0
- symfony/web-profiler-bundle: ^5.4 || ^6.4 || ^7.0
- symfony/webpack-encore-bundle: ^1.17.2
- willdurand/negotiation: ^3.1
Conflicts
- illuminate/contracts: <8.68.0
This package is auto-updated.
Last update: 2024-12-07 20:20:10 UTC
README
Meilisearch is an open-source search engine written in Rust, designed to create lightning-fast and hyper-relevant search experiences out of the box.
Installation
composer require setono/sylius-meilisearch-plugin
Import configuration
# config/packages/setono_sylius_meilisearch.yaml setono_sylius_meilisearch: indexes: products: document: 'Setono\SyliusMeilisearchPlugin\Document\Product' entities: [ 'App\Entity\Product\Product' ] search: index: products
In your .env.local
add your parameters:
###> setono/sylius-meilisearch-plugin ### MEILISEARCH_HOST=http://localhost:7700 MEILISEARCH_MASTER_KEY=YOUR_MASTER_KEY MEILISEARCH_SEARCH_KEY=YOUR_SEARCH_KEY ###< setono/sylius-meilisearch-plugin ###
Import routing
# config/routes/setono_sylius_meilisearch.yaml setono_sylius_meilisearch: resource: "@SetonoSyliusMeilisearchPlugin/Resources/config/routes.yaml"
or if your app doesn't use locales:
# config/routes/setono_sylius_meilisearch.yaml setono_sylius_meilisearch: resource: "@SetonoSyliusMeilisearchPlugin/Resources/config/routes_no_locale.yaml"
Implement the IndexableInterface
in your entities
The entities you've configured for indexing has to implement the Setono\SyliusMeilisearchPlugin\Model\IndexableInterface
.
In a typical Sylius application for the Product
entity it could look like this:
<?php declare(strict_types=1); namespace App\Entity\Product; use Doctrine\ORM\Mapping as ORM; use Setono\SyliusMeilisearchPlugin\Model\IndexableAwareTrait; use Setono\SyliusMeilisearchPlugin\Model\IndexableInterface; use Sylius\Component\Core\Model\Product as BaseProduct; /** * @ORM\Entity * @ORM\Table(name="sylius_product") */ class Product extends BaseProduct implements IndexableInterface { public function getDocumentIdentifier(): ?string { return (string) $this->getId(); } }
Update your database schema
php bin/console doctrine:migrations:diff php bin/console doctrine:migrations:migrate -n
Install assets
php bin/console assets:install
Populate the index
To populate the index you can run the following command:
php bin/console setono:sylius-meilisearch:index
The plugin will detect most changes in your entities and update the index accordingly. However, it will not detect changes in associations, so you might need to reindex the whole index from time to time.
Filter entities to index
When indexing entities, most likely there are some of the entities that you don't want included in the index. There are two ways you can do this. 1) When data is fetched from the database or 2) when data is traversed during indexing. Obviously, the first option is the most efficient, but let's look at both.
Filtering when fetching data from the database
Here you will listen to the \Setono\SyliusMeilisearchPlugin\Event\QueryBuilderForDataProvisionCreated
event and modify the query builder accordingly.
Here is an example where we filter out disabled products:
<?php namespace App\EventSubscriber; use Doctrine\ORM\QueryBuilder; use Setono\SyliusMeilisearchPlugin\Event\QueryBuilderForDataProvisionCreated; use Sylius\Component\Resource\Model\ToggleableInterface;use Symfony\Component\EventDispatcher\EventSubscriberInterface; class FilterDisabledEntitiesSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ QueryBuilderForDataProvisionCreated::class => 'filter', ]; } public function filter(QueryBuilderForDataProvisionCreated $event): void { if(!is_a($event->entity, ToggleableInterface::class, true)) { return; } $queryBuilder = $event->getQueryBuilder(); $alias = $queryBuilder->getRootAliases()[0]; $queryBuilder->andWhere($alias . '.enabled = true'); } }
Filtering when traversing data
Here you will implement the \Setono\SyliusMeilisearchPlugin\Model\FilterableInterface
in your entity and implement the filter
method.
The example below is the same as the previous example, but this time we filter out disabled products when traversing the data:
<?php namespace App\Entity\Product; use Doctrine\ORM\Mapping as ORM; use Setono\SyliusMeilisearchPlugin\Model\FilterableInterface; use Setono\SyliusMeilisearchPlugin\Model\IndexableInterface; use Sylius\Component\Core\Model\Product as BaseProduct; /** * @ORM\Entity * @ORM\Table(name="sylius_product") */ class Product extends BaseProduct implements IndexableInterface, FilterableInterface { public function getDocumentIdentifier(): ?string { return (string) $this->getId(); } public function filter(): bool { return $this->isEnabled(); } }
Testing
To run the functional tests in the plugin, here are the steps:
-
Ensure you have Meilisearch running and that you've set the required environment variables in
.env.test.local
. -
Create the test database
php bin/console doctrine:database:create --env=test
-
Update the test database schema
php bin/console doctrine:schema:update --env=test --force
-
Load fixtures
php bin/console sylius:fixtures:load -n --env=test
-
Populate the index
php bin/console setono:sylius-meilisearch:index --env=test
-
Run the tests
vendor/bin/phpunit --testsuite Functional