Initial commit

This commit is contained in:
Rob Gloudemans
2013-05-22 20:12:34 +02:00
commit fa7e90e48a
12 changed files with 517 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/vendor
composer.phar
composer.lock
.DS_Store

11
.travis.yml Normal file
View File

@@ -0,0 +1,11 @@
language: php
php:
- 5.3
- 5.4
before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install --dev
script: phpunit

21
composer.json Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "gloudemans/shoppingcart",
"description": "",
"authors": [
{
"name": "Rob Gloudemans",
"email": "Rob_Gloudemans@hotmail.com"
}
],
"require": {
"php": ">=5.3.0",
"illuminate/support": "4.0.x",
"mathiasverraes/money": "dev-zero-equality"
},
"autoload": {
"psr-0": {
"Gloudemans\\Shoppingcart": "src/"
}
},
"minimum-stability": "dev"
}

18
phpunit.xml Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false"
>
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -0,0 +1,251 @@
<?php namespace Gloudemans\Shoppingcart;
use Illuminate\Support\Collection;
use Money\Money;
class Cart {
/**
* Session class instance
*
* @var Session
*/
protected $session;
/**
* Constructor
*
* @param Session $session Session class instance
*/
public function __construct($session)
{
$this->session = $session;
}
/**
* Add a 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'
*/
public function add($id, $name, $qty, $price, $options = array())
{
$cart = $this->getContent();
$rowId = $this->generateRowId($id, $options);
if($cart->has($rowId))
{
$row = $cart->get($rowId);
$cart = $this->updateRow($rowId, $row->qty + $qty);
}
else
{
$cart = $this->createRow($rowId, $id, $name, $qty, $price, $options);
}
return $this->updateCart($cart);
}
/**
* Update the quantity of one row of the cart
* @param string $rowId The rowid of the item you want to update
* @param integer $qty New quantity of the item
* @return boolean
*/
public function update($rowId, $qty)
{
if($qty == 0)
{
return $this->remove($rowId);
}
return $this->updateRow($rowId, $qty);
}
/**
* Remove a row from the cart
*
* @param string $rowId The rowid of the item
* @return boolean
*/
public function remove($rowId)
{
$cart = $this->getContent();
$cart->forget($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 Array
*/
public function get($rowId)
{
$cart = $this->getContent();
return ($cart->has($rowId)) ? $cart->get($rowId) : NULL;
}
/**
* Get the cart content
*
* @return Array
*/
public function content()
{
$cart = $this->getContent();
return (empty($cart)) ? NULL : $cart;
}
/**
* Empty the cart
*
* @return boolean
*/
public function destroy()
{
return $this->updateCart(NULL);
}
/**
* 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
*
* @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;
}
/**
* 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)
{
return md5($id . serialize($options));
}
/**
* Update the cart
* @param Array $cart The new cart content
* @return void
*/
protected function updateCart($cart)
{
return $this->session->put('cart', $cart);
}
/**
* 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('cart')) ? $this->session->get('cart') : new CartCollection;
return $content;
}
/**
* 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 Collection
*/
protected function updateRow($rowId, $qty)
{
$cart = $this->getContent();
$row = $cart->get($rowId);
$row->qty = $qty;
$row->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 Collection
*/
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
]);
$cart->put($rowId, $newRow);
return $cart;
}
}

View File

@@ -0,0 +1,7 @@
<?php namespace Gloudemans\Shoppingcart;
use Illuminate\Support\Collection;
class CartCollection extends Collection {
}

View File

@@ -0,0 +1,22 @@
<?php namespace Gloudemans\Shoppingcart;
use Illuminate\Support\Collection;
class CartRowCollection extends Collection {
public function __construct($items)
{
parent::__construct($items);
}
public function __get($arg)
{
if($this->has($arg))
{
return $this->get($arg);
}
return NULL;
}
}

View File

@@ -0,0 +1,22 @@
<?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;
}
}

View File

@@ -0,0 +1,14 @@
<?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'; }
}

View File

@@ -0,0 +1,21 @@
<?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 = $this->app['session'];
return new Cart($session);
});
}
}

0
tests/.gitkeep Normal file
View File

126
tests/CartTest.php Normal file
View File

@@ -0,0 +1,126 @@
<?php
class CartTest extends TestCase {
public function testCartCanAdd()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
$this->assertEquals(Cart::count(), 1);
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanAddToExisting()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
$rowId = Cart::content()->first()->rowid;
$this->assertEquals(Cart::get($rowId)->qty, 2);
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanUpdate()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
$rowId = Cart::content()->first()->rowid;
Cart::update($rowId, 2);
$this->assertEquals(Cart::get($rowId)->qty, 2);
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanRemove()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
Cart::add(2, 'test', 1, 10.00, ['size' => 'L']);
$rowId = Cart::content()->first()->rowid;
Cart::remove($rowId);
$this->assertEquals(Cart::count(), 1);
$this->assertNull(Cart::get($rowId));
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanRemoveOnUpdate()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
$rowId = Cart::content()->first()->rowid;
Cart::update($rowId, 0);
$this->assertEquals(Cart::count(), 0);
$this->assertNull(Cart::get($rowId));
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanGet()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
$rowId = Cart::content()->first()->rowid;
$row = Cart::get($rowId);
$this->assertEquals($row->id, 1);
$this->assertEquals($row->name, 'test');
$this->assertEquals($row->qty, 1);
$this->assertEquals($row->price, 10.00);
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartRowCollection', $row);
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartRowOptionsCollection', $row->options);
$this->assertEquals($row, Cart::content()->first());
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanGetContent()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
$this->assertEquals(Cart::content()->count(), 1);
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanDestroy()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
Cart::destroy();
$this->assertEquals(Cart::count(), 0);
$this->assertInstanceOf('Gloudemans\Shoppingcart\CartCollection', Cart::content());
}
public function testCartCanGetTotal()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
Cart::add(2, 'test', 1, 10.00, ['size' => 'L']);
$total = Cart::total();
$this->assertTrue(is_float($total));
$this->assertEquals($total, 20.00);
}
public function testCartCanGetCount()
{
Cart::add(1, 'test', 1, 10.00, ['size' => 'L']);
Cart::add(2, 'test', 2, 10.00, ['size' => 'L']);
$count = Cart::count(false);
$this->assertTrue(is_integer($count));
$this->assertEquals($count, 2);
$count = Cart::count();
$this->assertTrue(is_integer($count));
$this->assertEquals($count, 3);
}
}