From f3c4ddae6edf6058f76fe0fc0af9dae7ef226d36 Mon Sep 17 00:00:00 2001 From: Joel Male Date: Sat, 13 Jun 2026 14:11:20 +1000 Subject: [PATCH] docs: add v3 recommended patterns to upgrade guide and link from README --- README.md | 2 + UPGRADE.md | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/README.md b/README.md index a5bb622..fe45072 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ For Laravel 9.0 and below, please use version [1.0](https://github.com/wearepixel/laravel-cart/releases/tag/1.0.12) +> **Upgrading from v2?** See the [Upgrade Guide](UPGRADE.md) for breaking changes and recommended v3 patterns. + ## Table of Contents - [Getting Started](#-getting-started) diff --git a/UPGRADE.md b/UPGRADE.md index aa73c99..edd4c49 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -58,3 +58,108 @@ ### Non-breaking additions - **HasCart trait:** Livewire reactive cart state - **ShareCartWithInertia:** static class for Inertia middleware integration - **Artisan generators:** `cart:install`, `cart:make:coupon`, `cart:make:tax`, `cart:make:shipping`, `cart:make:driver`, `cart:debug` + +--- + +### Recommended v3 patterns + +v3 is fully backwards compatible - your existing code will continue to work unchanged. The following patterns are recommended for new code and worth migrating to when you touch existing cart logic. + +#### 1. Publish the updated config + +Run the installer to get the new `driver` key and storage configuration in your `config/cart.php`: + +```bash +php artisan cart:install +``` + +The default driver is `session`, so behaviour is identical to v2 unless you change it. + +#### 2. Replace raw CartCondition arrays with first-class objects + +Generate typed classes with Artisan instead of constructing arrays inline: + +```bash +php artisan cart:make:coupon TenPercentOff +php artisan cart:make:tax GstTaxRule +php artisan cart:make:shipping FlatRateShipping +``` + +**Before:** + +```php +$condition = new CartCondition([ + 'name' => 'SAVE10', + 'type' => 'coupon', + 'target' => 'subtotal', + 'value' => '-10%', +]); + +Cart::condition($condition); +``` + +**After:** + +```php +// app/Cart/Coupons/TenPercentOff.php +class TenPercentOff extends Coupon +{ + protected string $code = 'SAVE10'; + protected string $value = '-10%'; + protected string $target = 'subtotal'; + + public function isValid(): bool + { + return true; + } +} + +Cart::coupon(new TenPercentOff); +Cart::tax(new GstTaxRule); +Cart::shipping(new FlatRateShipping); +``` + +The same pattern applies to `TaxRule` (implement `isApplicable()`) and `ShippingRate` (implement `isApplicable()`). + +#### 3. Use Cart::fake() in tests instead of mocking + +**Before:** + +```php +// Mocking the session or binding a fake driver manually +$this->mock(CartDriver::class, function ($mock) { + $mock->shouldReceive(...); +}); +``` + +**After:** + +```php +$factory = app('cart')->fake(); + +$factory->withItems(3)->withCondition(new GstTaxRule); + +$cart = app('cart'); +$cart->assertCount(3); +$cart->assertConditionApplied('GST'); +$cart->assertTotal(33.00); +``` + +`Cart::fake()` swaps the driver to an in-memory `NullDriver` for the duration of the test - no session, database, or Redis needed. + +#### 4. Switch to a persistent driver (optional) + +If you want cart state to survive beyond a session, update `config/cart.php`: + +```php +'driver' => 'database', // or 'redis' +``` + +For the database driver, publish and run the migration: + +```bash +php artisan cart:install +php artisan migrate +``` + +See the [Storage Drivers](README.md#storage-drivers) section of the README for full configuration options.