### Testing Application Setup and Commands
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
This section outlines the necessary steps to set up the testing environment, including installing dependencies, creating the database, loading fixtures, populating the Elasticsearch index, and running various test suites (Behat, PhpSpec, PHPUnit).
```bash
composer install
cd tests/Application
APP_ENV=test bin/console doctrine:database:create
APP_ENV=test bin/console doctrine:schema:create
# Start Elasticsearch (Docker Compose provided in repo root)
docker-compose up -d elasticsearch
APP_ENV=test bin/console sylius:fixtures:load
APP_ENV=test bin/console fos:elastica:populate
APP_ENV=test symfony server:run 127.0.0.1:8080 -d
APP_ENV=test bin/console assets:install
vendor/bin/behat # Behat functional tests
vendor/bin/phpspec run # PhpSpec unit tests
vendor/bin/phpunit # PHPUnit integration tests
```
--------------------------------
### Example Configuration Update
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/UPGRADE-1.7.md
This snippet shows an example of how a configuration might need to be updated. Ensure your configuration files reflect these changes.
```yaml
parameters:
# ...
# Old parameter
# sylius_elasticsearch.client.hosts: [%env(json:SYLIUS_ELASTICSEARCH_HOSTS)%]
# New parameter
sylius_elasticsearch.client.hosts: [%env(json:ELASTICSEARCH_HOSTS)%]
# ...
```
--------------------------------
### Update Installed Assets
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Run this command to install necessary assets for the plugin after installation.
```bash
bin/console assets:install
```
--------------------------------
### Install and Build Frontend Assets
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Run these commands to install Node.js dependencies and build your frontend assets using Webpack Encore.
```bash
yarn install
yarn encore dev # or prod, depends on your environment
```
--------------------------------
### OptionFacet Service Definition
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Example of manually defining an OptionFacet service, similar to AttributeFacet but for product options.
```yaml
services:
my_app.facet.option.t_shirt_size:
class: BitBag\SyliusElasticsearchPlugin\Facet\OptionFacet
arguments:
- '@bitbag_sylius_elasticsearch_plugin.property_name_resolver.option'
- '@=service("sylius.repository.product_option").findOneBy({"code": "t_shirt_size"})'
```
--------------------------------
### Set Up and Run Plugin Tests
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
This sequence of commands sets up the testing environment for the plugin. It includes installing dependencies, creating the database, applying schema, loading fixtures, populating Elasticsearch, running the development server, and executing Behat and Phpspec tests.
```bash
$ composer install
$ cd tests/Application
$ APP_ENV=test bin/console doctrine:database:create
$ APP_ENV=test bin/console doctrine:schema:create
// run elasticsearch
$ APP_ENV=test bin/console sylius:fixtures:load
$ APP_ENV=test bin/console fos:elastica:populate
$ APP_ENV=test symfony server:run 127.0.0.1:8080 -d
$ APP_ENV=test bin/console assets:install
$ open http://localhost:8080
$ vendor/bin/behat
$ vendor/bin/phpspec run
```
--------------------------------
### List Products by Partial Name (Bash)
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Example of using curl to query the autocomplete product endpoint for partial name matches. Handles empty queries by returning an empty item list.
```bash
# Request
curl "https://myshop.example/en_US/auto-complete/product?query=blue"
```
```json
# Response
{
"items": [
{
"taxon_name": "T-Shirts",
"name": "Blue Classic T-Shirt",
"description": "Comfortable cotton tee",
"slug": "/en_US/products/blue-classic-t-shirt",
"price": "$29.99",
"image": "/media/cache/sylius_shop_product_thumbnail/image.jpg"
}
]
}
```
```bash
# Empty query → returns {"items": []}
curl "https://myshop.example/en_US/auto-complete/product"
```
--------------------------------
### AttributeFacet Bucket Label and Name
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Examples of getting the formatted bucket label (e.g., 'Nike (14)') and the facet's display name (e.g., 'T-Shirt Brand').
```php
echo $facet->getBucketLabel(['key' => 'nike', 'doc_count' => 14]); // "Nike (14)"
echo $facet->getLabel(); // "T-Shirt Brand" (from Sylius attribute name)
```
--------------------------------
### Site-Wide Products Query Builder Data
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Example data array for SiteWideProductsQueryBuilder, used for global search queries.
```php
$data = [
'query' => 'running shoes', // search term
];
// Results: all enabled products in current channel matching "running shoes" (fuzzy)
```
--------------------------------
### Programmatic Facet Registry Usage
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Shows how to retrieve a facet by its ID or get all registered facets from the registry.
```php
$facet = $registry->getFacetById('price'); // throws FacetNotFoundException if missing
$all = $registry->getFacets(); // FacetInterface[]
```
--------------------------------
### Install Plugin via Composer
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Use this command to add the BitBag Elasticsearch Plugin to your project dependencies. The --no-scripts flag prevents immediate execution of post-install scripts.
```bash
composer require bitbag/elasticsearch-plugin --no-scripts
```
--------------------------------
### Manually Register Facet Filters
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
Example of manually registering custom facet filters like AttributeFacet and PriceFacet. This is required when auto-discovery is disabled.
```yaml
services:
bitbag_sylius_elasticsearch_plugin.facet.attribute.t_shirt_brand:
class: BitBag
SyliusElasticsearchPlugin
Facet
AttributeFacet
arguments:
- '@bitbag_sylius_elasticsearch_plugin.property_name_resolver.attribute'
- '@=service("sylius.repository.product_attribute").findOneBy({"code": "t_shirt_brand"})'
- '@sylius.context.locale'
bitbag_sylius_elasticsearch_plugin.facet.registry:
class: BitBag
SyliusElasticsearchPlugin
Facet
Registry
calls:
- method: addFacet
arguments:
- t_shirt_brand
- '@bitbag_sylius_elasticsearch_plugin.facet.attribute.t_shirt_brand'
- method: addFacet
arguments:
- price
- '@bitbag_sylius_elasticsearch_plugin.facet.price'
- method: addFacet
arguments:
- taxon
- '@bitbag_sylius_elasticsearch_plugin.facet.taxon'
```
--------------------------------
### Taxon Products Query Builder Data
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Example data array consumed by TaxonProductsQueryBuilder::buildQuery() for filtering products by taxon, price range, options, and attributes.
```php
$data = [
'name' => 'blue', // optional fuzzy name filter
'product_taxons' => 'caps', // taxon code (lowercased)
'min_price' => 1000, // cents
'max_price' => 5000,
'option_t_shirt_size' => ['s', 'm'], // option filter
'attribute_t_shirt_brand'=> ['nike', 'adidas'], // attribute filter
'sort' => ['product_created_at' => ['order' => 'desc']],
PaginationDataHandlerInterface::PAGE_INDEX => 1,
PaginationDataHandlerInterface::LIMIT_INDEX => 9,
];
```
--------------------------------
### AttributeFacet Aggregation Example
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
The Elasticsearch aggregation structure produced by an AttributeFacet for terms aggregation.
```json
{ "terms": { "field": "attribute_t_shirt_brand_en_us.keyword" } }
```
--------------------------------
### Configure Reindexing Persistence Listener
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
Override index definitions to control Doctrine event listeners for reindexing. This example disables updates while keeping inserts and deletes active.
```yaml
fos_elastica:
indexes:
bitbag_attribute_taxons:
types:
default:
persistence:
listener:
insert: true
update: false
delete: true
```
--------------------------------
### Populate Elasticsearch Index
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
This command populates the Elasticsearch index with your product data. Use '-e prod' for production environments.
```bash
bin/console fos:elastica:populate
```
--------------------------------
### Add Plugin Dependencies to bundles.php
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Register the FOSElasticaBundle and the BitBagSyliusElasticsearchPlugin in your `config/bundles.php` file to enable their services.
```php
# config/bundles.php
return [
...
FOS\ElasticaBundle\FOSElasticaBundle::class => ['all' => true],
BitBag\SyliusElasticsearchPlugin\BitBagSyliusElasticsearchPlugin::class => ['all' => true],
];
```
--------------------------------
### Initial Index Population
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Populate the Elasticsearch index with initial data using the provided console command.
```bash
bin/console fos:elastica:populate # initial index population
```
--------------------------------
### Shop Site-Wide Products Search Action Configuration
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Defines the route and default template for the Site-Wide Products Search Action, which handles global search queries.
```yaml
# Route: bitbag_sylius_elasticsearch_plugin_shop_search
# Default template: @BitBagSyliusElasticsearchPlugin/Shop/SiteWideSearch/index.html.twig
# Query string example:
# GET /en_US/search?search[query]=running+shoes&search[facets][t_shirt_brand][]=nike
# Template receives:
# - search_form: FormView (SearchType)
# - products: Pagerfanta|null
# - resources: Pagerfanta|null (alias of products)
```
--------------------------------
### Import Plugin Configuration
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Import the plugin's main configuration file into your `config/packages/_sylius.yaml` to apply its settings.
```yaml
# config/packages/_sylius.yaml
imports:
...
- { resource: "@BitBagSyliusElasticsearchPlugin/config/config.yml" }
```
--------------------------------
### ShopProductListDataHandler (PHP)
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Combines various request parameters such as name prefix, price range, options, attributes, and facets into a structured array for the `ShopProductsFinder`. It also enriches the data with taxon context.
```php
// Called inside TaxonProductsSearchAction:
$requestData = [
'name' => 'blue',
'price' => ['min_price' => 500, 'max_price' => 3000],
'options' => ['option_t_shirt_size' => ['S', 'M']],
'attributes' => ['attribute_t_shirt_brand' => ['Nike']],
'facets' => ['price' => [1000]],
];
$data = $shopProductListDataHandler->retrieveData($requestData);
// Adds: product_taxons (from TaxonContext), taxon object, normalised option/attribute arrays
```
--------------------------------
### Core Configuration Parameters
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Configure Elasticsearch connection details, pagination limits, search fuzziness, and facet auto-discovery settings.
```yaml
parameters:
# Elasticsearch connection
env(BITBAG_ES_HOST): "localhost"
env(BITBAG_ES_PORT): "9200"
env(BITBAG_ES_INDEX_PREFIX): "" # prefix all index names, e.g. "myshop_"
# Pagination
bitbag_es_pagination_available_page_limits: [9, 18, 36]
bitbag_es_pagination_default_limit: 9
# Search fuzziness (Elasticsearch fuzziness value: 0, 1, 2 or AUTO)
bitbag_es_fuzziness: AUTO
# Facet auto-discovery
bitbag_es_facets_auto_discover: true
bitbag_es_excluded_facet_attributes: ['jeans_material'] # skip specific attributes
bitbag_es_excluded_facet_options: ['t_shirt_size'] # skip specific options
# Index field prefixes (used by PropertyBuilders and QueryBuilders)
bitbag_es_shop_name_property_prefix: name
bitbag_es_shop_option_property_prefix: option
bitbag_es_shop_attribute_property_prefix: attribute
bitbag_es_shop_product_price_property_prefix: price
bitbag_es_shop_price_facet_interval: 5000 # price histogram bucket size (in cents)
```
--------------------------------
### API Platform Product Collection Data Provider (PHP)
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Demonstrates how ProductCollectionDataProvider integrates with API Platform to provide product data, including facets and pagination, powered by Elasticsearch. The configuration is typically defined in `config/api_platform/resources/Product.xml`.
```php
// config/api_platform/resources/Product.xml defines the GetCollection operation
// that uses ProductCollectionDataProvider automatically.
// API call example:
// GET /api/v2/products?query=shirt&facets[t_shirt_brand][]=nike&page=1&limit=10
// Response structure:
{
"items": [ /* ProductInterface objects serialized by API Platform */ ],
"facets": {
"t_shirt_brand": {
"buckets": [
{"key": "nike", "doc_count": 12},
{"key": "adidas", "doc_count": 8}
]
},
"price": {
"buckets": [
{"key": 1000, "doc_count": 5},
{"key": 2000, "doc_count": 7}
]
}
},
"pagination": {
"current_page": 1,
"has_previous_page": false,
"has_next_page": true,
"per_page": 10,
"total_items": 47,
"total_pages": 5
}
}
```
--------------------------------
### Configure Asset Package
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Define the `elasticsearch_shop` asset package in `config/packages/assets.yaml` to correctly reference plugin assets.
```yaml
framework:
assets:
packages:
...
elasticsearch_shop:
json_manifest_path: '%kernel.project_dir%/public/build/bitbag/elasticsearch/shop/manifest.json'
```
--------------------------------
### Import Plugin Routing
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Add the plugin's routing resource to your `config/routes.yaml`. Ensure this is loaded before Sylius shop routes for correct functionality.
```yaml
# config/routes.yaml
bitbag_sylius_elasticsearch_plugin:
resource: "@BitBagSyliusElasticsearchPlugin/config/routing.yml"
```
--------------------------------
### Configure Webpack Encore Build
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Add the `elasticsearch_shop` build configuration to `config/packages/webpack_encore.yaml` for Encore to manage plugin assets.
```yaml
webpack_encore:
output_path: '%kernel.project_dir%/public/build/default'
builds:
...
elasticsearch_shop: '%kernel.project_dir%/public/build/bitbag/elasticsearch/shop'
```
--------------------------------
### Import Plugin Configuration
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Import the plugin's default configuration file into your Sylius configuration.
```yaml
# config/packages/_sylius.yaml
imports:
- { resource: "@BitBagSyliusElasticsearchPlugin/config/config.yml" }
```
--------------------------------
### ListProductsByPartialNameAction
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Provides a JSON autocomplete endpoint for product search. It returns product details including name, slug, price, image, and taxon. Supports empty queries.
```APIDOC
## GET /{_locale}/auto-complete/product
### Description
JSON autocomplete endpoint. Returns an `ItemsResponse` with product name, slug, price, image, and taxon.
### Method
GET
### Endpoint
`/{_locale}/auto-complete/product`
### Query Parameters
- **query** (string) - Optional - The search query string for product names.
### Response
#### Success Response (200)
- **items** (array) - An array of product objects, each containing:
- **taxon_name** (string) - The name of the product's taxon.
- **name** (string) - The name of the product.
- **description** (string) - The product description.
- **slug** (string) - The product slug for its URL.
- **price** (string) - The product price.
- **image** (string) - The URL to the product image.
### Request Example
```bash
curl "https://myshop.example/en_US/auto-complete/product?query=blue"
```
### Response Example
```json
{
"items": [
{
"taxon_name": "T-Shirts",
"name": "Blue Classic T-Shirt",
"description": "Comfortable cotton tee",
"slug": "/en_US/products/blue-classic-t-shirt",
"price": "$29.99",
"image": "/media/cache/sylius_shop_product_thumbnail/image.jpg"
}
]
}
```
### Empty Query Example
```bash
curl "https://myshop.example/en_US/auto-complete/product"
```
### Empty Query Response Example
```json
{
"items": []
}
```
```
--------------------------------
### ShopProductListDataHandler
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Combines various request parameters like taxon context, name prefix, price range, options, and attributes into a comprehensive data array for product searching.
```APIDOC
### ShopProductListDataHandler
### Description
Combines taxon context, name prefix, price range, options, and attributes into the full `$data` array for `ShopProductsFinder`. This handler is typically called within actions like `TaxonProductsSearchAction`.
### Method
`retrieveData(array $requestData): array`
### Parameters
- **requestData** (array) - An associative array containing various product filtering criteria:
- **name** (string) - Optional - A prefix for product names to search by.
- **price** (array) - Optional - An array defining the price range, with `min_price` and `max_price` keys.
- **options** (array) - Optional - An associative array of product options and their values (e.g., `['option_t_shirt_size' => ['S', 'M']]`).
- **attributes** (array) - Optional - An associative array of product attributes and their values (e.g., `['attribute_t_shirt_brand' => ['Nike']]`).
- **facets** (array) - Optional - An associative array of facets and their selected values (e.g., `['price' => [1000]]`).
### Returns
- array - A structured array containing normalized data ready for product finding, including:
- `product_taxons` (derived from TaxonContext)
- `taxon` object
- Normalized option and attribute arrays
- Other combined criteria.
### Example
```php
// Assuming $shopProductListDataHandler is an instance of ShopProductListDataHandler
// This is typically called inside TaxonProductsSearchAction:
$requestData = [
'name' => 'blue',
'price' => ['min_price' => 500, 'max_price' => 3000],
'options' => ['option_t_shirt_size' => ['S', 'M']],
'attributes' => ['attribute_t_shirt_brand' => ['Nike']],
'facets' => ['price' => [1000]],
];
$data = $shopProductListDataHandler->retrieveData($requestData);
// $data will be populated with combined and normalized search criteria.
```
```
--------------------------------
### Debug Sylius Elasticsearch Plugin Services
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
Use this command to list available services provided by the plugin. This is useful for understanding the plugin's architecture and for service decoration.
```bash
$ bin/console debug:container | grep bitbag_sylius_elasticsearch_plugin
```
--------------------------------
### Manual Facet Registry Configuration
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Demonstrates manual registration of facets in services.yaml when auto-discovery is disabled. Facets are keyed by an ID string.
```yaml
services:
bitbag_sylius_elasticsearch_plugin.facet.registry:
class: BitBag\SyliusElasticsearchPlugin\Facet\Registry
calls:
- method: addFacet
arguments: ['price', '@bitbag_sylius_elasticsearch_plugin.facet.price']
- method: addFacet
arguments: ['taxon', '@bitbag_sylius_elasticsearch_plugin.facet.taxon']
- method: addFacet
arguments: ['t_shirt_brand', '@my_app.facet.attribute.t_shirt_brand']
```
--------------------------------
### Declare Plugin Routes
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Declare the plugin's routes in config/routes.yaml. This must be done BEFORE Sylius shop routes.
```yaml
# config/routes.yaml — must be declared BEFORE sylius_shop routes
bitbag_sylius_elasticsearch_plugin:
resource: "@BitBagSyliusElasticsearchPlugin/config/routing.yml"
```
--------------------------------
### Clear Application Cache
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Execute this command to clear the application cache, ensuring all new configurations are applied.
```bash
bin/console cache:clear
```
--------------------------------
### Shop Taxon Products Search Action Configuration
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Configures the route for the Taxon Products Search Action, which replaces the default Sylius taxon product list. It renders a form, merges data, and calls ShopProductsFinder.
```yaml
# Route: bitbag_sylius_elasticsearch_plugin_shop_taxon_products
# Template variable: @BitBagSyliusElasticsearchPlugin/Shop/TaxonProductsSearch/index.html.twig
# Query string example:
# GET /en_US/taxons/caps?name=blue&options[option_t_shirt_size][]=m&price[min_price]=500&page=2
# Template receives:
# - form: FormView (ShopProductsFilterType)
# - products: Pagerfanta
# - taxon: TaxonInterface
# Override template per-route:
# config/routes.yaml
bitbag_sylius_elasticsearch_plugin_shop_taxon_products:
path: /{_locale}/taxons/{slug}
defaults:
_controller: bitbag_sylius_elasticsearch_plugin.controller.action.shop.taxon_products_search
template: "shop/custom_taxon.html.twig"
```
--------------------------------
### Update Event Listener Configuration
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/UPGRADE-1.7.md
If the event listener configuration was overwritten, update it to include the new service definitions for resource indexing and order product updates. This ensures proper event handling for product attributes, options, products, product variants, and completed orders.
```xml
%sylius.model.product_attribute.class%
fos_elastica.object_persister.bitbag_attribute_taxons.default
%sylius.model.product_option.class%
fos_elastica.object_persister.bitbag_option_taxons.default
getProduct
%sylius.model.product.class%
fos_elastica.object_persister.bitbag_shop_product.default
fos_elastica.object_persister.bitbag_shop_product.default
```
--------------------------------
### Implement ProductVariant Entity Changes
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/UPGRADE-1.7.md
To ensure compatibility and leverage new features, use the `ProductVariantTrait` and implement the `ProductVariantInterface` in your overridden ProductVariant entity class. Refer to Sylius documentation for details on overwriting models.
```php
use BitBag\SyliusElasticsearchPlugin\Model\ProductVariantInterface as BitBagElasticsearchPluginVariant;
use BitBag\SyliusElasticsearchPlugin\Model\ProductVariantTrait;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface as BaseProductVariantInterface;
class ProductVariant extends BaseProductVariant implements BaseProductVariantInterface, BitBagElasticsearchPluginVariant
{
use ProductVariantTrait;
```
--------------------------------
### PriceFacet Bucket Label Formatting
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Formats a histogram bucket label with currency conversion. The interval is configured via parameters, and the output uses the shopper context's currency and a MoneyFormatter.
```php
// Interval configured via parameter (default 5000 = $50.00 in cents):
// parameters:
// bitbag_es_shop_price_facet_interval: 1000 # $10 buckets
// Aggregation:
// { "histogram": { "field": "price_us_web", "interval": 5000, "min_doc_count": 1 } }
// Bucket label (with currency conversion):
// "$10.00 - $60.00 (23)"
echo $facet->getBucketLabel(['key' => 1000, 'doc_count' => 23]);
// → "$10.00 - $60.00 (23)" (uses ShopperContext currency + MoneyFormatter)
```
--------------------------------
### Configure Webpack for Plugin
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Include the plugin's webpack configuration in your `webpack.config.js` to manage its frontend assets.
```js
const [ bitbagElasticSearchShop ] = require('./vendor/bitbag/elasticsearch-plugin/webpack.config.js')
module.exports = [..., bitbagElasticSearchShop];
```
--------------------------------
### ShopProductsSortDataHandler
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Resolves sorting parameters for product listings, mapping 'price' to the channel-specific price field and handling sort direction.
```APIDOC
### ShopProductsSortDataHandler
### Description
Resolves sort column and direction for product listings. It maps the `price` sorter to the current channel's price field and handles the sort order.
### Method
`retrieveData(array $queryParameters): array`
### Parameters
- **queryParameters** (array) - An associative array of HTTP query parameters, potentially including 'orderBy' and 'sort'.
- **SortDataHandlerInterface::ORDER_BY_INDEX** (string) - The field to sort by. Valid values: `sold_units`, `product_created_at`, `price`.
- **SortDataHandlerInterface::SORT_INDEX** (string) - The sort direction. Valid values: `asc`, `desc`.
### Returns
- array - A structured array containing the sort configuration.
- **sort** (object) - An object defining the sort criteria.
- **[field_name]** (object) - The field to sort on (e.g., `price_us_web`).
- **order** (string) - The sort order (`asc` or `desc`).
- **unmapped_type** (string) - Specifies the unmapped type for Elasticsearch.
### Example
```php
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\SortDataHandlerInterface;
// Assuming $sortHandler is an instance of ShopProductsSortDataHandler
$data = $sortHandler->retrieveData([
SortDataHandlerInterface::ORDER_BY_INDEX => 'price',
SortDataHandlerInterface::SORT_INDEX => 'asc',
]);
// $data will be:
// ['sort' => ['price_us_web' => ['order' => 'asc', 'unmapped_type' => 'keyword']]]
$data = $sortHandler->retrieveData([]);
// $data will be:
// ['sort' => ['product_created_at' => ['order' => 'asc', 'unmapped_type' => 'keyword']]] (default sort)
```
```
--------------------------------
### Configure FOSElasticaBundle
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Configure the Elasticsearch client connection URL and remove the default index to avoid conflicts with the plugin's indexes.
```yaml
# config/packages/fos_elastica.yaml
fos_elastica:
clients:
default: { url: '%env(ELASTICSEARCH_URL)%' }
# Remove the default "app" index — plugin registers its own indexes
```
--------------------------------
### Override Plugin Parameters
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
This command helps identify parameters that can be overridden in your parameters.yml(.dist) file. Adjusting these parameters allows for customization of the plugin's behavior.
```bash
$ bin/console debug:container --parameters | grep bitbag
```
--------------------------------
### ProductCollectionDataProvider
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Integrates with API Platform to provide product collection data using Elasticsearch. It supports filtering, faceting, and pagination.
```APIDOC
## API Platform Integration — ProductCollectionDataProvider
### Description
Implements `ApiPlatform\State\ProviderInterface` to power the product `GetCollection` operation with Elasticsearch data, returning items + facet aggregations + pagination metadata.
### Method
GET
### Endpoint
`/api/v2/products`
### Query Parameters
- **query** (string) - Optional - Search term for products.
- **facets** (object) - Optional - Facet filters. Example: `facets[t_shirt_brand][]=nike`.
- **page** (integer) - Optional - The current page number for pagination. Defaults to 1.
- **limit** (integer) - Optional - The number of items per page. Defaults to 10.
### Response
#### Success Response (200)
- **items** (array) - An array of product objects.
- **facets** (object) - An object containing facet aggregations.
- **[facet_name]** (object) - Represents a specific facet.
- **buckets** (array) - An array of facet buckets, each with a `key` and `doc_count`.
- **pagination** (object) - An object containing pagination metadata.
- **current_page** (integer) - The current page number.
- **has_previous_page** (boolean) - Indicates if there is a previous page.
- **has_next_page** (boolean) - Indicates if there is a next page.
- **per_page** (integer) - The number of items per page.
- **total_items** (integer) - The total number of items available.
- **total_pages** (integer) - The total number of pages.
### Request Example
```bash
GET /api/v2/products?query=shirt&facets[t_shirt_brand][]=nike&page=1&limit=10
```
### Response Example
```json
{
"items": [ /* ProductInterface objects serialized by API Platform */ ],
"facets": {
"t_shirt_brand": {
"buckets": [
{"key": "nike", "doc_count": 12},
{"key": "adidas", "doc_count": 8}
]
},
"price": {
"buckets": [
{"key": 1000, "doc_count": 5},
{"key": 2000, "doc_count": 7}
]
}
},
"pagination": {
"current_page": 1,
"has_previous_page": false,
"has_next_page": true,
"per_page": 10,
"total_items": 47,
"total_pages": 5
}
}
```
```
--------------------------------
### Configure Routing for Elasticsearch Plugin
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
Ensure the plugin's routing is loaded before Sylius shop routing to enable custom search functionality. This is crucial for taxon and site-wide searches.
```yaml
bitbag_sylius_elasticsearch_plugin:
resource: "@BitBagSyliusElasticsearchPlugin/config/routing.yml"
sylius_shop:
resource: "@SyliusShopBundle/Resources/config/routing.yml"
prefix: /{_locale}
requirements:
_locale: '^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$'
```
--------------------------------
### Configure FOSElasticaBundle Index
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Remove the default 'app' index configuration from `config/packages/fos_elastica.yaml` to avoid conflicts with the plugin's index management.
```yaml
# config/packages/fos_elastica.yaml
fos_elastica:
clients:
default: { url: '%env(ELASTICSEARCH_URL)%' }
indexes:
app: ~
```
```yaml
fos_elastica:
clients:
default: { url: '%env(ELASTICSEARCH_URL)%' }
```
--------------------------------
### Configure Search Fuzziness (XML)
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
Override the `contains_name` service definition in XML to configure search fuzziness. The 'AUTO' argument enables automatic fuzziness adjustment.
```xml
AUTO
```
--------------------------------
### Configure Elasticsearch URL
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Set the Elasticsearch connection URL in your `.env` file. This is used by the FOSElasticaBundle to connect to your Elasticsearch instance.
```dotenv
###> friendsofsymfony/elastica-bundle ###
ELASTICSEARCH_URL=http://localhost:9200/
###< friendsofsymfony/elastica-bundle ###
```
--------------------------------
### AttributeFacet Service Definition
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Manual service definition for an AttributeFacet, specifying dependencies for resolving property names and fetching the product attribute.
```yaml
services:
my_app.facet.attribute.t_shirt_brand:
class: BitBag\SyliusElasticsearchPlugin\Facet\AttributeFacet
arguments:
- '@bitbag_sylius_elasticsearch_plugin.property_name_resolver.attribute'
- '@=service("sylius.repository.product_attribute").findOneBy({"code": "t_shirt_brand"})'
- '@sylius.context.locale'
```
--------------------------------
### PaginationDataHandler
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Handles the normalization of raw HTTP query parameters for pagination, setting default values if not provided.
```APIDOC
### PaginationDataHandler
### Description
Data handlers normalize raw HTTP query parameters into the structured `$data` array consumed by finders and query builders. This handler specifically manages pagination parameters.
### Method
`retrieveData(array $queryParameters): array`
### Parameters
- **queryParameters** (array) - An associative array of HTTP query parameters, potentially including 'page' and 'limit'.
### Returns
- array - A structured array containing 'page' and 'limit' indices.
- **PaginationDataHandlerInterface::PAGE_INDEX** (integer) - The page number.
- **PaginationDataHandlerInterface::LIMIT_INDEX** (integer) - The number of items per page.
### Example
```php
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\PaginationDataHandler;
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\PaginationDataHandlerInterface;
// $defaultLimit injected from bitbag_es_pagination_default_limit
$handler = new PaginationDataHandler(defaultLimit: 9);
$data = $handler->retrieveData(['page' => '3', 'limit' => '18']);
// $data will be:
// [
// PaginationDataHandlerInterface::PAGE_INDEX => 3, // 'page'
// PaginationDataHandlerInterface::LIMIT_INDEX => 18, // 'limit'
// ]
$data = $handler->retrieveData([]);
// $data will be:
// [ 'page' => 1, 'limit' => 9 ] (defaults)
```
```
--------------------------------
### ShopProductsSortDataHandler (PHP)
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Resolves sorting column and direction from request data. It maps the 'price' sorter to the current channel's specific price field and handles default sorting.
```php
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\SortDataHandlerInterface;
// Valid orderBy values: sold_units, product_created_at, price
// Valid sort values: asc, desc
$data = $sortHandler->retrieveData([
SortDataHandlerInterface::ORDER_BY_INDEX => 'price',
SortDataHandlerInterface::SORT_INDEX => 'asc',
]);
// ['sort' => ['price_us_web' => ['order' => 'asc', 'unmapped_type' => 'keyword']]]
$data = $sortHandler->retrieveData([]);
// ['sort' => ['product_created_at' => ['order' => 'asc', 'unmapped_type' => 'keyword']]]
```
--------------------------------
### AutoDiscoverRegistry Trigger
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Illustrates how to trigger the lazy loading of facets in AutoDiscoverRegistry before performing a search.
```php
$autoDiscoverRegistry->autoRegister();
```
--------------------------------
### Configure Search Fuzziness (YAML)
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/README.md
Override the `contains_name` service definition in YAML to configure search fuzziness. The 'AUTO' argument enables automatic fuzziness adjustment.
```yaml
bitbag_sylius_elasticsearch_plugin.query_builder.contains_name:
class: BitBag
SyliusElasticsearchPlugin
QueryBuilder
ContainsNameQueryBuilder
arguments:
- '@sylius.context.locale'
- '@bitbag_sylius_elasticsearch_plugin.search_property_name_resolver_registry'
- 'AUTO'
```
--------------------------------
### PaginationDataHandler (PHP)
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Normalizes pagination parameters ('page', 'limit') from HTTP query parameters into a structured array. Uses default values if parameters are not provided.
```php
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\PaginationDataHandler;
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\PaginationDataHandlerInterface;
// $defaultLimit injected from bitbag_es_pagination_default_limit
$handler = new PaginationDataHandler(defaultLimit: 9);
$data = $handler->retrieveData(['page' => '3', 'limit' => '18']);
// [
// PaginationDataHandlerInterface::PAGE_INDEX => 3, // 'page'
// PaginationDataHandlerInterface::LIMIT_INDEX => 18, // 'limit'
// ]
$data = $handler->retrieveData([]);
// [ 'page' => 1, 'limit' => 9 ] (defaults)
```
--------------------------------
### Facet Exclusion Configuration
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Configuration parameters to exclude specific product attributes or options from auto-discovery in the facet registry.
```yaml
parameters:
bitbag_es_excluded_facet_attributes: ['internal_sku', 'weight_kg']
bitbag_es_excluded_facet_options: ['packaging_type']
```
--------------------------------
### Register Bundles in config/bundles.php
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Register the FOSElasticaBundle and the BitBagSyliusElasticsearchPlugin in your Sylius application's bundle configuration.
```php
// config/bundles.php
return [
FOSlkidElasticaBundlelkidElasticaBundle::class => ['all' => true],
BitBaglkidSyliusElasticsearchPluginlkidSyliusElasticsearchPlugin::class => ['all' => true],
];
```
--------------------------------
### SoldUnitsPropertyBuilder Document Output
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
The SoldUnitsPropertyBuilder aggregates total sold units across all variants and outputs this as the 'sold_units' field for popularity-based sorting.
```php
// Document output:
// { "sold_units": 42 }
```
--------------------------------
### Include Encore Entry Tags in Templates
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation.md
Use these Twig functions in your templates to include the necessary JavaScript and CSS tags for the plugin's frontend assets.
```twig
{# @templates/shop/javascripts.html.twig #}
{{ encore_entry_script_tags('bitbag-elasticsearch-shop', null, 'elasticsearch_shop') }}
{# @templates/shop/stylesheets.html.twig #}
{{ encore_entry_link_tags('bitbag-elasticsearch-shop', null, 'elasticsearch_shop') }}
```
--------------------------------
### Update Product Variant Entity with Trait
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation/attribute-mapping.md
Extend your `ProductVariant` entity by implementing `BitBagElasticsearchPluginVariant` and using the `ProductVariantTrait`. Ensure your entity extends `Sylius
Component
Core
Model
ProductVariant`.
```php
$products */
$products = $namedProductsFinder->findByNamePart('blue shi');
// Internally builds ProductsByPartialNameQueryBuilder query and calls FinderInterface::find()
foreach ($products as $product) {
echo $product->getName() . ' — ' . $product->getMainTaxon()?->getName();
}
```
--------------------------------
### TaxonFacet Bucket Label Formatting
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Formats a terms aggregation bucket label. It resolves taxon codes to human-readable names fetched from a repository, falling back to the code if the name is not found.
```php
// Aggregation:
// { "terms": { "field": "product_taxons.keyword" } }
// Bucket label:
echo $facet->getBucketLabel(['key' => 'caps', 'doc_count' => 7]);
// → "Caps (7)" (taxon name fetched from repository; falls back to code)
echo $facet->getLabel(); // "bitbag_sylius_elasticsearch_plugin.ui.facet.taxon.label"
```
--------------------------------
### Define Entity XML Mapping
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation/xml-mapping.md
Create an XML file in the specified Doctrine mapping directory to define your entity's mapping. This file links your entity class to its database table.
```xml
```
--------------------------------
### ResourceIndexListener Configuration (XML)
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
XML configuration for the ResourceIndexListener, which listens to Sylius CRUD events (product create, update, etc.) to refresh the Elasticsearch index via ResourceRefresherInterface. It maps model classes to their corresponding Elasticsearch persister service IDs.
```xml
%sylius.model.product.class%
fos_elastica.object_persister.bitbag_shop_product.default
```
--------------------------------
### ShopProductsFinder Usage
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
Finds paginated products applying facet filters and sorting. It takes merged data including taxons, name, sort order, facets, page index, and limit.
```php
use BitBag\SyliusElasticsearchPlugin\Finder\ShopProductsFinder;
use Pagerfanta\Pagerfanta;
// $data is the merged output of all DataHandlers + form data:
$data = [
'product_taxons' => 'caps',
'name' => '',
'sort' => ['product_created_at' => ['order' => 'desc', 'unmapped_type' => 'keyword']],
'facets' => [
'price' => [1000, 2000], // selected histogram buckets
't_shirt_brand' => ['nike'], // selected attribute values
],
PaginationDataHandlerInterface::PAGE_INDEX => 2,
PaginationDataHandlerInterface::LIMIT_INDEX => 9,
];
/** @var Pagerfanta $products */
$products = $shopProductsFinder->find($data);
echo $products->getCurrentPage(); // 2
echo $products->getMaxPerPage(); // 9
echo $products->getNbResults(); // 47
foreach ($products->getCurrentPageResults() as $product) {
echo $product->getName();
}
```
--------------------------------
### Configure Doctrine XML Mapping
Source: https://github.com/bitbagcommerce/syliuselasticsearchplugin/blob/master/doc/installation/xml-mapping.md
Specify the XML mapping type and directory in your `doctrine.yaml` configuration. This tells Doctrine where to find your custom entity mappings.
```yaml
doctrine:
...
orm:
entity_managers:
default:
...
mappings:
App:
...
type: xml
dir: '%kernel.project_dir%/src/Resources/config/doctrine'
```
--------------------------------
### ProductTaxonsBuilder Document Output
Source: https://context7.com/bitbagcommerce/syliuselasticsearchplugin/llms.txt
The ProductTaxonsBuilder stores all taxon codes, including ancestors, as a string array in the 'product_taxons' field for filtering.
```php
// Document output:
// { "product_taxons": ["caps", "accessories", "men"] }
```