webgriffe / sylius-fixtures-plugin
Sylius fixtures with fixed prices, per locale translations, stock, shipping categories, plus a complete demo store.
Package info
github.com/webgriffe/sylius-fixtures-plugin
Type:sylius-plugin
pkg:composer/webgriffe/sylius-fixtures-plugin
Requires
- php: ^8.2
- sylius/sylius: ^2.2
- symfony/config: ^6.4 || ^7.4
- symfony/dependency-injection: ^6.4 || ^7.4
- symfony/http-kernel: ^6.4 || ^7.4
- webmozart/assert: ^1.11
Requires (Dev)
- behat/behat: ^3.16
- dbrekelmans/bdi: ^1.4
- dmore/behat-chrome-extension: ^1.4
- dmore/chrome-mink-driver: ^2.9
- friends-of-behat/mink: ^1.11
- friends-of-behat/mink-browserkit-driver: ^1.6
- friends-of-behat/mink-debug-extension: ^2.1
- friends-of-behat/mink-extension: ^2.7
- friends-of-behat/page-object-extension: ^0.3
- friends-of-behat/suite-settings-extension: ^1.1
- friends-of-behat/symfony-extension: ^2.6
- friends-of-behat/variadic-extension: ^1.6
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^1.12
- phpstan/phpstan-doctrine: ^1.3
- phpstan/phpstan-webmozart-assert: ^1.2
- phpunit/phpunit: ^10.5
- sylius-labs/coding-standard: ^4.4
- sylius-labs/suite-tags-extension: ~0.2
- sylius/sylius-rector: ^2.0
- sylius/test-application: ^2.0.0@alpha
- symfony/browser-kit: ^6.4 || ^7.4
- symfony/debug-bundle: ^6.4 || ^7.4
- symfony/dotenv: ^6.4 || ^7.4
- symfony/http-client: ^6.4 || ^7.4
- symfony/intl: ^6.4 || ^7.4
- symfony/runtime: ^6.4 || ^7.4
- symfony/web-profiler-bundle: ^6.4 || ^7.4
- symfony/webpack-encore-bundle: ^2.2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-09-15 13:48:39 UTC
README
Sylius fixtures that can actually describe a real catalog: fixed prices, per locale translations, stock, shipping categories and configurable products. It also ships a complete demo store (wines, glassware and food and wine experiences) ready to be loaded on any Sylius project.
Installation
composer require webgriffe/sylius-fixtures-plugin --dev
Register the plugin in config/bundles.php:
Webgriffe\SyliusFixturesPlugin\WebgriffeSyliusFixturesPlugin::class => ['dev' => true, 'test' => true],
What it adds to the Sylius fixtures
Products
| Option | Description |
|---|---|
price |
Price of every variant, in the currency unit (12.50), instead of the random one generated by Sylius |
variant_prices |
Price per variant, keyed by product option value: numero_calici_2: 49.00. Several options are joined by a + (esperienza_2_giorni+partecipanti_4: 800.00), their order does not matter. price is the fallback |
minimum_price / minimum_price_ratio |
Floor the catalog promotions cannot go below, either as an amount or as a share of the price of each variant (0.75 keeps at most a 25% discount) |
original_price |
Original price, to show a discount |
on_hand |
Stock of every variant |
width, height, depth, weight |
Size of every variant, used by the weight and volume based shipping calculators |
variant_dimensions |
Size per variant, keyed like variant_prices: a pack of 8 glasses does not weigh what a pack of 2 does |
shipping_category |
Shipping category code, assigned to every variant. Sylius never sets it, so any shipping method bound to a category would be discarded at checkout |
translations |
name, slug, short_description, description, meta_keywords and meta_description per locale. Sylius writes the same translation in every locale |
sylius_fixtures: suites: my_suite: fixtures: product: options: custom: - code: 'chianti_docg' name: 'Chianti DOCG' price: 9.50 minimum_price_ratio: 0.75 on_hand: 180 tracked: true shipping_category: 'bottles' weight: 1.3 width: 8.0 height: 32.0 depth: 8.0 translations: it_IT: name: 'Chianti DOCG' short_description: 'Sangiovese fresco e sapido.' en_US: name: 'Chianti DOCG' short_description: 'Fresh and savoury Sangiovese.'
Product attributes
| Option | Description |
|---|---|
translations |
Name of the attribute per locale |
The values of the attributes are translated from the product, where a value is either a scalar, written in every locale as Sylius does, or a map of locale to value:
product_attributes: winery: 'Ruffino' region: it_IT: 'Toscana' en_US: 'Tuscany' fr_FR: 'Toscane'
Product options
| Option | Description |
|---|---|
translations |
Name of the option per locale |
values |
Every value is either a string, written in every locale as Sylius does, or a map of locale to value |
product_option: options: custom: - name: 'Numero di calici' code: 'number_of_glasses' translations: it_IT: 'Numero di calici' en_US: 'Number of glasses' values: two_glasses: it_IT: '2 calici' en_US: '2 glasses'
The variants of a configurable product are named after their option values in every locale: Sylius names them once, in whatever locale the entity happens to be in, so a configurable product would end up with its variants translated in a single language.
Taxons
| Option | Description |
|---|---|
images |
Images of the taxon, at any level of the tree. Sylius ignores them completely in its own fixtures |
taxon: options: custom: category: code: 'category' images: - { path: '@WebgriffeSyliusFixturesPlugin/fixtures/images/wines/enoteca_1.webp', type: 'main' } children: - code: 'red_wines' images: - { path: '@WebgriffeSyliusFixturesPlugin/fixtures/images/wines/vino_rosso_1.webp', type: 'main' }
A taxon declared in several fixtures files gets its images added once per declaration: keep them in a single file, as the demo store does with its root category.
Shipping methods
| Option | Description |
|---|---|
category_requirement |
match_any (default in Sylius), match_all or match_none |
shipping_method: options: custom: standard: code: 'standard' name: 'Standard courier' zone: 'IT' category: 'bottles' category_requirement: 'match_all'
Orders
The demo orders are created in the default locale of the channel, and their addresses are generated with a faker localized on the country of the address instead of the American one used by Sylius.
Sylius picks a random locale and then loads the products joining only the translation of that locale: reading the product name in another locale creates an empty translation and breaks the flush on a multi locale channel.
Price history (Omnibus)
The price_history fixture writes the past prices of a product, so the shop can show the lowest price of the
last 30 days required by the Omnibus directive. Sylius only logs the price of the moment the fixtures run, so
without it every product looks like it has always had its current price and the line never shows anything
useful.
price_history: options: products: chianti_docg: entries: - { days_ago: 50, price: 15.90 } - { days_ago: 26, price: 13.90 }
Do not list the price of today: the fixture logs it by itself as the last entry, and Sylius excludes exactly that entry from the computation. It then runs the Sylius processor, so the lowest price is computed the same way it would be in production.
The lowest price is stored only when the variant is discounted, that is either:
- a catalog promotion applies to it, and the price is recomputed on every run (remember to consume the
messenger
maintransport, the promotions are applied asynchronously); - or the product declares an
original_pricehigher than its price, a markdown made by hand.
Never combine the two on the same product: the catalog promotion recomputes the price from the original one, overwriting the markdown.
The demo store
Import the fixtures file of the plugin to get the webgriffe suite:
# config/packages/sylius_fixtures.yaml imports: - { resource: '@WebgriffeSyliusFixturesPlugin/Resources/config/app/fixtures.yaml' }
bin/console sylius:fixtures:load webgriffe -n
# catalog promotions are applied asynchronously
bin/console messenger:consume main --time-limit=60
The variants of the demo store are tracked, and the demo orders decrease their inventory: their stock is therefore generous (200 units and up) so that a random set of orders can never exhaust a variant and break the loading. Lower it in your own suite if you need to demo the out of stock behaviour.
It creates an Italian wine shop: the ecommerce channel in three locales (it_IT, en_US, fr_FR) with prices in
euro, shipping to Europe only, 27 wines, 5 configurable sets of glasses, 4 food and wine experiences (nothing to
ship, VAT 10%), promotions, 20 orders, 40 reviews and 20 customers.
The pictures are public domain (CC0) photos, their origin is tracked in
src/Resources/fixtures/images/CREDITS.md.
Contributing
composer install
composer suite # ecs + phpstan + phpunit
License
This plugin is under the MIT license. See the complete license in the LICENSE file.