Search by

webgriffe / sylius-fixtures-plugin

lruozzi9

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

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-master / 1.0.x-dev 2026-09-25 16:24 UTC

This package is not auto-updated.

Last update: 2026-09-29 13:58:31 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

The slug of each locale is generated from the name of that locale when the translation does not state one: Sylius generates it once, from the first name it reads, so a product translated in several languages would answer on the same url everywhere.

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.'

Orders

Option Description
state completed (default) or cancelled, to show cancelled orders in the admin as well
                cancelled_orders:
                    name: order
                    options:
                        amount: 3
                        channel: 'ecommerce'
                        state: 'cancelled'

The payments fixture completes the payments without checking whether the transition is allowed, so declare it before the fulfilled and the cancelled orders, or it will try to pay an order that cannot be paid.

Payment methods

Option Description
translations name, description and instructions per locale

The instructions are the text the customer reads after placing the order, the place for the bank details of an offline transfer.

Product association types

Option Description
translations Name of the association type per locale

The similar_product_association fixture of Sylius creates its own type named "Similar products", hard coded and identical in every locale. Declare product_association_type and product_association instead, as the demo store does: it also lets you choose the associations rather than picking them at random.

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
translations name and description per locale: Sylius writes the same ones in every locale
min_delivery_time_days, max_delivery_time_days Estimated delivery time, shown at the checkout
                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, their addresses are generated with a faker localized on the country of the address instead of the American one used by Sylius, and every shipped shipment carries a tracking code, which Sylius never writes. Every address also carries its province: the code of a real province where the country has them (Italy in the demo store), the name of a region as free text everywhere else.

The regions are a table of the plugin, not faker data: half of its locales have no region at all, and some fall back to the American states, so a Bulgarian address would end up in Vermont.

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.

Customers

Option Description
subscribed_to_newsletter Subscribes the customer to the newsletter, which the Sylius fixtures never set
                shop_user:
                    options:
                        custom:
                            -   email: 'cliente@webgriffe.com'
                                first_name: 'Mario'
                                last_name: 'Rossi'
                                password: 'webgriffe'
                                subscribed_to_newsletter: true

Promotions

Fixture Option Description
catalog_promotion translations label and description per locale
promotion translations The label per locale, the text the customer reads on the cart
                catalog_promotion:
                    options:
                        custom:
                            white_wines:
                                code: 'white_wines'
                                name: 'White wine week'
                                translations:
                                    it_IT:
                                        label: 'Settimana dei bianchi: 10% di sconto'
                                        description: 'Tutti i bianchi in catalogo scontati del 10%.'
                                    en_US:
                                        label: 'White wine week: 10% off'
                                        description: 'Every white in the catalogue is 10% off.'

The description of a cart promotion is not translatable in Sylius: it lives on the promotion itself, next to its name, and it is only read in the administration.

Provinces

The province fixture creates the provinces of a country with their abbreviation, which the geographical fixture of Sylius leaves empty: it only takes a code and a name. Declare it after geographical, the countries have to exist.

                province:
                    options:
                        countries:
                            IT:
                                IT-BO:
                                    name: 'Bologna'
                                    abbreviation: 'BO'

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 main transport, the promotions are applied asynchronously);
  • or the product declares an original_price higher 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.