Installation:
composer require daikazu/flexicart
Publish the config file:
php artisan vendor:publish --provider="Daikazu\FlexiCart\FlexiCartServiceProvider" --tag="config"
Configuration:
config/flexicart.php to match your database structure (e.g., cart_items table).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();
Daikazu\FlexiCart\Facades\FlexiCart (e.g., FlexiCart::add(), FlexiCart::get()).flexicart (optional, for cart persistence).Adding Items:
FlexiCart::add() with an associative array (required keys: id, name, price).options, meta).foreach ($products as $product) {
FlexiCart::add([
'id' => $product->id,
'name' => $product->name,
'price' => $product->price,
'quantity' => $request->input('quantity', 1),
]);
}
Updating/Cart Management:
FlexiCart::update($id, ['quantity' => 5]).FlexiCart::remove($id).FlexiCart::clear().Cart Persistence:
config/flexicart.php to persist carts across sessions.
'driver' => 'database',
'model' => Daikazu\FlexiCart\Models\Cart::class,
Checkout Flow:
FlexiCart::validate() (customize via events).FlexiCart::applyDiscount() with a callable.FlexiCart::checkout() (triggers cart.checkout event).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);
});
Session vs. Database Driver:
cart_id (auto-generated or manual) and may need cleanup for abandoned carts.FlexiCart::setCartId() to manually set cart IDs (e.g., for guest users).Item Uniqueness:
id + options hash. Changing options creates a new item.sku field instead of id if needed.Price Updates:
FlexiCart::refreshPrices() to sync with current product prices.cart.item.added to auto-refresh prices.Concurrency Issues:
version column in cart_items.Serialization:
options or meta must be serializable. Use arrays or JSON strings.'options' => ['size' => 'M', 'custom_data' => json_encode($object)],
\Log::debug('Cart contents:', ['items' => FlexiCart::get()->items]);
cart.* events to trace cart state changes:
\Daikazu\FlexiCart\Events\CartItemAdded::dispatch($item);
Table Names:
cart_items and carts. Override in config:
'tables' => [
'items' => 'shopping_cart_items',
'carts' => 'user_carts',
],
Guest vs. Auth Users:
cart_id. For guests, generate a UUID:
FlexiCart::setCartId(str()->uuid());
Custom Models:
Daikazu\FlexiCart\Models\CartItem to add fields (e.g., tax_rate):
php artisan make:model CartItemExtension --extends=Daikazu\FlexiCart\Models\CartItem
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}");
}
}
});
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.
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);
});
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
});
How can I help you explore Laravel packages today?