<?php
namespace App\Business\Cart\Session;
use App\Business\Cart\Transfer\CartAreaTransfer;
use App\Entity\Customer;
use App\Entity\CustomerAdvertisingArea;
use App\Repository\CustomerAdvertisingAreaRepository;
use App\Service\Utils\CustomerServiceInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class CartSessionHandler implements CartSessionHandlerInterface
{
private const CART_SESSION_NAME = 'CartSessionHandler:CART';
private SessionInterface $session;
private CustomerAdvertisingAreaRepository $customerAdvertisingAreaRepository;
private Customer $customer;
private CustomerServiceInterface $customerService;
private EntityManagerInterface $entityManager;
/**
* @param EntityManagerInterface $entityManager
* @param CustomerAdvertisingAreaRepository $customerAdvertisingAreaRepository
* @param CustomerServiceInterface $customerService
* @param RequestStack $request
*/
public function __construct(
EntityManagerInterface $entityManager,
CustomerAdvertisingAreaRepository $customerAdvertisingAreaRepository,
CustomerServiceInterface $customerService,
RequestStack $request
) {
$this->session = $request->getSession();
$this->customerAdvertisingAreaRepository = $customerAdvertisingAreaRepository;
$this->customerService = $customerService;
$this->entityManager = $entityManager;
if ($this->customerService->getCustomerByHost() !== null) {
$this->customer = $this->customerService->getCustomerByHost();
} else {
$this->customer = $this->customerService->getCustomer();
}
$this->init();
}
/**
* @return void
*/
protected function init(): void
{
/** @var ArrayCollection|null $items */
$items = $this->session->get(static::CART_SESSION_NAME);
if ($items === null) {
$items = new ArrayCollection();
}
$this->session->set(static::CART_SESSION_NAME, $items);
}
/**
* @return void
*/
public function clear(): void
{
$this->session->remove(static::CART_SESSION_NAME);
}
/**
* @param string $areaUuid
*
* @return CartAreaTransfer|null
*/
public function getItem(string $areaUuid): ?CartAreaTransfer
{
$items = $this->session->get(static::CART_SESSION_NAME);
/** @var CartAreaTransfer $item */
foreach ($items as $item) {
if ($areaUuid === $item->getUuidCustomerAdvertisingArea()) {
return $item;
}
}
return null;
}
/**
* @param bool $entity
*
* @return Collection|null
*/
public function getItems(bool $entity = false): ?Collection
{
if ($entity === true) {
$collection = new ArrayCollection();
/** @var CartAreaTransfer $item */
foreach ($this->session->get(static::CART_SESSION_NAME) as $item) {
$area = $this->entityManager->getRepository(CustomerAdvertisingArea::class)
->findOneBy([
'uuid' => $item->getUuidCustomerAdvertisingArea(),
'customer' => $this->customer->getId()
]);
if ($area === null) {
continue;
}
$area->setWithinSetupPrice($item->isWithinSetupPrice());
$collection->add($area);
}
return $collection;
}
return $this->session->get(static::CART_SESSION_NAME);
}
/**
* @param CartAreaTransfer $cartAreaTransfer
*
* @return bool
*/
public function addToCart(CartAreaTransfer $cartAreaTransfer): bool
{
if ($this->isInCart($cartAreaTransfer) === true) {
return false;
}
/** @var ArrayCollection<CartAreaTransfer> $items */
$items = $this->session->get(static::CART_SESSION_NAME);
$items->add($cartAreaTransfer);
$this->session->set(static::CART_SESSION_NAME, $items);
return true;
}
/**
* @param string $uuidCustomerAdvertisingArea
*
* @return bool
*/
public function removeFromCart(string $uuidCustomerAdvertisingArea): bool
{
$cartAreaTransfer = (new CartAreaTransfer())
->setUuidCustomerAdvertisingArea($uuidCustomerAdvertisingArea);
if ($this->isInCart($cartAreaTransfer) === false) {
return false;
}
/** @var ArrayCollection<CartAreaTransfer> $items */
$items = $this->session->get(static::CART_SESSION_NAME);
$rebuildCollection = new ArrayCollection();
/** @var CartAreaTransfer $item */
foreach ($items as $item) {
if ($item->getUuidCustomerAdvertisingArea() === $uuidCustomerAdvertisingArea) {
continue;
}
$rebuildCollection->add($item);
}
$this->session->set(static::CART_SESSION_NAME, $rebuildCollection);
return true;
}
/**
* @param CartAreaTransfer $cartAreaTransfer
*
* @return bool
*/
public function isInCart(CartAreaTransfer $cartAreaTransfer): bool
{
/** @var ArrayCollection<CartAreaTransfer> $items */
$items = $this->session->get(static::CART_SESSION_NAME);
if ($items === null) {
return false;
}
$customerAdvertisingArea = $this->customerAdvertisingAreaRepository->findOneBy([
'uuid' => $cartAreaTransfer->getUuidCustomerAdvertisingArea(),
'customer' => $this->customer->getId(),
]);
/** @var CartAreaTransfer $item */
return $items->exists(function ($key, $item) use ($customerAdvertisingArea) {
return $item->getUuidCustomerAdvertisingArea() === $customerAdvertisingArea->getUuid();
});
}
/**
* @param string $areaUuid
*
* @return bool
*/
public function toggleAreaProductionAndSetup(string $areaUuid): bool
{
$selectedItem = null;
/** @var ArrayCollection<CartAreaTransfer> $items */
$items = $this->getItems();
foreach ($items as $item) {
if ($areaUuid !== $item->getUuidCustomerAdvertisingArea()) {
continue;
}
$selectedItem = $item;
break;
}
if ($selectedItem === null) {
return false;
}
$selectedItem->setWithinSetupPrice(!$selectedItem->isWithinSetupPrice());
return true;
}
}