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

Flexicart Laravel Package

daikazu/flexicart

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require daikazu/flexicart
    

    Publish the config file:

    php artisan vendor:publish --provider="Daikazu\FlexiCart\FlexiCartServiceProvider" --tag="config"
    
  2. Configuration:

    • Update config/flexicart.php to match your database structure (e.g., cart_items table).
    • Define default cart behavior (e.g., session driver, item model).
  3. First Use Case: Add an item to the cart in a controller:

    use Daikazu\FlexiCart\Facades\FlexiCart;
    
    FlexiCart::add([
        'id' => 123,
        'name' => 'Product Name',
        'price' => 19.99,
        'quantity' => 1,
        'options' => ['color' => 'blue'],
    ]);
    

    Retrieve cart contents in a Blade view:

    $cart = FlexiCart::get();
    

Key Entry Points

  • Facade: Daikazu\FlexiCart\Facades\FlexiCart (e.g., FlexiCart::add(), FlexiCart::get()).
  • Service Provider: Registers cart events and binds interfaces.
  • Middleware: flexicart (optional, for cart persistence).

Implementation Patterns

Core Workflows

  1. Adding Items:

    • Basic: Use FlexiCart::add() with an associative array (required keys: id, name, price).
    • Dynamic: Extend with custom attributes (e.g., options, meta).
    • Bulk Add: Loop through products and add to cart in a single request.
    foreach ($products as $product) {
        FlexiCart::add([
            'id' => $product->id,
            'name' => $product->name,
            'price' => $product->price,
            'quantity' => $request->input('quantity', 1),
        ]);
    }
    
  2. Updating/Cart Management:

    • Update quantity: FlexiCart::update($id, ['quantity' => 5]).
    • Remove item: FlexiCart::remove($id).
    • Clear cart: FlexiCart::clear().
  3. Cart Persistence:

    • Session Driver: Default (stateless, ephemeral).
    • Database Driver: Configure in config/flexicart.php to persist carts across sessions.
      'driver' => 'database',
      'model' => Daikazu\FlexiCart\Models\Cart::class,
      
  4. Checkout Flow:

    • Validate cart: FlexiCart::validate() (customize via events).
    • Apply discounts: Use FlexiCart::applyDiscount() with a callable.
    • Finalize: FlexiCart::checkout() (triggers cart.checkout event).

Integration Tips

  • Blade Directives: Use @flexicart to render cart contents in views:

    @flexicart
        <div class="cart-summary">
            @foreach($cart->items as $item)
                {{ $item->name }} x {{ $item->quantity }}
            @endforeach
        </div>
    @endflexicart
    
  • Events: Listen for cart changes (e.g., cart.item.added, cart.checkout):

    event(new \Daikazu\FlexiCart\Events\CartItemAdded($item));
    
  • APIs: Expose cart endpoints (e.g., /api/cart) using FlexiCart::get() and FlexiCart::update().

  • Testing: Mock the facade in tests:

    $this->partialMock(FlexiCart::class, function ($mock) {
        $mock->shouldReceive('get')->andReturn($mockCart);
    });
    

Gotchas and Tips

Pitfalls

  1. Session vs. Database Driver:

    • Session: Cart resets on browser close or session expiry.
    • Database: Requires cart_id (auto-generated or manual) and may need cleanup for abandoned carts.
    • Fix: Use FlexiCart::setCartId() to manually set cart IDs (e.g., for guest users).
  2. Item Uniqueness:

    • Items are identified by id + options hash. Changing options creates a new item.
    • Workaround: Use a unique sku field instead of id if needed.
  3. Price Updates:

    • Prices are stored as-is when added. Use FlexiCart::refreshPrices() to sync with current product prices.
    • Tip: Bind to cart.item.added to auto-refresh prices.
  4. Concurrency Issues:

    • Database driver may cause race conditions if multiple users edit the same cart simultaneously.
    • Solution: Implement optimistic locking with version column in cart_items.
  5. Serialization:

    • Custom objects in options or meta must be serializable. Use arrays or JSON strings.
    • Example:
      'options' => ['size' => 'M', 'custom_data' => json_encode($object)],
      

Debugging

  • Log Cart Contents:
    \Log::debug('Cart contents:', ['items' => FlexiCart::get()->items]);
    
  • Check Events: Listen for cart.* events to trace cart state changes:
    \Daikazu\FlexiCart\Events\CartItemAdded::dispatch($item);
    

Configuration Quirks

  1. Table Names:

    • Defaults to cart_items and carts. Override in config:
      'tables' => [
          'items' => 'shopping_cart_items',
          'carts' => 'user_carts',
      ],
      
  2. Guest vs. Auth Users:

    • Database driver requires cart_id. For guests, generate a UUID:
      FlexiCart::setCartId(str()->uuid());
      
  3. Custom Models:

    • Extend Daikazu\FlexiCart\Models\CartItem to add fields (e.g., tax_rate):
      php artisan make:model CartItemExtension --extends=Daikazu\FlexiCart\Models\CartItem
      
    • Update the config to point to your extended model.

Extension Points

  1. Custom Validation: Override default validation (e.g., stock checks) by binding to cart.validate event:

    \Event::listen(\Daikazu\FlexiCart\Events\CartValidate::class, function ($event) {
        foreach ($event->cart->items as $item) {
            if ($item->quantity > $item->product->stock) {
                $event->fail("Out of stock: {$item->name}");
            }
        }
    });
    
  2. Storage Drivers: Implement Daikazu\FlexiCart\Contracts\CartDriver for custom storage (e.g., Redis):

    class RedisCartDriver implements CartDriver {
        public function get($cartId) { ... }
        public function save($cart) { ... }
    }
    

    Register in FlexiCartServiceProvider.

  3. Item Normalization: Modify how items are stored by extending Daikazu\FlexiCart\CartItemNormalizer:

    FlexiCart::extend(function ($app) {
        $app->bind(\Daikazu\FlexiCart\Contracts\CartItemNormalizer::class, CustomNormalizer::class);
    });
    
  4. Checkout Logic: Replace default checkout behavior by binding to cart.checkout and implementing your own logic (e.g., order creation):

    \Event::listen(\Daikazu\FlexiCart\Events\CartCheckout::class, function ($event) {
        $order = Order::createFromCart($event->cart);
        $event->markAsProcessed(); // Prevents default checkout
    });
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle