custom/plugins/KmPitchPrint/src/Controller/PitchPrintController.php line 658

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace KmPitchPrint\Controller;
  3. use KmPitchPrint\Services\ProductPitchPrintService;
  4. use PhpParser\Node\Expr\AssignOp\Mul;
  5. use PHPUnit\Util\Json;
  6. use Shopware\Core\Checkout\Cart\Cart;
  7. use Shopware\Core\Checkout\Cart\Error\Error;
  8. use Shopware\Core\Checkout\Cart\LineItemFactoryRegistry;
  9. use Shopware\Core\Content\Product\Exception\ProductNotFoundException;
  10. use Shopware\Core\Content\Seo\SeoUrlPlaceholderHandlerInterface;
  11. use Shopware\Core\Defaults;
  12. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  18. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  19. use Shopware\Core\Framework\Uuid\Uuid;
  20. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  21. use Shopware\Storefront\Controller\StorefrontController;
  22. use Shopware\Storefront\Framework\Routing\RequestTransformer;
  23. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoader;
  24. use Shopware\Storefront\Page\Product\Configurator\ProductCombinationFinder;
  25. use Shopware\Storefront\Page\Product\QuickView\MinimalQuickViewPageLoader;
  26. use Swp\ProductOptionsSix\Controller\ProductOptionsSix;
  27. use Swp\ProductOptionsSix\Core\Checkout\ProductOptions\Cart\ProductOptionsCartDataCollector;
  28. use Symfony\Component\HttpFoundation\JsonResponse;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpFoundation\Response;
  31. use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
  32. use Symfony\Component\Routing\Annotation\Route;
  33. use Symfony\Component\HttpFoundation\Cookie;
  34. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  35. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  36. use Shopware\Storefront\Page\Product\ProductPageLoader;
  37. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  38. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  39. use KmPitchPrint\Services\KmHelpers;
  40. use Shopware\Storefront\Page\Product\ProductPageLoadedHook;
  41. /**
  42.  * @RouteScope(scopes={"storefront"})
  43.  */
  44. class PitchPrintController extends StorefrontController
  45. {
  46.     /**
  47.      * @var CheckoutCartPageLoader
  48.      */
  49.     private $cartPageLoader;
  50.     /**
  51.      * @var LineItemFactoryRegistry
  52.      */
  53.     private $lineItemFactory;
  54.     /**
  55.      * @var CartService
  56.      */
  57.     private $cartService;
  58.     /**
  59.      * @var MinimalQuickViewPageLoader
  60.      */
  61.     private $minimalQuickViewPageLoader;
  62.     /**
  63.      * @var ProductPageLoader
  64.      */
  65.     private $productPageLoader;
  66.     /**
  67.      * @var SeoUrlPlaceholderHandlerInterface
  68.      */
  69.     private $seoUrlPlaceholderHandler;
  70.     /**
  71.      * @var ProductPitchPrintService
  72.      */
  73.     private $productPitchPrintService;
  74.     /**
  75.      * @var PitchPrint
  76.      */
  77.     private $pitchPrintRepository;
  78.     /**
  79.      * @var ProductCombinationFinder
  80.      */
  81.     private $combinationFinder;
  82.     public function __construct(CartService                       $cartService,
  83.                                 EntityRepositoryInterface         $pitchPrintRepository,
  84.                                 ProductPageLoader                 $productPageLoader,
  85.                                 MinimalQuickViewPageLoader        $minimalQuickViewPageLoader,
  86.                                 ProductPitchPrintService          $productPitchPrintService,
  87.                                 ProductCombinationFinder          $combinationFinder,
  88.                                 SeoUrlPlaceholderHandlerInterface $seoUrlPlaceholderHandler,
  89.                                 LineItemFactoryRegistry           $lineItemFactory,
  90.                                 CheckoutCartPageLoader            $cartPageLoader
  91.     )
  92.     {
  93.         $this->minimalQuickViewPageLoader $minimalQuickViewPageLoader;
  94.         $this->cartService $cartService;
  95.         $this->pitchPrintRepository $pitchPrintRepository;
  96.         $this->productPageLoader $productPageLoader;
  97.         $this->productPitchPrintService $productPitchPrintService;
  98.         $this->combinationFinder $combinationFinder;
  99.         $this->seoUrlPlaceholderHandler $seoUrlPlaceholderHandler;
  100.         $this->lineItemFactory $lineItemFactory;
  101.         $this->cartPageLoader $cartPageLoader;
  102.     }
  103.     private function generateSignature(): array
  104.     {
  105.         $timestamp time();
  106.         $signature md5(PITCH_APIKEY PITCH_SECRETKEY $timestamp);
  107.         return array('timestamp' => $timestamp'apiKey' => PITCH_APIKEY'signature' => $signature);
  108.     }
  109.     private function createPPCookie(): string
  110.     {
  111.         return KmHelpers::createPPCookie();
  112.     }
  113.     /**
  114.      * @Route ("/km/product/preview/{pp_mode}/{productId}/{projectId}", name="km.product.preview")
  115.      */
  116.     public function ppProductPreviewIndex(SalesChannelContext $contextRequest $request): Response
  117.     {
  118.         $criteria $this->productPitchPrintService->getCriteria();
  119.         $criteria->addFilter(new EqualsFilter('projectId'$request->get('projectId')));
  120.         $criteria->addFilter(new EqualsFilter('cookieId'$request->cookies->get('pp_id')));
  121.         $this->productPitchPrintService->setCriteria($criteria);
  122.         $productPitchprint $this->productPitchPrintService->getCreatedProject($context->getContext());
  123.         if (!$request->cookies->get('pp_id') && $request->get('pp_mode') == 'new') {
  124.             $this->createPPCookie();
  125.             return $this->redirectToRoute('frontend.detail.page', ['productId' => $request->get('productId')]);
  126.         }
  127.         if ($productPitchprint->getTotal() < 1) {
  128.             return $this->redirectToRoute('frontend.detail.page', ['productId' => $request->get('productId')]);
  129.         }
  130.         $page $this->productPageLoader->load($request$context);
  131.         $productPitchprint $productPitchprint->first();
  132.         $previews $productPitchprint->getPayload()['previews'];
  133.         $i 0;
  134.         $cart $this->cartService->getCart($context->getToken(), $context);
  135.         $lineItemQty 1;
  136.         foreach ($cart->getLineItems() as $lineItem) {
  137.             if ($lineItem->getReferencedId() == $page->getProduct()->getId()) {
  138.                 $lineItemQty $lineItem->getQuantity();
  139.             }
  140.         }
  141.         foreach ($page->getProduct()->getMedia() as $mediaEntity) {
  142.             //replace only previews, if the mediaItems are more, skip the rest
  143.             if (isset($previews[$i])) {
  144.                 $samplePreview $previews[$i];
  145.             } else {
  146.                 break;
  147.             }
  148.             foreach ($mediaEntity->getMedia()->getThumbnails() as $thumbnail) {
  149.                 $thumbnail->setUrl($samplePreview);
  150.             }
  151.             $mediaEntity->getMedia()->setUrl($samplePreview);
  152.             $i++;
  153.         }
  154.         $ratingSuccess $request->get('success');
  155.         // Fallback layout for non-assigned product layout
  156.         if (!$page->getCmsPage()) {
  157.             return $this->renderStorefront('@Storefront/storefront/page/product-detail/index.html.twig', ['page' => $page,
  158.                 'ratingSuccess' => $ratingSuccess,
  159.                 'pp_project_id' => $productPitchprint->getProjectId(),
  160.                 'pp_mode' => $request->get('pp_mode'),
  161.                 'lineItemQty' => $lineItemQty
  162.             ]);
  163.         }
  164.         return $this->renderStorefront('@Storefront/storefront/page/content/product-detail.html.twig', ['page' => $page]);
  165.     }
  166.     /**
  167.      * @Route ("/km/edit/project/{projectId}", name="km.edit.project")
  168.      */
  169.     public function editProject(string $projectIdSalesChannelContext $contextRequest $request): Response
  170.     {
  171.         $criteria = new Criteria();
  172.         $criteria->addFilter(new EqualsFilter('projectId'$projectId));
  173.         $result $this->pitchPrintRepository->search($criteria$context->getContext());
  174.         return $this->renderStorefront('@KmPitchPrint/storefront/page/edit-project.html.twig',
  175.             ['project' => $result->first()]);
  176.     }
  177.     /**
  178.      * @Route ("/km/edit/lineItem/{lineItemId}", name="km.edit.lineItem")
  179.      */
  180.     public function editLineItem(SalesChannelContext $contextRequest $request): Response
  181.     {
  182.         $page $this->productPageLoader->load($request$context);
  183.         //$ratingSuccess = $request->get('success');
  184.         // Fallback layout for non-assigned product layout
  185.         if (!$page->getCmsPage()) {
  186.             return $this->renderStorefront('@Storefront/storefront/page/product-detail/index.html.twig', ['page' => $page,
  187.             ]);
  188.         }
  189.         return $this->renderStorefront('@Storefront/storefront/page/content/product-detail.html.twig', ['page' => $page]);
  190.     }
  191.     /**
  192.      * @Route("/km/moveto/cart", name="km.moveto.cart.project", methods={"POST"}, defaults={"XmlHttpRequest"=true, "csrf_protected"=true}) #defaults={"csrf_protected"=false}, methods={"POST"})
  193.      */
  194.     public function moveToCartProject(SalesChannelContext $contextRequestDataBag $requestDataBagRequest $request): JsonResponse
  195.     {
  196.         $productPitchPrintService $this->container->get('km.services.product_pitchprint');
  197.         $projectId $request->get('projectId');
  198.         $criteria = new Criteria();
  199.         $criteria->addFilter(new EqualsFilter('projectId'$projectId));
  200.         #$criteria->addFilter(new EqualsFilter('cookieId', $request->cookies->get('pp_id')));
  201.         $ppRepository $this->container->get('km_product_pitchprint.repository')
  202.             ->search($criteria$context->getContext());
  203.         if (array_key_exists('swoptions'$ppRepository->first()->getPayload())) {
  204.             $productOptionsData $ppRepository->first()->getPayload()['swoptions'];
  205.             $requestDataBag->set(
  206.                 ProductOptionsSix::PRODUCT_OPTIONS_REQUEST_PARAMETER, new RequestDataBag($productOptionsData)
  207.             );
  208.         }
  209.         $cart $this->cartService->getCart($context->getToken(), $context);
  210.         $count 0;
  211.         $pp $ppRepository->first();
  212.         $payload $pp->getPayload();
  213.         $payload['previews'] = explode(','$request->get('previews'));
  214.         $productPitchPrintService->setProjectData(
  215.             [
  216.                 'id' => $pp->getId(),
  217.                 'payload' => serialize($payload),
  218.                 'projectUpdatedAt'=>(new \DateTimeImmutable())->format(Defaults::STORAGE_DATE_TIME_FORMAT)
  219.             ]
  220.         );
  221.         $productPitchPrintService->updateProject($context->getContext());
  222.         if (!$pp->getPayload()){
  223.             $type 'product';
  224.             $qty = (int)$requestDataBag->get('lineItems')->get($pp->getProjectId())->get('quantity');
  225.         }else{
  226.             $type $pp->getPayload()['type'];
  227.             $qty = (int)$pp->getPayload()['qty'];
  228.         }
  229.         try {
  230.             $items = [];
  231.             //$id = \Shopware\Core\Framework\Uuid\Uuid::randomHex();
  232.             $id $pp->getProjectId();
  233.             $lineItem = new LineItem(
  234.                 $id,
  235.                 $type,
  236.                 $pp->getProductId(),
  237.                 $qty
  238.             );
  239.             $lineItem->setStackable(true);
  240.             $lineItem->setRemovable(true);
  241.             $count += $lineItem->getQuantity();
  242.             if ($pp->getDesignId()) {
  243.                 $lineItem->setPayload(
  244.                     ['features' =>
  245.                         [
  246.                             'pitch_print' => [
  247.                                 'customer'=> $pp->getId(),
  248.                                 'projectId' => $pp->getProjectId(),
  249.                                 'designId' => $pp->getDesignId(),
  250.                                 'previews' => $payload['previews']
  251.                             ],
  252.                         ],
  253.                     ]
  254.                 );
  255.             }
  256.             //$lineItem->setPayloadValue('lineItemCreatedAt',(new \DateTimeImmutable())->format(Defaults::STORAGE_DATE_TIME_FORMAT));
  257.             $items[] = $lineItem;
  258.             /** @var RequestDataBag|null $productOptionsData */
  259.             $productOptionsData $requestDataBag->get(
  260.                 ProductOptionsSix::PRODUCT_OPTIONS_REQUEST_PARAMETER
  261.             );
  262.             if($productOptionsData!=null){
  263.                 if (!empty($productOptionsData->all())) {
  264.                     $cart $productPitchPrintService->addProductOptions($requestDataBag$context$cart$lineItem->getPayloadValue('features'));
  265.                 }else{
  266.                     $cart $this->cartService->add($cart$items$context);
  267.                 }
  268.             }else {
  269.                 $cart $this->cartService->add($cart$items$context);
  270.             }
  271.             //delete from wishlist
  272.             $this->productPitchPrintService->removeFromWishlist($pp->getId(), $context);
  273.             if (!$this->traceErrors($cart)) {
  274.                 $this->addFlash(self::SUCCESS$this->trans('checkout.addToCartSuccess', ['%count%' => $count]));
  275.             }
  276.         } catch (ProductNotFoundException $exception) {
  277.             $this->addFlash(self::DANGER$this->trans('error.addToCartError'));
  278.         }
  279.         return $this->json(['redirectUrl' => $this->generateUrl('frontend.checkout.cart.page')]);
  280.     }
  281.     /**
  282.      * @Route("/km/update/project", name="km.update.project", methods={"POST"}, defaults={"XmlHttpRequest"=true, "csrf_protected"=true}) #defaults={"csrf_protected"=false}, methods={"POST"})
  283.      */
  284.     public function updateProject(SalesChannelContext $contextRequestDataBag $requestDataBagRequest $request): JsonResponse
  285.     {
  286.         if (!$request->isXmlHttpRequest()) {
  287.             //errorhandling
  288.         }
  289.         $previews explode(','$request->get('previews'));
  290.         $projectId $request->get('projectId');
  291.         $criteria = new Criteria();
  292.         $criteria->addFilter(new EqualsFilter('projectId'$projectId));
  293.         #$criteria->addFilter(new EqualsFilter('cookieId', $request->cookies->get('pp_id')));
  294.         $pp_repo $this->container->get('km_product_pitchprint.repository');
  295.         $projectData $pp_repo->search($criteria$context->getContext())->first();
  296.         $payload $projectData->getPayload();
  297.         $payload['previews'] = $previews;
  298.         $this->productPitchPrintService->setProjectData([
  299.             'id' => $projectData->getId(),
  300.             'cookieId' => $request->cookies->get('pp_id'),
  301.             'projectId' => $projectId,
  302.             'productId' => $projectData->getProductId(),
  303.             'payload' => serialize($payload),
  304.             'projectUpdatedAt'=>(new \DateTimeImmutable())->format(Defaults::STORAGE_DATE_TIME_FORMAT)
  305.         ]);
  306.         $this->productPitchPrintService->updateProject($context->getContext());
  307.         /**/
  308.         $cart $this->cartService->getCart($context->getToken(), $context);
  309.         foreach ($cart->getLineItems() as $lineItem) {
  310.             $features $lineItem->getPayloadValue('features');
  311.             if ($features && isset($features['pitch_print'])) {
  312.                 if ($projectId == $features['pitch_print']['projectId']) {
  313.                     $features['pitch_print']['previews'] = $previews;
  314.                     $lineItem->setPayloadValue('features'$features);
  315.                     $lineItem->getCover()->setUrl($previews[0]);
  316.                     foreach ($lineItem->getCover()->getThumbnails() as $thumbnail) {
  317.                         $thumbnail->setUrl($previews[0]);
  318.                     }
  319.                     foreach ($lineItem->getChildren() as $childItem) {
  320.                         if ($childItem->getCover()) {
  321.                             $childItem->getCover()->setUrl($previews[0]);
  322.                             foreach ($childItem->getCover()->getThumbnails() as $thumbnail) {
  323.                                 $thumbnail->setUrl($previews[0]);
  324.                             }
  325.                             //$this->cartService->changeQuantity($cart, $childItem->getId(), $childItem->getQuantity(), $context);
  326.                         }
  327.                     }
  328.                 }
  329.             }
  330.         }
  331.         $qty = (int)$projectData->getPayload()['qty'];
  332.         if ($lineItem->getType() !='promotion')
  333.             $this->cartService->changeQuantity($cart$lineItem->getId(), $qty$context);
  334.         return $this->json(['redirectUrl' => $this->generateUrl('frontend.checkout.cart.page')]);
  335.     }
  336.     /**
  337.      * @Route("/km/add/project", name="km.add.project", methods={"POST"}, defaults={"XmlHttpRequest"=true, "csrf_protected"=true}) #defaults={"csrf_protected"=false}, methods={"POST"})
  338.      */
  339.     public function addProject(SalesChannelContext $contextRequestDataBag $requestDataBagRequest $request): JsonResponse
  340.     {
  341.         if (!$request->isXmlHttpRequest()) {
  342.             //errorhandling
  343.         }
  344.         $previews explode(','$request->get('previews'));
  345.         /*
  346.         $previews_raw = explode(',', $request->get('previews'));
  347.         $previews = [];
  348.         foreach($previews_raw as $preview){
  349.             $previews[] = urlencode($preview);
  350.         }
  351.         */
  352.         $projectId $request->get('projectId');
  353.         $productId $request->get('productId');
  354.         $designId $request->get('designId');
  355.         if (!$request->cookies->get('pp_id')) {
  356.             $cookieId $this->createPPCookie();
  357.         }else{
  358.             $cookieId $request->cookies->get('pp_id');
  359.         }
  360.         $ppPayload = [
  361.                 'previews' => $previews,
  362.                 'type' => LineItem::PRODUCT_LINE_ITEM_TYPE,
  363.             ];
  364.         $productOptionsData $requestDataBag->get(
  365.             ProductOptionsSix::PRODUCT_OPTIONS_REQUEST_PARAMETER
  366.         );
  367.         /** @var RequestDataBag|null $lineItems */
  368.         $lineItems $requestDataBag->get('lineItems');
  369.         if (!$lineItems) {
  370.             throw new MissingRequestParameterException('lineItems');
  371.         }
  372.         $count 0;
  373.         try {
  374.             $items = [];
  375.             /** @var RequestDataBag $lineItemData */
  376.             foreach ($lineItems as $lineItemData) {
  377.                 $lineItem = new LineItem(
  378.                     $projectId,
  379.                     $lineItemData->getAlnum('type'),
  380.                     $lineItemData->get('referencedId'),
  381.                     $lineItemData->getInt('quantity'1)
  382.                 );
  383.                 $lineItem->setStackable($lineItemData->getBoolean('stackable'true));
  384.                 $lineItem->setRemovable($lineItemData->getBoolean('removable'true));
  385.                 $count += $lineItem->getQuantity();
  386.                 //add previews to payload if the item was a pitch print designed
  387.                 $lineItem->setPayload(
  388.                     ['features' =>
  389.                         [
  390.                             'pitch_print' => [
  391.                                 'customer'=>$request->get('uuid'),
  392.                                 'projectId' => $projectId,
  393.                                 'designId' => $designId,
  394.                                 'previews' => $previews,
  395.                             ]
  396.                         ]
  397.                     ]
  398.                 );
  399.                 $items[] = $lineItem;
  400.                 if ($productOptionsData) {
  401.                     $sWoptions $this->productPitchPrintService->getProductOptions($productId$context);
  402.                     $ppPayload = [
  403.                         'previews' => $previews,
  404.                         'swoptions' => $productOptionsData->all(),
  405.                         'type' => ProductOptionsCartDataCollector::PRODUCT_OPTIONS_LINE_ITEM_TYPE,
  406.                     ];
  407.                 }
  408.                 $ppPayload['qty'] = $lineItem->getQuantity();
  409.                 $ppPayload serialize($ppPayload);
  410.                 $this->productPitchPrintService->setProjectData([
  411.                     'cookieId' => $cookieId,
  412.                     'projectId' => $projectId,
  413.                     'designId' => $designId,
  414.                     'productId' => $productId,
  415.                     'payload' => $ppPayload,
  416.                     'projectUpdatedAt' => (new \DateTimeImmutable())->format(Defaults::STORAGE_DATE_TIME_FORMAT)
  417.                 ]);
  418.                 $oldProjectId $request->get('oldProjectId');
  419.                 //hande project created from wishlist to cart
  420.                 //if update failes new project will be created
  421.                 if ($oldProjectId){
  422.                     $this->productPitchPrintService->updateTmpProject($oldProjectId$contexttrue);
  423.                 }else{
  424.                     $this->productPitchPrintService->createNewProject($context->getContext());
  425.                 }
  426.             }
  427.             $cart $this->cartService->getCart($context->getToken(), $context);
  428.             if ($productOptionsData) {
  429.                 $lineItem->setPayloadValue('swp0ptions'$sWoptions);
  430.                 $cart $this->productPitchPrintService->addProductOptions($requestDataBag$context$cart$lineItem->getPayloadValue('features'));
  431.             } else {
  432.                 $cart $this->cartService->add($cart$items$context);
  433.             }
  434.             if (!$this->traceErrors($cart)) {
  435.                 $this->addFlash(self::SUCCESS$this->trans('checkout.addToCartSuccess', ['%count%' => $count]));
  436.             }
  437.         } catch (ProductNotFoundException $exception) {
  438.             $this->addFlash(self::DANGER$this->trans('error.addToCartError'));
  439.         }
  440.         return $this->json(['redirectUrl' => $this->generateUrl('frontend.checkout.cart.page')]);
  441.     }
  442.     private function traceErrors(Cart $cart): bool
  443.     {
  444.         if ($cart->getErrors()->count() <= 0) {
  445.             return false;
  446.         }
  447.         $this->addCartErrors($cart, function (Error $error) {
  448.             return $error->isPersistent();
  449.         });
  450.         return true;
  451.     }
  452.     /**
  453.      * Leiche
  454.      */
  455.     public function switch(string $productIdRequest $requestSalesChannelContext $salesChannelContext): JsonResponse
  456.     {
  457.         $switchedOption $request->query->has('switched') ? (string) $request->query->get('switched') : null;
  458.         $options = (string) $request->query->get('options');
  459.         try {
  460.             $newOptions json_decode($optionstrue512\JSON_THROW_ON_ERROR);
  461.         } catch (\JsonException $jsonException) {
  462.             $newOptions = [];
  463.         }
  464.         try {
  465.             $redirect $this->combinationFinder->find($productId$switchedOption$newOptions$salesChannelContext);
  466.             $productId $redirect->getVariantId();
  467.         } catch (ProductNotFoundException $productNotFoundException) {
  468.             //nth
  469.         }
  470.         $host $request->attributes->get(RequestTransformer::SALES_CHANNEL_ABSOLUTE_BASE_URL)
  471.             . $request->attributes->get(RequestTransformer::SALES_CHANNEL_BASE_URL);
  472.         $url $this->seoUrlPlaceholderHandler->replace(
  473.             $this->seoUrlPlaceholderHandler->generate(
  474.                 'frontend.detail.page',
  475.                 ['productId' => $productId]
  476.             ),
  477.             $host,
  478.             $salesChannelContext
  479.         );
  480.         $response = [
  481.             'url' => $url,
  482.             'productId' => $productId,
  483.         ];
  484.         $responseData json_decode($request->query->get('options'), true);
  485.         if (isset($responseData['quantity'])){
  486.             $response = [
  487.                 'url' => $url,
  488.                 'productId' => $productId,
  489.                 'quantity'=>$responseData['quantity']
  490.             ];
  491.         }
  492.         $response = new JsonResponse(
  493.             $response
  494.         );
  495.         $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER'1');
  496.         return $response;
  497.     }
  498.     /**
  499.      * @Route("/detail/{productId}", name="frontend.detail.page", methods={"GET"})
  500.      */
  501.     public function index(SalesChannelContext $contextRequest $request): Response
  502.     {
  503.         $preselectedQty=0;
  504.         if($request->query->get('q')){
  505.             $preselectedQty $request->query->get('q');
  506.         }
  507.         $preselectedOpt=false;
  508.         if($request->query->get('opt')){
  509.             $preselectedOpt $request->query->get('opt');
  510.         }
  511.         $page $this->productPageLoader->load($request$context);
  512.         $this->hook(new ProductPageLoadedHook($page$context));
  513.         $ratingSuccess $request->get('success');
  514.         // Fallback layout for non-assigned product layout
  515.         if (!$page->getCmsPage()) {
  516.             return $this->renderStorefront('@Storefront/storefront/page/product-detail/index.html.twig',
  517.                 [
  518.                     'page' => $page,
  519.                     'ratingSuccess' => $ratingSuccess,
  520.                     'preselected_quantity' => $preselectedQty,
  521.                     'preselected_option'=>$preselectedOpt
  522.                 ]);
  523.         }
  524.         return $this->renderStorefront('@Storefront/storefront/page/content/product-detail.html.twig',
  525.             [
  526.                 'page' => $page,
  527.                 'preselected_quantity' => $preselectedQty,
  528.                 'preselected_option'=>$preselectedOpt
  529.             ]
  530.         );
  531.     }
  532.     /**
  533.      * @Route("/km/detail/{productId}/switch", name="km.detail.switch", methods={"GET"}, defaults={"XmlHttpRequest": true})
  534.      */
  535.     public function switchPP(string $productIdRequest $requestSalesChannelContext $salesChannelContext): JsonResponse
  536.     {
  537.         $switchedOption $request->query->get('switched');
  538.         $options $request->query->get('options');
  539.         $newOptions $options !== null json_decode($optionstrue) : [];
  540.         $ppMode $newOptions['pp_mode'];
  541.         $projectId $newOptions['pp_project_id'];
  542.         try {
  543.             $redirect $this->combinationFinder->find($productId$switchedOption$newOptions$salesChannelContext);
  544.             $productId $redirect->getVariantId();
  545.         } catch (ProductNotFoundException $productNotFoundException) {
  546.             //nth
  547.         }
  548.         $host $request->attributes->get(RequestTransformer::SALES_CHANNEL_ABSOLUTE_BASE_URL)
  549.             . $request->attributes->get(RequestTransformer::SALES_CHANNEL_BASE_URL);
  550.         if ($projectId && $projectId) {
  551.             $url $this->seoUrlPlaceholderHandler->replace(
  552.                 $this->seoUrlPlaceholderHandler->generate(
  553.                     'km.product.preview',
  554.                     ['productId' => $productId,
  555.                         'projectId' => $projectId,
  556.                         'pp_mode' => $ppMode,
  557.                     ]
  558.                 ),
  559.                 $host,
  560.                 $salesChannelContext
  561.             );
  562.         } else {
  563.             $url $this->seoUrlPlaceholderHandler->replace(
  564.                 $this->seoUrlPlaceholderHandler->generate(
  565.                     'frontend.detail.page',
  566.                     ['productId' => $productId]
  567.                 ),
  568.                 $host,
  569.                 $salesChannelContext
  570.             );
  571.         }
  572.         $response = new JsonResponse(['url' => $url]);
  573.         $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER'1');
  574.         return $response;
  575.     }
  576.     private function getSignature()
  577.     {
  578.         $timestamp time();
  579.         $signature md5(PITCH_APIKEY PITCH_SECRETKEY $timestamp);
  580.         return array('timestamp' => $timestamp'apiKey' => PITCH_APIKEY'signature' => $signature);
  581.     }
  582.     /**
  583.      * @Route("/km/pp/uuid", name="km.pp.uuid", methods={"GET"}, defaults={"XmlHttpRequest": true})
  584.      */
  585.     public function generateUuid(): JsonResponse{
  586.         $uuid Uuid::randomHex();
  587.         return $this->json([
  588.             'uuid'=>$uuid
  589.         ]);
  590.     }
  591.     /**
  592.      * @Route("/km/checkout/quickview/{lineItemId}", name="km.checkout.quickview.minimal", methods={"GET"}, defaults={"XmlHttpRequest": true})
  593.      */
  594.     public function checkoutQuickView(Request $requestSalesChannelContext $context): Response
  595.     {
  596.         //$page = $this->minimalQuickViewPageLoader->load($request, $context);
  597.         $lineItemId $request->get('lineItemId');
  598.         /*
  599.         $cartLineItems = $this->cartService->getCart($context->getToken(), $context)->getLineItems();
  600.         foreach ($cartLineItems as $lineItem) {
  601.             if ($lineItem->getId() == $lineItemId) {
  602.                 break;
  603.             }
  604.         }*/
  605.         $lineItem $this->cartService->getCart($context->getToken(), $context)->getLineItems()->filter(function (LineItem $lineItem) use ($lineItemId) {
  606.             return $lineItem->getId() == $lineItemId;
  607.         })->first();
  608.         //dump($lineItem->getCover());exit;
  609.         return $this->renderStorefront('@KmPitchPrint/storefront/page/km_pitch_print/quickview/minimal.html.twig', ['lineItem' => $lineItem]);
  610.     }
  611.     /**
  612.      * @Route("/km/multiply/project", name="km.multiply.project", defaults={"XmlHttpRequest"=true, "csrf_protected"=true})
  613.      */
  614.     public function multiplyProject(Request $requestSalesChannelContext $context): Response
  615.     {
  616.         $request->request->set('uuid'Uuid::randomHex());
  617.         $lineItemId $request->get('id');
  618.         $cart $this->cartService->getCart($context->getToken(), $context);
  619.         $lineItem $cart->getLineItems()->filter(function (LineItem $lineItem) use ($lineItemId) {
  620.             return $lineItem->getId() == $lineItemId;
  621.         })->first();
  622.         $productId $lineItem->getReferencedId();
  623.         $ppRepository $this->container->get('km_product_pitchprint.repository');
  624.         $projectId $lineItem->getId();
  625.         if (isset($lineItem->getPayload()['features']['pitch_print'])) {
  626.             $projectId $lineItem->getPayload()['features']['pitch_print']['projectId'];
  627.         }
  628.         $criteria = new Criteria();
  629.         $criteria->addFilter(new EqualsFilter('projectId'$projectId));
  630.         #$criteria->addFilter(new EqualsFilter('cookieId', $request->cookies->get('pp_id')));
  631.         $parentProject $ppRepository->search($criteria$context->getContext());
  632.         if (!$request->isXmlHttpRequest()) {
  633.             //errorhandling
  634.         }
  635.         if (isset($lineItem->getPayload()['features']['pitch_print'])) {
  636.             $criteria $this->productPitchPrintService->getCriteria();
  637.             $criteria->addFilter(new EqualsFilter('projectId'$lineItem->getPayload()['features']['pitch_print']['projectId']));
  638.             #$criteria->addFilter(new EqualsFilter('cookieId', $request->cookies->get('pp_id')));
  639.             $this->productPitchPrintService->setCriteria($criteria);
  640.             $previews $lineItem->getPayload()['features']['pitch_print']['previews'];
  641.             //if status == 1 and error == false
  642.             $newProject $this->productPitchPrintService->getClonedProject($lineItem->getPayload()['features']['pitch_print']['projectId']);
  643.             $designId $lineItem->getPayload()['features']['pitch_print']['designId'];
  644.             $payload $parentProject->first()->getPayload();
  645.             $this->productPitchPrintService->setProjectData([
  646.                 'cookieId' => $request->cookies->get('pp_id'),
  647.                 'projectId' => $newProject['newId'],
  648.                 'designId' => $designId,
  649.                 'productId' => $productId,
  650.                 'payload' => serialize($payload)
  651.             ]);
  652.             $this->productPitchPrintService->createNewProject($context->getContext());
  653.             $newId $newProject['newId'];
  654.         } else {
  655.             $newId Uuid::randomHex();
  656.             $this->productPitchPrintService->setProjectData([
  657.                 'cookieId' => $request->cookies->get('pp_id'),
  658.                 'projectId' => $newId,
  659.                 'productId' => $productId,
  660.                 'payload' => serialize($parentProject->first()->getPayload())
  661.             ]);
  662.             $this->productPitchPrintService->createNewProject($context->getContext());
  663.         }
  664.         if (!$cart->getLineItems()) {
  665.             throw new MissingRequestParameterException('lineItems');
  666.         }
  667.         $count 0;
  668.         try {
  669.             $items = [];
  670.             $lineItems = [$lineItem->getId() => $lineItem];
  671.             foreach ($lineItems as $lineItemData) {
  672.                 $newLineItem = new LineItem(
  673.                     $newId,
  674.                     $lineItemData->getType(),
  675.                     $lineItemData->getReferencedId(),
  676.                     $lineItemData->getQuantity()
  677.                 );
  678.                 $newLineItem->setStackable($lineItemData->isStackable());
  679.                 $newLineItem->setRemovable($lineItemData->isRemovable());
  680.                 $count += $lineItem->getQuantity();
  681.                 //add previews to payload if the item was a pitch print designed
  682.                 if (isset($lineItem->getPayload()['features']['pitch_print'])) {
  683.                     $newLineItem->setPayload(
  684.                         ['features' =>
  685.                             [
  686.                                 'pitch_print' => [
  687.                                     'customer' => $request->get('uuid'),
  688.                                     'projectId' => $newProject['newId'],
  689.                                     'designId' => $designId,
  690.                                     'previews' => $previews,
  691.                                 ]
  692.                             ]
  693.                         ]
  694.                     );
  695.                 }
  696.                 $newLineItem->setCover($lineItem->getCover());
  697.                 //$lineItem->getCover()->setId(Uuid::randomHex());
  698.                 $newLineItem->setQuantityInformation($lineItemData->getQuantityInformation());
  699.                 if ($lineItemData->hasChildren()) {
  700.                     /**
  701.                      * @var $childItem LineItem
  702.                      */
  703.                     foreach ($lineItemData->getChildren() as $childItem) {
  704.                         $newChildItem = new LineItem(
  705.                             Uuid::randomHex(),
  706.                             $childItem->getType(),
  707.                             $childItem->getReferencedId(),
  708.                             $childItem->getQuantity()
  709.                         );
  710.                         $newChildItem->setLabel($childItem->getLabel());
  711.                         $newChildItem->setPayload($childItem->getPayload());
  712.                         $newChildItem->setPriceDefinition($childItem->getPriceDefinition());
  713.                         $newChildItem->setPrice($childItem->getPrice());
  714.                         $newChildItem->setGood($childItem->isGood());
  715.                         $newChildItem->setDescription($childItem->getDescription());
  716.                         $newChildItem->setCover($childItem->getCover());
  717.                         $newChildItem->setDeliveryInformation($childItem->getDeliveryInformation());
  718.                         $newChildItem->setRequirement($childItem->getRequirement());
  719.                         $newChildItem->setRemovable($childItem->isRemovable());
  720.                         $newChildItem->setStackable($childItem->isStackable());
  721.                         $newChildItem->setQuantityInformation($childItem->getQuantityInformation());
  722.                         $newLineItem->addChild($newChildItem);
  723.                         $newLineItem->setDataTimestamp(new \DateTimeImmutable());
  724.                     }
  725.                 }
  726.                 $items[] = $newLineItem;
  727.             }
  728.             $cart $this->cartService->add($this->cartService->getCart($context->getToken(), $context), $items$context);
  729.             if (!$this->traceErrors($cart)) {
  730.                 $this->addFlash(self::SUCCESS$this->trans('checkout.addToCartSuccess', ['%count%' => $count]));
  731.             }
  732.         } catch (ProductNotFoundException $exception) {
  733.             $this->addFlash(self::DANGER$this->trans('error.addToCartError'));
  734.         }
  735.         return $this->json(['redirectUrl' => $this->generateUrl('frontend.checkout.cart.page')]);
  736.     }
  737.     /**
  738.      * @Route("/update/swp-option/", name="km_pitchprint.update.swp-option", defaults={"XmlHttpRequest"=true, "csrf_protected"=true}  )
  739.      */
  740.     public function updateSwpOption(Request $requestRequestDataBag $requestDataBagSalesChannelContext $context): JsonResponse
  741.     {
  742.         $cart $cart ?? $this->cartService->getCart($context->getToken(), $context);
  743.         $productOptionsData $requestDataBag->get(
  744.             #'product-option',
  745.             'productOptions'
  746.         );
  747.       #  dump($productOptionsData);exit;
  748.         $lineItemId $request->request->get('lineItemId');
  749.         /**
  750.          * @var $lineItem LineItem
  751.          */
  752.         $productOptionsLineItem $cart->getLineItems()->filter(function (LineItem $lineItem) use ($lineItemId) {
  753.             return $lineItem->getId() == $lineItemId;
  754.         })->first();
  755.         $projectId $lineItemId;
  756.         if (isset($productOptionsLineItem->getPayloadValue('features')['pitch_print'])) {
  757.             $projectId $productOptionsLineItem->getPayloadValue('features')['pitch_print']['projectId'];
  758.         }
  759.         $ppRepo $this->container->get('km_product_pitchprint.repository');
  760.         $pp $ppRepo->search(
  761.             (new Criteria())->addFilter(new EqualsFilter('projectId'$projectId)),
  762.             $context->getContext())->first();
  763.         $payload $pp->getPayload();
  764.         $payload['swoptions'] = $productOptionsData->all();
  765.         $ppRepo->upsert([
  766.             [
  767.                 'id' => $pp->getId(),
  768.                 'payload' => serialize($payload)
  769.             ]
  770.         ], $context->getContext());
  771.         $childLineItemId $request->request->get('childItemId');
  772.         $result $productOptionsLineItem->getChildren()->filter(function (LineItem $lineItem) use ($childLineItemId) {
  773.             return $lineItem->getType() == 'product-option';#&& $lineItem->getId() == $childLineItemId;
  774.         });
  775.         $qty $result->first()->getQuantity();
  776.         //$productOptionsLineItem->getChildren()->removeElement($optionLineItem);
  777.         /**
  778.          * @var $productOptionsCartService \Swp\ProductOptionsSix\Core\Checkout\ProductOptions\ProductOptionsCartService
  779.          */
  780.         $productOptionsCartService $this->container->get('swp.product_options_cart_service');
  781.         /* deprecated
  782.         $productOptions = $productOptionsCartService->loadOptions(
  783.             $productOptionsData,
  784.             $context->getContext()
  785.         );
  786.         */
  787.         $productOptions $this->container->get('swp.product_option_loader')->loadSelectedOptions(
  788.             $productOptionsData,
  789.             $context->getContext()
  790.         );
  791.         /**/
  792.         $productOptionsCartService->addOptions(
  793.             $productOptionsLineItem,
  794.             $productOptionsData,
  795.             $productOptions,
  796.             $qty
  797.         );
  798.         //remove old child Items with old options konfigurations
  799.         $oldLineItems $result->getElements();
  800.         foreach ($oldLineItems as $oldLineItem){
  801.             $productOptionsLineItem->getChildren()->removeElement($oldLineItem);
  802.         }
  803.         $cart $this->cartService->changeQuantity($cart$productOptionsLineItem->getId(), $qty$context);
  804.         //$this->cartService->add($cart, $productOptionsLineItem, $context);
  805.         if (!$this->traceErrors($cart)) {
  806.             $this->addFlash(self::SUCCESS$this->trans('checkout.cartUpdateSuccess'));
  807.         }
  808.         return new JsonResponse(array(
  809.             'lineItemId'=>$productOptionsLineItem->getId()
  810.         ));
  811.     }
  812.     /**
  813.      * @Route("/km/pp_preview/{projectId}.jpg", name="km.load.ppPreview", defaults={"csrf_protected"=false})
  814.      */
  815.     public function loadPpPreview(string $projectIdSalesChannelContext $context): Response
  816.     {
  817.         $criteria = new Criteria();
  818.         $criteria->addFilter(new EqualsFilter('projectId',$projectId));
  819.         $result $this->pitchPrintRepository->search($criteria$context->getContext());
  820.         $payload $result->first()->getPayload();
  821.         $ppPreview $payload['previews'][0];
  822.         $imginfo getimagesize($ppPreview);
  823.         $ch curl_init();
  824.         curl_setopt($chCURLOPT_URL$ppPreview);
  825.         curl_setopt($chCURLOPT_RETURNTRANSFER1);
  826.         curl_setopt($chCURLOPT_BINARYTRANSFER1);
  827.         $data curl_exec($ch);
  828.         curl_close($ch);
  829.         $im imagecreatefromstring($data);
  830.         header("Content-type: {$imginfo['mime']}");
  831.         $im imagescale($im300);
  832.         imagejpeg($im);
  833.         imagedestroy($im);
  834.         
  835.         return new Response();
  836.     }
  837. }