<?php declare(strict_types=1);
/**
* @copyright 2020 Crehler Sp. z o. o. <https://crehler.com>
*
* @author Jakub MedyĆski <jme@crehler.com>
* @support Crehler <support@crehler.com>
* @created 13 maj 2020
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Crehler\ShoppingList\Storefront\Controller;
use Crehler\ShoppingList\CrehlerShoppingList;
use Crehler\ShoppingList\Document\ShoppingListDocumentService;
use Crehler\ShoppingList\Service\ShoppingListService;
use Crehler\ShoppingList\Storefront\Page\ShoppingList\ShoppingListPageLoader;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Crehler\ShoppingList\Document\Controller\ShoppingListDocumentController;
use DateTimeImmutable;
use DateTimeZone;
/**
* @RouteScope(scopes={"storefront"})
*/
class ShoppingListController extends StorefrontController
{
private ShoppingListPageLoader $shoppingListPageLoader;
private ShoppingListService $shoppingListService;
private ShoppingListDocumentService $shoppingListDocumentService;
public function __construct(
ShoppingListPageLoader $shoppingListPageLoader,
ShoppingListService $shoppingListService,
ShoppingListDocumentService $shoppingListDocumentService)
{
$this->shoppingListPageLoader = $shoppingListPageLoader;
$this->shoppingListService = $shoppingListService;
$this->shoppingListDocumentService = $shoppingListDocumentService;
}
/**
* @Route("/shopping-list/cart-to-pdf", name="frontend.shopping-list.cart-to-pdf", methods={"POST"}, options={"seo"="false"}, defaults={"XmlHttpRequest": true})
*/
public function saveCartAndPrintPdf(Request $request, SalesChannelContext $salesChannelContext): Response
{
$productsData = json_decode($request->get('pdf_creator_add_to_post_products_data'), true);
$token = $request->cookies->get(CrehlerShoppingList::SHOPPING_LIST_COOKIE_TOKEN_NAME);
$dateNow = new DateTimeImmutable();
$dateNow = $dateNow->setTimezone(new \DateTimeZone('Europe/Warsaw'));
$listName = 'Koszyk_' . $dateNow->format('Y_m_d_H:i:s');
$listId = $this->shoppingListService->addListProducts(
$listName,
$productsData,
$token,
$salesChannelContext
);
$this->shoppingListDocumentService->createPdf($listId, true, $salesChannelContext);
$page = $this->shoppingListPageLoader->loadDetail($listId, $request, $salesChannelContext);
if (null === $page) {
return $this->redirectToRoute('frontend.shopping-list.page');
}
return $this->renderStorefront('@CrehlerShoppingList/storefront/page/shopping-list/list.html.twig', ['page' => $page]);
}
/**
* @Route("/shopping-list", name="frontend.shopping-list.page", methods={"GET"}, defaults={"XmlHttpRequest": true})
*/
public function index(Request $request, SalesChannelContext $salesChannelContext): Response
{
$page = $this->shoppingListPageLoader->load($request, $salesChannelContext);
return $this->renderStorefront('@CrehlerShoppingList/storefront/page/shopping-list/index.html.twig', ['page' => $page]);
}
/**
* @Route("/widgets/shopping-list", name="widgets.shopping-list.page", methods={"GET"}, defaults={"XmlHttpRequest": true})
*/
public function widgetsIndex(Request $request, SalesChannelContext $salesChannelContext): Response
{
$page = $this->shoppingListPageLoader->load($request, $salesChannelContext);
return $this->renderStorefront('@CrehlerShoppingList/storefront/page/shopping-list/widgets-index.html.twig', ['page' => $page]);
}
/**
* @Route("/shopping-list/list/{listId}", name="frontend.shopping-list.list", methods={"GET"}, defaults={"XmlHttpRequest": true})
*/
public function list(string $listId, Request $request, SalesChannelContext $salesChannelContext): Response
{
$token = $request->cookies->get(CrehlerShoppingList::SHOPPING_LIST_COOKIE_TOKEN_NAME);
$page = $this->shoppingListPageLoader->loadDetail($listId, $request, $salesChannelContext);
$isCustomer = $salesChannelContext->getCustomer() instanceof CustomerEntity;
if (null === $page) {
return $this->redirectToRoute('frontend.shopping-list.page');
}
if ($this->shoppingListService->isShareList(
$listId,
$isCustomer ? $salesChannelContext->getCustomer()->getId() : null,
$token,
$salesChannelContext
)) {
return $this->renderStorefront('@CrehlerShoppingList/storefront/page/shopping-list/share.html.twig', ['page' => $page]);
}
return $this->renderStorefront('@CrehlerShoppingList/storefront/page/shopping-list/list.html.twig', ['page' => $page]);
}
/**
* @Route("/shopping-list/create", name="frontend.shopping-list.page.create", methods={"POST"}, options={"seo"="false"}, defaults={"XmlHttpRequest": true})
*/
public function create(Request $request, SalesChannelContext $salesChannelContext): Response
{
$isJsonRequest = 'json' === $request->getContentType();
$token = $request->cookies->get(CrehlerShoppingList::SHOPPING_LIST_COOKIE_TOKEN_NAME);
$isCustomer = $salesChannelContext->getCustomer() instanceof CustomerEntity;
$productId = $request->get('productId');
$productsData = $request->get('productsData');
if ($productsData) {
$listId = $this->shoppingListService->addListProducts(
$request->get('name'),
$productsData,
$token,
$salesChannelContext
);
} else {
$listId = $this->shoppingListService->addList(
$request->get('name'),
$productId,
(int)$request->get('quantity', 1),
$token,
$salesChannelContext
);
}
if ($isJsonRequest) {
return JsonResponse::create(
$this->shoppingListService->getShoppingLists(
$isCustomer ? $salesChannelContext->getCustomer()->getId() : null,
$token,
$salesChannelContext,
true
)->jsonSerialize()
);
}
return new RedirectResponse($this->generateUrl('frontend.shopping-list.list', ['listId' => $listId]));
}
/**
* @Route("/shopping-list/remove", name="frontend.shopping-list.page.remove", methods={"POST"}, options={"seo"="false"}, defaults={"XmlHttpRequest": true})
*/
public function remove(Request $request, SalesChannelContext $salesChannelContext): Response
{
$listId = $request->get('listId');
if (null !== $listId) {
$this->shoppingListService->deleteList($listId, $salesChannelContext);
}
return $this->createActionResponse($request);
}
/**
* @Route("/shopping-list/rename", name="frontend.shopping-list.page.rename", methods={"POST"}, options={"seo"="false"}, defaults={"XmlHttpRequest": true})
*/
public function rename(Request $request, SalesChannelContext $salesChannelContext): Response
{
$listId = $request->get('listId');
$name = $request->get('name');
if (null !== $listId && $name) {
$this->shoppingListService->renameList($listId, $name, $salesChannelContext);
}
return $this->createActionResponse($request);
}
/**
* @Route("/shopping-list/addItem", name="frontend.shopping-list.page.addItem", methods={"POST"}, options={"seo"="false"}, defaults={"XmlHttpRequest": true})
*/
public function addItem(Request $request, SalesChannelContext $salesChannelContext): Response
{
$isJsonRequest = 'json' === $request->getContentType();
$isCustomer = $salesChannelContext->getCustomer() instanceof CustomerEntity;
$token = $request->cookies->get(CrehlerShoppingList::SHOPPING_LIST_COOKIE_TOKEN_NAME);
$productId = $request->get('productId');
$productsData = $request->get('productsData');
if ($productId) {
$this->shoppingListService->addItem(
$productId,
$request->get('shoppingListId'),
$request->get('quantity'),
$token,
$salesChannelContext
);
} elseif ($productsData) {
$this->shoppingListService->addItems(
$productsData,
$request->get('shoppingListId'),
$token,
$salesChannelContext
);
}
if ($isJsonRequest) {
return JsonResponse::create(
$this->shoppingListService->getShoppingLists(
$isCustomer ? $salesChannelContext->getCustomer()->getId() : null,
$token,
$salesChannelContext,
true
)->jsonSerialize()
);
}
return new RedirectResponse($this->generateUrl('frontend.shopping-list.page', ['itemAdded' => true]));
}
/**
* @Route("/shopping-list/changeQuantity", name="frontend.shopping-list.page.changeQuantity", methods={"POST"}, options={"seo"="false"}, defaults={"XmlHttpRequest": true})
*/
public function changeQuantity(Request $request, SalesChannelContext $salesChannelContext): Response
{
try {
$listId = $request->get('listId');
$quantity = $request->get('quantity');
if ($quantity === null) {
throw new \InvalidArgumentException('quantity field is required');
}
if ($quantity < 1) {
throw new \InvalidArgumentException('quantity cannot be lower than 0');
}
$shoppingListItemId = $request->get('shoppingListItemId');
if ($shoppingListItemId === null) {
throw new \InvalidArgumentException('shopping list item id field is required');
}
$this->shoppingListService->changeQuantity($listId, $shoppingListItemId, (int)$quantity, $salesChannelContext);
$this->addFlash('success', $this->trans('shoppingList.shoppingListUpdateSuccess'));
} catch (\Exception $exception) {
$this->addFlash('danger', $this->trans('error.message-default'));
}
return $this->createActionResponse($request);
}
/**
* @Route("/shopping-list/deleteItem", name="frontend.shopping-list.page.deleteItem", methods={"POST"}, options={"seo"="false"}, defaults={"XmlHttpRequest": true})
*/
public function deleteItem(Request $request, SalesChannelContext $salesChannelContext): Response
{
try {
$listId = $request->get('listId');
$shoppingListItemId = $request->get('shoppingListItemId');
$shoppingListItemIds = $request->get('shoppingListItemIds');
if ($shoppingListItemId === null && $shoppingListItemIds === null) {
throw new \InvalidArgumentException('shopping list item id field is required');
}
$this->shoppingListService->deleteItems($listId,
$shoppingListItemIds ?? [$shoppingListItemId], $salesChannelContext);
$this->addFlash('success', $this->trans('shoppingList.shoppingListRemoveSuccess'));
} catch (\Exception $exception) {
$this->addFlash('danger', $this->trans('error.message-default'));
}
return $this->createActionResponse($request);
}
/**
* @Route("/widgets/shopping-list/info", name="frontend.shopping-list.info", methods={"GET"}, defaults={"XmlHttpRequest"=true})
*/
public function info(Request $request, SalesChannelContext $salesChannelContext): Response
{
$page = $this->shoppingListPageLoader->load($request, $salesChannelContext);
return $this->renderStorefront('@CrehlerShoppingList/storefront/layout/header/actions/shopping-list-widget.html.twig', ['page' => $page]);
}
}