Skip to content

Instantly share code, notes, and snippets.

@BlackScorp
Last active March 28, 2022 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BlackScorp/d73b18e4d3d9549579ab1b3c0b51d131 to your computer and use it in GitHub Desktop.
Save BlackScorp/d73b18e4d3d9549579ab1b3c0b51d131 to your computer and use it in GitHub Desktop.
<?php
error_reporting(E_ALL);
interface CartItemInterface
{
public function getPrice(float $from = 0.1, float $to = 100.0): float;
}
class CartItem implements CartItemInterface
{
public function getPrice(float $from = 0.1, float $to = 100.0): float
{
return round((($to - $from) * (mt_rand(0, 100) / 100) + $from), 2);
}
}
class Discount implements CartItemInterface
{
public function getPrice(float $from = 0.1, float $to = 100.0): float
{
return 6.99;
}
}
class DiscountCalculatorService
{
private const CART_LIMIT = 1.0;
public function addDiscount(CartItemCollection $cartItems): CartItemCollection
{
if (count($cartItems) === 0) {
return $cartItems;
}
$total = 0.0;
foreach ($cartItems as $cartItem) {
$total += $cartItem->getPrice();
}
if ($total > self::CART_LIMIT) {
$cartItems[] = new Discount();
}
return $cartItems;
}
}
interface Collection extends Iterator, Countable, ArrayAccess, Serializable, Stringable{}
trait CollectionTrait{
private int $position = 0;
private array $items =[];
public function serialize()
{
return serialize($this->items);
}
public function unserialize(string $data)
{
$this->items = unserialize($data);
}
public function __serialize(): array
{
return $this->items;
}
public function __unserialize(array $data): void
{
$this->items = $data;
}
public function __toString(): string
{
return serialize($this);
}
public function offsetExists(mixed $offset): bool
{
return isset($this->items[$offset]);
}
public function offsetUnset(mixed $offset): void
{
unset($this->items[$offset]);
}
public function count(): int
{
return count($this->items);
}
public function current(): mixed
{
return $this->items[$this->position];
}
public function next(): void
{
++$this->position;
}
public function key(): mixed
{
return $this->position;
}
public function valid(): bool
{
return isset($this->items[$this->position]);
}
public function rewind(): void
{
$this->position = 0;
}
}
class CartItemCollection implements Collection
{
use CollectionTrait;
public function __construct(CartItemInterface... $items)
{
$this->items = $items;
}
public function offsetGet(mixed $offset): CartItemInterface
{
return $this->items[$offset];
}
public function offsetSet(mixed $offset, mixed $value): void
{
if(!$value instanceof CartItemInterface){
throw new InvalidArgumentException(sprintf("Unexpected Value type, expected %s",CartItemInterface::class));
}
if($offset === null){
$offset = $this->position;
}
$this->items[$offset] = $value;
}
}
$cartItems = [
new CartItem(),
new CartItem(),
];
$collection = new CartItemCollection(...$cartItems);
$calculator = new DiscountCalculatorService();
$newCartItems = $calculator->addDiscount($collection);
var_dump($newCartItems);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment