<?php declare(strict_types=1);
namespace KmPitchPrint\Controller;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerWishlistProduct\CustomerWishlistProductEntity;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\Exception\CustomerWishlistNotFoundException;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractAddWishlistProductRoute;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLoadWishlistRoute;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractMergeWishlistProductRoute;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractRemoveWishlistProductRoute;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Routing\Annotation\LoginRequired;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\Framework\Routing\Annotation\Since;
use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Wishlist\GuestWishlistPageLoader;
use Shopware\Storefront\Page\Wishlist\WishlistPageLoader;
use Shopware\Storefront\Page\Wishlist\WishListPageProductCriteriaEvent;
use Shopware\Storefront\Pagelet\Wishlist\GuestWishlistPageletLoader;
use Swp\ProductOptionsSix\Core\Checkout\ProductOptions\Cart\ProductOptionsCartDataCollector;
use Swp\ProductOptionsSix\Core\Content\ProductOptions\SalesChannel\ProductOptionsAddToCart;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use KmPitchPrint\Storefront\Page\Wishlist\KmWishlistGuestPageLoader;
use KmPitchPrint\Events\MoveToWishlistEvent;
/**
* @RouteScope(scopes={"storefront"})
*/
class WishlistController extends StorefrontController
{
private WishlistPageLoader $wishlistPageLoader;
private AbstractLoadWishlistRoute $wishlistLoadRoute;
private AbstractAddWishlistProductRoute $addWishlistRoute;
private AbstractRemoveWishlistProductRoute $removeWishlistProductRoute;
private AbstractMergeWishlistProductRoute $mergeWishlistProductRoute;
private GuestWishlistPageLoader $guestPageLoader;
private GuestWishlistPageletLoader $guestPageletLoader;
private EventDispatcherInterface $eventDispatcher;
/**
* @var CartService
*/
private $cartService;
/**
* @var KmWishlistGuestPageLoader
*/
private $kMWishlistGuestPageLoader;
private $productOptionsAddToCart;
public function __construct(
WishlistPageLoader $wishlistPageLoader,
AbstractLoadWishlistRoute $wishlistLoadRoute,
AbstractAddWishlistProductRoute $addWishlistRoute,
AbstractRemoveWishlistProductRoute $removeWishlistProductRoute,
AbstractMergeWishlistProductRoute $mergeWishlistProductRoute,
GuestWishlistPageLoader $guestPageLoader,
GuestWishlistPageletLoader $guestPageletLoader,
EventDispatcherInterface $eventDispatcher,
CartService $cartService,
KmWishlistGuestPageLoader $kMWishlistGuestPageLoader,
ProductOptionsAddToCart $productOptionsAddToCart
)
{
$this->wishlistPageLoader = $wishlistPageLoader;
$this->wishlistLoadRoute = $wishlistLoadRoute;
$this->addWishlistRoute = $addWishlistRoute;
$this->removeWishlistProductRoute = $removeWishlistProductRoute;
$this->mergeWishlistProductRoute = $mergeWishlistProductRoute;
$this->guestPageLoader = $guestPageLoader;
$this->guestPageletLoader = $guestPageletLoader;
$this->eventDispatcher = $eventDispatcher;
$this->cartService = $cartService;
$this->kMWishlistGuestPageLoader = $kMWishlistGuestPageLoader;
$this->productOptionsAddToCart = $productOptionsAddToCart;
}
private function wishlistIndex(Request $request, SalesChannelContext $context){
/**
* @var \KmPitchPrint\Services\TicketService
*
* Synchronisiere den Ticketstatus mit freescout
*/
$ticket = $this->container->get('km_pitch_print.services.ticket');
$ticket->syncCustomersTicketStatus($request, $context);
$customer = $context->getCustomer();
if ($customer !== null) {
$page = $this->wishlistPageLoader->load($request, $context, $customer);
} else {
$page = $this->kMWishlistGuestPageLoader->load($request, $context);
}
return $page;
}
/**
* @Since("6.3.4.0")
* @Route("/wishlist/cartoffcanvas", name="frontend.wishlist.page.offcanvas", options={"seo"="false"}, methods={"GET"})
*/
public function index_cartoffcanvas(Request $request, SalesChannelContext $context): Response
{
$page = $this->wishlistIndex($request, $context);
if ($page->getWishlist()->getProductListing()->getTotal() < 1){
return $this->redirectToRoute('frontend.checkout.cart.page');
}else{
return $this->renderStorefront('@Storefront/storefront/page/wishlist/index.html.twig',
['page' => $page,
'offcanvas'=>True,
]);
}
}
/**
* @Since("6.3.4.0")
* @Route("/wishlist", name="frontend.wishlist.page", options={"seo"="false"}, methods={"GET"})
*/
public function index(Request $request, SalesChannelContext $context): Response
{
$page = $this->wishlistIndex($request, $context);
return $this->renderStorefront('@Storefront/storefront/page/wishlist/index.html.twig', ['page' => $page]);
}
/**
* @Since("6.3.5.0")
* @Route("/wishlist/guest-pagelet", name="frontend.wishlist.guestPage.pagelet", options={"seo"="false"}, methods={"POST","GET"}, defaults={"XmlHttpRequest"=true})
*/
public function guestPagelet(Request $request, SalesChannelContext $context): Response
{
$customer = $context->getCustomer();
if ($customer !== null && $customer->getGuest() === false) {
throw new NotFoundHttpException();
}
$pagelet = $this->guestPageletLoader->load($request, $context);
return $this->renderStorefront(
'@Storefront/storefront/page/wishlist/wishlist-pagelet.html.twig',
['page' => $pagelet, 'searchResult' => $pagelet->getSearchResult()->getObject()]
);
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/widgets/wishlist", name="widgets.wishlist.pagelet", options={"seo"="false"}, methods={"GET", "POST"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxPagination(Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
$request->request->set('no-aggregations', true);
$page = $this->wishlistPageLoader->load($request, $context, $customer);
return $this->renderStorefront('@Storefront/storefront/page/wishlist/index.html.twig', ['page' => $page]);
}
/**
* @Since("6.3.4.0")
* @LoginRequired(allowGuest=true)
* @Route("/wishlist/list", name="frontend.wishlist.product.list", options={"seo"="false"}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxList(Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
$criteria = new Criteria();
$this->eventDispatcher->dispatch(new WishListPageProductCriteriaEvent($criteria, $context, $request));
try {
$res = $this->wishlistLoadRoute->load($request, $context, $criteria, $customer);
} catch (CustomerWishlistNotFoundException $exception) {
return new JsonResponse([]);
}
$productWishlistIds = $res->getProductListing()->getIds();
$ppRepo = $this->container->get('km_product_pitchprint.repository');
$criteria = new Criteria();
$eqFilters = [];
$compPids = [];
foreach ($productWishlistIds as $pId) {
$eqFilters[] = new EqualsFilter('productId', $pId);
$compPids[] = $pId;
}
$criteria->addFilter(
new MultiFilter(
MultiFilter::CONNECTION_OR,
$eqFilters
)
);
$criteria->addFilter(new EqualsFilter('cookieId', $request->cookies->get('pp_id')));
$criteria->addFilter(new NotFilter(
NotFilter::CONNECTION_OR,
[
new EqualsFilter('wishlistProductId', NULL)
]
));
$ppProductsCollection = $ppRepo->search($criteria, $context->getContext());
$ppIds = [];
//regenerate key-value with projectId-productId
foreach ($ppProductsCollection as $ppProduct) {
$ppIds[$ppProduct->getProjectId()] = $ppProduct->getProductId();
unset($productWishlistIds[$ppProduct->getProductId()]);
}
return new JsonResponse(array_merge($productWishlistIds, $ppIds));
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/product/delete/{id}", name="frontend.wishlist.product.delete", methods={"POST", "DELETE"}, defaults={"XmlHttpRequest"=true})
*/
public function remove(string $id, Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
if (!$id) {
throw new MissingRequestParameterException('Parameter id missing');
}
try {
$this->removeWishlistProductRoute->delete($id, $context, $customer);
$this->addFlash(self::SUCCESS, $this->trans('wishlist.itemDeleteSuccess'));
} catch (\Throwable $exception) {
$this->addFlash(self::DANGER, $this->trans('error.message-default'));
}
return $this->createActionResponse($request);
}
/**
* @Since("6.3.4.0")
* @LoginRequired(allowGuest=true)
* @Route("/wishlist/pp-product/delete/{id}/{projectId}", name="frontend.wishlist.pp-product.delete", methods={"POST", "DELETE"}, defaults={"XmlHttpRequest"=true})
*/
public function ppRemove(string $id, string $projectId, Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
if (!$id) {
throw new MissingRequestParameterException('Parameter id missing');
}
if (!$projectId) {
throw new MissingRequestParameterException('Parameter projectId missing');
}
$pp_repo = $this->container->get('km_product_pitchprint.repository');
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('projectId', $projectId));
$criteria->addFilter(new EqualsFilter('cookieId', $request->cookies->get('pp_id')));
$ppProject = $pp_repo->search($criteria, $context->getContext())->first();
//delete or. close open tickets
if($ppProject->getTicketId()>0){
/**
* @var \KmPitchPrint\Services\TicketService
*/
$ticket = $this->container->get('km_pitch_print.services.ticket');
$updData = [
'status'=>'closed'
];
$ticket->updateConversation($ppProject->getTicketId(),$updData);
}
$wishlistProductId = $ppProject->getWishlistProductId();
$deleted = $pp_repo->delete([
[
'id' => $ppProject->getId()
]
], $context->getContext());
if ($deleted) {
$criteria = new Criteria();
#$criteria->addFilter(new EqualsFilter('productId', $ppProject->getProductId()));
#$criteria->addFilter(new EqualsFilter('cookieId', $request->cookies->get('pp_id')));
$criteria->addFilter(new EqualsFilter('wishlistProductId', $wishlistProductId));
$ppProject = $pp_repo->search($criteria, $context->getContext());
//delete the wishlistitem only if the pp-projects are not available in the repository
if ($ppProject->getTotal() > 0) {
return $this->createActionResponse($request);
}
}
try {
$this->removeWishlistProductRoute->delete($id, $context, $customer);
$this->addFlash(self::SUCCESS, $this->trans('wishlist.itemDeleteSuccess'));
} catch (\Throwable $exception) {
$this->addFlash(self::DANGER, $this->trans('error.message-default'));
}
return $this->createActionResponse($request);
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/add/{productId}/{lineItemId}", name="frontend.wishlist.product.checkout-add", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxCheckoutAdd(string $productId, string $lineItemId, SalesChannelContext $context, CustomerEntity $customer): JsonResponse
{
$this->addWishlistRoute->add($productId, $context, $customer);
/**
* @var Cart
*/
$cart = $this->cartService->getCart($context->getToken(), $context);
$this->cartService->remove($cart, $lineItemId, $context);
return new JsonResponse([
'success' => true,
]);
}
private function addWishlist(string $productId, SalesChannelContext $context, CustomerEntity $customer): JsonResponse
{
$this->addWishlistRoute->add($productId, $context, $customer);
return new JsonResponse([
'success' => true,
]);
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/add/{productId}", name="frontend.wishlist.product.add", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxAdd(string $productId, Request $request, RequestDataBag $requestDataBag, SalesChannelContext $context, CustomerEntity $customer): JsonResponse
{
if (!$request->cookies->get('pp_id')) {
$rand_hex = Uuid::randomHex();
$cookie = Cookie::create('pp_id', $rand_hex, time() + (365 * 24 * 60 * 60));
$response = new Response();
$response->headers->setCookie($cookie);
$response->sendHeaders();
}
if ($customer !== null && $customer->getGuest() === false) {
$payload = [
'qty' => 1,
'swoptions' => [],
'type' => 'product',
];
if($request->get('qty')){
$payload['qty'] = (int)$request->get('qty');
}
$this->eventDispatcher->dispatch(new MoveToWishlistEvent($request, $requestDataBag, (string)$payload['qty'], $productId, $payload, $context));
}
return new JsonResponse();
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/add/{productId}/{projectId}/{lineItemId}", name="frontend.wishlist.product.checkout-add-pp", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxPPAdd(string $productId, string $projectId, string $lineItemId, Request $request, RequestDataBag $requestDataBag, SalesChannelContext $context, CustomerEntity $customer): JsonResponse
{
$this->eventDispatcher->dispatch(new MoveToWishlistEvent($request, $requestDataBag, (string)$request->get('qty'), $productId, [], $context));
$cart = $this->cartService->getCart($context->getToken(), $context);
$this->cartService->remove($cart, $lineItemId, $context);
return new JsonResponse([
'pp' => true,
]);
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/remove/{productId}", name="frontend.wishlist.product.remove", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxRemove(string $productId, SalesChannelContext $context, CustomerEntity $customer): JsonResponse
{
$this->removeWishlistProductRoute->delete($productId, $context, $customer);
return new JsonResponse([
'success' => true,
]);
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/add-after-login/{productId}", name="frontend.wishlist.add.after.login", options={"seo"="false"}, methods={"GET"})
*/
public function addAfterLogin(string $productId, Request $request, RequestDataBag $requestDataBag, SalesChannelContext $context, CustomerEntity $customer): Response
{
//string $productId,Request $request, SalesChannelContext $context, CustomerEntity $customer
$this->ajaxAdd($productId, $request, $requestDataBag, $context, $context->getCustomer());
return $this->redirectToRoute('frontend.home.page');
/*try {
$this->addWishlistRoute->add($productId, $context, $customer);
$this->addFlash(self::SUCCESS, $this->trans('wishlist.itemAddedSuccess'));
} catch (DuplicateWishlistProductException $exception) {
$this->addFlash(self::WARNING, $exception->getMessage());
} catch (\Throwable $exception) {
$this->addFlash(self::DANGER, $this->trans('error.message-default'));
}
return $this->redirectToRoute('frontend.home.page');*/
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/merge", name="frontend.wishlist.product.merge", options={"seo"="false"}, methods={"POST"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxMerge(RequestDataBag $requestDataBag, Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
try {
$this->mergeWishlistProductRoute->merge($requestDataBag, $context, $customer);
return $this->renderStorefront('@Storefront/storefront/utilities/alert.html.twig', [
'type' => 'info', 'content' => $this->trans('wishlist.wishlistMergeHint'),
]);
} catch (\Throwable $exception) {
$this->addFlash(self::DANGER, $this->trans('error.message-default'));
}
return $this->createActionResponse($request);
}
/**
* @Since("6.3.4.0")
* @LoginRequired()
* @Route("/wishlist/merge/pagelet", name="frontend.wishlist.product.merge.pagelet", methods={"GET", "POST"}, defaults={"XmlHttpRequest"=true})
*/
public function ajaxPagelet(Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
$request->request->set('no-aggregations', true);
$page = $this->wishlistPageLoader->load($request, $context, $customer);
return $this->renderStorefront('@Storefront/storefront/page/wishlist/wishlist-pagelet.html.twig', ['page' => $page]);
}
}