Getting Started
Treat sylius/cart as a framework-agnostic PHP domain library, not a Laravel package. It will not register a service provider, publish config, ship migrations, or provide Eloquent models. The repository metadata is incomplete and the package is archived, so verify the actual source and composer.json constraints before installing.
Minimal steps:
- Inspect
composer.json for PHP/Symfony/Doctrine constraints and confirm compatibility with your Laravel version.
- Read the domain contracts first:
CartInterface, CartItemInterface, repository/provider/context interfaces, and the item resolver/operator classes.
- Read the tests to understand expected lifecycle: create cart, add item, change quantity, remove item, recalculate totals.
- Wire it manually into Laravel through your own service class and repository adapters.
First practical use case: an anonymous session cart with “add product” behaviour. You provide product lookup, persistence, pricing, tax, and stock validation; the package supplies cart/item domain primitives.
// Pseudo-code: verify exact method names against the package source.
$cart = $cartRepository->findActiveForSession($sessionId)
?? $cartFactory->createNew();
$item = $cartItemFactory->createNew();
$item->setProduct($productReference); // or variant, depending on source interfaces
$item->setQuantity(1);
$item->setUnitPrice($priceInMinorUnits);
$cart->addItem($item);
$cart->recalculateTotal();
$cartRepository->save($cart);
Implementation Patterns
Use the package behind a Laravel service layer. Controllers, Livewire components, and API endpoints should call something like CartService::addItem() rather than manipulating package models directly.
Common integration patterns:
- Repository adapter: implement the package repository interface using Eloquent or session storage. Keep package cart models separate from Eloquent models unless you intentionally extend them.
- Cart identity: store only the cart ID in session, not the serialized cart. Resolve the active cart by session ID for guests and user ID for authenticated users.
- Guest-to-user merge: on login, merge or reassign the guest cart; define whether quantities are summed, maxed, or replaced.
- Product snapshots: persist product/variant ID, SKU, name, and unit price on the cart item at add time. Recalculate according to your business rules, but do not depend on live product data for historical carts.
- Money handling: store minor units as integers. Keep tax, shipping, discounts, and rounding in your own calculators after cart mutations.
- Persistence: use
carts and cart_items tables with user_id/session_id, currency, locale, status, timestamps, and a unique active-cart constraint where appropriate.
- Transactions and locking: wrap add/update/remove and total recalculation in a transaction; lock the cart row to avoid duplicate concurrent additions.
- Events: dispatch Laravel events from your service layer (
CartItemAdded, CartUpdated) instead of relying on the package’s event system, which may be Symfony-oriented.
- Testing: unit-test cart operations against an in-memory repository and feature-test HTTP endpoints. Freeze currency, locale, and time where pricing is involved.
- Exit strategy: isolate the package behind your own interfaces. Because it is archived, assume you may replace it with a Laravel-native cart implementation later.
If you are using full Sylius already, follow its checkout/order integration. For a standalone Laravel shop, use the package only if its domain model materially saves work.
Gotchas and Tips
- Archived package: no security updates, PHP compatibility fixes, or maintenance. Pin an exact version, fork if necessary, and plan a replacement. Do not choose it for a greenfield Laravel project without a strong reason.
- Not Laravel-native: no auto-discovery, no migrations, no config, no Blade views. You must wire repositories, factories, providers, and persistence yourself.
- Dependency conflicts: Sylius components often pull Symfony/Doctrine contracts. Check
composer why-not sylius/cart and test against your Laravel/PHP versions before committing.
- Do not assume Eloquent: package models may not extend
Model, may not have save(), and may not define relationships. Use mappers or adapters.
- Avoid session serialization: do not put full cart objects with ORM models into the session. Store the cart ID and reload it.
- Validate outside the package: stock availability, minimum/maximum quantity, product status, and price changes are your responsibility.
- Recalculate totals after every mutation: quantity changes, item removal, discounts, tax, and currency changes should all funnel through one recalculation path.
- Watch identity edge cases: duplicate active carts, logout/login, session expiry, and merging guest carts are common production bugs.
- Debug with the interfaces and tests: start from the failing service method, log cart ID/session/user ID, and inspect the package tests for expected behaviour.
- Extension points: prefer custom repositories, item resolvers, providers/contexts, operators/modifiers, and factories over modifying vendor code. Keep overrides in
app/ and document them.
- Simple-cart alternative: if you only need add/update/remove with session persistence, a small Laravel service plus
carts/cart_items tables is often safer than adopting an archived Sylius component.