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

Shipping Bundle Laravel Package

elcodi/shipping-bundle

Symfony shipping bundle from the Elcodi e-commerce suite, providing shipping rule and method management for handling order shipments. MIT licensed and read-only; contributions and issues go through the main elcodi/elcodi repository.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the compatibility reality first. elcodi/shipping-bundle is a read-only split of the Elcodi monorepo, last tagged in Feb 2016, archived, with zero dependents. It targets Symfony 2.x and PHP 5.x/7.0-era APIs. You will only get value from it if you are maintaining or migrating an existing Elcodi shop — do not start a new project on it.

  1. Pin a version. The README suggests dev-master for the "last commit", but on a dead repo that is the worst option. Use the last stable tag (^1.0 range) and commit composer.lock.
  2. Register the bundle in app/AppKernel.php after its dependencies (Core, Cart, Currency, Geo/Zone, Media if you use method images, Rule for expressions):
    new Elcodi\Bundle\ShippingBundle\ElcodiShippingBundle(),
    
  3. Look at the monorepo, not the split repo. The split only ships the bundle; the useful reference code lives at:
    • src/Elcodi/Bundle/ShippingBundle/ — DI extension, Resources/config/*.yml (service ids), Resources/config/doctrine/*.orm.yml (schema), form types, Twig views.
    • src/Elcodi/Component/Shipping/ — entities (ShippingMethod, Carrier, Warehouse, ranges, ShippingRule), factories, repositories.
    • Tests/Functional/ — the best documentation for how services are actually wired.
  4. First use case: create a carrier + shipping method with weight ranges and attach it to a cart. Elcodi's convention is elcodi.<entity>_factory / elcodi.<entity>_manager / elcodi.repository.<entity>; confirm the exact ids in Resources/config/services.yml before copying snippets:
    $carrier = $this->get('elcodi.carrier_factory')->create();
    $carrier->setName('MRW')->setEnabled(true);
    $this->get('elcodi.carrier_manager')->save($carrier);
    
    $method = $this->get('elcodi.shipping_method_factory')->create();
    $method->setName('Standard 24h')->setCarrier($carrier)->setEnabled(true);
    // ranges: from/to define the band the cart total or weight falls into
    $method->addRange($rangeFactory->create()->setFrom(0)->setTo(5));
    $this->get('elcodi.shipping_method_manager')->save($method);
    
    $cart->setShippingMethod($method);  // cart recalculates totals from here
    

Implementation Patterns

Always build entities through factories. Elcodi entities have defaults (enabled flags, empty collections, generated ids) applied by the factory create(). Constructing entities with new skips those and produces rows that fail silently in listings or rule evaluation.

Manager for writes, repository for reads. elcodi.<entity>_manager wraps the Doctrine EntityManager and dispatches Elcodi's pre/post save/delete events. Repositories (elcodi.repository.shipping_method, elcodi.repository.carrier, …) expose the read side and custom finders. Keep that split: bypassing the manager means listeners (image handling, event-driven cache busting) never fire.

Model shipping cost as ranges, not code. A shipping method owns a collection of range entities; the applicable price is the range whose from/to covers the cart's weight or amount. Add ranges via addRange() and persist through the method manager, not by saving ranges independently — the owning side is the method.

Eligibility belongs in ShippingRule, not controllers. Rules carry an expression string evaluated by the rule/expression-language service. Use this for "free over €50", "only for zone X", "max 20 kg" instead of branching in your checkout controller. If you need new vocabulary, register custom functions on the expression language through the rule bundle rather than editing the shipping bundle.

Integrate at the cart boundary. The shipping bundle is a dumb data provider: you set the method on the cart/order, and the cart's cost calculator reads ranges back. If you need per-order overrides (manual discount, negotiated rate), decorate the shipping cost calculator service in your app's services.yml instead of forking the bundle.

Reuse the shipped form types (Form/Type/) for admin CRUD. They already wire the carrier/warehouse/ranges relationships; hand-rolled forms usually miss the collection by_reference setting and end up orphaning range rows.

Override entities via container parameters, not by editing vendor. Elcodi bundles resolve entity classes from parameters (elcodi.entity.*.class-style keys in the bundle's configuration). Subclass the base entity, point the parameter at your class, and extend the Doctrine mapping in your own bundle so your extra columns survive schema updates.

Gotchas and Tips

  • It is archived. No security fixes, no Symfony 3/4/5/6 support, getRequest()-era APIs. If you must keep it, fork it internally and add replace in composer so transitive constraints resolve.
  • resolve_target_entities is mandatory. Because the component ships interfaces, Doctrine needs concrete Carrier, Warehouse, and ShippingMethod mappings in your app config. Miss this and you get "target entity … does not exist" at schema time or Class not found on hydration.
  • Zero-cost bug. If no range matches, the computed shipping cost is typically 0 — it will not throw. Boundary semantics (from/to inclusivity, null for open-ended) are the usual culprit. Add an explicit test for the exact weight/amount at each boundary.
  • Unit mismatch. Cart totals and product weights are stored in whatever unit the currency/measure configuration uses; the ranges you seed in fixtures must use the same unit. A grams-vs-kilograms mismatch looks like "shipping is always free".
  • Direct EntityManager saves skip events. If images or slugs are missing after a bulk import, that is why. Use the manager's save(), or dispatch the equivalent events yourself.
  • N+1 on ranges. Cart recalculation loads the method's ranges and images per line item. Profile with the Doctrine panel; add fetch="EAGER"/join fetch in a custom repository finder if you have many methods.
  • Images require MediaBundle. If the image resolver service is not wired, the method image handling breaks at save time. Disable images in config if you are not using Media.
  • Debugging: app/console debug:container elcodi.shipping (or plain container:debug on older versions), doctrine:schema:validate, and doctrine:mapping:info will resolve 90% of "service not found" and mapping errors faster than reading the source.
  • Extension points to prefer, in order: config parameters → decorating the cost calculator / rule resolver → custom form types and Twig overrides in Resources/views → subclassing entities. Patching the vendor copy is a last resort and will be lost on the next composer install.
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