Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: binafy/laravel-cart
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.0.4
Choose a base ref
...
head repository: binafy/laravel-cart
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.0.5
Choose a head ref
  • 18 commits
  • 7 files changed
  • 2 contributors

Commits on Jun 30, 2024

  1. add cartable contract

    milwad-dev committed Jun 30, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    71b34b9 View commit details

Commits on Jul 1, 2024

  1. fix tests

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    9749824 View commit details
  2. Update CartItem.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    402897c View commit details
  3. Update CartItem.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    b9a13cf View commit details
  4. Copy the full SHA
    6ddc0c4 View commit details
  5. Update Cart.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    9cc73b5 View commit details
  6. Merge pull request #11 from binafy/add-cartable-contract

    [1.x] Add `Cartable` contract
    milwad-dev authored Jul 1, 2024
    Copy the full SHA
    8c07070 View commit details
  7. Update Cart.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    fa5c2b0 View commit details
  8. Update Cart.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    075d2d9 View commit details
  9. Update CartStoreTest.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    116a0b6 View commit details
  10. Update CartStoreTest.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    21e79bb View commit details
  11. Update Cart.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    86abe04 View commit details
  12. wip

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    a5ea3ce View commit details
  13. Update Cart.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    927db01 View commit details
  14. Update Cart.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    4d09c1f View commit details
  15. Update Cart.php

    milwad-dev committed Jul 1, 2024
    Copy the full SHA
    e7cbbb5 View commit details

Commits on Jul 3, 2024

  1. Merge pull request #12 from binafy/add-store-item-method

    [1.x] Add store item method
    milwad-dev authored Jul 3, 2024
    Copy the full SHA
    ea921c5 View commit details
  2. Update README.md

    milwad-dev committed Jul 3, 2024
    Copy the full SHA
    ed35041 View commit details
Showing with 143 additions and 25 deletions.
  1. +33 −21 README.md
  2. +8 −0 src/Cartable.php
  3. +28 −3 src/Models/Cart.php
  4. +3 −0 src/Models/CartItem.php
  5. +39 −0 src/Observers/CartItemObserve.php
  6. +22 −0 tests/Feature/CartStoreTest.php
  7. +10 −1 tests/SetUp/Models/Product.php
54 changes: 33 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -15,10 +15,10 @@
- [Usage](#usage)
- [Configuration](#configuration)
- [Store Cart](#store-cart)
- [Store Items For a Cart](#store-items-for-a-cart)
- [Access Itemable](#access-itemable)
- [Create Cart With Storing Items](#create-cart-with-storing-items)
- [Store multiple items](#store-multiple-items)
- [Store Item For a Cart](#store-items-for-a-cart)
- [Delete Item From Cart](#delete-item-from-cart)
- [Delete All Items From Cart](#delete-all-items-from-cart)
- [Contributors](#contributors)
@@ -96,26 +96,6 @@ use \Binafy\LaravelCart\Models\Cart;
$cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
```

<a name="store-items-for-a-cart"></a>
### Store Items For a Cart

If you want to store items for cart, first you need to create a cart and attach items to cart:

```php
$cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cartItem = new CartItem([
'itemable_id' => $itemable->id,
'itemable_type' => $itemable::class,
'quantity' => 1,
]);

$cart->items()->save($cartItem);
```

If you may to access the items of one cart, you can use `items` relation that exists in Cart model.

> There is no need to use any Interface or something for itemable.
<a name="access-itemable"></a>
### Access Itemable

@@ -167,6 +147,38 @@ $cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cart->storeItems($items);
```

<a name="store-item-for-a-cart"></a>
### Store Item For a Cart

If you want to store items for cart, first you need to create a cart and attach items to cart:

```php
$cart = Cart::query()->firstOrCreate(['user_id' => $user->id]);
$cartItem = new CartItem([
'itemable_id' => $itemable->id,
'itemable_type' => $itemable::class,
'quantity' => 1,
]);

$cart->items()->save($cartItem);
```

If you may to access the items of one cart, you can use `items` relation that exists in Cart model.

For conveniences, you can use `storeItem` method. This method take a model or array:

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

// Model
$cart->storeItem($itemable);

// Array
$item['itemable'] = $itemable;
$item['quantity'] = 1;
$cart->storeItem($item);
```

<a name="delete-item-from-cart"></a>
### Delete Item From Cart

8 changes: 8 additions & 0 deletions src/Cartable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Binafy\LaravelCart;

interface Cartable
{
public function getPrice(): int;
}
31 changes: 28 additions & 3 deletions src/Models/Cart.php
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

namespace Binafy\LaravelCart\Models;

use Binafy\LaravelCart\Cartable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

@@ -43,6 +44,9 @@ public function items(): \Illuminate\Database\Eloquent\Relations\HasMany

// Scopes

/**
* @throws \Exception
*/
public function scopeFirstOrCreateWithStoreItems(
Builder $query,
Model $item,
@@ -52,10 +56,13 @@ public function scopeFirstOrCreateWithStoreItems(
if (is_null($userId)) {
$userId = auth()->id();
}
if (! $item instanceof Cartable) {
throw new \Exception('The item must be an instance of Cartable');
}

$cart = $query->firstOrCreate(['user_id' => $userId]);
$cartItem = new CartItem([
'itemable_id' => $item->id,
'itemable_id' => $item->getKey(),
'itemable_type' => $item::class,
'quantity' => $quantity,
]);
@@ -74,7 +81,7 @@ public function calculatedPriceByQuantity(): int
{
$totalPrice = 0;
foreach ($this->items()->get() as $item) {
$totalPrice += (int) $item->quantity * (int) $item->itemable->price;
$totalPrice += (int) $item->quantity * (int) $item->itemable->getPrice();
}

return $totalPrice;
@@ -86,11 +93,29 @@ public function calculatedPriceByQuantity(): int
public function storeItems(array $items): Cart
{
foreach ($items as $item) {
$this->storeItem($item);
}

return $this;
}

/**
* Store cart item in cart.
*/
public function storeItem(Model|array $item): Cart
{
if (is_array($item)) {
$item['itemable_id'] = $item['itemable']->getKey();
$item['itemable_type'] = get_class($item['itemable']);
$item['quantity'] = (int) $item['quantity'];

$this->items()->create($item);
if ($item['itemable'] instanceof Cartable) {
$this->items()->create($item);
} else {
throw new \RuntimeException('The item must be an instance of Cartable');
}
} else {
$this->items()->save($item);
}

return $this;
3 changes: 3 additions & 0 deletions src/Models/CartItem.php
Original file line number Diff line number Diff line change
@@ -2,8 +2,11 @@

namespace Binafy\LaravelCart\Models;

use Binafy\LaravelCart\Observers\CartItemObserve;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Model;

#[ObservedBy([CartItemObserve::class])]
class CartItem extends Model
{
/**
39 changes: 39 additions & 0 deletions src/Observers/CartItemObserve.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Binafy\LaravelCart\Observers;

use Binafy\LaravelCart\Cartable;
use Binafy\LaravelCart\Models\CartItem;

class CartItemObserve
{
/**
* Handle the CartItem "creating" event.
*/
public function creating(CartItem $cartItem): void
{
if (! new $cartItem->itemable_type instanceof Cartable) {
throw new \RuntimeException('The item must be an instance of Cartable');
}
}

/**
* Handle the CartItem "updating" event.
*/
public function updating(CartItem $cartItem): void
{
if (! new $cartItem->itemable_type instanceof Cartable) {
throw new \RuntimeException('The item must be an instance of Cartable');
}
}

/**
* Handle the CartItem "saving" event.
*/
public function saving(CartItem $cartItem): void
{
if (! new $cartItem->itemable_type instanceof Cartable) {
throw new \RuntimeException('The item must be an instance of Cartable');
}
}
}
22 changes: 22 additions & 0 deletions tests/Feature/CartStoreTest.php
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@

use function Pest\Laravel\assertDatabaseCount;
use function Pest\Laravel\assertDatabaseHas;
use function Pest\Laravel\assertDatabaseMissing;
use function PHPUnit\Framework\assertInstanceOf;

/*
@@ -180,3 +181,24 @@
'quantity' => 2,
]);
});

test('can not store product in cart when item is not instance of cartable', function () {
$user = User::query()->create(['name' => 'Milwad', 'email' => 'milwad.dev@gmail.comd']);
$user2 = User::query()->create(['name' => 'Binafy', 'email' => 'binafy23@gmail.comd']);

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

$item['itemable'] = $user2;
$item['quantity'] = 2;

$cart->storeItem($item);

// DB Assertions
assertDatabaseCount('carts', 1);
assertDatabaseCount('cart_items', 0);
assertDatabaseMissing('cart_items', [
'itemable_id' => $user2->id,
'itemable_type' => $user2::class,
'quantity' => 2,
]);
})->expectExceptionMessage('The item must be an instance of Cartable');
11 changes: 10 additions & 1 deletion tests/SetUp/Models/Product.php
Original file line number Diff line number Diff line change
@@ -2,14 +2,23 @@

namespace Tests\SetUp\Models;

use Binafy\LaravelCart\Cartable;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
class Product extends Model implements Cartable
{
/**
* Fillable columns.
*
* @var string[]
*/
protected $fillable = ['title', 'price'];

/**
* Get the correct price.
*/
public function getPrice(): int
{
return $this->price;
}
}