mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
Merge pull request #17 from stloyd/collection-fix
Small cleanup of cart functionality, re-use existing collection code fro...
This commit is contained in:
commit
595c8f0025
9 changed files with 134 additions and 50 deletions
|
|
@ -32,17 +32,6 @@ class Cart extends BaseCart
|
||||||
$this->items = new ArrayCollection();
|
$this->items = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function addItem(ItemInterface $item)
|
|
||||||
{
|
|
||||||
if (!$this->hasItem($item)) {
|
|
||||||
$this->items->add($item);
|
|
||||||
$item->setCart($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
@ -62,6 +51,22 @@ class Cart extends BaseCart
|
||||||
return $this->items->contains($item);
|
return $this->items->contains($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function searchItem(ItemInterface $item)
|
||||||
|
{
|
||||||
|
return $this->items->indexOf($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isEmpty()
|
||||||
|
{
|
||||||
|
return $this->items->isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -159,12 +159,20 @@ abstract class Cart implements CartInterface
|
||||||
*/
|
*/
|
||||||
public function addItem(ItemInterface $item)
|
public function addItem(ItemInterface $item)
|
||||||
{
|
{
|
||||||
if (!$this->hasItem($item)) {
|
$exists = false;
|
||||||
|
foreach ($this->items as $existingItem) {
|
||||||
|
/** @var $existingItem ItemInterface */
|
||||||
|
if ($existingItem->equals($item)) {
|
||||||
|
$existingItem->incrementQuantity($item->getQuantity());
|
||||||
|
$exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$exists) {
|
||||||
$item->setCart($this);
|
$item->setCart($this);
|
||||||
$this->items[] = $item;
|
$this->items[] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -172,8 +180,8 @@ abstract class Cart implements CartInterface
|
||||||
*/
|
*/
|
||||||
public function removeItem(ItemInterface $item)
|
public function removeItem(ItemInterface $item)
|
||||||
{
|
{
|
||||||
if ($this->hasItem($item)) {
|
$key = $this->searchItem($item);
|
||||||
$key = array_search($item, $this->items);
|
if (false !== $key) {
|
||||||
unset($this->items[$key]);
|
unset($this->items[$key]);
|
||||||
$item->setCart(null);
|
$item->setCart(null);
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +192,17 @@ abstract class Cart implements CartInterface
|
||||||
*/
|
*/
|
||||||
public function hasItem(ItemInterface $item)
|
public function hasItem(ItemInterface $item)
|
||||||
{
|
{
|
||||||
return $this === $item->getCart();
|
return false !== $this->searchItem($item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ItemInterface $item
|
||||||
|
*
|
||||||
|
* @return boolean|integer
|
||||||
|
*/
|
||||||
|
public function searchItem(ItemInterface $item)
|
||||||
|
{
|
||||||
|
return array_search($item, $this->items, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ interface CartInterface
|
||||||
*
|
*
|
||||||
* @param \DateTime $expiresAt
|
* @param \DateTime $expiresAt
|
||||||
*/
|
*/
|
||||||
function setExpiresAt(\DateTime $expiresAt);
|
function setExpiresAt(\DateTime $expiresAt = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bumps the expiration time.
|
* Bumps the expiration time.
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,10 @@ abstract class Item implements ItemInterface
|
||||||
*/
|
*/
|
||||||
public function setQuantity($quantity)
|
public function setQuantity($quantity)
|
||||||
{
|
{
|
||||||
|
if (1 > $quantity) {
|
||||||
|
throw new \OutOfRangeException('Quantity value must be bigger than zero.');
|
||||||
|
}
|
||||||
|
|
||||||
$this->quantity = $quantity;
|
$this->quantity = $quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,6 +105,11 @@ abstract class Item implements ItemInterface
|
||||||
public function incrementQuantity($amount = 1)
|
public function incrementQuantity($amount = 1)
|
||||||
{
|
{
|
||||||
$this->quantity += $amount;
|
$this->quantity += $amount;
|
||||||
|
|
||||||
|
// Quantity must be bigger than zero
|
||||||
|
if (1 > $this->quantity) {
|
||||||
|
$this->quantity = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -108,6 +117,10 @@ abstract class Item implements ItemInterface
|
||||||
*/
|
*/
|
||||||
public function equals(ItemInterface $item)
|
public function equals(ItemInterface $item)
|
||||||
{
|
{
|
||||||
return $item === $this;
|
if ($item->getId() !== $this->getId()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,16 +46,6 @@ abstract class CartOperator implements CartOperatorInterface
|
||||||
*/
|
*/
|
||||||
public function addItem(CartInterface $cart, ItemInterface $item)
|
public function addItem(CartInterface $cart, ItemInterface $item)
|
||||||
{
|
{
|
||||||
if (false === $cart->isEmpty()) {
|
|
||||||
foreach ($cart->getItems() as $existingItem) {
|
|
||||||
if ($existingItem->equals($item)) {
|
|
||||||
$existingItem->incrementQuantity($item->getQuantity());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$cart->addItem($item);
|
$cart->addItem($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ class CartTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
$cart = $this->getCart();
|
$cart = $this->getCart();
|
||||||
|
|
||||||
$this->assertEquals(0, $cart->getTotalItems());
|
$this->assertTrue($cart->isEmpty());
|
||||||
$this->assertEquals(false, $cart->isLocked());
|
$this->assertFalse($cart->isLocked());
|
||||||
$this->assertInstanceOf('DateTime', $cart->getExpiresAt());
|
$this->assertInstanceOf('DateTime', $cart->getExpiresAt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,6 +73,9 @@ class CartTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertGreaterThan($expiresAt, $cart->getExpiresAt());
|
$this->assertGreaterThan($expiresAt, $cart->getExpiresAt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\Cart
|
||||||
|
*/
|
||||||
private function getCart()
|
private function getCart()
|
||||||
{
|
{
|
||||||
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Cart');
|
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Cart');
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,57 @@ class ItemTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$item->setCart($cart);
|
$item->setCart($cart);
|
||||||
$this->assertEquals($cart, $item->getCart());
|
$this->assertEquals($cart, $item->getCart());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testEquals()
|
||||||
|
{
|
||||||
|
$item = $this->getItem();
|
||||||
|
$item->setId(1);
|
||||||
|
|
||||||
|
$duplicatedItem = clone $item;
|
||||||
|
$this->assertTrue($item->equals($duplicatedItem));
|
||||||
|
|
||||||
|
$duplicatedItem->setQuantity(2);
|
||||||
|
$this->assertTrue($item->equals($duplicatedItem));
|
||||||
|
$this->assertNotEquals($duplicatedItem->getQuantity(), $item->getQuantity());
|
||||||
|
|
||||||
|
$duplicatedItem->setId(2);
|
||||||
|
$this->assertFalse($item->equals($duplicatedItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testQuantityManagement()
|
||||||
|
{
|
||||||
|
$item = $this->getItem();
|
||||||
|
$item->setQuantity(5);
|
||||||
|
$this->assertEquals(5, $item->getQuantity());
|
||||||
|
|
||||||
|
$item->incrementQuantity(5);
|
||||||
|
$this->assertEquals(10, $item->getQuantity());
|
||||||
|
|
||||||
|
$item->incrementQuantity(-10);
|
||||||
|
$this->assertEquals(1, $item->getQuantity());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \OutOfRangeException
|
||||||
|
*/
|
||||||
|
public function testQuantityMustBeBiggerThanZero()
|
||||||
|
{
|
||||||
|
$item = $this->getItem();
|
||||||
|
$item->setQuantity(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\Item
|
||||||
|
*/
|
||||||
private function getItem()
|
private function getItem()
|
||||||
{
|
{
|
||||||
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Item');
|
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Item');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\CartInterface
|
||||||
|
*/
|
||||||
private function getMockCart()
|
private function getMockCart()
|
||||||
{
|
{
|
||||||
return $this->getMock('Sylius\Bundle\CartBundle\Model\CartInterface');
|
return $this->getMock('Sylius\Bundle\CartBundle\Model\CartInterface');
|
||||||
|
|
|
||||||
|
|
@ -35,16 +35,21 @@ class CartOperatorTest extends \PHPUnit_Framework_TestCase
|
||||||
public function testAddItemIncreasesQuantityIfThereAreItemsThatAreEqual()
|
public function testAddItemIncreasesQuantityIfThereAreItemsThatAreEqual()
|
||||||
{
|
{
|
||||||
$item = $this->getItem();
|
$item = $this->getItem();
|
||||||
|
$item->setId(1);
|
||||||
$item->setQuantity(3);
|
$item->setQuantity(3);
|
||||||
|
|
||||||
$cart = $this->getCart();
|
$cart = $this->getCart();
|
||||||
|
|
||||||
$cartOperator = $this->getCartOperator();
|
$cartOperator = $this->getCartOperator();
|
||||||
$cartOperator->addItem($cart, $item);
|
$cartOperator->addItem($cart, $item);
|
||||||
$cartOperator->addItem($cart, $item);
|
|
||||||
|
$duplicatedItem = clone $item;
|
||||||
|
$duplicatedItem->setQuantity(2);
|
||||||
|
|
||||||
|
$cartOperator->addItem($cart, $duplicatedItem);
|
||||||
|
|
||||||
$this->assertEquals(1, $cart->countItems());
|
$this->assertEquals(1, $cart->countItems());
|
||||||
$this->assertEquals(6, $item->getQuantity());
|
$this->assertEquals(5, $item->getQuantity());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRefreshSetsTotalItems()
|
public function testRefreshSetsTotalItems()
|
||||||
|
|
@ -105,6 +110,11 @@ class CartOperatorTest extends \PHPUnit_Framework_TestCase
|
||||||
$cartOperator->removeItem($cart, $item);
|
$cartOperator->removeItem($cart, $item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param object|null $cartManager
|
||||||
|
*
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Operator\CartOperator
|
||||||
|
*/
|
||||||
private function getCartOperator($cartManager = null)
|
private function getCartOperator($cartManager = null)
|
||||||
{
|
{
|
||||||
if (null === $cartManager) {
|
if (null === $cartManager) {
|
||||||
|
|
@ -117,26 +127,41 @@ class CartOperatorTest extends \PHPUnit_Framework_TestCase
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\Cart
|
||||||
|
*/
|
||||||
private function getCart()
|
private function getCart()
|
||||||
{
|
{
|
||||||
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Cart');
|
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Cart');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\Item
|
||||||
|
*/
|
||||||
private function getItem()
|
private function getItem()
|
||||||
{
|
{
|
||||||
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Item');
|
return $this->getMockForAbstractClass('Sylius\Bundle\CartBundle\Model\Item');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\CartManagerInterface
|
||||||
|
*/
|
||||||
private function getMockCartManager()
|
private function getMockCartManager()
|
||||||
{
|
{
|
||||||
return $this->getMock('Sylius\Bundle\CartBundle\Model\CartManagerInterface');
|
return $this->getMock('Sylius\Bundle\CartBundle\Model\CartManagerInterface');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\CartInterface
|
||||||
|
*/
|
||||||
private function getMockCart()
|
private function getMockCart()
|
||||||
{
|
{
|
||||||
return $this->getMock('Sylius\Bundle\CartBundle\Model\CartInterface');
|
return $this->getMock('Sylius\Bundle\CartBundle\Model\CartInterface');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Sylius\Bundle\CartBundle\Model\ItemInterface
|
||||||
|
*/
|
||||||
private function getMockItem()
|
private function getMockItem()
|
||||||
{
|
{
|
||||||
return $this->getMock('Sylius\Bundle\CartBundle\Model\ItemInterface');
|
return $this->getMock('Sylius\Bundle\CartBundle\Model\ItemInterface');
|
||||||
|
|
|
||||||
|
|
@ -9,23 +9,10 @@
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!file_exists($file = __DIR__.'/../vendor/.composer/autoload.php')) {
|
if (file_exists($file = __DIR__.'/../vendor/autoload.php')) {
|
||||||
|
$autoload = require_once $file;
|
||||||
$vendorDir = __DIR__.'/../vendor';
|
|
||||||
require_once $vendorDir.'/symfony/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
|
|
||||||
|
|
||||||
$loader = new \Symfony\Component\ClassLoader\UniversalClassLoader();
|
|
||||||
$loader->registerNamespaces(array(
|
|
||||||
'Symfony' => array($vendorDir.'/symfony/src', $vendorDir.'/bundles'),
|
|
||||||
'Doctrine\\Common' => $vendorDir.'/doctrine-common/lib',
|
|
||||||
'Doctrine\\DBAL' => $vendorDir.'/doctrine-dbal/lib',
|
|
||||||
'Doctrine' => $vendorDir.'/doctrine/lib',
|
|
||||||
));
|
|
||||||
|
|
||||||
$loader->register();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
require_once $file;
|
throw new RuntimeException('Install dependencies to run test suite.');
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_autoload_register(function($class) {
|
spl_autoload_register(function($class) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue