feat: clean up and starting documentation

This commit is contained in:
Joel Male
2025-02-25 14:53:49 +10:00
parent 8d6e1bcc26
commit ec99aa0563
9 changed files with 111 additions and 73 deletions
+25 -1
View File
@@ -20,7 +20,8 @@ ## Table of Contents
- [Configuration](#configuration) - [Configuration](#configuration)
- [Basic Usage](#basic-usage) - [Basic Usage](#basic-usage)
- [Conditions](#conditions) - [Conditions](#conditions)
- [Items](#items) - [Cart Items](#cart-items)
- [Database Support](#database-support)
- [Credits](#-credits) - [Credits](#-credits)
- [License](#-license) - [License](#-license)
@@ -684,6 +685,29 @@ ### Cart Items
$item->getPriceSumWithConditions(); $item->getPriceSumWithConditions();
``` ```
### Database Support
Sometimes you might want to store the cart in the database so that the cart can be retrieved even after the user logs out or closes the browser.
You may also find yourself wanting to add cart timeouts and support for multiple computers.
To get started, you'll need to create a new model for your Cart, the package requires only 3 columns, but you're free to extend this as you wish:
```php
$table->string('session_id');
$table->text('items');
$table->text('conditions');
```
Then add some json casts to your model:
```php
protected $casts = [
'items' => 'array',
'conditions' => 'array',
];
```
## 🫡 Credits ## 🫡 Credits
This package was orignally created by [darryldecode](https://github.com/darryldecode) but has since seen almost no updates. I have decided to take the old package and transform it into a new package with new features and updates. This package was orignally created by [darryldecode](https://github.com/darryldecode) but has since seen almost no updates. I have decided to take the old package and transform it into a new package with new features and updates.
+11 -11
View File
@@ -14,18 +14,18 @@
/* /*
* --------------------------------------------------------------- * ---------------------------------------------------------------
* Persistence * Storage
* --------------------------------------------------------------- * ---------------------------------------------------------------
*/ */
'storage' => null, 'driver' => 'session',
'storage_id' => null,
'storage_items' => null,
'storage_conditions' => null,
/* 'storage' => [
* --------------------------------------------------------------- 'session',
* Events 'database' => [
* --------------------------------------------------------------- 'model' => '',
*/ 'id' => '',
'events' => null, 'items' => '',
'conditions' => '',
],
],
]; ];
+35 -15
View File
@@ -27,15 +27,38 @@ class Cart
protected $decimals; protected $decimals;
protected $decPoint; protected $decPoint;
public function __construct($session, $events, $instanceName, $sessionKey, $config) public function __construct($sessionStorage, $events, $instanceName, $sessionKey, $config)
{ {
$this->validateConfig($config);
$this->events = $events; $this->events = $events;
$this->session = new CartSession($session, $sessionKey, $config); $this->session = new CartSession($sessionStorage, $sessionKey, $config);
$this->instanceName = $instanceName; $this->instanceName = $instanceName;
$this->config = $config; $this->config = $config;
$this->currentItemId = null; $this->currentItemId = null;
$this->fireEvent('created'); $this->fireEvent('Created');
}
private function validateConfig($config)
{
if ($config['driver'] == 'database') {
if (! isset($config['storage']['database']['model'])) {
throw new \Exception('You need to set a model for the database driver in the cart configuration.');
}
if (! isset($config['storage']['database']['id'])) {
throw new \Exception('You need to set an id (for the session) for the database driver in the cart configuration.');
}
if (! isset($config['storage']['database']['items'])) {
throw new \Exception('You need to set an items key for the database driver in the cart configuration.');
}
if (! isset($config['storage']['database']['conditions'])) {
throw new \Exception('You need to set a conditions key for the database driver in the cart configuration.');
}
}
} }
/** /**
@@ -145,7 +168,7 @@ public function add(
*/ */
public function update(int|string $id, array $data): bool public function update(int|string $id, array $data): bool
{ {
if ($this->fireEvent('updating', $data) === false) { if ($this->fireEvent('Updating', $data) === false) {
return false; return false;
} }
@@ -178,7 +201,7 @@ public function update(int|string $id, array $data): bool
$this->save($cart); $this->save($cart);
$this->fireEvent('updated', $item); $this->fireEvent('Updated', $item);
return true; return true;
} }
@@ -237,7 +260,7 @@ public function remove($id)
{ {
$cart = $this->getContent(); $cart = $this->getContent();
if ($this->fireEvent('removing', $id) === false) { if ($this->fireEvent('Removing', $id) === false) {
return false; return false;
} }
@@ -245,7 +268,7 @@ public function remove($id)
$this->save($cart); $this->save($cart);
$this->fireEvent('removed', $id); $this->fireEvent('Removed', $id);
return true; return true;
} }
@@ -257,13 +280,13 @@ public function remove($id)
*/ */
public function clear() public function clear()
{ {
if ($this->fireEvent('clearing') === false) { if ($this->fireEvent('Clearing') === false) {
return false; return false;
} }
$this->session->putItems([]); $this->session->putItems([]);
$this->fireEvent('cleared'); $this->fireEvent('Cleared');
return true; return true;
} }
@@ -691,7 +714,7 @@ protected function validate($item)
*/ */
protected function addItem($id, $item) protected function addItem($id, $item)
{ {
if ($this->fireEvent('adding', $item) === false) { if ($this->fireEvent('Adding', $item) === false) {
return false; return false;
} }
@@ -701,7 +724,7 @@ protected function addItem($id, $item)
$this->save($cart); $this->save($cart);
$this->fireEvent('added', $item); $this->fireEvent('Added', $item);
return true; return true;
} }
@@ -792,12 +815,9 @@ public function setDecimals($decimals)
$this->decimals = $decimals; $this->decimals = $decimals;
} }
/**
* @return mixed
*/
protected function fireEvent($name, $value = []) protected function fireEvent($name, $value = [])
{ {
return $this->events->dispatch($this->getInstanceName() . '.' . $name, array_values([$value, $this]), true); return $this->events->dispatch('LaravelCart.' . $name, array_values([$value, $this]), true);
} }
/** /**
+8 -13
View File
@@ -35,24 +35,19 @@ public function register()
$this->mergeConfigFrom(__DIR__ . '/../config/config.php', 'cart'); $this->mergeConfigFrom(__DIR__ . '/../config/config.php', 'cart');
$this->app->singleton('cart', function ($app) { $this->app->singleton('cart', function ($app) {
$storageClass = config('cart.storage'); $config = config('cart');
$eventsClass = config('cart.events'); $events = $app['events'];
$storage = $storageClass ? new $storageClass : $app['session']; $storage = $config['driver'] === 'database'
$events = $eventsClass ? new $eventsClass : $app['events']; ? new $config['storage']['database']['model']
$instanceName = 'cart'; : $app['session'];
// default session or cart identifier. This will be overridden when calling Cart::session($sessionKey)->add() etc..
// like when adding a cart for a specific user name. Session Key can be string or maybe a unique identifier to bind a cart
// to a specific user, this can also be a user ID
$session_key = '4yTlTDKu3oJOfzD';
return new Cart( return new Cart(
$storage, $storage,
$events, $events,
$instanceName, 'cart',
$session_key, '4yTlTDKu3oJOfzD',
config('cart') $config
); );
}); });
} }
+8 -9
View File
@@ -14,23 +14,22 @@ class CartSession
public function __construct($session, $sessionKey, $config) public function __construct($session, $sessionKey, $config)
{ {
if ($this->isInternalSession($session)) { if ($config['driver'] === 'session') {
$this->customStorage = false; $this->customStorage = false;
$this->session = $session; $this->session = $session;
$this->itemsKey = $sessionKey . '_cart_items'; $this->itemsKey = $sessionKey . '_cart_items';
$this->conditionsKey = $sessionKey . '_cart_conditions'; $this->conditionsKey = $sessionKey . '_cart_conditions';
} else { } elseif ($config['driver'] === 'database') {
$this->customStorage = true; $this->customStorage = true;
// @TODO validate these 3 exist $this->sessionId = $config['storage']['database']['id'];
$this->sessionId = $config['storage_id']; $this->itemsKey = $config['storage']['database']['items'];
$this->itemsKey = $config['storage_items']; $this->conditionsKey = $config['storage']['database']['conditions'];
$this->conditionsKey = $config['storage_conditions'];
// get the base class to do findOrCreate // find or create the session in the database
$this->session = $config['storage']; $this->session = $session->firstOrNew([$this->sessionId => $sessionKey]);
$this->session = (new $this->session)->firstOrNew([$this->sessionId => $sessionKey]);
// initialize the items and conditions
$this->session[$this->itemsKey] = $this->session[$this->itemsKey] ?? []; $this->session[$this->itemsKey] = $this->session[$this->itemsKey] ?? [];
$this->session[$this->conditionsKey] = $this->session[$this->conditionsKey] ?? []; $this->session[$this->conditionsKey] = $this->session[$this->conditionsKey] ?? [];
} }
+1 -2
View File
@@ -4,6 +4,5 @@
'format_numbers' => true, 'format_numbers' => true,
'decimals' => 2, 'decimals' => 2,
'dec_point' => '.', 'dec_point' => '.',
'thousands_sep' => ',', 'driver' => 'session',
'use_cents' => false,
]; ];
+1
View File
@@ -4,4 +4,5 @@
'format_numbers' => true, 'format_numbers' => true,
'decimals' => 2, 'decimals' => 2,
'round_mode' => 'up', 'round_mode' => 'up',
'driver' => 'session',
]; ];
+1 -1
View File
@@ -4,5 +4,5 @@
'format_numbers' => false, 'format_numbers' => false,
'decimals' => 3, 'decimals' => 3,
'dec_point' => ',', 'dec_point' => ',',
'thousands_sep' => '.', 'driver' => 'session',
]; ];
+21 -21
View File
@@ -9,9 +9,9 @@
Mockery::close(); Mockery::close();
}); });
test('event cart created', function () { test('event cart Created', function () {
$events = Mockery::mock('Illuminate\Contracts\Events\Dispatcher'); $events = Mockery::mock('Illuminate\Contracts\Events\Dispatcher');
$events->shouldReceive('dispatch')->once()->with('cart.created', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Created', Mockery::type('array'), true);
$cart = new Cart( $cart = new Cart(
new SessionMock, new SessionMock,
@@ -26,9 +26,9 @@
test('event cart adding', function () { test('event cart adding', function () {
$events = Mockery::mock('Illuminate\Events\Dispatcher'); $events = Mockery::mock('Illuminate\Events\Dispatcher');
$events->shouldReceive('dispatch')->once()->with('cart.created', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Created', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->once()->with('cart.adding', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Adding', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->once()->with('cart.added', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Added', Mockery::type('array'), true);
$cart = new Cart( $cart = new Cart(
new SessionMock, new SessionMock,
@@ -45,9 +45,9 @@
test('event cart adding multiple times', function () { test('event cart adding multiple times', function () {
$events = Mockery::mock('Illuminate\Events\Dispatcher'); $events = Mockery::mock('Illuminate\Events\Dispatcher');
$events->shouldReceive('dispatch')->once()->with('cart.created', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Created', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(2)->with('cart.adding', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(2)->with('LaravelCart.Adding', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(2)->with('cart.added', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(2)->with('LaravelCart.Added', Mockery::type('array'), true);
$cart = new Cart( $cart = new Cart(
new SessionMock, new SessionMock,
@@ -65,9 +65,9 @@
test('event cart adding multiple times scenario two', function () { test('event cart adding multiple times scenario two', function () {
$events = Mockery::mock('Illuminate\Events\Dispatcher'); $events = Mockery::mock('Illuminate\Events\Dispatcher');
$events->shouldReceive('dispatch')->once()->with('cart.created', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Created', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(3)->with('cart.adding', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(3)->with('LaravelCart.Adding', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(3)->with('cart.added', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(3)->with('LaravelCart.Added', Mockery::type('array'), true);
$items = [ $items = [
[ [
@@ -108,11 +108,11 @@
test('event cart remove item', function () { test('event cart remove item', function () {
$events = Mockery::mock('Illuminate\Events\Dispatcher'); $events = Mockery::mock('Illuminate\Events\Dispatcher');
$events->shouldReceive('dispatch')->once()->with('cart.created', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Created', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(3)->with('cart.adding', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(3)->with('LaravelCart.Adding', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(3)->with('cart.added', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(3)->with('LaravelCart.Added', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(1)->with('cart.removing', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(1)->with('LaravelCart.Removing', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(1)->with('cart.removed', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(1)->with('LaravelCart.Removed', Mockery::type('array'), true);
$items = [ $items = [
[ [
@@ -155,11 +155,11 @@
test('event cart clear', function () { test('event cart clear', function () {
$events = Mockery::mock('Illuminate\Events\Dispatcher'); $events = Mockery::mock('Illuminate\Events\Dispatcher');
$events->shouldReceive('dispatch')->once()->with('cart.created', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Created', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(3)->with('cart.adding', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(3)->with('LaravelCart.Adding', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->times(3)->with('cart.added', Mockery::type('array'), true); $events->shouldReceive('dispatch')->times(3)->with('LaravelCart.Added', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->once()->with('cart.clearing', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Clearing', Mockery::type('array'), true);
$events->shouldReceive('dispatch')->once()->with('cart.cleared', Mockery::type('array'), true); $events->shouldReceive('dispatch')->once()->with('LaravelCart.Cleared', Mockery::type('array'), true);
$items = [ $items = [
[ [