Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.x] Add methods to remove items and empty the cart #2

Merged
merged 9 commits into from
Jun 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,54 @@ $cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cart->storeItems($items);
```

### Delete Item From Cart

If you may to delete an item for a cart, you can use `removeItem` method:

```php
$items = [
[
'itemable' => $product1,
'quantity' => 2,
],
[
'itemable' => $product2,
'quantity' => 1,
],
[
'itemable' => $product3,
'quantity' => 5,
],
];

$cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cart->removeItem($product1);
```

### Delete All Items From Cart

If you may to delete all items from a cart, you can use `emptyCart` method:

```php
$items = [
[
'itemable' => $product1,
'quantity' => 2,
],
[
'itemable' => $product2,
'quantity' => 1,
],
[
'itemable' => $product3,
'quantity' => 5,
],
];

$cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cart->emptyCart();
```

<a name="contributors"></a>
## Contributors

Expand Down
54 changes: 54 additions & 0 deletions src/Models/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,36 @@ public function scopeFirstOrCreateWithStoreItems(
return $query;
}

/**
* Scope remove item from cart.
*/
public function scopeRemoveItem(Builder $query, Model $item): Builder
{
$this->items()->delete($item->getKey());

return $query;
}

/**
* Scope remove item from cart by id.
*/
public function scopeRemoveItemById(Builder $query, int $id): Builder
{
$this->items()->delete($id);

return $query;
}

/**
* Scope remove item from cart by id.
*/
public function scopeEmptyItems(Builder $query): Builder
{
$this->items()->delete();

return $query;
}

// Methods

/**
Expand Down Expand Up @@ -95,4 +125,28 @@ public function storeItems(array $items): Cart

return $this;
}

/**
* Remove a single item from the cart
*/
public function removeItem(Model $item): Cart
{
$itemToDelete = $this->items()->find($item->getKey());

if ($itemToDelete) {
$itemToDelete->delete();
}

return $this;
}

/**
* Remove every item from the cart
*/
public function emptyCart(): Cart
{
$this->items()->delete();

return $this;
}
}
97 changes: 97 additions & 0 deletions tests/Feature/CartDeleteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

use Binafy\LaravelCart\Models\Cart;
use Binafy\LaravelCart\Models\CartItem;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Artisan;
use Tests\SetUp\Models\Product;
use Tests\SetUp\Models\User;
use function Pest\Laravel\assertDatabaseCount;
use function Pest\Laravel\assertDatabaseHas;
use function PHPUnit\Framework\assertInstanceOf;

/*
* Use `RefreshDatabase` for delete migration data for each test.
*/
uses(RefreshDatabase::class);

test('can remove an item from the cart', function () {
$user = User::query()->create(['name' => 'Milwad', 'email' => 'milwad.dev@gmail.comd']);
$product1 = Product::query()->create(['title' => 'Product 1']);
$product2 = Product::query()->create(['title' => 'Product 2']);
$product3 = Product::query()->create(['title' => 'Product 3']);
$product4 = Product::query()->create(['title' => 'Product 4']);

$items = [
[
'itemable' => $product1,
'quantity' => 2,
],
[
'itemable' => $product2,
'quantity' => 1,
],
[
'itemable' => $product3,
'quantity' => 5,
],
[
'itemable' => $product4,
'quantity' => 3,
],
];

// Store items to cart
$cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cart->storeItems($items);

// Delete Item from cart
$cart->removeItem($product1);

// DB Assertions
assertDatabaseCount('carts', 1);
assertDatabaseCount('cart_items', 3);

$cart->removeItem($product2);
assertDatabaseCount('cart_items', 2);

$cart->removeItem($product1);
assertDatabaseCount('cart_items', 2);
});

test('can empty the cart', function() {
$user = User::query()->create(['name' => 'Milwad', 'email' => 'milwad.dev@gmail.comd']);
$product1 = Product::query()->create(['title' => 'Product 1']);
$product2 = Product::query()->create(['title' => 'Product 2']);
$product3 = Product::query()->create(['title' => 'Product 3']);
$product4 = Product::query()->create(['title' => 'Product 4']);

$items = [
[
'itemable' => $product1,
'quantity' => 2,
],
[
'itemable' => $product2,
'quantity' => 1,
],
[
'itemable' => $product3,
'quantity' => 5,
],
[
'itemable' => $product4,
'quantity' => 3,
],
];

// Store items to cart
$cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cart->storeItems($items);

assertDatabaseCount('cart_items', 4);

// Remove all items from cart
$cart->emptyCart();
assertDatabaseCount('cart_items', 0);
});