mirror of
https://github.com/kevin-DL/LaravelShoppingcart.git
synced 2026-01-11 18:54:33 +00:00
Large update for version 2.0
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,4 +2,3 @@
|
|||||||
composer.phar
|
composer.phar
|
||||||
composer.lock
|
composer.lock
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.idea
|
|
||||||
@@ -4,6 +4,7 @@ php:
|
|||||||
- 5.4
|
- 5.4
|
||||||
- 5.5
|
- 5.5
|
||||||
- 5.6
|
- 5.6
|
||||||
|
- 7.0
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- composer self-update
|
- composer self-update
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014 Rob Gloudemans <robgloudemans@gmail.com>
|
Copyright (c) 2016 Rob Gloudemans <info@robgloudemans.nl>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
34
README.md
34
README.md
@@ -2,43 +2,25 @@
|
|||||||
[](https://travis-ci.org/Crinsane/LaravelShoppingcart)
|
[](https://travis-ci.org/Crinsane/LaravelShoppingcart)
|
||||||
[](https://packagist.org/packages/gloudemans/shoppingcart)
|
[](https://packagist.org/packages/gloudemans/shoppingcart)
|
||||||
|
|
||||||
A simple shoppingcart implementation for Laravel 4.
|
A simple shoppingcart implementation for Laravel.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Install the package through [Composer](http://getcomposer.org/). Edit your project's `composer.json` file by adding:
|
Install the package through [Composer](http://getcomposer.org/).
|
||||||
|
|
||||||
### Laravel 4.2 and below
|
Run the Composer require command from the Terminal:
|
||||||
|
|
||||||
```php
|
composer require gloudemans/shoppingcart
|
||||||
"require": {
|
|
||||||
"laravel/framework": "4.2.*",
|
|
||||||
"gloudemans/shoppingcart": "~1.2"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Laravel 5
|
Now all you have to do is add the service provider of the package and alias the package. To do this open your `config/app.php` file.
|
||||||
|
|
||||||
```php
|
|
||||||
"require": {
|
|
||||||
"laravel/framework": "5.0.*",
|
|
||||||
"gloudemans/shoppingcart": "~1.3"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Next, run the Composer update command from the Terminal:
|
|
||||||
|
|
||||||
composer update
|
|
||||||
|
|
||||||
Now all you have to do is add the service provider of the package and alias the package. To do this open your `app/config/app.php` file.
|
|
||||||
|
|
||||||
Add a new line to the `service providers` array:
|
Add a new line to the `service providers` array:
|
||||||
|
|
||||||
'Gloudemans\Shoppingcart\ShoppingcartServiceProvider'
|
\Gloudemans\Shoppingcart\ShoppingcartServiceProvider::class
|
||||||
|
|
||||||
And finally add a new line to the `aliases` array:
|
And optionally add a new line to the `aliases` array:
|
||||||
|
|
||||||
'Cart' => 'Gloudemans\Shoppingcart\Facades\Cart',
|
'Cart' => \Gloudemans\Shoppingcart\Facades\Cart::class,
|
||||||
|
|
||||||
Now you're ready to start using the shoppingcart in your application.
|
Now you're ready to start using the shoppingcart in your application.
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,31 @@
|
|||||||
{
|
{
|
||||||
"name": "gloudemans/shoppingcart",
|
"name": "gloudemans/shoppingcart",
|
||||||
"description": "Laravel 5 Shoppingcart",
|
"description": "Laravel Shoppingcart",
|
||||||
"keywords": ["laravel", "shoppingcart"],
|
"keywords": ["laravel", "shoppingcart"],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Rob Gloudemans",
|
"name": "Rob Gloudemans",
|
||||||
"email": "Rob_Gloudemans@hotmail.com"
|
"email": "info@robgloudemans.nl"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.4.0",
|
"illuminate/support": "5.2.*",
|
||||||
"illuminate/support": "~5.0"
|
"illuminate/session": "^5.2.*",
|
||||||
|
"illuminate/events": "^5.2.*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"mockery/mockery": "~0.9",
|
"phpunit/phpunit": "~4.0",
|
||||||
"phpunit/phpunit": "~4.0"
|
"mockery/mockery": "~0.9.0",
|
||||||
},
|
"orchestra/testbench": "~3.0"
|
||||||
"suggest": {
|
|
||||||
"gloudemans/notify": "Simple flash notifications for Laravel 5"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {
|
"psr-4": {
|
||||||
"Gloudemans\\Shoppingcart": "src/"
|
"Gloudemans\\Shoppingcart\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"suggest": {
|
||||||
|
"gloudemans/notify": "Simple flash notifications for Laravel"
|
||||||
|
},
|
||||||
"minimum-stability": "dev"
|
"minimum-stability": "dev"
|
||||||
}
|
}
|
||||||
|
|||||||
16
config/cart.php
Normal file
16
config/cart.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default tax rate
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This default tax rate will be used when you make a class implement the
|
||||||
|
| Taxable interface and use the HasTax trait.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'tax' => 21
|
||||||
|
|
||||||
|
];
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateShoppingcartTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('shoppingcart', function (Blueprint $table) {
|
||||||
|
$table->string('identifier');
|
||||||
|
$table->string('instance');
|
||||||
|
$table->longText('content');
|
||||||
|
$table->nullableTimestamps();
|
||||||
|
|
||||||
|
$table->primary(['identifier', 'instance']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::drop('shoppingcart');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,8 +8,7 @@
|
|||||||
convertWarningsToExceptions="true"
|
convertWarningsToExceptions="true"
|
||||||
processIsolation="false"
|
processIsolation="false"
|
||||||
stopOnFailure="false"
|
stopOnFailure="false"
|
||||||
syntaxCheck="false"
|
syntaxCheck="false">
|
||||||
>
|
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite name="Package Test Suite">
|
<testsuite name="Package Test Suite">
|
||||||
<directory suffix=".php">./tests/</directory>
|
<directory suffix=".php">./tests/</directory>
|
||||||
|
|||||||
43
src/CanBeBought.php
Normal file
43
src/CanBeBought.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart;
|
||||||
|
|
||||||
|
trait CanBeBought
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the identifier of the Buyable item.
|
||||||
|
*
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
public function getBuyableIdentifier()
|
||||||
|
{
|
||||||
|
return method_exists($this, 'getKey') ? $this->getKey() : $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description or title of the Buyable item.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getBuyableDescription()
|
||||||
|
{
|
||||||
|
if(property_exists('name', $this)) return $this->name;
|
||||||
|
if(property_exists('title', $this)) return $this->title;
|
||||||
|
if(property_exists('description', $this)) return $this->description;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price of the Buyable item.
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function getBuyablePrice()
|
||||||
|
{
|
||||||
|
if(property_exists('price', $this)) return $this->price;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
503
src/Cart.php
Normal file
503
src/Cart.php
Normal file
@@ -0,0 +1,503 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Gloudemans\Shoppingcart\Exceptions\CartAlreadyStoredException;
|
||||||
|
use Illuminate\Database\DatabaseManager;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Session\SessionManager;
|
||||||
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||||
|
use Gloudemans\Shoppingcart\Exceptions\UnknownModelException;
|
||||||
|
use Gloudemans\Shoppingcart\Exceptions\InvalidRowIDException;
|
||||||
|
|
||||||
|
class Cart
|
||||||
|
{
|
||||||
|
const DEFAULT_INSTANCE = 'default';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of the session manager.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Session\SessionManager
|
||||||
|
*/
|
||||||
|
private $session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of the event dispatcher.
|
||||||
|
*
|
||||||
|
* @var \Illuminate\Contracts\Events\Dispatcher
|
||||||
|
*/
|
||||||
|
private $events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the current cart instance.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cart constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Session\SessionManager $session
|
||||||
|
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||||
|
*/
|
||||||
|
public function __construct(SessionManager $session, Dispatcher $events)
|
||||||
|
{
|
||||||
|
$this->session = $session;
|
||||||
|
$this->events = $events;
|
||||||
|
|
||||||
|
$this->instance(self::DEFAULT_INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current cart instance.
|
||||||
|
*
|
||||||
|
* @param string|null $instance
|
||||||
|
* @return \Gloudemans\Shoppingcart\Cart
|
||||||
|
*/
|
||||||
|
public function instance($instance = null)
|
||||||
|
{
|
||||||
|
$instance = $instance ?: self::DEFAULT_INSTANCE;
|
||||||
|
|
||||||
|
$this->instance = sprintf('%s.%s', 'cart', $instance);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current cart instance.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function currentInstance()
|
||||||
|
{
|
||||||
|
return str_replace('cart.', '', $this->instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an item to the cart.
|
||||||
|
*
|
||||||
|
* @param mixed $id
|
||||||
|
* @param mixed $name
|
||||||
|
* @param int|float $qty
|
||||||
|
* @param float $price
|
||||||
|
* @param array $options
|
||||||
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
|
*/
|
||||||
|
public function add($id, $name = null, $qty = null, $price = null, array $options = [])
|
||||||
|
{
|
||||||
|
if ($this->isMulti($id)) {
|
||||||
|
return array_map(function ($item) {
|
||||||
|
return $this->add($item);
|
||||||
|
}, $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$cartItem = $this->createCartItem($id, $name, $qty, $price, $options);
|
||||||
|
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
if ($content->has($cartItem->rowId)) {
|
||||||
|
$cartItem->qty++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$content->put($cartItem->rowId, $cartItem);
|
||||||
|
|
||||||
|
$this->events->fire('cart.added', $cartItem);
|
||||||
|
|
||||||
|
$this->session->put($this->instance, $content);
|
||||||
|
|
||||||
|
return $cartItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cart item with the given rowId.
|
||||||
|
*
|
||||||
|
* @param string $rowId
|
||||||
|
* @param mixed $qty
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function update($rowId, $qty)
|
||||||
|
{
|
||||||
|
$cartItem = $this->get($rowId);
|
||||||
|
|
||||||
|
if ($qty instanceof Buyable) {
|
||||||
|
$cartItem->updateFromBuyable($qty);
|
||||||
|
} elseif (is_array($qty)) {
|
||||||
|
$cartItem->updateFromArray($qty);
|
||||||
|
} else {
|
||||||
|
$cartItem->qty = $qty;
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
if ($rowId !== $cartItem->rowId) {
|
||||||
|
$content->pull($rowId);
|
||||||
|
|
||||||
|
if ($content->has($cartItem->rowId)) {
|
||||||
|
$existingCartItem = $this->get($cartItem->rowId);
|
||||||
|
$cartItem->setQuantity($existingCartItem->qty + $cartItem->qty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cartItem->qty <= 0) {
|
||||||
|
$this->remove($cartItem->rowId);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$content->put($cartItem->rowId, $cartItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->events->fire('cart.updated', $cartItem);
|
||||||
|
|
||||||
|
$this->session->put($this->instance, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the cart item with the given rowId from the cart.
|
||||||
|
*
|
||||||
|
* @param string $rowId
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function remove($rowId)
|
||||||
|
{
|
||||||
|
$cartItem = $this->get($rowId);
|
||||||
|
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
$content->pull($cartItem->rowId);
|
||||||
|
|
||||||
|
$this->events->fire('cart.removed', $cartItem);
|
||||||
|
|
||||||
|
$this->session->put($this->instance, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a cart item from the cart by its rowId.
|
||||||
|
*
|
||||||
|
* @param string $rowId
|
||||||
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
|
*/
|
||||||
|
public function get($rowId)
|
||||||
|
{
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
if ( ! $content->has($rowId))
|
||||||
|
throw new InvalidRowIDException("The cart does not contain rowId {$rowId}.");
|
||||||
|
|
||||||
|
return $content->get($rowId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the current cart instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function destroy()
|
||||||
|
{
|
||||||
|
$this->session->remove($this->instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content of the cart.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function content()
|
||||||
|
{
|
||||||
|
return $this->session->get($this->instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of items in the cart.
|
||||||
|
*
|
||||||
|
* @return int|float
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
return $content->sum('qty');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total price of the items in the cart.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function total($decimals = 2, $decimalPoint = '.', $thousandSeperator = ',')
|
||||||
|
{
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
$total = $content->reduce(function ($subTotal, CartItem $cartItem) {
|
||||||
|
return $subTotal + ($cartItem->qty * $cartItem->price);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
return number_format($total, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total tax of the items in the cart.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function tax($decimals = 2, $decimalPoint = '.', $thousandSeperator = ',')
|
||||||
|
{
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
$tax = $content->reduce(function ($tax, CartItem $cartItem) {
|
||||||
|
return $tax + ($cartItem->qty * $cartItem->tax);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
return number_format($tax, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the subtotal (total - tax) of the items in the cart.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function subtotal($decimals = 2, $decimalPoint = '.', $thousandSeperator = ',')
|
||||||
|
{
|
||||||
|
$subtotal = $this->total - $this->tax;
|
||||||
|
|
||||||
|
return number_format($subtotal, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the cart content for a cart item matching the given search closure.
|
||||||
|
*
|
||||||
|
* @param \Closure $search
|
||||||
|
* @return \Gloudemans\Shoppingcart\CartItem|\Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function search(Closure $search)
|
||||||
|
{
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
$found = $content->filter($search);
|
||||||
|
|
||||||
|
if($found->count() === 1) return $found->first();
|
||||||
|
|
||||||
|
return $found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associate the cart item with the given rowId with the given model.
|
||||||
|
*
|
||||||
|
* @param string $rowId
|
||||||
|
* @param mixed $model
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function associate($rowId, $model)
|
||||||
|
{
|
||||||
|
if(is_string($model) && ! class_exists($model))
|
||||||
|
throw new UnknownModelException("The supplied model {$model} does not exist.");
|
||||||
|
|
||||||
|
$cartItem = $this->get($rowId);
|
||||||
|
|
||||||
|
$cartItem->associate($model);
|
||||||
|
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
$content->put($cartItem->rowId, $cartItem);
|
||||||
|
|
||||||
|
$this->session->put($this->instance, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the tax rate for the cart item with the given rowId.
|
||||||
|
*
|
||||||
|
* @param string $rowId
|
||||||
|
* @param int|float $taxRate
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setTax($rowId, $taxRate)
|
||||||
|
{
|
||||||
|
$cartItem = $this->get($rowId);
|
||||||
|
|
||||||
|
$cartItem->setTaxRate($taxRate);
|
||||||
|
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
$content->put($cartItem->rowId, $cartItem);
|
||||||
|
|
||||||
|
$this->session->put($this->instance, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store an the current instance of the cart.
|
||||||
|
*
|
||||||
|
* @param mixed $identifier
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function store($identifier)
|
||||||
|
{
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
if ($this->storedCartWithIdentifierExists($identifier)) {
|
||||||
|
throw new CartAlreadyStoredException("A cart with identifier {$identifier} was already stored.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getConnection()->table($this->getTableName())->insert([
|
||||||
|
'identifier' => $identifier,
|
||||||
|
'instance' => $this->currentInstance(),
|
||||||
|
'content' => serialize($content)
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->events->fire('cart.stored');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the cart with the given identifier.
|
||||||
|
*
|
||||||
|
* @param mixed $identifier
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function restore($identifier)
|
||||||
|
{
|
||||||
|
if( ! $this->storedCartWithIdentifierExists($identifier)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stored = $this->getConnection()->table($this->getTableName())
|
||||||
|
->where('identifier', $identifier)->first();
|
||||||
|
|
||||||
|
$storedContent = unserialize($stored->content);
|
||||||
|
|
||||||
|
$currentInstance = $this->currentInstance();
|
||||||
|
|
||||||
|
$this->instance($stored->instance);
|
||||||
|
|
||||||
|
$content = $this->getContent();
|
||||||
|
|
||||||
|
foreach ($storedContent as $cartItem) {
|
||||||
|
$content->put($cartItem->rowId, $cartItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->events->fire('cart.restored');
|
||||||
|
|
||||||
|
$this->session->put($this->instance, $content);
|
||||||
|
|
||||||
|
$this->instance($currentInstance);
|
||||||
|
|
||||||
|
$this->getConnection()->table($this->getTableName())
|
||||||
|
->where('identifier', $identifier)->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic method to make accessing the total, tax and subtotal properties possible.
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @return float|null
|
||||||
|
*/
|
||||||
|
public function __get($attribute)
|
||||||
|
{
|
||||||
|
if($attribute === 'total') {
|
||||||
|
return $this->total(2, '.', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($attribute === 'tax') {
|
||||||
|
return $this->tax(2, '.', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($attribute === 'subtotal') {
|
||||||
|
return $this->subtotal(2, '.', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the carts content, if there is no cart content set yet, return a new empty Collection
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
protected function getContent()
|
||||||
|
{
|
||||||
|
$content = $this->session->has($this->instance)
|
||||||
|
? $this->session->get($this->instance)
|
||||||
|
: new Collection;
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new CartItem from the supplied attributes.
|
||||||
|
*
|
||||||
|
* @param mixed $id
|
||||||
|
* @param mixed $name
|
||||||
|
* @param int|float $qty
|
||||||
|
* @param float $price
|
||||||
|
* @param array $options
|
||||||
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
|
*/
|
||||||
|
private function createCartItem($id, $name, $qty, $price, array $options)
|
||||||
|
{
|
||||||
|
if ($id instanceof Buyable) {
|
||||||
|
$cartItem = CartItem::fromBuyable($id, $qty ?: []);
|
||||||
|
$cartItem->setQuantity($name ?: 1);
|
||||||
|
$cartItem->associate($id);
|
||||||
|
} elseif (is_array($id)) {
|
||||||
|
$cartItem = CartItem::fromArray($id);
|
||||||
|
$cartItem->setQuantity($id['qty']);
|
||||||
|
} else {
|
||||||
|
$cartItem = CartItem::fromAttributes($id, $name, $price, $options);
|
||||||
|
$cartItem->setQuantity($qty);
|
||||||
|
}
|
||||||
|
|
||||||
|
$cartItem->setTaxRate(config('cart.tax'));
|
||||||
|
|
||||||
|
return $cartItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the item is a multidimensional array or an array of Buyables.
|
||||||
|
*
|
||||||
|
* @param mixed $item
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function isMulti($item)
|
||||||
|
{
|
||||||
|
if ( ! is_array($item)) return false;
|
||||||
|
|
||||||
|
return is_array(head($item)) || head($item) instanceof Buyable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $identifier
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function storedCartWithIdentifierExists($identifier)
|
||||||
|
{
|
||||||
|
return $this->getConnection()->table($this->getTableName())->where('identifier', $identifier)->exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the database connection.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Connection
|
||||||
|
*/
|
||||||
|
private function getConnection()
|
||||||
|
{
|
||||||
|
return app(DatabaseManager::class)->connection(config('cart.database.connection', config('database.default')));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the database table name.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function getTableName()
|
||||||
|
{
|
||||||
|
return config('cart.database.table', 'shoppingcart');
|
||||||
|
}
|
||||||
|
}
|
||||||
271
src/CartItem.php
Normal file
271
src/CartItem.php
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart;
|
||||||
|
|
||||||
|
use Gloudemans\Shoppingcart\Contracts\Buyable;
|
||||||
|
|
||||||
|
class CartItem
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The rowID of the cart item.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $rowId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ID of the cart item.
|
||||||
|
*
|
||||||
|
* @var int|string
|
||||||
|
*/
|
||||||
|
public $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The quantity for this cart item.
|
||||||
|
*
|
||||||
|
* @var int|float
|
||||||
|
*/
|
||||||
|
public $qty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the cart item.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The price of the cart item.
|
||||||
|
*
|
||||||
|
* @var float
|
||||||
|
*/
|
||||||
|
public $price;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The options for this cart item.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The FQN of the associated model.
|
||||||
|
*
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
private $associatedModel = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tax rate for the cart item.
|
||||||
|
*
|
||||||
|
* @var int|float
|
||||||
|
*/
|
||||||
|
private $taxRate = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CartItem constructor.
|
||||||
|
*
|
||||||
|
* @param int|string $id
|
||||||
|
* @param string $name
|
||||||
|
* @param float $price
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
public function __construct($id, $name, $price, array $options = [])
|
||||||
|
{
|
||||||
|
if(empty($id)) throw new \InvalidArgumentException('Please supply a valid identifier.');
|
||||||
|
if(empty($name)) throw new \InvalidArgumentException('Please supply a valid name.');
|
||||||
|
if(empty($price) || ! is_numeric($price))
|
||||||
|
throw new \InvalidArgumentException('Please supply a valid price.');
|
||||||
|
|
||||||
|
$this->id = $id;
|
||||||
|
$this->name = $name;
|
||||||
|
$this->price = $price;
|
||||||
|
$this->options = new CartItemOptions($options);
|
||||||
|
|
||||||
|
$this->rowId = $this->generateRowId($id, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the formatted price.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function price($decimals = 2, $decimalPoint = '.', $thousandSeperator = ',')
|
||||||
|
{
|
||||||
|
return number_format($this->price, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the formatted subtotal.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function subtotal($decimals = 2, $decimalPoint = '.', $thousandSeperator = ',')
|
||||||
|
{
|
||||||
|
return number_format($this->subtotal, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the formatted tax.
|
||||||
|
*
|
||||||
|
* @param int $decimals
|
||||||
|
* @param string $decimalPoint
|
||||||
|
* @param string $thousandSeperator
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function tax($decimals = 2, $decimalPoint = '.', $thousandSeperator = ',')
|
||||||
|
{
|
||||||
|
return number_format($this->tax, $decimals, $decimalPoint, $thousandSeperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the quantity for this cart item.
|
||||||
|
*
|
||||||
|
* @param int|float $qty
|
||||||
|
*/
|
||||||
|
public function setQuantity($qty)
|
||||||
|
{
|
||||||
|
if(empty($qty) || ! is_numeric($qty))
|
||||||
|
throw new \InvalidArgumentException('Please supply a valid quantity.');
|
||||||
|
|
||||||
|
$this->qty = $qty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cart item from a Buyable.
|
||||||
|
*
|
||||||
|
* @param \Gloudemans\Shoppingcart\Contracts\Buyable $item
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateFromBuyable(Buyable $item)
|
||||||
|
{
|
||||||
|
$this->id = $item->getBuyableIdentifier();
|
||||||
|
$this->name = $item->getBuyableDescription();
|
||||||
|
$this->price = $item->getBuyablePrice();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cart item from an array.
|
||||||
|
*
|
||||||
|
* @param array $attributes
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateFromArray(array $attributes)
|
||||||
|
{
|
||||||
|
$this->id = array_get($attributes, 'id', $this->id);
|
||||||
|
$this->qty = array_get($attributes, 'qty', $this->qty);
|
||||||
|
$this->name = array_get($attributes, 'name', $this->name);
|
||||||
|
$this->price = array_get($attributes, 'price', $this->price);
|
||||||
|
$this->options = new CartItemOptions(array_get($attributes, 'options', []));
|
||||||
|
|
||||||
|
$this->rowId = $this->generateRowId($this->id, $this->options->all());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associate the cart item with the given model.
|
||||||
|
*
|
||||||
|
* @param mixed $model
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function associate($model)
|
||||||
|
{
|
||||||
|
$this->associatedModel = is_string($model) ? $model : get_class($model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the tax rate.
|
||||||
|
*
|
||||||
|
* @param int|float $taxRate
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setTaxRate($taxRate)
|
||||||
|
{
|
||||||
|
$this->taxRate = $taxRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an attribute from the cart item or get the associated model.
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($attribute)
|
||||||
|
{
|
||||||
|
if(property_exists($this, $attribute)) {
|
||||||
|
return $this->{$attribute};
|
||||||
|
}
|
||||||
|
|
||||||
|
if($attribute === 'subtotal') {
|
||||||
|
return $this->qty * $this->price;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($attribute === 'tax') {
|
||||||
|
return $this->price * ($this->taxRate / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($attribute === 'model') {
|
||||||
|
return with(new $this->associatedModel)->find($this->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from a Buyable.
|
||||||
|
*
|
||||||
|
* @param \Gloudemans\Shoppingcart\Contracts\Buyable $item
|
||||||
|
* @param array $options
|
||||||
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
|
*/
|
||||||
|
public static function fromBuyable(Buyable $item, array $options = [])
|
||||||
|
{
|
||||||
|
return new self($item->getBuyableIdentifier(), $item->getBuyableDescription(), $item->getBuyablePrice(), $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given array.
|
||||||
|
*
|
||||||
|
* @param array $attributes
|
||||||
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $attributes)
|
||||||
|
{
|
||||||
|
$options = array_get($attributes, 'options', []);
|
||||||
|
|
||||||
|
return new self($attributes['id'], $attributes['name'], $attributes['price'], $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given attributes.
|
||||||
|
*
|
||||||
|
* @param int|string $id
|
||||||
|
* @param string $name
|
||||||
|
* @param float $price
|
||||||
|
* @param array $options
|
||||||
|
* @return \Gloudemans\Shoppingcart\CartItem
|
||||||
|
*/
|
||||||
|
public static function fromAttributes($id, $name, $price, array $options = [])
|
||||||
|
{
|
||||||
|
return new self($id, $name, $price, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a unique id for the cart item.
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
* @param array $options
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function generateRowId($id, array $options)
|
||||||
|
{
|
||||||
|
ksort($options);
|
||||||
|
|
||||||
|
return md5($id . serialize($options));
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/CartItemOptions.php
Normal file
19
src/CartItemOptions.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class CartItemOptions extends Collection
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the option by the given key.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($key)
|
||||||
|
{
|
||||||
|
return $this->get($key);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/Contracts/Buyable.php
Normal file
27
src/Contracts/Buyable.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart\Contracts;
|
||||||
|
|
||||||
|
interface Buyable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the identifier of the Buyable item.
|
||||||
|
*
|
||||||
|
* @return int|string
|
||||||
|
*/
|
||||||
|
public function getBuyableIdentifier();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description or title of the Buyable item.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getBuyableDescription();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the price of the Buyable item.
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function getBuyablePrice();
|
||||||
|
}
|
||||||
7
src/Exceptions/CartAlreadyStoredException.php
Normal file
7
src/Exceptions/CartAlreadyStoredException.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart\Exceptions;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class CartAlreadyStoredException extends RuntimeException {}
|
||||||
7
src/Exceptions/InvalidRowIDException.php
Normal file
7
src/Exceptions/InvalidRowIDException.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart\Exceptions;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class InvalidRowIDException extends RuntimeException {}
|
||||||
7
src/Exceptions/UnknownModelException.php
Normal file
7
src/Exceptions/UnknownModelException.php
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart\Exceptions;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
class UnknownModelException extends RuntimeException {}
|
||||||
@@ -1,527 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart;
|
|
||||||
|
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
class Cart {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Session class instance
|
|
||||||
*
|
|
||||||
* @var Illuminate\Session\SessionManager
|
|
||||||
*/
|
|
||||||
protected $session;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event class instance
|
|
||||||
*
|
|
||||||
* @var Illuminate\Events\Dispatcher
|
|
||||||
*/
|
|
||||||
protected $event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Current cart instance
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $instance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Eloquent model a cart is associated with
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $associatedModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An optional namespace for the associated model
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $associatedModelNamespace;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param Illuminate\Session\SessionManager $session Session class instance
|
|
||||||
* @param \Illuminate\Contracts\Events\Dispatcher $event Event class instance
|
|
||||||
*/
|
|
||||||
public function __construct($session, Dispatcher $event)
|
|
||||||
{
|
|
||||||
$this->session = $session;
|
|
||||||
$this->event = $event;
|
|
||||||
|
|
||||||
$this->instance = 'main';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the current cart instance
|
|
||||||
*
|
|
||||||
* @param string $instance Cart instance name
|
|
||||||
* @return Gloudemans\Shoppingcart\Cart
|
|
||||||
*/
|
|
||||||
public function instance($instance = null)
|
|
||||||
{
|
|
||||||
if(empty($instance)) throw new Exceptions\ShoppingcartInstanceException;
|
|
||||||
|
|
||||||
$this->instance = $instance;
|
|
||||||
|
|
||||||
// Return self so the method is chainable
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the associated model
|
|
||||||
*
|
|
||||||
* @param string $modelName The name of the model
|
|
||||||
* @param string $modelNamespace The namespace of the model
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function associate($modelName, $modelNamespace = null)
|
|
||||||
{
|
|
||||||
$this->associatedModel = $modelName;
|
|
||||||
$this->associatedModelNamespace = $modelNamespace;
|
|
||||||
|
|
||||||
if( ! class_exists($modelNamespace . '\\' . $modelName)) throw new Exceptions\ShoppingcartUnknownModelException;
|
|
||||||
|
|
||||||
// Return self so the method is chainable
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a row to the cart
|
|
||||||
*
|
|
||||||
* @param string|array $id Unique ID of the item|Item formated as array|Array of items
|
|
||||||
* @param string $name Name of the item
|
|
||||||
* @param int $qty Item qty to add to the cart
|
|
||||||
* @param float $price Price of one item
|
|
||||||
* @param array $options Array of additional options, such as 'size' or 'color'
|
|
||||||
*/
|
|
||||||
public function add($id, $name = null, $qty = null, $price = null, array $options = [])
|
|
||||||
{
|
|
||||||
// If the first parameter is an array we need to call the add() function again
|
|
||||||
if(is_array($id))
|
|
||||||
{
|
|
||||||
// And if it's not only an array, but a multidimensional array, we need to
|
|
||||||
// recursively call the add function
|
|
||||||
if($this->is_multi($id))
|
|
||||||
{
|
|
||||||
// Fire the cart.batch event
|
|
||||||
$this->event->fire('cart.batch', $id);
|
|
||||||
|
|
||||||
foreach($id as $item)
|
|
||||||
{
|
|
||||||
$options = array_get($item, 'options', []);
|
|
||||||
$this->addRow($item['id'], $item['name'], $item['qty'], $item['price'], $options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire the cart.batched event
|
|
||||||
$this->event->fire('cart.batched', $id);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$options = array_get($id, 'options', []);
|
|
||||||
|
|
||||||
// Fire the cart.add event
|
|
||||||
$this->event->fire('cart.add', array_merge($id, ['options' => $options]));
|
|
||||||
|
|
||||||
$result = $this->addRow($id['id'], $id['name'], $id['qty'], $id['price'], $options);
|
|
||||||
|
|
||||||
// Fire the cart.added event
|
|
||||||
$this->event->fire('cart.added', array_merge($id, ['options' => $options]));
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire the cart.add event
|
|
||||||
$this->event->fire('cart.add', compact('id', 'name', 'qty', 'price', 'options'));
|
|
||||||
|
|
||||||
$result = $this->addRow($id, $name, $qty, $price, $options);
|
|
||||||
|
|
||||||
// Fire the cart.added event
|
|
||||||
$this->event->fire('cart.added', compact('id', 'name', 'qty', 'price', 'options'));
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the quantity of one row of the cart
|
|
||||||
*
|
|
||||||
* @param string $rowId The rowid of the item you want to update
|
|
||||||
* @param integer|array $attribute New quantity of the item|Array of attributes to update
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function update($rowId, $attribute)
|
|
||||||
{
|
|
||||||
if( ! $this->hasRowId($rowId)) throw new Exceptions\ShoppingcartInvalidRowIDException;
|
|
||||||
|
|
||||||
if(is_array($attribute))
|
|
||||||
{
|
|
||||||
// Fire the cart.update event
|
|
||||||
$this->event->fire('cart.update', $rowId);
|
|
||||||
|
|
||||||
$result = $this->updateAttribute($rowId, $attribute);
|
|
||||||
|
|
||||||
// Fire the cart.updated event
|
|
||||||
$this->event->fire('cart.updated', $rowId);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire the cart.update event
|
|
||||||
$this->event->fire('cart.update', $rowId);
|
|
||||||
|
|
||||||
$result = $this->updateQty($rowId, $attribute);
|
|
||||||
|
|
||||||
// Fire the cart.updated event
|
|
||||||
$this->event->fire('cart.updated', $rowId);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a row from the cart
|
|
||||||
*
|
|
||||||
* @param string $rowId The rowid of the item
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function remove($rowId)
|
|
||||||
{
|
|
||||||
if( ! $this->hasRowId($rowId)) throw new Exceptions\ShoppingcartInvalidRowIDException;
|
|
||||||
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
// Fire the cart.remove event
|
|
||||||
$this->event->fire('cart.remove', $rowId);
|
|
||||||
|
|
||||||
$cart->forget($rowId);
|
|
||||||
|
|
||||||
// Fire the cart.removed event
|
|
||||||
$this->event->fire('cart.removed', $rowId);
|
|
||||||
|
|
||||||
return $this->updateCart($cart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a row of the cart by its ID
|
|
||||||
*
|
|
||||||
* @param string $rowId The ID of the row to fetch
|
|
||||||
* @return Gloudemans\Shoppingcart\CartCollection
|
|
||||||
*/
|
|
||||||
public function get($rowId)
|
|
||||||
{
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
return ($cart->has($rowId)) ? $cart->get($rowId) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the cart content
|
|
||||||
*
|
|
||||||
* @return Gloudemans\Shoppingcart\CartRowCollection
|
|
||||||
*/
|
|
||||||
public function content()
|
|
||||||
{
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
return (empty($cart)) ? NULL : $cart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Empty the cart
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function destroy()
|
|
||||||
{
|
|
||||||
// Fire the cart.destroy event
|
|
||||||
$this->event->fire('cart.destroy');
|
|
||||||
|
|
||||||
$result = $this->updateCart(NULL);
|
|
||||||
|
|
||||||
// Fire the cart.destroyed event
|
|
||||||
$this->event->fire('cart.destroyed');
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the price total
|
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function total()
|
|
||||||
{
|
|
||||||
$total = 0;
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
if(empty($cart))
|
|
||||||
{
|
|
||||||
return $total;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($cart AS $row)
|
|
||||||
{
|
|
||||||
$total += $row->subtotal;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $total;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of items in the cart
|
|
||||||
*
|
|
||||||
* @param boolean $totalItems Get all the items (when false, will return the number of rows)
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function count($totalItems = true)
|
|
||||||
{
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
if( ! $totalItems)
|
|
||||||
{
|
|
||||||
return $cart->count();
|
|
||||||
}
|
|
||||||
|
|
||||||
$count = 0;
|
|
||||||
|
|
||||||
foreach($cart AS $row)
|
|
||||||
{
|
|
||||||
$count += $row->qty;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search if the cart has a item
|
|
||||||
*
|
|
||||||
* @param array $search An array with the item ID and optional options
|
|
||||||
* @return array|boolean
|
|
||||||
*/
|
|
||||||
public function search(array $search)
|
|
||||||
{
|
|
||||||
if(empty($search)) return false;
|
|
||||||
|
|
||||||
foreach($this->getContent() as $item)
|
|
||||||
{
|
|
||||||
$found = $item->search($search);
|
|
||||||
|
|
||||||
if($found)
|
|
||||||
{
|
|
||||||
$rows[] = $item->rowid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (empty($rows)) ? false : $rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add row to the cart
|
|
||||||
*
|
|
||||||
* @param string $id Unique ID of the item
|
|
||||||
* @param string $name Name of the item
|
|
||||||
* @param int $qty Item qty to add to the cart
|
|
||||||
* @param float $price Price of one item
|
|
||||||
* @param array $options Array of additional options, such as 'size' or 'color'
|
|
||||||
*/
|
|
||||||
protected function addRow($id, $name, $qty, $price, array $options = [])
|
|
||||||
{
|
|
||||||
if(empty($id) || empty($name) || empty($qty) || ! isset($price))
|
|
||||||
{
|
|
||||||
throw new Exceptions\ShoppingcartInvalidItemException;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ! is_numeric($qty))
|
|
||||||
{
|
|
||||||
throw new Exceptions\ShoppingcartInvalidQtyException;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ! is_numeric($price))
|
|
||||||
{
|
|
||||||
throw new Exceptions\ShoppingcartInvalidPriceException;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
$rowId = $this->generateRowId($id, $options);
|
|
||||||
|
|
||||||
if($cart->has($rowId))
|
|
||||||
{
|
|
||||||
$row = $cart->get($rowId);
|
|
||||||
$cart = $this->updateRow($rowId, ['qty' => $row->qty + $qty]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$cart = $this->createRow($rowId, $id, $name, $qty, $price, $options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->updateCart($cart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a unique id for the new row
|
|
||||||
*
|
|
||||||
* @param string $id Unique ID of the item
|
|
||||||
* @param array $options Array of additional options, such as 'size' or 'color'
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
protected function generateRowId($id, $options)
|
|
||||||
{
|
|
||||||
ksort($options);
|
|
||||||
|
|
||||||
return md5($id . serialize($options));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a rowid exists in the current cart instance
|
|
||||||
*
|
|
||||||
* @param string $id Unique ID of the item
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
protected function hasRowId($rowId)
|
|
||||||
{
|
|
||||||
return $this->getContent()->has($rowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the cart
|
|
||||||
*
|
|
||||||
* @param Gloudemans\Shoppingcart\CartCollection $cart The new cart content
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function updateCart($cart)
|
|
||||||
{
|
|
||||||
return $this->session->put($this->getInstance(), $cart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the carts content, if there is no cart content set yet, return a new empty Collection
|
|
||||||
*
|
|
||||||
* @return Gloudemans\Shoppingcart\CartCollection
|
|
||||||
*/
|
|
||||||
protected function getContent()
|
|
||||||
{
|
|
||||||
$content = ($this->session->has($this->getInstance())) ? $this->session->get($this->getInstance()) : new CartCollection;
|
|
||||||
|
|
||||||
return $content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current cart instance
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getInstance()
|
|
||||||
{
|
|
||||||
return 'cart.' . $this->instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a row if the rowId already exists
|
|
||||||
*
|
|
||||||
* @param string $rowId The ID of the row to update
|
|
||||||
* @param integer $qty The quantity to add to the row
|
|
||||||
* @return Gloudemans\Shoppingcart\CartCollection
|
|
||||||
*/
|
|
||||||
protected function updateRow($rowId, $attributes)
|
|
||||||
{
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
$row = $cart->get($rowId);
|
|
||||||
|
|
||||||
foreach($attributes as $key => $value)
|
|
||||||
{
|
|
||||||
if($key == 'options')
|
|
||||||
{
|
|
||||||
$options = $row->options->merge($value);
|
|
||||||
$row->put($key, $options);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$row->put($key, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ! is_null(array_keys($attributes, ['qty', 'price'])))
|
|
||||||
{
|
|
||||||
$row->put('subtotal', $row->qty * $row->price);
|
|
||||||
}
|
|
||||||
|
|
||||||
$cart->put($rowId, $row);
|
|
||||||
|
|
||||||
return $cart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new row Object
|
|
||||||
*
|
|
||||||
* @param string $rowId The ID of the new row
|
|
||||||
* @param string $id Unique ID of the item
|
|
||||||
* @param string $name Name of the item
|
|
||||||
* @param int $qty Item qty to add to the cart
|
|
||||||
* @param float $price Price of one item
|
|
||||||
* @param array $options Array of additional options, such as 'size' or 'color'
|
|
||||||
* @return Gloudemans\Shoppingcart\CartCollection
|
|
||||||
*/
|
|
||||||
protected function createRow($rowId, $id, $name, $qty, $price, $options)
|
|
||||||
{
|
|
||||||
$cart = $this->getContent();
|
|
||||||
|
|
||||||
$newRow = new CartRowCollection([
|
|
||||||
'rowid' => $rowId,
|
|
||||||
'id' => $id,
|
|
||||||
'name' => $name,
|
|
||||||
'qty' => $qty,
|
|
||||||
'price' => $price,
|
|
||||||
'options' => new CartRowOptionsCollection($options),
|
|
||||||
'subtotal' => $qty * $price
|
|
||||||
], $this->associatedModel, $this->associatedModelNamespace);
|
|
||||||
|
|
||||||
$cart->put($rowId, $newRow);
|
|
||||||
|
|
||||||
return $cart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the quantity of a row
|
|
||||||
*
|
|
||||||
* @param string $rowId The ID of the row
|
|
||||||
* @param int $qty The qty to add
|
|
||||||
* @return Gloudemans\Shoppingcart\CartCollection
|
|
||||||
*/
|
|
||||||
protected function updateQty($rowId, $qty)
|
|
||||||
{
|
|
||||||
if($qty <= 0)
|
|
||||||
{
|
|
||||||
return $this->remove($rowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->updateRow($rowId, ['qty' => $qty]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update an attribute of the row
|
|
||||||
*
|
|
||||||
* @param string $rowId The ID of the row
|
|
||||||
* @param array $attributes An array of attributes to update
|
|
||||||
* @return Gloudemans\Shoppingcart\CartCollection
|
|
||||||
*/
|
|
||||||
protected function updateAttribute($rowId, $attributes)
|
|
||||||
{
|
|
||||||
return $this->updateRow($rowId, $attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the array is a multidimensional array
|
|
||||||
*
|
|
||||||
* @param array $array The array to check
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
protected function is_multi(array $array)
|
|
||||||
{
|
|
||||||
return is_array(head($array));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart;
|
|
||||||
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
class CartCollection extends Collection {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart;
|
|
||||||
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
class CartRowCollection extends Collection {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Eloquent model a cart is associated with
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $associatedModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An optional namespace for the associated model
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $associatedModelNamespace;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for the CartRowCollection
|
|
||||||
*
|
|
||||||
* @param array $items
|
|
||||||
* @param string $associatedModel
|
|
||||||
* @param string $associatedModelNamespace
|
|
||||||
*/
|
|
||||||
public function __construct($items, $associatedModel, $associatedModelNamespace)
|
|
||||||
{
|
|
||||||
parent::__construct($items);
|
|
||||||
|
|
||||||
$this->associatedModel = $associatedModel;
|
|
||||||
$this->associatedModelNamespace = $associatedModelNamespace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __get($arg)
|
|
||||||
{
|
|
||||||
if($this->has($arg))
|
|
||||||
{
|
|
||||||
return $this->get($arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($arg == strtolower($this->associatedModel))
|
|
||||||
{
|
|
||||||
$modelInstance = $this->associatedModelNamespace ? $this->associatedModelNamespace . '\\' .$this->associatedModel : $this->associatedModel;
|
|
||||||
$model = new $modelInstance;
|
|
||||||
|
|
||||||
return $model->find($this->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function search($search, $strict = false)
|
|
||||||
{
|
|
||||||
foreach($search as $key => $value)
|
|
||||||
{
|
|
||||||
if($key === 'options')
|
|
||||||
{
|
|
||||||
$found = $this->{$key}->search($value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$found = ($this->{$key} === $value) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ! $found) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $found;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart;
|
|
||||||
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
class CartRowOptionsCollection extends Collection {
|
|
||||||
|
|
||||||
public function __construct($items)
|
|
||||||
{
|
|
||||||
parent::__construct($items);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __get($arg)
|
|
||||||
{
|
|
||||||
if($this->has($arg))
|
|
||||||
{
|
|
||||||
return $this->get($arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function search($search, $strict = false)
|
|
||||||
{
|
|
||||||
foreach($search as $key => $value)
|
|
||||||
{
|
|
||||||
$found = ($this->{$key} === $value) ? true : false;
|
|
||||||
|
|
||||||
if( ! $found) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $found;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart\Exceptions;
|
|
||||||
|
|
||||||
class ShoppingcartInstanceException extends \Exception {}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart\Exceptions;
|
|
||||||
|
|
||||||
class ShoppingcartInvalidItemException extends \Exception {}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart\Exceptions;
|
|
||||||
|
|
||||||
class ShoppingcartInvalidPriceException extends \Exception {}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart\Exceptions;
|
|
||||||
|
|
||||||
class ShoppingcartInvalidQtyException extends \Exception {}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart\Exceptions;
|
|
||||||
|
|
||||||
class ShoppingcartInvalidRowIDException extends \Exception {}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart\Exceptions;
|
|
||||||
|
|
||||||
class ShoppingcartUnknownModelException extends \Exception {}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart\Facades;
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Facade;
|
|
||||||
|
|
||||||
class Cart extends Facade {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the registered name of the component.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected static function getFacadeAccessor() { return 'cart'; }
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<?php namespace Gloudemans\Shoppingcart;
|
|
||||||
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
|
||||||
|
|
||||||
class ShoppingcartServiceProvider extends ServiceProvider {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register the service provider.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
$this->app['cart'] = $this->app->share(function($app)
|
|
||||||
{
|
|
||||||
$session = $app['session'];
|
|
||||||
$events = $app['events'];
|
|
||||||
return new Cart($session, $events);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
29
src/ShoppingcartServiceProvider.php
Normal file
29
src/ShoppingcartServiceProvider.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Gloudemans\Shoppingcart;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class ShoppingcartServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the service provider.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
$config = __DIR__ . '/../config/cart.php';
|
||||||
|
$this->mergeConfigFrom($config, 'cart');
|
||||||
|
|
||||||
|
if ( ! class_exists('CreateShoppingcartTable')) {
|
||||||
|
// Publish the migration
|
||||||
|
$timestamp = date('Y_m_d_His', time());
|
||||||
|
|
||||||
|
$this->publishes([
|
||||||
|
__DIR__.'/../database/migrations/0000_00_00_000000_create_shoppingcart_table.php' => database_path('migrations/'.$timestamp.'_create_shoppingcart_table.php'),
|
||||||
|
], 'migrations');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
tests/CartAssertions.php
Normal file
35
tests/CartAssertions.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Gloudemans\Shoppingcart\Cart;
|
||||||
|
use PHPUnit_Framework_Assert as PHPUnit;
|
||||||
|
|
||||||
|
trait CartAssertions
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that the cart contains the given number of items.
|
||||||
|
*
|
||||||
|
* @param int|float $items
|
||||||
|
* @param \Gloudemans\Shoppingcart\Cart $cart
|
||||||
|
*/
|
||||||
|
public function assertItemsInCart($items, Cart $cart)
|
||||||
|
{
|
||||||
|
$actual = $cart->count();
|
||||||
|
|
||||||
|
PHPUnit::assertEquals($items, $cart->count(), "Expected the cart to contain {$items} items, but got {$actual}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that the cart contains the given number of rows.
|
||||||
|
*
|
||||||
|
* @param int $rows
|
||||||
|
* @param \Gloudemans\Shoppingcart\Cart $cart
|
||||||
|
*/
|
||||||
|
public function assertRowsInCart($rows, Cart $cart)
|
||||||
|
{
|
||||||
|
$actual = $cart->content()->count();
|
||||||
|
|
||||||
|
PHPUnit::assertCount($rows, $cart->content(), "Expected the cart to contain {$rows} rows, but got {$actual}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1148
tests/CartTest.php
1148
tests/CartTest.php
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
|||||||
<?php namespace Acme\Test\Models;
|
|
||||||
class TestProduct {
|
|
||||||
public $description = 'This is the description of the namespaced test model';
|
|
||||||
public function find($id) { return $this; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class TestProduct {
|
|
||||||
public $description = 'This is the description of the test model';
|
|
||||||
public function find($id) { return $this; }
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class SessionMock {
|
|
||||||
protected $session;
|
|
||||||
public function has($key)
|
|
||||||
{
|
|
||||||
return isset($this->session[$key]);
|
|
||||||
}
|
|
||||||
public function get($key)
|
|
||||||
{
|
|
||||||
return $this->session[$key];
|
|
||||||
}
|
|
||||||
public function put($key, $value)
|
|
||||||
{
|
|
||||||
$this->session[$key] = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user