<?php declare(strict_types=1);
namespace SensusUptainConnect6\Storefront\Subscriber;
use SensusUptainConnect6\Storefront\Service\CartStructService;
use SensusUptainConnect6\Storefront\Struct\CategoryStruct;
use SensusUptainConnect6\Storefront\Struct\CheckoutFinishStruct;
use SensusUptainConnect6\Storefront\Struct\ProductDetailStruct;
use SensusUptainConnect6\Storefront\Struct\SearchStruct;
use SensusUptainConnect6\Storefront\Struct\UptainConfig;
use SensusUptainConnect6\Storefront\Struct\WhistlistStruct;
use Shopware\Core\Checkout\Cart\Event\CartSavedEvent;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Customer\Event\CustomerWishlistProductListingResultEvent;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Shopware\Storefront\Page\GenericPageLoaderInterface;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Storefront\Page\Search\SearchPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UptainSubscriber implements EventSubscriberInterface
{
protected ?SystemConfigService $systemConfigService;
protected ?EntityRepositoryInterface $pluginRepository;
protected ?GenericPageLoaderInterface $genericPageLoader;
protected ?EntityRepositoryInterface $categoryRepository;
protected ?EntityRepositoryInterface $cmsPageRepository;
protected ?EntityRepositoryInterface $wishlistRepository;
protected ?EntityRepositoryInterface $productRepository;
protected ?CartStructService $cartStructService;
// phpcs:disable
public function __construct(
SystemConfigService $systemConfigService,
EntityRepositoryInterface $pluginRepository,
GenericPageLoaderInterface $genericPageLoader,
EntityRepositoryInterface $categoryRepository,
EntityRepositoryInterface $cmsPageRepository,
EntityRepositoryInterface $wishlistRepository,
EntityRepositoryInterface $productRepository,
CartStructService $cartStructService
) {
$this->systemConfigService = $systemConfigService;
$this->pluginRepository = $pluginRepository;
$this->genericPageLoader = $genericPageLoader;
$this->categoryRepository = $categoryRepository;
$this->cmsPageRepository = $cmsPageRepository;
$this->wishlistRepository = $wishlistRepository;
$this->productRepository = $productRepository;
$this->cartStructService = $cartStructService;
}
// phpcs:enable
public function onStorefrontRender(StorefrontRenderEvent $event)
{
$context = $event->getSalesChannelContext();
$customer = $context->getCustomer();
$customerGroup = $context->getCurrentCustomerGroup();
$token = $context->getToken();
$route = $event->getRequest()->get('_route');
// phpcs:disable
switch ($route) {
case 'frontend.navigation.page':
$pageType = 'category';
break;
case 'frontend.detail.page':
$pageType = 'product';
break;
case 'frontend.checkout.finish.page':
$pageType = 'success';
break;
case 'frontend.search.page':
$pageType = 'search';
break;
case 'frontend.checkout.register.page':
case 'frontend.checkout.confirm.page':
$pageType = 'checkout';
break;
case 'frontend.checkout.cart.page':
$pageType = 'cart';
break;
case 'frontend.home.page':
$pageType = 'home';
break;
default:
$pageType = 'other';
break;
}
// phpcs:enable
$transmitNewsletterCustomers = $this->systemConfigService->get(
'SensusUptainConnect6.config.transmitNewsletterCustomers',
$context->getSalesChannel()->getId(),
);
$transmitCustomers = $this->systemConfigService->get(
'SensusUptainConnect6.config.transmitCustomers',
$context->getSalesChannel()->getId(),
);
$blockCookies = $this->systemConfigService->get(
'SensusUptainConnect6.config.blockCookies',
$context->getSalesChannel()->getId(),
);
$customer = ($transmitCustomers && $customer && $customer->getOrderCount() > 0)
|| ($transmitNewsletterCustomers && $customer && $customer->getNewsletterSalesChannelIds() && count($customer->getNewsletterSalesChannelIds()) > 0)
? $customer
: null;
$transmitRevenue = $this->systemConfigService->get(
'SensusUptainConnect6.config.transmitRevenue',
$context->getSalesChannel()->getId(),
);
$revenue = null;
if ($customer && $transmitRevenue) {
/** @phpstan-ignore-next-line */
$revenue = $customer->getOrderTotalAmount();
}
$cookieEnabled = 1;
if ($blockCookies) {
$cookieEnabled = 0;
}
$criteria = new Criteria;
$criteria->addFilter(new EqualsFilter('name', 'SensusUptainConnect6'));
$plugin = $this->pluginRepository->search($criteria, $event->getContext())->first();
$struct = new UptainConfig;
$struct->assign([
'active' => $this->systemConfigService->get(
'SensusUptainConnect6.config.active',
$context->getSalesChannel()->getId(),
),
'uptainId' => $this->systemConfigService->get(
'SensusUptainConnect6.config.uptainId',
$context->getSalesChannel()->getId(),
),
'token' => $token,
'customerEmail' => $customer ? $customer->getEmail() : null,
'customerFirstName' => $customer ? $customer->getFirstName() : null,
'customerLastName' => $customer ? $customer->getLastName() : null,
'customerTitle' => $customer ? $customer->getTitle() : null,
'customerUid' => $customer ? \md5('5f6384bfec4ca' . $customer->getId()) : null,
'revenue' => $revenue,
'customerGroup' => $customerGroup->getName(),
'pluginData' => 'sensus-sw6:' . $plugin->getVersion(),
'pageType' => $pageType,
'cookieEnabled' => $cookieEnabled,
]);
$event->setParameter('sensusUptainConnect', $struct);
}
public function onCheckoutFinishPageLoaded(CheckoutFinishPageLoadedEvent $event)
{
$order = $event->getPage()->getOrder();
$promotionCode = null;
$cartProductsNetSum = 0;
foreach ($order->getLineItems() as $item) {
if ($item->getPrice()) {
$cartProductsNetSum += $item->getPrice()->getTotalPrice();
$cartProductsNetSum -= $item->getPrice()->getCalculatedTaxes()->getAmount();
}
if (!($item instanceof OrderLineItemEntity) ||
!\in_array($item->getType(), [
'easy-coupon',
LineItem::PROMOTION_LINE_ITEM_TYPE,
], true)) {
continue;
}
$promotionCode = $item->getReferencedId();
}
$struct = new CheckoutFinishStruct;
$struct->assign([
'orderNumber' => $order->getOrderNumber(),
'voucherCode' => $promotionCode,
'scv' => $cartProductsNetSum,
]);
$event->getPage()->addExtension('sensusUptainConnectFinish', $struct);
}
public function onCustomerWishlistProductListingResultEvent(CustomerWishlistProductListingResultEvent $event)
{
$products = $event->getResult();
if ($products->getTotal() <= 0) {
return;
}
$struct = new WhistlistStruct;
$context = $event->getSalesChannelContext();
$whistlistArray = [];
foreach ($products->getEntities() as $product) {
$variants = $product->getVariation();
$filterVariants = \array_splice($variants, 0, 300);
$whistlistArray[] = [
'amount' => 1,
'price' => $product->getPrice()->getCurrencyPrice($context->getCurrencyId())->getGross(),
'name' => $product->getTranslated()['name'],
'variants' => $filterVariants,
];
}
$struct->assign([
'wishlist' => \json_encode($whistlistArray),
]);
$context->addExtension('sensusUptainConnectWhistlist', $struct);
}
public function onCartSavedEvent(CartSavedEvent $event)
{
$salesChannelContext = $event->getSalesChannelContext();
$cartStruct = $this->cartStructService->getCartStruct($salesChannelContext, $event->getCart());
$salesChannelContext->addExtension('sensusUptainConnectCart', $cartStruct);
}
public function onProductListingResultEvent(ProductListingResultEvent $event)
{
$request = $event->getRequest();
$context = $event->getSalesChannelContext();
$parents = [];
$navigationId = $request->get('navigationId', $context->getSalesChannel()->getNavigationCategoryId());
$category = $this->categoryRepository->search(new Criteria([$navigationId]), $event->getContext())->first();
while ($parent = $category->getParent()) {
if ($parent->getId() === $category->getId()) {
break;
}
$parents[] = $parent->getName();
}
$productListArray = [];
$position = 0;
foreach ($event->getResult()->getEntities() as $product) {
$productListArray[] = [
'name' => $product->getTranslated()['name'],
'position' => $position,
];
$position += 1;
}
$struct = new CategoryStruct;
$struct->assign([
'categoryName' => $category->getName(),
'categoryPath' => \implode(';', \array_reverse($parents)),
'categoryProducts' => \json_encode($productListArray),
'categorySorting' => $event->getResult()->getSorting(),
]);
$context->addExtension('sensusUptainProductListing', $struct);
}
public function onProductPageLoadedEvent(ProductPageLoadedEvent $event)
{
try {
$page = $event->getPage();
$product = $page->getProduct();
$breadcrumb = [];
$categoryName = '';
if ($product->getSeoCategory()) {
$breadcrumb = $product->getSeoCategory()->getBreadcrumb();
$categoryName = $product->getSeoCategory()->getName();
}
$salesChannelContext = $event->getSalesChannelContext();
$transmitProductDetails = $this->systemConfigService->get(
'SensusUptainConnect6.config.transmitProductDetails',
$salesChannelContext->getSalesChannel()->getId(),
);
$struct = new ProductDetailStruct;
$struct->assign([
'productCategory' => $categoryName,
'productCategoryPaths' => \implode('/', $breadcrumb) . ';',
]);
if ($transmitProductDetails) {
$mediaUrl = '';
if ($product->getMedia()->count() > 0) {
$mediaUrl = $product->getMedia()->first()->getMedia()->getUrl();
}
$struct->assign([
'productId' => \md5('5f6384bfec4ca' . $product->getId()),
'productName' => $product->getTranslated()['name'],
'productPrice' => $product->getCalculatedCheapestPrice()->getTotalPrice(),
'productOriginalPrice' => $product->getCalculatedPrice()->getTotalPrice(),
'productImage' => $mediaUrl,
'productTags' => $product->getTags(),
'productVariants' => $product->getVariation(),
]);
}
$event->getPage()->addExtension('sensusUptainProductDetail', $struct);
} catch (\Throwable $ex) {
//ignore
}
}
public function onSearchPageLoadedEvent(SearchPageLoadedEvent $event)
{
$page = $event->getPage();
$productListing = $page->getListing();
$searchTerm = $page->getSearchTerm();
$productListArray = [];
$position = 0;
foreach ($productListing->getEntities() as $product) {
$productListArray[] = [
'name' => $product->getTranslated()['name'],
'position' => $position,
];
$position += 1;
}
$struct = new SearchStruct;
$struct->assign([
'searchTerm' => $searchTerm,
'searchProducts' => \json_encode($productListArray),
'searchSorting' => $productListing->getSorting(),
]);
$event->getPage()->addExtension('sensusUptainProductSearch', $struct);
}
/**
* @return array<string>
*/
public static function getSubscribedEvents(): array
{
return [
StorefrontRenderEvent::class => 'onStorefrontRender',
CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishPageLoaded',
CustomerWishlistProductListingResultEvent::class => 'onCustomerWishlistProductListingResultEvent',
CartSavedEvent::class => 'onCartSavedEvent',
ProductListingResultEvent::class => 'onProductListingResultEvent',
ProductPageLoadedEvent::class => 'onProductPageLoadedEvent',
SearchPageLoadedEvent::class => 'onSearchPageLoadedEvent',
];
}
}