Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Product Bundle Laravel Package

elcodi/product-bundle

Product Bundle is part of Elcodi, a suite of e-commerce components and bundles built on Symfony under the MIT license. This read-only package provides product functionality for Elcodi-based stores; use the main elcodi/elcodi repository for issues and contributions.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a read-only split of the elcodi/elcodi monorepo and has been EOL/archived since 2016. Before you write any code, make the buy-vs-maintain decision: you are either (a) inheriting a legacy Elcodi app and need to understand this bundle, or (b) starting fresh, in which case you should not adopt it at all — use a maintained Symfony e-commerce stack (Sylius, Shopware, or custom Doctrine entities). The rest of this assessment assumes case (a).

Minimal steps for a legacy app:

  1. Confirm the dependency graph first. ProductBundle is not standalone — it hangs off elcodi/core-bundle, elcodi/attribute-bundle, elcodi/media-bundle, elcodi/currency-bundle, and elcodi/language-bundle. Check composer.json require and composer.lock; the split packages were tagged independently and often lag the monorepo, so elcodi/product-bundle:^1.0 alone rarely resolves.
  2. Register the bundle the way the existing app does it. On Symfony 2.x that's AppKernel::registerBundles(); on 3.x it's app/AppKernel.php or config/bundles.php. Look at how sibling Elcodi bundles are registered and copy that pattern — do not invent a new one.
  3. Import the bundle's DI config and routing. The bundle ships Resources/config/doctrine/*.orm.yml mappings and an extension class in DependencyInjection/. Run bin/console debug:container elcodi (or grep elcodi) to see which services actually exist in your app — service IDs differ by version.
  4. Verify the schema with bin/console doctrine:schema:validate before touching business logic.
  5. First use case: create a Product, attach a ProductVariant, persist via the product manager, and render it. This is the whole point of the bundle — Product is the catalogue entry, ProductVariant is the purchasable unit tied to attributes (size, colour, etc.).

Implementation Patterns

Understand the three-layer entity model before anything else. Product → ProductVariant → Variant. The Product holds translatable catalogue data (name, slug, description, media). The ProductVariant is the SKU-level record that joins a Product to attribute combinations and is what the cart/price layers actually reference. If you find yourself adding price or stock fields to Product, you are in the wrong entity.

Use the factories and managers, not new. The bundle wires factories (elcodi.factory.product, elcodi.factory.product_variant) and managers that handle persistence plus events. Constructing entities directly bypasses validation and the event dispatcher, and entities have required constructor arguments in several versions. Get the service from the container, call the factory, set fields, then ->save($entity) on the manager.

Translations are mandatory, not optional. Product name/slug/description are translatable via the elcodi/language-bundle pattern. A product with no translation for the current locale renders empty rather than falling back in every version — always create the translation object alongside the product in the same transaction.

Extend entities via resolve_target_entities, not by forking the mapping. Elcodi's intended extension point is the standard Doctrine mechanism: define your subclass, set the bundle's class parameters (the DIC extension exposes %elcodi.entity.product.class%-style parameters in the relevant versions — read DependencyInjection/ElcodiProductExtension.php in your installed tag, since parameter names changed between versions), and register doctrine.orm.resolve_target_entities. Verify with doctrine:mapping:info that your class won the resolution.

Hook business logic through events, not manager overrides. The bundle dispatches product/variant lifecycle events (constants live alongside the entity or in an *Events class). Subscribing with a listener is far more upgrade-safe than decorating managers, and it composes with the cart and pricing bundles that also listen.

Integration shape for a catalogue page: repository query (filter by enabled/showInHome in the repo, not in Twig) → controller → Twig partial that renders product.variants and picks the default variant. Keep the "which variant is purchasable" decision in a service — it is the piece most likely to need changing.

Treat the bundle as a legacy island. If you are rebuilding around it, wrap Elcodi services behind your own interfaces so a future migration does not touch controllers or templates. That wrapper is the single highest-value thing you can add.

Gotchas and Tips

  • No security patches, ever. Read-only means the maintainers explicitly ignore PRs on this repo. Any CVE in a transitive dependency (Symfony 2/3, old Doctrine, old Twig) is yours. Pin an exact commit or fork into a private VCS repository — do not leave a floating dev-master or ^1.0 in a production composer.json.
  • "Use last unstable version" advice in the README is a trap today. dev-master on an archived 2016 repo resolves to whatever the last commit was; tag aliases may no longer resolve because the Packagist metadata has drifted. Always install from a tagged version and commit the lockfile.
  • PHP and Doctrine compatibility is the first failure you'll hit. Composer constraints cap PHP at 5.x–7.0-era and Doctrine at 2.x. If you're on PHP 8 or DBAL 3, expect composer require to fail outright. Options: run the legacy app in a container on the original PHP version, or vendor the code and patch types yourself.
  • Split-repo version skew. elcodi/product-bundle may be tagged v1.0.x while elcodi/cart-bundle expects a different product-bundle API. Always bump the whole Elcodi family together and read the monorepo's CHANGELOG at the matching tag, not this package's.
  • Service IDs are version-dependent. Names like elcodi.factory.product vs elcodi.product.factory exist across releases. Never guess — dump the container and grep. bin/console debug:container --show-private | grep product is the fastest way out of a ServiceNotFoundException.
  • YAML mappings are fragile on overrides. If you override an entity, the original Resources/config/doctrine/*.orm.yml still loads unless you disable it. You'll get duplicate-mapping or "association refers to unknown target entity" errors. Check doctrine:mapping:info and, if needed, exclude the bundle mapping via the Doctrine config.
  • Debugging playbook: doctrine:schema:validate → doctrine:mapping:info → debug:container | grep elcodi → debug:event-dispatcher to see whether the product events you expect are actually wired. That sequence resolves most "nothing happens when I save" issues.
  • Extension point for tests: use the manager/factory services behind your own interfaces so unit tests can mock them. Testing against the real Elcodi container pulls in the whole bundle stack and is slow and brittle.
  • Set a migration budget. This bundle is a liability, not an asset. Scope a replacement (even a small custom Product/ProductVariant model) before you invest heavily; the 2016 data model is simple enough that a rewrite is usually cheaper than a PHP 8 port.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo