src/Services/CartService.php line 269

Open in your IDE?
  1. <?php
  2. namespace App\Services;
  3. use App\Model\DataObject\Customer;
  4. use App\Model\DataObject\Sample;
  5. use Carbon\Carbon;
  6. use CustomerManagementFrameworkBundle\Model\CustomerInterface;
  7. use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\CartInterface;
  8. use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\SessionCart;
  9. use Pimcore\Bundle\EcommerceFrameworkBundle\EnvironmentInterface;
  10. use Pimcore\Bundle\EcommerceFrameworkBundle\Factory;
  11. use Pimcore\Bundle\EcommerceFrameworkBundle\Model\CheckoutableInterface;
  12. use Pimcore\Model\DataObject\OnlineShopOrder;
  13. use Symfony\Component\HttpFoundation\Cookie;
  14. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  15. use Symfony\Component\Security\Core\Security;
  16. class CartService {
  17.     public const CART_KEY 'cart';
  18.     public const GUEST_ORDER_LIMIT 3;
  19.     public const PRODUCT_ORDER_LIMIT 3;
  20.     public const COOKIE_GUEST_LIMIT 'cookie_guest_limit';
  21.     protected const COOKIE_GUEST_LIMIT_LIFETIME 24// hours
  22.     const USER_ORDER_LIMIT 999;
  23.     protected ?EnvironmentInterface $environment null;
  24.     private bool $cartInitialized false;
  25.     public function __construct(protected Factory $factory, protected Security $security, protected StockService $stockService, protected SessionInterface $session)
  26.     {
  27.     }
  28.     public function getEnvironment(): ?EnvironmentInterface
  29.     {
  30.         if (!$this->environment instanceof EnvironmentInterface) {
  31.             $this->environment $this->factory->getEnvironment();
  32.         }
  33.         return $this->environment;
  34.     }
  35.     /**
  36.      * @param string $cartName
  37.      *
  38.      * @return CartInterface
  39.      */
  40.     public function getCart(string $cartName self::CART_KEY ): CartInterface
  41.     {
  42.         $cartManager $this->factory->getCartManager();
  43.         if (!$this->cartInitialized) {
  44.             $this->initializeCart($cartName);
  45.         }
  46.         return $cartManager->getOrCreateCartByName$cartName );
  47.     }
  48.     /**
  49.      * @param CheckoutableInterface $product
  50.      * @param int $count
  51.      * @param null $comment
  52.      * @param string $cartName
  53.      * @return CartInterface
  54.      */
  55.     public function addToCartCheckoutableInterface $productint $count 1$comment nullstring $cartName self::CART_KEY ): CartInterface
  56.     {
  57.         $cart $this->getCart$cartName );
  58.         $cart->addItem$product$countnullfalse, [], [], $comment );
  59.         $cart->save();
  60.         return $cart;
  61.     }
  62.     public function containsProductCheckoutableInterface $productstring $cartName self::CART_KEY ): bool
  63.     {
  64.         $cart $this->getCart$cartName );
  65.         foreach($cart->getItems() as $item) {
  66.             if ($item->getProduct()->getId() === $product->getId()) {
  67.                 return true;
  68.             }
  69.         }
  70.         return false;
  71.     }
  72.     public function limitItemCountToMax(string $cartName self::CART_KEY): void
  73.     {
  74.         $cart $this->getCart($cartName);
  75.         $modified false;
  76.         foreach($cart->getItems() as $item) {
  77.             if ($item->getCount() > 3) {
  78.                 $item->setCount(3);
  79.                 $modified true;
  80.             }
  81.         }
  82.         if ($modified) {
  83.             $cart->save();
  84.         }
  85.     }
  86.     /**
  87.      * @param CheckoutableInterface $product
  88.      * @param int $count
  89.      * @param string $cartName
  90.      * @return CartInterface
  91.      */
  92.     public function updateCartItem(  CheckoutableInterface $productint $count 1string $cartName self::CART_KEY ): CartInterface
  93.     {
  94.         $cart $this->getCart$cartName );
  95.         if( $count <= ){
  96.             $cart->removeItem$product->getId() );
  97.         } else {
  98.             $cart->updateItemCount$product->getId(), $count );
  99.         }
  100.         $cart->save();
  101.         return $cart;
  102.     }
  103.     public function removeCartItem(string $itemKeystring $cartName self::CART_KEY): CartInterface
  104.     {
  105.         $cart $this->getCart$cartName );
  106.         $cart->removeItem($itemKey);
  107.         $cart->save();
  108.         return $cart;
  109.     }
  110.     /**
  111.      * load only Cart Counter
  112.      *
  113.      * @param string $cartName
  114.      *
  115.      * @return int
  116.      */
  117.     public function getCartCount(string $cartName self::CART_KEY): int
  118.     {
  119.         return $this->getCart($cartName)->getItemAmount();
  120.     }
  121.     /** Remove all items that in the cart
  122.      * @param string $cartName
  123.      */
  124.     public function emptyCart(string $cartName self::CART_KEY): void
  125.     {
  126.         $cart $this->getCart($cartName);
  127.         if(!empty($cart->getItems())) {
  128.             foreach($cart->getItems() as $cartItem) {
  129.                 $cart->removeItem($cartItem->getItemKey());
  130.             }
  131.             $cart->save();
  132.         }
  133.     }
  134.     public function deleteCart(string $cartName self::CART_KEY): void
  135.     {
  136.         $this->getCart($cartName)->delete();
  137.     }
  138.     /**
  139.      * @param bool $enabled
  140.      */
  141.     public function setUseGuestCart(bool $enabled): void
  142.     {
  143.         $env $this->getEnvironment();
  144.         if ($env && $env->getUseGuestCart() !== $enabled) {
  145.             $env->setUseGuestCart($enabled);
  146.             $env->save();
  147.         }
  148.     }
  149.     public function canAddToCart($cartName self::CART_KEY): bool
  150.     {
  151.         $cartCount $this->getCartCount($cartName);
  152.         $env $this->getEnvironment();
  153.         if ($env && $env->getUseGuestCart()) {
  154.             // if the guest has reached the daily limit. no ordering for him!
  155.             if($this->guestHasReachedDailySampleLimit()) {
  156.                 return false;
  157.             }
  158.             // guest could have already ordered something, still the limit applies
  159.             $cartCount += $this->getGuestOrderedAmount();
  160.             return $cartCount self::GUEST_ORDER_LIMIT;
  161.         }
  162.         return true;
  163.     }
  164.     /**
  165.      * @param $sessionCart
  166.      * @param $dbCart
  167.      * @throws \Exception
  168.      */
  169.     public function convertSessionCartToDbCart($sessionCart$dbCart)
  170.     {
  171.         foreach ($sessionCart->getItems() as $item) {
  172.             $dbCart->addItem($item->getProduct(), $item->getCount());
  173.         }
  174.         $dbCart->save();
  175.         $sessionCart->delete();
  176.     }
  177.     /**
  178.      * @param string $country
  179.      * @param string $cartName
  180.      *
  181.      * @return bool
  182.      * @throws \Doctrine\DBAL\Driver\Exception
  183.      * @throws \Doctrine\DBAL\Exception
  184.      */
  185.     public function checkAvailability(string $country LocationService::DEFAULT_LOCATIONstring $cartName self::CART_KEY): bool
  186.     {
  187.         $cart $this->getCart($cartName);
  188.         if(!$cart || empty($cart->getItems())) {
  189.             return false;
  190.         }
  191.         foreach($cart->getItems() as $cartItem) {
  192.             $product $cartItem->getProduct();
  193.             if($product instanceof Sample && $this->stockService->getStockForSampleBasedOnCountry($product$country) <= 0) {
  194.                 return false;
  195.             }
  196.         }
  197.         return true;
  198.     }
  199.     /**
  200.      * @param OnlineShopOrder $order
  201.      */
  202.     public function saveSampleAmountToSession(OnlineShopOrder $order): void
  203.     {
  204.          $value = (int)$this->getMaxOrderAmount($order);
  205.          $cookie $this->session->get(self::COOKIE_GUEST_LIMIT);
  206.          $expiresTime Carbon::now()->addHours(self::COOKIE_GUEST_LIMIT_LIFETIME)->getTimestamp();
  207.          if($cookie instanceof Cookie) {
  208.              $expiresTime $cookie->getExpiresTime();
  209.              $value += (int)$cookie->getValue();
  210.          }
  211.         $cookie = new Cookie(self::COOKIE_GUEST_LIMIT$value$expiresTime);
  212.         $this->session->set(self::COOKIE_GUEST_LIMIT$cookie);
  213.     }
  214.     /**
  215.      * @param OnlineShopOrder $order
  216.      *
  217.      * @return float|int|null
  218.      */
  219.     protected function getMaxOrderAmount(OnlineShopOrder $order) {
  220.         $amount 0;
  221.         $items $order->getItems();
  222.         if(!empty($items)) {
  223.             foreach($items as $item) {
  224.                 $amount += $item->getAmount();
  225.             }
  226.         }
  227.         return $amount;
  228.     }
  229.     /**
  230.      * @return bool
  231.      */
  232.     public function guestHasReachedDailySampleLimit(): bool
  233.     {
  234.         $this->checkIfCookieHasExpired();
  235.         $cookie $this->session->get(self::COOKIE_GUEST_LIMIT);
  236.         return $cookie instanceof Cookie && (int)$cookie->getValue() >= self::GUEST_ORDER_LIMIT;
  237.     }
  238.     /**
  239.      * @return int
  240.      */
  241.     protected function getGuestOrderedAmount(): int
  242.     {
  243.         $cookie $this->session->get(self::COOKIE_GUEST_LIMIT);
  244.         return $cookie instanceof Cookie ? (int)$cookie->getValue() : 0;
  245.     }
  246.     protected function checkIfCookieHasExpired(): void
  247.     {
  248.         $cookie $this->session->get(self::COOKIE_GUEST_LIMIT);
  249.         if($cookie instanceof Cookie && !$cookie->getMaxAge()) {
  250.             $this->session->set(self::COOKIE_GUEST_LIMITnull);
  251.         }
  252.     }
  253.     /**
  254.      * @param $cartName
  255.      */
  256.     protected function initializeCart($cartName): void
  257.     {
  258.         try {
  259.             $customer $this->security->getUser();
  260.             $environment $this->getEnvironment();
  261.             if($environment) {
  262.                 if (!$customer instanceof Customer) {
  263.                     $this->setUseGuestCart(true);
  264.                     $environment->setCurrentUserId(null);
  265.                     $environment->save();
  266.                 } else {
  267.                     $cartManager $this->factory->getCartManager();
  268.                     if ($environment->getCurrentUserId() !== $customer->getId()) {
  269.                         $environment->setCurrentUserId($customer->getId());
  270.                         $environment->save();
  271.                     }
  272.                     if ($environment->getUseGuestCart()) {
  273.                         $sessionCart $cartManager->getCartByName($cartName);
  274.                         $this->setUseGuestCart(false);
  275.                         $cartManager->reset();
  276.                         if ($sessionCart instanceof SessionCart) {
  277.                             $dbCart $cartManager->getOrCreateCartByName($cartName);
  278.                             $dbCart->setCheckoutData($cartName$sessionCart->getCheckoutData($cartName));
  279.                             $this->convertSessionCartToDbCart($sessionCart$dbCart);
  280.                             $sessionCart->delete();
  281.                         }
  282.                     }
  283.                 }
  284.             }
  285.         } catch (\Throwable $exception) {
  286.             $this->setUseGuestCart(!$customer instanceof Customer);
  287.         }
  288.         $this->cartInitialized true;
  289.     }
  290.     public function cartAddMaxAmount(CheckoutableInterface $productCustomerInterface $user nullstring $cartName self::CART_KEY): int
  291.     {
  292.         $cart $this->getCart($cartName);
  293.         $item $cart->getItem($product->getId());
  294.         $maxAmount self::PRODUCT_ORDER_LIMIT;
  295.         if ($item) {
  296.             $maxAmount -= $item->getCount();
  297.         }
  298.         if (!$user) {
  299.             $itemCount $cart->getItemAmount();
  300.             if (self::GUEST_ORDER_LIMIT $itemCount $maxAmount) {
  301.                 $maxAmount self::GUEST_ORDER_LIMIT $itemCount;
  302.             }
  303.         }
  304.         if ($user) {
  305.             $maxAmount self::USER_ORDER_LIMIT;
  306.         }
  307.         return $maxAmount;
  308.     }
  309. }