Stworzyłem sobie klasę koszyka i klasę produktu. Dla wygodnego wyświetlania zawartości koszyk implementuje interfejs Iterator i tutaj pojawia się dziwnym problem. Gdy dodam kilka produktów do koszyka wszystko działa, pętla foreach poprawnie wyświetla produkty ale jak usunę tylko jeden produkt to w pętli już nic się nie wyświetla. Oto cały kod:
<?php
class CartProduct {
private $id;
private $quantity;
public function __construct($id, $quantity) {
$this->id = $id;
$this->setQuantity($quantity);
}
public function id() {
return $this->id;
}
public function setQuantity($quantity) {
$q = (int)$quantity;
$this->quantity = $q < 0 ? 0 : $q;
return $this;
}
public function increaseQuantity($value) {
$v = (int)$value;
$this->setQuantity($this->quantity() + $v);
return $this;
}
public function decreaseQuantity($value) {
$v = (int)$value;
$this->setQuantity($this->quantity() - $v);
return $this;
}
public function quantity() {
return $this->quantity;
}
public function equals(CartProduct $product) {
return $this->id == $product->id;
}
public function append(CartProduct $product) {
if($this->equals($product)) {
$this->increaseQuantity($product->quantity());
}
return $this;
}
}
class Cart implements Iterator {
private $products = array();
private $cursor = 0;
public function add(CartProduct $product) {
if(($existingProduct = $this->search($product))) {
$existingProduct->append($product);
} else {
$this->products[] = $product;
}
return $this;
}
public function remove(CartProduct $product) {
$tmp = array_filter($this->products, function($p) use ($product){
return !$p->equals($product);
});
$this->products = $tmp;
return $this;
}
public function search(CartProduct $product) {
foreach($this as $p) {
if($p->equals($product)) return $p;
}
return false;
}
public function current() {
return isset($this->products[$this->cursor]) ? $this->products[$this->cursor] : null;
}
public function key() {
return $this->cursor;
}
public function next() {
$row = $this->current();
$this->cursor++;
return $row;
}
public function rewind() {
$this->cursor = 0;
}
public function valid() {
return (!is_null($this->current()));
}
}
$cart = new Cart();
$p1 = new CartProduct(1, 10);
$p2 = new CartProduct(2, 20);
$p3 = new CartProduct(3, 30);
$cart->add($p1)->add($p2)->add($p3);
foreach($cart as $p) { //ta petla dziala
var_dump($p);
}
$cart->remove($p1);
foreach($cart as $p) { //ta nie dziala
var_dump($p);
}