Here is my shopping cart class! I want it to be perfect and never to have to implement it.
What improvements would you do?
New : IComparable
interface IComparable
{
public function equals($object);
}
New : ICartItem
interface ICartItem extends IComparable
{
public function setQuantity($quantity);
public function getQuantity();
}
New : ICart
interface ICart
{
public function add(ICartItem $item);
public function remove(ICartItem $item);
public function getQuantity(ICartItem $item);
public function setQuantity(ICartItem $item, $quantity);
public function isEmpty();
public function getItems();
public function clear();
}
New : Cart
class SessionCart implements ICart
{
const IDENTIFIER = '_CART_';
protected $items;
public function __construct(&$container = null)
{
if (is_null($container)) {
if (session_id() == '') {
session_start();
}
if (!isset($_SESSION[self::IDENTIFIER])) {
$_SESSION[self::IDENTIFIER] = array();
}
$container = & $_SESSION[self::IDENTIFIER];
}
$this->items = & $container;
}
public function add(ICartItem $item)
{
$index = $this->getIndexOfItem($item);
if ($index == -1) {
$this->items[] = $item;
} else {
$item = $this->items[$index];
$item->setQuantity($item->getQuantity() + 1);
}
return $item->getQuantity();
}
public function remove(ICartItem $item)
{
$index = $this->getIndexOfItem($item);
if ($index == -1) {
throw new Exception('The item isn\'t inside the cart.');
}
$item = $this->items[$index];
$quantity = $item->getQuantity() - 1;
if ($quantity > 0) {
$item->setQuantity($quantity);
} else {
unset($this->items[$index]);
}
return $quantity;
}
public function getQuantity(ICartItem $item)
{
$index = $this->getIndexOfItem($item);
if ($index == -1) {
return 0;
} else {
return $this->items[$index]->getQuantity();
}
}
public function setQuantity(ICartItem $item, $quantity)
{
if (($quantity = (int)$quantity) < 1) {
throw new Exception('A positive quantity is required.');
}
$index = $this->getIndexOfItem($item);
if ($index == -1) {
$item->setQuantity($quantity);
$this->items[] = $item;
} else {
$item = $this->items[$index];
$item->setQuantity($quantity);
}
return $item->getQuantity();
}
public function isEmpty()
{
return empty($this->items);
}
public function getItems()
{
return $this->items;
}
public function clear()
{
$this->items = array();
}
private function getIndexOfItem(ICartItem $item)
{
foreach ($this->items as $key => $value) {
if ($item->equals($value)) {
return $key;
}
}
return -1;
}
}