sylius/assortment-bundle
Sylius Assortment Bundle delivers the product catalog domain for Sylius e-commerce, modeling products, variants, options, and taxonomy with Doctrine and Symfony integration. It lets teams build flexible, variant-aware assortments and manage catalog data for online stores and sales channels.
This is not a Laravel package. sylius/assortment-bundle is a Symfony 2 bundle from the pre-1.0 Sylius era, archived, with PHP 5.x era constraints and a Doctrine ORM domain model wired into Symfony's DI container. Installing it in a modern Laravel app will fail on composer require before you write a line of code, and even if you force it, there is no service provider, no Eloquent mapping, and no maintained branch.
Treat the repository as a domain-model reference, not a dependency.
Minimal steps that actually pay off:
Model/ for Product, Variant, Option, OptionValue, Property, and the master-variant concept.Resources/config/doctrine/*.orm.xml or YAML) to see the intended cardinalities: product → many variants, variant ↔ many option values, product → many properties.DependencyInjection/Configuration.php to see which classes were designed to be swappable.First use case: you are building a catalog where a t-shirt has size and color, and you need one SKU per combination. Copy the relationship shape from this bundle into four or five Laravel migrations, then discard the rest. That is the highest-value 30 minutes you will get from this package.
If you genuinely must run it (legacy Symfony 2 app), note it is archived and pinned to EOL Symfony/PHP versions. Budget for a rewrite, not an upgrade.
1. Port the schema, not the code. The value is the normalized model. A minimal Eloquent translation:
// products: id, name, slug, ...
// variants: id, product_id, sku, price, is_master
// options: id, product_id, name (Size, Color)
// option_values: id, option_id, value (S, M, L / Red, Blue)
// variant_option_value: variant_id, option_value_id
// properties: id, name, type (Brand, Material — descriptive, not variant-defining)
// product_property: product_id, property_id, value
The distinction the bundle gets right and most homegrown catalogs get wrong: options drive variant generation; properties are descriptive metadata. Do not model "Brand" as an option unless you want one SKU per brand.
2. Variant generation as a service. The bundle's cartesian-product semantics are worth reimplementing directly:
class VariantGenerator
{
public function generate(Product $product, array $optionValueIds): Collection
{
$optionValues = OptionValue::whereIn('id', $optionValueIds)->get()
->groupBy('option_id');
$combinations = collect([[]]);
foreach ($optionValues as $values) {
$combinations = $combinations->crossJoin($values->all());
}
return $combinations->map(function (array $combo) use ($product) {
return DB::transaction(function () use ($product, $combo) {
$variant = $product->variants()->create([
'sku' => $this->skuFor($product, $combo),
'is_master' => false,
]);
$variant->optionValues()->sync(collect($combo)->pluck('id'));
return $variant;
});
});
}
}
Keep the master variant (the bundle's default purchasable entity when a product has no options) as a boolean flag on variants, and enforce exactly one per product with a partial unique index or a model observer.
3. Wrap the domain in repositories/managers, mirroring the bundle's manager layer. The original had ProductManager-style services precisely so controllers stayed thin. In Laravel that means a CatalogService or repository, not fat models:
class ProductManager
{
public function createWithVariants(array $data, array $optionValueIds): Product { /* ... */ }
public function findPurchasableBySku(string $sku): ?Variant { /* ... */ }
}
This keeps the option/property logic out of controllers and makes it testable without HTTP.
4. Integration tip — don't bridge containers. If you need the bundle's behavior alongside Laravel, do not attempt to boot a Symfony kernel inside Laravel. Extract the model and reimplement. If you're in a mixed environment, run the Symfony app as a separate service and expose catalog reads over HTTP, then consume it from Laravel with a thin client. Anything else is a maintenance sink.
composer why-not sylius/assortment-bundle before spending time on an install attempt.(product_id, sorted_option_value_ids_hash) or compute a deterministic hash column when generating variants.Product model class in config.yml). That pattern is worth copying conceptually — store model class names in config so a future fork can swap implementations — but it does not map to Laravel's container.How can I help you explore Laravel packages today?