custom/plugins/PremsWishlist/src/Storefront/Controller/WishlistController.php line 135

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /**
  3.  * PremSoft
  4.  * Copyright © 2019 Premsoft - Sven Mittreiter
  5.  *
  6.  * @copyright  Copyright (c) 2019, premsoft - Sven Mittreiter (http://www.premsoft.de)
  7.  * @author     Sven Mittreiter <info@premsoft.de>
  8.  */
  9. namespace Prems\Plugin\PremsWishlist\Storefront\Controller;
  10. use Prems\Plugin\PremsWishlist\Core\Wishlist\Storefront\ConfigService;
  11. use Prems\Plugin\PremsWishlist\Entity\Wishlist\Aggregate\WishlistProduct\WishlistProductEntity;
  12. use Prems\Plugin\PremsWishlist\Exception\Wishlist\WishlistIdMissingException;
  13. use Prems\Plugin\PremsWishlist\Exception\Wishlist\WishlistNotFoundException;
  14. use Shopware\Core\Checkout\Cart\Exception\CartTokenNotFoundException;
  15. use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
  16. use Shopware\Core\Checkout\Cart\Exception\InvalidPayloadException;
  17. use Shopware\Core\Checkout\Cart\Exception\InvalidQuantityException;
  18. use Shopware\Core\Checkout\Cart\Exception\MixedLineItemTypeException;
  19. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  20. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  21. use Shopware\Core\PlatformRequest;
  22. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  23. use Shopware\Storefront\Controller\StorefrontController;
  24. use Shopware\Storefront\Page\GenericPageLoaderInterface;
  25. use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
  26. use Symfony\Component\HttpFoundation\JsonResponse;
  27. use Symfony\Component\HttpFoundation\RedirectResponse;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\HttpFoundation\RequestStack;
  30. use Symfony\Component\HttpFoundation\Response;
  31. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  32. use Symfony\Component\Routing\Annotation\Route;
  33. use Prems\Plugin\PremsWishlist\Core\Wishlist\Storefront\WishlistService;
  34. use Prems\Plugin\PremsWishlist\Core\Wishlist\Storefront\ProductService;
  35. use Prems\Plugin\PremsWishlist\Storefront\Page\Detail\DetailPageLoader;
  36. use Prems\Plugin\PremsWishlist\Storefront\Page\Listing\ListingPageLoader;
  37. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  38. use Symfony\Component\HttpFoundation\Session\Session;
  39. /**
  40.  * @RouteScope(scopes={"storefront"})
  41.  */
  42. class WishlistController extends StorefrontController
  43. {
  44.     private GenericPageLoaderInterface $genericPageLoader;
  45.     /**
  46.      * @var DetailPageLoader
  47.      */
  48.     private $detailPageLoader;
  49.     /**
  50.      * @var ListingPageLoader
  51.      */
  52.     private $listingPageLoader;
  53.     /**
  54.      * @var WishlistService
  55.      */
  56.     private $wishlistService;
  57.     /**
  58.      * @var ProductService
  59.      */
  60.     private $productService;
  61.     /**
  62.      * @var ConfigService
  63.      */
  64.     private $configService;
  65.     /**
  66.      * @var Session
  67.      */
  68.     private $sessionService;
  69.     /**
  70.      * @var \Shopware\Core\Framework\Struct\Struct
  71.      */
  72.     protected $wishlistSettings;
  73.     public function __construct(
  74.         GenericPageLoaderInterface $genericPageLoader,
  75.         ListingPageLoader $listingPageLoader,
  76.         DetailPageLoader $detailPageLoader,
  77.         WishlistService $wishlistService,
  78.         ProductService $productService,
  79.         ConfigService $configService
  80.     ) {
  81.         $this->genericPageLoader $genericPageLoader;
  82.         $this->listingPageLoader  $listingPageLoader;
  83.         $this->detailPageLoader $detailPageLoader;
  84.         $this->wishlistService  $wishlistService;
  85.         $this->productService  $productService;
  86.         $this->sessionService = new Session();
  87.         $this->configService $configService;
  88.     }
  89.     /**
  90.      * Get plugin settings
  91.      *
  92.      * @throws \Exception
  93.      * @return \Shopware\Core\Framework\Struct\Struct
  94.      */
  95.     protected function getWishlistSettings() {
  96.         if ($this->wishlistSettings) {
  97.             return $this->wishlistSettings;
  98.         }
  99.         $this->wishlistSettings $this->configService->getConfig();
  100.         if (!$this->wishlistSettings) {
  101.             throw new \Exception('No wishlist settings found');
  102.         }
  103.         return $this->wishlistSettings;
  104.     }
  105.     /**
  106.      * Shows all wishlist of a customer. If not logged in then redirected to login page
  107.      * @Route(
  108.      *     "/wishlist/index",
  109.      *     name="frontend.PremsWishlist.index",
  110.      *     methods={"GET"}
  111.      * )
  112.      *
  113.      * @param SalesChannelContext $context
  114.      * @param Request $request
  115.      *
  116.      * @return Response
  117.      */
  118.     public function index(SalesChannelContext $contextRequest $request): Response
  119.     {
  120.         $maxWishlistNumberReached false;
  121.         $page $this->genericPageLoader->load($request$context);
  122.         if ($page->getMetaInformation()) {
  123.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  124.         }
  125.         if ($this->getWishlistSettings()->isLoginRequired()) {
  126.             $this->denyAccessUnlessLoggedIn();
  127.         }
  128.         if (!$context->getCustomer()) {
  129.             $this->addFlash('info'$this->trans('prems-wishlist.status_messages.login_recommended'));
  130.         }
  131.         $wishlistId $request->request->get('wishlistId'0);
  132.         $premsWishlistStoredArticle $this->sessionService->get('premsWishlistStoredArticle');
  133.         $page $this->listingPageLoader->load($request$context);
  134.         $maxNumberWishlistsPerUser = (int) $this->getWishlistSettings()->getMaxNumberWishlistsPerUser();
  135.         if ($maxNumberWishlistsPerUser == || $page->getListing()->getTotal() < $maxNumberWishlistsPerUser) {
  136.             $maxWishlistNumberReached false;
  137.         } else {
  138.             $maxWishlistNumberReached true;
  139.             $this->addFlash('info'$this->trans('prems-wishlist.status_messages.max_number_wishlists_per_user_reached'));
  140.         }
  141.         $response $this->renderStorefront('@PremsWishlist/storefront/page/wishlist/list.html.twig', [
  142.             'maxWishlistNumberReached' => $maxWishlistNumberReached,
  143.             'premsWishlist' => $this->getWishlistSettings(),
  144.             'page' => $page,
  145.             'storedArticle' => $premsWishlistStoredArticle,
  146.             'wishlistId' => $wishlistId
  147.         ]);
  148.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  149.         return $response;
  150.     }
  151.     /**
  152.      * @Route(
  153.      *   "/widgets/wishlist/detail/{id}",
  154.      *   name="frontend.PremsWishlist.ajaxWishlistDetail",
  155.      *   options={"seo"="false"},
  156.      *   methods={"GET"},
  157.      *   defaults={"XmlHttpRequest"=true})
  158.      *
  159.      * @param SalesChannelContext $context
  160.      * @param Request $request
  161.      */
  162.     public function ajaxWishlistDetail(SalesChannelContext $contextRequest $request)
  163.     {
  164.         $page $this->genericPageLoader->load($request$context);
  165.         if ($page->getMetaInformation()) {
  166.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  167.         }
  168.         if ($this->getWishlistSettings()->isLoginRequired()) {
  169.             $this->denyAccessUnlessLoggedIn();
  170.         }
  171.         $wishlistId = (string) $request->attributes->get('id');
  172.         if ($wishlistId === '') {
  173.             throw new MissingRequestParameterException('id');
  174.         }
  175.         $wishlist $this->wishlistService->getWishlistById($wishlistId$contexttrue);
  176.         if (!$wishlist) {
  177.             throw new WishlistNotFoundException("Wishlist $wishlist not found");
  178.         }
  179.         $customerIsOwner false;
  180.         $customer $context->getCustomer();
  181.         if ($customer) {
  182.             $customerId $context->getCustomer()->getId();
  183.             if ($customerId === $wishlist->getCustomer()->getId()) {
  184.                 $customerIsOwner true;
  185.             }
  186.         } else {
  187.             $token $context->getToken();
  188.             if ($token === $wishlist->getToken()) {
  189.                 $customerIsOwner true;
  190.             }
  191.         }
  192.         $isPublic = !$wishlist->isPrivate();
  193.         if (! ($isPublic || $customerIsOwner)) {
  194.             throw new AccessDeniedException($wishlistId);
  195.         }
  196.         $response $this->renderStorefront('@PremsWishlist/storefront/page/wishlist/wishlist-detail-list.html.twig',
  197.             [
  198.                 'premsWishlist' => $this->getWishlistSettings(),
  199.                 'wishlistId' => $wishlistId,
  200.                 'wishlist' => $wishlist,
  201.             ]);
  202.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  203.         return $response;
  204.     }
  205.     /**
  206.      * Shows number of articles in all wishlist of user. Used for count sign in header
  207.      * @Route(
  208.      *     "/wishlist/count",
  209.      *     name="frontend.PremsWishlist.count",
  210.      *     methods={"GET"}
  211.      * )
  212.      *
  213.      * @param SalesChannelContext $context
  214.      * @param Request $request
  215.      *
  216.      * @return JsonResponse
  217.      */
  218.     public function count(SalesChannelContext $contextRequest $request): Response
  219.     {
  220.         $page $this->genericPageLoader->load($request$context);
  221.         if ($page->getMetaInformation()) {
  222.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  223.         }
  224.         if ($this->getWishlistSettings()->isLoginRequired() && !$context->getCustomer()) {
  225.             $response = new JsonResponse([
  226.                 'success' => true,
  227.                 'count' => 0,
  228.                 'products' => []
  229.             ]);
  230.             $response->headers->set('X-Robots-Tag''noindex,nofollow');
  231.             return $response;
  232.         }
  233.         $results $this->wishlistService->getProductCountForUser($context);
  234.         /**$wishlistSettings = null;
  235.         $wishlistSettings = $this->configService->getConfig();
  236.         if (!$wishlistSettings) {
  237.         throw new \Exception('No wishlist settings found');
  238.         }
  239.         $premsWishlistStoredArticle = $this->sessionService->get($request, 'premsWishlistStoredArticle');
  240.         $page = $this->listingPageLoader->load($request, $context);
  241.         return $this->renderStorefront('@PremsWishlist/storefront/page/wishlist/index.html.twig', [
  242.         'premsWishlist' => $wishlistSettings,
  243.         'page' => $page,
  244.         'storedArticle' => $premsWishlistStoredArticle
  245.         ]);*/
  246.         $response = new JsonResponse([
  247.             'success' => true,
  248.             'count' => $results['number'],
  249.             'products' => $results['products']
  250.         ]);
  251.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  252.         return $response;
  253.     }
  254.     /**
  255.      * @Route(
  256.      *     "/wishlist/{wishlistId}",
  257.      *     name="frontend.PremsWishlist.detail",
  258.      *     methods={"GET"}
  259.      * )
  260.      *
  261.      * @param SalesChannelContext $context
  262.      * @param Request     $request
  263.      *
  264.      * @return Response
  265.      *
  266.      * @throws InconsistentCriteriaIdsException
  267.      * @throws MissingRequestParameterException
  268.      */
  269.     public function detail(SalesChannelContext $contextRequest $request): Response
  270.     {
  271.         $page $this->genericPageLoader->load($request$context);
  272.         if ($page->getMetaInformation()) {
  273.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  274.         }
  275.         try {
  276.             $page $this->detailPageLoader->load($request$context);
  277.         } catch (WishlistNotFoundException $e) {
  278.             $this->addFlash('warning'$this->trans('prems-wishlist.status_messages.access_denied'));
  279.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  280.         } catch (WishlistIdMissingException $e) {
  281.             $this->addFlash('warning'$this->trans('prems-wishlist.status_messages.access_denied'));
  282.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  283.         } catch (AccessDeniedException $e) {
  284.             $this->addFlash('warning'$this->trans('prems-wishlist.status_messages.access_denied'));
  285.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  286.         }
  287.         $customer $context->getCustomer();
  288.         if ($this->getWishlistSettings()->isLoginRequired() && !$customer) {
  289.             $isLoggedIn false;
  290.         } else {
  291.             $isLoggedIn true;
  292.         }
  293.         $response $this->renderStorefront('@PremsWishlist/storefront/page/wishlist/detail.html.twig', [
  294.             'isLoggedIn' => $isLoggedIn,
  295.             'premsWishlist' => $this->getWishlistSettings(),
  296.             'page' => $page
  297.         ]);
  298.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  299.         return $response;
  300.     }
  301.     /**
  302.      * Modal window for adding product to wishlists
  303.      *
  304.      * @Route(
  305.      *     "/wishlist/modal/{productId}",
  306.      *     name="frontend.PremsWishlist.add.modal",
  307.      *     options={"seo"="false"},
  308.      *     methods={"GET"}
  309.      * )
  310.      *
  311.      * @param string              $productId
  312.      * @param SalesChannelContext $context
  313.      * @param Request     $request
  314.      *
  315.      * @return Response
  316.      *
  317.      * @throws InconsistentCriteriaIdsException
  318.      */
  319.     public function modalForAddingProduct(string $productIdSalesChannelContext $contextRequest $request): Response
  320.     {
  321.         $maxWishlistNumberReached false;
  322.         $page $this->genericPageLoader->load($request$context);
  323.         if ($page->getMetaInformation()) {
  324.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  325.         }
  326.         $customer $context->getCustomer();
  327.         $product $this->productService->getProductById($productId$context);
  328.         $lists = [];
  329.         if ($this->getWishlistSettings()->isLoginRequired() && !$customer) {
  330.             $isLoggedIn false;
  331.             $this->sessionService->set('premsWishlistStoredArticle'$productId);
  332.         } else {
  333.             $isLoggedIn true;
  334.             $lists $this->wishlistService->getWishlistsForUser($context);
  335.             $maxNumberWishlistsPerUser = (int) $this->getWishlistSettings()->getMaxNumberWishlistsPerUser();
  336.             if ($maxNumberWishlistsPerUser == || count($lists) < $maxNumberWishlistsPerUser) {
  337.                 $maxWishlistNumberReached false;
  338.             } else {
  339.                 $maxWishlistNumberReached true;
  340.                 $this->addFlash('info'$this->trans('prems-wishlist.status_messages.max_number_wishlists_per_user_reached'));
  341.             }
  342.         }
  343.         $response $this->renderStorefront('@PremsWishlist/storefront/page/wishlist/modal_for_adding_product.html.twig', [
  344.             'maxWishlistNumberReached' => $maxWishlistNumberReached,
  345.             'loggedIn' => $isLoggedIn,
  346.             'lists' => $lists,
  347.             'product' => $product,
  348.         ]);
  349.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  350.         return $response;
  351.     }
  352.     /**
  353.      * Update a wishlist
  354.      *
  355.      * @Route(
  356.      *     "/wishlist/updateWishlist",
  357.      *     name="frontend.PremsWishlist.updateWishlist",
  358.      *     options={"seo"="false"}, methods={"POST"}
  359.      * )
  360.      *
  361.      * @param string $productId
  362.      * @param Request $request
  363.      * @param SalesChannelContext $context
  364.      *
  365.      * @return Response
  366.      *
  367.      * @throws InconsistentCriteriaIdsException
  368.      */
  369.     public function updateWishlist(Request $requestSalesChannelContext $context): Response
  370.     {
  371.         $page $this->genericPageLoader->load($request$context);
  372.         if ($page->getMetaInformation()) {
  373.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  374.         }
  375.         if ($this->getWishlistSettings()->isLoginRequired()) {
  376.             $this->denyAccessUnlessLoggedIn();
  377.         }
  378.         $id $request->request->get('id''');
  379.         $listName $request->request->get('listName''');
  380.         $visibility $request->request->get('visibility'0);
  381.         if ($visibility) {
  382.             $private false;
  383.         } else {
  384.             $private true;
  385.         }
  386.         if (!$id) {
  387.             throw new WishlistNotFoundException($id);
  388.         }
  389.         $wishlist $this->wishlistService->getWishlistById($id$context);
  390.         if (!$wishlist) {
  391.             throw new WishlistNotFoundException($id);
  392.         }
  393.         if (!$this->wishlistService->hasAccessToWishlist($wishlist$contexttrue)) {
  394.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.update_failed'));
  395.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  396.         }
  397.         if ($listName) {
  398.             $this->wishlistService->updateWishlist([
  399.                 [
  400.                     'id' => $id,
  401.                     'name' => $listName,
  402.                     'private' => $private,
  403.                     'salesChannelId' => $context->getSalesChannelId(),
  404.                 ]
  405.             ], $context->getContext());
  406.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.update_successful'));
  407.         } else {
  408.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.update_failed'));
  409.         }
  410.         return $this->redirectToRoute('frontend.PremsWishlist.index');
  411.     }
  412.     /**
  413.      * Create a new wishlist
  414.      *
  415.      * @Route(
  416.      *     "/wishlist/createWishlist",
  417.      *     name="frontend.PremsWishlist.createWishlist",
  418.      *     options={"seo"="false"}, methods={"POST"}
  419.      * )
  420.      *
  421.      * @param string $productId
  422.      * @param Request $request
  423.      * @param SalesChannelContext $context
  424.      *
  425.      * @return Response
  426.      *
  427.      * @throws InconsistentCriteriaIdsException
  428.      */
  429.     public function createWishlist(Request $requestSalesChannelContext $context): Response
  430.     {
  431.         $page $this->genericPageLoader->load($request$context);
  432.         if ($page->getMetaInformation()) {
  433.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  434.         }
  435.         if ($this->getWishlistSettings()->isLoginRequired()) {
  436.             $this->denyAccessUnlessLoggedIn();
  437.         }
  438.         $listName $request->request->get('listName''');
  439.         $user $context->getCustomer();
  440.         $visibility $request->request->get('visibility'0);
  441.         if ($visibility) {
  442.             $private false;
  443.         } else {
  444.             $private true;
  445.         }
  446.         if ($listName) {
  447.             $wishlistData = [
  448.                 'name' => $listName,
  449.                 'private' => $private,
  450.                 'priority' => 0,
  451.             ];
  452.             if ($user) {
  453.                 $wishlistData['customerId'] = $user->getId();
  454.             } else {
  455.                 $wishlistData['token'] = $context->getToken();
  456.             }
  457.             $wishlistData['salesChannelId'] = $context->getSalesChannelId();
  458.             $this->wishlistService->createWishlist([
  459.                 $wishlistData
  460.             ], $context->getContext());
  461.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.create_successful'));
  462.         } else {
  463.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.create_failed'));
  464.         }
  465.         return $this->redirectToRoute('frontend.PremsWishlist.index');
  466.     }
  467.     /**
  468.      * Saves an external public wishlist as an own private one
  469.      *
  470.      * @Route(
  471.      *     "/wishlist/saveAsOwnWishlist",
  472.      *     name="frontend.PremsWishlist.saveAsOwnWishlist",
  473.      *     options={"seo"="false"}, methods={"POST"}
  474.      * )
  475.      *
  476.      * @param Request $request
  477.      * @param SalesChannelContext $context
  478.      *
  479.      * @return Response
  480.      *
  481.      * @throws InconsistentCriteriaIdsException
  482.      */
  483.     public function saveAsOwnWishlist(Request $requestSalesChannelContext $context): Response
  484.     {
  485.         $page $this->genericPageLoader->load($request$context);
  486.         if ($page->getMetaInformation()) {
  487.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  488.         }
  489.         if ($this->getWishlistSettings()->isLoginRequired()) {
  490.             $this->denyAccessUnlessLoggedIn();
  491.         }
  492.         $wishlistId $request->request->getAlnum('wishlistId');
  493.         if (!$wishlistId) {
  494.             throw new MissingRequestParameterException('wishlistId');
  495.         }
  496.         $wishlist $this->wishlistService->getWishlistById($wishlistId$contexttrue);
  497.         if (!$wishlist) {
  498.             throw new WishlistNotFoundException($wishlistId);
  499.         }
  500.         if (!$this->wishlistService->hasAccessToWishlist($wishlist$context)) {
  501.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  502.         }
  503.         $user $context->getCustomer();
  504.         $sourceProducts $wishlist->getProducts();
  505.         $targetProducts = [];
  506.         /** @var WishlistProductEntity $product */
  507.         foreach ($sourceProducts->getElements() as $product) {
  508.             $targetProducts[] = [
  509.                 'productId' => $product->getProductId(),
  510.                 'number_wished' => $product->getNumberWished(),
  511.                 'position' => $product->getPosition(),
  512.                 'hint' => $product->getHint(),
  513.             ];
  514.         }
  515.         $wishlistData = [
  516.             'name' => $wishlist->getName(),
  517.             'private' => true,
  518.             'products' => $targetProducts,
  519.             'priority' => 0,
  520.         ];
  521.         if ($user) {
  522.             $wishlistData['customerId'] = $user->getId();
  523.         } else {
  524.             $wishlistData['token'] = $context->getToken();
  525.         }
  526.         $wishlistData['salesChannelId'] = $context->getSalesChannelId();
  527.         $this->wishlistService->createWishlist([
  528.             $wishlistData
  529.         ], $context->getContext());
  530.         $this->addFlash('success'$this->trans('prems-wishlist.status_messages.create_successful'));
  531.         return $this->redirectToRoute('frontend.PremsWishlist.index');
  532.     }
  533.     /**
  534.      * Adds a product by product number to wishlist
  535.      * @Route("/wishlist/add-by-number",
  536.      *   name="frontend.PremsWishlist.addByProductNumber", methods={"POST"})
  537.      *
  538.      * @throws InconsistentCriteriaIdsException
  539.      * @throws MissingRequestParameterException
  540.      */
  541.     public function addByProductNumber(Request $requestSalesChannelContext $context): Response
  542.     {
  543.         $page $this->genericPageLoader->load($request$context);
  544.         if ($page->getMetaInformation()) {
  545.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  546.         }
  547.         if ($this->getWishlistSettings()->isLoginRequired()) {
  548.             $this->denyAccessUnlessLoggedIn();
  549.         }
  550.         $number $request->request->get('number');
  551.         if (!$number) {
  552.             throw new MissingRequestParameterException('number');
  553.         }
  554.         $wishlistId $request->request->getAlnum('wishlistId');
  555.         if (!$wishlistId) {
  556.             throw new MissingRequestParameterException('wishlistId');
  557.         }
  558.         $wishlist $this->wishlistService->getWishlistById($wishlistId$context);
  559.         if (!$wishlist) {
  560.             throw new WishlistNotFoundException($wishlistId);
  561.         }
  562.         if (!$this->wishlistService->hasAccessToWishlist($wishlist$context)) {
  563.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  564.         }
  565.         $data $this->productService->getProductByNumber($number$context->getContext());
  566.         if (empty($data)) {
  567.             $this->addFlash('danger'$this->trans('error.productNotFound', ['%number%' => $number]));
  568.             return $this->redirectToRoute('frontend.PremsWishlist.index', ['wishlistId' => $wishlistId]);
  569.         }
  570.         $productId array_shift($data);
  571.         $listIds[] = $wishlistId;
  572.         $lists $this->wishlistService->getWishlistsByIds($listIds$context);
  573.         // Add Article to List
  574.         $this->wishlistService->addProductToWishlists($productId$lists$context->getContext());
  575.         $this->addFlash('success'$this->trans('prems-wishlist.status_messages.article_added_successful'));
  576.         return $this->redirectToRoute('frontend.PremsWishlist.index', ['wishlistId' => $wishlistId]);
  577.     }
  578.     /**
  579.      * Adds a product to a wishlist
  580.      *
  581.      * @Route(
  582.      *     "/wishlist/add/{productId}/{wishlistId}",
  583.      *     name="frontend.PremsWishlist.add",
  584.      *     options={"seo"="false"}, methods={"GET"}
  585.      * )
  586.      *
  587.      * @param string $productId
  588.      * @param Request $request
  589.      * @param SalesChannelContext $context
  590.      *
  591.      * @return Response
  592.      *
  593.      * @throws InconsistentCriteriaIdsException
  594.      */
  595.     public function add(string $productIdstring $wishlistIdRequest $requestSalesChannelContext $context): Response
  596.     {
  597.         $page $this->genericPageLoader->load($request$context);
  598.         if ($page->getMetaInformation()) {
  599.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  600.         }
  601.         if ($this->getWishlistSettings()->isLoginRequired()) {
  602.             $this->denyAccessUnlessLoggedIn();
  603.         }
  604.         $wishlist $this->wishlistService->getWishlistById($wishlistId$context);
  605.         if (!$wishlist) {
  606.             throw new WishlistNotFoundException($wishlistId);
  607.         }
  608.         $lists = [];
  609.         $listIds  = [];
  610.         if (!$this->wishlistService->hasAccessToWishlist($wishlist$context)) {
  611.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  612.         }
  613.         // Add request is for a stored article? Then delete this session entry
  614.         if ($request->request->get('storedArticle') == 1) {
  615.             $this->sessionService->remove('premsWishlistStoredArticle');
  616.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.article_added_successful'));
  617.         }
  618.         $user  $context->getCustomer();
  619.         $listIds[] = $wishlistId;
  620.         // ListIds given?
  621.         if (!empty($listIds)) {
  622.             $lists $this->wishlistService->getWishlistsByIds($listIds$context);
  623.             // Add Article to List
  624.             $this->wishlistService->addProductToWishlists($productId$lists$context->getContext());
  625.         }
  626.         return $this->redirectToRoute('frontend.PremsWishlist.index');
  627.     }
  628.     /**
  629.      * Save all cart items as a new wishlist
  630.      *
  631.      * @Route(
  632.      *     "/wishlist/addCartAsWishlist",
  633.      *     name="frontend.PremsWishlist.add.cart.as.wishlist",
  634.      *     options={"seo"="false"}, methods={"POST"}
  635.      * )
  636.      *
  637.      * @param string $productId
  638.      * @param Request $request
  639.      * @param SalesChannelContext $context
  640.      *
  641.      * @return Response
  642.      *
  643.      * @throws InconsistentCriteriaIdsException
  644.      */
  645.     public function saveCartAsWishlist(Request $requestSalesChannelContext $context): Response
  646.     {
  647.         $page $this->genericPageLoader->load($request$context);
  648.         if ($page->getMetaInformation()) {
  649.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  650.         }
  651.         if ($this->getWishlistSettings()->isLoginRequired()) {
  652.             $this->denyAccessUnlessLoggedIn();
  653.         }
  654.         $listName $request->request->get('listName''');
  655.         if (strlen($listName) > 0) {
  656.             $this->wishlistService->saveCartAsWishlist(
  657.                 $listName,
  658.                 $context,
  659.                 $this->getWishlistSettings()->isClearCartAfterAddingToWishlist()
  660.             );
  661.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.create_successful'));
  662.         } else {
  663.             $this->addFlash('warning'$this->trans('prems-wishlist.status_messages.create_failed'));
  664.         }
  665.         return $this->redirectToRoute('frontend.checkout.cart.page');
  666.     }
  667.     /**
  668.      * Adds a product to a wishlist in modal window context
  669.      *
  670.      * @Route(
  671.      *     "/wishlist/modalAdd/{productId}",
  672.      *     name="frontend.PremsWishlist.add.modal.product",
  673.      *     options={"seo"="false"}, methods={"POST"}
  674.      * )
  675.      *
  676.      * @param string $productId
  677.      * @param Request $request
  678.      * @param SalesChannelContext $context
  679.      *
  680.      * @return Response
  681.      *
  682.      * @throws InconsistentCriteriaIdsException
  683.      */
  684.     public function modalAdd(string $productIdRequest $requestSalesChannelContext $context): Response
  685.     {
  686.         $page $this->genericPageLoader->load($request$context);
  687.         if ($page->getMetaInformation()) {
  688.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  689.         }
  690.         $customer $context->getCustomer();
  691.         $token $context->getToken();
  692.         $quantity = (int) $request->get('quantity'1);
  693.         $listIds  $request->get('lists');
  694.         $listName $request->get('listName''');
  695.         $visibility $request->get('visibility'0);
  696.         if ($visibility) {
  697.             $private false;
  698.         } else {
  699.             $private true;
  700.         }
  701.         // Check if User is Logged In
  702.         if ($this->getWishlistSettings()->isLoginRequired() && !$customer) {
  703.             $response = new JsonResponse([
  704.                 'code'    => 601,
  705.                 'message' => 'User not logged in'
  706.             ]);
  707.             $response->headers->set('X-Robots-Tag''noindex,nofollow');
  708.             return $response;
  709.         }
  710.         // ListIds given?
  711.         if (!empty($listIds)) {
  712.             $lists $this->wishlistService->getWishlistsByIds($listIds$context);
  713.             // Add Article to List
  714.             $this->wishlistService->addProductToWishlists($productId$lists$context->getContext(), $quantity);
  715.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.article_added_successful'));
  716.         }
  717.         // Create new list
  718.         if (strlen($listName) > 0) {
  719.             $data =                 [
  720.                 'name' => $listName,
  721.                 'private' => $private,
  722.                 'products' => [
  723.                     [
  724.                         'productId' => $productId,
  725.                         'numberWished' => $quantity
  726.                     ]
  727.                 ],
  728.                 'priority' => 0,
  729.             ];
  730.             if ($customer) {
  731.                 $data['customerId'] = $context->getCustomer()->getId();
  732.             } else {
  733.                 $data['token'] = $token;
  734.             }
  735.             $data['salesChannelId'] = $context->getSalesChannelId();
  736.             $this->wishlistService->createWishlist([
  737.                 $data
  738.             ], $context->getContext());
  739.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.article_added_successful'));
  740.         }
  741.         $response = new JsonResponse([
  742.             'success' => true
  743.         ]);
  744.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  745.         return $response;
  746.     }
  747.     /**
  748.      * Function to change quantity of product in a wishlist
  749.      *
  750.      * @Route("/wishlist/changeProductQuantity/{wishlistId}/id/{id}", name="frontend.PremsWishlist.product.quantity.change", methods={"POST"})
  751.      *
  752.      * @param string $wishlistId
  753.      * @param string $id
  754.      * @param Request $request
  755.      * @param SalesChannelContext $context
  756.      * @return JsonResponse
  757.      * @throws InconsistentCriteriaIdsException
  758.      * @throws WishlistNotFoundException
  759.      */
  760.     public function changeProductQuantity(string $wishlistIdstring $idRequest $requestSalesChannelContext $context): Response
  761.     {
  762.         $page $this->genericPageLoader->load($request$context);
  763.         if ($page->getMetaInformation()) {
  764.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  765.         }
  766.         $customer $context->getCustomer();
  767.         if ($this->getWishlistSettings()->isLoginRequired() && !$customer) {
  768.             throw new WishlistNotFoundException($wishlistId);
  769.         }
  770.         $wishlist $this->wishlistService->getWishlistById($wishlistId$context);
  771.         if (!$wishlist) {
  772.             throw new WishlistNotFoundException($wishlistId);
  773.         }
  774.         if (!$this->wishlistService->hasAccessToWishlist($wishlist$contexttrue)) {
  775.             throw new WishlistNotFoundException($wishlistId);
  776.         }
  777.         $numberWished  = (int) $request->request->get('numberWished'0);
  778.         if ($numberWished) {
  779.             if (!$this->wishlistService->hasAccessToWishlist($wishlist$contexttrue)) {
  780.                 throw new WishlistNotFoundException($wishlistId);
  781.             }
  782.             $this->wishlistService->changeProductQuantity($id$wishlist$numberWished$context->getContext());
  783.             /**$this->wishlistService->removeProductFromWishlist($wishlist, $id, $context->getContext());
  784.             $this->wishlistService->addProductToWishlists($productId, [$moveToWishlist], $context->getContext());*/
  785.             $response = new JsonResponse([
  786.                 'success' => true
  787.             ]);
  788.             $response->headers->set('X-Robots-Tag''noindex,nofollow');
  789.             return $response;
  790.         }
  791.         $response = new JsonResponse([
  792.             'success' => true
  793.         ]);
  794.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  795.         return $response;
  796.     }
  797.     /**
  798.      * Adds all wishlist products to cart. Used for Wishlist Toolbox in Checkout
  799.      *
  800.      * @Route(
  801.      *     "/wishlist/addToCart/{wishlistId}",
  802.      *     name="frontend.PremsWishlist.add_to_cart",
  803.      *     options={"seo"="false"},
  804.      *     methods={"POST"}
  805.      * )
  806.      *
  807.      * @param string $wishlistId
  808.      * @param Request $request
  809.      * @param SalesChannelContext $context
  810.      *
  811.      * @return RedirectResponse
  812.      *
  813.      * @throws InconsistentCriteriaIdsException
  814.      * @throws WishlistNotFoundException
  815.      * @throws CartTokenNotFoundException
  816.      * @throws InvalidPayloadException
  817.      * @throws InvalidQuantityException
  818.      * @throws MixedLineItemTypeException
  819.      */
  820.     public function addToCart(Request $requestSalesChannelContext $contextstring $wishlistId ""): RedirectResponse
  821.     {
  822.         $page $this->genericPageLoader->load($request$context);
  823.         if ($page->getMetaInformation()) {
  824.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  825.         }
  826.         if ($this->getWishlistSettings()->isLoginRequired()) {
  827.             $this->denyAccessUnlessLoggedIn();
  828.         }
  829.         $wishlistSettings $this->configService->getConfig();
  830.         if (strlen($wishlistId) == 0) {
  831.             $wishlistId $request->request->get('wishlistId''');
  832.         }
  833.         if (!$wishlistId) {
  834.             throw new \Exception("No wishlist id specified");
  835.         }
  836.         $wishlist $this->wishlistService->getWishlistById($wishlistId$contexttrue);
  837.         if (!$wishlist) {
  838.             throw new WishlistNotFoundException($wishlistId);
  839.         }
  840.         if ($wishlist->isPrivate() && !$this->wishlistService->hasAccessToWishlist($wishlist$context)) {
  841.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  842.         }
  843.         $this->wishlistService->addProductsToCart(
  844.             $request->request->getAlnum('token'$context->getToken()),
  845.             $wishlist,
  846.             $context
  847.         );
  848.         $this->addFlash('success'$this->trans('checkout.cartUpdateSuccess'));
  849.         $errors $wishlist->getExtension('errors');
  850.         if ($errors){
  851.             $errors $errors->getVars();
  852.             if (isset($errors['productNotFound'])) {
  853.                 $this->addFlash('danger'$this->trans('checkout.product-not-found'));
  854.             }
  855.         }
  856.         if ($request->request->get('redirectToCart')) {
  857.             return $this->redirectToRoute('frontend.checkout.cart.page');
  858.         }
  859.         if ($wishlistSettings->getAddAllRedirectToCart()) {
  860.             if ($request->request->get('redirectToCheckout')) {
  861.                 return $this->redirectToRoute('frontend.checkout.confirm.page');
  862.             } else {
  863.                 return $this->redirectToRoute('frontend.checkout.cart.page');
  864.             }
  865.         } else {
  866.             if ($request->request->get('originDetailpage')) {
  867.                 return $this->redirectToRoute('frontend.PremsWishlist.detail', ['wishlistId' => $wishlistId]);
  868.             } else {
  869.                 return $this->redirectToRoute('frontend.PremsWishlist.index');
  870.             }
  871.         }
  872.     }
  873.     /**
  874.      * Removes a wishlist
  875.      *
  876.      * @Route("/wishlist/remove/{wishlistId}", name="frontend.PremsWishlist.remove", methods={"GET"})
  877.      *
  878.      * @param string $wishlistId
  879.      * @param Request $request
  880.      * @param SalesChannelContext $context
  881.      * @return RedirectResponse
  882.      * @throws InconsistentCriteriaIdsException
  883.      * @throws WishlistNotFoundException
  884.      */
  885.     public function removeWishlist(string $wishlistIdRequest $requestSalesChannelContext $context): RedirectResponse
  886.     {
  887.         $page $this->genericPageLoader->load($request$context);
  888.         if ($page->getMetaInformation()) {
  889.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  890.         }
  891.         if ($this->getWishlistSettings()->isLoginRequired()) {
  892.             $this->denyAccessUnlessLoggedIn();
  893.         }
  894.         $wishlist $this->wishlistService->getWishlistById($wishlistId$context);
  895.         if (!$wishlist) {
  896.             throw new WishlistNotFoundException($wishlistId);
  897.         }
  898.         if ($this->wishlistService->hasAccessToWishlist($wishlist$contexttrue)) {
  899.             $this->wishlistService->removeWishlist($wishlist,  $context->getContext());
  900.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.remove_successful'));
  901.         } else {
  902.             $this->addFlash('success'$this->trans('prems-wishlist.status_messages.remove_failed'));
  903.         }
  904.         return $this->redirectToRoute('frontend.PremsWishlist.index');
  905.     }
  906.     /**
  907.      * Removes a product from wishlist
  908.      *
  909.      * @Route("/wishlist/remove/{id}/wishlist/{wishlistId}", name="frontend.PremsWishlist.product.remove", methods={"GET"})
  910.      *
  911.      * @param string $id
  912.      * @param string $wishlistId
  913.      * @param Request $request
  914.      * @param SalesChannelContext $context
  915.      * @return JsonResponse
  916.      * @throws InconsistentCriteriaIdsException
  917.      * @throws WishlistNotFoundException
  918.      */
  919.     public function removeProductFromWishlist(string $idstring $wishlistIdRequest $requestSalesChannelContext $context): RedirectResponse
  920.     {
  921.         $page $this->genericPageLoader->load($request$context);
  922.         if ($page->getMetaInformation()) {
  923.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  924.         }
  925.         if ($this->getWishlistSettings()->isLoginRequired()) {
  926.             $this->denyAccessUnlessLoggedIn();
  927.         }
  928.         $wishlist $this->wishlistService->getWishlistById($wishlistId$context);
  929.         if (!$wishlist) {
  930.             throw new WishlistNotFoundException($wishlistId);
  931.         }
  932.         if (!$this->wishlistService->hasAccessToWishlist($wishlist$contexttrue)) {
  933.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  934.         }
  935.         $this->wishlistService->removeProductFromWishlist($wishlist$id$context->getContext());
  936.         return $this->redirectToRoute('frontend.PremsWishlist.index', ['wishlistId' => $wishlistId]);
  937.     }
  938.     /**
  939.      * Modal window to change product of a wishlist: Add comment, Number of products or move to another wishlist
  940.      *
  941.      * @Route("/wishlist/change/{wishlistId}/id/{id}", name="frontend.PremsWishlist.product.change", methods={"GET", "POST"})
  942.      *
  943.      * @param string $wishlistId
  944.      * @param string $id
  945.      * @param Request $request
  946.      * @param SalesChannelContext $context
  947.      * @return JsonResponse
  948.      * @throws InconsistentCriteriaIdsException
  949.      * @throws WishlistNotFoundException
  950.      */
  951.     public function changeProductOfWishlist(string $wishlistIdstring $idRequest $requestSalesChannelContext $context): Response
  952.     {
  953.         $page $this->genericPageLoader->load($request$context);
  954.         if ($page->getMetaInformation()) {
  955.             $page->getMetaInformation()->setRobots('noindex,nofollow');
  956.         }
  957.         $wishlist $this->wishlistService->getWishlistById($wishlistId$context);
  958.         if (!$wishlist) {
  959.             throw new WishlistNotFoundException($wishlistId);
  960.         }
  961.         if (!$this->wishlistService->hasAccessToWishlist($wishlist$contexttrue)) {
  962.             throw new WishlistNotFoundException($wishlistId);
  963.         }
  964.         $moveToWishlistId  $request->request->get('moveToWishlist');
  965.         $hint  $request->request->get('hint');
  966.         $numberWished  = (int) $request->request->get('numberWished'0);
  967.         $numberGet  = (int) $request->request->get('numberGet'0);
  968.         $position  = (int) $request->request->get('position'0);
  969.         if ($moveToWishlistId) {
  970.             $moveToWishlist $this->wishlistService->getWishlistById($moveToWishlistId$context);
  971.             if (!$this->wishlistService->hasAccessToWishlist($moveToWishlist$contexttrue)) {
  972.                 throw new WishlistNotFoundException($moveToWishlistId);
  973.             }
  974.             $this->wishlistService->changeProductOfWishlist($id$moveToWishlist$hint$numberWished$numberGet$position$context->getContext());
  975.             /**$this->wishlistService->removeProductFromWishlist($wishlist, $id, $context->getContext());
  976.             $this->wishlistService->addProductToWishlists($productId, [$moveToWishlist], $context->getContext());*/
  977.             return $this->redirectToRoute('frontend.PremsWishlist.index');
  978.         }
  979.         $lists $this->wishlistService->getWishlistsForUser($context);
  980.         foreach ($wishlist->getProducts() as $product) {
  981.             if ($product->getId() == $id) {
  982.                 $hint  $product->getHint();
  983.                 $numberWished  $product->getNumberWished();
  984.                 $numberGet  $product->getNumberGet();
  985.                 $position $product->getPosition();
  986.                 break;
  987.             }
  988.         }
  989.         $response $this->renderStorefront('@PremsWishlist/storefront/page/wishlist/modal_change_product.html.twig', [
  990.             'premsWishlist' => $this->getWishlistSettings(),
  991.             'lists' => $lists,
  992.             'wishlistId' => $wishlistId,
  993.             'id' => $id,
  994.             'hint' => $hint,
  995.             'numberWished' => $numberWished,
  996.             'numberGet' => $numberGet,
  997.             'position' => $position
  998.         ]);
  999.         $response->headers->set('X-Robots-Tag''noindex,nofollow');
  1000.         return $response;
  1001.     }
  1002.     /**
  1003.      * @throws CustomerNotLoggedInException
  1004.      */
  1005.     protected function denyAccessUnlessLoggedIn(bool $allowGuest false): void
  1006.     {
  1007.         /** @var RequestStack $requestStack */
  1008.         $requestStack $this->get('request_stack');
  1009.         $request $requestStack->getCurrentRequest();
  1010.         if (!$request) {
  1011.             throw new CustomerNotLoggedInException();
  1012.         }
  1013.         /** @var SalesChannelContext|null $context */
  1014.         $context $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  1015.         if (
  1016.             $context
  1017.             && $context->getCustomer()
  1018.             && (
  1019.                 $allowGuest === true
  1020.                 || $context->getCustomer()->getGuest() === false
  1021.             )
  1022.         ) {
  1023.             return;
  1024.         }
  1025.         throw new CustomerNotLoggedInException();
  1026.     }
  1027. }