Weave Code
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

Cart Bundle Laravel Package

ekyna/cart-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Run:

    composer require ekyna/cart-bundle
    

    Add to config/bundles.php:

    Ekyna\CartBundle\EkynaCartBundle::class => ['all' => true],
    
  2. Publish Config

    php artisan vendor:publish --provider="Ekyna\CartBundle\EkynaCartBundle" --tag="config"
    

    This generates config/ekyna_cart.php. Update with your cart settings (e.g., session driver, cart lifetime).

  3. First Use Case: Adding Items Inject the CartManager service into a controller or service:

    use Ekyna\CartBundle\Manager\CartManager;
    
    public function __construct(private CartManager $cartManager) {}
    
    public function addToCart(Request $request, $productId, $quantity = 1) {
        $product = $this->productRepository->find($productId);
        $this->cartManager->add($product, $quantity);
        return redirect()->back()->with('success', 'Added to cart!');
    }
    
  4. Viewing the Cart Use the Cart service to render cart contents in a Blade template:

    @foreach($cart->getItems() as $item)
        <li>{{ $item->getProduct()->getName() }} ({{ $item->getQuantity() }})</li>
    @endforeach
    

Implementation Patterns

Core Workflows

  1. Cart Operations

    • Add Items: $cartManager->add($product, $quantity)
    • Update Quantity: $cartManager->update($productId, $newQuantity)
    • Remove Item: $cartManager->remove($productId)
    • Clear Cart: $cartManager->clear()
  2. Session-Based Cart The bundle uses Symfony’s session component by default. Configure the session driver in config/ekyna_cart.php:

    'driver' => 'session', // or 'database', 'redis', etc. (if extended)
    'lifetime' => 86400, // 24 hours
    
  3. Product Integration Ensure your Product entity implements Ekyna\CartBundle\Model\ProductInterface:

    use Ekyna\CartBundle\Model\ProductInterface;
    
    class Product implements ProductInterface {
        public function getId(): string|int { ... }
        public function getName(): string { ... }
        public function getPrice(): float { ... }
        public function getImageUrl(): ?string { ... }
    }
    
  4. Cart Events Listen for cart events (e.g., cart.item.added) via Symfony’s event dispatcher:

    $eventDispatcher->addListener('cart.item.added', function (CartEvent $event) {
        // Log or notify when an item is added
    });
    
  5. API Integration For APIs, use the CartManager to manipulate carts via HTTP requests:

    // Add to cart via API
    $request->request->add(['product_id' => 123, 'quantity' => 2]);
    $this->cartManager->addFromRequest($request);
    

Advanced Patterns

  1. Custom Cart Storage Extend the CartStorageInterface to use a database or Redis:

    class DatabaseCartStorage implements CartStorageInterface {
        public function save(Cart $cart) { ... }
        public function load(string $cartId): ?Cart { ... }
    }
    

    Bind it in config/ekyna_cart.php:

    'storage' => Ekyna\CartBundle\Storage\DatabaseCartStorage::class,
    
  2. Cart Validation Validate cart items before checkout (e.g., stock availability):

    $validator = new CartValidator();
    $errors = $validator->validate($cart);
    if ($errors->count() > 0) {
        throw new \RuntimeException('Cart validation failed');
    }
    
  3. Multi-Cart Support Use the CartManager to switch between carts (e.g., for guest vs. logged-in users):

    $guestCart = $cartManager->createCart('guest_' . $request->ip());
    $userCart = $cartManager->createCart('user_' . auth()->id());
    
  4. Checkout Workflow

    • Calculate total: $cart->getTotal()
    • Apply discounts: $cart->applyDiscount($code)
    • Persist cart before checkout (e.g., to database):
      $cartManager->save($cart);
      

Gotchas and Tips

Common Pitfalls

  1. Session Driver Issues

    • If using the default session driver, ensure SESSION_DRIVER is configured in .env (e.g., SESSION_DRIVER=file).
    • For production, use redis or database to avoid session file locks:
      SESSION_DRIVER=redis
      REDIS_HOST=127.0.0.1
      
  2. Product Interface Mismatch

    • Forgetting to implement ProductInterface will throw RuntimeException when adding items to the cart.
    • Fix: Ensure all product models implement getId(), getPrice(), etc.
  3. Cart Lifetime Expiry

    • The cart expires after lifetime seconds (default: 86400). For persistent carts (e.g., abandoned carts), extend the lifetime or switch to a database-backed storage.
  4. Concurrent Requests

    • Session-based carts may cause race conditions if multiple tabs/windows are open. Use database/Redis storage for shared sessions.
  5. Event Dispatcher Not Bound

    • If cart events (e.g., cart.item.added) aren’t firing, ensure the EventDispatcher is bound in the bundle’s services:
      # config/services.yaml
      Ekyna\CartBundle\Event\CartEvents::class: ~
      

Debugging Tips

  1. Log Cart Contents Add a temporary route to inspect the cart:

    Route::get('/debug-cart', function () {
        return response()->json($this->cartManager->getCart()->getItems());
    });
    
  2. Check Session Data Dump session data to verify cart storage:

    dd($request->getSession()->all());
    
  3. Validate Product Data Ensure product IDs/prices are serializable (no circular references or non-public properties).


Extension Points

  1. Custom Cart Item Model Extend Ekyna\CartBundle\Model\CartItem to add metadata (e.g., custom attributes):

    class CustomCartItem extends CartItem {
        public function setAttribute(string $key, $value) { ... }
        public function getAttribute(string $key) { ... }
    }
    
  2. Plugin System Create a CartPlugin interface to add functionality (e.g., taxes, shipping):

    interface CartPlugin {
        public function apply(Cart $cart);
    }
    

    Register plugins in config/ekyna_cart.php:

    'plugins' => [
        Ekyna\CartBundle\Plugin\TaxPlugin::class,
        App\Plugin\CustomShippingPlugin::class,
    ],
    
  3. Override Cart Storage Replace the default storage with a custom implementation (e.g., for analytics):

    $cartManager->setStorage(new AnalyticsCartStorage());
    
  4. Localization Extend the bundle’s translation files (resources/translations) for multi-language support.


Configuration Quirks

  1. Default Cart ID The bundle uses default as the cart ID by default. Override in config:

    'default_cart_id' => 'user_cart_' . auth()->id(),
    
  2. Floating-Point Precision Use round() when calculating totals to avoid precision issues:

    $total = round($cart->getTotal(), 2);
    
  3. Lazy Loading The bundle may lazy-load cart items. Eager-load in templates:

    $cart->getItems()->load('product'); // If using Eloquent
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware