<?php
/**
* Created by Elements.at New Media Solutions GmbH
*
*/
namespace App\Controller\Shop;
use App\Model\Shop\Event\EventProduct;
use App\Model\Shop\Merchandise\MerchandiseProduct;
use App\Service\ContentService;
use App\Service\Shop\ProductService;
use App\Service\TrackingService;
use App\Twig\LinkGeneratorExtension;
use Knp\Component\Pager\PaginatorInterface;
use Pimcore\Model\DataObject;
use Pimcore\Model\DataObject\ShopEvent;
use Pimcore\Model\DataObject\ShopMerchandiseProduct;
use Pimcore\Model\DataObject\ShopTicketCatalog;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\GoneHttpException;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends AbstractShopController
{
public function ticketOverviewAction(Request $request, PaginatorInterface $paginator, ProductService $service, TrackingService $trackingService): Response
{
$catalogs = new ShopTicketCatalog\Listing();
$catalogs->addConditionParam('hideInListing IS NULL OR hideInListing = ""');
$returnData = $service->prepareProductData($catalogs, $request, $paginator);
$trackingData = $trackingService->getOverviewItemList($returnData['products']);
if ($trackingData) {
$returnData['trackingData'] = $trackingData;
}
if ($request->isXmlHttpRequest()) {
$returnData['ajax'] = 1;
$template = $this->renderTemplate('shop/includes/product/product-grid-result.html.twig', $returnData);
$jsonResponse = [
'success' => true,
'html' => $template->getContent(),
];
if ($trackingData) {
$jsonResponse['responseTrackingData'] = [
'gtm' => [
'datalayer' => $trackingData,
],
];
}
return $this->json($jsonResponse);
}
return $this->render('shop/product/ticketOverview.html.twig', $returnData);
}
public function ticketDetailAction(Request $request): Response
{
if ($product = $this->document->getProperty('shopProduct')) {
$trackingManager = $this->factory->getTrackingManager();
$trackingManager->trackProductView($product);
}
$editables = $this->document->getEditables();
$keys = array_keys($editables);
$showFaqAnchor = false;
foreach ($keys as $key) {
if (str_contains($key, 'accordion')) {
$showFaqAnchor = true;
break;
}
}
return $this->render('shop/product/ticketDetail.html.twig', [
'showFaqAnchor' => $showFaqAnchor,
]);
}
public function eventOverviewAction(Request $request, PaginatorInterface $paginator, ProductService $service, TrackingService $trackingService): Response
{
$events = new ShopEvent\Listing();
$events->addConditionParam('hideInEventList IS NULL OR hideInEventList = ""');
$returnData = $service->prepareProductData($events, $request, $paginator);
$trackingData = $trackingService->getOverviewItemList($returnData['products']);
if ($trackingData) {
$returnData['trackingData'] = $trackingData;
}
if ($request->isXmlHttpRequest()) {
$returnData['ajax'] = 1;
$template = $this->renderTemplate('shop/includes/product/product-grid-result.html.twig', $returnData);
$jsonResponse = [
'success' => true,
'html' => $template->getContent(),
];
if ($trackingData) {
$jsonResponse['responseTrackingData'] = [
'gtm' => [
'datalayer' => $trackingData,
],
];
}
return $this->json($jsonResponse);
}
return $this->render('shop/product/eventOverview.html.twig', $returnData);
}
public function eventDetailAction(Request $request): Response
{
if ($product = $this->document->getProperty('shopProduct')) {
$trackingManager = $this->factory->getTrackingManager();
$trackingManager->trackProductView($product);
}
$editables = $this->document->getEditables();
$keys = array_keys($editables);
$showFaqAnchor = false;
foreach ($keys as $key) {
if (str_contains($key, 'accordion')) {
$showFaqAnchor = true;
break;
}
}
return $this->render('shop/product/eventDetail.html.twig', [
'showFaqAnchor' => $showFaqAnchor,
]);
}
public function merchandiseOverviewAction(Request $request, PaginatorInterface $paginator, ProductService $service, TrackingService $trackingService): Response
{
$merchandise = new ShopMerchandiseProduct\Listing();
$returnData = $service->prepareMerchData($merchandise, $request, $paginator);
$trackingData = $trackingService->getOverviewItemList($returnData['products']);
if ($trackingData) {
$returnData['trackingData'] = $trackingData;
}
if ($request->isXmlHttpRequest()) {
$returnData['ajax'] = 1;
$returnData['merchandise'] = 1;
$template = $this->renderTemplate('shop/includes/product/product-grid-result.html.twig', $returnData);
$jsonResponse = [
'success' => true,
'html' => $template->getContent(),
];
if ($trackingData) {
$jsonResponse['responseTrackingData'] = [
'gtm' => [
'datalayer' => $trackingData,
],
];
}
return $this->json($jsonResponse);
}
return $this->render('shop/product/merchandiseOverview.html.twig', $returnData);
}
/**
* @Route("{path}{name}_m_{id}", name="merchandise_detail", defaults={"path"=""}, requirements={"path"=".*?", "name"="[\w-]+", "id"="\d+"})
*
* @param Request $request
* @param ContentService $service
*
* @return Response
*/
public function merchandiseDetailAction(Request $request, ContentService $service, TrackingService $trackingService): Response
{
$merchandise = MerchandiseProduct::getById($request->get('id'));
if ((!($merchandise instanceof MerchandiseProduct) || !$merchandise->isPublished()) && !$request->get('pimcore_object_preview')) {
throw new GoneHttpException('Requested object not found or not published!');
}
$trackingManager = $this->factory->getTrackingManager();
$trackingManager->trackProductView($merchandise);
$tracking = $trackingService->createGA4ProductInfoArray($merchandise, 'add_to_cart');
$faqs = $merchandise->getFaqCategory() ? $service->getFaqsByCategories([$merchandise->getFaqCategory()])->load() : [];
$returnArray = [ 'product' => $merchandise, 'faqs' => $faqs, 'tracking' => $tracking ];
if ($request->get('reload-variant')) {
$product = MerchandiseProduct::getById(intval($request->get('reload-variant')));
$returnArray['product'] = $product;
$template = $this->renderTemplate('shop/includes/product/merchandise-content.html.twig', $returnArray);
return $this->json([ 'success' => true, 'html' => $template->getContent() ]);
}
return $this->render('shop/product/merchandiseDetail.html.twig', $returnArray);
}
/**
* @Route("{_locale}/notification-overlay?id={id}", name="notification_overlay")
*
* @param Request $request
* @param ProductService $productService
* @param LinkGeneratorExtension $linkGenerator
*
* @return Response|RedirectResponse
*/
public function notificationOverlay(Request $request, ProductService $productService, LinkGeneratorExtension $linkGenerator): Response|RedirectResponse
{
$id = $request->get('id');
$product = DataObject::getById($id);
$email = $request->get('email');
if ((!$product instanceof MerchandiseProduct && !$product instanceof EventProduct && !$product instanceof ShopTicketCatalog) || !$product->isPublished()) {
throw new GoneHttpException('Requested object not found or not published!');
}
if ($request->getMethod() == 'POST' && $email != '') {
$success = $productService->handleNotificationRequest($email, $id, $request->getLocale()) ?: 'false';
return new RedirectResponse($linkGenerator->getDetailLink($product) . '?success=' . $success);
}
$template = $this->renderTemplate('includes/overlays/notification-content.html.twig', [ 'id' => $id, 'product' => $product ]);
return $this->json([ 'success' => true, 'html' => $template->getContent() ]);
}
}