<?php declare(strict_types=1);
/**
* gb media
* All Rights Reserved.
*
* Unauthorized copying of this file, via any medium is strictly prohibited.
* The content of this file is proprietary and confidential.
*
* @category Shopware
* @package Shopware_Plugins
* @subpackage GbmedShoppingList
* @copyright Copyright (c) 2020, gb media
* @license proprietary
* @author Giuseppe Bottino
* @link http://www.gb-media.biz
*/
namespace Gbmed\ShoppingList\Controller;
use Gbmed\ShoppingList\Storefront\Page\Account\Order\AccountShoppingListPage;
use Gbmed\ShoppingList\Service\ShoppingList;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\Error\Error;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Content\Product\Exception\ProductNotFoundException;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Storefront\Page\GenericPageLoaderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* @Route(defaults={"_routeScope"={"storefront"}})
*/
class ShoppingListController extends StorefrontController
{
private GenericPageLoaderInterface $genericLoader;
private ShoppingList $shoppingListService;
private CartService $cartService;
/**
* ShoppingListController constructor.
* @param GenericPageLoaderInterface $genericLoader
* @param ShoppingList $shoppingListService
* @param CartService $cartService
*/
public function __construct(
GenericPageLoaderInterface $genericLoader,
ShoppingList $shoppingListService,
CartService $cartService
) {
$this->genericLoader = $genericLoader;
$this->shoppingListService = $shoppingListService;
$this->cartService = $cartService;
}
/**
* @Route(
* "/account/shoppinglist",
* name="frontend.shopping_list.overview.page",
* methods={"GET"},
* options={"seo"="false"},
* defaults={"_loginRequired"=true}
* )
* @param Request $request
* @param SalesChannelContext $salesChannelContext
* @return Response
* @throws \Exception
*/
public function shoppingLists(Request $request, SalesChannelContext $salesChannelContext): Response
{
$page = $this->genericLoader->load($request, $salesChannelContext);
$page = AccountShoppingListPage::createFrom($page);
try {
$page->setShoppingLists($this->shoppingListService->getCustomerShoppingLists($salesChannelContext));
} catch (\Exception $e) {
throw $e;
}
return $this->renderStorefront('@Storefront/storefront/page/account/shopping_list/index.html.twig',
['page' => $page]);
}
/**
* @Route(
* "/shoppinglist/rename",
* name="gbmed.shopping_list.rename",
* methods={"POST"},
* defaults={"XmlHttpRequest"=true,"csrf_protected"=true, "_loginRequired"=true},
* options={"seo"="false"}
* )
* @param Request $request
* @param SalesChannelContext $salesChannelContext
* @return JsonResponse
* @throws \Exception
*/
public function renameShoppingList(Request $request, SalesChannelContext $salesChannelContext): JsonResponse
{
$name = $request->get('name');
$data = [
'id' => $request->get('id'),
'name' => strlen(trim($name)) ? $name : 'Shopping-List'
];
try {
$this->shoppingListService->renameCustomerShoppingList(
$data['id'],
[$data],
$salesChannelContext
);
} catch (\Exception $e) {
throw $e;
}
return new JsonResponse(['success' => true]);
}
/**
* @Route(
* "/shoppinglist/remove",
* name="gbmed.shopping_list.remove",
* methods={"POST"},
* defaults={"XmlHttpRequest"=true,"csrf_protected"=true, "_loginRequired"=true},
* options={"seo"="false"}
* )
* @param Request $request
* @param SalesChannelContext $salesChannelContext
* @return JsonResponse
* @throws \Exception
*/
public function removeShoppingList(Request $request, SalesChannelContext $salesChannelContext): JsonResponse
{
$data = [
'id' => $request->get('id')
];
try {
$this->shoppingListService->removeCustomerShoppingList(
$data['id'],
[$data],
$salesChannelContext
);
} catch (\Exception $e) {
throw $e;
}
return new JsonResponse(['success' => true]);
}
/**
* @Route(
* "/shoppinglist/remove-product",
* name="gbmed.shopping_list.remove.product",
* methods={"POST"},
* defaults={"XmlHttpRequest"=true,"csrf_protected"=true, "_loginRequired"=true},
* options={"seo"="false"}
* )
* @param Request $request
* @param SalesChannelContext $salesChannelContext
* @return JsonResponse
* @throws \Exception
*/
public function removeShoppingListProduct(Request $request, SalesChannelContext $salesChannelContext): JsonResponse
{
$id = $request->get('id');
try {
$this->shoppingListService->deleteCustomerProductItem($id, $salesChannelContext);
} catch (\Exception $e) {
throw $e;
}
return new JsonResponse(['success' => true]);
}
/**
* @Route(
* "/shoppinglist/push-product",
* name="gbmed.shopping_list.push.product",
* methods={"POST"},
* defaults={"XmlHttpRequest"=true,"csrf_protected"=true, "_loginRequired"=true},
* options={"seo"="false"}
* )
* @param Request $request
* @param SalesChannelContext $salesChannelContext
* @return JsonResponse
* @throws \Exception
*/
public function pushShoppingListProduct(Request $request, SalesChannelContext $salesChannelContext): JsonResponse
{
$productId = $request->get('productId');
$quantity = (int)$request->get('quantity', 1);
$existList = $request->get('existList');
$newList = $request->get('newList');
try {
if ($existList && $productId) {
$data = [
'gbmedShoppingListId' => $existList,
'gbmedShoppingListProductId' => Uuid::randomHex(),
'productId' => $productId,
'quantity' => $quantity
];
$this->shoppingListService->createCustomerProductItem($data, $salesChannelContext);
} else {
if (trim($newList) && $productId) {
$data = [
'gbmedShoppingListId' => Uuid::randomHex(),
'customerId' => $salesChannelContext->getCustomer()->getId(),
'name' => $newList,
'position' => 0,
'gbmedShoppingListProductId' => Uuid::randomHex(),
'productId' => $productId,
'quantity' => $quantity
];
$this->shoppingListService->createCustomerProductItem($data, $salesChannelContext);
}
}
} catch (\Exception $e) {
throw $e;
}
return new JsonResponse(['success' => true]);
}
/**
* @Route(
* "/shoppinglist/push-cart",
* name="gbmed.shopping_list.push.cart",
* methods={"POST"},
* defaults={"XmlHttpRequest"=true,"csrf_protected"=true, "_loginRequired"=true},
* options={"seo"="false"}
* )
* @param Request $request
* @param SalesChannelContext $salesChannelContext
* @return JsonResponse
* @throws \Exception
*/
public function pushShoppingListCart(Request $request, SalesChannelContext $salesChannelContext): JsonResponse
{
$cart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
$existList = $request->get('existList');
$newList = $request->get('newList');
$data = [
'gbmedShoppingListId' => $existList,
'customerId' => $salesChannelContext->getCustomer()->getId(),
'position' => 0,
];
if (trim($newList)) {
$data = array_merge($data, [
'gbmedShoppingListId' => Uuid::randomHex(),
'name' => $newList,
]);
}
try {
foreach ($cart->getLineItems() as $lineItem) {
$data['gbmedShoppingListProductId'] = Uuid::randomHex();
$data['productId'] = $lineItem->getId();
$data['quantity'] = $lineItem->getQuantity();
$this->shoppingListService->createCustomerProductItem($data, $salesChannelContext);
}
} catch (\Exception $e) {
throw $e;
}
return new JsonResponse(['success' => true]);
}
/**
* @Route("/shoppinglist/line-item/add",
* name="gbmed.shopping_list.line-item.add",
* methods={"POST"},
* defaults={"XmlHttpRequest"=true,"csrf_protected"=true, "_loginRequired"=true},
* options={"seo"="false"}
* )
*/
public function addLineItems(Cart $cart, RequestDataBag $requestDataBag, Request $request, SalesChannelContext $context): Response
{
/** @var RequestDataBag|null $lineItems */
$lineItems = $requestDataBag->get('lineItems');
if ($lineItems) {
try {
$items = [];
/** @var RequestDataBag $lineItemData */
foreach ($lineItems as $lineItemData) {
if($lineItemData->getInt('quantity', 0) < 1){
continue;
}
$lineItem = new LineItem(
$lineItemData->getAlnum('id'),
$lineItemData->getAlnum('type'),
$lineItemData->get('referencedId'),
$lineItemData->getInt('quantity', 1)
);
$lineItem->setStackable($lineItemData->getBoolean('stackable', true));
$lineItem->setRemovable($lineItemData->getBoolean('removable', true));
$items[] = $lineItem;
}
$cart = $this->cartService->add($cart, $items, $context);
} catch (ProductNotFoundException $exception) {
throw $exception;
}
}
return $this->createActionResponse($request);
}
private function traceErrors(Cart $cart): bool
{
if ($cart->getErrors()->count() <= 0) {
return false;
}
$this->addCartErrors($cart, function (Error $error) {
return $error->isPersistent();
});
return true;
}
}