HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/app/Cart/ShoppingCart.php
<?php
namespace App\Cart;

use App\Discounts\DiscountableTrait;
use App\Products\AbstractProductable;
use App\Session\HasSessionTrait;
use App\Products\Product\Product;
use App\ShippingCosts\ShippingCostsService;
use App\Vat\VatService;

/**
 * Represents a shopping cart
 *
 * Class ShoppingCartService
 * @package App\Cart
 */
class ShoppingCart implements ShoppingCartInterface
{
    use HasSessionTrait;
    use DiscountableTrait;

    use HasCouponCodesTrait {
        addCouponCode as traitAddCouponCode;
        removeCouponCode as traitRemoveCouponCode;
    }

    /** @var array The names of variables in this class to store and restore. */
    protected $variablesForSession = [
        'items',
        'couponCodes',
        'shippingCosts'
    ];

    /** @var ShoppingCartItem[] $items */
    private array $items = [];
    private float $shippingCosts = 0;
    private VatService $vatService;
    private ShippingCostsService $shippingCostService;

    public function __construct()
    {
        $this->items = [];
        $this->discountPriceMutations = collect();
        $this->discountQuantityMutations = collect();

        $this->restoreFromSession();
    }

    /**
     * Add a productable in the cart
     *
     * @param AbstractProductable $productable
     * @param int $quantity
     * @return ShoppingCartItem
     */
    public function addProductable(AbstractProductable $productable, int $quantity = 1) : ?ShoppingCartItem
    {
        /** @var Product $product */
        if(!$productable) return null;

        //If item exists, update it's quantity...
        /** @var ShoppingCartItem $shoppingCartItem */
        $item = $this->getShoppingCartItemByProductableIdAndType($productable);
        if($item) {
            $item->setQuantity($item->getQuantity() + $quantity);
        }
        //Else add a new Shopping cart item
        else {
            /** @var ShoppingCartItem $shoppingCartItem */
            $shoppingCartItem = (app(ShoppingCartItem::class));

            $item = $shoppingCartItem->setProductable($productable)->setQuantity($quantity);
            $this->items[] = $item;
        }

        $this->saveSession();
        return $item;
    }

    /**
     * Returns an existing shoppingCartItem by checking if it has a productable with a
     * certain id or false if there was no shoppingcart item with a
     * productable with the specified productable id
     * @param $productable
     * @return ShoppingCartItem|false
     */
    private function getShoppingCartItemByProductableIdAndType(AbstractProductable $productable)
    {
        foreach($this->items as $item)
        {
            $itemProductable = $item->getProductable();

            /** @var ShoppingCartItem $item */
            if($itemProductable->id == $productable->id && get_class($productable) === get_class($itemProductable)) return $item;
        }

        return false;
    }

    /**
     * Set the amount of items for a product
     *
     * @param int $itemId
     * @param int $quantity
     *
     * @return ShoppingCartInterface
     */
    public function setItemQuantity(int $itemId, int $quantity = 1): ShoppingCartInterface
    {
        $item = $this->getItemById($itemId);
        if(!$item) return $this;

        $item->setQuantity($quantity);
        $this->saveSession();

        return $this;
    }


    /**
     * Deletes the ShoppingCartItem that has a product with the specified id
     *
     * @param int $itemId
     *
     * @return ShoppingCartInterface
     */
    public function deleteItem(int $itemId): ShoppingCartInterface
    {
        foreach($this->items as $index => $item) {
            if ($item->getId() == $itemId) {
                unset($this->items[$index]);
            }
        }

        $this->saveSession();

        return $this;
    }

    /**
     * Clears the shopping cart of all items
     *
     * @return ShoppingCartInterface
     */
    public function clear(): ShoppingCartInterface
    {
        $this->items = [];
        $this->saveSession();

        return $this;
    }

    /**
     * Returns the amount of items in the cart.
     * @return int
     */
    public function getItemsCount(): int
    {
        return array_reduce($this->getItems(), function (int $accumulator, ShoppingCartItem $item) {
            return $accumulator + $item->getQuantity();
        }, 0);
    }

    /**
     * Get all shopping cart items
     *
     * @return array
     */
    public function getItems(): array
    {
        return !empty($this->items) ? $this->items : [];
    }

    /**
     * Get a shoppingCartItem by ID
     *
     * @param $itemId int
     * @return ShoppingCartItem
     */
    private function getItemById(int $itemId): ?ShoppingCartItem
    {
        $returnItem = null;
        foreach($this->items as $index => $item) {
            if ($item->getId() == $itemId) {
                $returnItem = $item;
            }
        }
        return $returnItem;
    }
}